UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

76 lines 28.8 kB
import { Component, Input, Optional } from '@angular/core'; import { DatePipe, DynamicComponentComponent, MeasurementRealtimeService } from '@c8y/ngx-components'; import { AsyncPipe, DecimalPipe, NgFor, NgIf, NgStyle } from '@angular/common'; import { InfoGaugeCurrentMeasurementPipe } from '../current-measurement.pipe'; import { ContextDashboardComponent } from '@c8y/ngx-components/context-dashboard'; import { defaultWidgetIds } from '@c8y/ngx-components/widgets/definitions'; import { RadialGaugeViewComponent } from '../radial-gauge/radial-gauge.component'; import * as i0 from "@angular/core"; import * as i1 from "@c8y/ngx-components/context-dashboard"; import * as i2 from "@c8y/ngx-components"; export class InfoGaugeWidgetViewComponent { constructor(dashboard, dynamicComponent) { this.dashboard = dashboard; this.dynamicComponent = dynamicComponent; this.activeDatapointLabels = []; this.fractionSize = '1.1-1'; } ngOnInit() { if (this.config?.datapoints && !this.config.datapointsGauge) { this.config.datapointsGauge = this.config.datapoints; } } ngOnChanges() { if (this.config?.datapointsLabels && Array.isArray(this.config?.datapointsLabels)) { this.config.datapointsLabels.forEach(dp => this.assignContextFromContextDashboard(dp)); this.activeDatapointLabels = this.config?.datapointsLabels.filter(dp => dp.__active); } if (this.config?.datapointsGauge && Array.isArray(this.config?.datapointsGauge)) { this.config.datapointsGauge.forEach(dp => this.assignContextFromContextDashboard(dp)); this.activeDatapointGauge = this.config?.datapointsGauge.find(dp => dp.__active); } if (this.config?.datapoints && Array.isArray(this.config?.datapoints) && this.config?.datapoints.length > 0 && !this.config?.datapointsGauge) { this.config.datapoints.forEach(dp => this.assignContextFromContextDashboard(dp)); this.activeDatapointGauge = this.config?.datapoints.find(dp => dp.__active); } if (typeof this.config.fractionSize === 'number' && !Number.isNaN(this.config.fractionSize)) { this.fractionSize = `1.${this.config.fractionSize}-${this.config.fractionSize}`; } this.isInfoGauge = this.dynamicComponent?.componentId === defaultWidgetIds.INFO_GAUGE; } assignContextFromContextDashboard(datapoint) { if (!this.dashboard?.isDeviceTypeDashboard) { return; } const context = this.dashboard?.context; if (context?.id) { const { name, id } = context; datapoint.__target = { name, id }; } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: InfoGaugeWidgetViewComponent, deps: [{ token: i1.ContextDashboardComponent, optional: true }, { token: i2.DynamicComponentComponent, optional: true }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: InfoGaugeWidgetViewComponent, isStandalone: true, selector: "c8y-info-gauge-widget-view", inputs: { config: "config" }, host: { classAttribute: "d-contents" }, providers: [MeasurementRealtimeService], usesOnChanges: true, ngImport: i0, template: "<div\n class=\"label-value-unit-gauge new-radial\"\n *ngIf=\"isInfoGauge\"\n>\n <div\n class=\"gauge-legend\"\n *ngIf=\"activeDatapointLabels?.length && isInfoGauge\"\n >\n <ng-container *ngFor=\"let dp of activeDatapointLabels\">\n <ng-container *ngIf=\"dp | infoGaugeCurrentMeasurement | async as measurement\">\n <label\n class=\"text-truncate\"\n title=\"{{ dp.label }}\"\n >\n {{ dp.label }}\n </label>\n <h3\n class=\"text-truncate\"\n title=\"{{ measurement.value | number: fractionSize }} {{ dp.unit || measurement.unit }}\"\n *ngIf=\"!measurement.notFound; else notFound\"\n >\n {{ measurement.value | number: fractionSize }} {{ dp.unit || measurement.unit }}\n </h3>\n <ng-template #notFound>\n <h3>--</h3>\n </ng-template>\n <p class=\"text-muted m-b-8\">\n <small>\n <em>{{ measurement.date | c8yDate: 'short' }}</em>\n </small>\n </p>\n </ng-container>\n </ng-container>\n </div>\n\n <ng-container *ngIf=\"activeDatapointGauge && isInfoGauge\">\n <div\n class=\"gauge-svg\"\n *ngIf=\"activeDatapointGauge | infoGaugeCurrentMeasurement: true | async as measurement\"\n >\n <svg\n height=\"214px\"\n width=\"214px\"\n viewBox=\"0 0 214 214\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <desc>radial gauge</desc>\n <g\n id=\"scale\"\n stroke=\"none\"\n stroke-width=\"1\"\n fill=\"none\"\n fill-rule=\"evenodd\"\n stroke-dasharray=\"1,5\"\n >\n <circle\n id=\"Oval\"\n stroke=\"#CACECE\"\n stroke-width=\"7\"\n cx=\"107\"\n cy=\"107\"\n r=\"103\"\n ></circle>\n <rect\n id=\"mask\"\n height=\"214\"\n stroke=\"none\"\n fill-rule=\"evenodd\"\n x=\"0\"\n y=\"0\"\n width=\"214\"\n transform=\"rotate(-45 290 182)\"\n ></rect>\n </g>\n <path\n class=\"track\"\n d=\"M 107 27 a 80 80 0 1 0.1 0 Z\"\n transform=\"rotate(-135 107 107)\"\n ></path>\n <path\n class=\"track-value\"\n [ngStyle]=\"{\n stroke: measurement.color,\n 'stroke-dashoffset': -measurement.strokeDashOffset\n }\"\n d=\"M 107 27 a 80 80 0 1 0.1 0 Z\"\n transform=\"rotate(-135 107 107)\"\n ></path>\n <foreignObject\n class=\"d-flex a-i-center j-c-center\"\n height=\"100%\"\n width=\"100%\"\n requiredFeatures=\"http://www.w3.org/TR/SVG11/feature#Extensibility\"\n >\n <div\n class=\"d-flex d-col fit-h a-i-center j-c-center\"\n style=\"padding: 3rem\"\n xmlns=\"http://www.w3.org/1999/xhtml\"\n >\n <p\n class=\"text-truncate text-center\"\n title=\"{{ activeDatapointGauge.label }}\"\n >\n {{ activeDatapointGauge.label }}\n </p>\n <p\n class=\"center-value text-truncate\"\n title=\"{{ measurement.value | number: fractionSize }}\"\n *ngIf=\"!measurement.notFound; else notFoundSVG\"\n >\n {{ measurement.value | number: fractionSize }}\n </p>\n <ng-template #notFoundSVG>\n <p class=\"center-value\">--</p>\n </ng-template>\n <p class=\"center-unit strong\">{{ activeDatapointGauge.unit || measurement.unit }}</p>\n <p class=\"center-date-time\">{{ measurement.date | c8yDate: 'short' }}</p>\n </div>\n </foreignObject>\n </svg>\n </div>\n </ng-container>\n\n <div class=\"clearfix\"></div>\n</div>\n<ng-container *ngIf=\"!isInfoGauge\">\n <c8y-radial-gauge\n *ngIf=\"activeDatapointGauge | infoGaugeCurrentMeasurement | async as measurement\"\n [activeDatapointGauge]=\"activeDatapointGauge\"\n [measurement]=\"measurement\"\n [fractionSize]=\"config.fractionSize\"\n [gaugeOptions]=\"config.gaugeOptions\"\n [selectedPresetId]=\"config.selectedPresetId\"\n ></c8y-radial-gauge>\n</ng-container>\n", dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: InfoGaugeCurrentMeasurementPipe, name: "infoGaugeCurrentMeasurement" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: DecimalPipe, name: "number" }, { kind: "pipe", type: DatePipe, name: "c8yDate" }, { kind: "component", type: RadialGaugeViewComponent, selector: "c8y-radial-gauge", inputs: ["activeDatapointGauge", "measurement", "fractionSize", "gaugeOptions", "selectedPresetId"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: InfoGaugeWidgetViewComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-info-gauge-widget-view', host: { class: 'd-contents' }, providers: [MeasurementRealtimeService], standalone: true, imports: [ NgIf, NgFor, NgStyle, InfoGaugeCurrentMeasurementPipe, AsyncPipe, DecimalPipe, DatePipe, RadialGaugeViewComponent ], template: "<div\n class=\"label-value-unit-gauge new-radial\"\n *ngIf=\"isInfoGauge\"\n>\n <div\n class=\"gauge-legend\"\n *ngIf=\"activeDatapointLabels?.length && isInfoGauge\"\n >\n <ng-container *ngFor=\"let dp of activeDatapointLabels\">\n <ng-container *ngIf=\"dp | infoGaugeCurrentMeasurement | async as measurement\">\n <label\n class=\"text-truncate\"\n title=\"{{ dp.label }}\"\n >\n {{ dp.label }}\n </label>\n <h3\n class=\"text-truncate\"\n title=\"{{ measurement.value | number: fractionSize }} {{ dp.unit || measurement.unit }}\"\n *ngIf=\"!measurement.notFound; else notFound\"\n >\n {{ measurement.value | number: fractionSize }} {{ dp.unit || measurement.unit }}\n </h3>\n <ng-template #notFound>\n <h3>--</h3>\n </ng-template>\n <p class=\"text-muted m-b-8\">\n <small>\n <em>{{ measurement.date | c8yDate: 'short' }}</em>\n </small>\n </p>\n </ng-container>\n </ng-container>\n </div>\n\n <ng-container *ngIf=\"activeDatapointGauge && isInfoGauge\">\n <div\n class=\"gauge-svg\"\n *ngIf=\"activeDatapointGauge | infoGaugeCurrentMeasurement: true | async as measurement\"\n >\n <svg\n height=\"214px\"\n width=\"214px\"\n viewBox=\"0 0 214 214\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <desc>radial gauge</desc>\n <g\n id=\"scale\"\n stroke=\"none\"\n stroke-width=\"1\"\n fill=\"none\"\n fill-rule=\"evenodd\"\n stroke-dasharray=\"1,5\"\n >\n <circle\n id=\"Oval\"\n stroke=\"#CACECE\"\n stroke-width=\"7\"\n cx=\"107\"\n cy=\"107\"\n r=\"103\"\n ></circle>\n <rect\n id=\"mask\"\n height=\"214\"\n stroke=\"none\"\n fill-rule=\"evenodd\"\n x=\"0\"\n y=\"0\"\n width=\"214\"\n transform=\"rotate(-45 290 182)\"\n ></rect>\n </g>\n <path\n class=\"track\"\n d=\"M 107 27 a 80 80 0 1 0.1 0 Z\"\n transform=\"rotate(-135 107 107)\"\n ></path>\n <path\n class=\"track-value\"\n [ngStyle]=\"{\n stroke: measurement.color,\n 'stroke-dashoffset': -measurement.strokeDashOffset\n }\"\n d=\"M 107 27 a 80 80 0 1 0.1 0 Z\"\n transform=\"rotate(-135 107 107)\"\n ></path>\n <foreignObject\n class=\"d-flex a-i-center j-c-center\"\n height=\"100%\"\n width=\"100%\"\n requiredFeatures=\"http://www.w3.org/TR/SVG11/feature#Extensibility\"\n >\n <div\n class=\"d-flex d-col fit-h a-i-center j-c-center\"\n style=\"padding: 3rem\"\n xmlns=\"http://www.w3.org/1999/xhtml\"\n >\n <p\n class=\"text-truncate text-center\"\n title=\"{{ activeDatapointGauge.label }}\"\n >\n {{ activeDatapointGauge.label }}\n </p>\n <p\n class=\"center-value text-truncate\"\n title=\"{{ measurement.value | number: fractionSize }}\"\n *ngIf=\"!measurement.notFound; else notFoundSVG\"\n >\n {{ measurement.value | number: fractionSize }}\n </p>\n <ng-template #notFoundSVG>\n <p class=\"center-value\">--</p>\n </ng-template>\n <p class=\"center-unit strong\">{{ activeDatapointGauge.unit || measurement.unit }}</p>\n <p class=\"center-date-time\">{{ measurement.date | c8yDate: 'short' }}</p>\n </div>\n </foreignObject>\n </svg>\n </div>\n </ng-container>\n\n <div class=\"clearfix\"></div>\n</div>\n<ng-container *ngIf=\"!isInfoGauge\">\n <c8y-radial-gauge\n *ngIf=\"activeDatapointGauge | infoGaugeCurrentMeasurement | async as measurement\"\n [activeDatapointGauge]=\"activeDatapointGauge\"\n [measurement]=\"measurement\"\n [fractionSize]=\"config.fractionSize\"\n [gaugeOptions]=\"config.gaugeOptions\"\n [selectedPresetId]=\"config.selectedPresetId\"\n ></c8y-radial-gauge>\n</ng-container>\n" }] }], ctorParameters: () => [{ type: i1.ContextDashboardComponent, decorators: [{ type: Optional }] }, { type: i2.DynamicComponentComponent, decorators: [{ type: Optional }] }], propDecorators: { config: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5mby1nYXVnZS13aWRnZXQtdmlldy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi93aWRnZXRzL2ltcGxlbWVudGF0aW9ucy9pbmZvLWdhdWdlL2luZm8tZ2F1Z2Utd2lkZ2V0LXZpZXcvaW5mby1nYXVnZS13aWRnZXQtdmlldy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi93aWRnZXRzL2ltcGxlbWVudGF0aW9ucy9pbmZvLWdhdWdlL2luZm8tZ2F1Z2Utd2lkZ2V0LXZpZXcvaW5mby1nYXVnZS13aWRnZXQtdmlldy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFhLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFdEUsT0FBTyxFQUNMLFFBQVEsRUFDUix5QkFBeUIsRUFDekIsMEJBQTBCLEVBQzNCLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvRSxPQUFPLEVBQUUsK0JBQStCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUM5RSxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUNsRixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUMzRSxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQzs7OztBQW9CbEYsTUFBTSxPQUFPLDRCQUE0QjtJQU92QyxZQUNzQixTQUFvQyxFQUNwQyxnQkFBNEM7UUFENUMsY0FBUyxHQUFULFNBQVMsQ0FBMkI7UUFDcEMscUJBQWdCLEdBQWhCLGdCQUFnQixDQUE0QjtRQVBsRSwwQkFBcUIsR0FBRyxFQUFFLENBQUM7UUFFM0IsaUJBQVksR0FBRyxPQUFPLENB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QUFNLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxHQUFHLE9BQU8sQ0FBQztZQUM3QixTQUFTLENBQUMsUUFBUSxHQUFHLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDO1FBQ3BDLENBQUM7SUFDSCxDQUFDOytHQXREVSw0QkFBNEI7bUdBQTVCLDRCQUE0QiwrSUFiNUIsQ0FBQywwQkFBMEIsQ0FBQywrQ0NsQnpDLG0zSUF5SUEsNENEcEhJLElBQUksNkZBQ0osS0FBSyxtSEFDTCxPQUFPLHNFQUNQLCtCQUErQiwrREFDL0IsU0FBUyx5Q0FDVCxXQUFXLDBDQUNYLFFBQVEsZ0RBQ1Isd0JBQXdCOzs0RkFHZiw0QkFBNEI7a0JBakJ4QyxTQUFTOytCQUNFLDRCQUE0QixRQUVoQyxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsYUFDbEIsQ0FBQywwQkFBMEIsQ0FBQyxjQUMzQixJQUFJLFdBQ1A7d0JBQ1AsSUFBSTt3QkFDSixLQUFLO3dCQUNMLE9BQU87d0JBQ1AsK0JBQStCO3dCQUMvQixTQUFTO3dCQUNULFdBQVc7d0JBQ1gsUUFBUTt3QkFDUix3QkFBd0I7cUJBQ3pCOzswQkFVRSxRQUFROzswQkFDUixRQUFRO3lDQVJGLE1BQU07c0JBQWQsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgT25DaGFuZ2VzLCBJbnB1dCwgT3B0aW9uYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB0eXBlIHsgS1BJRGV0YWlscyB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMvZGF0YXBvaW50LXNlbGVjdG9yJztcbmltcG9ydCB7XG4gIERhdGVQaXBlLFxuICBEeW5hbWljQ29tcG9uZW50Q29tcG9uZW50LFxuICBNZWFzdXJlbWVudFJlYWx0aW1lU2VydmljZVxufSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzJztcbmltcG9ydCB7IEFzeW5jUGlwZSwgRGVjaW1hbFBpcGUsIE5nRm9yLCBOZ0lmLCBOZ1N0eWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEluZm9HYXVnZUN1cnJlbnRNZWFzdXJlbWVudFBpcGUgfSBmcm9tICcuLi9jdXJyZW50LW1lYXN1cmVtZW50LnBpcGUnO1xuaW1wb3J0IHsgQ29udGV4dERhc2hib2FyZENvbXBvbmVudCB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMvY29udGV4dC1kYXNoYm9hcmQnO1xuaW1wb3J0IHsgZGVmYXVsdFdpZGdldElkcyB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMvd2lkZ2V0cy9kZWZpbml0aW9ucyc7XG5pbXBvcnQgeyBSYWRpYWxHYXVnZVZpZXdDb21wb25lbnQgfSBmcm9tICcuLi9yYWRpYWwtZ2F1Z2UvcmFkaWFsLWdhdWdlLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBJbmZvR2F1Z2VXaWRnZXRDb25maWcgfSBmcm9tICcuLi9pbmZvLWdhdWdlLXdpZGdldC1jb25maWcvZ2F1Z2UubW9kZWwnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjOHktaW5mby1nYXVnZS13aWRnZXQtdmlldycsXG4gIHRlbXBsYXRlVXJsOiAnLi9pbmZvLWdhdWdlLXdpZGdldC12aWV3LmNvbXBvbmVudC5odG1sJyxcbiAgaG9zdDogeyBjbGFzczogJ2QtY29udGVudHMnIH0sXG4gIHByb3ZpZGVyczogW01lYXN1cmVtZW50UmVhbHRpbWVTZXJ2aWNlXSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIE5nSWYsXG4gICAgTmdGb3IsXG4gICAgTmdTdHlsZSxcbiAgICBJbmZvR2F1Z2VDdXJyZW50TWVhc3VyZW1lbnRQaXBlLFxuICAgIEFzeW5jUGlwZSxcbiAgICBEZWNpbWFsUGlwZSxcbiAgICBEYXRlUGlwZSxcbiAgICBSYWRpYWxHYXVnZVZpZXdDb21wb25lbnRcbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBJbmZvR2F1Z2VXaWRnZXRWaWV3Q29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcbiAgQElucHV0KCkgY29uZmlnOiBJbmZvR2F1Z2VXaWRnZXRDb25maWc7XG4gIGFjdGl2ZURhdGFwb2ludExhYmVscyA9IFtdO1xuICBhY3RpdmVEYXRhcG9pbnRHYXVnZTogS1BJRGV0YWlscztcbiAgZnJhY3Rpb25TaXplID0gJzEuMS0xJztcbiAgaXNJbmZvR2F1Z2U6IGJvb2xlYW47XG5cbiAgY29uc3RydWN0b3IoXG4gICAgQE9wdGlvbmFsKCkgcHJpdmF0ZSBkYXNoYm9hcmQ6IENvbnRleHREYXNoYm9hcmRDb21wb25lbnQsXG4gICAgQE9wdGlvbmFsKCkgcHJpdmF0ZSBkeW5hbWljQ29tcG9uZW50PzogRHluYW1pY0NvbXBvbmVudENvbXBvbmVudFxuICApIHt9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgaWYgKHRoaXMuY29uZmlnPy5kYXRhcG9pbnRzICYmICF0aGlzLmNvbmZpZy5kYXRhcG9pbnRzR2F1Z2UpIHtcbiAgICAgIHRoaXMuY29uZmlnLmRhdGFwb2ludHNHYXVnZSA9IHRoaXMuY29uZmlnLmRhdGFwb2ludHM7XG4gICAgfVxuICB9XG5cbiAgbmdPbkNoYW5nZXMoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuY29uZmlnPy5kYXRhcG9pbnRzTGFiZWxzICYmIEFycmF5LmlzQXJyYXkodGhpcy5jb25maWc/LmRhdGFwb2ludHNMYWJlbHMpKSB7XG4gICAgICB0aGlzLmNvbmZpZy5kYXRhcG9pbnRzTGFiZWxzLmZvckVhY2goZHAgPT4gdGhpcy5hc3NpZ25Db250ZXh0RnJvbUNvbnRleHREYXNoYm9hcmQoZHApKTtcbiAgICAgIHRoaXMuYWN0aXZlRGF0YXBvaW50TGFiZWxzID0gdGhpcy5jb25maWc/LmRhdGFwb2ludHNMYWJlbHMuZmlsdGVyKGRwID0+IGRwLl9fYWN0aXZlKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jb25maWc/LmRhdGFwb2ludHNHYXVnZSAmJiBBcnJheS5pc0FycmF5KHRoaXMuY29uZmlnPy5kYXRhcG9pbnRzR2F1Z2UpKSB7XG4gICAgICB0aGlzLmNvbmZpZy5kYXRhcG9pbnRzR2F1Z2UuZm9yRWFjaChkcCA9PiB0aGlzLmFzc2lnbkNvbnRleHRGcm9tQ29udGV4dERhc2hib2FyZChkcCkpO1xuICAgICAgdGhpcy5hY3RpdmVEYXRhcG9pbnRHYXVnZSA9IHRoaXMuY29uZmlnPy5kYXRhcG9pbnRzR2F1Z2UuZmluZChkcCA9PiBkcC5fX2FjdGl2ZSk7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdGhpcy5jb25maWc/LmRhdGFwb2ludHMgJiZcbiAgICAgIEFycmF5LmlzQXJyYXkodGhpcy5jb25maWc/LmRhdGFwb2ludHMpICYmXG4gICAgICB0aGlzLmNvbmZpZz8uZGF0YXBvaW50cy5sZW5ndGggPiAwICYmXG4gICAgICAhdGhpcy5jb25maWc/LmRhdGFwb2ludHNHYXVnZVxuICAgICkge1xuICAgICAgdGhpcy5jb25maWcuZGF0YXBvaW50cy5mb3JFYWNoKGRwID0+IHRoaXMuYXNzaWduQ29udGV4dEZyb21Db250ZXh0RGFzaGJvYXJkKGRwKSk7XG4gICAgICB0aGlzLmFjdGl2ZURhdGFwb2ludEdhdWdlID0gdGhpcy5jb25maWc/LmRhdGFwb2ludHMuZmluZChkcCA9PiBkcC5fX2FjdGl2ZSk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiB0aGlzLmNvbmZpZy5mcmFjdGlvblNpemUgPT09ICdudW1iZXInICYmICFOdW1iZXIuaXNOYU4odGhpcy5jb25maWcuZnJhY3Rpb25TaXplKSkge1xuICAgICAgdGhpcy5mcmFjdGlvblNpemUgPSBgMS4ke3RoaXMuY29uZmlnLmZyYWN0aW9uU2l6ZX0tJHt0aGlzLmNvbmZpZy5mcmFjdGlvblNpemV9YDtcbiAgICB9XG4gICAgdGhpcy5pc0luZm9HYXVnZSA9IHRoaXMuZHluYW1pY0NvbXBvbmVudD8uY29tcG9uZW50SWQgPT09IGRlZmF1bHRXaWRnZXRJZHMuSU5GT19HQVVHRTtcbiAgfVxuXG4gIHByaXZhdGUgYXNzaWduQ29udGV4dEZyb21Db250ZXh0RGFzaGJvYXJkKGRhdGFwb2ludDogS1BJRGV0YWlscykge1xuICAgIGlmICghdGhpcy5kYXNoYm9hcmQ/LmlzRGV2aWNlVHlwZURhc2hib2FyZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5kYXNoYm9hcmQ/LmNvbnRleHQ7XG4gICAgaWYgKGNvbnRleHQ/LmlkKSB7XG4gICAgICBjb25zdCB7IG5hbWUsIGlkIH0gPSBjb250ZXh0O1xuICAgICAgZGF0YXBvaW50Ll9fdGFyZ2V0ID0geyBuYW1lLCBpZCB9O1xuICAgIH1cbiAgfVxufVxuIiwiPGRpdlxuICBjbGFzcz1cImxhYmVsLXZhbHVlLXVuaXQtZ2F1Z2UgbmV3LXJhZGlhbFwiXG4gICpuZ0lmPVwiaXNJbmZvR2F1Z2VcIlxuPlxuICA8ZGl2XG4gICAgY2xhc3M9XCJnYXVnZS1sZWdlbmRcIlxuICAgICpuZ0lmPVwiYWN0aXZlRGF0YXBvaW50TGFiZWxzPy5sZW5ndGggJiYgaXNJbmZvR2F1Z2VcIlxuICA+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgZHAgb2YgYWN0aXZlRGF0YXBvaW50TGFiZWxzXCI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZHAgfCBpbmZvR2F1Z2VDdXJyZW50TWVhc3VyZW1lbnQgfCBhc3luYyBhcyBtZWFzdXJlbWVudFwiPlxuICAgICAgICA8bGFiZWxcbiAgICAgICAgICBjbGFzcz1cInRleHQtdHJ1bmNhdGVcIlxuICAgICAgICAgIHRpdGxlPVwie3sgZHAubGFiZWwgfX1cIlxuICAgICAgICA+XG4gICAgICAgICAge3sgZHAubGFiZWwgfX1cbiAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgPGgzXG4gICAgICAgICAgY2xhc3M9XCJ0ZXh0LXRydW5jYXRlXCJcbiAgICAgICAgICB0aXRsZT1cInt7IG1lYXN1cmVtZW50LnZhbHVlIHwgbnVtYmVyOiBmcmFjdGlvblNpemUgfX0ge3sgZHAudW5pdCB8fCBtZWFzdXJlbWVudC51bml0IH19XCJcbiAgICAgICAgICAqbmdJZj1cIiFtZWFzdXJlbWVudC5ub3RGb3VuZDsgZWxzZSBub3RGb3VuZFwiXG4gICAgICAgID5cbiAgICAgICAgICB7eyBtZWFzdXJlbWVudC52YWx1ZSB8IG51bWJlcjogZnJhY3Rpb25TaXplIH19IHt7IGRwLnVuaXQgfHwgbWVhc3VyZW1lbnQudW5pdCB9fVxuICAgICAgICA8L2gzPlxuICAgICAgICA8bmctdGVtcGxhdGUgI25vdEZvdW5kPlxuICAgICAgICAgIDxoMz4tLTwvaDM+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgIDxwIGNsYXNzPVwidGV4dC1tdXRlZCBtLWItOFwiPlxuICAgICAgICAgIDxzbWFsbD5cbiAgICAgICAgICAgIDxlbT57eyBtZWFzdXJlbWVudC5kYXRlIHwgYzh5RGF0ZTogJ3Nob3J0JyB9fTwvZW0+XG4gICAgICAgICAgPC9zbWFsbD5cbiAgICAgICAgPC9wPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC9uZy1jb250YWluZXI+XG4gIDwvZGl2PlxuXG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJhY3RpdmVEYXRhcG9pbnRHYXVnZSAmJiBpc0luZm9HYXVnZVwiPlxuICAgIDxkaXZcbiAgICAgIGNsYXNzPVwiZ2F1Z2Utc3ZnXCJcbiAgICAgICpuZ0lmPVwiYWN0aXZlRGF0YXBvaW50R2F1Z2UgfCBpbmZvR2F1Z2VDdXJyZW50TWVhc3VyZW1lbnQ6IHRydWUgfCBhc3luYyBhcyBtZWFzdXJlbWVudFwiXG4gICAgPlxuICAgICAgPHN2Z1xuICAgICAgICBoZWlnaHQ9XCIyMTRweFwiXG4gICAgICAgIHdpZHRoPVwiMjE0cHhcIlxuICAgICAgICB2aWV3Qm94PVwiMCAwIDIxNCAyMTRcIlxuICAgICAgICB2ZXJzaW9uPVwiMS4xXCJcbiAgICAgICAgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiXG4gICAgICAgIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiXG4gICAgICA+XG4gICAgICAgIDxkZXNjPnJhZGlhbCBnYXVnZTwvZGVzYz5cbiAgICAgICAgPGdcbiAgICAgICAgICBpZD1cInNjYWxlXCJcbiAgICAgICAgICBzdHJva2U9XCJub25lXCJcbiAgICAgICAgICBzdHJva2Utd2lkdGg9XCIxXCJcbiAgICAgICAgICBmaWxsPVwibm9uZVwiXG4gICAgICAgICAgZmlsbC1ydWxlPVwiZXZlbm9kZFwiXG4gICAgICAgICAgc3Ryb2tlLWRhc2hhcnJheT1cIjEsNVwiXG4gICAgICAgID5cbiAgICAgICAgICA8Y2lyY2xlXG4gICAgICAgICAgICBpZD1cIk92YWxcIlxuICAgICAgICAgICAgc3Ryb2tlPVwiI0NBQ0VDRVwiXG4gICAgICAgICAgICBzdHJva2Utd2lkdGg9XCI3XCJcbiAgICAgICAgICAgIGN4PVwiMTA3XCJcbiAgICAgICAgICAgIGN5PVwiMTA3XCJcbiAgICAgICAgICAgIHI9XCIxMDNcIlxuICAgICAgICAgID48L2NpcmNsZT5cbiAgICAgICAgICA8cmVjdFxuICAgICAgICAgICAgaWQ9XCJtYXNrXCJcbiAgICAgICAgICAgIGhlaWdodD1cIjIxNFwiXG4gICAgICAgICAgICBzdHJva2U9XCJub25lXCJcbiAgICAgICAgICAgIGZpbGwtcnVsZT1cImV2ZW5vZGRcIlxuICAgICAgICAgICAgeD1cIjBcIlxuICAgICAgICAgICAgeT1cIjBcIlxuICAgICAgICAgICAgd2lkdGg9XCIyMTRcIlxuICAgICAgICAgICAgdHJhbnNmb3JtPVwicm90YXRlKC00NSAyOTAgMTgyKVwiXG4gICAgICAgICAgPjwvcmVjdD5cbiAgICAgICAgPC9nPlxuICAgICAgICA8cGF0aFxuICAgICAgICAgIGNsYXNzPVwidHJhY2tcIlxuICAgICAgICAgIGQ9XCJNIDEwNyAyNyBhIDgwIDgwIDAgMSAwLjEgMCBaXCJcbiAgICAgICAgICB0cmFuc2Zvcm09XCJyb3RhdGUoLTEzNSAxMDcgMTA3KVwiXG4gICAgICAgID48L3BhdGg+XG4gICAgICAgIDxwYXRoXG4gICAgICAgICAgY2xhc3M9XCJ0cmFjay12YWx1ZVwiXG4gICAgICAgICAgW25nU3R5bGVdPVwie1xuICAgICAgICAgICAgc3Ryb2tlOiBtZWFzdXJlbWVudC5jb2xvcixcbiAgICAgICAgICAgICdzdHJva2UtZGFzaG9mZnNldCc6IC1tZWFzdXJlbWVudC5zdHJva2VEYXNoT2Zmc2V0XG4gICAgICAgICAgfVwiXG4gICAgICAgICAgZD1cIk0gMTA3IDI3IGEgODAgODAgMCAxIDAuMSAwIFpcIlxuICAgICAgICAgIHRyYW5zZm9ybT1cInJvdGF0ZSgtMTM1IDEwNyAxMDcpXCJcbiAgICAgICAgPjwvcGF0aD5cbiAgICAgICAgPGZvcmVpZ25PYmplY3RcbiAgICAgICAgICBjbGFzcz1cImQtZmxleCBhLWktY2VudGVyIGotYy1jZW50ZXJcIlxuICAgICAgICAgIGhlaWdodD1cIjEwMCVcIlxuICAgICAgICAgIHdpZHRoPVwiMTAwJVwiXG4gICAgICAgICAgcmVxdWlyZWRGZWF0dXJlcz1cImh0dHA6Ly93d3cudzMub3JnL1RSL1NWRzExL2ZlYXR1cmUjRXh0ZW5zaWJpbGl0eVwiXG4gICAgICAgID5cbiAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICBjbGFzcz1cImQtZmxleCBkLWNvbCBmaXQtaCBhLWktY2VudGVyIGotYy1jZW50ZXJcIlxuICAgICAgICAgICAgc3R5bGU9XCJwYWRkaW5nOiAzcmVtXCJcbiAgICAgICAgICAgIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHBcbiAgICAgICAgICAgICAgY2xhc3M9XCJ0ZXh0LXRydW5jYXRlIHRleHQtY2VudGVyXCJcbiAgICAgICAgICAgICAgdGl0bGU9XCJ7eyBhY3RpdmVEYXRhcG9pbnRHYXVnZS5sYWJlbCB9fVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIHt7IGFjdGl2ZURhdGFwb2ludEdhdWdlLmxhYmVsIH19XG4gICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICA8cFxuICAgICAgICAgICAgICBjbGFzcz1cImNlbnRlci12YWx1ZSB0ZXh0LXRydW5jYXRlXCJcbiAgICAgICAgICAgICAgdGl0bGU9XCJ7eyBtZWFzdXJlbWVudC52YWx1ZSB8IG51bWJlcjogZnJhY3Rpb25TaXplIH19XCJcbiAgICAgICAgICAgICAgKm5nSWY9XCIhbWVhc3VyZW1lbnQubm90Rm91bmQ7IGVsc2Ugbm90Rm91bmRTVkdcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICB7eyBtZWFzdXJlbWVudC52YWx1ZSB8IG51bWJlcjogZnJhY3Rpb25TaXplIH19XG4gICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgI25vdEZvdW5kU1ZHPlxuICAgICAgICAgICAgICA8cCBjbGFzcz1cImNlbnRlci12YWx1ZVwiPi0tPC9wPlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIDxwIGNsYXNzPVwiY2VudGVyLXVuaXQgc3Ryb25nXCI+e3sgYWN0aXZlRGF0YXBvaW50R2F1Z2UudW5pdCB8fCBtZWFzdXJlbWVudC51bml0IH19PC9wPlxuICAgICAgICAgICAgPHAgY2xhc3M9XCJjZW50ZXItZGF0ZS10aW1lXCI+e3sgbWVhc3VyZW1lbnQuZGF0ZSB8IGM4eURhdGU6ICdzaG9ydCcgfX08L3A+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZm9yZWlnbk9iamVjdD5cbiAgICAgIDwvc3ZnPlxuICAgIDwvZGl2PlxuICA8L25nLWNvbnRhaW5lcj5cblxuICA8ZGl2IGNsYXNzPVwiY2xlYXJmaXhcIj48L2Rpdj5cbjwvZGl2PlxuPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFpc0luZm9HYXVnZVwiPlxuICA8Yzh5LXJhZGlhbC1nYXVnZVxuICAgICpuZ0lmPVwiYWN0aXZlRGF0YXBvaW50R2F1Z2UgfCBpbmZvR2F1Z2VDdXJyZW50TWVhc3VyZW1lbnQgfCBhc3luYyBhcyBtZWFzdXJlbWVudFwiXG4gICAgW2FjdGl2ZURhdGFwb2ludEdhdWdlXT1cImFjdGl2ZURhdGFwb2ludEdhdWdlXCJcbiAgICBbbWVhc3VyZW1lbnRdPVwibWVhc3VyZW1lbnRcIlxuICAgIFtmcmFjdGlvblNpemVdPVwiY29uZmlnLmZyYWN0aW9uU2l6ZVwiXG4gICAgW2dhdWdlT3B0aW9uc109XCJjb25maWcuZ2F1Z2VPcHRpb25zXCJcbiAgICBbc2VsZWN0ZWRQcmVzZXRJZF09XCJjb25maWcuc2VsZWN0ZWRQcmVzZXRJZFwiXG4gID48L2M4eS1yYWRpYWwtZ2F1Z2U+XG48L25nLWNvbnRhaW5lcj5cbiJdfQ==