@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
183 lines • 33.4 kB
JavaScript
// © 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 { Validators, } from "@angular/forms";
import get from "lodash/get";
import isEmpty from "lodash/isEmpty";
import isEqual from "lodash/isEqual";
import { distinctUntilChanged, distinctUntilKeyChanged, filter, map, pluck,
// eslint-disable-next-line import/no-deprecated
startWith, takeUntil, tap, } from "rxjs/operators";
import { EventBus, immutableSet } from "@nova-ui/bits";
import { PizzagnaService } from "../../../../pizzagna/services/pizzagna.service";
import { PizzagnaLayer, PIZZAGNA_EVENT_BUS } 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 TableColumnsConverterService extends BaseConverter {
constructor(eventBus, previewService, pizzagnaService) {
super(eventBus, previewService, pizzagnaService);
}
ngAfterViewInit() {
super.ngAfterViewInit();
}
buildForm() {
const table = this.getPreview()?.table;
const dataFields = table?.properties?.dataFields;
const columns = table?.properties?.configuration?.columns;
let formPizzagna = this.pizzagnaService.pizzagna;
formPizzagna = immutableSet(formPizzagna, `${PizzagnaLayer.Data}.columns.properties.columns`, columns ?? []);
formPizzagna = immutableSet(formPizzagna, `${PizzagnaLayer.Data}.columns.properties.dataFields`, dataFields);
this.updateFormPizzagna(formPizzagna);
}
toPreview(form) {
// table configurator v2 doesn't have `columnsOutput`, it just uses `columns` as source of truth
const formControl = form.contains("columnsOutput")
? form.get("columnsOutput")
: form.get("columns");
if (!formControl) {
throw new Error("FormControl is not defined!");
}
formControl.valueChanges
.pipe(takeUntil(this.destroy$), distinctUntilChanged(isEqual))
.subscribe((columns) => {
const columnsPath = "table.properties.configuration.columns";
// need to wait till forms are initialized in case of creating new column
setTimeout(() => {
const preview = this.getPreview();
this.updatePreview(immutableSet(preview, columnsPath, columns));
});
let formPizzagna = this.pizzagnaService.pizzagna;
// using setTimeout here updates the "filters" component properly - without it it doesn't update the dropdown with sortable columns
setTimeout(() => {
// hackfix for NUI-5712
// this assigment resolves a race condition that sometimes occured when data fields received from the data source would be
// overwritten by an "older" formPizzagna value assigned above
formPizzagna = immutableSet(formPizzagna, `${PizzagnaLayer.Structure}.columns.properties.template`, this.pizzagnaService.pizzagna[PizzagnaLayer.Structure]
.columns.properties?.template);
formPizzagna = immutableSet(formPizzagna, `${PizzagnaLayer.Data}.filters.properties.columns`, columns);
// this triggers change detection on the "filters" component
formPizzagna = immutableSet(formPizzagna, `${PizzagnaLayer.Structure}.presentation.properties.nodes`, [
...(formPizzagna?.structure?.presentation
?.properties?.nodes ?? []),
]);
this.updateFormPizzagna(formPizzagna);
});
});
this.subscribeToColumnsValueChange();
}
subscribeToColumnsValueChange() {
this.component.form
.get("columnsOutput")
?.valueChanges.pipe(
// trigger subscription after tableColumnsFormArray is filled with values
// eslint-disable-next-line import/no-deprecated
startWith(this.component.form.get("columnsOutput").value), filter((columns) => columns.length > 0), tap(() => this.handleWidthValidation()), map((columns) => this.filterColumnsWithoutSpecifiedWidth(columns)), map((activeColumnsWithoutWidth) => this.handleColumnsWithoutSpecifiedWidth(activeColumnsWithoutWidth)), distinctUntilKeyChanged("id"), pluck("id"), takeUntil(this.destroy$))
.subscribe((columnId) => this.setWidthMessages(columnId));
}
/**
* Filters columns which are active (visible) and don't have specified width
* @param columns
*/
filterColumnsWithoutSpecifiedWidth(columns) {
return columns.filter((column) => column.isActive && !column.width);
}
/**
* Receives columns which are active and don't have specified width and returns:
* - if all columns have specified width, reset width of the last column and return its id
* - if there are only one column, set this columns id as last without specified width
* - if there are more than one column that don't have specified width, do nothing
* @param activeColumnsWithoutWidth
*/
handleColumnsWithoutSpecifiedWidth(activeColumnsWithoutWidth) {
switch (activeColumnsWithoutWidth.length) {
// if all columns have specified width, reset last columns value so that other columns can resize
case 0: {
const activeColumns = this.component.form.get("columns").controls.filter((control) => get(control, `value.properties[${control.value.id}/description].isActive`));
if (isEmpty(activeColumns)) {
return {
id: undefined,
label: undefined,
};
}
const lastActiveColumn = activeColumns[activeColumns.length - 1];
console.warn(`Cannot set width for all columns. Resetting "${lastActiveColumn.value.label}" width.`);
lastActiveColumn.patchValue({ width: null }, { emitEvent: false });
return lastActiveColumn.value;
}
case 1:
return activeColumnsWithoutWidth[0];
default:
return {
id: undefined,
label: undefined,
};
}
}
handleWidthValidation() {
this.component.form.get("columns").controls.forEach((formGroup) => {
const descriptionFormPath = `properties.${formGroup.value.id}/description`;
const descriptionForm = formGroup.get(descriptionFormPath);
if (!descriptionForm) {
return;
}
const isActive = descriptionForm.get("isActive")?.value;
const widthFormField = descriptionForm.get("width");
if (isActive) {
widthFormField?.setValidators([Validators.min(62)]);
widthFormField?.markAllAsTouched();
widthFormField?.updateValueAndValidity({
emitEvent: false,
});
}
else {
widthFormField?.clearValidators();
widthFormField?.updateValueAndValidity({
emitEvent: false,
});
}
});
}
setWidthMessages(columnId) {
if (!this.pizzagnaService.pizzagna) {
return;
}
const widthMessageInput = "isWidthMessageDisplayed";
const { pizzagna } = this.pizzagnaService;
const columns = pizzagna.data.columns.properties?.columns;
columns.forEach((col) => this.pizzagnaService.setProperty(`${PizzagnaLayer.Data}.${col.id}/description.properties.${widthMessageInput}`, false));
if (!columnId) {
return;
}
this.pizzagnaService.setProperty(`${PizzagnaLayer.Data}.${columnId}/description.properties.${widthMessageInput}`, true);
}
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TableColumnsConverterService, 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: TableColumnsConverterService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TableColumnsConverterService, 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUtY29sdW1ucy1jb252ZXJ0ZXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvY29uZmlndXJhdG9yL3NlcnZpY2VzL2NvbnZlcnRlcnMvdGFibGUvdGFibGUtY29sdW1ucy1jb252ZXJ0ZXIuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx5REFBeUQ7QUFDekQsRUFBRTtBQUNGLCtFQUErRTtBQUMvRSw0RUFBNEU7QUFDNUUsOEVBQThFO0FBQzlFLCtFQUErRTtBQUMvRSw4RUFBOEU7QUFDOUUsNERBQTREO0FBQzVELEVBQUU7QUFDRiw2RUFBNkU7QUFDN0UsdURBQXVEO0FBQ3ZELEVBQUU7QUFDRiw2RUFBNkU7QUFDN0UsNEVBQTRFO0FBQzVFLCtFQUErRTtBQUMvRSwwRUFBMEU7QUFDMUUsaUZBQWlGO0FBQ2pGLDZFQUE2RTtBQUM3RSxpQkFBaUI7QUFFakIsT0FBTyxFQUFpQixNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2xFLE9BQU8sRUFJSCxVQUFVLEdBQ2IsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEdBQUcsTUFBTSxZQUFZLENBQUM7QUFDN0IsT0FBTyxPQUFPLE1BQU0sZ0JBQWdCLENBQUM7QUFDckMsT0FBTyxPQUFPLE1BQU0sZ0JBQWdCLENBQUM7QUFDckMsT0FBTyxFQUNILG9CQUFvQixFQUNwQix1QkFBdUIsRUFDdkIsTUFBTSxFQUNOLEdBQUcsRUFDSCxLQUFLO0FBQ0wsZ0RBQWdEO0FBQ2hELFNBQVMsRUFDVCxTQUFTLEVBQ1QsR0FBRyxHQUNOLE1BQU0sZ0JBQWdCLENBQUM7QUFFeEIsT0FBTyxFQUFFLFFBQVEsRUFBVSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHL0QsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGdEQUFnRCxDQUFDO0FBQ2pGLE9BQU8sRUFBRSxhQUFhLEVBQUUsa0JBQWtC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Q3JDLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLFFBQVEsRUFBRTtZQUNoQyxPQUFPO1NBQ1Y7UUFFRCxNQUFNLGlCQUFpQixHQUFHLHlCQUF5QixDQUFDO1FBQ3BELE1BQU0sRUFBRSxRQUFRLEVBQUUsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDO1FBQzFDLE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxPQUFPLENBQUM7UUFDMUQsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQTZCLEVBQUUsRUFBRSxDQUM5QyxJQUFJLENBQUMsZUFBZSxDQUFDLFdBQVcsQ0FDNUIsR0FBRyxhQUFhLENBQUMsSUFBSSxJQUFJLEdBQUcsQ0FBQyxFQUFFLDJCQUEyQixpQkFBaUIsRUFBRSxFQUM3RSxLQUFLLENBQ1IsQ0FDSixDQUFDO1FBRUYsSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNYLE9BQU87U0FDVjtRQUNELElBQUksQ0FBQyxlQUFlLENBQUMsV0FBVyxDQUM1QixHQUFHLGFBQWEsQ0FBQyxJQUFJLElBQUksUUFBUSwyQkFBMkIsaUJBQWlCLEVBQUUsRUFDL0UsSUFBSSxDQUNQLENBQUM7SUFDTixDQUFDO2tJQW5PUSw0QkFBNEIsa0JBS3pCLGtCQUFrQjtzSUFMckIsNEJBQTRCOzs0RkFBNUIsNEJBQTRCO2tCQUR4QyxVQUFVOzswQkFNRixNQUFNOzJCQUFDLGtCQUFrQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIMKpIDIwMjIgU29sYXJXaW5kcyBXb3JsZHdpZGUsIExMQy4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4vLyAgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG9cbi8vICBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZVxuLy8gIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vclxuLy8gIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4vLyAgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8gIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vICBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vICBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbi8vICBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4vLyAgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbi8vICBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOXG4vLyAgVEhFIFNPRlRXQVJFLlxuXG5pbXBvcnQgeyBBZnRlclZpZXdJbml0LCBJbmplY3QsIEluamVjdGFibGUgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHtcbiAgICBBYnN0cmFjdENvbnRyb2wsXG4gICAgRm9ybUFycmF5LFxuICAgIEZvcm1Hcm91cCxcbiAgICBWYWxpZGF0b3JzLFxufSBmcm9tIFwiQGFuZ3VsYXIvZm9ybXNcIjtcbmltcG9ydCBnZXQgZnJvbSBcImxvZGFzaC9nZXRcIjtcbmltcG9ydCBpc0VtcHR5IGZyb20gXCJsb2Rhc2gvaXNFbXB0eVwiO1xuaW1wb3J0IGlzRXF1YWwgZnJvbSBcImxvZGFzaC9pc0VxdWFsXCI7XG5pbXBvcnQge1xuICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkLFxuICAgIGRpc3RpbmN0VW50aWxLZXlDaGFuZ2VkLFxuICAgIGZpbHRlcixcbiAgICBtYXAsXG4gICAgcGx1Y2ssXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby1kZXByZWNhdGVkXG4gICAgc3RhcnRXaXRoLFxuICAgIHRha2VVbnRpbCxcbiAgICB0YXAsXG59IGZyb20gXCJyeGpzL29wZXJhdG9yc1wiO1xuXG5pbXBvcnQgeyBFdmVudEJ1cywgSUV2ZW50LCBpbW11dGFibGVTZXQgfSBmcm9tIFwiQG5vdmEtdWkvYml0c1wiO1xuXG5pbXBvcnQgeyBJVGFibGVXaWRnZXRDb2x1bW5Db25maWcgfSBmcm9tIFwiLi4vLi4vLi4vLi4vY29tcG9uZW50cy90YWJsZS13aWRnZXQvdHlwZXNcIjtcbmltcG9ydCB7IFBpenphZ25hU2VydmljZSB9IGZyb20gXCIuLi8uLi8uLi8uLi9waXp6YWduYS9zZXJ2aWNlcy9waXp6YWduYS5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBQaXp6YWduYUxheWVyLCBQSVpaQUdOQV9FVkVOVF9CVVMgfSBmcm9tIFwiLi4vLi4vLi4vLi4vdHlwZXNcIjtcbmltcG9ydCB7IElJdGVtQ29uZmlndXJhdGlvbiB9IGZyb20gXCIuLi8uLi8uLi9jb21wb25lbnRzL3R5cGVzXCI7XG5pbXBvcnQgeyBQcmV2aWV3U2VydmljZSB9IGZyb20gXCIuLi8uLi9wcmV2aWV3LnNlcnZpY2VcIjtcbmltcG9ydCB7IEJhc2VDb252ZXJ0ZXIgfSBmcm9tIFwiLi4vYmFzZS1jb252ZXJ0ZXJcIjtcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFRhYmxlQ29sdW1uc0NvbnZlcnRlclNlcnZpY2VcbiAgICBleHRlbmRzIEJhc2VDb252ZXJ0ZXJcbiAgICBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXRcbntcbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgQEluamVjdChQSVpaQUdOQV9FVkVOVF9CVVMpIGV2ZW50QnVzOiBFdmVudEJ1czxJRXZlbnQ+LFxuICAgICAgICBwcmV2aWV3U2VydmljZTogUHJldmlld1NlcnZpY2UsXG4gICAgICAgIHBpenphZ25hU2VydmljZTogUGl6emFnbmFTZXJ2aWNlXG4gICAgKSB7XG4gICAgICAgIHN1cGVyKGV2ZW50QnVzLCBwcmV2aWV3U2VydmljZSwgcGl6emFnbmFTZXJ2aWNlKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgICAgICBzdXBlci5uZ0FmdGVyVmlld0luaXQoKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYnVpbGRGb3JtKCk6IHZvaWQge1xuICAgICAgICBjb25zdCB0YWJsZSA9IHRoaXMuZ2V0UHJldmlldygpPy50YWJsZTtcbiAgICAgICAgY29uc3QgZGF0YUZpZWxkcyA9IHRhYmxlPy5wcm9wZXJ0aWVzPy5kYXRhRmllbGRzO1xuICAgICAgICBjb25zdCBjb2x1bW5zID0gdGFibGU/LnByb3BlcnRpZXM/LmNvbmZpZ3VyYXRpb24/LmNvbHVtbnM7XG5cbiAgICAgICAgbGV0IGZvcm1QaXp6YWduYSA9IHRoaXMucGl6emFnbmFTZXJ2aWNlLnBpenphZ25hO1xuXG4gICAgICAgIGZvcm1QaXp6YWduYSA9IGltbXV0YWJsZVNldChcbiAgICAgICAgICAgIGZvcm1QaXp6YWduYSxcbiAgICAgICAgICAgIGAke1BpenphZ25hTGF5ZXIuRGF0YX0uY29sdW1ucy5wcm9wZXJ0aWVzLmNvbHVtbnNgLFxuICAgICAgICAgICAgY29sdW1ucyA/PyBbXVxuICAgICAgICApO1xuICAgICAgICBmb3JtUGl6emFnbmEgPSBpbW11dGFibGVTZXQoXG4gICAgICAgICAgICBmb3JtUGl6emFnbmEsXG4gICAgICAgICAgICBgJHtQaXp6YWduYUxheWVyLkRhdGF9LmNvbHVtbnMucHJvcGVydGllcy5kYXRhRmllbGRzYCxcbiAgICAgICAgICAgIGRhdGFGaWVsZHNcbiAgICAgICAgKTtcblxuICAgICAgICB0aGlzLnVwZGF0ZUZvcm1QaXp6YWduYShmb3JtUGl6emFnbmEpO1xuICAgIH1cblxuICAgIHB1YmxpYyB0b1ByZXZpZXcoZm9ybTogRm9ybUdyb3VwKTogdm9pZCB7XG4gICAgICAgIC8vIHRhYmxlIGNvbmZpZ3VyYXRvciB2MiBkb2Vzbid0IGhhdmUgYGNvbHVtbnNPdXRwdXRgLCBpdCBqdXN0IHVzZXMgYGNvbHVtbnNgIGFzIHNvdXJjZSBvZiB0cnV0aFxuICAgICAgICBjb25zdCBmb3JtQ29udHJvbCA9IGZvcm0uY29udGFpbnMoXCJjb2x1bW5zT3V0cHV0XCIpXG4gICAgICAgICAgICA/IGZvcm0uZ2V0KFwiY29sdW1uc091dHB1dFwiKVxuICAgICAgICAgICAgOiBmb3JtLmdldChcImNvbHVtbnNcIik7XG5cbiAgICAgICAgaWYgKCFmb3JtQ29udHJvbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRm9ybUNvbnRyb2wgaXMgbm90IGRlZmluZWQhXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9ybUNvbnRyb2wudmFsdWVDaGFuZ2VzXG4gICAgICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCksIGRpc3RpbmN0VW50aWxDaGFuZ2VkKGlzRXF1YWwpKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgoY29sdW1uczogSVRhYmxlV2lkZ2V0Q29sdW1uQ29uZmlnW10pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBjb2x1bW5zUGF0aCA9IFwidGFibGUucHJvcGVydGllcy5jb25maWd1cmF0aW9uLmNvbHVtbnNcIjtcblxuICAgICAgICAgICAgICAgIC8vIG5lZWQgdG8gd2FpdCB0aWxsIGZvcm1zIGFyZSBpbml0aWFsaXplZCBpbiBjYXNlIG9mIGNyZWF0aW5nIG5ldyBjb2x1bW5cbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcHJldmlldyA9IHRoaXMuZ2V0UHJldmlldygpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZVByZXZpZXcoXG4gICAgICAgICAgICAgICAgICAgICAgICBpbW11dGFibGVTZXQocHJldmlldywgY29sdW1uc1BhdGgsIGNvbHVtbnMpXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICBsZXQgZm9ybVBpenphZ25hID0gdGhpcy5waXp6YWduYVNlcnZpY2UucGl6emFnbmE7XG5cbiAgICAgICAgICAgICAgICAvLyB1c2luZyBzZXRUaW1lb3V0IGhlcmUgdXBkYXRlcyB0aGUgXCJmaWx0ZXJzXCIgY29tcG9uZW50IHByb3Blcmx5IC0gd2l0aG91dCBpdCBpdCBkb2Vzbid0IHVwZGF0ZSB0aGUgZHJvcGRvd24gd2l0aCBzb3J0YWJsZSBjb2x1bW5zXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGhhY2tmaXggZm9yIE5VSS01NzEyXG4gICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgYXNzaWdtZW50IHJlc29sdmVzIGEgcmFjZSBjb25kaXRpb24gdGhhdCBzb21ldGltZXMgb2NjdXJlZCB3aGVuIGRhdGEgZmllbGRzIHJlY2VpdmVkIGZyb20gdGhlIGRhdGEgc291cmNlIHdvdWxkIGJlXG4gICAgICAgICAgICAgICAgICAgIC8vIG92ZXJ3cml0dGVuIGJ5IGFuIFwib2xkZXJcIiBmb3JtUGl6emFnbmEgdmFsdWUgYXNzaWduZWQgYWJvdmVcbiAgICAgICAgICAgICAgICAgICAgZm9ybVBpenphZ25hID0gaW1tdXRhYmxlU2V0KFxuICAgICAgICAgICAgICAgICAgICAgICAgZm9ybVBpenphZ25hLFxuICAgICAgICAgICAgICAgICAgICAgICAgYCR7UGl6emFnbmFMYXllci5TdHJ1Y3R1cmV9LmNvbHVtbnMucHJvcGVydGllcy50ZW1wbGF0ZWAsXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBpenphZ25hU2VydmljZS5waXp6YWduYVtQaXp6YWduYUxheWVyLlN0cnVjdHVyZV1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY29sdW1ucy5wcm9wZXJ0aWVzPy50ZW1wbGF0ZVxuICAgICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgICAgIGZvcm1QaXp6YWduYSA9IGltbXV0YWJsZVNldChcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1QaXp6YWduYSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGAke1BpenphZ25hTGF5ZXIuRGF0YX0uZmlsdGVycy5wcm9wZXJ0aWVzLmNvbHVtbnNgLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29sdW1uc1xuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAvLyB0aGlzIHRyaWdnZXJzIGNoYW5nZSBkZXRlY3Rpb24gb24gdGhlIFwiZmlsdGVyc1wiIGNvbXBvbmVudFxuICAgICAgICAgICAgICAgICAgICBmb3JtUGl6emFnbmEgPSBpbW11dGFibGVTZXQoXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3JtUGl6emFnbmEsXG4gICAgICAgICAgICAgICAgICAgICAgICBgJHtQaXp6YWduYUxheWVyLlN0cnVjdHVyZX0ucHJlc2VudGF0aW9uLnByb3BlcnRpZXMubm9kZXNgLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLihmb3JtUGl6emFnbmE/LnN0cnVjdHVyZT8ucHJlc2VudGF0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8ucHJvcGVydGllcz8ubm9kZXMgPz8gW10pLFxuICAgICAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlRm9ybVBpenphZ25hKGZvcm1QaXp6YWduYSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLnN1YnNjcmliZVRvQ29sdW1uc1ZhbHVlQ2hhbmdlKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdWJzY3JpYmVUb0NvbHVtbnNWYWx1ZUNoYW5nZSgpIHtcbiAgICAgICAgdGhpcy5jb21wb25lbnQuZm9ybVxuICAgICAgICAgICAgLmdldChcImNvbHVtbnNPdXRwdXRcIilcbiAgICAgICAgICAgID8udmFsdWVDaGFuZ2VzLnBpcGUoXG4gICAgICAgICAgICAgICAgLy8gdHJpZ2dlciBzdWJzY3JpcHRpb24gYWZ0ZXIgdGFibGVDb2x1bW5zRm9ybUFycmF5IGlzIGZpbGxlZCB3aXRoIHZhbHVlc1xuICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tZGVwcmVjYXRlZFxuICAgICAgICAgICAgICAgIHN0YXJ0V2l0aCh0aGlzLmNvbXBvbmVudC5mb3JtLmdldChcImNvbHVtbnNPdXRwdXRcIikudmFsdWUpLFxuICAgICAgICAgICAgICAgIGZpbHRlcigoY29sdW1uczogSUl0ZW1Db25maWd1cmF0aW9uW10pID0+IGNvbHVtbnMubGVuZ3RoID4gMCksXG4gICAgICAgICAgICAgICAgdGFwKCgpID0+IHRoaXMuaGFuZGxlV2lkdGhWYWxpZGF0aW9uKCkpLFxuICAgICAgICAgICAgICAgIG1hcCgoY29sdW1uczogSVRhYmxlV2lkZ2V0Q29sdW1uQ29uZmlnW10pID0+XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmlsdGVyQ29sdW1uc1dpdGhvdXRTcGVjaWZpZWRXaWR0aChjb2x1bW5zKVxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgbWFwKChhY3RpdmVDb2x1bW5zV2l0aG91dFdpZHRoOiBJVGFibGVXaWRnZXRDb2x1bW5Db25maWdbXSkgPT5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVDb2x1bW5zV2l0aG91dFNwZWNpZmllZFdpZHRoKFxuICAgICAgICAgICAgICAgICAgICAgICAgYWN0aXZlQ29sdW1uc1dpdGhvdXRXaWR0aFxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICBkaXN0aW5jdFVudGlsS2V5Q2hhbmdlZChcImlkXCIpLFxuICAgICAgICAgICAgICAgIHBsdWNrKFwiaWRcIiksXG4gICAgICAgICAgICAgICAgdGFrZVVudGlsKHRoaXMuZGVzdHJveSQpXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAuc3Vic2NyaWJlKChjb2x1bW5JZDogc3RyaW5nKSA9PiB0aGlzLnNldFdpZHRoTWVzc2FnZXMoY29sdW1uSWQpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGaWx0ZXJzIGNvbHVtbnMgd2hpY2ggYXJlIGFjdGl2ZSAodmlzaWJsZSkgYW5kIGRvbid0IGhhdmUgc3BlY2lmaWVkIHdpZHRoXG4gICAgICogQHBhcmFtIGNvbHVtbnNcbiAgICAgKi9cbiAgICBwcml2YXRlIGZpbHRlckNvbHVtbnNXaXRob3V0U3BlY2lmaWVkV2lkdGgoXG4gICAgICAgIGNvbHVtbnM6IElUYWJsZVdpZGdldENvbHVtbkNvbmZpZ1tdXG4gICAgKSB7XG4gICAgICAgIHJldHVybiBjb2x1bW5zLmZpbHRlcigoY29sdW1uKSA9PiBjb2x1bW4uaXNBY3RpdmUgJiYgIWNvbHVtbi53aWR0aCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVjZWl2ZXMgY29sdW1ucyB3aGljaCBhcmUgYWN0aXZlIGFuZCBkb24ndCBoYXZlIHNwZWNpZmllZCB3aWR0aCBhbmQgcmV0dXJuczpcbiAgICAgKiAtIGlmIGFsbCBjb2x1bW5zIGhhdmUgc3BlY2lmaWVkIHdpZHRoLCByZXNldCB3aWR0aCBvZiB0aGUgbGFzdCBjb2x1bW4gYW5kIHJldHVybiBpdHMgaWRcbiAgICAgKiAtIGlmIHRoZXJlIGFyZSBvbmx5IG9uZSBjb2x1bW4sIHNldCB0aGlzIGNvbHVtbnMgaWQgYXMgbGFzdCB3aXRob3V0IHNwZWNpZmllZCB3aWR0aFxuICAgICAqIC0gaWYgdGhlcmUgYXJlIG1vcmUgdGhhbiBvbmUgY29sdW1uIHRoYXQgZG9uJ3QgaGF2ZSBzcGVjaWZpZWQgd2lkdGgsIGRvIG5vdGhpbmdcbiAgICAgKiBAcGFyYW0gYWN0aXZlQ29sdW1uc1dpdGhvdXRXaWR0aFxuICAgICAqL1xuICAgIHByaXZhdGUgaGFuZGxlQ29sdW1uc1dpdGhvdXRTcGVjaWZpZWRXaWR0aChcbiAgICAgICAgYWN0aXZlQ29sdW1uc1dpdGhvdXRXaWR0aDogQXJyYXk8SVRhYmxlV2lkZ2V0Q29sdW1uQ29uZmlnPlxuICAgICkge1xuICAgICAgICBzd2l0Y2ggKGFjdGl2ZUNvbHVtbnNXaXRob3V0V2lkdGgubGVuZ3RoKSB7XG4gICAgICAgICAgICAvLyBpZiBhbGwgY29sdW1ucyBoYXZlIHNwZWNpZmllZCB3aWR0aCwgcmVzZXQgbGFzdCBjb2x1bW5zIHZhbHVlIHNvIHRoYXQgb3RoZXIgY29sdW1ucyBjYW4gcmVzaXplXG4gICAgICAgICAgICBjYXNlIDA6IHtcbiAgICAgICAgICAgICAgICBjb25zdCBhY3RpdmVDb2x1bW5zID0gKFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbXBvbmVudC5mb3JtLmdldChcImNvbHVtbnNcIikgYXMgRm9ybUFycmF5XG4gICAgICAgICAgICAgICAgKS5jb250cm9scy5maWx0ZXIoKGNvbnRyb2wpID0+XG4gICAgICAgICAgICAgICAgICAgIGdldChcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2wsXG4gICAgICAgICAgICAgICAgICAgICAgICBgdmFsdWUucHJvcGVydGllc1ske2NvbnRyb2wudmFsdWUuaWR9L2Rlc2NyaXB0aW9uXS5pc0FjdGl2ZWBcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgaWYgKGlzRW1wdHkoYWN0aXZlQ29sdW1ucykpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlkOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBsYXN0QWN0aXZlQ29sdW1uID1cbiAgICAgICAgICAgICAgICAgICAgYWN0aXZlQ29sdW1uc1thY3RpdmVDb2x1bW5zLmxlbmd0aCAtIDFdO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICAgICAgICAgYENhbm5vdCBzZXQgd2lkdGggZm9yIGFsbCBjb2x1bW5zLiBSZXNldHRpbmcgXCIke2xhc3RBY3RpdmVDb2x1bW4udmFsdWUubGFiZWx9XCIgd2lkdGguYFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgbGFzdEFjdGl2ZUNvbHVtbi5wYXRjaFZhbHVlKFxuICAgICAgICAgICAgICAgICAgICB7IHdpZHRoOiBudWxsIH0sXG4gICAgICAgICAgICAgICAgICAgIHsgZW1pdEV2ZW50OiBmYWxzZSB9XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbGFzdEFjdGl2ZUNvbHVtbi52YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgICAgICByZXR1cm4gYWN0aXZlQ29sdW1uc1dpdGhvdXRXaWR0aFswXTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgaWQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBoYW5kbGVXaWR0aFZhbGlkYXRpb24oKSB7XG4gICAgICAgICh0aGlzLmNvbXBvbmVudC5mb3JtLmdldChcImNvbHVtbnNcIikgYXMgRm9ybUFycmF5KS5jb250cm9scy5mb3JFYWNoKFxuICAgICAgICAgICAgKGZvcm1Hcm91cDogQWJzdHJhY3RDb250cm9sKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGVzY3JpcHRpb25Gb3JtUGF0aCA9IGBwcm9wZXJ0aWVzLiR7Zm9ybUdyb3VwLnZhbHVlLmlkfS9kZXNjcmlwdGlvbmA7XG4gICAgICAgICAgICAgICAgY29uc3QgZGVzY3JpcHRpb25Gb3JtID0gZm9ybUdyb3VwLmdldChkZXNjcmlwdGlvbkZvcm1QYXRoKTtcblxuICAgICAgICAgICAgICAgIGlmICghZGVzY3JpcHRpb25Gb3JtKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgaXNBY3RpdmUgPSBkZXNjcmlwdGlvbkZvcm0uZ2V0KFwiaXNBY3RpdmVcIik/LnZhbHVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IHdpZHRoRm9ybUZpZWxkID0gZGVzY3JpcHRpb25Gb3JtLmdldChcIndpZHRoXCIpO1xuICAgICAgICAgICAgICAgIGlmIChpc0FjdGl2ZSkge1xuICAgICAgICAgICAgICAgICAgICB3aWR0aEZvcm1GaWVsZD8uc2V0VmFsaWRhdG9ycyhbVmFsaWRhdG9ycy5taW4oNjIpXSk7XG4gICAgICAgICAgICAgICAgICAgIHdpZHRoRm9ybUZpZWxkPy5tYXJrQWxsQXNUb3VjaGVkKCk7XG4gICAgICAgICAgICAgICAgICAgIHdpZHRoRm9ybUZpZWxkPy51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVtaXRFdmVudDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHdpZHRoRm9ybUZpZWxkPy5jbGVhclZhbGlkYXRvcnMoKTtcbiAgICAgICAgICAgICAgICAgICAgd2lkdGhGb3JtRmllbGQ/LnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoe1xuICAgICAgICAgICAgICAgICAgICAgICAgZW1pdEV2ZW50OiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2V0V2lkdGhNZXNzYWdlcyhjb2x1bW5JZDogc3RyaW5nKSB7XG4gICAgICAgIGlmICghdGhpcy5waXp6YWduYVNlcnZpY2UucGl6emFnbmEpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHdpZHRoTWVzc2FnZUlucHV0ID0gXCJpc1dpZHRoTWVzc2FnZURpc3BsYXllZFwiO1xuICAgICAgICBjb25zdCB7IHBpenphZ25hIH0gPSB0aGlzLnBpenphZ25hU2VydmljZTtcbiAgICAgICAgY29uc3QgY29sdW1ucyA9IHBpenphZ25hLmRhdGEuY29sdW1ucy5wcm9wZXJ0aWVzPy5jb2x1bW5zO1xuICAgICAgICBjb2x1bW5zLmZvckVhY2goKGNvbDogSVRhYmxlV2lkZ2V0Q29sdW1uQ29uZmlnKSA9PlxuICAgICAgICAgICAgdGhpcy5waXp6YWduYVNlcnZpY2Uuc2V0UHJvcGVydHkoXG4gICAgICAgICAgICAgICAgYCR7UGl6emFnbmFMYXllci5EYXRhfS4ke2NvbC5pZH0vZGVzY3JpcHRpb24ucHJvcGVydGllcy4ke3dpZHRoTWVzc2FnZUlucHV0fWAsXG4gICAgICAgICAgICAgICAgZmFsc2VcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoIWNvbHVtbklkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5waXp6YWduYVNlcnZpY2Uuc2V0UHJvcGVydHkoXG4gICAgICAgICAgICBgJHtQaXp6YWduYUxheWVyLkRhdGF9LiR7Y29sdW1uSWR9L2Rlc2NyaXB0aW9uLnByb3BlcnRpZXMuJHt3aWR0aE1lc3NhZ2VJbnB1dH1gLFxuICAgICAgICAgICAgdHJ1ZVxuICAgICAgICApO1xuICAgIH1cbn1cbiJdfQ==