UNPKG

@iotize/ionic

Version:

Iotize specific building blocks on top of @ionic/angular.

270 lines 38.6 kB
import { __decorate, __metadata } from "tslib"; import { ChangeDetectorRef, Component, ElementRef, Inject, Input, NgZone, PLATFORM_ID, ViewChild, } from '@angular/core'; import { AlertController } from '@ionic/angular'; import { LegendPosition, LineChartComponent } from '@swimlane/ngx-charts'; import * as shape from 'd3-shape'; import { BehaviorSubject, Subject, combineLatest, } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { MonitoringAppGenComponent, } from '../../metadata/decorators'; import { ChartDataModel, } from '../ChartDataModel'; import { dataWithSeriesToCsv } from '../ExportDataFormat'; import * as i0 from "@angular/core"; import * as i1 from "@ionic/angular"; import * as i2 from "@angular/common"; import * as i3 from "@swimlane/ngx-charts"; import * as i4 from "../../ui-directive/export-data.directive"; const CURVES = { Basis: shape.curveBasis, BasisClosed: shape.curveBasisClosed, Bundle: shape.curveBundle.beta(1), Cardinal: shape.curveCardinal, CardinalClosed: shape.curveCardinalClosed, CatmullRom: shape.curveCatmullRom, CatmullRomClosed: shape.curveCatmullRomClosed, Linear: shape.curveLinear, Linear_Closed: shape.curveLinearClosed, MonotoneX: shape.curveMonotoneX, MonotoneY: shape.curveMonotoneY, Natural: shape.curveNatural, Step: shape.curveStep, Step_After: shape.curveStepAfter, Step_Before: shape.curveStepBefore, Default: shape.curveLinear, }; const DEFAULT_VALUE_COUNT_LIMIT = 30; let TapVariableLineChartComponent = class TapVariableLineChartComponent extends LineChartComponent { /** * @deprecated use */ set linearCurve(curve) { this.predefinedCurve = curve; } set predefinedCurve(curveFctOrId) { if (Object.keys(CURVES).includes(curveFctOrId)) { this._curve = CURVES[curveFctOrId]; } else { this._curve = CURVES.Default; } } /** * CHARTS OPTIONS */ /** * @deprecated use legend instead */ set showLegend(v) { this.legend = v; } set history(enable) { this._history.next(enable); } set valueCountLimit(limit) { if (limit === undefined) { limit = DEFAULT_VALUE_COUNT_LIMIT; } this._valueCountLimit.next(limit); } set label(indexOrArray) { this.chartModel.initLabel(indexOrArray); } set variable(variableOrArray) { this.multiple = !!Array.isArray(variableOrArray); this.input = this.chartModel.initVariable(variableOrArray); } set input(inputs) { this._input.next(inputs); } set data(results) { // TODO | ChartInputSingle[] if (typeof results === 'number' || typeof results === 'string') { if (!this.results?.[0]) { this.results = [ { name: 'Value', series: [], }, ]; } this.results[0].series.push({ name: new Date(), value: results, extra: results, }); } else if (results) { if (!Array.isArray(results)) { const result = results; const existingSerieIndex = this.results.findIndex((r) => result.name); if (existingSerieIndex >= 0) { this.results[existingSerieIndex] = result; } else { this.results.push(result); } } else { this.results = results; } } } ngOnInit() { combineLatest([this._valueCountLimit, this._input, this._history]) .pipe(takeUntil(this.destroyed)) .subscribe(([valueCountLimit, input, history]) => { this.chartModel.destroyCurrentSub(); if (this.multiple) { this.subscription = this.chartModel .defineMultiInputStream(input) .subscribe((result) => { this.results = result; }); } else if (history && !this.multiple) { this.subscription = this.chartModel .defineInputStreamHistoryMultiLegend(input, valueCountLimit) .subscribe((result) => { this.results = result; }); } else if (!this.multiple) { this.subscription = this.chartModel .defineInputStreamMulti(input, false, valueCountLimit) .subscribe((result) => { this.results = result; }); } }); } constructor(myChartElement, zone, cd, platformId, alertController) { super(myChartElement, zone, cd, platformId); this.alertController = alertController; this._curve = CURVES.Default; this.legendTitle = ''; /** * @deprecated use showLegend instead */ this.legend = true; this.legendPosition = LegendPosition.Below; this.xAxis = true; this.showXAxisLabel = false; this.xAxisLabel = ''; this.yAxis = true; this.showYAxisLabel = false; this.yAxisLabel = ''; this.yScaleMin = 0; this.showExportButton = false; this.xAxisTickFormatting = this.defaultDateTickFormatting.bind(this); this.colorScheme = { domain: [ '#5DADE2', '#9B59B6', '#F39C12', '#5AA454', '#A10A28', '#C7B42C', '#AAAAAA', ], }; this._history = new BehaviorSubject(true); this._valueCountLimit = new BehaviorSubject(30); this._input = new BehaviorSubject([]); this.destroyed = new Subject(); this.results = [ { name: 'Value', series: [], }, ]; this.chartModel = new ChartDataModel(); } createExportedData() { return dataWithSeriesToCsv(this.results); } defaultDateTickFormatting(val) { if (val instanceof Date) { return val.toLocaleTimeString(); } return val; } onSelect(event) { /* Not implemented this.chartModel.showDetail(event, this.modalController, TapVariableDataPopupComponent); */ } ngOnDestroy() { this.subscription?.unsubscribe(); this.chartModel.destroyCurrentSub(); this.destroyed.next(); } }; /** @nocollapse */ TapVariableLineChartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: TapVariableLineChartComponent, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }, { token: PLATFORM_ID }, { token: i1.AlertController }], target: i0.ɵɵFactoryTarget.Component }); /** @nocollapse */ TapVariableLineChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: TapVariableLineChartComponent, selector: "tap-variable-line-chart", inputs: { linearCurve: "linearCurve", predefinedCurve: "predefinedCurve", legendTitle: "legendTitle", legend: "legend", showLegend: "showLegend", legendPosition: "legendPosition", xAxis: "xAxis", showXAxisLabel: "showXAxisLabel", xAxisLabel: "xAxisLabel", yAxis: "yAxis", showYAxisLabel: "showYAxisLabel", yAxisLabel: "yAxisLabel", yScaleMin: "yScaleMin", showExportButton: "showExportButton", exportedFileName: "exportedFileName", history: "history", valueCountLimit: "valueCountLimit", xAxisTickFormatting: "xAxisTickFormatting", label: "label", colorScheme: "colorScheme", variable: "variable", input: "input", data: "data" }, viewQueries: [{ propertyName: "lineChart", first: true, predicate: LineChartComponent, descendants: true }], usesInheritance: true, ngImport: i0, template: "<div\n style=\"position: relative\"\n #containerRef\n class=\"chart-container\"\n [ngClass]=\"\n legendPosition === 'below' && legend ? 'belowLegend' : 'rightLegend'\n \"\n>\n <ngx-charts-line-chart\n [view]=\"[containerRef.offsetWidth, containerRef.offsetHeight]\"\n [scheme]=\"colorScheme\"\n [results]=\"results\"\n [gradient]=\"gradient\"\n [legendPosition]=\"legendPosition\"\n [xAxis]=\"xAxis\"\n [yAxis]=\"yAxis\"\n [legendTitle]=\"legendTitle\"\n [legend]=\"legend\"\n [showXAxisLabel]=\"showXAxisLabel\"\n [showYAxisLabel]=\"showYAxisLabel\"\n [timeline]=\"timeline\"\n [yAxisLabel]=\"yAxisLabel\"\n [xAxisLabel]=\"xAxisLabel\"\n [xAxisTickFormatting]=\"xAxisTickFormatting\"\n [curve]=\"_curve\"\n [autoScale]=\"autoScale\"\n [xScaleMin]=\"xScaleMin\"\n [xScaleMax]=\"xScaleMax\"\n [yScaleMin]=\"yScaleMin\"\n [yScaleMax]=\"yScaleMax\"\n [showGridLines]=\"showGridLines\"\n [animations]=\"animations\"\n [trimXAxisTicks]=\"trimXAxisTicks\"\n [maxXAxisTickLength]=\"maxXAxisTickLength\"\n [trimYAxisTicks]=\"trimYAxisTicks\"\n [maxYAxisTickLength]=\"maxYAxisTickLength\"\n [rangeFillOpacity]=\"rangeFillOpacity\"\n [roundDomains]=\"roundDomains\"\n [showRefLines]=\"showRefLines\"\n [showRefLabels]=\"showRefLabels\"\n [referenceLines]=\"referenceLines\"\n (select)=\"onSelect($event)\"\n >\n </ngx-charts-line-chart>\n <ion-fab-button\n id=\"exportFabButton\"\n size=\"small\"\n tapExportData\n [dataToExport]=\"createExportedData.bind(this)\"\n [exportedFileName]=\"exportedFileName\"\n *ngIf=\"showExportButton\"\n >\n <ion-icon name=\"download\"></ion-icon>\n </ion-fab-button>\n</div>\n", styles: ["::ng-deep .horizontal-legend{overflow:auto!important}.belowLegend{height:50vh;width:100%;margin-bottom:100px}.rightLegend{height:50vh;width:100%}#exportFabButton{position:absolute;top:10px;right:10px}@media (prefers-color-scheme: dark){::ng-deep span.legend-label-text{color:#ccc!important}::ng-deep span.legend-label-text:hover{color:#fff!important}::ng-deep .ngx-charts text{fill:#fff!important}::ng-deep .ngx-charts .tooltip-anchor{fill:var(--ion-color-primary)!important}}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.LineChartComponent, selector: "ngx-charts-line-chart", inputs: ["legend", "legendTitle", "legendPosition", "xAxis", "yAxis", "showXAxisLabel", "showYAxisLabel", "xAxisLabel", "yAxisLabel", "autoScale", "timeline", "gradient", "showGridLines", "curve", "activeEntries", "schemeType", "rangeFillOpacity", "trimXAxisTicks", "trimYAxisTicks", "rotateXAxisTicks", "maxXAxisTickLength", "maxYAxisTickLength", "xAxisTickFormatting", "yAxisTickFormatting", "xAxisTicks", "yAxisTicks", "roundDomains", "tooltipDisabled", "showRefLines", "referenceLines", "showRefLabels", "xScaleMin", "xScaleMax", "yScaleMin", "yScaleMax", "wrapTicks"], outputs: ["activate", "deactivate"] }, { kind: "component", type: i1.IonFabButton, selector: "ion-fab-button", inputs: ["activated", "closeIcon", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "show", "size", "target", "translucent", "type"] }, { kind: "component", type: i1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "directive", type: i4.ExportDataDirective, selector: "[tapExportData]", inputs: ["exportedFileName", "dataToExport", "format"], outputs: ["exportDataError"] }] }); TapVariableLineChartComponent = __decorate([ MonitoringAppGenComponent({ constraints: { isNumber: 'YES', }, }), __metadata("design:paramtypes", [ElementRef, NgZone, ChangeDetectorRef, String, AlertController]) ], TapVariableLineChartComponent); export { TapVariableLineChartComponent }; i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: TapVariableLineChartComponent, decorators: [{ type: Component, args: [{ selector: 'tap-variable-line-chart', template: "<div\n style=\"position: relative\"\n #containerRef\n class=\"chart-container\"\n [ngClass]=\"\n legendPosition === 'below' && legend ? 'belowLegend' : 'rightLegend'\n \"\n>\n <ngx-charts-line-chart\n [view]=\"[containerRef.offsetWidth, containerRef.offsetHeight]\"\n [scheme]=\"colorScheme\"\n [results]=\"results\"\n [gradient]=\"gradient\"\n [legendPosition]=\"legendPosition\"\n [xAxis]=\"xAxis\"\n [yAxis]=\"yAxis\"\n [legendTitle]=\"legendTitle\"\n [legend]=\"legend\"\n [showXAxisLabel]=\"showXAxisLabel\"\n [showYAxisLabel]=\"showYAxisLabel\"\n [timeline]=\"timeline\"\n [yAxisLabel]=\"yAxisLabel\"\n [xAxisLabel]=\"xAxisLabel\"\n [xAxisTickFormatting]=\"xAxisTickFormatting\"\n [curve]=\"_curve\"\n [autoScale]=\"autoScale\"\n [xScaleMin]=\"xScaleMin\"\n [xScaleMax]=\"xScaleMax\"\n [yScaleMin]=\"yScaleMin\"\n [yScaleMax]=\"yScaleMax\"\n [showGridLines]=\"showGridLines\"\n [animations]=\"animations\"\n [trimXAxisTicks]=\"trimXAxisTicks\"\n [maxXAxisTickLength]=\"maxXAxisTickLength\"\n [trimYAxisTicks]=\"trimYAxisTicks\"\n [maxYAxisTickLength]=\"maxYAxisTickLength\"\n [rangeFillOpacity]=\"rangeFillOpacity\"\n [roundDomains]=\"roundDomains\"\n [showRefLines]=\"showRefLines\"\n [showRefLabels]=\"showRefLabels\"\n [referenceLines]=\"referenceLines\"\n (select)=\"onSelect($event)\"\n >\n </ngx-charts-line-chart>\n <ion-fab-button\n id=\"exportFabButton\"\n size=\"small\"\n tapExportData\n [dataToExport]=\"createExportedData.bind(this)\"\n [exportedFileName]=\"exportedFileName\"\n *ngIf=\"showExportButton\"\n >\n <ion-icon name=\"download\"></ion-icon>\n </ion-fab-button>\n</div>\n", styles: ["::ng-deep .horizontal-legend{overflow:auto!important}.belowLegend{height:50vh;width:100%;margin-bottom:100px}.rightLegend{height:50vh;width:100%}#exportFabButton{position:absolute;top:10px;right:10px}@media (prefers-color-scheme: dark){::ng-deep span.legend-label-text{color:#ccc!important}::ng-deep span.legend-label-text:hover{color:#fff!important}::ng-deep .ngx-charts text{fill:#fff!important}::ng-deep .ngx-charts .tooltip-anchor{fill:var(--ion-color-primary)!important}}\n"] }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{ type: Inject, args: [PLATFORM_ID] }] }, { type: i1.AlertController }]; }, propDecorators: { lineChart: [{ type: ViewChild, args: [LineChartComponent] }], linearCurve: [{ type: Input }], predefinedCurve: [{ type: Input }], legendTitle: [{ type: Input }], legend: [{ type: Input }], showLegend: [{ type: Input }], legendPosition: [{ type: Input }], xAxis: [{ type: Input }], showXAxisLabel: [{ type: Input }], xAxisLabel: [{ type: Input }], yAxis: [{ type: Input }], showYAxisLabel: [{ type: Input }], yAxisLabel: [{ type: Input }], yScaleMin: [{ type: Input }], showExportButton: [{ type: Input }], exportedFileName: [{ type: Input }], history: [{ type: Input }], valueCountLimit: [{ type: Input }], xAxisTickFormatting: [{ type: Input }], label: [{ type: Input }], colorScheme: [{ type: Input }], variable: [{ type: Input }], input: [{ type: Input }], data: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFwLXZhcmlhYmxlLWxpbmUtY2hhcnQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaW90aXplLWlvbmljL21vbml0b3Jpbmcvc3JjL2xpYi91aS1jb21wb25lbnRzL3RhcC12YXJpYWJsZS1saW5lLWNoYXJ0L3RhcC12YXJpYWJsZS1saW5lLWNoYXJ0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2lvdGl6ZS1pb25pYy9tb25pdG9yaW5nL3NyYy9saWIvdWktY29tcG9uZW50cy90YXAtdmFyaWFibGUtbGluZS1jaGFydC90YXAtdmFyaWFibGUtbGluZS1jaGFydC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUNMLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsVUFBVSxFQUNWLE1BQU0sRUFDTixLQUFLLEVBQ0wsTUFBTSxFQUdOLFdBQVcsRUFDWCxTQUFTLEdBQ1YsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRWpELE9BQU8sRUFBRSxjQUFjLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUMxRSxPQUFPLEtBQUssS0FBSyxNQUFNLFVBQVUsQ0FBQztBQUNsQyxPQUFPLEVBQ0wsZUFBZSxFQUVmLE9BQU8sRUFFUCxhQUFhLEdBQ2QsTUFBTSxNQUFNLENBQUM7QUFDZCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDM0MsT0FBTyxFQUVMLHlCQUF5QixHQUMxQixNQUFNLDJCQUEyQixDQUFDO0FBQ25DLE9BQU8sRUFDTCxjQUFjLEdBR2YsTUFBTSxtQkFBbUIsQ0FBQztBQUMzQixPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQzs7Ozs7O0FBb0IxRCxNQUFNLE1B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QUs7Z0JBSU4sU0FBUztzQkFEUixLQUFLO2dCQUlOLGdCQUFnQjtzQkFEZixLQUFLO2dCQUlOLGdCQUFnQjtzQkFEZixLQUFLO2dCQUlGLE9BQU87c0JBRFYsS0FBSztnQkFNRixlQUFlO3NCQURsQixLQUFLO2dCQVFHLG1CQUFtQjtzQkFBM0IsS0FBSztnQkFJRixLQUFLO3NCQURSLEtBQUs7Z0JBTU4sV0FBVztzQkFEVixLQUFLO2dCQWtCRixRQUFRO3NCQURYLEtBQUs7Z0JBY0YsS0FBSztzQkFEUixLQUFLO2dCQUtPLElBQUk7c0JBQWhCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBJbmplY3QsXG4gIElucHV0LFxuICBOZ1pvbmUsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBQTEFURk9STV9JRCxcbiAgVmlld0NoaWxkLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFsZXJ0Q29udHJvbGxlciB9IGZyb20gJ0Bpb25pYy9hbmd1bGFyJztcbmltcG9ydCB7IEFic3RyYWN0VmFyaWFibGUgfSBmcm9tICdAaW90aXplL3RhcC9kYXRhJztcbmltcG9ydCB7IExlZ2VuZFBvc2l0aW9uLCBMaW5lQ2hhcnRDb21wb25lbnQgfSBmcm9tICdAc3dpbWxhbmUvbmd4LWNoYXJ0cyc7XG5pbXBvcnQgKiBhcyBzaGFwZSBmcm9tICdkMy1zaGFwZSc7XG5pbXBvcnQge1xuICBCZWhhdmlvclN1YmplY3QsXG4gIE9ic2VydmFibGUsXG4gIFN1YmplY3QsXG4gIFN1YnNjcmlwdGlvbixcbiAgY29tYmluZUxhdGVzdCxcbn0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQge1xuICBBcHBHZW5GaWVsZCxcbiAgTW9uaXRvcmluZ0FwcEdlbkNvbXBvbmVudCxcbn0gZnJvbSAnLi4vLi4vbWV0YWRhdGEvZGVjb3JhdG9ycyc7XG5pbXBvcnQge1xuICBDaGFydERhdGFNb2RlbCxcbiAgQ2hhcnRJbnB1dE11dGxpLFxuICBDaGFydElucHV0U3RyZWFtVmFyLFxufSBmcm9tICcuLi9DaGFydERhdGFNb2RlbCc7XG5pbXBvcnQgeyBkYXRhV2l0aFNlcmllc1RvQ3N2IH0gZnJvbSAnLi4vRXhwb3J0RGF0YUZvcm1hdCc7XG5pbXBvcnQge1xuICBDT0xPUl9TQ0hFTUVfU0NIRU1BLFxuICBFWFBPUlRfREFUQV9GSUxFX05BTUVfU0NIRU1BLFxuICBMRUdFTkRfUE9TSVRJT05fU0NIRU1BLFxuICBMRUdFTkRfVElUTEVfU0NIRU1BLFxuICBTSE9XX0VYUE9SVF9EQVRBX0JVVFRPTl9TQ0hFTUEsXG4gIFNIT1dfTEVHRU5EX1NDSEVNQSxcbiAgU0hPV19YX0FYSVNfTEFCRUxfU0NIRU1BLFxuICBTSE9XX1hfQVhJU19TQ0hFTUEsXG4gIFNIT1dfWV9BWElTX0xBQkVMX1NDSEVNQSxcbiAgU0hPV19ZX0FYSVNfU0NIRU1BLFxuICBUQVBfVkFSSUFCTEVfU0NIRU1BLFxuICBYX0FYSVNfTEFCRUxfU0NIRU1BLFxuICBZX0FYSVNfTEFCRUxfU0NIRU1BLFxuICBZX1NDQUxFX01BWF9TQ0hFTUEsXG4gIFlfU0NBTEVfTUlOX1NDSEVNQSxcbn0gZnJvbSAnLi4vc2hhcmVkLXNjaGVtYSc7XG5pbXBvcnQgeyBPbkNoYXJ0U2VsZWN0RXZlbnQgfSBmcm9tICcuLi9zaGFyZWQtdHlwZXMnO1xuXG5jb25zdCBDVVJWRVMgPSB7XG4gIEJhc2lzOiBzaGFwZS5jdXJ2ZUJhc2lzLFxuICBCYXNpc0Nsb3NlZDogc2hhcGUuY3VydmVCYXNpc0Nsb3NlZCxcbiAgQnVuZGxlOiBzaGFwZS5jdXJ2ZUJ1bmRsZS5iZXRhKDEpLFxuICBDYXJkaW5hbDogc2hhcGUuY3VydmVDYXJkaW5hbCxcbiAgQ2FyZGluYWxDbG9zZWQ6IHNoYXBlLmN1cnZlQ2FyZGluYWxDbG9zZWQsXG4gIENhdG11bGxSb206IHNoYXBlLmN1cnZlQ2F0bXVsbFJvbSxcbiAgQ2F0bXVsbFJvbUNsb3NlZDogc2hhcGUuY3VydmVDYXRtdWxsUm9tQ2xvc2VkLFxuICBMaW5lYXI6IHNoYXBlLmN1cnZlTGluZWFyLFxuICBMaW5lYXJfQ2xvc2VkOiBzaGFwZS5jdXJ2ZUxpbmVhckNsb3NlZCxcbiAgTW9ub3RvbmVYOiBzaGFwZS5jdXJ2ZU1vbm90b25lWCxcbiAgTW9ub3RvbmVZOiBzaGFwZS5jdXJ2ZU1vbm90b25lWSxcbiAgTmF0dXJhbDogc2hhcGUuY3VydmVOYXR1cmFsLFxuICBTdGVwOiBzaGFwZS5jdXJ2ZVN0ZXAsXG4gIFN0ZXBfQWZ0ZXI6IHNoYXBlLmN1cnZlU3RlcEFmdGVyLFxuICBTdGVwX0JlZm9yZTogc2hhcGUuY3VydmVTdGVwQmVmb3JlLFxuICBEZWZhdWx0OiBzaGFwZS5jdXJ2ZUxpbmVhcixcbn07XG5pbnRlcmZhY2UgU2VyaWVJdGVtIHtcbiAgbmFtZTogc3RyaW5nIHwgRGF0ZTtcbiAgdmFsdWU6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDaGFydElucHV0RGF0YSB7XG4gIG5hbWU6IHN0cmluZztcbiAgc2VyaWVzPzogU2VyaWVJdGVtW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2hhcnRJbnB1dFN0cmVhbSB7XG4gIHN0cmVhbTogT2JzZXJ2YWJsZTxudW1iZXI+O1xuICBsYWJlbDogc3RyaW5nO1xufVxuXG5jb25zdCBERUZBVUxUX1ZBTFVFX0NPVU5UX0xJTUlUID0gMzA7XG5cbkBNb25pdG9yaW5nQXBwR2VuQ29tcG9uZW50KHtcbiAgY29uc3RyYWludHM6IHtcbiAgICBpc051bWJlcjogJ1lFUycsXG4gIH0sXG59KVxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndGFwLXZhcmlhYmxlLWxpbmUtY2hhcnQnLFxuICB0ZW1wbGF0ZVVybDogJy4vdGFwLXZhcmlhYmxlLWxpbmUtY2hhcnQuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi90YXAtdmFyaWFibGUtbGluZS1jaGFydC5jb21wb25lbnQuc2NzcyddLFxufSlcbmV4cG9ydCBjbGFzcyBUYXBWYXJpYWJsZUxpbmVDaGFydENvbXBvbmVudFxuICBleHRlbmRzIExpbmVDaGFydENvbXBvbmVudFxuICBpbXBsZW1lbnRzIE9uRGVzdHJveSwgT25Jbml0XG57XG4gIGlkPzogS2V5VHlwZTtcblxuICBAVmlld0NoaWxkKExpbmVDaGFydENvbXBvbmVudCkgbGluZUNoYXJ0ITogTGluZUNoYXJ0Q29tcG9uZW50O1xuXG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCB1c2VcbiAgICovXG4gIEBJbnB1dCgpXG4gIHNldCBsaW5lYXJDdXJ2ZShjdXJ2ZTogc3RyaW5nKSB7XG4gICAgdGhpcy5wcmVkZWZpbmVkQ3VydmUgPSBjdXJ2ZTtcbiAgfVxuXG4gIEBJbnB1dCgpIHNldCBwcmVkZWZpbmVkQ3VydmUoY3VydmVGY3RPcklkOiBzdHJpbmcpIHtcbiAgICBpZiAoT2JqZWN0LmtleXMoQ1VSVkVTKS5pbmNsdWRlcyhjdXJ2ZUZjdE9ySWQpKSB7XG4gICAgICB0aGlzLl9jdXJ2ZSA9IENVUlZFU1tjdXJ2ZUZjdE9ySWQgYXMga2V5b2YgdHlwZW9mIENVUlZFU107XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX2N1cnZlID0gQ1VSVkVTLkRlZmF1bHQ7XG4gICAgfVxuICB9XG5cbiAgX2N1cnZlOiBzaGFwZS5DdXJ2ZUZhY3RvcnkgfCBzaGFwZS5DdXJ2ZUJ1bmRsZUZhY3RvcnkgPSBDVVJWRVMuRGVmYXVsdDtcblxuICBASW5wdXQoKVxuICBsZWdlbmRUaXRsZTogc3RyaW5nID0gJyc7XG5cbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIHVzZSBzaG93TGVnZW5kIGluc3RlYWRcbiAgICovXG4gIEBJbnB1dCgpXG4gIGxlZ2VuZDogYm9vbGVhbiA9IHRydWU7XG5cbiAgLyoqXG4gICAqIENIQVJUUyBPUFRJT05TXG4gICAqL1xuICAvKipcbiAgICogQGRlcHJlY2F0ZWQgdXNlIGxlZ2VuZCBpbnN0ZWFkXG4gICAqL1xuICBASW5wdXQoKVxuICBzZXQgc2hvd0xlZ2VuZCh2OiBib29sZWFuKSB7XG4gICAgdGhpcy5sZWdlbmQgPSB2O1xuICB9XG5cbiAgQElucHV0KClcbiAgbGVnZW5kUG9zaXRpb246IExlZ2VuZFBvc2l0aW9uID0gTGVnZW5kUG9zaXRpb24uQmVsb3c7XG5cbiAgQElucHV0KClcbiAgeEF4aXM6IGJvb2xlYW4gPSB0cnVlO1xuXG4gIEBJbnB1dCgpXG4gIHNob3dYQXhpc0xhYmVsOiBib29sZWFuID0gZmFsc2U7XG5cbiAgQElucHV0KClcbiAgeEF4aXNMYWJlbCA9ICcnO1xuXG4gIEBJbnB1dCgpXG4gIHlBeGlzOiBib29sZWFuID0gdHJ1ZTtcblxuICBASW5wdXQoKVxuICBzaG93WUF4aXNMYWJlbDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIEBJbnB1dCgpXG4gIHlBeGlzTGFiZWwgPSAnJztcblxuICBASW5wdXQoKVxuICB5U2NhbGVNaW46IG51bWJlciA9IDA7XG5cbiAgQElucHV0KClcbiAgc2hvd0V4cG9ydEJ1dHRvbjogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIEBJbnB1dCgpXG4gIGV4cG9ydGVkRmlsZU5hbWU/OiBzdHJpbmc7XG5cbiAgQElucHV0KClcbiAgc2V0IGhpc3RvcnkoZW5hYmxlOiBib29sZWFuKSB7XG4gICAgdGhpcy5faGlzdG9yeS5uZXh0KGVuYWJsZSk7XG4gIH1cblxuICBASW5wdXQoKVxuICBzZXQgdmFsdWVDb3VudExpbWl0KGxpbWl0OiBudW1iZXIgfCB1bmRlZmluZWQpIHtcbiAgICBpZiAobGltaXQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgbGltaXQgPSBERUZBVUxUX1ZBTFVFX0NPVU5UX0xJTUlUO1xuICAgIH1cbiAgICB0aGlzLl92YWx1ZUNvdW50TGltaXQubmV4dChsaW1pdCk7XG4gIH1cblxuICBASW5wdXQoKSB4QXhpc1RpY2tGb3JtYXR0aW5nOiAoaW5wdXQ6IGFueSkgPT4gc3RyaW5nID1cbiAgICB0aGlzLmRlZmF1bHREYXRlVGlja0Zvcm1hdHRpbmcuYmluZCh0aGlzKTtcblxuICBASW5wdXQoKVxuICBzZXQgbGFiZWwoaW5kZXhPckFycmF5OiBzdHJpbmcgfCBzdHJpbmdbXSB8IHVuZGVmaW5lZCB8IEZ1bmN0aW9uKSB7XG4gICAgdGhpcy5jaGFydE1vZGVsLmluaXRMYWJlbChpbmRleE9yQXJyYXkpO1xuICB9XG5cbiAgQElucHV0KClcbiAgY29sb3JTY2hlbWUgPSB7XG4gICAgZG9tYWluOiBbXG4gICAgICAnIzVEQURFMicsXG4gICAgICAnIzlCNTlCNicsXG4gICAgICAnI0YzOUMxMicsXG4gICAgICAnIzVBQTQ1NCcsXG4gICAgICAnI0ExMEEyOCcsXG4gICAgICAnI0M3QjQyQycsXG4gICAgICAnI0FBQUFBQScsXG4gICAgXSxcbiAgfTtcblxuICBwcml2YXRlIF9oaXN0b3J5ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPih0cnVlKTtcblxuICBwcml2YXRlIF92YWx1ZUNvdW50TGltaXQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PG51bWJlcj4oMzApO1xuXG4gIEBJbnB1dCgpXG4gIHNldCB2YXJpYWJsZShcbiAgICB2YXJpYWJsZU9yQXJyYXk6XG4gICAgICB8IEFic3RyYWN0VmFyaWFibGU8bnVtYmVyIHwgbnVtYmVyW10+XG4gICAgICB8IEFic3RyYWN0VmFyaWFibGU8bnVtYmVyIHwgbnVtYmVyW10+W11cbiAgICAgIHwgdW5kZWZpbmVkXG4gICkge1xuICAgIHRoaXMubXVsdGlwbGUgPSAhIUFycmF5LmlzQXJyYXkodmFyaWFibGVPckFycmF5KTtcbiAgICB0aGlzLmlucHV0ID0gdGhpcy5jaGFydE1vZGVsLmluaXRWYXJpYWJsZSh2YXJpYWJsZU9yQXJyYXkpO1xuICB9XG5cbiAgcHJpdmF0ZSBfaW5wdXQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PENoYXJ0SW5wdXRTdHJlYW1WYXJbXT4oW10pO1xuXG4gIEBJbnB1dCgpXG4gIHNldCBpbnB1dChpbnB1dHM6IENoYXJ0SW5wdXRTdHJlYW1WYXJbXSkge1xuICAgIHRoaXMuX2lucHV0Lm5leHQoaW5wdXRzKTtcbiAgfVxuXG4gIEBJbnB1dCgpIHNldCBkYXRhKHJlc3VsdHM6IENoYXJ0SW5wdXRNdXRsaVtdIHwgbnVtYmVyIHwgc3RyaW5nKSB7XG4gICAgLy8gVE9ETyAgfCBDaGFydElucHV0U2luZ2xlW11cbiAgICBpZiAodHlwZW9mIHJlc3VsdHMgPT09ICdudW1iZXInIHx8IHR5cGVvZiByZXN1bHRzID09PSAnc3RyaW5nJykge1xuICAgICAgaWYgKCF0aGlzLnJlc3VsdHM/LlswXSkge1xuICAgICAgICB0aGlzLnJlc3VsdHMgPSBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgbmFtZTogJ1ZhbHVlJyxcbiAgICAgICAgICAgIHNlcmllczogW10sXG4gICAgICAgICAgfSxcbiAgICAgICAgXTtcbiAgICAgIH1cbiAgICAgIHRoaXMucmVzdWx0c1swXS5zZXJpZXMucHVzaCh7XG4gICAgICAgIG5hbWU6IG5ldyBEYXRlKCksXG4gICAgICAgIHZhbHVlOiByZXN1bHRzLFxuICAgICAgICBleHRyYTogcmVzdWx0cyxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAocmVzdWx0cykge1xuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHJlc3VsdHMpKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHJlc3VsdHMgYXMgQ2hhcnRJbnB1dE11dGxpO1xuICAgICAgICBjb25zdCBleGlzdGluZ1NlcmllSW5kZXggPSB0aGlzLnJlc3VsdHMuZmluZEluZGV4KChyKSA9PiByZXN1bHQubmFtZSk7XG4gICAgICAgIGlmIChleGlzdGluZ1NlcmllSW5kZXggPj0gMCkge1xuICAgICAgICAgIHRoaXMucmVzdWx0c1tleGlzdGluZ1NlcmllSW5kZXhdID0gcmVzdWx0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMucmVzdWx0cy5wdXNoKHJlc3VsdCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucmVzdWx0cyA9IHJlc3VsdHM7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBkZXN0cm95ZWQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIGNvbWJpbmVMYXRlc3QoW3RoaXMuX3ZhbHVlQ291bnRMaW1pdCwgdGhpcy5faW5wdXQsIHRoaXMuX2hpc3RvcnldKVxuICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveWVkKSlcbiAgICAgIC5zdWJzY3JpYmUoKFt2YWx1ZUNvdW50TGltaXQsIGlucHV0LCBoaXN0b3J5XSkgPT4ge1xuICAgICAgICB0aGlzLmNoYXJ0TW9kZWwuZGVzdHJveUN1cnJlbnRTdWIoKTtcbiAgICAgICAgaWYgKHRoaXMubXVsdGlwbGUpIHtcbiAgICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbiA9IHRoaXMuY2hhcnRNb2RlbFxuICAgICAgICAgICAgLmRlZmluZU11bHRpSW5wdXRTdHJlYW0oaW5wdXQpXG4gICAgICAgICAgICAuc3Vic2NyaWJlKChyZXN1bHQpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5yZXN1bHRzID0gcmVzdWx0O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoaGlzdG9yeSAmJiAhdGhpcy5tdWx0aXBsZSkge1xuICAgICAgICAgIHRoaXMuc3Vic2NyaXB0aW9uID0gdGhpcy5jaGFydE1vZGVsXG4gICAgICAgICAgICAuZGVmaW5lSW5wdXRTdHJlYW1IaXN0b3J5TXVsdGlMZWdlbmQoaW5wdXQsIHZhbHVlQ291bnRMaW1pdCEhKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgocmVzdWx0KSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMucmVzdWx0cyA9IHJlc3VsdDtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKCF0aGlzLm11bHRpcGxlKSB7XG4gICAgICAgICAgdGhpcy5zdWJzY3JpcHRpb24gPSB0aGlzLmNoYXJ0TW9kZWxcbiAgICAgICAgICAgIC5kZWZpbmVJbnB1dFN0cmVhbU11bHRpKGlucHV0LCBmYWxzZSwgdmFsdWVDb3VudExpbWl0ISEpXG4gICAgICAgICAgICAuc3Vic2NyaWJlKChyZXN1bHQpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5yZXN1bHRzID0gcmVzdWx0IGFzIENoYXJ0SW5wdXRNdXRsaVtdO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgcmVzdWx0czogQ2hhcnRJbnB1dE11dGxpW10gPSBbXG4gICAge1xuICAgICAgbmFtZTogJ1ZhbHVlJyxcbiAgICAgIHNlcmllczogW10sXG4gICAgfSxcbiAgXTtcblxuICBwcml2YXRlIHN1YnNjcmlwdGlvbj86IFN1YnNjcmlwdGlvbjtcblxuICBwcml2YXRlIG11bHRpcGxlPzogYm9vbGVhbjtcblxuICBwcml2YXRlIGNoYXJ0TW9kZWw6IENoYXJ0RGF0YU1vZGVsID0gbmV3IENoYXJ0RGF0YU1vZGVsKCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgbXlDaGFydEVsZW1lbnQ6IEVsZW1lbnRSZWYsXG4gICAgem9uZTogTmdab25lLFxuICAgIGNkOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBASW5qZWN0KFBMQVRGT1JNX0lEKSBwbGF0Zm9ybUlkOiBzdHJpbmcsXG4gICAgcHVibGljIGFsZXJ0Q29udHJvbGxlcjogQWxlcnRDb250cm9sbGVyXG4gICkge1xuICAgIHN1cGVyKG15Q2hhcnRFbGVtZW50LCB6b25lLCBjZCwgcGxhdGZvcm1JZCk7XG4gIH1cblxuICBjcmVhdGVFeHBvcnRlZERhdGEoKSB7XG4gICAgcmV0dXJuIGRhdGFXaXRoU2VyaWVzVG9Dc3YodGhpcy5yZXN1bHRzKTtcbiAgfVxuXG4gIGRlZmF1bHREYXRlVGlja0Zvcm1hdHRpbmcodmFsOiBhbnkpOiBzdHJpbmcge1xuICAgIGlmICh2YWwgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICByZXR1cm4gdmFsLnRvTG9jYWxlVGltZVN0cmluZygpO1xuICAgIH1cbiAgICByZXR1cm4gdmFsO1xuICB9XG5cbiAgb25TZWxlY3QoZXZlbnQ6IE9uQ2hhcnRTZWxlY3RFdmVudCkge1xuICAgIC8qIE5vdCBpbXBsZW1lbnRlZFxuICAgIHRoaXMuY2hhcnRNb2RlbC5zaG93RGV0YWlsKGV2ZW50LCB0aGlzLm1vZGFsQ29udHJvbGxlciwgVGFwVmFyaWFibGVEYXRhUG9wdXBDb21wb25lbnQpO1xuICAgICovXG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLmNoYXJ0TW9kZWwuZGVzdHJveUN1cnJlbnRTdWIoKTtcbiAgICB0aGlzLmRlc3Ryb3llZC5uZXh0KCk7XG4gIH1cbn1cbiIsIjxkaXZcbiAgc3R5bGU9XCJwb3NpdGlvbjogcmVsYXRpdmVcIlxuICAjY29udGFpbmVyUmVmXG4gIGNsYXNzPVwiY2hhcnQtY29udGFpbmVyXCJcbiAgW25nQ2xhc3NdPVwiXG4gICAgbGVnZW5kUG9zaXRpb24gPT09ICdiZWxvdycgJiYgbGVnZW5kID8gJ2JlbG93TGVnZW5kJyA6ICdyaWdodExlZ2VuZCdcbiAgXCJcbj5cbiAgPG5neC1jaGFydHMtbGluZS1jaGFydFxuICAgIFt2aWV3XT1cIltjb250YWluZXJSZWYub2Zmc2V0V2lkdGgsIGNvbnRhaW5lclJlZi5vZmZzZXRIZWlnaHRdXCJcbiAgICBbc2NoZW1lXT1cImNvbG9yU2NoZW1lXCJcbiAgICBbcmVzdWx0c109XCJyZXN1bHRzXCJcbiAgICBbZ3JhZGllbnRdPVwiZ3JhZGllbnRcIlxuICAgIFtsZWdlbmRQb3NpdGlvbl09XCJsZWdlbmRQb3NpdGlvblwiXG4gICAgW3hBeGlzXT1cInhBeGlzXCJcbiAgICBbeUF4aXNdPVwieUF4aXNcIlxuICAgIFtsZWdlbmRUaXRsZV09XCJsZWdlbmRUaXRsZVwiXG4gICAgW2xlZ2VuZF09XCJsZWdlbmRcIlxuICAgIFtzaG93WEF4aXNMYWJlbF09XCJzaG93WEF4aXNMYWJlbFwiXG4gICAgW3Nob3dZQXhpc0xhYmVsXT1cInNob3dZQXhpc0xhYmVsXCJcbiAgICBbdGltZWxpbmVdPVwidGltZWxpbmVcIlxuICAgIFt5QXhpc0xhYmVsXT1cInlBeGlzTGFiZWxcIlxuICAgIFt4QXhpc0xhYmVsXT1cInhBeGlzTGFiZWxcIlxuICAgIFt4QXhpc1RpY2tGb3JtYXR0aW5nXT1cInhBeGlzVGlja0Zvcm1hdHRpbmdcIlxuICAgIFtjdXJ2ZV09XCJfY3VydmVcIlxuICAgIFthdXRvU2NhbGVdPVwiYXV0b1NjYWxlXCJcbiAgICBbeFNjYWxlTWluXT1cInhTY2FsZU1pblwiXG4gICAgW3hTY2FsZU1heF09XCJ4U2NhbGVNYXhcIlxuICAgIFt5U2NhbGVNaW5dPVwieVNjYWxlTWluXCJcbiAgICBbeVNjYWxlTWF4XT1cInlTY2FsZU1heFwiXG4gICAgW3Nob3dHcmlkTGluZXNdPVwic2hvd0dyaWRMaW5lc1wiXG4gICAgW2FuaW1hdGlvbnNdPVwiYW5pbWF0aW9uc1wiXG4gICAgW3RyaW1YQXhpc1RpY2tzXT1cInRyaW1YQXhpc1RpY2tzXCJcbiAgICBbbWF4WEF4aXNUaWNrTGVuZ3RoXT1cIm1heFhBeGlzVGlja0xlbmd0aFwiXG4gICAgW3RyaW1ZQXhpc1RpY2tzXT1cInRyaW1ZQXhpc1RpY2tzXCJcbiAgICBbbWF4WUF4aXNUaWNrTGVuZ3RoXT1cIm1heFlBeGlzVGlja0xlbmd0aFwiXG4gICAgW3JhbmdlRmlsbE9wYWNpdHldPVwicmFuZ2VGaWxsT3BhY2l0eVwiXG4gICAgW3JvdW5kRG9tYWluc109XCJyb3VuZERvbWFpbnNcIlxuICAgIFtzaG93UmVmTGluZXNdPVwic2hvd1JlZkxpbmVzXCJcbiAgICBbc2hvd1JlZkxhYmVsc109XCJzaG93UmVmTGFiZWxzXCJcbiAgICBbcmVmZXJlbmNlTGluZXNdPVwicmVmZXJlbmNlTGluZXNcIlxuICAgIChzZWxlY3QpPVwib25TZWxlY3QoJGV2ZW50KVwiXG4gID5cbiAgPC9uZ3gtY2hhcnRzLWxpbmUtY2hhcnQ+XG4gIDxpb24tZmFiLWJ1dHRvblxuICAgIGlkPVwiZXhwb3J0RmFiQnV0dG9uXCJcbiAgICBzaXplPVwic21hbGxcIlxuICAgIHRhcEV4cG9ydERhdGFcbiAgICBbZGF0YVRvRXhwb3J0XT1cImNyZWF0ZUV4cG9ydGVkRGF0YS5iaW5kKHRoaXMpXCJcbiAgICBbZXhwb3J0ZWRGaWxlTmFtZV09XCJleHBvcnRlZEZpbGVOYW1lXCJcbiAgICAqbmdJZj1cInNob3dFeHBvcnRCdXR0b25cIlxuICA+XG4gICAgPGlvbi1pY29uIG5hbWU9XCJkb3dubG9hZFwiPjwvaW9uLWljb24+XG4gIDwvaW9uLWZhYi1idXR0b24+XG48L2Rpdj5cbiJdfQ==