@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
227 lines • 57 kB
JavaScript
import { Component, Input, Optional, ViewChild } from '@angular/core';
import { ControlContainer, FormBuilder, NgForm, ReactiveFormsModule, Validators } from '@angular/forms';
import { DatapointSelectorModule } from '@c8y/ngx-components/datapoint-selector';
import { WidgetConfigComponent } from '@c8y/ngx-components/context-dashboard';
import { CommonModule, DynamicComponentComponent, FormGroupComponent, FormsModule, gettext, MeasurementRealtimeService, MessagesComponent } from '@c8y/ngx-components';
import { Subject, takeUntil } from 'rxjs';
import { defaultWidgetIds } from '@c8y/ngx-components/widgets/definitions';
import { RadialGaugeViewComponent } from '../radial-gauge/radial-gauge.component';
import { InfoGaugeCurrentMeasurementPipe } from '../current-measurement.pipe';
import { GAUGE_PRESET_NAMES, GAUGE_PRESETS } from './gauge.model';
import { EditorComponent, MonacoEditorMarkerValidatorDirective } from '@c8y/ngx-components/editor';
import { CollapseModule } from 'ngx-bootstrap/collapse';
import { PresetPreviewComponent } from './preset-preview/preset-preview.component';
import * as i0 from "@angular/core";
import * as i1 from "@angular/forms";
import * as i2 from "@c8y/ngx-components/context-dashboard";
import * as i3 from "@c8y/ngx-components";
import * as i4 from "@angular/common";
import * as i5 from "ngx-bootstrap/collapse";
import * as i6 from "@c8y/ngx-components/datapoint-selector";
function ensureAtLeastOneDatapointSelectedAndActive(datapointListAttributes) {
return (control) => {
const formValue = control.value;
for (const listAttributeName of datapointListAttributes) {
const valueForList = formValue[listAttributeName];
if (!valueForList || !Array.isArray(valueForList)) {
continue;
}
if (valueForList.find(dp => dp.__active)) {
return null;
}
}
return { noActiveDatapoint: true };
};
}
export class InfoGaugeWidgetConfigComponent {
constructor(formBuilder, form, widgetConfig, dynamicComponent) {
this.formBuilder = formBuilder;
this.form = form;
this.widgetConfig = widgetConfig;
this.dynamicComponent = dynamicComponent;
this.datapointSelectionConfig = {};
this.defaultFormOptions = {
showRedRange: true,
showYellowRange: true,
showRange: true,
selectableChartRenderTypes: []
};
this.showAdvancedOptions = false;
this.gaugeOptionsString = '';
this.showAdvancedOptionsLabel = gettext('Show advanced options');
this.hideAdvancedOptionsLabel = gettext('Hide advanced options');
this.ALL_GAUGE_PRESETS = [...GAUGE_PRESETS];
this.limits = {
numberOfDecimalPlacesMax: 10,
numberOfDecimalPlacesMin: 0
};
this.GAUGE_PRESETS = GAUGE_PRESETS;
this.destroy$ = new Subject();
}
onBeforeSave(config) {
if (this.formGroup.valid) {
Object.assign(config, this.formGroup.value);
Object.assign(config, {
gaugeOptions: this.gaugeOptions,
selectedPresetId: this.isInfoGauge ? null : this.getPresetId(this.gaugeOptions)
});
return true;
}
return false;
}
ngOnInit() {
if (this.widgetConfig.context?.id) {
this.datapointSelectionConfig.contextAsset = this.widgetConfig?.context;
}
this.initForm();
if (this.config?.datapointsLabels) {
this.formGroup.patchValue({ datapointsLabels: this.config.datapointsLabels });
}
if (this.config?.datapointsGauge) {
this.formGroup.patchValue({ datapointsGauge: this.config.datapointsGauge });
}
if (typeof this.config?.fractionSize === 'number' && !Number.isNaN(this.config?.fractionSize)) {
this.formGroup.patchValue({ fractionSize: this.config.fractionSize });
}
this.isInfoGauge = this.dynamicComponent?.componentId === defaultWidgetIds.INFO_GAUGE;
const isRadialGauge = !this.isInfoGauge;
if (isRadialGauge) {
this.setupRadialGauge();
}
this.formGroup.valueChanges.pipe(takeUntil(this.destroy$)).subscribe(value => {
if (value.datapointsGauge) {
this.activeDatapointGauge = value.datapointsGauge.find(dp => dp.__active);
}
});
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
onRadioPresetChange(presetId) {
// Find the selected preset
const selectedPreset = this.ALL_GAUGE_PRESETS.find(preset => preset.id === presetId);
if (selectedPreset) {
this.gaugeOptions = { ...selectedPreset }; // Update gaugeOptions with the selected preset
this.gaugeOptionsString = JSON.stringify(this.gaugeOptions, null, 2);
// If the selected preset is not custom, hide advanced options
if (selectedPreset.id !== 'custom') {
this.showAdvancedOptions = false;
}
// Update the form control value
this.formGroup.patchValue({ gaugePresetId: selectedPreset.id });
}
}
async assignSchema() {
const { schema } = await import('c8y-schema-loader?interfaceName=GaugeOptions!@c8y/ngx-components/widgets/implementations/info-gauge');
this.editorComponent.monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
validate: true,
schemas: [
{
uri: 'gauge-schema.json',
schema: schema,
fileMatch: ['*']
}
],
enableSchemaRequest: false,
allowComments: false
});
}
gaugeJSONChange(value) {
try {
const parsedOptions = JSON.parse(value);
// Check if the parsed options match any existing preset
const matchingPreset = this.GAUGE_PRESETS.find(preset => JSON.stringify(preset) === JSON.stringify(parsedOptions));
if (matchingPreset) {
this.formGroup.patchValue({ gaugePresetId: matchingPreset.id });
}
else {
this.gaugeOptions = parsedOptions;
this.gaugeOptions.name = GAUGE_PRESET_NAMES.CUSTOM;
this.gaugeOptions.id = 'custom';
const customPresetExists = this.ALL_GAUGE_PRESETS.some(preset => preset.id === 'custom');
if (!customPresetExists) {
this.ALL_GAUGE_PRESETS = [...this.ALL_GAUGE_PRESETS, this.gaugeOptions];
}
else {
this.ALL_GAUGE_PRESETS = this.ALL_GAUGE_PRESETS.map(preset => preset.id === 'custom' ? this.gaugeOptions : preset);
}
this.formGroup.patchValue({ gaugePresetId: 'custom' });
}
}
catch (error) {
console.error('Invalid JSON:', error);
}
}
trackByFn(_index, item) {
return item.id;
}
getPresetId(gaugeOptions) {
const matchingPreset = this.GAUGE_PRESETS.find(preset => preset.id === gaugeOptions.id);
return matchingPreset ? matchingPreset.id : 'custom';
}
setupRadialGauge() {
if (this.config.datapoints && !this.config.datapointsGauge) {
this.config.datapointsGauge = this.config.datapoints;
}
this.gaugeOptions = this.config.gaugeOptions || { ...this.GAUGE_PRESETS[0] };
if (this.config.selectedPresetId === 'custom') {
this.gaugeOptions.name = GAUGE_PRESET_NAMES.CUSTOM;
this.gaugeOptions.id = 'custom';
this.ALL_GAUGE_PRESETS = [...this.GAUGE_PRESETS, this.config.gaugeOptions];
this.formGroup.patchValue({ gaugePresetId: 'custom' });
}
this.gaugeOptionsString = JSON.stringify(this.gaugeOptions, null, 2);
}
initForm() {
this.formGroup = this.createForm();
this.form.form.addControl('config', this.formGroup);
this.formGroup.patchValue(this.config);
}
createForm() {
return this.formBuilder.group({
fractionSize: [
2,
[
Validators.required,
Validators.min(this.limits.numberOfDecimalPlacesMin),
Validators.max(this.limits.numberOfDecimalPlacesMax)
]
],
datapointsLabels: this.formBuilder.control(new Array(), []),
datapointsGauge: this.formBuilder.control(new Array(), []),
gaugePresetId: [this.config.selectedPresetId || 'default']
}, {
validators: [
ensureAtLeastOneDatapointSelectedAndActive(['datapointsLabels', 'datapointsGauge'])
]
});
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: InfoGaugeWidgetConfigComponent, deps: [{ token: i1.FormBuilder }, { token: i1.NgForm }, { token: i2.WidgetConfigComponent }, { token: i3.DynamicComponentComponent, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: InfoGaugeWidgetConfigComponent, isStandalone: true, selector: "c8y-info-gauge-widget-config", inputs: { config: "config" }, providers: [MeasurementRealtimeService], viewQueries: [{ propertyName: "editorComponent", first: true, predicate: EditorComponent, descendants: true }], ngImport: i0, template: "<form\n class=\"fit-h\"\n [formGroup]=\"formGroup\"\n>\n <div\n class=\"m-l-16 m-r-16\"\n *ngIf=\"isInfoGauge; else radialGauge\"\n >\n <div class=\"row\">\n <div class=\"col-md-6\">\n <c8y-form-group class=\"p-t-8\">\n <label translate>Decimal places</label>\n <input\n class=\"form-control\"\n name=\"fractionSize\"\n type=\"number\"\n formControlName=\"fractionSize\"\n step=\"1\"\n />\n <c8y-messages [show]=\"formGroup.controls.fractionSize.errors\"></c8y-messages>\n </c8y-form-group>\n </div>\n <div class=\"col-md-6 p-t-8\">\n <div\n class=\"alert alert-info\"\n role=\"alert\"\n *ngIf=\"formGroup.errors?.noActiveDatapoint\"\n translate\n >\n At least one data point for the labels or the gauge needs to be selected.\n </div>\n </div>\n </div>\n\n <div class=\"row\">\n <div class=\"col-md-6\">\n <c8y-datapoint-selection-list\n class=\"bg-inherit separator-top p-t-16 d-block\"\n listTitle=\"{{ 'Multiple label and value pairs' | translate }}\"\n name=\"datapoints\"\n [defaultFormOptions]=\"defaultFormOptions\"\n [config]=\"datapointSelectionConfig\"\n [minActiveCount]=\"0\"\n formControlName=\"datapointsLabels\"\n ></c8y-datapoint-selection-list>\n </div>\n <div class=\"col-md-6\">\n <c8y-datapoint-selection-list\n class=\"bg-inherit separator-top p-t-16 d-block\"\n listTitle=\"{{ 'Gauge`display`' | translate }}\"\n name=\"datapoints\"\n [defaultFormOptions]=\"defaultFormOptions\"\n [config]=\"datapointSelectionConfig\"\n [minActiveCount]=\"0\"\n [maxActiveCount]=\"1\"\n formControlName=\"datapointsGauge\"\n ></c8y-datapoint-selection-list>\n </div>\n </div>\n </div>\n\n <ng-template #radialGauge>\n <div class=\"d-flex-md fit-h\">\n <div class=\"col-md-6 inner-scroll p-0 bg-component\">\n <c8y-datapoint-selection-list\n class=\"bg-inherit d-block\"\n listTitle=\"{{ 'Data points`display`' | translate }}\"\n name=\"datapoints\"\n [defaultFormOptions]=\"defaultFormOptions\"\n [config]=\"datapointSelectionConfig\"\n [minActiveCount]=\"0\"\n [maxActiveCount]=\"1\"\n formControlName=\"datapointsGauge\"\n ></c8y-datapoint-selection-list>\n\n <c8y-form-group class=\"p-t-8 p-r-16 p-l-16\">\n <label translate>Decimal places</label>\n <input\n class=\"form-control\"\n name=\"fractionSize\"\n type=\"number\"\n formControlName=\"fractionSize\"\n step=\"1\"\n />\n <c8y-messages [show]=\"formGroup.controls.fractionSize.errors\"></c8y-messages>\n </c8y-form-group>\n\n <div class=\"form-group p-r-16 p-l-16 m-b-0\">\n <legend>\n {{ 'Presets' | translate }}\n </legend>\n <c8y-preset-preview\n formControlName=\"gaugePresetId\"\n [ALL_GAUGE_PRESETS]=\"ALL_GAUGE_PRESETS\"\n (onPresetChange)=\"onRadioPresetChange($event)\"\n ></c8y-preset-preview>\n </div>\n\n <div class=\"p-16\">\n <button\n class=\"btn btn-default\"\n aria-controls=\"advancedCollapse\"\n [attr.aria-expanded]=\"showAdvancedOptions\"\n type=\"button\"\n (click)=\"showAdvancedOptions = !showAdvancedOptions\"\n >\n {{ showAdvancedOptions ? hideAdvancedOptionsLabel : showAdvancedOptionsLabel }}\n </button>\n </div>\n\n <div\n class=\"collapse\"\n id=\"advancedCollapse\"\n [collapse]=\"!showAdvancedOptions\"\n [isAnimated]=\"true\"\n >\n <div\n class=\"fit-h\"\n style=\"min-height: 400px\"\n >\n <c8y-editor\n [ngModel]=\"gaugeOptionsString\"\n (ngModelChange)=\"gaugeJSONChange($event)\"\n (editorInit)=\"assignSchema()\"\n [ngModelOptions]=\"{ standalone: true }\"\n monacoEditorMarkerValidator\n ></c8y-editor>\n </div>\n </div>\n </div>\n <div\n class=\"col-md-6\"\n *ngIf=\"\n this.formGroup.value.datapointsGauge.length > 0 && activeDatapointGauge;\n else emptyState\n \"\n >\n <!-- Radial Gauge -->\n <c8y-radial-gauge\n class=\"c8y-radial-gauge--square\"\n *ngIf=\"activeDatapointGauge | infoGaugeCurrentMeasurement | async as measurement\"\n [activeDatapointGauge]=\"activeDatapointGauge\"\n [measurement]=\"measurement\"\n [fractionSize]=\"formGroup.value.fractionSize\"\n [gaugeOptions]=\"gaugeOptions\"\n [selectedPresetId]=\"formGroup.value.gaugePresetId\"\n ></c8y-radial-gauge>\n </div>\n </div>\n </ng-template>\n</form>\n\n<ng-template #emptyState>\n <div class=\"col-md-6 d-col a-i-start j-c-center\">\n <c8y-ui-empty-state\n [icon]=\"'c8y-data-points'\"\n [title]=\"'Please select a data point first.' | translate\"\n [horizontal]=\"false\"\n ></c8y-ui-empty-state>\n </div>\n</ng-template>\n", dependencies: [{ kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "ngmodule", type: CommonModule }, { kind: "component", type: i3.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "pipe", type: i3.C8yTranslatePipe, name: "translate" }, { kind: "directive", type: i3.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "ngmodule", type: CollapseModule }, { kind: "directive", type: i5.CollapseDirective, selector: "[collapse]", inputs: ["display", "isAnimated", "collapse"], outputs: ["collapsed", "collapses", "expanded", "expands"], exportAs: ["bs-collapse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: EditorComponent, selector: "c8y-editor", inputs: ["editorOptions"], outputs: ["editorInit"] }, { kind: "directive", type: MonacoEditorMarkerValidatorDirective, selector: "c8y-editor [monacoEditorMarkerValidator]" }, { kind: "ngmodule", type: DatapointSelectorModule }, { kind: "component", type: i6.DatapointSelectionListComponent, selector: "c8y-datapoint-selection-list", inputs: ["actions", "allowDragAndDrop", "config", "defaultFormOptions", "maxActiveCount", "minActiveCount", "resolveContext", "listTitle"], outputs: ["isValid", "change"] }, { kind: "component", type: RadialGaugeViewComponent, selector: "c8y-radial-gauge", inputs: ["activeDatapointGauge", "measurement", "fractionSize", "gaugeOptions", "selectedPresetId"] }, { kind: "pipe", type: InfoGaugeCurrentMeasurementPipe, name: "infoGaugeCurrentMeasurement" }, { kind: "component", type: PresetPreviewComponent, selector: "c8y-preset-preview", inputs: ["ALL_GAUGE_PRESETS"], outputs: ["onPresetChange"] }], viewProviders: [{ provide: ControlContainer, useExisting: NgForm }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: InfoGaugeWidgetConfigComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-info-gauge-widget-config', viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], providers: [MeasurementRealtimeService], standalone: true, imports: [
FormGroupComponent,
MessagesComponent,
CommonModule,
FormsModule,
CollapseModule,
ReactiveFormsModule,
EditorComponent,
MonacoEditorMarkerValidatorDirective,
DatapointSelectorModule,
RadialGaugeViewComponent,
InfoGaugeCurrentMeasurementPipe,
PresetPreviewComponent
], template: "<form\n class=\"fit-h\"\n [formGroup]=\"formGroup\"\n>\n <div\n class=\"m-l-16 m-r-16\"\n *ngIf=\"isInfoGauge; else radialGauge\"\n >\n <div class=\"row\">\n <div class=\"col-md-6\">\n <c8y-form-group class=\"p-t-8\">\n <label translate>Decimal places</label>\n <input\n class=\"form-control\"\n name=\"fractionSize\"\n type=\"number\"\n formControlName=\"fractionSize\"\n step=\"1\"\n />\n <c8y-messages [show]=\"formGroup.controls.fractionSize.errors\"></c8y-messages>\n </c8y-form-group>\n </div>\n <div class=\"col-md-6 p-t-8\">\n <div\n class=\"alert alert-info\"\n role=\"alert\"\n *ngIf=\"formGroup.errors?.noActiveDatapoint\"\n translate\n >\n At least one data point for the labels or the gauge needs to be selected.\n </div>\n </div>\n </div>\n\n <div class=\"row\">\n <div class=\"col-md-6\">\n <c8y-datapoint-selection-list\n class=\"bg-inherit separator-top p-t-16 d-block\"\n listTitle=\"{{ 'Multiple label and value pairs' | translate }}\"\n name=\"datapoints\"\n [defaultFormOptions]=\"defaultFormOptions\"\n [config]=\"datapointSelectionConfig\"\n [minActiveCount]=\"0\"\n formControlName=\"datapointsLabels\"\n ></c8y-datapoint-selection-list>\n </div>\n <div class=\"col-md-6\">\n <c8y-datapoint-selection-list\n class=\"bg-inherit separator-top p-t-16 d-block\"\n listTitle=\"{{ 'Gauge`display`' | translate }}\"\n name=\"datapoints\"\n [defaultFormOptions]=\"defaultFormOptions\"\n [config]=\"datapointSelectionConfig\"\n [minActiveCount]=\"0\"\n [maxActiveCount]=\"1\"\n formControlName=\"datapointsGauge\"\n ></c8y-datapoint-selection-list>\n </div>\n </div>\n </div>\n\n <ng-template #radialGauge>\n <div class=\"d-flex-md fit-h\">\n <div class=\"col-md-6 inner-scroll p-0 bg-component\">\n <c8y-datapoint-selection-list\n class=\"bg-inherit d-block\"\n listTitle=\"{{ 'Data points`display`' | translate }}\"\n name=\"datapoints\"\n [defaultFormOptions]=\"defaultFormOptions\"\n [config]=\"datapointSelectionConfig\"\n [minActiveCount]=\"0\"\n [maxActiveCount]=\"1\"\n formControlName=\"datapointsGauge\"\n ></c8y-datapoint-selection-list>\n\n <c8y-form-group class=\"p-t-8 p-r-16 p-l-16\">\n <label translate>Decimal places</label>\n <input\n class=\"form-control\"\n name=\"fractionSize\"\n type=\"number\"\n formControlName=\"fractionSize\"\n step=\"1\"\n />\n <c8y-messages [show]=\"formGroup.controls.fractionSize.errors\"></c8y-messages>\n </c8y-form-group>\n\n <div class=\"form-group p-r-16 p-l-16 m-b-0\">\n <legend>\n {{ 'Presets' | translate }}\n </legend>\n <c8y-preset-preview\n formControlName=\"gaugePresetId\"\n [ALL_GAUGE_PRESETS]=\"ALL_GAUGE_PRESETS\"\n (onPresetChange)=\"onRadioPresetChange($event)\"\n ></c8y-preset-preview>\n </div>\n\n <div class=\"p-16\">\n <button\n class=\"btn btn-default\"\n aria-controls=\"advancedCollapse\"\n [attr.aria-expanded]=\"showAdvancedOptions\"\n type=\"button\"\n (click)=\"showAdvancedOptions = !showAdvancedOptions\"\n >\n {{ showAdvancedOptions ? hideAdvancedOptionsLabel : showAdvancedOptionsLabel }}\n </button>\n </div>\n\n <div\n class=\"collapse\"\n id=\"advancedCollapse\"\n [collapse]=\"!showAdvancedOptions\"\n [isAnimated]=\"true\"\n >\n <div\n class=\"fit-h\"\n style=\"min-height: 400px\"\n >\n <c8y-editor\n [ngModel]=\"gaugeOptionsString\"\n (ngModelChange)=\"gaugeJSONChange($event)\"\n (editorInit)=\"assignSchema()\"\n [ngModelOptions]=\"{ standalone: true }\"\n monacoEditorMarkerValidator\n ></c8y-editor>\n </div>\n </div>\n </div>\n <div\n class=\"col-md-6\"\n *ngIf=\"\n this.formGroup.value.datapointsGauge.length > 0 && activeDatapointGauge;\n else emptyState\n \"\n >\n <!-- Radial Gauge -->\n <c8y-radial-gauge\n class=\"c8y-radial-gauge--square\"\n *ngIf=\"activeDatapointGauge | infoGaugeCurrentMeasurement | async as measurement\"\n [activeDatapointGauge]=\"activeDatapointGauge\"\n [measurement]=\"measurement\"\n [fractionSize]=\"formGroup.value.fractionSize\"\n [gaugeOptions]=\"gaugeOptions\"\n [selectedPresetId]=\"formGroup.value.gaugePresetId\"\n ></c8y-radial-gauge>\n </div>\n </div>\n </ng-template>\n</form>\n\n<ng-template #emptyState>\n <div class=\"col-md-6 d-col a-i-start j-c-center\">\n <c8y-ui-empty-state\n [icon]=\"'c8y-data-points'\"\n [title]=\"'Please select a data point first.' | translate\"\n [horizontal]=\"false\"\n ></c8y-ui-empty-state>\n </div>\n</ng-template>\n" }]
}], ctorParameters: () => [{ type: i1.FormBuilder }, { type: i1.NgForm }, { type: i2.WidgetConfigComponent }, { type: i3.DynamicComponentComponent, decorators: [{
type: Optional
}] }], propDecorators: { config: [{
type: Input
}], editorComponent: [{
type: ViewChild,
args: [EditorComponent]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5mby1nYXVnZS13aWRnZXQtY29uZmlnLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3dpZGdldHMvaW1wbGVtZW50YXRpb25zL2luZm8tZ2F1Z2UvaW5mby1nYXVnZS13aWRnZXQtY29uZmlnL2luZm8tZ2F1Z2Utd2lkZ2V0LWNvbmZpZy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi93aWRnZXRzL2ltcGxlbWVudGF0aW9ucy9pbmZvLWdhdWdlL2luZm8tZ2F1Z2Utd2lkZ2V0LWNvbmZpZy9pbmZvLWdhdWdlLXdpZGdldC1jb25maWcuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBVSxLQUFLLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBYSxNQUFNLGVBQWUsQ0FBQztBQUN6RixPQUFPLEVBRUwsZ0JBQWdCLEVBQ2hCLFdBQVcsRUFDWCxNQUFNLEVBQ04sbUJBQW1CLEVBRW5CLFVBQVUsRUFDWCxNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFDTCx1QkFBdUIsRUFJeEIsTUFBTSx3Q0FBd0MsQ0FBQztBQUNoRCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUM5RSxPQUFPLEVBQ0wsWUFBWSxFQUNaLHlCQUF5QixFQUN6QixrQkFBa0IsRUFDbEIsV0FBVyxFQUNYLE9BQU8sRUFDUCwwQkFBMEIsRUFDMUIsaUJBQWlCLEVBRWxCLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUFjLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDdEQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDM0UsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFDbEYsT0FBTyxFQUFFLCtCQUErQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDOUUsT0FBTyxFQUNMLGtCQUFrQixFQUNsQixhQUFhLEVBR2QsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGVBQWUsRUFBRSxvQ0FBb0MsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ25HLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN4RCxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQzs7Ozs7Ozs7QUFFbkYsU0FBUywwQ0FBMEMsQ0FDakQsdUJBQWlDO0lBRWpDLE9BQU8sQ0FBQyxPQUF3QixFQUFFLEVBQUU7UUFDbEMsTUFBTSxTQUFTLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQztRQUNoQyxLQUFLLE1BQU0saUJBQWlCLElBQUksdUJBQXVCLEVBQUUsQ0FBQztZQUN4RCxNQUFNLFlBQVksR0FBaUIsU0FBUyxDQUFDLGlCQUFpQixDQUFDLENBQUM7WUFDaEUsSUFBSSxDQUFDLFlBQVksSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQztnQkFDbEQsU0FBUztZQUNYLENBQUM7WUFFRCxJQUFJLFlBQVksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztnQkFDekMsT0FBTyxJQUFJLENBQUM7WUFDZCxDQUFDO1FBQ0gsQ0FBQztRQUNELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxJQUFJLEVBQUUsQ0FBQztJQUNyQyxDQUFDLENBQUM7QUFDSixDQUFDO0FBdUJELE1BQU0sT0FBTyw4QkFBOEI7SUEyQnpDLFlBQ1UsV0FBd0IsRUFDeEIsSUFBWSxFQUNaLFlBQW1DLEVBQ3ZCLGdCQUE0QztRQUh4RCxnQkFBVyxHQUFYLFdBQVcsQ0FBYTtRQUN4QixTQUFJLEdBQUosSUFBSSxDQUFRO1FBQ1osaUJBQVksR0FBWixZQUFZLENBQXVCO1FBQ3ZCLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBNEI7UUEzQmxFLDZCQUF3QixHQUEyQyxFQUFFLENBQUM7UUFDdEUsdUJBQWtCLEdBQTJDO1lBQzNELFlBQVksRUFBRSxJQUFJO1lBQ2xCLGVBQWUsRUFBRSxJQUFJO1lBQ3JCLFNBQVMsRUFBRSxJQUFJO1lBQ2YsMEJBQTBCLEVBQUUsRUFBRTtTQUMvQixDQUFDO1FBR0Ysd0JBQW1CLEdBQUcsS0FBSyxDQUFDO1FBQzVCLHVCQUFrQixHQUFHLEVBQUUsQ0FBQztRQUV4Qiw2QkFBd0IsR0FBRyxPQUFPLENBQUMsdUJBQXVCLENBQUMsQ0FBQztRQUM1RCw2QkFBd0IsR0FBRyxPQUFPLENBQUMsdUJBQXVCLENBQUMsQ0FBQztRQUM1RCxzQkFBaUIsR0FBRyxDQUFDLEdBQUcsYUFBYSxDQUFDLENBQUM7UUFDL0IsV0FBTSxHQUFHO1lBQ2Ysd0JBQXdCLEVBQUUsRUFBRTtZQUM1Qix3QkFBd0IsRUFBRSxDQUFDO1NBQ25CLENBQUM7UUFFRixrQkFBYSxHQUFHLGFBQWEsQ0FBQztRQUMvQixhQUFRLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztJQU9wQyxDQUFDO0lBRUosWUFBWSxDQUNWLE1BQWlEO1FBRWpELElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUN6QixNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQzVDLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFO2dCQUNwQixZQUFZLEVBQUUsSUFBSSxDQUFDLFlBQVk7Z0JBQy9CLGdCQUFnQixFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDO2FBQ2hGLENBQUMsQ0FBQztZQUNILE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUNELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVELFFBQVE7UUFDTixJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLEVBQUUsRUFBRSxDQUFDO1lBQ2xDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRSxPQUFPLENBQUM7UUFDMUUsQ0FBQztRQUNELElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNoQixJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQztZQUNsQyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxFQUFFLGdCQUFnQixFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDO1FBQ2hGLENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsZUFBZSxFQUFFLENBQUM7WUFDakMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsRUFBRSxlQUFlLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxlQUFlLEVBQUUsQ0FBQyxDQUFDO1FBQzlFLENBQUM7UUFDRCxJQUFJLE9BQU8sSUFBSSxDQUFDLE1BQU0sRUFBRSxZQUFZLEtBQUssUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLFlBQVksQ0FBQyxFQUFFLENBQUM7WUFDOUYsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsRUFBRSxZQUFZLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFDRCxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxXQUFXLEtBQUssZ0JBQWdCLENBQUMsVUFBVSxDQUFDO1FBRXRGLE1BQU0sYUFBYSxHQUFHLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQztRQUV4QyxJQUFJLGFBQWEsRUFBRSxDQUFDO1lBQ2xCLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQzFCLENBQUM7UUFFRCxJQUFJLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUMzRSxJQUFJLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztnQkFDMUIsSUFBSSxDQUFDLG9CQUFvQixHQUFHLEtBQUssQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzVFLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNyQixJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQzNCLENBQUM7SUFFRCxtQkFBbUIsQ0FBQyxRQUFnQjtRQUNsQywyQkFBMkI7UUFDM0IsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEtBQUssUUFBUSxDQUFDLENBQUM7UUFFckYsSUFBSSxjQUFjLEVBQUUsQ0FBQztZQUNuQixJQUFJLENBQUMsWUFBWSxHQUFHLEVBQUUsR0FBRyxjQUFjLEVBQUUsQ0FBQyxDQUFDLCtDQUErQztZQUMxRixJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztZQUVyRSw4REFBOEQ7WUFDOUQsSUFBSSxjQUFjLENBQUMsRUFBRSxLQUFLLFFBQVEsRUFBRSxDQUFDO2dCQUNuQyxJQUFJLENBQUMsbUJBQW1CLEdBQUcsS0FBSyxDQUFDO1lBQ25DLENBQUM7WUFFRCxnQ0FBZ0M7WUFDaEMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsRUFBRSxhQUFhLEVBQUUsY0FBYyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDbEUsQ0FBQztJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsWUFBWTtRQUNoQixNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsTUFBTSxNQUFNLENBQzdCLHFHQUFxRyxDQUN0RyxDQUFDO1FBQ0YsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMscUJBQXFCLENBQUM7WUFDNUUsUUFBUSxFQUFFLElBQUk7WUFDZCxPQUFPLEVBQUU7Z0JBQ1A7b0JBQ0UsR0FBRyxFQUFFLG1CQUFtQjtvQkFDeEIsTUFBTSxFQUFFLE1BQU07b0JBQ2QsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDO2lCQUNqQjthQUNGO1lBQ0QsbUJBQW1CLEVBQUUsS0FBSztZQUMxQixhQUFhLEVBQUUsS0FBSztTQUNyQixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsZUFBZSxDQUFDLEtBQWE7UUFDM0IsSUFBSSxDQUFDO1lBQ0gsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUV4Qyx3REFBd0Q7WUFDeEQsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQzVDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsS0FBSyxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxDQUNuRSxDQUFDO1lBRUYsSUFBSSxjQUFjLEVBQUUsQ0FBQztnQkFDbkIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsRUFBRSxhQUFhLEVBQUUsY0FBYyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDbEUsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLElBQUksQ0FBQyxZQUFZLEdBQUcsYUFBYSxDQUFDO2dCQUNsQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksR0FBRyxrQkFBa0IsQ0FBQyxNQUFNLENBQUM7Z0JBQ25ELElBQUksQ0FBQyxZQUFZLENBQUMsRUFBRSxHQUFHLFFBQVEsQ0FBQztnQkFFaEMsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUUsS0FBSyxRQUFRLENBQUMsQ0FBQztnQkFFekYsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7b0JBQ3hCLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztnQkFDMUUsQ0FBQztxQkFBTSxDQUFDO29CQUNOLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQzNELE1BQU0sQ0FBQyxFQUFFLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQ3BELENBQUM7Z0JBQ0osQ0FBQztnQkFFRCxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxFQUFFLGFBQWEsRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDO1lBQ3pELENBQUM7UUFDSCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE9BQU8sQ0FBQyxLQUFLLENBQUMsZUFBZSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3hDLENBQUM7SUFDSCxDQUFDO0lBRUQsU0FBUyxDQUFDLE1BQWMsRUFBRSxJQUFrQjtRQUMxQyxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUM7SUFDakIsQ0FBQztJQUVPLFdBQVcsQ0FBQyxZQUEwQjtRQUM1QyxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEtBQUssWUFBWSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBRXhGLE9BQU8sY0FBYyxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUM7SUFDdkQsQ0FBQztJQUVPLGdCQUFnQjtRQUN0QixJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUMzRCxJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQztRQUN2RCxDQUFDO1FBRUQsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBRTdFLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUM5QyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksR0FBRyxrQkFBa0IsQ0FBQyxNQUFNLENBQUM7WUFDbkQsSUFBSSxDQUFDLFlBQVksQ0FBQyxFQUFFLEdBQUcsUUFBUSxDQUFDO1lBQ2hDLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQzNFLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLEVBQUUsYUFBYSxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDekQsQ0FBQztRQUVELElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3ZFLENBQUM7SUFFTyxRQUFRO1FBQ2QsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDbkMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDcEQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFFTyxVQUFVO1FBQ2hCLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQzNCO1lBQ0UsWUFBWSxFQUFFO2dCQUNaLENBQUM7Z0JBQ0Q7b0JBQ0UsVUFBVSxDQUFDLFFBQVE7b0JBQ25CLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyx3QkFBd0IsQ0FBQztvQkFDcEQsVUFBVSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLHdCQUF3QixDQUFDO2lCQUNyRDthQUNGO1lBQ0QsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsSUFBSSxLQUFLLEVBQWMsRUFBRSxFQUFFLENBQUM7WUFDdkUsZUFBZSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLElBQUksS0FBSyxFQUFjLEVBQUUsRUFBRSxDQUFDO1lBQ3RFLGFBQWEsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLElBQUksU0FBUyxDQUFDO1NBQzNELEVBQ0Q7WUFDRSxVQUFVLEVBQUU7Z0JBQ1YsMENBQTBDLENBQUMsQ0FBQyxrQkFBa0IsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO2FBQ3BGO1NBQ0YsQ0FDRixDQUFDO0lBQ0osQ0FBQzsrR0E3TVUsOEJBQThCO21HQUE5Qiw4QkFBOEIseUdBakI5QixDQUFDLDBCQUEwQixDQUFDLDJFQW1CNUIsZUFBZSxnRENuRjVCLDYxS0FpS0EsNENEOUZJLGtCQUFrQix1SUFDbEIsaUJBQWlCLHFHQUNqQixZQUFZLGllQUNaLFdBQVcsNm9DQUNYLGNBQWMsK09BQ2QsbUJBQW1CLGdWQUNuQixlQUFlLDJHQUNmLG9DQUFvQyxvRkFDcEMsdUJBQXVCLHNUQUN2Qix3QkFBd0IsNkpBQ3hCLCtCQUErQixvRUFDL0Isc0JBQXNCLGdIQWZULENBQUMsRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxDQUFDOzs0RkFrQnhELDhCQUE4QjtrQkFyQjFDLFNBQVM7K0JBQ0UsOEJBQThCLGlCQUV6QixDQUFDLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUUsQ0FBQyxhQUN4RCxDQUFDLDBCQUEwQixDQUFDLGNBQzNCLElBQUksV0FDUDt3QkFDUCxrQkFBa0I7d0JBQ2xCLGlCQUFpQjt3QkFDakIsWUFBWTt3QkFDWixXQUFXO3dCQUNYLGNBQWM7d0JBQ2QsbUJBQW1CO3dCQUNuQixlQUFlO3dCQUNmLG9DQUFvQzt3QkFDcEMsdUJBQXVCO3dCQUN2Qix3QkFBd0I7d0JBQ3hCLCtCQUErQjt3QkFDL0Isc0JBQXNCO3FCQUN2Qjs7MEJBaUNFLFFBQVE7eUNBOUJGLE1BQU07c0JBQWQsS0FBSztnQkFDc0IsZUFBZTtzQkFBMUMsU0FBUzt1QkFBQyxlQUFlIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIElucHV0LCBPcHRpb25hbCwgVmlld0NoaWxkLCBPbkRlc3Ryb3kgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIEFic3RyYWN0Q29udHJvbCxcbiAgQ29udHJvbENvbnRhaW5lcixcbiAgRm9ybUJ1aWxkZXIsXG4gIE5nRm9ybSxcbiAgUmVhY3RpdmVGb3Jtc01vZHVsZSxcbiAgVmFsaWRhdG9yRm4sXG4gIFZhbGlkYXRvcnNcbn0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHtcbiAgRGF0YXBvaW50U2VsZWN0b3JNb2R1bGUsXG4gIHR5cGUgRGF0YXBvaW50QXR0cmlidXRlc0Zvcm1Db25maWcsXG4gIHR5cGUgRGF0YXBvaW50U2VsZWN0b3JNb2RhbE9wdGlvbnMsXG4gIHR5cGUgS1BJRGV0YWlsc1xufSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzL2RhdGFwb2ludC1zZWxlY3Rvcic7XG5pbXBvcnQgeyBXaWRnZXRDb25maWdDb21wb25lbnQgfSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzL2NvbnRleHQtZGFzaGJvYXJkJztcbmltcG9ydCB7XG4gIENvbW1vbk1vZHVsZSxcbiAgRHluYW1pY0NvbXBvbmVudENvbXBvbmVudCxcbiAgRm9ybUdyb3VwQ29tcG9uZW50LFxuICBGb3Jtc01vZHVsZSxcbiAgZ2V0dGV4dCxcbiAgTWVhc3VyZW1lbnRSZWFsdGltZVNlcnZpY2UsXG4gIE1lc3NhZ2VzQ29tcG9uZW50LFxuICBPbkJlZm9yZVNhdmVcbn0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cyc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJqZWN0LCB0YWtlVW50aWwgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGRlZmF1bHRXaWRnZXRJZHMgfSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzL3dpZGdldHMvZGVmaW5pdGlvbnMnO1xuaW1wb3J0IHsgUmFkaWFsR2F1Z2VWaWV3Q29tcG9uZW50IH0gZnJvbSAnLi4vcmFkaWFsLWdhdWdlL3JhZGlhbC1nYXVnZS5jb21wb25lbnQnO1xuaW1wb3J0IHsgSW5mb0dhdWdlQ3VycmVudE1lYXN1cmVtZW50UGlwZSB9IGZyb20gJy4uL2N1cnJlbnQtbWVhc3VyZW1lbnQucGlwZSc7XG5pbXBvcnQge1xuICBHQVVHRV9QUkVTRVRfTkFNRVMsXG4gIEdBVUdFX1BSRVNFVFMsXG4gIEdhdWdlT3B0aW9ucyxcbiAgSW5mb0dhdWdlV2lkZ2V0Q29uZmlnXG59IGZyb20gJy4vZ2F1Z2UubW9kZWwnO1xuaW1wb3J0IHsgRWRpdG9yQ29tcG9uZW50LCBNb25hY29FZGl0b3JNYXJrZXJWYWxpZGF0b3JEaXJlY3RpdmUgfSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzL2VkaXRvcic7XG5pbXBvcnQgeyBDb2xsYXBzZU1vZHVsZSB9IGZyb20gJ25neC1ib290c3RyYXAvY29sbGFwc2UnO1xuaW1wb3J0IHsgUHJlc2V0UHJldmlld0NvbXBvbmVudCB9IGZyb20gJy4vcHJlc2V0LXByZXZpZXcvcHJlc2V0LXByZXZpZXcuY29tcG9uZW50JztcblxuZnVuY3Rpb24gZW5zdXJlQXRMZWFzdE9uZURhdGFwb2ludFNlbGVjdGVkQW5kQWN0aXZlKFxuICBkYXRhcG9pbnRMaXN0QXR0cmlidXRlczogc3RyaW5nW11cbik6IFZhbGlkYXRvckZuIHtcbiAgcmV0dXJuIChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpID0+IHtcbiAgICBjb25zdCBmb3JtVmFsdWUgPSBjb250cm9sLnZhbHVlO1xuICAgIGZvciAoY29uc3QgbGlzdEF0dHJpYnV0ZU5hbWUgb2YgZGF0YXBvaW50TGlzdEF0dHJpYnV0ZXMpIHtcbiAgICAgIGNvbnN0IHZhbHVlRm9yTGlzdDogS1BJRGV0YWlsc1tdID0gZm9ybVZhbHVlW2xpc3RBdHRyaWJ1dGVOYW1lXTtcbiAgICAgIGlmICghdmFsdWVGb3JMaXN0IHx8ICFBcnJheS5pc0FycmF5KHZhbHVlRm9yTGlzdCkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmICh2YWx1ZUZvckxpc3QuZmluZChkcCA9PiBkcC5fX2FjdGl2ZSkpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7IG5vQWN0aXZlRGF0YXBvaW50OiB0cnVlIH07XG4gIH07XG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2M4eS1pbmZvLWdhdWdlLXdpZGdldC1jb25maWcnLFxuICB0ZW1wbGF0ZVVybDogJy4vaW5mby1nYXVnZS13aWRnZXQtY29uZmlnLmNvbXBvbmVudC5odG1sJyxcbiAgdmlld1Byb3ZpZGVyczogW3sgcHJvdmlkZTogQ29udHJvbENvbnRhaW5lciwgdXNlRXhpc3Rpbmc6IE5nRm9ybSB9XSxcbiAgcHJvdmlkZXJzOiBbTWVhc3VyZW1lbnRSZWFsdGltZVNlcnZpY2VdLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgRm9ybUdyb3VwQ29tcG9uZW50LFxuICAgIE1lc3NhZ2VzQ29tcG9uZW50LFxuICAgIENvbW1vbk1vZHVsZSxcbiAgICBGb3Jtc01vZHVsZSxcbiAgICBDb2xsYXBzZU1vZHVsZSxcbiAgICBSZWFjdGl2ZUZvcm1zTW9kdWxlLFxuICAgIEVkaXRvckNvbXBvbmVudCxcbiAgICBNb25hY29FZGl0b3JNYXJrZXJWYWxpZGF0b3JEaXJlY3RpdmUsXG4gICAgRGF0YXBvaW50U2VsZWN0b3JNb2R1bGUsXG4gICAgUmFkaWFsR2F1Z2VWaWV3Q29tcG9uZW50LFxuICAgIEluZm9HYXVnZUN1cnJlbnRNZWFzdXJlbWVudFBpcGUsXG4gICAgUHJlc2V0UHJldmlld0NvbXBvbmVudFxuICBdXG59KVxuZXhwb3J0IGNsYXNzIEluZm9HYXVnZVdpZGdldENvbmZpZ0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25CZWZvcmVTYXZlLCBPbkRlc3Ryb3kge1xuICBASW5wdXQoKSBjb25maWc6IEluZm9HYXVnZVdpZGdldENvbmZpZztcbiAgQFZpZXdDaGlsZChFZGl0b3JDb21wb25lbnQpIGVkaXRvckNvbXBvbmVudCE6IEVkaXRvckNvbXBvbmVudDtcbiAgZm9ybUdyb3VwOiBSZXR1cm5UeXBlPEluZm9HYXVnZVdpZGdldENvbmZpZ0NvbXBvbmVudFsnY3JlYXRlRm9ybSddPjtcbiAgZGF0YXBvaW50U2VsZWN0aW9uQ29uZmlnOiBQYXJ0aWFsPERhdGFwb2ludFNlbGVjdG9yTW9kYWxPcHRpb25zPiA9IHt9O1xuICBkZWZhdWx0Rm9ybU9wdGlvbnM6IFBhcnRpYWw8RGF0YXBvaW50QXR0cmlidXRlc0Zvcm1Db25maWc+ID0ge1xuICAgIHNob3dSZWRSYW5nZTogdHJ1ZSxcbiAgICBzaG93WWVsbG93UmFuZ2U6IHRydWUsXG4gICAgc2hvd1JhbmdlOiB0cnVlLFxuICAgIHNlbGVjdGFibGVDaGFydFJlbmRlclR5cGVzOiBbXVxuICB9O1xuICBpc0luZm9HYXVnZTogYm9vbGVhbjtcbiAgYWN0aXZlRGF0YXBvaW50R2F1Z2U6IEtQSURldGFpbHM7XG4gIHNob3dBZHZhbmNlZE9wdGlvbnMgPSBmYWxzZTtcbiAgZ2F1Z2VPcHRpb25zU3RyaW5nID0gJyc7XG4gIGdhdWdlT3B0aW9uczogR2F1Z2VPcHRpb25zO1xuICBzaG93QWR2YW5jZWRPcHRpb25zTGFiZWwgPSBnZXR0ZXh0KCdTaG93IGFkdmFuY2VkIG9wdGlvbnMnKTtcbiAgaGlkZUFkdmFuY2VkT3B0aW9uc0xhYmVsID0gZ2V0dGV4dCgnSGlkZSBhZHZhbmNlZCBvcHRpb25zJyk7XG4gIEFMTF9HQVVHRV9QUkVTRVRTID0gWy4uLkdBVUdFX1BSRVNFVFNdO1xuICBwcml2YXRlIGxpbWl0cyA9IHtcbiAgICBudW1iZXJPZkRlY2ltYWxQbGFjZXNNYXg6IDEwLFxuICAgIG51bWJlck9mRGVjaW1hbFBsYWNlc01pbjogMFxuICB9IGFzIGNvbnN0O1xuXG4gIHJlYWRvbmx5IEdBVUdFX1BSRVNFVFMgPSBHQVVHRV9QUkVTRVRTO1xuICBwcml2YXRlIGRlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGZvcm1CdWlsZGVyOiBGb3JtQnVpbGRlcixcbiAgICBwcml2YXRlIGZvcm06IE5nRm9ybSxcbiAgICBwcml2YXRlIHdpZGdldENvbmZpZzogV2lkZ2V0Q29uZmlnQ29tcG9uZW50LFxuICAgIEBPcHRpb25hbCgpIHByaXZhdGUgZHluYW1pY0NvbXBvbmVudD86IER5bmFtaWNDb21wb25lbnRDb21wb25lbnRcbiAgKSB7fVxuXG4gIG9uQmVmb3JlU2F2ZShcbiAgICBjb25maWc/OiBJbmZvR2F1Z2VXaWRnZXRDb25maWdDb21wb25lbnRbJ2NvbmZpZyddXG4gICk6IGJvb2xlYW4gfCBQcm9taXNlPGJvb2xlYW4+IHwgT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgaWYgKHRoaXMuZm9ybUdyb3VwLnZhbGlkKSB7XG4gICAgICBPYmplY3QuYXNzaWduKGNvbmZpZywgdGhpcy5mb3JtR3JvdXAudmFsdWUpO1xuICAgICAgT2JqZWN0LmFzc2lnbihjb25maWcsIHtcbiAgICAgICAgZ2F1Z2VPcHRpb25zOiB0aGlzLmdhdWdlT3B0aW9ucyxcbiAgICAgICAgc2VsZWN0ZWRQcmVzZXRJZDogdGhpcy5pc0luZm9HYXVnZSA/IG51bGwgOiB0aGlzLmdldFByZXNldElkKHRoaXMuZ2F1Z2VPcHRpb25zKVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMud2lkZ2V0Q29uZmlnLmNvbnRleHQ/LmlkKSB7XG4gICAgICB0aGlzLmRhdGFwb2ludFNlbGVjdGlvbkNvbmZpZy5jb250ZXh0QXNzZXQgPSB0aGlzLndpZGdldENvbmZpZz8uY29udGV4dDtcbiAgICB9XG4gICAgdGhpcy5pbml0Rm9ybSgpO1xuICAgIGlmICh0aGlzLmNvbmZpZz8uZGF0YXBvaW50c0xhYmVscykge1xuICAgICAgdGhpcy5mb3JtR3JvdXAucGF0Y2hWYWx1ZSh7IGRhdGFwb2ludHNMYWJlbHM6IHRoaXMuY29uZmlnLmRhdGFwb2ludHNMYWJlbHMgfSk7XG4gICAgfVxuICAgIGlmICh0aGlzLmNvbmZpZz8uZGF0YXBvaW50c0dhdWdlKSB7XG4gICAgICB0aGlzLmZvcm1Hcm91cC5wYXRjaFZhbHVlKHsgZGF0YXBvaW50c0dhdWdlOiB0aGlzLmNvbmZpZy5kYXRhcG9pbnRzR2F1Z2UgfSk7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdGhpcy5jb25maWc/LmZyYWN0aW9uU2l6ZSA9PT0gJ251bWJlcicgJiYgIU51bWJlci5pc05hTih0aGlzLmNvbmZpZz8uZnJhY3Rpb25TaXplKSkge1xuICAgICAgdGhpcy5mb3JtR3JvdXAucGF0Y2hWYWx1ZSh7IGZyYWN0aW9uU2l6ZTogdGhpcy5jb25maWcuZnJhY3Rpb25TaXplIH0pO1xuICAgIH1cbiAgICB0aGlzLmlzSW5mb0dhdWdlID0gdGhpcy5keW5hbWljQ29tcG9uZW50Py5jb21wb25lbnRJZCA9PT0gZGVmYXVsdFdpZGdldElkcy5JTkZPX0dBVUdFO1xuXG4gICAgY29uc3QgaXNSYWRpYWxHYXVnZSA9ICF0aGlzLmlzSW5mb0dhdWdlO1xuXG4gICAgaWYgKGlzUmFkaWFsR2F1Z2UpIHtcbiAgICAgIHRoaXMuc2V0dXBSYWRpYWxHYXVnZSgpO1xuICAgIH1cblxuICAgIHRoaXMuZm9ybUdyb3VwLnZhbHVlQ2hhbmdlcy5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKHZhbHVlID0+IHtcbiAgICAgIGlmICh2YWx1ZS5kYXRhcG9pbnRzR2F1Z2UpIHtcbiAgICAgICAgdGhpcy5hY3RpdmVEYXRhcG9pbnRHYXVnZSA9IHZhbHVlLmRhdGFwb2ludHNHYXVnZS5maW5kKGRwID0+IGRwLl9fYWN0aXZlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuZGVzdHJveSQubmV4dCgpO1xuICAgIHRoaXMuZGVzdHJveSQuY29tcGxldGUoKTtcbiAgfVxuXG4gIG9uUmFkaW9QcmVzZXRDaGFuZ2UocHJlc2V0SWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIC8vIEZpbmQgdGhlIHNlbGVjdGVkIHByZXNldFxuICAgIGNvbnN0IHNlbGVjdGVkUHJlc2V0ID0gdGhpcy5BTExfR0FVR0VfUFJFU0VUUy5maW5kKHByZXNldCA9PiBwcmVzZXQuaWQgPT09IHByZXNldElkKTtcblxuICAgIGlmIChzZWxlY3RlZFByZXNldCkge1xuICAgICAgdGhpcy5nYXVnZU9wdGlvbnMgPSB7IC4uLnNlbGVjdGVkUHJlc2V0IH07IC8vIFVwZGF0ZSBnYXVnZU9wdGlvbnMgd2l0aCB0aGUgc2VsZWN0ZWQgcHJlc2V0XG4gICAgICB0aGlzLmdhdWdlT3B0aW9uc1N0cmluZyA9IEpTT04uc3RyaW5naWZ5KHRoaXMuZ2F1Z2VPcHRpb25zLCBudWxsLCAyKTtcblxuICAgICAgLy8gSWYgdGhlIHNlbGVjdGVkIHByZXNldCBpcyBub3QgY3VzdG9tLCBoaWRlIGFkdmFuY2VkIG9wdGlvbnNcbiAgICAgIGlmIChzZWxlY3RlZFByZXNldC5pZCAhPT0gJ2N1c3RvbScpIHtcbiAgICAgICAgdGhpcy5zaG93QWR2YW5jZWRPcHRpb25zID0gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIC8vIFVwZGF0ZSB0aGUgZm9ybSBjb250cm9sIHZhbHVlXG4gICAgICB0aGlzLmZvcm1Hcm91cC5wYXRjaFZhbHVlKHsgZ2F1Z2VQcmVzZXRJZDogc2VsZWN0ZWRQcmVzZXQuaWQgfSk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgYXNzaWduU2NoZW1hKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHsgc2NoZW1hIH0gPSBhd2FpdCBpbXBvcnQoXG4gICAgICAnYzh5LXNjaGVtYS1sb2FkZXI/aW50ZXJmYWNlTmFtZT1HYXVnZU9wdGlvbnMhQGM4eS9uZ3gtY29tcG9uZW50cy93aWRnZXRzL2ltcGxlbWVudGF0aW9ucy9pbmZvLWdhdWdlJ1xuICAgICk7XG4gICAgdGhpcy5lZGl0b3JDb21wb25lbnQubW9uYWNvLmxhbmd1YWdlcy5qc29uLmpzb25EZWZhdWx0cy5zZXREaWFnbm9zdGljc09wdGlvbnMoe1xuICAgICAgdmFsaWRhdGU6IHRydWUsXG4gICAgICBzY2hlbWFzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICB1cmk6ICdnYXVnZS1zY2hlbWEuanNvbicsXG4gICAgICAgICAgc2NoZW1hOiBzY2hlbWEsXG4gICAgICAgICAgZmlsZU1hdGNoOiBbJyonXVxuICAgICAgICB9XG4gICAgICBdLFxuICAgICAgZW5hYmxlU2NoZW1hUmVxdWVzdDogZmFsc2UsXG4gICAgICBhbGxvd0NvbW1lbnRzOiBmYWxzZVxuICAgIH0pO1xuICB9XG5cbiAgZ2F1Z2VKU09OQ2hhbmdlKHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcGFyc2VkT3B0aW9ucyA9IEpTT04ucGFyc2UodmFsdWUpO1xuXG4gICAgICAvLyBDaGVjayBpZiB0aGUgcGFyc2VkIG9wdGlvbnMgbWF0Y2ggYW55IGV4aXN0aW5nIHByZXNldFxuICAgICAgY29uc3QgbWF0Y2hpbmdQcmVzZXQgPSB0aGlzLkdBVUdFX1BSRVNFVFMuZmluZChcbiAgICAgICAgcHJlc2V0ID0+IEpTT04uc3RyaW5naWZ5KHByZXNldCkgPT09IEpTT04uc3RyaW5naWZ5KHBhcnNlZE9wdGlvbnMpXG4gICAgICApO1xuXG4gICAgICBpZiAobWF0Y2hpbmdQcmVzZXQpIHtcbiAgICAgICAgdGhpcy5mb3JtR3JvdXAucGF0Y2hWYWx1ZSh7IGdhdWdlUHJlc2V0SWQ6IG1hdGNoaW5nUHJlc2V0LmlkIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5nYXVnZU9wdGlvbnMgPSBwYXJzZWRPcHRpb25zO1xuICAgICAgICB0aGlzLmdhdWdlT3B0aW9ucy5uYW1lID0gR0FVR0VfUFJFU0VUX05BTUVTLkNVU1RPTTtcbiAgICAgICAgdGhpcy5nYXVnZU9wdGlvbnMuaWQgPSAnY3VzdG9tJztcblxuICAgICAgICBjb25zdCBjdXN0b21QcmVzZXRFeGlzdHMgPSB0aGlzLkFMTF9HQVVHRV9QUkVTRVRTLnNvbWUocHJlc2V0ID0+IHByZXNldC5pZCA9PT0gJ2N1c3RvbScpO1xuXG4gICAgICAgIGlmICghY3VzdG9tUHJlc2V0RXhpc3RzKSB7XG4gICAgICAgICAgdGhpcy5BTExfR0FVR0VfUFJFU0VUUyA9IFsuLi50aGlzLkFMTF9HQVVHRV9QUkVTRVRTLCB0aGlzLmdhdWdlT3B0aW9uc107XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5BTExfR0FVR0VfUFJFU0VUUyA9IHRoaXMuQUxMX0dBVUdFX1BSRVNFVFMubWFwKHByZXNldCA9PlxuICAgICAgICAgICAgcHJlc2V0LmlkID09PSAnY3VzdG9tJyA/IHRoaXMuZ2F1Z2VPcHRpb25zIDogcHJlc2V0XG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZm9ybUdyb3VwLnBhdGNoVmFsdWUoeyBnYXVnZVByZXNldElkOiAnY3VzdG9tJyB9KTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcignSW52YWxpZCBKU09OOicsIGVycm9yKTtcbiAgICB9XG4gIH1cblxuICB0cmFja0J5Rm4oX2luZGV4OiBudW1iZXIsIGl0ZW06IEdhdWdlT3B0aW9ucyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGl0ZW0uaWQ7XG4gIH1cblxuICBwcml2YXRlIGdldFByZXNldElkKGdhdWdlT3B0aW9uczogR2F1Z2VPcHRpb25zKTogc3RyaW5nIHtcbiAgICBjb25zdCBtYXRjaGluZ1ByZXNldCA9IHRoaXMuR0FVR0VfUFJFU0VUUy5maW5kKHByZXNldCA9PiBwcmVzZXQuaWQgPT09IGdhdWdlT3B0aW9ucy5pZCk7XG5cbiAgICByZXR1cm4gbWF0Y2hpbmdQcmVzZXQgPyBtYXRjaGluZ1ByZXNldC5pZCA6ICdjdXN0b20nO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXR1cFJhZGlhbEdhdWdlKCkge1xuICAgIGlmICh0aGlzLmNvbmZpZy5kYXRhcG9pbnRzICYmICF0aGlzLmNvbmZpZy5kYXRhcG9pbnRzR2F1Z2UpIHtcbiAgICAgIHRoaXMuY29uZmlnLmRhdGFwb2ludHNHYXVnZSA9IHRoaXMuY29uZmlnLmRhdGFwb2ludHM7XG4gICAgfVxuXG4gICAgdGhpcy5nYXVnZU9wdGlvbnMgPSB0aGlzLmNvbmZpZy5nYXVnZU9wdGlvbnMgfHwgeyAuLi50aGlzLkdBVUdFX1BSRVNFVFNbMF0gfTtcblxuICAgIGlmICh0aGlzLmNvbmZpZy5zZWxlY3RlZFByZXNldElkID09PSAnY3VzdG9tJykge1xuICAgICAgdGhpcy5nYXVnZU9wdGlvbnMubmFtZSA9IEdBVUdFX1BSRVNFVF9OQU1FUy5DVVNUT007XG4gICAgICB0aGlzLmdhdWdlT3B0aW9ucy5pZCA9ICdjdXN0b20nO1xuICAgICAgdGhpcy5BTExfR0FVR0VfUFJFU0VUUyA9IFsuLi50aGlzLkdBVUdFX1BSRVNFVFMsIHRoaXMuY29uZmlnLmdhdWdlT3B0aW9uc107XG4gICAgICB0aGlzLmZvcm1Hcm91cC5wYXRjaFZhbHVlKHsgZ2F1Z2VQcmVzZXRJZDogJ2N1c3RvbScgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5nYXVnZU9wdGlvbnNTdHJpbmcgPSBKU09OLnN0cmluZ2lmeSh0aGlzLmdhdWdlT3B0aW9ucywgbnVsbCwgMik7XG4gIH1cblxuICBwcml2YXRlIGluaXRGb3JtKCk6IHZvaWQge1xuICAgIHRoaXMuZm9ybUdyb3VwID0gdGhpcy5jcmVhdGVGb3JtKCk7XG4gICAgdGhpcy5mb3JtLmZvcm0uYWRkQ29udHJvbCgnY29uZmlnJywgdGhpcy5mb3JtR3JvdXApO1xuICAgIHRoaXMuZm9ybUdyb3VwLnBhdGNoVmFsdWUodGhpcy5jb25maWcpO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVGb3JtKCkge1xuICAgIHJldHVybiB0aGlzLmZvcm1CdWlsZGVyLmdyb3VwKFxuICAgICAge1xuICAgICAgICBmcmFjdGlvblNpemU6IFtcbiAgICAgICAgICAyLFxuICAgICAgICAgIFtcbiAgICAgICAgICAgIFZhbGlkYXRvcnMucmVxdWlyZWQsXG4gICAgICAgICAgICBWYWxpZGF0b3JzLm1pbih0aGlzLmxpbWl0cy5udW1iZXJPZkRlY2ltYWxQbGFjZXNNaW4pLFxuICAgICAgICAgICAgVmFsaWRhdG9ycy5tYXgodGhpcy5saW1pdHMubnVtYmVyT2ZEZWNpbWFsUGxhY2VzTWF4KVxuICAgICAgICAgIF1cbiAgICAgICAgXSxcbiAgICAgICAgZGF0YXBvaW50c0xhYmVsczogdGhpcy5mb3JtQnVpbGRlci5jb250cm9sKG5ldyBBcnJheTxLUElEZXRhaWxzPigpLCBbXSksXG4gICAgICAgIGRhdGFwb2ludHNHYXVnZTogdGhpcy5mb3JtQnVpbGRlci5jb250cm9sKG5ldyBBcnJheTxLUElEZXRhaWxzPigpLCBbXSksXG4gICAgICAgIGdhdWdlUHJlc2V0SWQ6IFt0aGlzLmNvbmZpZy5zZWxlY3RlZFByZXNldElkIHx8ICdkZWZhdWx0J11cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIHZhbGlkYXRvcnM6IFtcbiAgICAgICAgICBlbnN1cmVBdExlYXN0T25lRGF0YXBvaW50U2VsZWN0ZWRBbmRBY3RpdmUoWydkYXRhcG9pbnRzTGFiZWxzJywgJ2RhdGFwb2ludHNHYXVnZSddKVxuICAgICAgICBdXG4gICAgICB9XG4gICAgKTtcbiAgfVxufVxuIiwiPGZvcm1cbiAgY2xhc3M9XCJmaXQtaFwiXG4gIFtmb3JtR3JvdXBdPVwiZm9ybUdyb3VwXCJcbj5cbiAgPGRpdlxuICAgIGNsYXNzPVwibS1sLTE2IG0tci0xNlwiXG4gICAgKm5nSWY9XCJpc0luZm9HYXVnZTsgZWxzZSByYWRpYWxHYXVnZVwiXG4gID5cbiAgICA8ZGl2IGNsYXNzPVwicm93XCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTZcIj5cbiAgICAgICAgPGM4eS1mb3JtLWdyb3VwIGNsYXNzPVwicC10LThcIj5cbiAgICAgICAgICA8bGFiZWwgdHJhbnNsYXRlPkRlY2ltYWwgcGxhY2VzPC9sYWJlbD5cbiAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgICAgIG5hbWU9XCJmcmFjdGlvblNpemVcIlxuICAgICAgICAgICAgdHlwZT1cIm51bWJlclwiXG4gICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJmcmFjdGlvblNpemVcIlxuICAgICAgICAgICAgc3RlcD1cIjFcIlxuICAgICAgICAgIC8+XG4gICAgICAgICAgPGM4eS1tZXNzYWdlcyBbc2hvd109XCJmb3JtR3JvdXAuY29udHJvbHMuZnJhY3Rpb25TaXplLmVycm9yc1wiPjwvYzh5LW1lc3NhZ2VzPlxuICAgICAgICA8L2M4eS1mb3JtLWdyb3VwPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTYgcC10LThcIj5cbiAgICAgICAgPGRpdlxuICAgICAgICAgIGNsYXNzPVwiYWxlcnQgYWxlcnQtaW5mb1wiXG4gICAgICAgICAgcm9sZT1cImFsZXJ0XCJcbiAgICAgICAgICAqbmdJZj1cImZvcm1Hcm91cC5lcnJvcnM/Lm5vQWN0aXZlRGF0YXBvaW50XCJcbiAgICAgICAgICB0cmFuc2xhdGVcbiAgICAgICAgPlxuICAgICAgICAgIEF0IGxlYXN0IG9uZSBkYXRhIHBvaW50IGZvciB0aGUgbGFiZWxzIG9yIHRoZSBnYXVnZSBuZWVkcyB0byBiZSBzZWxlY3RlZC5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJyb3dcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNlwiPlxuICAgICAgICA8Yzh5LWRhdGFwb2ludC1zZWxlY3Rpb24tbGlzdFxuICAgICAgICAgIGNsYXNzPVwiYmctaW5oZXJpdCBzZXBhcmF0b3ItdG9wIHAtdC0xNiBkLWJsb2NrXCJcbiAgICAgICAgICBsaXN0VGl0bGU9XCJ7eyAnTXVsdGlwbGUgbGFiZWwgYW5kIHZhbHVlIHBhaXJzJyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgICAgICAgbmFtZT1cImRhdGFwb2ludHNcIlxuICAgICAgICAgIFtkZWZhdWx0Rm9ybU9wdGlvbnNdPVwiZGVmYXVsdEZvcm1PcHRpb25zXCJcbiAgICAgICAgICBbY29uZmlnXT1cImRhdGFwb2ludFNlbGVjdGlvbkNvbmZpZ1wiXG4gICAgICAgICAgW21pbkFjdGl2ZUNvdW50XT1cIjBcIlxuICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cImRhdGFwb2ludHNMYWJlbHNcIlxuICAgICAgICA+PC9jOHktZGF0YXBvaW50LXNlbGVjdGlvbi1saXN0PlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTZcIj5cbiAgICAgICAgPGM4eS1kYXRhcG9pbnQtc2VsZWN0aW9uLWxpc3RcbiAgICAgICAgICBjbGFzcz1cImJnLWluaGVyaXQgc2VwYXJhdG9yLXRvcCBwLXQtMTYgZC1ibG9ja1wiXG4gICAgICAgICAgbGlzdFRpdGxlPVwie3sgJ0dhdWdlYGRpc3BsYXlgJyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgICAgICAgbmFtZT1cImRhdGFwb2ludHNcIlxuICAgICAgICAgIFtkZWZhdWx0Rm9ybU9wdGlvbnNdPVwiZGVmYXVsdEZvcm1PcHRpb25zXCJcbiAgICAgICAgICBbY29uZmlnXT1cImRhdGFwb2ludFNlbGVjdGlvbkNvbmZpZ1wiXG4gICAgICAgICAgW21pbkFjdGl2ZUNvdW50XT1cIjBcIlxuICAgICAgICAgIFttYXhBY3RpdmVDb3VudF09XCIxXCJcbiAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJkYXRhcG9pbnRzR2F1Z2VcIlxuICAgICAgICA+PC9jOHktZGF0YXBvaW50LXNlbGVjdGlvbi1saXN0PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuXG4gIDxuZy10ZW1wbGF0ZSAjcmFkaWFsR2F1Z2U+XG4gICAgPGRpdiBjbGFzcz1cImQtZmxleC1tZCBmaXQtaFwiPlxuICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC02IGlubmVyLXNjcm9sbCBwLTAgYmctY29tcG9uZW50XCI+XG4gICAgICAgIDxjOHktZGF0YXBvaW50LXNlbGVjdGlvbi1saXN0XG4gICAgICAgICAgY2xhc3M9XCJiZy1pbmhlcml0IGQtYmxvY2tcIlxuICAgICAgICAgIGxpc3RUaXRsZT1cInt7ICdEYXRhIHBvaW50c2BkaXNwbGF5YCcgfCB0cmFuc2xhdGUgfX1cIlxuICAgICAgICAgIG5hbWU9XCJkYXRhcG9pbnRzXCJcbiAgICAgICAgICBbZGVmYXVsdEZvcm1PcHRpb25zXT1cImRlZmF1bHRGb3JtT3B0aW9uc1wiXG4gICAgICAgICAgW2NvbmZpZ109XCJkYXRhcG9pbnRTZWxlY3Rpb25Db25maWdcIlxuICAgICAgICAgIFttaW5BY3RpdmVDb3VudF09XCIwXCJcbiAgICAgICAgICBbbWF4QWN0aXZlQ291bnRdPVwiMVwiXG4gICAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwiZGF0YXBvaW50c0dhdWdlXCJcbiAgICAgICAgPjwvYzh5LWRhdGFwb2ludC1zZWxlY3Rpb24tbGlzdD5cblxuICAgICAgICA8Yzh5LWZvcm0tZ3JvdXAgY2xhc3M9XCJwLXQtOCBwLXItMTYgcC1sLTE2XCI+XG4gICAgICAgICAgPGxhYmVsIHRyYW5zbGF0ZT5EZWNpbWFsIHBsYWNlczwvbGFiZWw+XG4gICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICBjbGFzcz1cImZvcm0tY29udHJvbFwiXG4gICAgICAgICAgICBuYW1lPVwiZnJhY3Rpb25TaXplXCJcbiAgICAgICAgICAgIHR5cGU9XCJudW1iZXJcIlxuICAgICAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwiZnJhY3Rpb25TaXplXCJcbiAgICAgICAgICAgIHN0ZXA9XCIxXCJcbiAgICAgICAgICAvPlxuICAgICAgICAgIDxjOHktbWVzc2FnZXMgW3Nob3ddPVwiZm9ybUdyb3VwLmNvbnRyb2xzLmZyYWN0aW9uU2l6ZS5lcnJvcnNcIj48L2M4eS1tZXNzYWdlcz5cbiAgICAgICAgPC9jOHktZm9ybS1ncm91cD5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cCBwLXItMTYgcC1sLTE2IG0tYi0wXCI+XG4gICAgICAgICAgPGxlZ2VuZD5cbiAgICAgICAgICAgIHt7ICdQcmVzZXRzJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgIDwvbGVnZW5kPlxuICAgICAgICAgIDxjOHktcHJlc2V0LXByZXZpZXdcbiAgICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cImdhdWdlUHJlc2V0SWRcIlxuICAgICAgICAgICAgW0FMTF9HQVVHRV9QUkVTRVRTXT1cIkFMTF9HQVVHRV9QUkVTRVRTXCJcbiAgICAgICAgICAgIChvblByZXNldENoYW5nZSk9XCJvblJhZGlvUHJlc2V0Q2hhbmdlKCRldmVudClcIlxuICAgICAgICAgID48L2M4eS1wcmVzZXQtcHJldmlldz5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPGRpdiBjbGFzcz1cInAtMTZcIj5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICBjbGFzcz1cImJ0biBidG4tZGVmYXVsdFwiXG4gICAgICAgICAgICBhcmlhLWNvbnRyb2xzPVwiYWR2YW5jZWRDb2xsYXBzZVwiXG4gICAgICAgICAgICBbYXR0ci5hcmlhLWV4cGFuZGVkXT1cInNob3dBZHZhbmNlZE9wdGlvbnNcIlxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAoY2xpY2spPVwic2hvd0FkdmFuY2VkT3B0aW9ucyA9ICFzaG93QWR2YW5jZWRPcHRpb25zXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICB7eyBzaG93QWR2YW5jZWRPcHRpb25zID8gaGlkZUFkdmFuY2VkT3B0aW9uc0xhYmVsIDogc2hvd0FkdmFuY2VkT3B0aW9uc0xhYmVsIH19XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXZcbiAgICAgICAgICBjbGFzcz1cImNvbGxhcHNlXCJcbiAgICAgICAgICBpZD1cImFkdmFuY2VkQ29sbGFwc2VcIlxuICAgICAgICAgIFtjb2xsYXBzZV09XCIhc2hvd0FkdmFuY2VkT3B0aW9uc1wiXG4gICAgICAgICAgW2lzQW5pbWF0ZWRdPVwidHJ1ZVwiXG4gICAgICAgID5cbiAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICBjbGFzcz1cImZpdC1oXCJcbiAgICAgICAgICAgIHN0eWxlPVwibWluLWhlaWdodDogNDAwcHhcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxjOHktZWRpdG9yXG4gICAgICAgICAgICAgIFtuZ01vZGVsXT1cImdhdWdlT3B0aW9uc1N0cmluZ1wiXG4gICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cImdhdWdlSlNPTkNoYW5nZSgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgKGVkaXRvckluaXQpPVwiYXNzaWduU2NoZW1hKClcIlxuICAgICAgICAgICAgICBbbmdNb2RlbE9wdGlvbnNdPVwieyBzdGFuZGFsb25lOiB0cnVlIH1cIlxuICAgICAgICAgICAgICBtb25hY29FZGl0b3JNYXJrZXJWYWxpZGF0b3JcbiAgICAgICAgICAgID48L2M4eS1lZGl0b3I+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2XG4gICAgICAgIGNsYXNzPVwiY29sLW1kLTZcIlxuICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgIHRoaXMuZm9ybUdyb3VwLnZhbHVlLmRhdGFwb2ludHNHYXVnZS5sZW5ndGggPiAwICYmIGFjdGl2ZURhdGFwb2ludEdhdWdlO1xuICAgICAgICAgIGVsc2UgZW1wdHlTdGF0ZVxuICAgICAgICBcIlxuICAgICAgPlxuICAgICAgICA8IS0tIFJhZGlhbCBHYXVnZSAtLT5cbiAgICAgICAgPGM4eS1yYWRpYWwtZ2F1Z2VcbiAgICAgICAgICBjbGFzcz1cImM4eS1yYWRpYWwtZ2F1Z2UtLXNxdWFyZVwiXG4gICAgICAgICAgKm5nSWY9XCJhY3RpdmVEYXRhcG9pbnRHYXVnZSB8IGluZm9HYXVnZUN1cnJlbnRNZWFzdXJlbWVudCB8IGFzeW5jIGFzIG1lYXN1cmVtZW50XCJcbiAgICAgICAgICBbYWN0aXZlRGF0YXBvaW50R2F1Z2VdPVwiYWN0aXZlRGF0YXBvaW50R2F1Z2VcIlxuICAgICAgICAgIFttZWFzdXJlbWVudF09XCJtZWFzdXJlbWVudFwiXG4gICAgICAgICAgW2ZyYWN0aW9uU2l6ZV09XCJmb3JtR3JvdXAudmFsdWUuZnJhY3Rpb25TaXplXCJcbiAgICAgICAgICBbZ2F1Z2VPcHRpb25zXT1cImdhdWdlT3B0aW9uc1wiXG4gICAgICAgICAgW3NlbGVjdGVkUHJlc2V0SWRdPVwiZm9ybUdyb3VwLnZhbHVlLmdhdWdlUHJlc2V0SWRcIlxuICAgICAgICA+PC9jOHktcmFkaWFsLWdhdWdlPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvbmctdGVtcGxhdGU+XG48L2Zvcm0+XG5cbjxuZy10ZW1wbGF0ZSAjZW1wdHlTdGF0ZT5cbiAgPGRpdiBjbGFzcz1cImNvbC1tZC02IGQtY29sIGEtaS1zdGFydCBqLWMtY2VudGVyXCI+XG4gICAgPGM4eS11aS1lbXB0eS1zdGF0ZVxuICAgICAgW2ljb25dPVwiJ2M4eS1kYXRhLXBvaW50cydcIlxuICAgICAgW3RpdGxlXT1cIidQbGVhc2Ugc2VsZWN0IGEgZGF0YSBwb2ludCBmaXJzdC4nIHwgdHJhbnNsYXRlXCJcbiAgICAgIFtob3Jpem9udGFsXT1cImZhbHNlXCJcbiAgICA+PC9jOHktdWktZW1wdHktc3RhdGU+XG4gIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==