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

172 lines 38.4 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 { Inject, Injectable } from "@angular/core"; import get from "lodash/get"; import isEmpty from "lodash/isEmpty"; import isEqual from "lodash/isEqual"; import isUndefined from "lodash/isUndefined"; // eslint-disable-next-line import/no-deprecated import { combineLatest, Subject } from "rxjs"; import { distinctUntilChanged, map, takeUntil } from "rxjs/operators"; import { EventBus, immutableSet } from "@nova-ui/bits"; import { PizzagnaService } from "../../../../pizzagna/services/pizzagna.service"; import { PizzagnaLayer, PIZZAGNA_EVENT_BUS, WellKnownProviders, } from "../../../../types"; import { DATA_SOURCE_CHANGE, DATA_SOURCE_OUTPUT } from "../../../types"; import { PreviewService } from "../../preview.service"; import { BaseConverter } from "../base-converter"; import * as i0 from "@angular/core"; import * as i1 from "../../preview.service"; import * as i2 from "../../../../pizzagna/services/pizzagna.service"; import * as i3 from "@nova-ui/bits"; export class TimeseriesSeriesConverterService extends BaseConverter { constructor(eventBus, previewService, pizzagnaService) { super(eventBus, previewService, pizzagnaService); this.indicatorDataKey = "indicatorData"; this.previewSeriesPath = `providers.${WellKnownProviders.Adapter}.properties.series`; this.formSeriesComponentPath = `${PizzagnaLayer.Data}.series.properties`; this.dataSourceSeries$ = new Subject(); this.selectedSeriesIds$ = new Subject(); this.shouldReadForm = false; this.subscribeToAvailableDataFieldsChange(); this.eventBus.subscribeUntil(DATA_SOURCE_CHANGE, this.destroy$, (v) => { const nodesPath = `${PizzagnaLayer.Structure}.series.properties.nodes`; const nodes = get(this.pizzagnaService.pizzagna, nodesPath); this.pizzagnaService.removeComponents(nodes); let updatedPizzagna = this.pizzagnaService.pizzagna; updatedPizzagna = immutableSet(updatedPizzagna, nodesPath, []); updatedPizzagna = immutableSet(updatedPizzagna, `${this.formSeriesComponentPath}.series`, []); this.updateFormPizzagna(updatedPizzagna); }); this.eventBus.subscribeUntil(DATA_SOURCE_OUTPUT, this.destroy$, (event) => { // Because typing is lenient for the data source output, the event may or may not contain an IDataSourceOutput // with a result property; the payload may actually be the result itself, so both possibilities are accommodated. const { series } = isUndefined(event.payload.result) ? event.payload : event.payload.result || {}; if (series) { this.dataSourceSeries$.next(series); let updatedPizzagna = this.pizzagnaService.pizzagna; updatedPizzagna = immutableSet(updatedPizzagna, `${this.formSeriesComponentPath}.allSeries`, series); const seriesTemplate = this.pizzagnaService.pizzagna[PizzagnaLayer.Structure][this.component.componentId].properties?.template; const indicatorDataIndex = seriesTemplate.findIndex((val) => val.id === this.indicatorDataKey); const indicatorDataPath = `${PizzagnaLayer.Structure}.series.properties.template[${indicatorDataIndex}].properties.allSeries`; updatedPizzagna = immutableSet(updatedPizzagna, indicatorDataPath, series); const previewSeries = get(this.getPreview(), `chart.${this.previewSeriesPath}`, []); updatedPizzagna = previewSeries.reduce((res, s) => immutableSet(res, `${PizzagnaLayer.Data}.${s.id}/${this.indicatorDataKey}.properties.allSeries`, series), updatedPizzagna); this.updateFormPizzagna(updatedPizzagna); // updating preview series if no series set in editor. this occurs when changing DS, for example. // in DS is changing all the series are removed and then all series from DS should be set. // that's why updating preview series. const editorSeriesPath = `${this.formSeriesComponentPath}.series`; const editorSeries = get(this.pizzagnaService.pizzagna, editorSeriesPath); if (isEmpty(editorSeries)) { this.shouldReadForm = false; const seriesForPreview = series.map((s) => ({ id: s.id, selectedSeriesId: s.id, label: s.name, })); const updatedPreview = immutableSet(this.getPreview(), `chart.${this.previewSeriesPath}`, seriesForPreview); this.updatePreview(updatedPreview); this.buildForm(); setTimeout(() => { this.updateAvailableSeries([]); this.shouldReadForm = true; }); } } }); } buildForm() { const preview = this.getPreview(); const series = get(preview, `chart.${this.previewSeriesPath}`, []); const seriesToSet = series.map((s) => ({ id: s.id, selectedSeriesId: s.selectedSeriesId, })); const seriesIds = series.map((s) => s.id); this.pizzagnaService.createComponentsFromTemplate("series", seriesIds); const editorPizzagna = this.pizzagnaService.pizzagna; const pizzagnaWithSeries = immutableSet(editorPizzagna, `${this.formSeriesComponentPath}.series`, seriesToSet); this.updateFormPizzagna(pizzagnaWithSeries); this.selectedSeriesIds$.next(seriesToSet.map((s) => s.selectedSeriesId)); setTimeout(() => (this.shouldReadForm = true)); } toPreview(form) { form.valueChanges .pipe(takeUntil(this.destroy$)) .subscribe((formSeries) => { if (!this.shouldReadForm) { return; } const preview = this.getPreview(); const { chart } = preview; const seriesFromPreview = get(chart, this.previewSeriesPath, []); const series = formSeries.map((s) => ({ id: s.id, selectedSeriesId: s.selectedSeriesId, ...seriesFromPreview.find((previewSeries) => previewSeries.id === s.id), })); const updatedPreview = immutableSet(preview, `chart.${this.previewSeriesPath}`, series); this.updatePreview(updatedPreview); const selectedSeriesIds = formSeries .map((s) => get(s, `properties[${s.id}/indicatorData].id`)) .filter((v) => !isEmpty(v)); this.selectedSeriesIds$.next(selectedSeriesIds); }); } ngOnDestroy() { this.dataSourceSeries$.complete(); this.selectedSeriesIds$.complete(); super.ngOnDestroy(); } updateAvailableSeries(availableSeries) { if (!this.pizzagnaService.pizzagna) { return; } let updatedPizzagna = this.pizzagnaService.pizzagna; // configuration component updatedPizzagna = immutableSet(updatedPizzagna, `${this.formSeriesComponentPath}.availableSeries`, availableSeries); // template const seriesTemplate = this.pizzagnaService.pizzagna[PizzagnaLayer.Structure][this.component.componentId].properties?.template; const indicatorDataIndex = seriesTemplate.findIndex((val) => val.id === this.indicatorDataKey); const indicatorDataPath = `${PizzagnaLayer.Structure}.series.properties.template[${indicatorDataIndex}].properties.availableSeries`; updatedPizzagna = immutableSet(updatedPizzagna, indicatorDataPath, availableSeries); // already created forms const seriesIds = get(this.pizzagnaService.pizzagna, `${PizzagnaLayer.Structure}.series.properties.nodes`); updatedPizzagna = seriesIds.reduce((res, id) => immutableSet(res, `${PizzagnaLayer.Data}.${id}/${this.indicatorDataKey}.properties.availableSeries`, availableSeries), updatedPizzagna); this.updateFormPizzagna(updatedPizzagna); } subscribeToAvailableDataFieldsChange() { // eslint-disable-next-line import/no-deprecated combineLatest([this.dataSourceSeries$, this.selectedSeriesIds$]) .pipe(takeUntil(this.destroy$), map(([dsSeries, usedSeriesIds]) => dsSeries.filter((ds) => !usedSeriesIds.find((id) => id === ds.id))), distinctUntilChanged(isEqual)) .subscribe(this.updateAvailableSeries.bind(this)); } /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TimeseriesSeriesConverterService, deps: [{ token: PIZZAGNA_EVENT_BUS }, { token: i1.PreviewService }, { token: i2.PizzagnaService }], target: i0.ɵɵFactoryTarget.Injectable }); } /** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TimeseriesSeriesConverterService }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TimeseriesSeriesConverterService, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: i3.EventBus, decorators: [{ type: Inject, args: [PIZZAGNA_EVENT_BUS] }] }, { type: i1.PreviewService }, { type: i2.PizzagnaService }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZXNlcmllcy1zZXJpZXMtY29udmVydGVyLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL2NvbmZpZ3VyYXRvci9zZXJ2aWNlcy9jb252ZXJ0ZXJzL3RpbWVzZXJpZXMvdGltZXNlcmllcy1zZXJpZXMtY29udmVydGVyLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEseURBQXlEO0FBQ3pELEVBQUU7QUFDRiwrRUFBK0U7QUFDL0UsNEVBQTRFO0FBQzVFLDhFQUE4RTtBQUM5RSwrRUFBK0U7QUFDL0UsOEVBQThFO0FBQzlFLDREQUE0RDtBQUM1RCxFQUFFO0FBQ0YsNkVBQTZFO0FBQzdFLHVEQUF1RDtBQUN2RCxFQUFFO0FBQ0YsNkVBQTZFO0FBQzdFLDRFQUE0RTtBQUM1RSwrRUFBK0U7QUFDL0UsMEVBQTBFO0FBQzFFLGlGQUFpRjtBQUNqRiw2RUFBNkU7QUFDN0UsaUJBQWlCO0FBRWpCLE9BQU8sRUFBaUIsTUFBTSxFQUFFLFVBQVUsRUFBYSxNQUFNLGVBQWUsQ0FBQztBQUU3RSxPQUFPLEdBQUcsTUFBTSxZQUFZLENBQUM7QUFDN0IsT0FBTyxPQUFPLE1BQU0sZ0JBQWdCLENBQUM7QUFDckMsT0FBTyxPQUFPLE1BQU0sZ0JBQWdCLENBQUM7QUFDckMsT0FBTyxXQUFXLE1BQU0sb0JBQW9CLENBQUM7QUFDN0MsZ0RBQWdEO0FBQ2hELE9BQU8sRUFBRSxhQUFhLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzlDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFdEUsT0FBTyxFQUFFLFFBQVEsRUFBVSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFPL0QsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGdEQUFnRCxDQUFDO0FBQ2pGLE9BQU8sRUFDSCxhQUFhLEVBQ2Isa0JBQWtC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QUFRLEVBQUUsYUFBYSxDQUFDLEVBQUUsRUFBRSxDQUM5QixRQUFRLENBQUMsTUFBTSxDQUNYLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQ3BELENBQ0osRUFDRCxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsQ0FDaEM7YUFDQSxTQUFTLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQzFELENBQUM7a0lBelFRLGdDQUFnQyxrQkFhN0Isa0JBQWtCO3NJQWJyQixnQ0FBZ0M7OzRGQUFoQyxnQ0FBZ0M7a0JBRDVDLFVBQVU7OzBCQWNGLE1BQU07MkJBQUMsa0JBQWtCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gwqkgMjAyMiBTb2xhcldpbmRzIFdvcmxkd2lkZSwgTExDLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbi8vICBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0b1xuLy8gIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlXG4vLyAgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXG4vLyAgc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbi8vICBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLyAgYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8gIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vICBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuLy8gIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cbi8vICBUSEUgU09GVFdBUkUuXG5cbmltcG9ydCB7IEFmdGVyVmlld0luaXQsIEluamVjdCwgSW5qZWN0YWJsZSwgT25EZXN0cm95IH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IEZvcm1Hcm91cCB9IGZyb20gXCJAYW5ndWxhci9mb3Jtc1wiO1xuaW1wb3J0IGdldCBmcm9tIFwibG9kYXNoL2dldFwiO1xuaW1wb3J0IGlzRW1wdHkgZnJvbSBcImxvZGFzaC9pc0VtcHR5XCI7XG5pbXBvcnQgaXNFcXVhbCBmcm9tIFwibG9kYXNoL2lzRXF1YWxcIjtcbmltcG9ydCBpc1VuZGVmaW5lZCBmcm9tIFwibG9kYXNoL2lzVW5kZWZpbmVkXCI7XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLWRlcHJlY2F0ZWRcbmltcG9ydCB7IGNvbWJpbmVMYXRlc3QsIFN1YmplY3QgfSBmcm9tIFwicnhqc1wiO1xuaW1wb3J0IHsgZGlzdGluY3RVbnRpbENoYW5nZWQsIG1hcCwgdGFrZVVudGlsIH0gZnJvbSBcInJ4anMvb3BlcmF0b3JzXCI7XG5cbmltcG9ydCB7IEV2ZW50QnVzLCBJRXZlbnQsIGltbXV0YWJsZVNldCB9IGZyb20gXCJAbm92YS11aS9iaXRzXCI7XG5cbmltcG9ydCB7IElEYXRhU291cmNlT3V0cHV0IH0gZnJvbSBcIi4uLy4uLy4uLy4uL2NvbXBvbmVudHMvcHJvdmlkZXJzL3R5cGVzXCI7XG5pbXBvcnQge1xuICAgIElUaW1lc2VyaWVzV2lkZ2V0RGF0YSxcbiAgICBJVGltZXNlcmllc1dpZGdldFNlcmllcyxcbn0gZnJvbSBcIi4uLy4uLy4uLy4uL2NvbXBvbmVudHMvdGltZXNlcmllcy13aWRnZXQvdHlwZXNcIjtcbmltcG9ydCB7IFBpenphZ25hU2VydmljZSB9IGZyb20gXCIuLi8uLi8uLi8uLi9waXp6YWduYS9zZXJ2aWNlcy9waXp6YWduYS5zZXJ2aWNlXCI7XG5pbXBvcnQge1xuICAgIFBpenphZ25hTGF5ZXIsXG4gICAgUElaWkFHTkFfRVZFTlRfQlVTLFxuICAgIFdlbGxLbm93blByb3ZpZGVycyxcbn0gZnJvbSBcIi4uLy4uLy4uLy4uL3R5cGVzXCI7XG5pbXBvcnQgeyBJSXRlbUNvbmZpZ3VyYXRpb24gfSBmcm9tIFwiLi4vLi4vLi4vY29tcG9uZW50cy90eXBlc1wiO1xuaW1wb3J0IHsgSVRpbWVzZXJpZXNJdGVtQ29uZmlndXJhdGlvbiB9IGZyb20gXCIuLi8uLi8uLi9jb21wb25lbnRzL3dpZGdldHMvdGltZXNlcmllcy90eXBlc1wiO1xuaW1wb3J0IHsgREFUQV9TT1VSQ0VfQ0hBTkdFLCBEQVRBX1NPVVJDRV9PVVRQVVQgfSBmcm9tIFwiLi4vLi4vLi4vdHlwZXNcIjtcbmltcG9ydCB7IFByZXZpZXdTZXJ2aWNlIH0gZnJvbSBcIi4uLy4uL3ByZXZpZXcuc2VydmljZVwiO1xuaW1wb3J0IHsgQmFzZUNvbnZlcnRlciB9IGZyb20gXCIuLi9iYXNlLWNvbnZlcnRlclwiO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgVGltZXNlcmllc1Nlcmllc0NvbnZlcnRlclNlcnZpY2VcbiAgICBleHRlbmRzIEJhc2VDb252ZXJ0ZXJcbiAgICBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveVxue1xuICAgIHByaXZhdGUgaW5kaWNhdG9yRGF0YUtleSA9IFwiaW5kaWNhdG9yRGF0YVwiO1xuICAgIHByaXZhdGUgcHJldmlld1Nlcmllc1BhdGggPSBgcHJvdmlkZXJzLiR7V2VsbEtub3duUHJvdmlkZXJzLkFkYXB0ZXJ9LnByb3BlcnRpZXMuc2VyaWVzYDtcbiAgICBwcml2YXRlIGZvcm1TZXJpZXNDb21wb25lbnRQYXRoID0gYCR7UGl6emFnbmFMYXllci5EYXRhfS5zZXJpZXMucHJvcGVydGllc2A7XG5cbiAgICBwcml2YXRlIGRhdGFTb3VyY2VTZXJpZXMkID0gbmV3IFN1YmplY3Q8SVRpbWVzZXJpZXNXaWRnZXREYXRhW10+KCk7XG4gICAgcHJpdmF0ZSBzZWxlY3RlZFNlcmllc0lkcyQgPSBuZXcgU3ViamVjdDxzdHJpbmdbXT4oKTtcbiAgICBwcml2YXRlIHNob3VsZFJlYWRGb3JtID0gZmFsc2U7XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgQEluamVjdChQSVpaQUdOQV9FVkVOVF9CVVMpIGV2ZW50QnVzOiBFdmVudEJ1czxJRXZlbnQ+LFxuICAgICAgICBwcmV2aWV3U2VydmljZTogUHJldmlld1NlcnZpY2UsXG4gICAgICAgIHBpenphZ25hU2VydmljZTogUGl6emFnbmFTZXJ2aWNlXG4gICAgKSB7XG4gICAgICAgIHN1cGVyKGV2ZW50QnVzLCBwcmV2aWV3U2VydmljZSwgcGl6emFnbmFTZXJ2aWNlKTtcblxuICAgICAgICB0aGlzLnN1YnNjcmliZVRvQXZhaWxhYmxlRGF0YUZpZWxkc0NoYW5nZSgpO1xuXG4gICAgICAgIHRoaXMuZXZlbnRCdXMuc3Vic2NyaWJlVW50aWwoREFUQV9TT1VSQ0VfQ0hBTkdFLCB0aGlzLmRlc3Ryb3kkLCAodikgPT4ge1xuICAgICAgICAgICAgY29uc3Qgbm9kZXNQYXRoID0gYCR7UGl6emFnbmFMYXllci5TdHJ1Y3R1cmV9LnNlcmllcy5wcm9wZXJ0aWVzLm5vZGVzYDtcbiAgICAgICAgICAgIGNvbnN0IG5vZGVzID0gZ2V0KFxuICAgICAgICAgICAgICAgIHRoaXMucGl6emFnbmFTZXJ2aWNlLnBpenphZ25hLFxuICAgICAgICAgICAgICAgIG5vZGVzUGF0aFxuICAgICAgICAgICAgKSBhcyB1bmtub3duIGFzIHN0cmluZ1tdO1xuICAgICAgICAgICAgdGhpcy5waXp6YWduYVNlcnZpY2UucmVtb3ZlQ29tcG9uZW50cyhub2Rlcyk7XG5cbiAgICAgICAgICAgIGxldCB1cGRhdGVkUGl6emFnbmEgPSB0aGlzLnBpenphZ25hU2VydmljZS5waXp6YWduYTtcbiAgICAgICAgICAgIHVwZGF0ZWRQaXp6YWduYSA9IGltbXV0YWJsZVNldCh1cGRhdGVkUGl6emFnbmEsIG5vZGVzUGF0aCwgW10pO1xuICAgICAgICAgICAgdXBkYXRlZFBpenphZ25hID0gaW1tdXRhYmxlU2V0KFxuICAgICAgICAgICAgICAgIHVwZGF0ZWRQaXp6YWduYSxcbiAgICAgICAgICAgICAgICBgJHt0aGlzLmZvcm1TZXJpZXNDb21wb25lbnRQYXRofS5zZXJpZXNgLFxuICAgICAgICAgICAgICAgIFtdXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy51cGRhdGVGb3JtUGl6emFnbmEodXBkYXRlZFBpenphZ25hKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5ldmVudEJ1cy5zdWJzY3JpYmVVbnRpbChcbiAgICAgICAgICAgIERBVEFfU09VUkNFX09VVFBVVCxcbiAgICAgICAgICAgIHRoaXMuZGVzdHJveSQsXG4gICAgICAgICAgICAoZXZlbnQ6IElFdmVudDxhbnkgfCBJRGF0YVNvdXJjZU91dHB1dDxhbnk+PikgPT4ge1xuICAgICAgICAgICAgICAgIC8vIEJlY2F1c2UgdHlwaW5nIGlzIGxlbmllbnQgZm9yIHRoZSBkYXRhIHNvdXJjZSBvdXRwdXQsIHRoZSBldmVudCBtYXkgb3IgbWF5IG5vdCBjb250YWluIGFuIElEYXRhU291cmNlT3V0cHV0XG4gICAgICAgICAgICAgICAgLy8gd2l0aCBhIHJlc3VsdCBwcm9wZXJ0eTsgdGhlIHBheWxvYWQgbWF5IGFjdHVhbGx5IGJlIHRoZSByZXN1bHQgaXRzZWxmLCBzbyBib3RoIHBvc3NpYmlsaXRpZXMgYXJlIGFjY29tbW9kYXRlZC5cbiAgICAgICAgICAgICAgICBjb25zdCB7IHNlcmllcyB9ID0gaXNVbmRlZmluZWQoZXZlbnQucGF5bG9hZC5yZXN1bHQpXG4gICAgICAgICAgICAgICAgICAgID8gZXZlbnQucGF5bG9hZFxuICAgICAgICAgICAgICAgICAgICA6IGV2ZW50LnBheWxvYWQucmVzdWx0IHx8IHt9O1xuXG4gICAgICAgICAgICAgICAgaWYgKHNlcmllcykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRhdGFTb3VyY2VTZXJpZXMkLm5leHQoc2VyaWVzKTtcblxuICAgICAgICAgICAgICAgICAgICBsZXQgdXBkYXRlZFBpenphZ25hID0gdGhpcy5waXp6YWduYVNlcnZpY2UucGl6emFnbmE7XG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZWRQaXp6YWduYSA9IGltbXV0YWJsZVNldChcbiAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZWRQaXp6YWduYSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGAke3RoaXMuZm9ybVNlcmllc0NvbXBvbmVudFBhdGh9LmFsbFNlcmllc2AsXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXJpZXNcbiAgICAgICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzZXJpZXNUZW1wbGF0ZSA9XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBpenphZ25hU2VydmljZS5waXp6YWduYVtQaXp6YWduYUxheWVyLlN0cnVjdHVyZV1bXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb21wb25lbnQuY29tcG9uZW50SWRcbiAgICAgICAgICAgICAgICAgICAgICAgIF0ucHJvcGVydGllcz8udGVtcGxhdGU7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGljYXRvckRhdGFJbmRleCA9IHNlcmllc1RlbXBsYXRlLmZpbmRJbmRleChcbiAgICAgICAgICAgICAgICAgICAgICAgICh2YWw6IElJdGVtQ29uZmlndXJhdGlvbikgPT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWwuaWQgPT09IHRoaXMuaW5kaWNhdG9yRGF0YUtleVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBpbmRpY2F0b3JEYXRhUGF0aCA9IGAke1BpenphZ25hTGF5ZXIuU3RydWN0dXJlfS5zZXJpZXMucHJvcGVydGllcy50ZW1wbGF0ZVske2luZGljYXRvckRhdGFJbmRleH1dLnByb3BlcnRpZXMuYWxsU2VyaWVzYDtcbiAgICAgICAgICAgICAgICAgICAgdXBkYXRlZFBpenphZ25hID0gaW1tdXRhYmxlU2V0KFxuICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlZFBpenphZ25hLFxuICAgICAgICAgICAgICAgICAgICAgICAgaW5kaWNhdG9yRGF0YVBhdGgsXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXJpZXNcbiAgICAgICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwcmV2aWV3U2VyaWVzID0gZ2V0KFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXRQcmV2aWV3KCksXG4gICAgICAgICAgICAgICAgICAgICAgICBgY2hhcnQuJHt0aGlzLnByZXZpZXdTZXJpZXNQYXRofWAsXG4gICAgICAgICAgICAgICAgICAgICAgICBbXVxuICAgICAgICAgICAgICAgICAgICApIGFzIElUaW1lc2VyaWVzV2lkZ2V0U2VyaWVzW107XG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZWRQaXp6YWduYSA9IHByZXZpZXdTZXJpZXMucmVkdWNlKFxuICAgICAgICAgICAgICAgICAgICAgICAgKHJlcywgcykgPT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbW11dGFibGVTZXQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYCR7UGl6emFnbmFMYXllci5EYXRhfS4ke3MuaWR9LyR7dGhpcy5pbmRpY2F0b3JEYXRhS2V5fS5wcm9wZXJ0aWVzLmFsbFNlcmllc2AsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcmllc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVkUGl6emFnbmFcbiAgICAgICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUZvcm1QaXp6YWduYSh1cGRhdGVkUGl6emFnbmEpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIHVwZGF0aW5nIHByZXZpZXcgc2VyaWVzIGlmIG5vIHNlcmllcyBzZXQgaW4gZWRpdG9yLiB0aGlzIG9jY3VycyB3aGVuIGNoYW5naW5nIERTLCBmb3IgZXhhbXBsZS5cbiAgICAgICAgICAgICAgICAgICAgLy8gaW4gRFMgaXMgY2hhbmdpbmcgYWxsIHRoZSBzZXJpZXMgYXJlIHJlbW92ZWQgYW5kIHRoZW4gYWxsIHNlcmllcyBmcm9tIERTIHNob3VsZCBiZSBzZXQuXG4gICAgICAgICAgICAgICAgICAgIC8vIHRoYXQncyB3aHkgdXBkYXRpbmcgcHJldmlldyBzZXJpZXMuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVkaXRvclNlcmllc1BhdGggPSBgJHt0aGlzLmZvcm1TZXJpZXNDb21wb25lbnRQYXRofS5zZXJpZXNgO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlZGl0b3JTZXJpZXMgPSBnZXQoXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBpenphZ25hU2VydmljZS5waXp6YWduYSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGVkaXRvclNlcmllc1BhdGhcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzRW1wdHkoZWRpdG9yU2VyaWVzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zaG91bGRSZWFkRm9ybSA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzZXJpZXNGb3JQcmV2aWV3OiBJVGltZXNlcmllc1dpZGdldFNlcmllc1tdID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXJpZXMubWFwKChzOiBJVGltZXNlcmllc1dpZGdldERhdGEpID0+ICh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkOiBzLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZFNlcmllc0lkOiBzLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogcy5uYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVwZGF0ZWRQcmV2aWV3ID0gaW1tdXRhYmxlU2V0KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZ2V0UHJldmlldygpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBjaGFydC4ke3RoaXMucHJldmlld1Nlcmllc1BhdGh9YCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXJpZXNGb3JQcmV2aWV3XG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVQcmV2aWV3KHVwZGF0ZWRQcmV2aWV3KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5idWlsZEZvcm0oKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVBdmFpbGFibGVTZXJpZXMoW10pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2hvdWxkUmVhZEZvcm0gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcHVibGljIGJ1aWxkRm9ybSgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgcHJldmlldyA9IHRoaXMuZ2V0UHJldmlldygpO1xuICAgICAgICBjb25zdCBzZXJpZXMgPSBnZXQoXG4gICAgICAgICAgICBwcmV2aWV3LFxuICAgICAgICAgICAgYGNoYXJ0LiR7dGhpcy5wcmV2aWV3U2VyaWVzUGF0aH1gLFxuICAgICAgICAgICAgW11cbiAgICAgICAgKSBhcyBJVGltZXNlcmllc1dpZGdldFNlcmllc1tdO1xuICAgICAgICBjb25zdCBzZXJpZXNUb1NldCA9IHNlcmllcy5tYXAoXG4gICAgICAgICAgICAocykgPT5cbiAgICAgICAgICAgICAgICAoe1xuICAgICAgICAgICAgICAgICAgICBpZDogcy5pZCxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRTZXJpZXNJZDogcy5zZWxlY3RlZFNlcmllc0lkLFxuICAgICAgICAgICAgICAgIH0gYXMgSVRpbWVzZXJpZXNJdGVtQ29uZmlndXJhdGlvbilcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3Qgc2VyaWVzSWRzID0gc2VyaWVzLm1hcCgocykgPT4gcy5pZCk7XG5cbiAgICAgICAgdGhpcy5waXp6YWduYVNlcnZpY2UuY3JlYXRlQ29tcG9uZW50c0Zyb21UZW1wbGF0ZShcInNlcmllc1wiLCBzZXJpZXNJZHMpO1xuICAgICAgICBjb25zdCBlZGl0b3JQaXp6YWduYSA9IHRoaXMucGl6emFnbmFTZXJ2aWNlLnBpenphZ25hO1xuICAgICAgICBjb25zdCBwaXp6YWduYVdpdGhTZXJpZXMgPSBpbW11dGFibGVTZXQoXG4gICAgICAgICAgICBlZGl0b3JQaXp6YWduYSxcbiAgICAgICAgICAgIGAke3RoaXMuZm9ybVNlcmllc0NvbXBvbmVudFBhdGh9LnNlcmllc2AsXG4gICAgICAgICAgICBzZXJpZXNUb1NldFxuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMudXBkYXRlRm9ybVBpenphZ25hKHBpenphZ25hV2l0aFNlcmllcyk7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRTZXJpZXNJZHMkLm5leHQoXG4gICAgICAgICAgICBzZXJpZXNUb1NldC5tYXAoKHMpID0+IHMuc2VsZWN0ZWRTZXJpZXNJZClcbiAgICAgICAgKTtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiAodGhpcy5zaG91bGRSZWFkRm9ybSA9IHRydWUpKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgdG9QcmV2aWV3KGZvcm06IEZvcm1Hcm91cCk6IHZvaWQge1xuICAgICAgICBmb3JtLnZhbHVlQ2hhbmdlc1xuICAgICAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgoZm9ybVNlcmllcykgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghdGhpcy5zaG91bGRSZWFkRm9ybSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IHByZXZpZXcgPSB0aGlzLmdldFByZXZpZXcoKTtcbiAgICAgICAgICAgICAgICBjb25zdCB7IGNoYXJ0IH0gPSBwcmV2aWV3O1xuICAgICAgICAgICAgICAgIGNvbnN0IHNlcmllc0Zyb21QcmV2aWV3ID0gZ2V0KFxuICAgICAgICAgICAgICAgICAgICBjaGFydCxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcmV2aWV3U2VyaWVzUGF0aCxcbiAgICAgICAgICAgICAgICAgICAgW11cbiAgICAgICAgICAgICAgICApIGFzIElUaW1lc2VyaWVzV2lkZ2V0U2VyaWVzW107XG5cbiAgICAgICAgICAgICAgICBjb25zdCBzZXJpZXM6IElUaW1lc2VyaWVzV2lkZ2V0U2VyaWVzW10gPSBmb3JtU2VyaWVzLm1hcChcbiAgICAgICAgICAgICAgICAgICAgKHM6IElUaW1lc2VyaWVzV2lkZ2V0U2VyaWVzKSA9PiAoe1xuICAgICAgICAgICAgICAgICAgICAgICAgaWQ6IHMuaWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZFNlcmllc0lkOiBzLnNlbGVjdGVkU2VyaWVzSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAuLi5zZXJpZXNGcm9tUHJldmlldy5maW5kKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChwcmV2aWV3U2VyaWVzKSA9PiBwcmV2aWV3U2VyaWVzLmlkID09PSBzLmlkXG4gICAgICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCB1cGRhdGVkUHJldmlldyA9IGltbXV0YWJsZVNldChcbiAgICAgICAgICAgICAgICAgICAgcHJldmlldyxcbiAgICAgICAgICAgICAgICAgICAgYGNoYXJ0LiR7dGhpcy5wcmV2aWV3U2VyaWVzUGF0aH1gLFxuICAgICAgICAgICAgICAgICAgICBzZXJpZXNcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlUHJldmlldyh1cGRhdGVkUHJldmlldyk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBzZWxlY3RlZFNlcmllc0lkcyA9IGZvcm1TZXJpZXNcbiAgICAgICAgICAgICAgICAgICAgLm1hcCgoczogSVRpbWVzZXJpZXNXaWRnZXRTZXJpZXMpID0+XG4gICAgICAgICAgICAgICAgICAgICAgICBnZXQocywgYHByb3BlcnRpZXNbJHtzLmlkfS9pbmRpY2F0b3JEYXRhXS5pZGApXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgLmZpbHRlcigodjogYW55KSA9PiAhaXNFbXB0eSh2KSkgYXMgc3RyaW5nW107XG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RlZFNlcmllc0lkcyQubmV4dChzZWxlY3RlZFNlcmllc0lkcyk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZGF0YVNvdXJjZVNlcmllcyQuY29tcGxldGUoKTtcbiAgICAgICAgdGhpcy5zZWxlY3RlZFNlcmllc0lkcyQuY29tcGxldGUoKTtcbiAgICAgICAgc3VwZXIubmdPbkRlc3Ryb3koKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHVwZGF0ZUF2YWlsYWJsZVNlcmllcyhhdmFpbGFibGVTZXJpZXM6IElUaW1lc2VyaWVzV2lkZ2V0RGF0YVtdKSB7XG4gICAgICAgIGlmICghdGhpcy5waXp6YWduYVNlcnZpY2UucGl6emFnbmEpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCB1cGRhdGVkUGl6emFnbmEgPSB0aGlzLnBpenphZ25hU2VydmljZS5waXp6YWduYTtcblxuICAgICAgICAvLyBjb25maWd1cmF0aW9uIGNvbXBvbmVudFxuICAgICAgICB1cGRhdGVkUGl6emFnbmEgPSBpbW11dGFibGVTZXQoXG4gICAgICAgICAgICB1cGRhdGVkUGl6emFnbmEsXG4gICAgICAgICAgICBgJHt0aGlzLmZvcm1TZXJpZXNDb21wb25lbnRQYXRofS5hdmFpbGFibGVTZXJpZXNgLFxuICAgICAgICAgICAgYXZhaWxhYmxlU2VyaWVzXG4gICAgICAgICk7XG5cbiAgICAgICAgLy8gdGVtcGxhdGVcbiAgICAgICAgY29uc3Qgc2VyaWVzVGVtcGxhdGUgPVxuICAgICAgICAgICAgdGhpcy5waXp6YWduYVNlcnZpY2UucGl6emFnbmFbUGl6emFnbmFMYXllci5TdHJ1Y3R1cmVdW1xuICAgICAgICAgICAgICAgIHRoaXMuY29tcG9uZW50LmNvbXBvbmVudElkXG4gICAgICAgICAgICBdLnByb3BlcnRpZXM/LnRlbXBsYXRlO1xuICAgICAgICBjb25zdCBpbmRpY2F0b3JEYXRhSW5kZXggPSBzZXJpZXNUZW1wbGF0ZS5maW5kSW5kZXgoXG4gICAgICAgICAgICAodmFsOiBJVGltZXNlcmllc1dpZGdldFNlcmllcykgPT4gdmFsLmlkID09PSB0aGlzLmluZGljYXRvckRhdGFLZXlcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgaW5kaWNhdG9yRGF0YVBhdGggPSBgJHtQaXp6YWduYUxheWVyLlN0cnVjdHVyZX0uc2VyaWVzLnByb3BlcnRpZXMudGVtcGxhdGVbJHtpbmRpY2F0b3JEYXRhSW5kZXh9XS5wcm9wZXJ0aWVzLmF2YWlsYWJsZVNlcmllc2A7XG4gICAgICAgIHVwZGF0ZWRQaXp6YWduYSA9IGltbXV0YWJsZVNldChcbiAgICAgICAgICAgIHVwZGF0ZWRQaXp6YWduYSxcbiAgICAgICAgICAgIGluZGljYXRvckRhdGFQYXRoLFxuICAgICAgICAgICAgYXZhaWxhYmxlU2VyaWVzXG4gICAgICAgICk7XG5cbiAgICAgICAgLy8gYWxyZWFkeSBjcmVhdGVkIGZvcm1zXG4gICAgICAgIGNvbnN0IHNlcmllc0lkcyA9IGdldChcbiAgICAgICAgICAgIHRoaXMucGl6emFnbmFTZXJ2aWNlLnBpenphZ25hLFxuICAgICAgICAgICAgYCR7UGl6emFnbmFMYXllci5TdHJ1Y3R1cmV9LnNlcmllcy5wcm9wZXJ0aWVzLm5vZGVzYFxuICAgICAgICApIGFzIHVua25vd24gYXMgc3RyaW5nW107XG4gICAgICAgIHVwZGF0ZWRQaXp6YWduYSA9IHNlcmllc0lkcy5yZWR1Y2UoXG4gICAgICAgICAgICAocmVzLCBpZCkgPT5cbiAgICAgICAgICAgICAgICBpbW11dGFibGVTZXQoXG4gICAgICAgICAgICAgICAgICAgIHJlcyxcbiAgICAgICAgICAgICAgICAgICAgYCR7UGl6emFnbmFMYXllci5EYXRhfS4ke2lkfS8ke3RoaXMuaW5kaWNhdG9yRGF0YUtleX0ucHJvcGVydGllcy5hdmFpbGFibGVTZXJpZXNgLFxuICAgICAgICAgICAgICAgICAgICBhdmFpbGFibGVTZXJpZXNcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgdXBkYXRlZFBpenphZ25hXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy51cGRhdGVGb3JtUGl6emFnbmEodXBkYXRlZFBpenphZ25hKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN1YnNjcmliZVRvQXZhaWxhYmxlRGF0YUZpZWxkc0NoYW5nZSgpIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby1kZXByZWNhdGVkXG4gICAgICAgIGNvbWJpbmVMYXRlc3QoW3RoaXMuZGF0YVNvdXJjZVNlcmllcyQsIHRoaXMuc2VsZWN0ZWRTZXJpZXNJZHMkXSlcbiAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICAgIHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSxcbiAgICAgICAgICAgICAgICBtYXAoKFtkc1NlcmllcywgdXNlZFNlcmllc0lkc10pID0+XG4gICAgICAgICAgICAgICAgICAgIGRzU2VyaWVzLmZpbHRlcihcbiAgICAgICAgICAgICAgICAgICAgICAgIChkcykgPT4gIXVzZWRTZXJpZXNJZHMuZmluZCgoaWQpID0+IGlkID09PSBkcy5pZClcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoaXNFcXVhbClcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC5zdWJzY3JpYmUodGhpcy51cGRhdGVBdmFpbGFibGVTZXJpZXMuYmluZCh0aGlzKSk7XG4gICAgfVxufVxuIl19