@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
48 lines • 23.1 kB
JavaScript
import { Component, Input, Optional } from '@angular/core';
import { DatePipe, 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 * as i0 from "@angular/core";
import * as i1 from "@c8y/ngx-components/context-dashboard";
export class InfoGaugeWidgetViewComponent {
constructor(dashboard) {
this.dashboard = dashboard;
this.activeDatapointLabels = [];
this.fractionSize = '1.1-1';
}
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 (typeof this.config.fractionSize === 'number' && !Number.isNaN(this.config.fractionSize)) {
this.fractionSize = `1.${this.config.fractionSize}-${this.config.fractionSize}`;
}
}
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 }], 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 class=\"label-value-unit-gauge\">\n <div\n class=\"gauge-legend\"\n *ngIf=\"activeDatapointLabels?.length\"\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\">\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 <div class=\"clearfix\"></div>\n</div>\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" }] }); }
}
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], template: "<div class=\"label-value-unit-gauge\">\n <div\n class=\"gauge-legend\"\n *ngIf=\"activeDatapointLabels?.length\"\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\">\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 <div class=\"clearfix\"></div>\n</div>\n" }]
}], ctorParameters: () => [{ type: i1.ContextDashboardComponent, decorators: [{
type: Optional
}] }], propDecorators: { config: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5mby1nYXVnZS13aWRnZXQtdmlldy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi93aWRnZXRzL2ltcGxlbWVudGF0aW9ucy9pbmZvLWdhdWdlL2luZm8tZ2F1Z2Utd2lkZ2V0LXZpZXcvaW5mby1nYXVnZS13aWRnZXQtdmlldy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi93aWRnZXRzL2ltcGxlbWVudGF0aW9ucy9pbmZvLWdhdWdlL2luZm8tZ2F1Z2Utd2lkZ2V0LXZpZXcvaW5mby1nYXVnZS13aWRnZXQtdmlldy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFhLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFdEUsT0FBTyxFQUFFLFFBQVEsRUFBRSwwQkFBMEIsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQzNFLE9BQU8sRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0UsT0FBTyxFQUFFLCtCQUErQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDOUUsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sdUNBQXVDLENBQUM7OztBQVdsRixNQUFNLE9BQU8sNEJBQTRCO0lBTXZDLFlBQWdDLFNBQW9DO1FBQXBDLGNBQVMsR0FBVCxTQUFTLENBQTJCO1FBSnBFLDBCQUFxQixHQUFHLEVBQUUsQ0FBQztRQUUzQixpQkFBWSxHQUFHLE9BQU8sQ0FBQztJQUVnRCxDQUFDO0lBRXhFLFdBQVc7UUFDVCxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsZ0JBQWdCLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLGdCQUFnQixDQUFDLEVBQUUsQ0FBQztZQUNsRixJQUFJLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxpQ0FBaUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3ZGLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN2RixDQUFDO1FBRUQsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLGVBQWUsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsZUFBZSxDQUFDLEVBQUUsQ0FBQztZQUNoRixJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsaUNBQWlDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUN0RixJQUFJLENBQUMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxlQUFlLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ25GLENBQUM7UUFFRCxJQUFJLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLEtBQUssUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7WUFDNUYsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFLLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDbEYsQ0FBQztJQUNILENBQUM7SUFFTyxpQ0FBaUMsQ0FBQyxTQUFxQjtRQUM3RCxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxxQkFBcUIsRUFBRSxDQUFDO1lBQzNDLE9BQU87UUFDVCxDQUFDO1FBQ0QsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUM7UUFDeEMsSUFBSSxPQUFPLEVBQUUsRUFBRSxFQUFFLENBQUM7WUFDaEIsTUFBTSxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsR0FBRyxPQUFPLENBQUM7WUFDN0IsU0FBUyxDQUFDLFFBQVEsR0FBRyxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsQ0FBQztRQUNwQyxDQUFDO0lBQ0gsQ0FBQzsrR0FqQ1UsNEJBQTRCO21HQUE1Qiw0QkFBNEIsK0lBSjVCLENBQUMsMEJBQTBCLENBQUMsK0NDWnpDLHc0SEEySEEsNENEN0dZLElBQUksNkZBQUUsS0FBSyxtSEFBRSxPQUFPLHNFQUFFLCtCQUErQiwrREFBRSxTQUFTLHlDQUFFLFdBQVcsMENBQUUsUUFBUTs7NEZBRXRGLDRCQUE0QjtrQkFSeEMsU0FBUzsrQkFDRSw0QkFBNEIsUUFFaEMsRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLGFBQ2xCLENBQUMsMEJBQTBCLENBQUMsY0FDM0IsSUFBSSxXQUNQLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsK0JBQStCLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxRQUFRLENBQUM7OzBCQVFyRixRQUFRO3lDQUxaLE1BQU07c0JBQWQsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgT25DaGFuZ2VzLCBJbnB1dCwgT3B0aW9uYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB0eXBlIHsgS1BJRGV0YWlscyB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMvZGF0YXBvaW50LXNlbGVjdG9yJztcbmltcG9ydCB7IERhdGVQaXBlLCBNZWFzdXJlbWVudFJlYWx0aW1lU2VydmljZSB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMnO1xuaW1wb3J0IHsgQXN5bmNQaXBlLCBEZWNpbWFsUGlwZSwgTmdGb3IsIE5nSWYsIE5nU3R5bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgSW5mb0dhdWdlQ3VycmVudE1lYXN1cmVtZW50UGlwZSB9IGZyb20gJy4uL2N1cnJlbnQtbWVhc3VyZW1lbnQucGlwZSc7XG5pbXBvcnQgeyBDb250ZXh0RGFzaGJvYXJkQ29tcG9uZW50IH0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cy9jb250ZXh0LWRhc2hib2FyZCc7XG5pbXBvcnQgeyBJbmZvR2F1Z2VXaWRnZXRDb25maWcgfSBmcm9tICcuLi9pbmZvLWdhdWdlLm1vZGVsJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYzh5LWluZm8tZ2F1Z2Utd2lkZ2V0LXZpZXcnLFxuICB0ZW1wbGF0ZVVybDogJy4vaW5mby1nYXVnZS13aWRnZXQtdmlldy5jb21wb25lbnQuaHRtbCcsXG4gIGhvc3Q6IHsgY2xhc3M6ICdkLWNvbnRlbnRzJyB9LFxuICBwcm92aWRlcnM6IFtNZWFzdXJlbWVudFJlYWx0aW1lU2VydmljZV0sXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtOZ0lmLCBOZ0ZvciwgTmdTdHlsZSwgSW5mb0dhdWdlQ3VycmVudE1lYXN1cmVtZW50UGlwZSwgQXN5bmNQaXBlLCBEZWNpbWFsUGlwZSwgRGF0ZVBpcGVdXG59KVxuZXhwb3J0IGNsYXNzIEluZm9HYXVnZVdpZGdldFZpZXdDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMge1xuICBASW5wdXQoKSBjb25maWc6IEluZm9HYXVnZVdpZGdldENvbmZpZztcbiAgYWN0aXZlRGF0YXBvaW50TGFiZWxzID0gW107XG4gIGFjdGl2ZURhdGFwb2ludEdhdWdlOiBLUElEZXRhaWxzO1xuICBmcmFjdGlvblNpemUgPSAnMS4xLTEnO1xuXG4gIGNvbnN0cnVjdG9yKEBPcHRpb25hbCgpIHByaXZhdGUgZGFzaGJvYXJkOiBDb250ZXh0RGFzaGJvYXJkQ29tcG9uZW50KSB7fVxuXG4gIG5nT25DaGFuZ2VzKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmNvbmZpZz8uZGF0YXBvaW50c0xhYmVscyAmJiBBcnJheS5pc0FycmF5KHRoaXMuY29uZmlnPy5kYXRhcG9pbnRzTGFiZWxzKSkge1xuICAgICAgdGhpcy5jb25maWcuZGF0YXBvaW50c0xhYmVscy5mb3JFYWNoKGRwID0+IHRoaXMuYXNzaWduQ29udGV4dEZyb21Db250ZXh0RGFzaGJvYXJkKGRwKSk7XG4gICAgICB0aGlzLmFjdGl2ZURhdGFwb2ludExhYmVscyA9IHRoaXMuY29uZmlnPy5kYXRhcG9pbnRzTGFiZWxzLmZpbHRlcihkcCA9PiBkcC5fX2FjdGl2ZSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY29uZmlnPy5kYXRhcG9pbnRzR2F1Z2UgJiYgQXJyYXkuaXNBcnJheSh0aGlzLmNvbmZpZz8uZGF0YXBvaW50c0dhdWdlKSkge1xuICAgICAgdGhpcy5jb25maWcuZGF0YXBvaW50c0dhdWdlLmZvckVhY2goZHAgPT4gdGhpcy5hc3NpZ25Db250ZXh0RnJvbUNvbnRleHREYXNoYm9hcmQoZHApKTtcbiAgICAgIHRoaXMuYWN0aXZlRGF0YXBvaW50R2F1Z2UgPSB0aGlzLmNvbmZpZz8uZGF0YXBvaW50c0dhdWdlLmZpbmQoZHAgPT4gZHAuX19hY3RpdmUpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdGhpcy5jb25maWcuZnJhY3Rpb25TaXplID09PSAnbnVtYmVyJyAmJiAhTnVtYmVyLmlzTmFOKHRoaXMuY29uZmlnLmZyYWN0aW9uU2l6ZSkpIHtcbiAgICAgIHRoaXMuZnJhY3Rpb25TaXplID0gYDEuJHt0aGlzLmNvbmZpZy5mcmFjdGlvblNpemV9LSR7dGhpcy5jb25maWcuZnJhY3Rpb25TaXplfWA7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3NpZ25Db250ZXh0RnJvbUNvbnRleHREYXNoYm9hcmQoZGF0YXBvaW50OiBLUElEZXRhaWxzKSB7XG4gICAgaWYgKCF0aGlzLmRhc2hib2FyZD8uaXNEZXZpY2VUeXBlRGFzaGJvYXJkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLmRhc2hib2FyZD8uY29udGV4dDtcbiAgICBpZiAoY29udGV4dD8uaWQpIHtcbiAgICAgIGNvbnN0IHsgbmFtZSwgaWQgfSA9IGNvbnRleHQ7XG4gICAgICBkYXRhcG9pbnQuX190YXJnZXQgPSB7IG5hbWUsIGlkIH07XG4gICAgfVxuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwibGFiZWwtdmFsdWUtdW5pdC1nYXVnZVwiPlxuICA8ZGl2XG4gICAgY2xhc3M9XCJnYXVnZS1sZWdlbmRcIlxuICAgICpuZ0lmPVwiYWN0aXZlRGF0YXBvaW50TGFiZWxzPy5sZW5ndGhcIlxuICA+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgZHAgb2YgYWN0aXZlRGF0YXBvaW50TGFiZWxzXCI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZHAgfCBpbmZvR2F1Z2VDdXJyZW50TWVhc3VyZW1lbnQgfCBhc3luYyBhcyBtZWFzdXJlbWVudFwiPlxuICAgICAgICA8bGFiZWxcbiAgICAgICAgICBjbGFzcz1cInRleHQtdHJ1bmNhdGVcIlxuICAgICAgICAgIHRpdGxlPVwie3sgZHAubGFiZWwgfX1cIlxuICAgICAgICA+XG4gICAgICAgICAge3sgZHAubGFiZWwgfX1cbiAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgPGgzXG4gICAgICAgICAgY2xhc3M9XCJ0ZXh0LXRydW5jYXRlXCJcbiAgICAgICAgICB0aXRsZT1cInt7IG1lYXN1cmVtZW50LnZhbHVlIHwgbnVtYmVyOiBmcmFjdGlvblNpemUgfX0ge3sgZHAudW5pdCB8fCBtZWFzdXJlbWVudC51bml0IH19XCJcbiAgICAgICAgICAqbmdJZj1cIiFtZWFzdXJlbWVudC5ub3RGb3VuZDsgZWxzZSBub3RGb3VuZFwiXG4gICAgICAgID5cbiAgICAgICAgICB7eyBtZWFzdXJlbWVudC52YWx1ZSB8IG51bWJlcjogZnJhY3Rpb25TaXplIH19IHt7IGRwLnVuaXQgfHwgbWVhc3VyZW1lbnQudW5pdCB9fVxuICAgICAgICA8L2gzPlxuICAgICAgICA8bmctdGVtcGxhdGUgI25vdEZvdW5kPlxuICAgICAgICAgIDxoMz4tLTwvaDM+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgIDxwIGNsYXNzPVwidGV4dC1tdXRlZCBtLWItOFwiPlxuICAgICAgICAgIDxzbWFsbD5cbiAgICAgICAgICAgIDxlbT57eyBtZWFzdXJlbWVudC5kYXRlIHwgYzh5RGF0ZTogJ3Nob3J0JyB9fTwvZW0+XG4gICAgICAgICAgPC9zbWFsbD5cbiAgICAgICAgPC9wPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC9uZy1jb250YWluZXI+XG4gIDwvZGl2PlxuXG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJhY3RpdmVEYXRhcG9pbnRHYXVnZVwiPlxuICAgIDxkaXZcbiAgICAgIGNsYXNzPVwiZ2F1Z2Utc3ZnXCJcbiAgICAgICpuZ0lmPVwiYWN0aXZlRGF0YXBvaW50R2F1Z2UgfCBpbmZvR2F1Z2VDdXJyZW50TWVhc3VyZW1lbnQ6IHRydWUgfCBhc3luYyBhcyBtZWFzdXJlbWVudFwiXG4gICAgPlxuICAgICAgPHN2Z1xuICAgICAgICBoZWlnaHQ9XCIyMTRweFwiXG4gICAgICAgIHdpZHRoPVwiMjE0cHhcIlxuICAgICAgICB2aWV3Qm94PVwiMCAwIDIxNCAyMTRcIlxuICAgICAgICB2ZXJzaW9uPVwiMS4xXCJcbiAgICAgICAgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiXG4gICAgICAgIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiXG4gICAgICA+XG4gICAgICAgIDxkZXNjPnJhZGlhbCBnYXVnZTwvZGVzYz5cbiAgICAgICAgPGdcbiAgICAgICAgICBpZD1cInNjYWxlXCJcbiAgICAgICAgICBzdHJva2U9XCJub25lXCJcbiAgICAgICAgICBzdHJva2Utd2lkdGg9XCIxXCJcbiAgICAgICAgICBmaWxsPVwibm9uZVwiXG4gICAgICAgICAgZmlsbC1ydWxlPVwiZXZlbm9kZFwiXG4gICAgICAgICAgc3Ryb2tlLWRhc2hhcnJheT1cIjEsNVwiXG4gICAgICAgID5cbiAgICAgICAgICA8Y2lyY2xlXG4gICAgICAgICAgICBpZD1cIk92YWxcIlxuICAgICAgICAgICAgc3Ryb2tlPVwiI0NBQ0VDRVwiXG4gICAgICAgICAgICBzdHJva2Utd2lkdGg9XCI3XCJcbiAgICAgICAgICAgIGN4PVwiMTA3XCJcbiAgICAgICAgICAgIGN5PVwiMTA3XCJcbiAgICAgICAgICAgIHI9XCIxMDNcIlxuICAgICAgICAgID48L2NpcmNsZT5cbiAgICAgICAgICA8cmVjdFxuICAgICAgICAgICAgaWQ9XCJtYXNrXCJcbiAgICAgICAgICAgIGhlaWdodD1cIjIxNFwiXG4gICAgICAgICAgICBzdHJva2U9XCJub25lXCJcbiAgICAgICAgICAgIGZpbGwtcnVsZT1cImV2ZW5vZGRcIlxuICAgICAgICAgICAgeD1cIjBcIlxuICAgICAgICAgICAgeT1cIjBcIlxuICAgICAgICAgICAgd2lkdGg9XCIyMTRcIlxuICAgICAgICAgICAgdHJhbnNmb3JtPVwicm90YXRlKC00NSAyOTAgMTgyKVwiXG4gICAgICAgICAgPjwvcmVjdD5cbiAgICAgICAgPC9nPlxuICAgICAgICA8cGF0aFxuICAgICAgICAgIGNsYXNzPVwidHJhY2tcIlxuICAgICAgICAgIGQ9XCJNIDEwNyAyNyBhIDgwIDgwIDAgMSAwLjEgMCBaXCJcbiAgICAgICAgICB0cmFuc2Zvcm09XCJyb3RhdGUoLTEzNSAxMDcgMTA3KVwiXG4gICAgICAgID48L3BhdGg+XG4gICAgICAgIDxwYXRoXG4gICAgICAgICAgY2xhc3M9XCJ0cmFjay12YWx1ZVwiXG4gICAgICAgICAgW25nU3R5bGVdPVwie1xuICAgICAgICAgICAgc3Ryb2tlOiBtZWFzdXJlbWVudC5jb2xvcixcbiAgICAgICAgICAgICdzdHJva2UtZGFzaG9mZnNldCc6IC1tZWFzdXJlbWVudC5zdHJva2VEYXNoT2Zmc2V0XG4gICAgICAgICAgfVwiXG4gICAgICAgICAgZD1cIk0gMTA3IDI3IGEgODAgODAgMCAxIDAuMSAwIFpcIlxuICAgICAgICAgIHRyYW5zZm9ybT1cInJvdGF0ZSgtMTM1IDEwNyAxMDcpXCJcbiAgICAgICAgPjwvcGF0aD5cbiAgICAgICAgPGZvcmVpZ25PYmplY3RcbiAgICAgICAgICBjbGFzcz1cImQtZmxleCBhLWktY2VudGVyIGotYy1jZW50ZXJcIlxuICAgICAgICAgIGhlaWdodD1cIjEwMCVcIlxuICAgICAgICAgIHdpZHRoPVwiMTAwJVwiXG4gICAgICAgICAgcmVxdWlyZWRGZWF0dXJlcz1cImh0dHA6Ly93d3cudzMub3JnL1RSL1NWRzExL2ZlYXR1cmUjRXh0ZW5zaWJpbGl0eVwiXG4gICAgICAgID5cbiAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICBjbGFzcz1cImQtZmxleCBkLWNvbCBmaXQtaCBhLWktY2VudGVyIGotYy1jZW50ZXJcIlxuICAgICAgICAgICAgc3R5bGU9XCJwYWRkaW5nOiAzcmVtXCJcbiAgICAgICAgICAgIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHBcbiAgICAgICAgICAgICAgY2xhc3M9XCJ0ZXh0LXRydW5jYXRlIHRleHQtY2VudGVyXCJcbiAgICAgICAgICAgICAgdGl0bGU9XCJ7eyBhY3RpdmVEYXRhcG9pbnRHYXVnZS5sYWJlbCB9fVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIHt7IGFjdGl2ZURhdGFwb2ludEdhdWdlLmxhYmVsIH19XG4gICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICA8cFxuICAgICAgICAgICAgICBjbGFzcz1cImNlbnRlci12YWx1ZSB0ZXh0LXRydW5jYXRlXCJcbiAgICAgICAgICAgICAgdGl0bGU9XCJ7eyBtZWFzdXJlbWVudC52YWx1ZSB8IG51bWJlcjogZnJhY3Rpb25TaXplIH19XCJcbiAgICAgICAgICAgICAgKm5nSWY9XCIhbWVhc3VyZW1lbnQubm90Rm91bmQ7IGVsc2Ugbm90Rm91bmRTVkdcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICB7eyBtZWFzdXJlbWVudC52YWx1ZSB8IG51bWJlcjogZnJhY3Rpb25TaXplIH19XG4gICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgI25vdEZvdW5kU1ZHPlxuICAgICAgICAgICAgICA8cCBjbGFzcz1cImNlbnRlci12YWx1ZVwiPi0tPC9wPlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIDxwIGNsYXNzPVwiY2VudGVyLXVuaXQgc3Ryb25nXCI+e3sgYWN0aXZlRGF0YXBvaW50R2F1Z2UudW5pdCB8fCBtZWFzdXJlbWVudC51bml0IH19PC9wPlxuICAgICAgICAgICAgPHAgY2xhc3M9XCJjZW50ZXItZGF0ZS10aW1lXCI+e3sgbWVhc3VyZW1lbnQuZGF0ZSB8IGM4eURhdGU6ICdzaG9ydCcgfX08L3A+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZm9yZWlnbk9iamVjdD5cbiAgICAgIDwvc3ZnPlxuICAgIDwvZGl2PlxuICA8L25nLWNvbnRhaW5lcj5cbiAgPGRpdiBjbGFzcz1cImNsZWFyZml4XCI+PC9kaXY+XG48L2Rpdj5cbiJdfQ==