UNPKG

@nova-ui/dashboards

Version:

Nova Dashboards is a framework designed to provide feature developers with a common solution for presenting data coming from various sources within a single view, as well as a set of predefined widget visualizations that are 100% configuration-driven and

146 lines 25.7 kB
// © 2022 SolarWinds Worldwide, LLC. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, ViewChild, } from "@angular/core"; import { FormBuilder } from "@angular/forms"; import get from "lodash/get"; import { BehaviorSubject, Subject } from "rxjs"; import { takeUntil } from "rxjs/operators"; import { PizzagnaComponent } from "../../../pizzagna/components/pizzagna/pizzagna.component"; import { PREVIEW_EVENT } from "../../../services/types"; import { PizzagnaLayer, } from "../../../types"; import { PreviewService } from "../../services/preview.service"; import { ConfiguratorComponent } from "../configurator/configurator.component"; import * as i0 from "@angular/core"; import * as i1 from "@angular/forms"; import * as i2 from "../../services/preview.service"; import * as i3 from "../configurator/configurator.component"; import * as i4 from "@angular/common"; import * as i5 from "../../../pizzagna/components/pizzagna/pizzagna.component"; import * as i6 from "../wizard/dashwiz/dashwiz.component"; import * as i7 from "../wizard/dashwiz-step/dashwiz-step.component"; import * as i8 from "../heading/configurator-heading.component"; export class WidgetEditorComponent { static { this.lateLoadKey = "WidgetEditorComponent"; } static { this.TITLE_PATH = "header.properties.title"; } set formPizzagnaComponent(value) { value?.eventBus ?.getStream(PREVIEW_EVENT) .pipe(takeUntil(this.destroy$)) .subscribe((event) => { const payload = event.payload; if (payload && payload.id) { this.configurator?.previewPizzagnaComponent?.eventBus ?.getStream(payload.id) .next(payload.payload); } }); this._formPizzagnaComponent = value; } constructor(changeDetector, formBuilder, previewService, configurator) { this.changeDetector = changeDetector; this.formBuilder = formBuilder; this.previewService = previewService; this.configurator = configurator; this.navigationControl = new BehaviorSubject({ busyState: { busy: false }, allowStepChange: true, }); this.busy = false; this.destroy$ = new Subject(); this.form = this.formBuilder.group({}); } ngOnInit() { // TODO: Reconsider this // @ts-ignore: We can depend on preview being undefined somewhere this.previewService.preview = this.configurator.previewWidget?.pizzagna[PizzagnaLayer.Configuration]; this.previewService.previewChanged .pipe(takeUntil(this.destroy$)) .subscribe((pizzagna) => { this.onPreviewPizzagnaUpdate(pizzagna); this.changeDetector.detectChanges(); }); this.configurator.submitError .pipe(takeUntil(this.destroy$)) .subscribe(() => { this.toggleBusy(); }); this.changeDetector.detectChanges(); } ngOnDestroy() { this.destroy$.next(); this.destroy$.complete(); } // -------------------------------------------------------------------------------- onPreviewPizzagnaUpdate(configLayer) { const previewWidget = { ...this.configurator.previewWidget, pizzagna: { ...this.configurator.previewWidget?.pizzagna, [PizzagnaLayer.Configuration]: configLayer, }, }; // TODO: Make previewWidget to be assignable to IWidget // @ts-ignore: Type '{ pizzagna: { configuration: IPizzagnaLayer; }; }' is missing the following properties from type 'IWidget': id, type this.configurator.updateWidget(previewWidget); const widgetTitle = get(configLayer, WidgetEditorComponent.TITLE_PATH, ""); this.configuratorTitle = $localize `Editing ${widgetTitle}`; } onFinish() { if (this.form.invalid) { this.form.markAllAsTouched(); // is used to trigger valueChanges to detect changes in forms // as form is invalid and marking as touched doesn't trigger neither statusChanges nor valueChanges // and validation messages and styles are not applied in that cases this.form.patchValue(this.form.value); this.form.updateValueAndValidity({ onlySelf: false, emitEvent: true, }); return; } this.toggleBusy(); this.configurator.formSubmit(); } onCancel() { this.configurator.formCancel(); } toggleBusy() { this.busy = !this.busy; this.navigationControl.next({ busyState: { busy: this.busy }, allowStepChange: !this.busy, }); } /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: WidgetEditorComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.FormBuilder }, { token: i2.PreviewService }, { token: i3.ConfiguratorComponent }], target: i0.ɵɵFactoryTarget.Component }); } /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: WidgetEditorComponent, selector: "nui-widget-editor", inputs: { formPizzagna: "formPizzagna", formRoot: "formRoot" }, host: { classAttribute: "d-flex flex-column h-100" }, viewQueries: [{ propertyName: "formPizzagnaComponent", first: true, predicate: ["formPizzagnaComponent"], descendants: true }], ngImport: i0, template: "<nui-configurator-heading\n [configuratorTitle]=\"configuratorTitle\"\n (close)=\"onCancel()\"\n [disableCloseButton]=\"busy\"\n></nui-configurator-heading>\n<nui-dashwiz\n [hideHeader]=\"true\"\n finishText=\"Save Changes\"\n i18n-finishText\n [navigationControl]=\"navigationControl\"\n (finish)=\"onFinish()\"\n (cancel)=\"onCancel()\"\n>\n <nui-dashwiz-step [stepTemplate]=\"step1\"></nui-dashwiz-step>\n</nui-dashwiz>\n\n<ng-template #step1>\n <div [formGroup]=\"form\">\n <nui-pizzagna\n *ngIf=\"formPizzagna\"\n #formPizzagnaComponent\n [rootNode]=\"formRoot\"\n [(pizzagna)]=\"formPizzagna\"\n >\n </nui-pizzagna>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i5.PizzagnaComponent, selector: "nui-pizzagna", inputs: ["rootNode", "pizzagna", "outputs"], outputs: ["pizzagnaChange", "output"] }, { kind: "component", type: i6.DashwizComponent, selector: "nui-dashwiz", inputs: ["hideHeader", "canProceed", "canFinish", "finishText", "stretchStepLines", "buttonComponentTypes", "navigationControl"], outputs: ["stepNavigated", "cancel", "finish", "next", "back"] }, { kind: "component", type: i7.DashwizStepComponent, selector: "nui-dashwiz-step", inputs: ["stepTemplate", "stepControl", "title", "nextText", "hidden", "disabled", "spinnerSize"], outputs: ["enter", "valid", "exit", "next"] }, { kind: "component", type: i8.ConfiguratorHeadingComponent, selector: "nui-configurator-heading", inputs: ["configuratorTitle", "disableCloseButton"], outputs: ["close"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: WidgetEditorComponent, decorators: [{ type: Component, args: [{ selector: "nui-widget-editor", host: { class: "d-flex flex-column h-100" }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<nui-configurator-heading\n [configuratorTitle]=\"configuratorTitle\"\n (close)=\"onCancel()\"\n [disableCloseButton]=\"busy\"\n></nui-configurator-heading>\n<nui-dashwiz\n [hideHeader]=\"true\"\n finishText=\"Save Changes\"\n i18n-finishText\n [navigationControl]=\"navigationControl\"\n (finish)=\"onFinish()\"\n (cancel)=\"onCancel()\"\n>\n <nui-dashwiz-step [stepTemplate]=\"step1\"></nui-dashwiz-step>\n</nui-dashwiz>\n\n<ng-template #step1>\n <div [formGroup]=\"form\">\n <nui-pizzagna\n *ngIf=\"formPizzagna\"\n #formPizzagnaComponent\n [rootNode]=\"formRoot\"\n [(pizzagna)]=\"formPizzagna\"\n >\n </nui-pizzagna>\n </div>\n</ng-template>\n" }] }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.FormBuilder }, { type: i2.PreviewService }, { type: i3.ConfiguratorComponent }], propDecorators: { formPizzagna: [{ type: Input }], formRoot: [{ type: Input }], formPizzagnaComponent: [{ type: ViewChild, args: ["formPizzagnaComponent", { static: false }] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2lkZ2V0LWVkaXRvci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL2NvbmZpZ3VyYXRvci9jb21wb25lbnRzL3dpZGdldC1lZGl0b3Ivd2lkZ2V0LWVkaXRvci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL2NvbmZpZ3VyYXRvci9jb21wb25lbnRzL3dpZGdldC1lZGl0b3Ivd2lkZ2V0LWVkaXRvci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx5REFBeUQ7QUFDekQsRUFBRTtBQUNGLCtFQUErRTtBQUMvRSw0RUFBNEU7QUFDNUUsOEVBQThFO0FBQzlFLCtFQUErRTtBQUMvRSw4RUFBOEU7QUFDOUUsNERBQTREO0FBQzVELEVBQUU7QUFDRiw2RUFBNkU7QUFDN0UsdURBQXVEO0FBQ3ZELEVBQUU7QUFDRiw2RUFBNkU7QUFDN0UsNEVBQTRFO0FBQzVFLCtFQUErRTtBQUMvRSwwRUFBMEU7QUFDMUUsaUZBQWlGO0FBQ2pGLDZFQUE2RTtBQUM3RSxpQkFBaUI7QUFFakIsT0FBTyxFQUNILHVCQUF1QixFQUN2QixpQkFBaUIsRUFDakIsU0FBUyxFQUNULEtBQUssRUFHTCxTQUFTLEdBQ1osTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFdBQVcsRUFBYSxNQUFNLGdCQUFnQixDQUFDO0FBQ3hELE9BQU8sR0FBRyxNQUFNLFlBQVksQ0FBQztBQUM3QixPQUFPLEVBQUUsZUFBZSxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNoRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFJM0MsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sMERBQTBELENBQUM7QUFDN0YsT0FBTyxFQUF3QixhQUFhLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM5RSxPQUFPLEVBSUgsYUFBYSxHQUNoQixNQUFN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QztRQUN2QixJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDO1lBQ3hCLFNBQVMsRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFO1lBQzlCLGVBQWUsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJO1NBQzlCLENBQUMsQ0FBQztJQUNQLENBQUM7a0lBNUhRLHFCQUFxQjtzSEFBckIscUJBQXFCLCtTQ3REbEMsK3VCQTJCQTs7NEZEMkJhLHFCQUFxQjtrQkFOakMsU0FBUzsrQkFDSSxtQkFBbUIsUUFFdkIsRUFBRSxLQUFLLEVBQUUsMEJBQTBCLEVBQUUsbUJBQzFCLHVCQUF1QixDQUFDLE1BQU07aUxBUXRDLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFLSyxxQkFBcUI7c0JBRC9CLFNBQVM7dUJBQUMsdUJBQXVCLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiLy8gwqkgMjAyMiBTb2xhcldpbmRzIFdvcmxkd2lkZSwgTExDLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbi8vICBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0b1xuLy8gIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlXG4vLyAgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXG4vLyAgc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbi8vICBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLyAgYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8gIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vICBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuLy8gIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cbi8vICBUSEUgU09GVFdBUkUuXG5cbmltcG9ydCB7XG4gICAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gICAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgQ29tcG9uZW50LFxuICAgIElucHV0LFxuICAgIE9uRGVzdHJveSxcbiAgICBPbkluaXQsXG4gICAgVmlld0NoaWxkLFxufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgRm9ybUJ1aWxkZXIsIEZvcm1Hcm91cCB9IGZyb20gXCJAYW5ndWxhci9mb3Jtc1wiO1xuaW1wb3J0IGdldCBmcm9tIFwibG9kYXNoL2dldFwiO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBTdWJqZWN0IH0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB7IHRha2VVbnRpbCB9IGZyb20gXCJyeGpzL29wZXJhdG9yc1wiO1xuXG5pbXBvcnQgeyBJRXZlbnQgfSBmcm9tIFwiQG5vdmEtdWkvYml0c1wiO1xuXG5pbXBvcnQgeyBQaXp6YWduYUNvbXBvbmVudCB9IGZyb20gXCIuLi8uLi8uLi9waXp6YWduYS9jb21wb25lbnRzL3BpenphZ25hL3BpenphZ25hLmNvbXBvbmVudFwiO1xuaW1wb3J0IHsgSVByZXZpZXdFdmVudFBheWxvYWQsIFBSRVZJRVdfRVZFTlQgfSBmcm9tIFwiLi4vLi4vLi4vc2VydmljZXMvdHlwZXNcIjtcbmltcG9ydCB7XG4gICAgSUhhc0NoYW5nZURldGVjdG9yLFxuICAgIElQaXp6YWduYSxcbiAgICBJUGl6emFnbmFMYXllcixcbiAgICBQaXp6YWduYUxheWVyLFxufSBmcm9tIFwiLi4vLi4vLi4vdHlwZXNcIjtcbmltcG9ydCB7IFByZXZpZXdTZXJ2aWNlIH0gZnJvbSBcIi4uLy4uL3NlcnZpY2VzL3ByZXZpZXcuc2VydmljZVwiO1xuaW1wb3J0IHsgQ29uZmlndXJhdG9yQ29tcG9uZW50IH0gZnJvbSBcIi4uL2NvbmZpZ3VyYXRvci9jb25maWd1cmF0b3IuY29tcG9uZW50XCI7XG5pbXBvcnQgeyBJRGFzaHdpeldhaXRFdmVudCB9IGZyb20gXCIuLi93aXphcmQvdHlwZXNcIjtcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6IFwibnVpLXdpZGdldC1lZGl0b3JcIixcbiAgICB0ZW1wbGF0ZVVybDogXCIuL3dpZGdldC1lZGl0b3IuY29tcG9uZW50Lmh0bWxcIixcbiAgICBob3N0OiB7IGNsYXNzOiBcImQtZmxleCBmbGV4LWNvbHVtbiBoLTEwMFwiIH0sXG4gICAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIFdpZGdldEVkaXRvckNvbXBvbmVudFxuICAgIGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3ksIElIYXNDaGFuZ2VEZXRlY3Rvclxue1xuICAgIHB1YmxpYyBzdGF0aWMgbGF0ZUxvYWRLZXkgPSBcIldpZGdldEVkaXRvckNvbXBvbmVudFwiO1xuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgVElUTEVfUEFUSCA9IFwiaGVhZGVyLnByb3BlcnRpZXMudGl0bGVcIjtcblxuICAgIEBJbnB1dCgpIGZvcm1QaXp6YWduYTogSVBpenphZ25hO1xuICAgIEBJbnB1dCgpIGZvcm1Sb290OiBzdHJpbmc7XG5cbiAgICBwcml2YXRlIF9mb3JtUGl6emFnbmFDb21wb25lbnQ6IFBpenphZ25hQ29tcG9uZW50O1xuXG4gICAgQFZpZXdDaGlsZChcImZvcm1QaXp6YWduYUNvbXBvbmVudFwiLCB7IHN0YXRpYzogZmFsc2UgfSlcbiAgICBwdWJsaWMgc2V0IGZvcm1QaXp6YWduYUNvbXBvbmVudCh2YWx1ZTogUGl6emFnbmFDb21wb25lbnQpIHtcbiAgICAgICAgdmFsdWU/LmV2ZW50QnVzXG4gICAgICAgICAgICA/LmdldFN0cmVhbShQUkVWSUVXX0VWRU5UKVxuICAgICAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgoZXZlbnQ6IElFdmVudDxJUHJldmlld0V2ZW50UGF5bG9hZD4pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXlsb2FkID0gZXZlbnQucGF5bG9hZDtcbiAgICAgICAgICAgICAgICBpZiAocGF5bG9hZCAmJiBwYXlsb2FkLmlkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlndXJhdG9yPy5wcmV2aWV3UGl6emFnbmFDb21wb25lbnQ/LmV2ZW50QnVzXG4gICAgICAgICAgICAgICAgICAgICAgICA/LmdldFN0cmVhbShwYXlsb2FkLmlkKVxuICAgICAgICAgICAgICAgICAgICAgICAgLm5leHQocGF5bG9hZC5wYXlsb2FkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fZm9ybVBpenphZ25hQ29tcG9uZW50ID0gdmFsdWU7XG4gICAgfVxuXG4gICAgcHVibGljIGZvcm06IEZvcm1Hcm91cDtcbiAgICBwdWJsaWMgbmF2aWdhdGlvbkNvbnRyb2w6IEJlaGF2aW9yU3ViamVjdDxJRGFzaHdpeldhaXRFdmVudD4gPVxuICAgICAgICBuZXcgQmVoYXZpb3JTdWJqZWN0PElEYXNod2l6V2FpdEV2ZW50Pih7XG4gICAgICAgICAgICBidXN5U3RhdGU6IHsgYnVzeTogZmFsc2UgfSxcbiAgICAgICAgICAgIGFsbG93U3RlcENoYW5nZTogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgcHVibGljIGJ1c3kgPSBmYWxzZTtcbiAgICBwdWJsaWMgY29uZmlndXJhdG9yVGl0bGU6IHN0cmluZztcblxuICAgIHByaXZhdGUgcmVhZG9ubHkgZGVzdHJveSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHB1YmxpYyBjaGFuZ2VEZXRlY3RvcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgICAgIHByaXZhdGUgZm9ybUJ1aWxkZXI6IEZvcm1CdWlsZGVyLFxuICAgICAgICBwcml2YXRlIHByZXZpZXdTZXJ2aWNlOiBQcmV2aWV3U2VydmljZSxcbiAgICAgICAgcHVibGljIGNvbmZpZ3VyYXRvcjogQ29uZmlndXJhdG9yQ29tcG9uZW50XG4gICAgKSB7XG4gICAgICAgIHRoaXMuZm9ybSA9IHRoaXMuZm9ybUJ1aWxkZXIuZ3JvdXAoe30pO1xuICAgIH1cblxuICAgIHB1YmxpYyBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICAgICAgLy8gVE9ETzogUmVjb25zaWRlciB0aGlzXG4gICAgICAgIC8vIEB0cy1pZ25vcmU6IFdlIGNhbiBkZXBlbmQgb24gcHJldmlldyBiZWluZyB1bmRlZmluZWQgc29tZXdoZXJlXG4gICAgICAgIHRoaXMucHJldmlld1NlcnZpY2UucHJldmlldyA9XG4gICAgICAgICAgICB0aGlzLmNvbmZpZ3VyYXRvci5wcmV2aWV3V2lkZ2V0Py5waXp6YWduYVtcbiAgICAgICAgICAgICAgICBQaXp6YWduYUxheWVyLkNvbmZpZ3VyYXRpb25cbiAgICAgICAgICAgIF07XG5cbiAgICAgICAgdGhpcy5wcmV2aWV3U2VydmljZS5wcmV2aWV3Q2hhbmdlZFxuICAgICAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgocGl6emFnbmE6IElQaXp6YWduYUxheWVyKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5vblByZXZpZXdQaXp6YWduYVVwZGF0ZShwaXp6YWduYSk7XG4gICAgICAgICAgICAgICAgdGhpcy5jaGFuZ2VEZXRlY3Rvci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLmNvbmZpZ3VyYXRvci5zdWJtaXRFcnJvclxuICAgICAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy50b2dnbGVCdXN5KCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5jaGFuZ2VEZXRlY3Rvci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgfVxuXG4gICAgcHVibGljIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgICAgICB0aGlzLmRlc3Ryb3kkLm5leHQoKTtcbiAgICAgICAgdGhpcy5kZXN0cm95JC5jb21wbGV0ZSgpO1xuICAgIH1cblxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgICBwdWJsaWMgb25QcmV2aWV3UGl6emFnbmFVcGRhdGUoY29uZmlnTGF5ZXI6IElQaXp6YWduYUxheWVyKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHByZXZpZXdXaWRnZXQgPSB7XG4gICAgICAgICAgICAuLi50aGlzLmNvbmZpZ3VyYXRvci5wcmV2aWV3V2lkZ2V0LFxuICAgICAgICAgICAgcGl6emFnbmE6IHtcbiAgICAgICAgICAgICAgICAuLi50aGlzLmNvbmZpZ3VyYXRvci5wcmV2aWV3V2lkZ2V0Py5waXp6YWduYSxcbiAgICAgICAgICAgICAgICBbUGl6emFnbmFMYXllci5Db25maWd1cmF0aW9uXTogY29uZmlnTGF5ZXIsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICAvLyBUT0RPOiBNYWtlIHByZXZpZXdXaWRnZXQgdG8gYmUgYXNzaWduYWJsZSB0byBJV2lkZ2V0XG4gICAgICAgIC8vIEB0cy1pZ25vcmU6IFR5cGUgJ3sgcGl6emFnbmE6IHsgY29uZmlndXJhdGlvbjogSVBpenphZ25hTGF5ZXI7IH07IH0nIGlzIG1pc3NpbmcgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzIGZyb20gdHlwZSAnSVdpZGdldCc6IGlkLCB0eXBlXG4gICAgICAgIHRoaXMuY29uZmlndXJhdG9yLnVwZGF0ZVdpZGdldChwcmV2aWV3V2lkZ2V0KTtcbiAgICAgICAgY29uc3Qgd2lkZ2V0VGl0bGUgPSBnZXQoXG4gICAgICAgICAgICBjb25maWdMYXllcixcbiAgICAgICAgICAgIFdpZGdldEVkaXRvckNvbXBvbmVudC5USVRMRV9QQVRILFxuICAgICAgICAgICAgXCJcIlxuICAgICAgICApO1xuICAgICAgICB0aGlzLmNvbmZpZ3VyYXRvclRpdGxlID0gJGxvY2FsaXplYEVkaXRpbmcgJHt3aWRnZXRUaXRsZX1gO1xuICAgIH1cblxuICAgIHB1YmxpYyBvbkZpbmlzaCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuZm9ybS5pbnZhbGlkKSB7XG4gICAgICAgICAgICB0aGlzLmZvcm0ubWFya0FsbEFzVG91Y2hlZCgpO1xuICAgICAgICAgICAgLy8gaXMgdXNlZCB0byB0cmlnZ2VyIHZhbHVlQ2hhbmdlcyB0byBkZXRlY3QgY2hhbmdlcyBpbiBmb3Jtc1xuICAgICAgICAgICAgLy8gYXMgZm9ybSBpcyBpbnZhbGlkIGFuZCBtYXJraW5nIGFzIHRvdWNoZWQgZG9lc24ndCB0cmlnZ2VyIG5laXRoZXIgc3RhdHVzQ2hhbmdlcyBub3IgdmFsdWVDaGFuZ2VzXG4gICAgICAgICAgICAvLyBhbmQgdmFsaWRhdGlvbiBtZXNzYWdlcyBhbmQgc3R5bGVzIGFyZSBub3QgYXBwbGllZCBpbiB0aGF0IGNhc2VzXG4gICAgICAgICAgICB0aGlzLmZvcm0ucGF0Y2hWYWx1ZSh0aGlzLmZvcm0udmFsdWUpO1xuICAgICAgICAgICAgdGhpcy5mb3JtLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoe1xuICAgICAgICAgICAgICAgIG9ubHlTZWxmOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBlbWl0RXZlbnQ6IHRydWUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMudG9nZ2xlQnVzeSgpO1xuICAgICAgICB0aGlzLmNvbmZpZ3VyYXRvci5mb3JtU3VibWl0KCk7XG4gICAgfVxuXG4gICAgcHVibGljIG9uQ2FuY2VsKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmNvbmZpZ3VyYXRvci5mb3JtQ2FuY2VsKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSB0b2dnbGVCdXN5KCkge1xuICAgICAgICB0aGlzLmJ1c3kgPSAhdGhpcy5idXN5O1xuICAgICAgICB0aGlzLm5hdmlnYXRpb25Db250cm9sLm5leHQoe1xuICAgICAgICAgICAgYnVzeVN0YXRlOiB7IGJ1c3k6IHRoaXMuYnVzeSB9LFxuICAgICAgICAgICAgYWxsb3dTdGVwQ2hhbmdlOiAhdGhpcy5idXN5LFxuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCI8bnVpLWNvbmZpZ3VyYXRvci1oZWFkaW5nXG4gICAgW2NvbmZpZ3VyYXRvclRpdGxlXT1cImNvbmZpZ3VyYXRvclRpdGxlXCJcbiAgICAoY2xvc2UpPVwib25DYW5jZWwoKVwiXG4gICAgW2Rpc2FibGVDbG9zZUJ1dHRvbl09XCJidXN5XCJcbj48L251aS1jb25maWd1cmF0b3ItaGVhZGluZz5cbjxudWktZGFzaHdpelxuICAgIFtoaWRlSGVhZGVyXT1cInRydWVcIlxuICAgIGZpbmlzaFRleHQ9XCJTYXZlIENoYW5nZXNcIlxuICAgIGkxOG4tZmluaXNoVGV4dFxuICAgIFtuYXZpZ2F0aW9uQ29udHJvbF09XCJuYXZpZ2F0aW9uQ29udHJvbFwiXG4gICAgKGZpbmlzaCk9XCJvbkZpbmlzaCgpXCJcbiAgICAoY2FuY2VsKT1cIm9uQ2FuY2VsKClcIlxuPlxuICAgIDxudWktZGFzaHdpei1zdGVwIFtzdGVwVGVtcGxhdGVdPVwic3RlcDFcIj48L251aS1kYXNod2l6LXN0ZXA+XG48L251aS1kYXNod2l6PlxuXG48bmctdGVtcGxhdGUgI3N0ZXAxPlxuICAgIDxkaXYgW2Zvcm1Hcm91cF09XCJmb3JtXCI+XG4gICAgICAgIDxudWktcGl6emFnbmFcbiAgICAgICAgICAgICpuZ0lmPVwiZm9ybVBpenphZ25hXCJcbiAgICAgICAgICAgICNmb3JtUGl6emFnbmFDb21wb25lbnRcbiAgICAgICAgICAgIFtyb290Tm9kZV09XCJmb3JtUm9vdFwiXG4gICAgICAgICAgICBbKHBpenphZ25hKV09XCJmb3JtUGl6emFnbmFcIlxuICAgICAgICA+XG4gICAgICAgIDwvbnVpLXBpenphZ25hPlxuICAgIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==