ngx-smart-modal-wgv
Version:
Smart modal handler to manage modals and data everywhere in Angular apps.
465 lines • 54.4 kB
JavaScript
import { Inject, Injectable, PLATFORM_ID, TemplateRef, Type } from '@angular/core';
import { DOCUMENT, isPlatformBrowser } from '@angular/common';
import { NgxSmartModalComponent } from '../components/ngx-smart-modal.component';
import { NgxSmartModalConfig } from '../config/ngx-smart-modal.config';
import * as i0 from "@angular/core";
import * as i1 from "./ngx-smart-modal-stack.service";
export class NgxSmartModalService {
constructor(_appRef, _injector, _modalStack, _document, _platformId) {
this._appRef = _appRef;
this._injector = _injector;
this._modalStack = _modalStack;
this._document = _document;
this._platformId = _platformId;
/**
* Close the latest opened modal if escape key event is emitted
* @param event The Keyboard Event
*/
this._escapeKeyboardEvent = (event) => {
if (event.key === 'Escape') {
try {
const modal = this.getTopOpenedModal();
if (!modal.escapable) {
return false;
}
modal.onEscape.emit(modal);
this.closeLatestModal();
return true;
}
catch (e) {
return false;
}
}
return false;
};
/**
* While modal is open, the focus stay on it
* @param event The Keyboar dEvent
*/
this._trapFocusModal = (event) => {
if (event.key === 'Tab') {
try {
const modal = this.getTopOpenedModal();
if (!modal.nsmDialog.first.nativeElement.contains(document.activeElement)) {
event.preventDefault();
event.stopPropagation();
modal.nsmDialog.first.nativeElement.focus();
}
return true;
}
catch (e) {
return false;
}
}
return false;
};
this._addEvents();
}
/**
* Add a new modal instance. This step is essential and allows to retrieve any modal at any time.
* It stores an object that contains the given modal identifier and the modal itself directly in the `modalStack`.
*
* @param modalInstance The object that contains the given modal identifier and the modal itself.
* @param force Optional parameter that forces the overriding of modal instance if it already exists.
* @returns nothing special.
*/
addModal(modalInstance, force) {
this._modalStack.addModal(modalInstance, force);
}
/**
* Retrieve a modal instance by its identifier.
*
* @param id The modal identifier used at creation time.
*/
getModal(id) {
return this._modalStack.getModal(id);
}
/**
* Alias of `getModal` to retrieve a modal instance by its identifier.
*
* @param id The modal identifier used at creation time.
*/
get(id) {
return this.getModal(id);
}
/**
* Open a given modal
*
* @param id The modal identifier used at creation time.
* @param force Tell the modal to open top of all other opened modals
*/
open(id, force = false) {
return this._openModal(this.get(id), force);
}
/**
* Close a given modal
*
* @param id The modal identifier used at creation time.
*/
close(id) {
return this._closeModal(this.get(id));
}
/**
* Close all opened modals
*/
closeAll() {
this.getOpenedModals().forEach((instance) => {
this._closeModal(instance.modal);
});
}
/**
* Toggles a given modal
* If the retrieved modal is opened it closes it, else it opens it.
*
* @param id The modal identifier used at creation time.
* @param force Tell the modal to open top of all other opened modals
*/
toggle(id, force = false) {
return this._toggleModal(this.get(id), force);
}
/**
* Retrieve all the created modals.
*
* @returns an array that contains all modal instances.
*/
getModalStack() {
return this._modalStack.getModalStack();
}
/**
* Retrieve all the opened modals. It looks for all modal instances with their `visible` property set to `true`.
*
* @returns an array that contains all the opened modals.
*/
getOpenedModals() {
return this._modalStack.getOpenedModals();
}
/**
* Retrieve the opened modal with highest z-index.
*
* @returns the opened modal with highest z-index.
*/
getTopOpenedModal() {
return this._modalStack.getTopOpenedModal();
}
/**
* Get the higher `z-index` value between all the modal instances. It iterates over the `ModalStack` array and
* calculates a higher value (it takes the highest index value between all the modal instances and adds 1).
* Use it to make a modal appear foreground.
*
* @returns a higher index from all the existing modal instances.
*/
getHigherIndex() {
return this._modalStack.getHigherIndex();
}
/**
* It gives the number of modal instances. It's helpful to know if the modal stack is empty or not.
*
* @returns the number of modal instances.
*/
getModalStackCount() {
return this._modalStack.getModalStackCount();
}
/**
* Remove a modal instance from the modal stack.
*
* @param id The modal identifier.
* @returns the removed modal instance.
*/
removeModal(id) {
const modalInstance = this._modalStack.removeModal(id);
if (modalInstance) {
this._destroyModal(modalInstance.modal);
}
}
/**
* Associate data to an identified modal. If the modal isn't already associated to some data, it creates a new
* entry in the `modalData` array with its `id` and the given `data`. If the modal already has data, it rewrites
* them with the new ones. Finally if no modal found it returns an error message in the console and false value
* as method output.
*
* @param data The data you want to associate to the modal.
* @param id The modal identifier.
* @param force If true, overrides the previous stored data if there was.
* @returns true if the given modal exists and the process has been tried, either false.
*/
setModalData(data, id, force) {
const modal = this.get(id);
if (modal) {
modal.setData(data, force);
return true;
}
else {
return false;
}
}
/**
* Retrieve modal data by its identifier.
*
* @param id The modal identifier used at creation time.
* @returns the associated modal data.
*/
getModalData(id) {
const modal = this.get(id);
if (modal) {
return modal.getData();
}
return null;
}
/**
* Reset the data attached to a given modal.
*
* @param id The modal identifier used at creation time.
* @returns the removed data or false if modal doesn't exist.
*/
resetModalData(id) {
if (this._modalStack.getModalStack().find((o) => o.id === id)) {
const removed = this.getModal(id).getData();
this.getModal(id).removeData();
return removed;
}
else {
return false;
}
}
/**
* Close the latest opened modal
*/
closeLatestModal() {
this.getTopOpenedModal().close();
}
/**
* Create dynamic NgxSmartModalComponent
* @param vcr A ViewContainerRef reference
* @param id The modal identifier used at creation time
* @param content The modal content (string, templateRef or Component)
* @param options Any NgxSmartModalComponent available options
*/
create(id, content, vcr, options = {}) {
try {
return this.getModal(id);
}
catch (e) {
const ngContent = this._resolveNgContent(content);
const componentRef = vcr.createComponent(NgxSmartModalComponent, { injector: this._injector, projectableNodes: ngContent });
if (content instanceof Type) {
componentRef.instance.contentComponent = content;
}
componentRef.instance.identifier = id;
componentRef.instance.createFrom = 'service';
if (typeof options.closable === 'boolean') {
componentRef.instance.closable = options.closable;
}
if (typeof options.escapable === 'boolean') {
componentRef.instance.escapable = options.escapable;
}
if (typeof options.dismissable === 'boolean') {
componentRef.instance.dismissable = options.dismissable;
}
if (typeof options.customClass === 'string') {
componentRef.instance.customClass = options.customClass;
}
if (typeof options.backdrop === 'boolean') {
componentRef.instance.backdrop = options.backdrop;
}
if (typeof options.force === 'boolean') {
componentRef.instance.force = options.force;
}
if (typeof options.hideDelay === 'number') {
componentRef.instance.hideDelay = options.hideDelay;
}
if (typeof options.autostart === 'boolean') {
componentRef.instance.autostart = options.autostart;
}
if (typeof options.target === 'string') {
componentRef.instance.target = options.target;
}
if (typeof options.ariaLabel === 'string') {
componentRef.instance.ariaLabel = options.ariaLabel;
}
if (typeof options.ariaLabelledBy === 'string') {
componentRef.instance.ariaLabelledBy = options.ariaLabelledBy;
}
if (typeof options.ariaDescribedBy === 'string') {
componentRef.instance.ariaDescribedBy = options.ariaDescribedBy;
}
if (typeof options.refocus === 'boolean') {
componentRef.instance.refocus = options.refocus;
}
const domElem = componentRef.hostView.rootNodes[0];
this._document.body.appendChild(domElem);
return componentRef.instance;
}
}
_addEvents() {
if (!this.isBrowser) {
return false;
}
window.addEventListener(NgxSmartModalConfig.prefixEvent + 'create', ((e) => {
this._initModal(e.detail.instance);
}));
window.addEventListener(NgxSmartModalConfig.prefixEvent + 'delete', ((e) => {
this._deleteModal(e.detail.instance);
}));
window.addEventListener(NgxSmartModalConfig.prefixEvent + 'open', ((e) => {
this._openModal(e.detail.instance.modal, e.detail.extraData.top);
}));
window.addEventListener(NgxSmartModalConfig.prefixEvent + 'toggle', ((e) => {
this._toggleModal(e.detail.instance.modal, e.detail.extraData.top);
}));
window.addEventListener(NgxSmartModalConfig.prefixEvent + 'close', ((e) => {
this._closeModal(e.detail.instance.modal);
}));
window.addEventListener(NgxSmartModalConfig.prefixEvent + 'dismiss', ((e) => {
this._dismissModal(e.detail.instance.modal);
}));
window.addEventListener('keyup', this._escapeKeyboardEvent);
return true;
}
_initModal(modalInstance) {
modalInstance.modal.layerPosition += this.getModalStackCount();
this.addModal(modalInstance, modalInstance.modal.force);
if (modalInstance.modal.autostart) {
this.open(modalInstance.id);
}
}
_openModal(modal, top) {
if (modal.visible) {
return false;
}
this.lastElementFocused = document.activeElement;
if (modal.escapable) {
window.addEventListener('keyup', this._escapeKeyboardEvent);
}
if (modal.backdrop) {
window.addEventListener('keydown', this._trapFocusModal);
}
if (top) {
modal.layerPosition = this.getHigherIndex();
}
modal.addBodyClass();
modal.overlayVisible = true;
modal.visible = true;
modal.onOpen.emit(modal);
modal.markForCheck();
setTimeout(() => {
modal.openedClass = true;
if (modal.target) {
modal.targetPlacement();
}
modal.nsmDialog.first.nativeElement.setAttribute('role', 'dialog');
modal.nsmDialog.first.nativeElement.setAttribute('tabIndex', '-1');
modal.nsmDialog.first.nativeElement.setAttribute('aria-modal', 'true');
modal.nsmDialog.first.nativeElement.focus();
modal.markForCheck();
modal.onOpenFinished.emit(modal);
});
return true;
}
_toggleModal(modal, top) {
if (modal.visible) {
return this._closeModal(modal);
}
else {
return this._openModal(modal, top);
}
}
_closeModal(modal) {
if (!modal.openedClass) {
return false;
}
modal.openedClass = false;
modal.onClose.emit(modal);
modal.onAnyCloseEvent.emit(modal);
if (this.getOpenedModals().length < 2) {
modal.removeBodyClass();
window.removeEventListener('keyup', this._escapeKeyboardEvent);
window.removeEventListener('keydown', this._trapFocusModal);
}
setTimeout(() => {
modal.visibleChange.emit(modal.visible);
modal.visible = false;
modal.overlayVisible = false;
modal.nsmDialog.first.nativeElement.removeAttribute('tabIndex');
modal.markForCheck();
modal.onCloseFinished.emit(modal);
modal.onAnyCloseEventFinished.emit(modal);
if (modal.refocus) {
this.lastElementFocused.focus();
}
}, modal.hideDelay);
return true;
}
_dismissModal(modal) {
if (!modal.openedClass) {
return false;
}
modal.openedClass = false;
modal.onDismiss.emit(modal);
modal.onAnyCloseEvent.emit(modal);
if (this.getOpenedModals().length < 2) {
modal.removeBodyClass();
}
setTimeout(() => {
modal.visible = false;
modal.visibleChange.emit(modal.visible);
modal.overlayVisible = false;
modal.markForCheck();
modal.onDismissFinished.emit(modal);
modal.onAnyCloseEventFinished.emit(modal);
}, modal.hideDelay);
return true;
}
_deleteModal(modalInstance) {
this.removeModal(modalInstance.id);
if (!this.getModalStack().length) {
modalInstance.modal.removeBodyClass();
}
}
/**
* Resolve content according to the types
* @param content The modal content (string, templateRef or Component)
*/
_resolveNgContent(content) {
if (typeof content === 'string') {
const element = this._document.createTextNode(content);
return [[element]];
}
if (content instanceof TemplateRef) {
const viewRef = content.createEmbeddedView(null);
this._appRef.attachView(viewRef);
return [viewRef.rootNodes];
}
return [];
}
/**
* Is current platform browser
*/
get isBrowser() {
return isPlatformBrowser(this._platformId);
}
/**
* Remove dynamically created modal from DOM
*/
_destroyModal(modal) {
// Prevent destruction of the inline modals
if (modal.createFrom !== 'service') {
return;
}
this._document.body.removeChild(modal.elementRef.nativeElement);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.10", ngImport: i0, type: NgxSmartModalService, deps: [{ token: i0.ApplicationRef }, { token: i0.Injector }, { token: i1.NgxSmartModalStackService }, { token: DOCUMENT }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.10", ngImport: i0, type: NgxSmartModalService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.10", ngImport: i0, type: NgxSmartModalService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}], ctorParameters: function () { return [{ type: i0.ApplicationRef }, { type: i0.Injector }, { type: i1.NgxSmartModalStackService }, { type: undefined, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }, { type: undefined, decorators: [{
type: Inject,
args: [PLATFORM_ID]
}] }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LXNtYXJ0LW1vZGFsLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtc21hcnQtbW9kYWwvc3JjL2xpYi9zZXJ2aWNlcy9uZ3gtc21hcnQtbW9kYWwuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQW1DLE1BQU0sRUFBRSxVQUFVLEVBQVksV0FBVyxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQW9CLE1BQU0sZUFBZSxDQUFDO0FBQ2hKLE9BQU8sRUFBRSxRQUFRLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUNqRixPQUFPLEVBQXlCLG1CQUFtQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7OztBQVM5RixNQUFNLE9BQU8sb0JBQW9CO0lBRy9CLFlBQ1UsT0FBdUIsRUFDdkIsU0FBbUIsRUFDbkIsV0FBc0MsRUFDcEIsU0FBYyxFQUNYLFdBQWdCO1FBSnJDLFlBQU8sR0FBUCxPQUFPLENBQWdCO1FBQ3ZCLGNBQVMsR0FBVCxTQUFTLENBQVU7UUFDbkIsZ0JBQVcsR0FBWCxXQUFXLENBQTJCO1FBQ3BCLGNBQVMsR0FBVCxTQUFTLENBQUs7UUFDWCxnQkFBVyxHQUFYLFdBQVcsQ0FBSztRQThaL0M7OztXQUdHO1FBQ0sseUJBQW9CLEdBQUcsQ0FBQyxLQUFvQixFQUFFLEVBQUU7WUFDdEQsSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLFFBQVEsRUFBRTtnQkFDMUIsSUFBSTtvQkFDRixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztvQkFFdkMsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUU7d0JBQ3BCLE9BQU8sS0FBSyxDQUFDO3FCQUNkO29CQUVELEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxD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QUksT0FBTyxPQUFPLEtBQUssUUFBUSxFQUFFO1lBQy9CLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3ZELE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7U0FDcEI7UUFFRCxJQUFJLE9BQU8sWUFBWSxXQUFXLEVBQUU7WUFDbEMsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFDLElBQVcsQ0FBQyxDQUFDO1lBQ3hELElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ2pDLE9BQU8sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7U0FDNUI7UUFFRCxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7SUEyQkQ7O09BRUc7SUFDSCxJQUFZLFNBQVM7UUFDbkIsT0FBTyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDN0MsQ0FBQztJQTBCRDs7T0FFRztJQUNLLGFBQWEsQ0FBQyxLQUE2QjtRQUNqRCwyQ0FBMkM7UUFDM0MsSUFBSSxLQUFLLENBQUMsVUFBVSxLQUFLLFNBQVMsRUFBRTtZQUNsQyxPQUFPO1NBQ1I7UUFFRCxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUNsRSxDQUFDOytHQXhlVSxvQkFBb0IsaUhBT3JCLFFBQVEsYUFDUixXQUFXO21IQVJWLG9CQUFvQixjQUZuQixNQUFNOzs0RkFFUCxvQkFBb0I7a0JBSGhDLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25COzswQkFRSSxNQUFNOzJCQUFDLFFBQVE7OzBCQUNmLE1BQU07MkJBQUMsV0FBVyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFwcGxpY2F0aW9uUmVmLCBFbWJlZGRlZFZpZXdSZWYsIEluamVjdCwgSW5qZWN0YWJsZSwgSW5qZWN0b3IsIFBMQVRGT1JNX0lELCBUZW1wbGF0ZVJlZiwgVHlwZSwgVmlld0NvbnRhaW5lclJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRE9DVU1FTlQsIGlzUGxhdGZvcm1Ccm93c2VyIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IE5neFNtYXJ0TW9kYWxDb21wb25lbnQgfSBmcm9tICcuLi9jb21wb25lbnRzL25neC1zbWFydC1tb2RhbC5jb21wb25lbnQnO1xuaW1wb3J0IHsgSU5neFNtYXJ0TW9kYWxPcHRpb25zLCBOZ3hTbWFydE1vZGFsQ29uZmlnIH0gZnJvbSAnLi4vY29uZmlnL25neC1zbWFydC1tb2RhbC5jb25maWcnO1xuaW1wb3J0IHsgTmd4U21hcnRNb2RhbFN0YWNrU2VydmljZSB9IGZyb20gJy4vbmd4LXNtYXJ0LW1vZGFsLXN0YWNrLnNlcnZpY2UnO1xuaW1wb3J0IHsgTW9kYWxJbnN0YW5jZSB9IGZyb20gJy4vbW9kYWwtaW5zdGFuY2UnO1xuXG5leHBvcnQgdHlwZSBDb250ZW50PFQ+ID0gc3RyaW5nIHwgVGVtcGxhdGVSZWY8VD4gfCBUeXBlPFQ+O1xuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBOZ3hTbWFydE1vZGFsU2VydmljZSB7XG4gIHByaXZhdGUgbGFzdEVsZW1lbnRGb2N1c2VkOiBhbnk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBfYXBwUmVmOiBBcHBsaWNhdGlvblJlZixcbiAgICBwcml2YXRlIF9pbmplY3RvcjogSW5qZWN0b3IsXG4gICAgcHJpdmF0ZSBfbW9kYWxTdGFjazogTmd4U21hcnRNb2RhbFN0YWNrU2VydmljZSxcbiAgICBASW5qZWN0KERPQ1VNRU5UKSBwcml2YXRlIF9kb2N1bWVudDogYW55LFxuICAgIEBJbmplY3QoUExBVEZPUk1fSUQpIHByaXZhdGUgX3BsYXRmb3JtSWQ6IGFueVxuICApIHtcbiAgICB0aGlzLl9hZGRFdmVudHMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgYSBuZXcgbW9kYWwgaW5zdGFuY2UuIFRoaXMgc3RlcCBpcyBlc3NlbnRpYWwgYW5kIGFsbG93cyB0byByZXRyaWV2ZSBhbnkgbW9kYWwgYXQgYW55IHRpbWUuXG4gICAqIEl0IHN0b3JlcyBhbiBvYmplY3QgdGhhdCBjb250YWlucyB0aGUgZ2l2ZW4gbW9kYWwgaWRlbnRpZmllciBhbmQgdGhlIG1vZGFsIGl0c2VsZiBkaXJlY3RseSBpbiB0aGUgYG1vZGFsU3RhY2tgLlxuICAgKlxuICAgKiBAcGFyYW0gbW9kYWxJbnN0YW5jZSBUaGUgb2JqZWN0IHRoYXQgY29udGFpbnMgdGhlIGdpdmVuIG1vZGFsIGlkZW50aWZpZXIgYW5kIHRoZSBtb2RhbCBpdHNlbGYuXG4gICAqIEBwYXJhbSBmb3JjZSBPcHRpb25hbCBwYXJhbWV0ZXIgdGhhdCBmb3JjZXMgdGhlIG92ZXJyaWRpbmcgb2YgbW9kYWwgaW5zdGFuY2UgaWYgaXQgYWxyZWFkeSBleGlzdHMuXG4gICAqIEByZXR1cm5zIG5vdGhpbmcgc3BlY2lhbC5cbiAgICovXG4gIHB1YmxpYyBhZGRNb2RhbChtb2RhbEluc3RhbmNlOiBNb2RhbEluc3RhbmNlLCBmb3JjZT86IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLl9tb2RhbFN0YWNrLmFkZE1vZGFsKG1vZGFsSW5zdGFuY2UsIGZvcmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZSBhIG1vZGFsIGluc3RhbmNlIGJ5IGl0cyBpZGVudGlmaWVyLlxuICAgKlxuICAgKiBAcGFyYW0gaWQgVGhlIG1vZGFsIGlkZW50aWZpZXIgdXNlZCBhdCBjcmVhdGlvbiB0aW1lLlxuICAgKi9cbiAgcHVibGljIGdldE1vZGFsKGlkOiBzdHJpbmcpOiBOZ3hTbWFydE1vZGFsQ29tcG9uZW50IHtcbiAgICByZXR1cm4gdGhpcy5fbW9kYWxTdGFjay5nZXRNb2RhbChpZCk7XG4gIH1cblxuICAvKipcbiAgICogQWxpYXMgb2YgYGdldE1vZGFsYCB0byByZXRyaWV2ZSBhIG1vZGFsIGluc3RhbmNlIGJ5IGl0cyBpZGVudGlmaWVyLlxuICAgKlxuICAgKiBAcGFyYW0gaWQgVGhlIG1vZGFsIGlkZW50aWZpZXIgdXNlZCBhdCBjcmVhdGlvbiB0aW1lLlxuICAgKi9cbiAgcHVibGljIGdldChpZDogc3RyaW5nKTogTmd4U21hcnRNb2RhbENvbXBvbmVudCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0TW9kYWwoaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIE9wZW4gYSBnaXZlbiBtb2RhbFxuICAgKlxuICAgKiBAcGFyYW0gaWQgVGhlIG1vZGFsIGlkZW50aWZpZXIgdXNlZCBhdCBjcmVhdGlvbiB0aW1lLlxuICAgKiBAcGFyYW0gZm9yY2UgVGVsbCB0aGUgbW9kYWwgdG8gb3BlbiB0b3Agb2YgYWxsIG90aGVyIG9wZW5lZCBtb2RhbHNcbiAgICovXG4gIHB1YmxpYyBvcGVuKGlkOiBzdHJpbmcsIGZvcmNlID0gZmFsc2UpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fb3Blbk1vZGFsKHRoaXMuZ2V0KGlkKSwgZm9yY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIENsb3NlIGEgZ2l2ZW4gbW9kYWxcbiAgICpcbiAgICogQHBhcmFtIGlkIFRoZSBtb2RhbCBpZGVudGlmaWVyIHVzZWQgYXQgY3JlYXRpb24gdGltZS5cbiAgICovXG4gIHB1YmxpYyBjbG9zZShpZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX2Nsb3NlTW9kYWwodGhpcy5nZXQoaWQpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbG9zZSBhbGwgb3BlbmVkIG1vZGFsc1xuICAgKi9cbiAgcHVibGljIGNsb3NlQWxsKCk6IHZvaWQge1xuICAgIHRoaXMuZ2V0T3BlbmVkTW9kYWxzKCkuZm9yRWFjaCgoaW5zdGFuY2U6IE1vZGFsSW5zdGFuY2UpID0+IHtcbiAgICAgIHRoaXMuX2Nsb3NlTW9kYWwoaW5zdGFuY2UubW9kYWwpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFRvZ2dsZXMgYSBnaXZlbiBtb2RhbFxuICAgKiBJZiB0aGUgcmV0cmlldmVkIG1vZGFsIGlzIG9wZW5lZCBpdCBjbG9zZXMgaXQsIGVsc2UgaXQgb3BlbnMgaXQuXG4gICAqXG4gICAqIEBwYXJhbSBpZCBUaGUgbW9kYWwgaWRlbnRpZmllciB1c2VkIGF0IGNyZWF0aW9uIHRpbWUuXG4gICAqIEBwYXJhbSBmb3JjZSBUZWxsIHRoZSBtb2RhbCB0byBvcGVuIHRvcCBvZiBhbGwgb3RoZXIgb3BlbmVkIG1vZGFsc1xuICAgKi9cbiAgcHVibGljIHRvZ2dsZShpZDogc3RyaW5nLCBmb3JjZSA9IGZhbHNlKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX3RvZ2dsZU1vZGFsKHRoaXMuZ2V0KGlkKSwgZm9yY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlIGFsbCB0aGUgY3JlYXRlZCBtb2RhbHMuXG4gICAqXG4gICAqIEByZXR1cm5zIGFuIGFycmF5IHRoYXQgY29udGFpbnMgYWxsIG1vZGFsIGluc3RhbmNlcy5cbiAgICovXG4gIHB1YmxpYyBnZXRNb2RhbFN0YWNrKCk6IE1vZGFsSW5zdGFuY2VbXSB7XG4gICAgcmV0dXJuIHRoaXMuX21vZGFsU3RhY2suZ2V0TW9kYWxTdGFjaygpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlIGFsbCB0aGUgb3BlbmVkIG1vZGFscy4gSXQgbG9va3MgZm9yIGFsbCBtb2RhbCBpbnN0YW5jZXMgd2l0aCB0aGVpciBgdmlzaWJsZWAgcHJvcGVydHkgc2V0IHRvIGB0cnVlYC5cbiAgICpcbiAgICogQHJldHVybnMgYW4gYXJyYXkgdGhhdCBjb250YWlucyBhbGwgdGhlIG9wZW5lZCBtb2RhbHMuXG4gICAqL1xuICBwdWJsaWMgZ2V0T3BlbmVkTW9kYWxzKCk6IE1vZGFsSW5zdGFuY2VbXSB7XG4gICAgcmV0dXJuIHRoaXMuX21vZGFsU3RhY2suZ2V0T3BlbmVkTW9kYWxzKCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmUgdGhlIG9wZW5lZCBtb2RhbCB3aXRoIGhpZ2hlc3Qgei1pbmRleC5cbiAgICpcbiAgICogQHJldHVybnMgdGhlIG9wZW5lZCBtb2RhbCB3aXRoIGhpZ2hlc3Qgei1pbmRleC5cbiAgICovXG4gIHB1YmxpYyBnZXRUb3BPcGVuZWRNb2RhbCgpOiBOZ3hTbWFydE1vZGFsQ29tcG9uZW50IHtcbiAgICByZXR1cm4gdGhpcy5fbW9kYWxTdGFjay5nZXRUb3BPcGVuZWRNb2RhbCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgaGlnaGVyIGB6LWluZGV4YCB2YWx1ZSBiZXR3ZWVuIGFsbCB0aGUgbW9kYWwgaW5zdGFuY2VzLiBJdCBpdGVyYXRlcyBvdmVyIHRoZSBgTW9kYWxTdGFja2AgYXJyYXkgYW5kXG4gICAqIGNhbGN1bGF0ZXMgYSBoaWdoZXIgdmFsdWUgKGl0IHRha2VzIHRoZSBoaWdoZXN0IGluZGV4IHZhbHVlIGJldHdlZW4gYWxsIHRoZSBtb2RhbCBpbnN0YW5jZXMgYW5kIGFkZHMgMSkuXG4gICAqIFVzZSBpdCB0byBtYWtlIGEgbW9kYWwgYXBwZWFyIGZvcmVncm91bmQuXG4gICAqXG4gICAqIEByZXR1cm5zIGEgaGlnaGVyIGluZGV4IGZyb20gYWxsIHRoZSBleGlzdGluZyBtb2RhbCBpbnN0YW5jZXMuXG4gICAqL1xuICBwdWJsaWMgZ2V0SGlnaGVySW5kZXgoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fbW9kYWxTdGFjay5nZXRIaWdoZXJJbmRleCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEl0IGdpdmVzIHRoZSBudW1iZXIgb2YgbW9kYWwgaW5zdGFuY2VzLiBJdCdzIGhlbHBmdWwgdG8ga25vdyBpZiB0aGUgbW9kYWwgc3RhY2sgaXMgZW1wdHkgb3Igbm90LlxuICAgKlxuICAgKiBAcmV0dXJucyB0aGUgbnVtYmVyIG9mIG1vZGFsIGluc3RhbmNlcy5cbiAgICovXG4gIHB1YmxpYyBnZXRNb2RhbFN0YWNrQ291bnQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fbW9kYWxTdGFjay5nZXRNb2RhbFN0YWNrQ291bnQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgYSBtb2RhbCBpbnN0YW5jZSBmcm9tIHRoZSBtb2RhbCBzdGFjay5cbiAgICpcbiAgICogQHBhcmFtIGlkIFRoZSBtb2RhbCBpZGVudGlmaWVyLlxuICAgKiBAcmV0dXJucyB0aGUgcmVtb3ZlZCBtb2RhbCBpbnN0YW5jZS5cbiAgICovXG4gIHB1YmxpYyByZW1vdmVNb2RhbChpZDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgbW9kYWxJbnN0YW5jZSA9IHRoaXMuX21vZGFsU3RhY2sucmVtb3ZlTW9kYWwoaWQpO1xuICAgIGlmIChtb2RhbEluc3RhbmNlKSB7XG4gICAgICB0aGlzLl9kZXN0cm95TW9kYWwobW9kYWxJbnN0YW5jZS5tb2RhbCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFzc29jaWF0ZSBkYXRhIHRvIGFuIGlkZW50aWZpZWQgbW9kYWwuIElmIHRoZSBtb2RhbCBpc24ndCBhbHJlYWR5IGFzc29jaWF0ZWQgdG8gc29tZSBkYXRhLCBpdCBjcmVhdGVzIGEgbmV3XG4gICAqIGVudHJ5IGluIHRoZSBgbW9kYWxEYXRhYCBhcnJheSB3aXRoIGl0cyBgaWRgIGFuZCB0aGUgZ2l2ZW4gYGRhdGFgLiBJZiB0aGUgbW9kYWwgYWxyZWFkeSBoYXMgZGF0YSwgaXQgcmV3cml0ZXNcbiAgICogdGhlbSB3aXRoIHRoZSBuZXcgb25lcy4gRmluYWxseSBpZiBubyBtb2RhbCBmb3VuZCBpdCByZXR1cm5zIGFuIGVycm9yIG1lc3NhZ2UgaW4gdGhlIGNvbnNvbGUgYW5kIGZhbHNlIHZhbHVlXG4gICAqIGFzIG1ldGhvZCBvdXRwdXQuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhIFRoZSBkYXRhIHlvdSB3YW50IHRvIGFzc29jaWF0ZSB0byB0aGUgbW9kYWwuXG4gICAqIEBwYXJhbSBpZCBUaGUgbW9kYWwgaWRlbnRpZmllci5cbiAgICogQHBhcmFtIGZvcmNlIElmIHRydWUsIG92ZXJyaWRlcyB0aGUgcHJldmlvdXMgc3RvcmVkIGRhdGEgaWYgdGhlcmUgd2FzLlxuICAgKiBAcmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBtb2RhbCBleGlzdHMgYW5kIHRoZSBwcm9jZXNzIGhhcyBiZWVuIHRyaWVkLCBlaXRoZXIgZmFsc2UuXG4gICAqL1xuICBwdWJsaWMgc2V0TW9kYWxEYXRhKGRhdGE6IGFueSwgaWQ6IHN0cmluZywgZm9yY2U/OiBib29sZWFuKTogYm9vbGVhbiB7XG4gICAgY29uc3QgbW9kYWwgPSB0aGlzLmdldChpZCk7XG4gICAgaWYgKG1vZGFsKSB7XG4gICAgICBtb2RhbC5zZXREYXRhKGRhdGEsIGZvcmNlKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlIG1vZGFsIGRhdGEgYnkgaXRzIGlkZW50aWZpZXIuXG4gICAqXG4gICAqIEBwYXJhbSBpZCBUaGUgbW9kYWwgaWRlbnRpZmllciB1c2VkIGF0IGNyZWF0aW9uIHRpbWUuXG4gICAqIEByZXR1cm5zIHRoZSBhc3NvY2lhdGVkIG1vZGFsIGRhdGEuXG4gICAqL1xuICBwdWJsaWMgZ2V0TW9kYWxEYXRhKGlkOiBzdHJpbmcpOiB1bmtub3duIHtcbiAgICBjb25zdCBtb2RhbCA9IHRoaXMuZ2V0KGlkKTtcbiAgICBpZiAobW9kYWwpIHtcbiAgICAgIHJldHVybiBtb2RhbC5nZXREYXRhKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKipcbiAgICogUmVzZXQgdGhlIGRhdGEgYXR0YWNoZWQgdG8gYSBnaXZlbiBtb2RhbC5cbiAgICpcbiAgICogQHBhcmFtIGlkIFRoZSBtb2RhbCBpZGVudGlmaWVyIHVzZWQgYXQgY3JlYXRpb24gdGltZS5cbiAgICogQHJldHVybnMgdGhlIHJlbW92ZWQgZGF0YSBvciBmYWxzZSBpZiBtb2RhbCBkb2Vzbid0IGV4aXN0LlxuICAgKi9cbiAgcHVibGljIHJlc2V0TW9kYWxEYXRhKGlkOiBzdHJpbmcpOiB1bmtub3duIHwgYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMuX21vZGFsU3RhY2suZ2V0TW9kYWxTdGFjaygpLmZpbmQoKG86IE1vZGFsSW5zdGFuY2UpID0+IG8uaWQgPT09IGlkKSkge1xuICAgICAgY29uc3QgcmVtb3ZlZDogdW5rbm93biA9IHRoaXMuZ2V0TW9kYWwoaWQpLmdldERhdGEoKTtcbiAgICAgIHRoaXMuZ2V0TW9kYWwoaWQpLnJlbW92ZURhdGEoKTtcbiAgICAgIHJldHVybiByZW1vdmVkO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENsb3NlIHRoZSBsYXRlc3Qgb3BlbmVkIG1vZGFsXG4gICAqL1xuICBwdWJsaWMgY2xvc2VMYXRlc3RNb2RhbCgpOiB2b2lkIHtcbiAgICB0aGlzLmdldFRvcE9wZW5lZE1vZGFsKCkuY2xvc2UoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgZHluYW1pYyBOZ3hTbWFydE1vZGFsQ29tcG9uZW50XG4gICAqIEBwYXJhbSB2Y3IgQSBWaWV3Q29udGFpbmVyUmVmIHJlZmVyZW5jZVxuICAgKiBAcGFyYW0gaWQgVGhlIG1vZGFsIGlkZW50aWZpZXIgdXNlZCBhdCBjcmVhdGlvbiB0aW1lXG4gICAqIEBwYXJhbSBjb250ZW50IFRoZSBtb2RhbCBjb250ZW50IChzdHJpbmcsIHRlbXBsYXRlUmVmIG9yIENvbXBvbmVudClcbiAgICogQHBhcmFtIG9wdGlvbnMgQW55IE5neFNtYXJ0TW9kYWxDb21wb25lbnQgYXZhaWxhYmxlIG9wdGlvbnNcbiAgICovXG4gIHB1YmxpYyBjcmVhdGU8VD4oaWQ6IHN0cmluZywgY29udGVudDogQ29udGVudDxUPiwgdmNyOiBWaWV3Q29udGFpbmVyUmVmLCBvcHRpb25zOiBJTmd4U21hcnRNb2RhbE9wdGlvbnMgPSB7fSkge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRNb2RhbChpZCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29uc3QgbmdDb250ZW50ID0gdGhpcy5fcmVzb2x2ZU5nQ29udGVudChjb250ZW50KTtcblxuICAgICAgY29uc3QgY29tcG9uZW50UmVmID0gdmNyLmNyZWF0ZUNvbXBvbmVudChOZ3hTbWFydE1vZGFsQ29tcG9uZW50LCB7IGluamVjdG9yOiB0aGlzLl9pbmplY3RvciwgcHJvamVjdGFibGVOb2RlczogbmdDb250ZW50IH0pO1xuXG4gICAgICBpZiAoY29udGVudCBpbnN0YW5jZW9mIFR5cGUpIHtcbiAgICAgICAgY29tcG9uZW50UmVmLmluc3RhbmNlLmNvbnRlbnRDb21wb25lbnQgPSBjb250ZW50O1xuICAgICAgfVxuXG4gICAgICBjb21wb25lbnRSZWYuaW5zdGFuY2UuaWRlbnRpZmllciA9IGlkO1xuICAgICAgY29tcG9uZW50UmVmLmluc3RhbmNlLmNyZWF0ZUZyb20gPSAnc2VydmljZSc7XG5cbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5jbG9zYWJsZSA9PT0gJ2Jvb2xlYW4nKSB7IGNvbXBvbmVudFJlZi5pbnN0YW5jZS5jbG9zYWJsZSA9IG9wdGlvbnMuY2xvc2FibGU7IH1cbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5lc2NhcGFibGUgPT09ICdib29sZWFuJykgeyBjb21wb25lbnRSZWYuaW5zdGFuY2UuZXNjYXBhYmxlID0gb3B0aW9ucy5lc2NhcGFibGU7IH1cbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5kaXNtaXNzYWJsZSA9PT0gJ2Jvb2xlYW4nKSB7IGNvbXBvbmVudFJlZi5pbnN0YW5jZS5kaXNtaXNzYWJsZSA9IG9wdGlvbnMuZGlzbWlzc2FibGU7IH1cbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5jdXN0b21DbGFzcyA9PT0gJ3N0cmluZycpIHsgY29tcG9uZW50UmVmLmluc3RhbmNlLmN1c3RvbUNsYXNzID0gb3B0aW9ucy5jdXN0b21DbGFzczsgfVxuICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLmJhY2tkcm9wID09PSAnYm9vbGVhbicpIHsgY29tcG9uZW50UmVmLmluc3RhbmNlLmJhY2tkcm9wID0gb3B0aW9ucy5iYWNrZHJvcDsgfVxuICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLmZvcmNlID09PSAnYm9vbGVhbicpIHsgY29tcG9uZW50UmVmLmluc3RhbmNlLmZvcmNlID0gb3B0aW9ucy5mb3JjZTsgfVxuICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLmhpZGVEZWxheSA9PT0gJ251bWJlcicpIHsgY29tcG9uZW50UmVmLmluc3RhbmNlLmhpZGVEZWxheSA9IG9wdGlvbnMuaGlkZURlbGF5OyB9XG4gICAgICBpZiAodHlwZW9mIG9wdGlvbnMuYXV0b3N0YXJ0ID09PSAnYm9vbGVhbicpIHsgY29tcG9uZW50UmVmLmluc3RhbmNlLmF1dG9zdGFydCA9IG9wdGlvbnMuYXV0b3N0YXJ0OyB9XG4gICAgICBpZiAodHlwZW9mIG9wdGlvbnMudGFyZ2V0ID09PSAnc3RyaW5nJykgeyBjb21wb25lbnRSZWYuaW5zdGFuY2UudGFyZ2V0ID0gb3B0aW9ucy50YXJnZXQ7IH1cbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5hcmlhTGFiZWwgPT09ICdzdHJpbmcnKSB7IGNvbXBvbmVudFJlZi5pbnN0YW5jZS5hcmlhTGFiZWwgPSBvcHRpb25zLmFyaWFMYWJlbDsgfVxuICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLmFyaWFMYWJlbGxlZEJ5ID09PSAnc3RyaW5nJykgeyBjb21wb25lbnRSZWYuaW5zdGFuY2UuYXJpYUxhYmVsbGVkQnkgPSBvcHRpb25zLmFyaWFMYWJlbGxlZEJ5OyB9XG4gICAgICBpZiAodHlwZW9mIG9wdGlvbnMuYXJpYURlc2NyaWJlZEJ5ID09PSAnc3RyaW5nJykgeyBjb21wb25lbnRSZWYuaW5zdGFuY2UuYXJpYURlc2NyaWJlZEJ5ID0gb3B0aW9ucy5hcmlhRGVzY3JpYmVkQnk7IH1cbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5yZWZvY3VzID09PSAnYm9vbGVhbicpIHsgY29tcG9uZW50UmVmLmluc3RhbmNlLnJlZm9jdXMgPSBvcHRpb25zLnJlZm9jdXM7IH1cblxuICAgICAgY29uc3QgZG9tRWxlbSA9IChjb21wb25lbnRSZWYuaG9zdFZpZXcgYXMgRW1iZWRkZWRWaWV3UmVmPGFueT4pLnJvb3ROb2Rlc1swXSBhcyBIVE1MRWxlbWVudDtcbiAgICAgIHRoaXMuX2RvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoZG9tRWxlbSk7XG5cbiAgICAgIHJldHVybiBjb21wb25lbnRSZWYuaW5zdGFuY2U7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfYWRkRXZlbnRzKCk6IGJvb2xlYW4ge1xuICAgIGlmICghdGhpcy5pc0Jyb3dzZXIpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihOZ3hTbWFydE1vZGFsQ29uZmlnLnByZWZpeEV2ZW50ICsgJ2NyZWF0ZScsICgoZTogQ3VzdG9tRXZlbnQpID0+IHtcbiAgICAgIHRoaXMuX2luaXRNb2RhbChlLmRldGFpbC5pbnN0YW5jZSk7XG4gICAgfSkgYXMgRXZlbnRMaXN0ZW5lcik7XG5cbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihOZ3hTbWFydE1vZGFsQ29uZmlnLnByZWZpeEV2ZW50ICsgJ2RlbGV0ZScsICgoZTogQ3VzdG9tRXZlbnQpID0+IHtcbiAgICAgIHRoaXMuX2RlbGV0ZU1vZGFsKGUuZGV0YWlsLmluc3RhbmNlKTtcbiAgICB9KSBhcyBFdmVudExpc3RlbmVyKTtcblxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKE5neFNtYXJ0TW9kYWxDb25maWcucHJlZml4RXZlbnQgKyAnb3BlbicsICgoZTogQ3VzdG9tRXZlbnQpID0+IHtcbiAgICAgIHRoaXMuX29wZW5Nb2RhbChlLmRldGFpbC5pbnN0YW5jZS5tb2RhbCwgZS5kZXRhaWwuZXh0cmFEYXRhLnRvcCk7XG4gICAgfSkgYXMgRXZlbnRMaXN0ZW5lcik7XG5cbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihOZ3hTbWFydE1vZGFsQ29uZmlnLnByZWZpeEV2ZW50ICsgJ3RvZ2dsZScsICgoZTogQ3VzdG9tRXZlbnQpID0+IHtcbiAgICAgIHRoaXMuX3RvZ2dsZU1vZGFsKGUuZGV0YWlsLmluc3RhbmNlLm1vZGFsLCBlLmRldGFpbC5leHRyYURhdGEudG9wKTtcbiAgICB9KSBhcyBFdmVudExpc3RlbmVyKTtcblxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKE5neFNtYXJ0TW9kYWxDb25maWcucHJlZml4RXZlbnQgKyAnY2xvc2UnLCAoKGU6IEN1c3RvbUV2ZW50KSA9PiB7XG4gICAgICB0aGlzLl9jbG9zZU1vZGFsKGUuZGV0YWlsLmluc3RhbmNlLm1vZGFsKTtcbiAgICB9KSBhcyBFdmVudExpc3RlbmVyKTtcblxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKE5neFNtYXJ0TW9kYWxDb25maWcucHJlZml4RXZlbnQgKyAnZGlzbWlzcycsICgoZTogQ3VzdG9tRXZlbnQpID0+IHtcbiAgICAgIHRoaXMuX2Rpc21pc3NNb2RhbChlLmRldGFpbC5pbnN0YW5jZS5tb2RhbCk7XG4gICAgfSkgYXMgRXZlbnRMaXN0ZW5lcik7XG5cbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigna2V5dXAnLCB0aGlzLl9lc2NhcGVLZXlib2FyZEV2ZW50KTtcblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBfaW5pdE1vZGFsKG1vZGFsSW5zdGFuY2U6IE1vZGFsSW5zdGFuY2UpIHtcbiAgICBtb2RhbEluc3RhbmNlLm1vZGFsLmxheWVyUG9zaXRpb24gKz0gdGhpcy5nZXRNb2RhbFN0YWNrQ291bnQoKTtcbiAgICB0aGlzLmFkZE1vZGFsKG1vZGFsSW5zdGFuY2UsIG1vZGFsSW5zdGFuY2UubW9kYWwuZm9yY2UpO1xuXG4gICAgaWYgKG1vZGFsSW5zdGFuY2UubW9kYWwuYXV0b3N0YXJ0KSB7XG4gICAgICB0aGlzLm9wZW4obW9kYWxJbnN0YW5jZS5pZCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfb3Blbk1vZGFsKG1vZGFsOiBOZ3hTbWFydE1vZGFsQ29tcG9uZW50LCB0b3A/OiBib29sZWFuKTogYm9vbGVhbiB7XG4gICAgaWYgKG1vZGFsLnZpc2libGUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB0aGlzLmxhc3RFbGVtZW50Rm9jdXNlZCA9IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQ7XG5cbiAgICBpZiAobW9kYWwuZXNjYXBhYmxlKSB7XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigna2V5dXAnLCB0aGlzLl9lc2NhcGVLZXlib2FyZEV2ZW50KTtcbiAgICB9XG5cbiAgICBpZiAobW9kYWwuYmFja2Ryb3ApIHtcbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgdGhpcy5fdHJhcEZvY3VzTW9kYWwpO1xuICAgIH1cblxuICAgIGlmICh0b3ApIHtcbiAgICAgIG1vZGFsLmxheWVyUG9zaXRpb24gPSB0aGlzLmdldEhpZ2hlckluZGV4KCk7XG4gICAgfVxuXG4gICAgbW9kYWwuYWRkQm9keUNsYXNzKCk7XG4gICAgbW9kYWwub3ZlcmxheVZpc2libGUgPSB0cnVlO1xuICAgIG1vZGFsLnZpc2libGUgPSB0cnVlO1xuICAgIG1vZGFsLm9uT3Blbi5lbWl0KG1vZGFsKTtcbiAgICBtb2RhbC5tYXJrRm9yQ2hlY2soKTtcblxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgbW9kYWwub3BlbmVkQ2xhc3MgPSB0cnVlO1xuXG4gICAgICBpZiAobW9kYWwudGFyZ2V0KSB7XG4gICAgICAgIG1vZGFsLnRhcmdldFBsYWNlbWVudCgpO1xuICAgICAgfVxuXG4gICAgICBtb2RhbC5uc21EaWFsb2cuZmlyc3QubmF0aXZlRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3JvbGUnLCAnZGlhbG9nJyk7XG4gICAgICBtb2RhbC5uc21EaWFsb2cuZmlyc3QubmF0aXZlRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3RhYkluZGV4JywgJy0xJyk7XG4gICAgICBtb2RhbC5uc21EaWFsb2cuZmlyc3QubmF0aXZlRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2FyaWEtbW9kYWwnLCAndHJ1ZScpO1xuICAgICAgbW9kYWwubnNtRGlhbG9nLmZpcnN0Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcblxuICAgICAgbW9kYWwubWFya0ZvckNoZWNrKCk7XG4gICAgICBtb2RhbC5vbk9wZW5GaW5pc2hlZC5lbWl0KG1vZGFsKTtcbiAgICB9KTtcblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBfdG9nZ2xlTW9kYWwobW9kYWw6IE5neFNtYXJ0TW9kYWxDb21wb25lbnQsIHRvcD86IGJvb2xlYW4pOiBib29sZWFuIHtcbiAgICBpZiAobW9kYWwudmlzaWJsZSkge1xuICAgICAgcmV0dXJuIHRoaXMuX2Nsb3NlTW9kYWwobW9kYWwpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5fb3Blbk1vZGFsKG1vZGFsLCB0b3ApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2Nsb3NlTW9kYWwobW9kYWw6IE5neFNtYXJ0TW9kYWxDb21wb25lbnQpOiBib29sZWFuIHtcbiAgICBpZiAoIW1vZGFsLm9wZW5lZENsYXNzKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgbW9kYWwub3BlbmVkQ2xhc3MgPSBmYWxzZTtcbiAgICBtb2RhbC5vbkNsb3NlLmVtaXQobW9kYWwpO1xuICAgIG1vZGFsLm9uQW55Q2xvc2VFdmVudC5lbWl0KG1vZGFsKTtcblxuICAgIGlmICh0aGlzLmdldE9wZW5lZE1vZGFscygpLmxlbmd0aCA8IDIpIHtcbiAgICAgIG1vZGFsLnJlbW92ZUJvZHlDbGFzcygpO1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2tleXVwJywgdGhpcy5fZXNjYXBlS2V5Ym9hcmRFdmVudCk7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIHRoaXMuX3RyYXBGb2N1c01vZGFsKTtcbiAgICB9XG5cbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIG1vZGFsLnZpc2libGVDaGFuZ2UuZW1pdChtb2RhbC52aXNpYmxlKTtcbiAgICAgIG1vZGFsLnZpc2libGUgPSBmYWxzZTtcbiAgICAgIG1vZGFsLm92ZXJsYXlWaXNpYmxlID0gZmFsc2U7XG4gICAgICBtb2RhbC5uc21EaWFsb2cuZmlyc3QubmF0aXZlRWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoJ3RhYkluZGV4Jyk7XG4gICAgICBtb2RhbC5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIG1vZGFsLm9uQ2xvc2VGaW5pc2hlZC5lbWl0KG1vZGFsKTtcbiAgICAgIG1vZGFsLm9uQW55Q2xvc2VFdmVudEZpbmlzaGVkLmVtaXQobW9kYWwpO1xuICAgICAgaWYgKG1vZGFsLnJlZm9jdXMpIHtcbiAgICAgICAgdGhpcy5sYXN0RWxlbWVudEZvY3VzZWQuZm9jdXMoKTtcbiAgICAgIH1cbiAgICB9LCBtb2RhbC5oaWRlRGVsYXkpO1xuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBwcml2YXRlIF9kaXNtaXNzTW9kYWwobW9kYWw6IE5neFNtYXJ0TW9kYWxDb21wb25lbnQpOiBib29sZWFuIHtcbiAgICBpZiAoIW1vZGFsLm9wZW5lZENsYXNzKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgbW9kYWwub3BlbmVkQ2xhc3MgPSBmYWxzZTtcbiAgICBtb2RhbC5vbkRpc21pc3MuZW1pdChtb2RhbCk7XG4gICAgbW9kYWwub25BbnlDbG9zZUV2ZW50LmVtaXQobW9kYWwpO1xuXG4gICAgaWYgKHRoaXMuZ2V0T3BlbmVkTW9kYWxzKCkubGVuZ3RoIDwgMikge1xuICAgICAgbW9kYWwucmVtb3ZlQm9keUNsYXNzKCk7XG4gICAgfVxuXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBtb2RhbC52aXNpYmxlID0gZmFsc2U7XG4gICAgICBtb2RhbC52aXNpYmxlQ2hhbmdlLmVtaXQobW9kYWwudmlzaWJsZSk7XG4gICAgICBtb2RhbC5vdmVybGF5VmlzaWJsZSA9IGZhbHNlO1xuICAgICAgbW9kYWwubWFya0ZvckNoZWNrKCk7XG4gICAgICBtb2RhbC5vbkRpc21pc3NGaW5pc2hlZC5lbWl0KG1vZGFsKTtcbiAgICAgIG1vZGFsLm9uQW55Q2xvc2VFdmVudEZpbmlzaGVkLmVtaXQobW9kYWwpO1xuICAgIH0sIG1vZGFsLmhpZGVEZWxheSk7XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHByaXZhdGUgX2RlbGV0ZU1vZGFsKG1vZGFsSW5zdGFuY2U6IE1vZGFsSW5zdGFuY2UpIHtcbiAgICB0aGlzLnJlbW92ZU1vZGFsKG1vZGFsSW5zdGFuY2UuaWQpO1xuXG4gICAgaWYgKCF0aGlzLmdldE1vZGFsU3RhY2soKS5sZW5ndGgpIHtcbiAgICAgIG1vZGFsSW5zdGFuY2UubW9kYWwucmVtb3ZlQm9keUNsYXNzKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmUgY29udGVudCBhY2NvcmRpbmcgdG8gdGhlIHR5cGVzXG4gICAqIEBwYXJhbSBjb250ZW50IFRoZSBtb2RhbCBjb250ZW50IChzdHJpbmcsIHRlbXBsYXRlUmVmIG9yIENvbXBvbmVudClcbiAgICovXG4gIHByaXZhdGUgX3Jlc29sdmVOZ0NvbnRlbnQ8VD4oY29udGVudDogQ29udGVudDxUPik6IGFueVtdW10gfCBUZXh0W11bXSB7XG4gICAgaWYgKHR5cGVvZiBjb250ZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuX2RvY3VtZW50LmNyZWF0ZVRleHROb2RlKGNvbnRlbnQpO1xuICAgICAgcmV0dXJuIFtbZWxlbWVudF1dO1xuICAgIH1cblxuICAgIGlmIChjb250ZW50IGluc3RhbmNlb2YgVGVtcGxhdGVSZWYpIHtcbiAgICAgIGNvbnN0IHZpZXdSZWYgPSBjb250ZW50LmNyZWF0ZUVtYmVkZGVkVmlldyhudWxsIGFzIGFueSk7XG4gICAgICB0aGlzLl9hcHBSZWYuYXR0YWNoVmlldyh2aWV3UmVmKTtcbiAgICAgIHJldHVybiBbdmlld1JlZi5yb290Tm9kZXNdO1xuICAgIH1cblxuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbG9zZSB0aGUgbGF0ZXN0IG9wZW5lZCBtb2RhbCBpZiBlc2NhcGUga2V5IGV2ZW50IGlzIGVtaXR0ZWRcbiAgICogQHBhcmFtIGV2ZW50IFRoZSBLZXlib2FyZCBFdmVudFxuICAgKi9cbiAgcHJpdmF0ZSBfZXNjYXBlS2V5Ym9hcmRFdmVudCA9IChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4ge1xuICAgIGlmIChldmVudC5rZXkgPT09ICdFc2NhcGUnKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBtb2RhbCA9IHRoaXMuZ2V0VG9wT3BlbmVkTW9kYWwoKTtcblxuICAgICAgICBpZiAoIW1vZGFsLmVzY2FwYWJsZSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIG1vZGFsLm9uRXNjYXBlLmVtaXQobW9kYWwpO1xuICAgICAgICB0aGlzLmNsb3NlTGF0ZXN0TW9kYWwoKTtcblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJcyBjdXJyZW50IHBsYXRmb3JtIGJyb3dzZXJcbiAgICovXG4gIHByaXZhdGUgZ2V0IGlzQnJvd3NlcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gaXNQbGF0Zm9ybUJyb3dzZXIodGhpcy5fcGxhdGZvcm1JZCk7XG4gIH1cblxuICAvKipcbiAgICogV2hpbGUgbW9kYWwgaXMgb3BlbiwgdGhlIGZvY3VzIHN0YXkgb24gaXRcbiAgICogQHBhcmFtIGV2ZW50IFRoZSBLZXlib2FyIGRFdmVudFxuICAgKi9cbiAgcHJpdmF0ZSBfdHJhcEZvY3VzTW9kYWwgPSAoZXZlbnQ6IEtleWJvYXJkRXZlbnQpID0+IHtcbiAgICBpZiAoZXZlbnQua2V5ID09PSAnVGFiJykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgbW9kYWwgPSB0aGlzLmdldFRvcE9wZW5lZE1vZGFsKCk7XG5cbiAgICAgICAgaWYgKCFtb2RhbC5uc21EaWFsb2cuZmlyc3QubmF0aXZlRWxlbWVudC5jb250YWlucyhkb2N1bWVudC5hY3RpdmVFbGVtZW50KSkge1xuICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgbW9kYWwubnNtRGlhbG9nLmZpcnN0Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZSBkeW5hbWljYWxseSBjcmVhdGVkIG1vZGFsIGZyb20gRE9NXG4gICAqL1xuICBwcml2YXRlIF9kZXN0cm95TW9kYWwobW9kYWw6IE5neFNtYXJ0TW9kYWxDb21wb25lbnQpOiB2b2lkIHtcbiAgICAvLyBQcmV2ZW50IGRlc3RydWN0aW9uIG9mIHRoZSBpbmxpbmUgbW9kYWxzXG4gICAgaWYgKG1vZGFsLmNyZWF0ZUZyb20gIT09ICdzZXJ2aWNlJykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX2RvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQobW9kYWwuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50KTtcbiAgfVxufVxuIl19