UNPKG

devextreme-angular

Version:

Angular UI and visualization components based on DevExtreme widgets

292 lines 38.3 kB
/*! * devextreme-angular * Version: 25.2.3 * Build date: Fri Dec 12 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, createNgModule, inject, Injector, } 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 { DxIntegrationModule } from './integration'; 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; if (!DxIntegrationModule.initialized) { createNgModule(DxIntegrationModule, inject(Injector)); } 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vZGlzdC9jb3JlL2NvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7R0FXRztBQUVILE9BQU8sRUFDTCxhQUFhLEVBQ2IsWUFBWSxFQUNaLFNBQVMsRUFDVCxVQUFVLEVBQ1YsTUFBTSxFQUdOLFdBQVcsRUFDWCxNQUFNLEVBQ04sWUFBWSxFQVFaLGNBQWMsRUFDZCxNQUFNLEVBQ04sUUFBUSxHQUNULE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRW5ELE9BQU8sVUFBVSxNQUFNLDZCQUE2QixDQUFDO0FBQ3JELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNuRCxPQUFPLE1BQU0sTUFBTSx3QkFBd0IsQ0FBQztBQUc1QyxPQUFPLEVBQW1CLGNBQWMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxhQUFhLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNwRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFakQsT0FBTyxFQUlMLG1DQUFtQyxHQUNwQyxNQUFNLGlCQUFpQixDQUFDO0FBRXpCLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGVBQWUsQ0FBQzs7OztBQUVwRCxNQUFNLENBQUM7SUFDTCxVQUFVLEVBQUUsZ0ZBQWdGO0lBQzVGLGdCQUFnQixFQUFFLDBFQUEwRTtDQUM3RixDQUFDLENBQUM7QUFFSCxJQUFJLGNBQWMsQ0FBQztBQUNuQixNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyxHQUFHLEVBQUU7SUFDcEMsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3BCLGNBQWMsR0FBRyxZQUFZLENBQU0scUJBQXFCLENBQUMsQ0FBQztJQUM1RCxDQUFDO0lB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IjpbIi8qIVxuICogZGV2ZXh0cmVtZS1hbmd1bGFyXG4gKiBWZXJzaW9uOiAyNS4yLjNcbiAqIEJ1aWxkIGRhdGU6IEZyaSBEZWMgMTIgMjAyNVxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMiAtIDIwMjUgRGV2ZWxvcGVyIEV4cHJlc3MgSW5jLiBBTEwgUklHSFRTIFJFU0VSVkVEXG4gKlxuICogVGhpcyBzb2Z0d2FyZSBtYXkgYmUgbW9kaWZpZWQgYW5kIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtc1xuICogb2YgdGhlIE1JVCBsaWNlbnNlLiBTZWUgdGhlIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBvZiB0aGUgcHJvamVjdCBmb3IgZGV0YWlscy5cbiAqXG4gKiBodHRwczovL2dpdGh1Yi5jb20vRGV2RXhwcmVzcy9kZXZleHRyZW1lLWFuZ3VsYXJcbiAqL1xuXG5pbXBvcnQge1xyXG4gIFRyYW5zZmVyU3RhdGUsXHJcbiAgbWFrZVN0YXRlS2V5LFxyXG4gIENvbXBvbmVudCxcclxuICBFbGVtZW50UmVmLFxyXG4gIE5nWm9uZSxcclxuICBRdWVyeUxpc3QsXHJcbiAgU2ltcGxlQ2hhbmdlcyxcclxuICBQTEFURk9STV9JRCxcclxuICBJbmplY3QsXHJcbiAgRXZlbnRFbWl0dGVyLFxyXG5cclxuICBPbkNoYW5nZXMsXHJcbiAgT25Jbml0LFxyXG4gIERvQ2hlY2ssXHJcbiAgQWZ0ZXJDb250ZW50Q2hlY2tlZCxcclxuICBBZnRlclZpZXdJbml0LFxyXG4gIEFmdGVyVmlld0NoZWNrZWQsXHJcbiAgY3JlYXRlTmdNb2R1bGUsXHJcbiAgaW5qZWN0LFxyXG4gIEluamVjdG9yLFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5cclxuaW1wb3J0IHsgaXNQbGF0Zm9ybVNlcnZlciB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcblxyXG5pbXBvcnQgZG9tQWRhcHRlciBmcm9tICdkZXZleHRyZW1lL2NvcmUvZG9tX2FkYXB0ZXInO1xyXG5pbXBvcnQgeyB0cmlnZ2VySGFuZGxlciB9IGZyb20gJ2RldmV4dHJlbWUvZXZlbnRzJztcclxuaW1wb3J0IGNvbmZpZyBmcm9tICdkZXZleHRyZW1lL2NvcmUvY29uZmlnJztcclxuXHJcbmltcG9ydCB7IER4VGVtcGxhdGVEaXJlY3RpdmUgfSBmcm9tICcuL3RlbXBsYXRlJztcclxuaW1wb3J0IHsgSUR4VGVtcGxhdGVIb3N0LCBEeFRlbXBsYXRlSG9zdCB9IGZyb20gJy4vdGVtcGxhdGUtaG9zdCc7XHJcbmltcG9ydCB7IEVtaXR0ZXJIZWxwZXIsIE5nRXZlbnRzU3RyYXRlZ3kgfSBmcm9tICcuL2V2ZW50cy1zdHJhdGVneSc7XHJcbmltcG9ydCB7IFdhdGNoZXJIZWxwZXIgfSBmcm9tICcuL3dhdGNoZXItaGVscGVyJztcclxuXHJcbmltcG9ydCB7XHJcbiAgSU5lc3RlZE9wdGlvbkNvbnRhaW5lcixcclxuICBJQ29sbGVjdGlvbk5lc3RlZE9wdGlvbixcclxuICBJQ29sbGVjdGlvbk5lc3RlZE9wdGlvbkNvbnRhaW5lcixcclxuICBDb2xsZWN0aW9uTmVzdGVkT3B0aW9uQ29udGFpbmVySW1wbCxcclxufSBmcm9tICcuL25lc3RlZC1vcHRpb24nO1xyXG5cclxuaW1wb3J0IHsgRHhJbnRlZ3JhdGlvbk1vZHVsZSB9IGZyb20gJy4vaW50ZWdyYXRpb24nO1xyXG5cclxuY29uZmlnKHtcclxuICBidXlOb3dMaW5rOiAnaHR0cHM6Ly9nby5kZXZleHByZXNzLmNvbS9MaWNlbnNpbmdfSW5zdGFsbGVyX1dhdGVybWFya19EZXZFeHRyZW1lQW5ndWxhci5hc3B4JyxcclxuICBsaWNlbnNpbmdEb2NMaW5rOiAnaHR0cHM6Ly9nby5kZXZleHByZXNzLmNvbS9MaWNlbnNpbmdfRG9jdW1lbnRhdGlvbl9EZXZFeHRyZW1lQW5ndWxhci5hc3B4JyxcclxufSk7XHJcblxyXG5sZXQgc2VydmVyU3RhdGVLZXk7XHJcbmV4cG9ydCBjb25zdCBnZXRTZXJ2ZXJTdGF0ZUtleSA9ICgpID0+IHtcclxuICBpZiAoIXNlcnZlclN0YXRlS2V5KSB7XHJcbiAgICBzZXJ2ZXJTdGF0ZUtleSA9IG1ha2VTdGF0ZUtleTxhbnk+KCdEWF9pc1BsYXRmb3JtU2VydmVyJyk7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gc2VydmVyU3RhdGVLZXk7XHJcbn07XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICB0ZW1wbGF0ZTogJycsXHJcbn0pXHJcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBEeENvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgT25Jbml0LCBEb0NoZWNrLCBBZnRlckNvbnRlbnRDaGVja2VkLCBBZnRlclZpZXdJbml0LCBBZnRlclZpZXdDaGVja2VkLFxyXG4gICAgSU5lc3RlZE9wdGlvbkNvbnRhaW5lciwgSUNvbGxlY3Rpb25OZXN0ZWRPcHRpb25Db250YWluZXIsIElEeFRlbXBsYXRlSG9zdCB7XHJcbiAgcHJpdmF0ZSBfaW5pdGlhbE9wdGlvbnM6IGFueSA9IHt9O1xyXG5cclxuICBwcm90ZWN0ZWQgX29wdGlvbnNUb1VwZGF0ZTogYW55ID0ge307XHJcblxyXG4gIHByaXZhdGUgcmVhZG9ubHkgX2NvbGxlY3Rpb25Db250YWluZXJJbXBsOiBJQ29sbGVjdGlvbk5lc3RlZE9wdGlvbkNvbnRhaW5lcjtcclxuXHJcbiAgZXZlbnRIZWxwZXI6IEVtaXR0ZXJIZWxwZXI7XHJcblxyXG4gIG9wdGlvbkNoYW5nZWRIYW5kbGVyczogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XHJcblxyXG4gIHRlbXBsYXRlczogRHhUZW1wbGF0ZURpcmVjdGl2ZVtdO1xyXG5cclxuICBpbnN0YW5jZTogYW55O1xyXG5cclxuICBpc0xpbmtlZCA9IHRydWU7XHJcblxyXG4gIGNoYW5nZWRPcHRpb25zID0ge307XHJcblxyXG4gIHJlbW92ZWROZXN0ZWRDb21wb25lbnRzOiBzdHJpbmdbXSA9IFtdO1xyXG5cclxuICByZWNyZWF0ZWROZXN0ZWRDb21wb25lbnRzOiBhbnlbXTtcclxuXHJcbiAgd2lkZ2V0VXBkYXRlTG9ja2VkID0gZmFsc2U7XHJcblxyXG4gIHRlbXBsYXRlVXBkYXRlUmVxdWlyZWQgPSBmYWxzZTtcclxuXHJcbiAgcHJpdmF0ZSBfdXBkYXRlVGVtcGxhdGVzKCkge1xyXG4gICAgaWYgKHRoaXMudGVtcGxhdGVzLmxlbmd0aCAmJiB0aGlzLnRlbXBsYXRlVXBkYXRlUmVxdWlyZWQpIHtcclxuICAgICAgY29uc3QgdXBkYXRlZFRlbXBsYXRlcyA9IHt9O1xyXG4gICAgICB0aGlzLnRlbXBsYXRlcy5mb3JFYWNoKCh0ZW1wbGF0ZSkgPT4ge1xyXG4gICAgICAgIHVwZGF0ZWRUZW1wbGF0ZXNbdGVtcGxhdGUubmFtZV0gPSB0ZW1wbGF0ZTtcclxuICAgICAgfSk7XHJcbiAgICAgIHRoaXMuaW5zdGFuY2Uub3B0aW9uKCdpbnRlZ3JhdGlvbk9wdGlvbnMudGVtcGxhdGVzJywgdXBkYXRlZFRlbXBsYXRlcyk7XHJcbiAgICAgIHRoaXMudGVtcGxhdGVzID0gT2JqZWN0LnZhbHVlcyh1cGRhdGVkVGVtcGxhdGVzKTtcclxuICAgICAgdGhpcy50ZW1wbGF0ZVVwZGF0ZVJlcXVpcmVkID0gZmFsc2U7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9pbml0RXZlbnRzKCkge1xyXG4gICAgdGhpcy5pbnN0YW5jZS5vbignb3B0aW9uQ2hhbmdlZCcsIChlKSA9PiB7XHJcbiAgICAgIHRoaXMuY2hhbmdlZE9wdGlvbnNbZS5uYW1lXSA9IGUudmFsdWU7XHJcblxyXG4gICAgICBjb25zdCB2YWx1ZSA9IGUubmFtZSA9PT0gZS5mdWxsTmFtZSA/IGUudmFsdWUgOiBlLmNvbXBvbmVudC5vcHRpb24oZS5uYW1lKTtcclxuICAgICAgdGhpcy5ldmVudEhlbHBlci5maXJlTmdFdmVudChgJHtlLm5hbWV9Q2hhbmdlYCwgW3ZhbHVlXSk7XHJcbiAgICAgIHRoaXMub3B0aW9uQ2hhbmdlZEhhbmRsZXJzLmVtaXQoZSk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2luaXRPcHRpb25zKCkge1xyXG4gICAgdGhpcy5faW5pdGlhbE9wdGlvbnMuaW50ZWdyYXRpb25PcHRpb25zLndhdGNoTWV0aG9kID0gdGhpcy53YXRjaGVySGVscGVyLmdldFdhdGNoTWV0aG9kKCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9pbml0UGxhdGZvcm0oKSB7XHJcbiAgICBpZiAodGhpcy50cmFuc2ZlclN0YXRlLmhhc0tleShnZXRTZXJ2ZXJTdGF0ZUtleSgpKSkge1xyXG4gICAgICB0aGlzLl9pbml0aWFsT3B0aW9ucy5pbnRlZ3JhdGlvbk9wdGlvbnMucmVuZGVyZWRPblNlcnZlciA9IHRoaXMudHJhbnNmZXJTdGF0ZS5nZXQoZ2V0U2VydmVyU3RhdGVLZXkoKSwgbnVsbCk7XHJcbiAgICB9IGVsc2UgaWYgKGlzUGxhdGZvcm1TZXJ2ZXIodGhpcy5wbGF0Zm9ybUlkKSkge1xyXG4gICAgICB0aGlzLnRyYW5zZmVyU3RhdGUuc2V0KGdldFNlcnZlclN0YXRlS2V5KCksIHRydWUpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJvdGVjdGVkIF9jcmVhdGVFdmVudEVtaXR0ZXJzKGV2ZW50cykge1xyXG4gICAgY29uc3Qgem9uZSA9IHRoaXMubmdab25lO1xyXG4gICAgdGhpcy5ldmVudEhlbHBlci5jcmVhdGVFbWl0dGVycyhldmVudHMpO1xyXG5cclxuICAgIHRoaXMuX2luaXRpYWxPcHRpb25zLmV2ZW50c1N0cmF0ZWd5ID0gKGluc3RhbmNlKSA9PiB7XHJcbiAgICAgIGNvbnN0IHN0cmF0ZWd5ID0gbmV3IE5nRXZlbnRzU3RyYXRlZ3koaW5zdGFuY2UsIHpvbmUpO1xyXG5cclxuICAgICAgZXZlbnRzLmZpbHRlcigoZXZlbnQpID0+IGV2ZW50LnN1YnNjcmliZSkuZm9yRWFjaCgoZXZlbnQpID0+IHtcclxuICAgICAgICBzdHJhdGVneS5hZGRFbWl0dGVyKGV2ZW50LnN1YnNjcmliZSwgdGhpc1tldmVudC5lbWl0XSk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgcmV0dXJuIHN0cmF0ZWd5O1xyXG4gICAgfTtcclxuXHJcbiAgICB0aGlzLl9pbml0aWFsT3B0aW9ucy5uZXN0ZWRDb21wb25lbnRPcHRpb25zID0gZnVuY3Rpb24gKGNvbXBvbmVudCkge1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGV2ZW50c1N0cmF0ZWd5OiAoaW5zdGFuY2UpID0+IG5ldyBOZ0V2ZW50c1N0cmF0ZWd5KGluc3RhbmNlLCB6b25lKSxcclxuICAgICAgICBuZXN0ZWRDb21wb25lbnRPcHRpb25zOiBjb21wb25lbnQub3B0aW9uKCduZXN0ZWRDb21wb25lbnRPcHRpb25zJyksXHJcbiAgICAgIH07XHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgX3Nob3VsZE9wdGlvbkNoYW5nZShuYW1lOiBzdHJpbmcsIHZhbHVlOiBhbnkpIHtcclxuICAgIGlmICh0aGlzLmNoYW5nZWRPcHRpb25zLmhhc093blByb3BlcnR5KG5hbWUpKSB7XHJcbiAgICAgIGNvbnN0IHByZXZWYWx1ZSA9IHRoaXMuY2hhbmdlZE9wdGlvbnNbbmFtZV07XHJcbiAgICAgIGRlbGV0ZSB0aGlzLmNoYW5nZWRPcHRpb25zW25hbWVdO1xyXG5cclxuICAgICAgcmV0dXJuIHZhbHVlICE9PSBwcmV2VmFsdWU7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdHJ1ZTtcclxuICB9XHJcblxyXG4gIGNsZWFyQ2hhbmdlZE9wdGlvbnMoKSB7XHJcbiAgICB0aGlzLmNoYW5nZWRPcHRpb25zID0ge307XHJcbiAgfVxyXG5cclxuICBwcm90ZWN0ZWQgX2dldE9wdGlvbihuYW1lOiBzdHJpbmcpIHtcclxuICAgIHJldHVybiB0aGlzLmluc3RhbmNlXHJcbiAgICAgID8gdGhpcy5pbnN0YW5jZS5vcHRpb24obmFtZSlcclxuICAgICAgOiB0aGlzLl9pbml0aWFsT3B0aW9uc1tuYW1lXTtcclxuICB9XHJcblxyXG4gIGxvY2tXaWRnZXRVcGRhdGUoKSB7XHJcbiAgICBpZiAoIXRoaXMud2lkZ2V0VXBkYXRlTG9ja2VkICYmIHRoaXMuaW5zdGFuY2UpIHtcclxuICAgICAgdGhpcy5pbnN0YW5jZS5iZWdpblVwZGF0ZSgpO1xyXG4gICAgICB0aGlzLndpZGdldFVwZGF0ZUxvY2tlZCA9IHRydWU7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICB1bmxvY2tXaWRnZXRVcGRhdGUoKSB7XHJcbiAgICBpZiAodGhpcy53aWRnZXRVcGRhdGVMb2NrZWQpIHtcclxuICAgICAgdGhpcy53aWRnZXRVcGRhdGVMb2NrZWQgPSBmYWxzZTtcclxuICAgICAgdGhpcy5pbnN0YW5jZS5lbmRVcGRhdGUoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBfc2V0T3B0aW9uKG5hbWU6IHN0cmluZywgdmFsdWU6IGFueSkge1xyXG4gICAgdGhpcy5sb2NrV2lkZ2V0VXBkYXRlKCk7XHJcblxyXG4gICAgaWYgKCF0aGlzLl9zaG91bGRPcHRpb25DaGFuZ2UobmFtZSwgdmFsdWUpKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5pbnN0YW5jZSkge1xyXG4gICAgICB0aGlzLmluc3RhbmNlLm9wdGlvbihuYW1lLCB2YWx1ZSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLl9pbml0aWFsT3B0aW9uc1tuYW1lXSA9IHZhbHVlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJvdGVjdGVkIGFic3RyYWN0IF9jcmVhdGVJbnN0YW5jZShlbGVtZW50LCBvcHRpb25zKTtcclxuXHJcbiAgcHJvdGVjdGVkIF9jcmVhdGVXaWRnZXQoZWxlbWVudDogYW55KSB7XHJcbiAgICB0aGlzLl9pbml0aWFsT3B0aW9ucy5pbnRlZ3JhdGlvbk9wdGlvbnMgPSB7fTtcclxuICAgIHRoaXMuX2luaXRQbGF0Zm9ybSgpO1xyXG4gICAgdGhpcy5faW5pdE9wdGlvbnMoKTtcclxuXHJcbiAgICB0aGlzLl9pbml0aWFsT3B0aW9ucy5vbkluaXRpYWxpemluZyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgdGhpcy5iZWdpblVwZGF0ZSgpO1xyXG4gICAgfTtcclxuICAgIHRoaXMuaW5zdGFuY2UgPSB0aGlzLl9jcmVhdGVJbnN0YW5jZShlbGVtZW50LCB0aGlzLl9pbml0aWFsT3B0aW9ucyk7XHJcbiAgICB0aGlzLl9pbml0RXZlbnRzKCk7XHJcbiAgICB0aGlzLl9pbml0aWFsT3B0aW9ucyA9IHt9O1xyXG4gIH1cclxuXHJcbiAgcHJvdGVjdGVkIF9kZXN0cm95V2lkZ2V0KCkge1xyXG4gICAgdGhpcy5yZW1vdmVkTmVzdGVkQ29tcG9uZW50cyA9IFtdO1xyXG4gICAgaWYgKHRoaXMuaW5zdGFuY2UpIHtcclxuICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuaW5zdGFuY2UuZWxlbWVudCgpO1xyXG4gICAgICB0cmlnZ2VySGFuZGxlcihlbGVtZW50LCAnZHhyZW1vdmUnLCB7IF9hbmd1bGFySW50ZWdyYXRpb246IHRydWUgfSk7XHJcbiAgICAgIHRoaXMuaW5zdGFuY2UuZGlzcG9zZSgpO1xyXG4gICAgICBkb21BZGFwdGVyLnJlbW92ZUVsZW1lbnQoZWxlbWVudCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcm90ZWN0ZWQgX3NldENoaWxkcmVuKHByb3BlcnR5TmFtZSwgdmFsdWUsIGNsYXNzTmFtZSkge1xyXG4gICAgaWYgKHRoaXMuY2hlY2tDb250ZW50Q2hpbGRyZW4ocHJvcGVydHlOYW1lLCB2YWx1ZSwgY2xhc3NOYW1lKSkge1xyXG4gICAgICB0aGlzLnNldENvbnRlbnRDaGlsZHJlbihwcm9wZXJ0eU5hbWUsIHZhbHVlLCBjbGFzc05hbWUpO1xyXG4gICAgICB0aGlzLnNldENoaWxkcmVuKHByb3BlcnR5TmFtZSwgdmFsdWUpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcm90ZWN0ZWQgZWxlbWVudDogRWxlbWVudFJlZixcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgbmdab25lOiBOZ1pvbmUsXHJcbiAgICB0ZW1wbGF0ZUhvc3Q6IER4VGVtcGxhdGVIb3N0LFxyXG4gICAgcHJpdmF0ZSByZWFkb25seSB3YXRjaGVySGVscGVyOiBXYXRjaGVySGVscGVyLFxyXG4gICAgcHJpdmF0ZSByZWFkb25seSB0cmFuc2ZlclN0YXRlOiBUcmFuc2ZlclN0YXRlLFxyXG4gICAgQEluamVjdChQTEFURk9STV9JRCkgcHJpdmF0ZSByZWFkb25seSBwbGF0Zm9ybUlkOiBhbnksXHJcbiAgKSB7XHJcbiAgICBpZiAoIUR4SW50ZWdyYXRpb25Nb2R1bGUuaW5pdGlhbGl6ZWQpIHtcclxuICAgICAgY3JlYXRlTmdNb2R1bGUoRHhJbnRlZ3JhdGlvbk1vZHVsZSwgaW5qZWN0KEluamVjdG9yKSk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy50ZW1wbGF0ZXMgPSBbXTtcclxuICAgIHRlbXBsYXRlSG9zdC5zZXRIb3N0KHRoaXMpO1xyXG4gICAgdGhpcy5fY29sbGVjdGlvbkNvbnRhaW5lckltcGwgPSBuZXcgQ29sbGVjdGlvbk5lc3RlZE9wdGlvbkNvbnRhaW5lckltcGwodGhpcy5fc2V0T3B0aW9uLmJpbmQodGhpcykpO1xyXG4gICAgdGhpcy5ldmVudEhlbHBlciA9IG5ldyBFbWl0dGVySGVscGVyKG5nWm9uZSwgdGhpcyk7XHJcbiAgfVxyXG5cclxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XHJcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBjaGFuZ2VzKSB7XHJcbiAgICAgIGNvbnN0IGNoYW5nZSA9IGNoYW5nZXNba2V5XTtcclxuICAgICAgaWYgKGNoYW5nZS5jdXJyZW50VmFsdWUgIT09IHRoaXNba2V5XSkge1xyXG4gICAgICAgIHRoaXMuX29wdGlvbnNUb1VwZGF0ZVtrZXldID0gY2hhbmdlc1trZXldLmN1cnJlbnRWYWx1ZTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgbmdPbkluaXQoKSB7XHJcbiAgICB0aGlzLl9jcmVhdGVXaWRnZXQodGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQpO1xyXG4gIH1cclxuXHJcbiAgbmdEb0NoZWNrKCkge1xyXG4gICAgdGhpcy5hcHBseU9wdGlvbnMoKTtcclxuICB9XHJcblxyXG4gIG5nQWZ0ZXJDb250ZW50Q2hlY2tlZCgpIHtcclxuICAgIHRoaXMuYXBwbHlPcHRpb25zKCk7XHJcbiAgICB0aGlzLnJlc2V0T3B0aW9ucygpO1xyXG4gICAgdGhpcy51bmxvY2tXaWRnZXRVcGRhdGUoKTtcclxuICB9XHJcblxyXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcclxuICAgIHRoaXMuX3VwZGF0ZVRlbXBsYXRlcygpO1xyXG4gICAgdGhpcy5pbnN0YW5jZS5lbmRVcGRhdGUoKTtcclxuICAgIHRoaXMucmVjcmVhdGVkTmVzdGVkQ29tcG9uZW50cyA9IFtdO1xyXG4gIH1cclxuXHJcbiAgbmdBZnRlclZpZXdDaGVja2VkKCk6IHZvaWQge1xyXG4gICAgdGhpcy5fdXBkYXRlVGVtcGxhdGVzKCk7XHJcbiAgfVxyXG5cclxuICBhcHBseU9wdGlvbnMoKSB7XHJcbiAgICBpZiAoT2JqZWN0LmtleXModGhpcy5fb3B0aW9uc1RvVXBkYXRlKS5sZW5ndGgpIHtcclxuICAgICAgaWYgKHRoaXMuaW5zdGFuY2UpIHtcclxuICAgICAgICB0aGlzLmluc3RhbmNlLm9wdGlvbih0aGlzLl9vcHRpb25zVG9VcGRhdGUpO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuX29wdGlvbnNUb1VwZGF0ZSA9IHt9O1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcmVzZXRPcHRpb25zKGNvbGxlY3Rpb25OYW1lPzogc3RyaW5nKSB7XHJcbiAgICBpZiAodGhpcy5pbnN0YW5jZSkge1xyXG4gICAgICB0aGlzLnJlbW92ZWROZXN0ZWRDb21wb25lbnRzLmZpbHRlcigob3B0aW9uKSA9PiAob3B0aW9uXHJcbiAgICAgICAgICAgICAgICAmJiAhdGhpcy5pc1JlY3JlYXRlZChvcHRpb24pXHJcbiAgICAgICAgICAgICAgICAmJiBjb2xsZWN0aW9uTmFtZSA/IG9wdGlvbi5zdGFydHNXaXRoKGNvbGxlY3Rpb25OYW1lKSA6IHRydWUpKVxyXG4gICAgICAgIC5mb3JFYWNoKChvcHRpb24pID0+IHtcclxuICAgICAgICAgIHRoaXMuaW5zdGFuY2UucmVzZXRPcHRpb24ob3B0aW9uKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgIHRoaXMucmVtb3ZlZE5lc3RlZENvbXBvbmVudHMgPSBbXTtcclxuICAgICAgdGhpcy5yZWNyZWF0ZWROZXN0ZWRDb21wb25lbnRzID0gW107XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBpc1JlY3JlYXRlZChuYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLnJlY3JlYXRlZE5lc3RlZENvbXBvbmVudHNcclxuICAgICAgICAgICAgJiYgdGhpcy5yZWNyZWF0ZWROZXN0ZWRDb21wb25lbnRzLnNvbWUoKG5lc3RlZENvbXBvbmVudCkgPT4gbmVzdGVkQ29tcG9uZW50LmdldE9wdGlvblBhdGgoKSA9PT0gbmFtZSk7XHJcbiAgfVxyXG5cclxuICBzZXRUZW1wbGF0ZSh0ZW1wbGF0ZTogRHhUZW1wbGF0ZURpcmVjdGl2ZSkge1xyXG4gICAgdGhpcy50ZW1wbGF0ZXMucHVzaCh0ZW1wbGF0ZSk7XHJcbiAgICB0aGlzLnRlbXBsYXRlVXBkYXRlUmVxdWlyZWQgPSB0cnVlO1xyXG4gIH1cclxuXHJcbiAgY29udGVudENoaWxkcmVuID0ge307XHJcblxyXG4gIGNoZWNrQ29udGVudENoaWxkcmVuPFQ+KHByb3BlcnR5TmFtZTogc3RyaW5nLCBpdGVtczogUXVlcnlMaXN0PFQ+LCBjbGFzc05hbWU6IHN0cmluZykge1xyXG4gICAgaWYgKHRoaXMuY29udGVudENoaWxkcmVuW3Byb3BlcnR5TmFtZV0gJiYgdGhpcy5jb250ZW50Q2hpbGRyZW5bcHJvcGVydHlOYW1lXSAhPT0gY2xhc3NOYW1lKSB7XHJcbiAgICAgIGlmIChpdGVtcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgaWYgKGNvbnNvbGUgJiYgY29uc29sZS53YXJuKSB7XHJcbiAgICAgICAgICBjb25zb2xlLndhcm4oYEluICR7dGhpcy5jb25zdHJ1Y3Rvci5uYW1lfSwgXHJcbiAgICAgICAgICB0aGUgbmVzdGVkICR7Y2xhc3NOYW1lfSBhbmQgJHt0aGlzLmNvbnRlbnRDaGlsZHJlbltwcm9wZXJ0eU5hbWVdfSBjb21wb25lbnRzIGFyZSBpbmNvbXBhdGlibGUuIFxyXG4gICAgICAgICAgRW5zdXJlIHRoYXQgYWxsIG5lc3RlZCBjb21wb25lbnRzIGluIHRoZSBjb250ZW50IGFyZWEgbWF0Y2guYCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIHJldHVybiB0cnVlO1xyXG4gIH1cclxuXHJcbiAgc2V0Q29udGVudENoaWxkcmVuPFQ+KHByb3BlcnR5TmFtZTogc3RyaW5nLCBpdGVtczogUXVlcnlMaXN0PFQ+LCBjbGFzc05hbWU6IHN0cmluZykge1xyXG4gICAgaWYgKGl0ZW1zLmxlbmd0aCA+IDApIHtcclxuICAgICAgdGhpcy5jb250ZW50Q2hpbGRyZW5bcHJvcGVydHlOYW1lXSA9IGNsYXNzTmFtZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHNldENoaWxkcmVuPFQgZXh0ZW5kcyBJQ29sbGVjdGlvbk5lc3RlZE9wdGlvbj4ocHJvcGVydHlOYW1lOiBzdHJpbmcsIGl0ZW1zOiBRdWVyeUxpc3Q8VD4pIHtcclxuICAgIHRoaXMucmVzZXRPcHRpb25zKHByb3BlcnR5TmFtZSk7XHJcbiAgICByZXR1cm4gdGhpcy5fY29sbGVjdGlvbkNvbnRhaW5lckltcGwuc2V0Q2hpbGRyZW4ocHJvcGVydHlOYW1lLCBpdGVtcyk7XHJcbiAgfVxyXG59XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICB0ZW1wbGF0ZTogJycsXHJcbn0pXHJcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBEeENvbXBvbmVudEV4dGVuc2lvbiBleHRlbmRzIER4Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBBZnRlclZpZXdJbml0IHtcclxuICBjcmVhdGVJbnN0YW5jZShlbGVtZW50OiBhbnkpIHtcclxuICAgIHRoaXMuX2NyZWF0ZVdpZGdldChlbGVtZW50KTtcclxuICB9XHJcblxyXG4gIG5nT25Jbml0KCkge1xyXG4gIH1cclxuXHJcbiAgbmdBZnRlclZpZXdJbml0KCkge1xyXG4gICAgdGhpcy5fY3JlYXRlV2lkZ2V0KHRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50KTtcclxuICAgIHRoaXMuaW5zdGFuY2UuZW5kVXBkYXRlKCk7XHJcbiAgfVxyXG59XHJcbiJdfQ==