UNPKG

devextreme-angular

Version:

Angular UI and visualization components based on DevExtreme widgets

288 lines 37.5 kB
/*! * devextreme-angular * Version: 24.2.6 * Build date: Mon Mar 17 2025 * * Copyright (c) 2012 - 2025 Developer Express Inc. ALL RIGHTS RESERVED * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file in the root of the project for details. * * https://github.com/DevExpress/devextreme-angular */ import { TransferState, makeStateKey, Component, ElementRef, NgZone, PLATFORM_ID, Inject, EventEmitter, } from '@angular/core'; import { isPlatformServer } from '@angular/common'; import domAdapter from 'devextreme/core/dom_adapter'; import { triggerHandler } from 'devextreme/events'; import config from 'devextreme/core/config'; import { DxTemplateHost } from './template-host'; import { EmitterHelper, NgEventsStrategy } from './events-strategy'; import { WatcherHelper } from './watcher-helper'; import { CollectionNestedOptionContainerImpl, } from './nested-option'; import * as i0 from "@angular/core"; import * as i1 from "./template-host"; import * as i2 from "./watcher-helper"; config({ buyNowLink: 'https://go.devexpress.com/Licensing_Installer_Watermark_DevExtremeAngular.aspx', licensingDocLink: 'https://go.devexpress.com/Licensing_Documentation_DevExtremeAngular.aspx', }); let serverStateKey; export const getServerStateKey = () => { if (!serverStateKey) { serverStateKey = makeStateKey('DX_isPlatformServer'); } return serverStateKey; }; export class DxComponent { element; ngZone; watcherHelper; transferState; platformId; _initialOptions = {}; _optionsToUpdate = {}; _collectionContainerImpl; eventHelper; optionChangedHandlers = new EventEmitter(); templates; instance; isLinked = true; changedOptions = {}; removedNestedComponents = []; recreatedNestedComponents; widgetUpdateLocked = false; templateUpdateRequired = false; _updateTemplates() { if (this.templates.length && this.templateUpdateRequired) { const updatedTemplates = {}; this.templates.forEach((template) => { updatedTemplates[template.name] = template; }); this.instance.option('integrationOptions.templates', updatedTemplates); this.templates = Object.values(updatedTemplates); this.templateUpdateRequired = false; } } _initEvents() { this.instance.on('optionChanged', (e) => { this.changedOptions[e.name] = e.value; const value = e.name === e.fullName ? e.value : e.component.option(e.name); this.eventHelper.fireNgEvent(`${e.name}Change`, [value]); this.optionChangedHandlers.emit(e); }); } _initOptions() { this._initialOptions.integrationOptions.watchMethod = this.watcherHelper.getWatchMethod(); } _initPlatform() { if (this.transferState.hasKey(getServerStateKey())) { this._initialOptions.integrationOptions.renderedOnServer = this.transferState.get(getServerStateKey(), null); } else if (isPlatformServer(this.platformId)) { this.transferState.set(getServerStateKey(), true); } } _createEventEmitters(events) { const zone = this.ngZone; this.eventHelper.createEmitters(events); this._initialOptions.eventsStrategy = (instance) => { const strategy = new NgEventsStrategy(instance, zone); events.filter((event) => event.subscribe).forEach((event) => { strategy.addEmitter(event.subscribe, this[event.emit]); }); return strategy; }; this._initialOptions.nestedComponentOptions = function (component) { return { eventsStrategy: (instance) => new NgEventsStrategy(instance, zone), nestedComponentOptions: component.option('nestedComponentOptions'), }; }; } _shouldOptionChange(name, value) { if (this.changedOptions.hasOwnProperty(name)) { const prevValue = this.changedOptions[name]; delete this.changedOptions[name]; return value !== prevValue; } return true; } clearChangedOptions() { this.changedOptions = {}; } _getOption(name) { return this.instance ? this.instance.option(name) : this._initialOptions[name]; } lockWidgetUpdate() { if (!this.widgetUpdateLocked && this.instance) { this.instance.beginUpdate(); this.widgetUpdateLocked = true; } } unlockWidgetUpdate() { if (this.widgetUpdateLocked) { this.widgetUpdateLocked = false; this.instance.endUpdate(); } } _setOption(name, value) { this.lockWidgetUpdate(); if (!this._shouldOptionChange(name, value)) { return; } if (this.instance) { this.instance.option(name, value); } else { this._initialOptions[name] = value; } } _createWidget(element) { this._initialOptions.integrationOptions = {}; this._initPlatform(); this._initOptions(); this._initialOptions.onInitializing = function () { this.beginUpdate(); }; this.instance = this._createInstance(element, this._initialOptions); this._initEvents(); this._initialOptions = {}; } _destroyWidget() { this.removedNestedComponents = []; if (this.instance) { const element = this.instance.element(); triggerHandler(element, 'dxremove', { _angularIntegration: true }); this.instance.dispose(); domAdapter.removeElement(element); } } _setChildren(propertyName, value, className) { if (this.checkContentChildren(propertyName, value, className)) { this.setContentChildren(propertyName, value, className); this.setChildren(propertyName, value); } } constructor(element, ngZone, templateHost, watcherHelper, transferState, platformId) { this.element = element; this.ngZone = ngZone; this.watcherHelper = watcherHelper; this.transferState = transferState; this.platformId = platformId; this.templates = []; templateHost.setHost(this); this._collectionContainerImpl = new CollectionNestedOptionContainerImpl(this._setOption.bind(this)); this.eventHelper = new EmitterHelper(ngZone, this); } ngOnChanges(changes) { for (const key in changes) { const change = changes[key]; if (change.currentValue !== this[key]) { this._optionsToUpdate[key] = changes[key].currentValue; } } } ngOnInit() { this._createWidget(this.element.nativeElement); } ngDoCheck() { this.applyOptions(); } ngAfterContentChecked() { this.applyOptions(); this.resetOptions(); this.unlockWidgetUpdate(); } ngAfterViewInit() { this._updateTemplates(); this.instance.endUpdate(); this.recreatedNestedComponents = []; } ngAfterViewChecked() { this._updateTemplates(); } applyOptions() { if (Object.keys(this._optionsToUpdate).length) { if (this.instance) { this.instance.option(this._optionsToUpdate); } this._optionsToUpdate = {}; } } resetOptions(collectionName) { if (this.instance) { this.removedNestedComponents.filter((option) => (option && !this.isRecreated(option) && collectionName ? option.startsWith(collectionName) : true)) .forEach((option) => { this.instance.resetOption(option); }); this.removedNestedComponents = []; this.recreatedNestedComponents = []; } } isRecreated(name) { return this.recreatedNestedComponents && this.recreatedNestedComponents.some((nestedComponent) => nestedComponent.getOptionPath() === name); } setTemplate(template) { this.templates.push(template); this.templateUpdateRequired = true; } contentChildren = {}; checkContentChildren(propertyName, items, className) { if (this.contentChildren[propertyName] && this.contentChildren[propertyName] !== className) { if (items.length > 0) { if (console && console.warn) { console.warn(`In ${this.constructor.name}, the nested ${className} and ${this.contentChildren[propertyName]} components are incompatible. Ensure that all nested components in the content area match.`); } } return false; } return true; } setContentChildren(propertyName, items, className) { if (items.length > 0) { this.contentChildren[propertyName] = className; } } setChildren(propertyName, items) { this.resetOptions(propertyName); return this._collectionContainerImpl.setChildren(propertyName, items); } /** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DxComponent, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }, { token: i1.DxTemplateHost }, { token: i2.WatcherHelper }, { token: i0.TransferState }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Component }); /** @nocollapse */ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: DxComponent, selector: "ng-component", usesOnChanges: true, ngImport: i0, template: '', isInline: true }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DxComponent, decorators: [{ type: Component, args: [{ template: '', }] }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: i1.DxTemplateHost }, { type: i2.WatcherHelper }, { type: i0.TransferState }, { type: undefined, decorators: [{ type: Inject, args: [PLATFORM_ID] }] }] }); export class DxComponentExtension extends DxComponent { createInstance(element) { this._createWidget(element); } ngOnInit() { } ngAfterViewInit() { this._createWidget(this.element.nativeElement); this.instance.endUpdate(); } /** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DxComponentExtension, deps: null, target: i0.ɵɵFactoryTarget.Component }); /** @nocollapse */ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: DxComponentExtension, selector: "ng-component", usesInheritance: true, ngImport: i0, template: '', isInline: true }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DxComponentExtension, decorators: [{ type: Component, args: [{ template: '', }] }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vZGlzdC9jb3JlL2NvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7R0FXRztBQUVILE9BQU8sRUFDTCxhQUFhLEVBQ2IsWUFBWSxFQUNaLFNBQVMsRUFDVCxVQUFVLEVBQ1YsTUFBTSxFQUdOLFdBQVcsRUFDWCxNQUFNLEVBQ04sWUFBWSxHQVFiLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRW5ELE9BQU8sVUFBVSxNQUFNLDZCQUE2QixDQUFDO0FBQ3JELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNuRCxPQUFPLE1BQU0sTUFBTSx3QkFBd0IsQ0FBQztBQUc1QyxPQUFPLEVBQW1CLGNBQWMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxhQUFhLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNwRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFakQsT0FBTyxFQUlMLG1DQUFtQyxHQUNwQyxNQUFNLGlCQUFpQixDQUFDOzs7O0FBRXpCLE1BQU0sQ0FBQztJQUNMLFVBQVUsRUFBRSxnRkFBZ0Y7SUFDNUYsZ0JBQWdCLEVBQUUsMEVBQTBFO0NBQzdGLENBQUMsQ0FBQztBQUVILElBQUksY0FBYyxDQUFDO0FBQ25CLE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFHLEdBQUcsRUFBRTtJQUNwQyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDcEIsY0FBYyxHQUFHLFlBQVksQ0FBTSxxQkFBcUIsQ0FBQyxDQUFDO0lBQzVELENBQUM7SUFFRCxPQUFPLGNBQWMsQ0FBQztBQUN4QixDQUFDLENBQUM7QUFLRixNQUFNLE9BQWdCLFdBQVc7SUFxS25CO0lBQ087SUFFQTtJ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SUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZLENBQUMsR0FBRyxTQUFTLENBQUM7UUFDakQsQ0FBQztJQUNILENBQUM7SUFFRCxXQUFXLENBQW9DLFlBQW9CLEVBQUUsS0FBbUI7UUFDdEYsSUFBSSxDQUFDLFlBQVksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNoQyxPQUFPLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxXQUFXLENBQUMsWUFBWSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ3hFLENBQUM7MkhBN1FtQixXQUFXLDBKQTBLckIsV0FBVzsrR0ExS0QsV0FBVyx5RUFGckIsRUFBRTs7NEZBRVEsV0FBVztrQkFIaEMsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsRUFBRTtpQkFDYjs7MEJBMktJLE1BQU07MkJBQUMsV0FBVzs7QUF5R3ZCLE1BQU0sT0FBZ0Isb0JBQXFCLFNBQVEsV0FBVztJQUM1RCxjQUFjLENBQUMsT0FBWTtRQUN6QixJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzlCLENBQUM7SUFFRCxRQUFRO0lBQ1IsQ0FBQztJQUVELGVBQWU7UUFDYixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDL0MsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLEVBQUUsQ0FBQztJQUM1QixDQUFDOzJIQVhtQixvQkFBb0I7K0dBQXBCLG9CQUFvQiwyRUFGOUIsRUFBRTs7NEZBRVEsb0JBQW9CO2tCQUh6QyxTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxFQUFFO2lCQUNiIiwic291cmNlc0NvbnRlbnQiOlsiLyohXG4gKiBkZXZleHRyZW1lLWFuZ3VsYXJcbiAqIFZlcnNpb246IDI0LjIuNlxuICogQnVpbGQgZGF0ZTogTW9uIE1hciAxNyAyMDI1XG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDEyIC0gMjAyNSBEZXZlbG9wZXIgRXhwcmVzcyBJbmMuIEFMTCBSSUdIVFMgUkVTRVJWRURcbiAqXG4gKiBUaGlzIHNvZnR3YXJlIG1heSBiZSBtb2RpZmllZCBhbmQgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIHRlcm1zXG4gKiBvZiB0aGUgTUlUIGxpY2Vuc2UuIFNlZSB0aGUgTElDRU5TRSBmaWxlIGluIHRoZSByb290IG9mIHRoZSBwcm9qZWN0IGZvciBkZXRhaWxzLlxuICpcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9EZXZFeHByZXNzL2RldmV4dHJlbWUtYW5ndWxhclxuICovXG5cbmltcG9ydCB7XHJcbiAgVHJhbnNmZXJTdGF0ZSxcclxuICBtYWtlU3RhdGVLZXksXHJcbiAgQ29tcG9uZW50LFxyXG4gIEVsZW1lbnRSZWYsXHJcbiAgTmdab25lLFxyXG4gIFF1ZXJ5TGlzdCxcclxuICBTaW1wbGVDaGFuZ2VzLFxyXG4gIFBMQVRGT1JNX0lELFxyXG4gIEluamVjdCxcclxuICBFdmVudEVtaXR0ZXIsXHJcblxyXG4gIE9uQ2hhbmdlcyxcclxuICBPbkluaXQsXHJcbiAgRG9DaGVjayxcclxuICBBZnRlckNvbnRlbnRDaGVja2VkLFxyXG4gIEFmdGVyVmlld0luaXQsXHJcbiAgQWZ0ZXJWaWV3Q2hlY2tlZCxcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuXHJcbmltcG9ydCB7IGlzUGxhdGZvcm1TZXJ2ZXIgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5cclxuaW1wb3J0IGRvbUFkYXB0ZXIgZnJvbSAnZGV2ZXh0cmVtZS9jb3JlL2RvbV9hZGFwdGVyJztcclxuaW1wb3J0IHsgdHJpZ2dlckhhbmRsZXIgfSBmcm9tICdkZXZleHRyZW1lL2V2ZW50cyc7XHJcbmltcG9ydCBjb25maWcgZnJvbSAnZGV2ZXh0cmVtZS9jb3JlL2NvbmZpZyc7XHJcblxyXG5pbXBvcnQgeyBEeFRlbXBsYXRlRGlyZWN0aXZlIH0gZnJvbSAnLi90ZW1wbGF0ZSc7XHJcbmltcG9ydCB7IElEeFRlbXBsYXRlSG9zdCwgRHhUZW1wbGF0ZUhvc3QgfSBmcm9tICcuL3RlbXBsYXRlLWhvc3QnO1xyXG5pbXBvcnQgeyBFbWl0dGVySGVscGVyLCBOZ0V2ZW50c1N0cmF0ZWd5IH0gZnJvbSAnLi9ldmVudHMtc3RyYXRlZ3knO1xyXG5pbXBvcnQgeyBXYXRjaGVySGVscGVyIH0gZnJvbSAnLi93YXRjaGVyLWhlbHBlcic7XHJcblxyXG5pbXBvcnQge1xyXG4gIElOZXN0ZWRPcHRpb25Db250YWluZXIsXHJcbiAgSUNvbGxlY3Rpb25OZXN0ZWRPcHRpb24sXHJcbiAgSUNvbGxlY3Rpb25OZXN0ZWRPcHRpb25Db250YWluZXIsXHJcbiAgQ29sbGVjdGlvbk5lc3RlZE9wdGlvbkNvbnRhaW5lckltcGwsXHJcbn0gZnJvbSAnLi9uZXN0ZWQtb3B0aW9uJztcclxuXHJcbmNvbmZpZyh7XHJcbiAgYnV5Tm93TGluazogJ2h0dHBzOi8vZ28uZGV2ZXhwcmVzcy5jb20vTGljZW5zaW5nX0luc3RhbGxlcl9XYXRlcm1hcmtfRGV2RXh0cmVtZUFuZ3VsYXIuYXNweCcsXHJcbiAgbGljZW5zaW5nRG9jTGluazogJ2h0dHBzOi8vZ28uZGV2ZXhwcmVzcy5jb20vTGljZW5zaW5nX0RvY3VtZW50YXRpb25fRGV2RXh0cmVtZUFuZ3VsYXIuYXNweCcsXHJcbn0pO1xyXG5cclxubGV0IHNlcnZlclN0YXRlS2V5O1xyXG5leHBvcnQgY29uc3QgZ2V0U2VydmVyU3RhdGVLZXkgPSAoKSA9PiB7XHJcbiAgaWYgKCFzZXJ2ZXJTdGF0ZUtleSkge1xyXG4gICAgc2VydmVyU3RhdGVLZXkgPSBtYWtlU3RhdGVLZXk8YW55PignRFhfaXNQbGF0Zm9ybVNlcnZlcicpO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIHNlcnZlclN0YXRlS2V5O1xyXG59O1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgdGVtcGxhdGU6ICcnLFxyXG59KVxyXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgRHhDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMsIE9uSW5pdCwgRG9DaGVjaywgQWZ0ZXJDb250ZW50Q2hlY2tlZCwgQWZ0ZXJWaWV3SW5pdCwgQWZ0ZXJWaWV3Q2hlY2tlZCxcclxuICAgIElOZXN0ZWRPcHRpb25Db250YWluZXIsIElDb2xsZWN0aW9uTmVzdGVkT3B0aW9uQ29udGFpbmVyLCBJRHhUZW1wbGF0ZUhvc3Qge1xyXG4gIHByaXZhdGUgX2luaXRpYWxPcHRpb25zOiBhbnkgPSB7fTtcclxuXHJcbiAgcHJvdGVjdGVkIF9vcHRpb25zVG9VcGRhdGU6IGFueSA9IHt9O1xyXG5cclxuICBwcml2YXRlIHJlYWRvbmx5IF9jb2xsZWN0aW9uQ29udGFpbmVySW1wbDogSUNvbGxlY3Rpb25OZXN0ZWRPcHRpb25Db250YWluZXI7XHJcblxyXG4gIGV2ZW50SGVscGVyOiBFbWl0dGVySGVscGVyO1xyXG5cclxuICBvcHRpb25DaGFuZ2VkSGFuZGxlcnM6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xyXG5cclxuICB0ZW1wbGF0ZXM6IER4VGVtcGxhdGVEaXJlY3RpdmVbXTtcclxuXHJcbiAgaW5zdGFuY2U6IGFueTtcclxuXHJcbiAgaXNMaW5rZWQgPSB0cnVlO1xyXG5cclxuICBjaGFuZ2VkT3B0aW9ucyA9IHt9O1xyXG5cclxuICByZW1vdmVkTmVzdGVkQ29tcG9uZW50czogc3RyaW5nW10gPSBbXTtcclxuXHJcbiAgcmVjcmVhdGVkTmVzdGVkQ29tcG9uZW50czogYW55W107XHJcblxyXG4gIHdpZGdldFVwZGF0ZUxvY2tlZCA9IGZhbHNlO1xyXG5cclxuICB0ZW1wbGF0ZVVwZGF0ZVJlcXVpcmVkID0gZmFsc2U7XHJcblxyXG4gIHByaXZhdGUgX3VwZGF0ZVRlbXBsYXRlcygpIHtcclxuICAgIGlmICh0aGlzLnRlbXBsYXRlcy5sZW5ndGggJiYgdGhpcy50ZW1wbGF0ZVVwZGF0ZVJlcXVpcmVkKSB7XHJcbiAgICAgIGNvbnN0IHVwZGF0ZWRUZW1wbGF0ZXMgPSB7fTtcclxuICAgICAgdGhpcy50ZW1wbGF0ZXMuZm9yRWFjaCgodGVtcGxhdGUpID0+IHtcclxuICAgICAgICB1cGRhdGVkVGVtcGxhdGVzW3RlbXBsYXRlLm5hbWVdID0gdGVtcGxhdGU7XHJcbiAgICAgIH0pO1xyXG4gICAgICB0aGlzLmluc3RhbmNlLm9wdGlvbignaW50ZWdyYXRpb25PcHRpb25zLnRlbXBsYXRlcycsIHVwZGF0ZWRUZW1wbGF0ZXMpO1xyXG4gICAgICB0aGlzLnRlbXBsYXRlcyA9IE9iamVjdC52YWx1ZXModXBkYXRlZFRlbXBsYXRlcyk7XHJcbiAgICAgIHRoaXMudGVtcGxhdGVVcGRhdGVSZXF1aXJlZCA9IGZhbHNlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfaW5pdEV2ZW50cygpIHtcclxuICAgIHRoaXMuaW5zdGFuY2Uub24oJ29wdGlvbkNoYW5nZWQnLCAoZSkgPT4ge1xyXG4gICAgICB0aGlzLmNoYW5nZWRPcHRpb25zW2UubmFtZV0gPSBlLnZhbHVlO1xyXG5cclxuICAgICAgY29uc3QgdmFsdWUgPSBlLm5hbWUgPT09IGUuZnVsbE5hbWUgPyBlLnZhbHVlIDogZS5jb21wb25lbnQub3B0aW9uKGUubmFtZSk7XHJcbiAgICAgIHRoaXMuZXZlbnRIZWxwZXIuZmlyZU5nRXZlbnQoYCR7ZS5uYW1lfUNoYW5nZWAsIFt2YWx1ZV0pO1xyXG4gICAgICB0aGlzLm9wdGlvbkNoYW5nZWRIYW5kbGVycy5lbWl0KGUpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9pbml0T3B0aW9ucygpIHtcclxuICAgIHRoaXMuX2luaXRpYWxPcHRpb25zLmludGVncmF0aW9uT3B0aW9ucy53YXRjaE1ldGhvZCA9IHRoaXMud2F0Y2hlckhlbHBlci5nZXRXYXRjaE1ldGhvZCgpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfaW5pdFBsYXRmb3JtKCkge1xyXG4gICAgaWYgKHRoaXMudHJhbnNmZXJTdGF0ZS5oYXNLZXkoZ2V0U2VydmVyU3RhdGVLZXkoKSkpIHtcclxuICAgICAgdGhpcy5faW5pdGlhbE9wdGlvbnMuaW50ZWdyYXRpb25PcHRpb25zLnJlbmRlcmVkT25TZXJ2ZXIgPSB0aGlzLnRyYW5zZmVyU3RhdGUuZ2V0KGdldFNlcnZlclN0YXRlS2V5KCksIG51bGwpO1xyXG4gICAgfSBlbHNlIGlmIChpc1BsYXRmb3JtU2VydmVyKHRoaXMucGxhdGZvcm1JZCkpIHtcclxuICAgICAgdGhpcy50cmFuc2ZlclN0YXRlLnNldChnZXRTZXJ2ZXJTdGF0ZUtleSgpLCB0cnVlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBfY3JlYXRlRXZlbnRFbWl0dGVycyhldmVudHMpIHtcclxuICAgIGNvbnN0IHpvbmUgPSB0aGlzLm5nWm9uZTtcclxuICAgIHRoaXMuZXZlbnRIZWxwZXIuY3JlYXRlRW1pdHRlcnMoZXZlbnRzKTtcclxuXHJcbiAgICB0aGlzLl9pbml0aWFsT3B0aW9ucy5ldmVudHNTdHJhdGVneSA9IChpbnN0YW5jZSkgPT4ge1xyXG4gICAgICBjb25zdCBzdHJhdGVneSA9IG5ldyBOZ0V2ZW50c1N0cmF0ZWd5KGluc3RhbmNlLCB6b25lKTtcclxuXHJcbiAgICAgIGV2ZW50cy5maWx0ZXIoKGV2ZW50KSA9PiBldmVudC5zdWJzY3JpYmUpLmZvckVhY2goKGV2ZW50KSA9PiB7XHJcbiAgICAgICAgc3RyYXRlZ3kuYWRkRW1pdHRlcihldmVudC5zdWJzY3JpYmUsIHRoaXNbZXZlbnQuZW1pdF0pO1xyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIHJldHVybiBzdHJhdGVneTtcclxuICAgIH07XHJcblxyXG4gICAgdGhpcy5faW5pdGlhbE9wdGlvbnMubmVzdGVkQ29tcG9uZW50T3B0aW9ucyA9IGZ1bmN0aW9uIChjb21wb25lbnQpIHtcclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBldmVudHNTdHJhdGVneTogKGluc3RhbmNlKSA9PiBuZXcgTmdFdmVudHNTdHJhdGVneShpbnN0YW5jZSwgem9uZSksXHJcbiAgICAgICAgbmVzdGVkQ29tcG9uZW50T3B0aW9uczogY29tcG9uZW50Lm9wdGlvbignbmVzdGVkQ29tcG9uZW50T3B0aW9ucycpLFxyXG4gICAgICB9O1xyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIF9zaG91bGRPcHRpb25DaGFuZ2UobmFtZTogc3RyaW5nLCB2YWx1ZTogYW55KSB7XHJcbiAgICBpZiAodGhpcy5jaGFuZ2VkT3B0aW9ucy5oYXNPd25Qcm9wZXJ0eShuYW1lKSkge1xyXG4gICAgICBjb25zdCBwcmV2VmFsdWUgPSB0aGlzLmNoYW5nZWRPcHRpb25zW25hbWVdO1xyXG4gICAgICBkZWxldGUgdGhpcy5jaGFuZ2VkT3B0aW9uc1tuYW1lXTtcclxuXHJcbiAgICAgIHJldHVybiB2YWx1ZSAhPT0gcHJldlZhbHVlO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRydWU7XHJcbiAgfVxyXG5cclxuICBjbGVhckNoYW5nZWRPcHRpb25zKCkge1xyXG4gICAgdGhpcy5jaGFuZ2VkT3B0aW9ucyA9IHt9O1xyXG4gIH1cclxuXHJcbiAgcHJvdGVjdGVkIF9nZXRPcHRpb24obmFtZTogc3RyaW5nKSB7XHJcbiAgICByZXR1cm4gdGhpcy5pbnN0YW5jZVxyXG4gICAgICA/IHRoaXMuaW5zdGFuY2Uub3B0aW9uKG5hbWUpXHJcbiAgICAgIDogdGhpcy5faW5pdGlhbE9wdGlvbnNbbmFtZV07XHJcbiAgfVxyXG5cclxuICBsb2NrV2lkZ2V0VXBkYXRlKCkge1xyXG4gICAgaWYgKCF0aGlzLndpZGdldFVwZGF0ZUxvY2tlZCAmJiB0aGlzLmluc3RhbmNlKSB7XHJcbiAgICAgIHRoaXMuaW5zdGFuY2UuYmVnaW5VcGRhdGUoKTtcclxuICAgICAgdGhpcy53aWRnZXRVcGRhdGVMb2NrZWQgPSB0cnVlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgdW5sb2NrV2lkZ2V0VXBkYXRlKCkge1xyXG4gICAgaWYgKHRoaXMud2lkZ2V0VXBkYXRlTG9ja2VkKSB7XHJcbiAgICAgIHRoaXMud2lkZ2V0VXBkYXRlTG9ja2VkID0gZmFsc2U7XHJcbiAgICAgIHRoaXMuaW5zdGFuY2UuZW5kVXBkYXRlKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcm90ZWN0ZWQgX3NldE9wdGlvbihuYW1lOiBzdHJpbmcsIHZhbHVlOiBhbnkpIHtcclxuICAgIHRoaXMubG9ja1dpZGdldFVwZGF0ZSgpO1xyXG5cclxuICAgIGlmICghdGhpcy5fc2hvdWxkT3B0aW9uQ2hhbmdlKG5hbWUsIHZhbHVlKSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuaW5zdGFuY2UpIHtcclxuICAgICAgdGhpcy5pbnN0YW5jZS5vcHRpb24obmFtZSwgdmFsdWUpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5faW5pdGlhbE9wdGlvbnNbbmFtZV0gPSB2YWx1ZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBfY3JlYXRlSW5zdGFuY2UoZWxlbWVudCwgb3B0aW9ucyk7XHJcblxyXG4gIHByb3RlY3RlZCBfY3JlYXRlV2lkZ2V0KGVsZW1lbnQ6IGFueSkge1xyXG4gICAgdGhpcy5faW5pdGlhbE9wdGlvbnMuaW50ZWdyYXRpb25PcHRpb25zID0ge307XHJcbiAgICB0aGlzLl9pbml0UGxhdGZvcm0oKTtcclxuICAgIHRoaXMuX2luaXRPcHRpb25zKCk7XHJcblxyXG4gICAgdGhpcy5faW5pdGlhbE9wdGlvbnMub25Jbml0aWFsaXppbmcgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHRoaXMuYmVnaW5VcGRhdGUoKTtcclxuICAgIH07XHJcbiAgICB0aGlzLmluc3RhbmNlID0gdGhpcy5fY3JlYXRlSW5zdGFuY2UoZWxlbWVudCwgdGhpcy5faW5pdGlhbE9wdGlvbnMpO1xyXG4gICAgdGhpcy5faW5pdEV2ZW50cygpO1xyXG4gICAgdGhpcy5faW5pdGlhbE9wdGlvbnMgPSB7fTtcclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBfZGVzdHJveVdpZGdldCgpIHtcclxuICAgIHRoaXMucmVtb3ZlZE5lc3RlZENvbXBvbmVudHMgPSBbXTtcclxuICAgIGlmICh0aGlzLmluc3RhbmNlKSB7XHJcbiAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmluc3RhbmNlLmVsZW1lbnQoKTtcclxuICAgICAgdHJpZ2dlckhhbmRsZXIoZWxlbWVudCwgJ2R4cmVtb3ZlJywgeyBfYW5ndWxhckludGVncmF0aW9uOiB0cnVlIH0pO1xyXG4gICAgICB0aGlzLmluc3RhbmNlLmRpc3Bvc2UoKTtcclxuICAgICAgZG9tQWRhcHRlci5yZW1vdmVFbGVtZW50KGVsZW1lbnQpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJvdGVjdGVkIF9zZXRDaGlsZHJlbihwcm9wZXJ0eU5hbWUsIHZhbHVlLCBjbGFzc05hbWUpIHtcclxuICAgIGlmICh0aGlzLmNoZWNrQ29udGVudENoaWxkcmVuKHByb3BlcnR5TmFtZSwgdmFsdWUsIGNsYXNzTmFtZSkpIHtcclxuICAgICAgdGhpcy5zZXRDb250ZW50Q2hpbGRyZW4ocHJvcGVydHlOYW1lLCB2YWx1ZSwgY2xhc3NOYW1lKTtcclxuICAgICAgdGhpcy5zZXRDaGlsZHJlbihwcm9wZXJ0eU5hbWUsIHZhbHVlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHJvdGVjdGVkIGVsZW1lbnQ6IEVsZW1lbnRSZWYsXHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IG5nWm9uZTogTmdab25lLFxyXG4gICAgdGVtcGxhdGVIb3N0OiBEeFRlbXBsYXRlSG9zdCxcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgd2F0Y2hlckhlbHBlcjogV2F0Y2hlckhlbHBlcixcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgdHJhbnNmZXJTdGF0ZTogVHJhbnNmZXJTdGF0ZSxcclxuICAgIEBJbmplY3QoUExBVEZPUk1fSUQpIHByaXZhdGUgcmVhZG9ubHkgcGxhdGZvcm1JZDogYW55LFxyXG4gICkge1xyXG4gICAgdGhpcy50ZW1wbGF0ZXMgPSBbXTtcclxuICAgIHRlbXBsYXRlSG9zdC5zZXRIb3N0KHRoaXMpO1xyXG4gICAgdGhpcy5fY29sbGVjdGlvbkNvbnRhaW5lckltcGwgPSBuZXcgQ29sbGVjdGlvbk5lc3RlZE9wdGlvbkNvbnRhaW5lckltcGwodGhpcy5fc2V0T3B0aW9uLmJpbmQodGhpcykpO1xyXG4gICAgdGhpcy5ldmVudEhlbHBlciA9IG5ldyBFbWl0dGVySGVscGVyKG5nWm9uZSwgdGhpcyk7XHJcbiAgfVxyXG5cclxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XHJcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBjaGFuZ2VzKSB7XHJcbiAgICAgIGNvbnN0IGNoYW5nZSA9IGNoYW5nZXNba2V5XTtcclxuICAgICAgaWYgKGNoYW5nZS5jdXJyZW50VmFsdWUgIT09IHRoaXNba2V5XSkge1xyXG4gICAgICAgIHRoaXMuX29wdGlvbnNUb1VwZGF0ZVtrZXldID0gY2hhbmdlc1trZXldLmN1cnJlbnRWYWx1ZTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgbmdPbkluaXQoKSB7XHJcbiAgICB0aGlzLl9jcmVhdGVXaWRnZXQodGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQpO1xyXG4gIH1cclxuXHJcbiAgbmdEb0NoZWNrKCkge1xyXG4gICAgdGhpcy5hcHBseU9wdGlvbnMoKTtcclxuICB9XHJcblxyXG4gIG5nQWZ0ZXJDb250ZW50Q2hlY2tlZCgpIHtcclxuICAgIHRoaXMuYXBwbHlPcHRpb25zKCk7XHJcbiAgICB0aGlzLnJlc2V0T3B0aW9ucygpO1xyXG4gICAgdGhpcy51bmxvY2tXaWRnZXRVcGRhdGUoKTtcclxuICB9XHJcblxyXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcclxuICAgIHRoaXMuX3VwZGF0ZVRlbXBsYXRlcygpO1xyXG4gICAgdGhpcy5pbnN0YW5jZS5lbmRVcGRhdGUoKTtcclxuICAgIHRoaXMucmVjcmVhdGVkTmVzdGVkQ29tcG9uZW50cyA9IFtdO1xyXG4gIH1cclxuXHJcbiAgbmdBZnRlclZpZXdDaGVja2VkKCk6IHZvaWQge1xyXG4gICAgdGhpcy5fdXBkYXRlVGVtcGxhdGVzKCk7XHJcbiAgfVxyXG5cclxuICBhcHBseU9wdGlvbnMoKSB7XHJcbiAgICBpZiAoT2JqZWN0LmtleXModGhpcy5fb3B0aW9uc1RvVXBkYXRlKS5sZW5ndGgpIHtcclxuICAgICAgaWYgKHRoaXMuaW5zdGFuY2UpIHtcclxuICAgICAgICB0aGlzLmluc3RhbmNlLm9wdGlvbih0aGlzLl9vcHRpb25zVG9VcGRhdGUpO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuX29wdGlvbnNUb1VwZGF0ZSA9IHt9O1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcmVzZXRPcHRpb25zKGNvbGxlY3Rpb25OYW1lPzogc3RyaW5nKSB7XHJcbiAgICBpZiAodGhpcy5pbnN0YW5jZSkge1xyXG4gICAgICB0aGlzLnJlbW92ZWROZXN0ZWRDb21wb25lbnRzLmZpbHRlcigob3B0aW9uKSA9PiAob3B0aW9uXHJcbiAgICAgICAgICAgICAgICAmJiAhdGhpcy5pc1JlY3JlYXRlZChvcHRpb24pXHJcbiAgICAgICAgICAgICAgICAmJiBjb2xsZWN0aW9uTmFtZSA/IG9wdGlvbi5zdGFydHNXaXRoKGNvbGxlY3Rpb25OYW1lKSA6IHRydWUpKVxyXG4gICAgICAgIC5mb3JFYWNoKChvcHRpb24pID0+IHtcclxuICAgICAgICAgIHRoaXMuaW5zdGFuY2UucmVzZXRPcHRpb24ob3B0aW9uKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgIHRoaXMucmVtb3ZlZE5lc3RlZENvbXBvbmVudHMgPSBbXTtcclxuICAgICAgdGhpcy5yZWNyZWF0ZWROZXN0ZWRDb21wb25lbnRzID0gW107XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBpc1JlY3JlYXRlZChuYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLnJlY3JlYXRlZE5lc3RlZENvbXBvbmVudHNcclxuICAgICAgICAgICAgJiYgdGhpcy5yZWNyZWF0ZWROZXN0ZWRDb21wb25lbnRzLnNvbWUoKG5lc3RlZENvbXBvbmVudCkgPT4gbmVzdGVkQ29tcG9uZW50LmdldE9wdGlvblBhdGgoKSA9PT0gbmFtZSk7XHJcbiAgfVxyXG5cclxuICBzZXRUZW1wbGF0ZSh0ZW1wbGF0ZTogRHhUZW1wbGF0ZURpcmVjdGl2ZSkge1xyXG4gICAgdGhpcy50ZW1wbGF0ZXMucHVzaCh0ZW1wbGF0ZSk7XHJcbiAgICB0aGlzLnRlbXBsYXRlVXBkYXRlUmVxdWlyZWQgPSB0cnVlO1xyXG4gIH1cclxuXHJcbiAgY29udGVudENoaWxkcmVuID0ge307XHJcblxyXG4gIGNoZWNrQ29udGVudENoaWxkcmVuPFQ+KHByb3BlcnR5TmFtZTogc3RyaW5nLCBpdGVtczogUXVlcnlMaXN0PFQ+LCBjbGFzc05hbWU6IHN0cmluZykge1xyXG4gICAgaWYgKHRoaXMuY29udGVudENoaWxkcmVuW3Byb3BlcnR5TmFtZV0gJiYgdGhpcy5jb250ZW50Q2hpbGRyZW5bcHJvcGVydHlOYW1lXSAhPT0gY2xhc3NOYW1lKSB7XHJcbiAgICAgIGlmIChpdGVtcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgaWYgKGNvbnNvbGUgJiYgY29uc29sZS53YXJuKSB7XHJcbiAgICAgICAgICBjb25zb2xlLndhcm4oYEluICR7dGhpcy5jb25zdHJ1Y3Rvci5uYW1lfSwgXHJcbiAgICAgICAgICB0aGUgbmVzdGVkICR7Y2xhc3NOYW1lfSBhbmQgJHt0aGlzLmNvbnRlbnRDaGlsZHJlbltwcm9wZXJ0eU5hbWVdfSBjb21wb25lbnRzIGFyZSBpbmNvbXBhdGlibGUuIFxyXG4gICAgICAgICAgRW5zdXJlIHRoYXQgYWxsIG5lc3RlZCBjb21wb25lbnRzIGluIHRoZSBjb250ZW50IGFyZWEgbWF0Y2guYCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIHJldHVybiB0cnVlO1xyXG4gIH1cclxuXHJcbiAgc2V0Q29udGVudENoaWxkcmVuPFQ+KHByb3BlcnR5TmFtZTogc3RyaW5nLCBpdGVtczogUXVlcnlMaXN0PFQ+LCBjbGFzc05hbWU6IHN0cmluZykge1xyXG4gICAgaWYgKGl0ZW1zLmxlbmd0aCA+IDApIHtcclxuICAgICAgdGhpcy5jb250ZW50Q2hpbGRyZW5bcHJvcGVydHlOYW1lXSA9IGNsYXNzTmFtZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHNldENoaWxkcmVuPFQgZXh0ZW5kcyBJQ29sbGVjdGlvbk5lc3RlZE9wdGlvbj4ocHJvcGVydHlOYW1lOiBzdHJpbmcsIGl0ZW1zOiBRdWVyeUxpc3Q8VD4pIHtcclxuICAgIHRoaXMucmVzZXRPcHRpb25zKHByb3BlcnR5TmFtZSk7XHJcbiAgICByZXR1cm4gdGhpcy5fY29sbGVjdGlvbkNvbnRhaW5lckltcGwuc2V0Q2hpbGRyZW4ocHJvcGVydHlOYW1lLCBpdGVtcyk7XHJcbiAgfVxyXG59XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICB0ZW1wbGF0ZTogJycsXHJcbn0pXHJcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBEeENvbXBvbmVudEV4dGVuc2lvbiBleHRlbmRzIER4Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBBZnRlclZpZXdJbml0IHtcclxuICBjcmVhdGVJbnN0YW5jZShlbGVtZW50OiBhbnkpIHtcclxuICAgIHRoaXMuX2NyZWF0ZVdpZGdldChlbGVtZW50KTtcclxuICB9XHJcblxyXG4gIG5nT25Jbml0KCkge1xyXG4gIH1cclxuXHJcbiAgbmdBZnRlclZpZXdJbml0KCkge1xyXG4gICAgdGhpcy5fY3JlYXRlV2lkZ2V0KHRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50KTtcclxuICAgIHRoaXMuaW5zdGFuY2UuZW5kVXBkYXRlKCk7XHJcbiAgfVxyXG59XHJcbiJdfQ==