@iotize/ionic
Version:
Iotize specific building blocks on top of @ionic/angular.
276 lines • 38.4 kB
JavaScript
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 {
alertController;
id;
lineChart;
/**
* @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;
}
}
_curve = CURVES.Default;
legendTitle = '';
/**
* @deprecated use showLegend instead
*/
legend = true;
/**
* CHARTS OPTIONS
*/
/**
* @deprecated use legend instead
*/
set showLegend(v) {
this.legend = v;
}
legendPosition = LegendPosition.Below;
xAxis = true;
showXAxisLabel = false;
xAxisLabel = '';
yAxis = true;
showYAxisLabel = false;
yAxisLabel = '';
yScaleMin = 0;
showExportButton = false;
exportedFileName;
set history(enable) {
this._history.next(enable);
}
set valueCountLimit(limit) {
if (limit === undefined) {
limit = DEFAULT_VALUE_COUNT_LIMIT;
}
this._valueCountLimit.next(limit);
}
xAxisTickFormatting = this.defaultDateTickFormatting.bind(this);
set label(indexOrArray) {
this.chartModel.initLabel(indexOrArray);
}
colorScheme = {
domain: [
'#5DADE2',
'#9B59B6',
'#F39C12',
'#5AA454',
'#A10A28',
'#C7B42C',
'#AAAAAA',
],
};
_history = new BehaviorSubject(true);
_valueCountLimit = new BehaviorSubject(30);
set variable(variableOrArray) {
this.multiple = !!Array.isArray(variableOrArray);
this.input = this.chartModel.initVariable(variableOrArray);
}
_input = new BehaviorSubject([]);
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;
}
}
}
destroyed = new Subject();
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;
});
}
});
}
results = [
{
name: 'Value',
series: [],
},
];
subscription;
multiple;
chartModel = new ChartDataModel();
constructor(myChartElement, zone, cd, platformId, alertController) {
super(myChartElement, zone, cd, platformId);
this.alertController = alertController;
}
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 */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", 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 */ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", 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: "18.2.14", 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: () => [{ 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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QUFLO2dCQU9OLE1BQU07c0JBREwsS0FBSztnQkFVRixVQUFVO3NCQURiLEtBQUs7Z0JBTU4sY0FBYztzQkFEYixLQUFLO2dCQUlOLEtBQUs7c0JBREosS0FBSztnQkFJTixjQUFjO3NCQURiLEtBQUs7Z0JBSU4sVUFBVTtzQkFEVCxLQUFLO2dCQUlOLEtBQUs7c0JBREosS0FBSztnQkFJTixjQUFjO3NCQURiLEtBQUs7Z0JBSU4sVUFBVTtzQkFEVCxLQUFLO2dCQUlOLFNBQVM7c0JBRFIsS0FBSztnQkFJTixnQkFBZ0I7c0JBRGYsS0FBSztnQkFJTixnQkFBZ0I7c0JBRGYsS0FBSztnQkFJRixPQUFPO3NCQURWLEtBQUs7Z0JBTUYsZUFBZTtzQkFEbEIsS0FBSztnQkFRRyxtQkFBbUI7c0JBQTNCLEtBQUs7Z0JBSUYsS0FBSztzQkFEUixLQUFLO2dCQU1OLFdBQVc7c0JBRFYsS0FBSztnQkFrQkYsUUFBUTtzQkFEWCxLQUFLO2dCQWNGLEtBQUs7c0JBRFIsS0FBSztnQkFLTyxJQUFJO3NCQUFoQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgSW5qZWN0LFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgUExBVEZPUk1fSUQsXG4gIFZpZXdDaGlsZCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBbGVydENvbnRyb2xsZXIgfSBmcm9tICdAaW9uaWMvYW5ndWxhcic7XG5pbXBvcnQgeyBBYnN0cmFjdFZhcmlhYmxlIH0gZnJvbSAnQGlvdGl6ZS90YXAvZGF0YSc7XG5pbXBvcnQgeyBMZWdlbmRQb3NpdGlvbiwgTGluZUNoYXJ0Q29tcG9uZW50IH0gZnJvbSAnQHN3aW1sYW5lL25neC1jaGFydHMnO1xuaW1wb3J0ICogYXMgc2hhcGUgZnJvbSAnZDMtc2hhcGUnO1xuaW1wb3J0IHtcbiAgQmVoYXZpb3JTdWJqZWN0LFxuICBPYnNlcnZhYmxlLFxuICBTdWJqZWN0LFxuICBTdWJzY3JpcHRpb24sXG4gIGNvbWJpbmVMYXRlc3QsXG59IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHtcbiAgQXBwR2VuRmllbGQsXG4gIE1vbml0b3JpbmdBcHBHZW5Db21wb25lbnQsXG59IGZyb20gJy4uLy4uL21ldGFkYXRhL2RlY29yYXRvcnMnO1xuaW1wb3J0IHtcbiAgQ2hhcnREYXRhTW9kZWwsXG4gIENoYXJ0SW5wdXRNdXRsaSxcbiAgQ2hhcnRJbnB1dFN0cmVhbVZhcixcbn0gZnJvbSAnLi4vQ2hhcnREYXRhTW9kZWwnO1xuaW1wb3J0IHsgZGF0YVdpdGhTZXJpZXNUb0NzdiB9IGZyb20gJy4uL0V4cG9ydERhdGFGb3JtYXQnO1xuaW1wb3J0IHtcbiAgQ09MT1JfU0NIRU1FX1NDSEVNQSxcbiAgRVhQT1JUX0RBVEFfRklMRV9OQU1FX1NDSEVNQSxcbiAgTEVHRU5EX1BPU0lUSU9OX1NDSEVNQSxcbiAgTEVHRU5EX1RJVExFX1NDSEVNQSxcbiAgU0hPV19FWFBPUlRfREFUQV9CVVRUT05fU0NIRU1BLFxuICBTSE9XX0xFR0VORF9TQ0hFTUEsXG4gIFNIT1dfWF9BWElTX0xBQkVMX1NDSEVNQSxcbiAgU0hPV19YX0FYSVNfU0NIRU1BLFxuICBTSE9XX1lfQVhJU19MQUJFTF9TQ0hFTUEsXG4gIFNIT1dfWV9BWElTX1NDSEVNQSxcbiAgVEFQX1ZBUklBQkxFX1NDSEVNQSxcbiAgWF9BWElTX0xBQkVMX1NDSEVNQSxcbiAgWV9BWElTX0xBQkVMX1NDSEVNQSxcbiAgWV9TQ0FMRV9NQVhfU0NIRU1BLFxuICBZX1NDQUxFX01JTl9TQ0hFTUEsXG59IGZyb20gJy4uL3NoYXJlZC1zY2hlbWEnO1xuaW1wb3J0IHsgT25DaGFydFNlbGVjdEV2ZW50IH0gZnJvbSAnLi4vc2hhcmVkLXR5cGVzJztcblxuY29uc3QgQ1VSVkVTID0ge1xuICBCYXNpczogc2hhcGUuY3VydmVCYXNpcyxcbiAgQmFzaXNDbG9zZWQ6IHNoYXBlLmN1cnZlQmFzaXNDbG9zZWQsXG4gIEJ1bmRsZTogc2hhcGUuY3VydmVCdW5kbGUuYmV0YSgxKSxcbiAgQ2FyZGluYWw6IHNoYXBlLmN1cnZlQ2FyZGluYWwsXG4gIENhcmRpbmFsQ2xvc2VkOiBzaGFwZS5jdXJ2ZUNhcmRpbmFsQ2xvc2VkLFxuICBDYXRtdWxsUm9tOiBzaGFwZS5jdXJ2ZUNhdG11bGxSb20sXG4gIENhdG11bGxSb21DbG9zZWQ6IHNoYXBlLmN1cnZlQ2F0bXVsbFJvbUNsb3NlZCxcbiAgTGluZWFyOiBzaGFwZS5jdXJ2ZUxpbmVhcixcbiAgTGluZWFyX0Nsb3NlZDogc2hhcGUuY3VydmVMaW5lYXJDbG9zZWQsXG4gIE1vbm90b25lWDogc2hhcGUuY3VydmVNb25vdG9uZVgsXG4gIE1vbm90b25lWTogc2hhcGUuY3VydmVNb25vdG9uZVksXG4gIE5hdHVyYWw6IHNoYXBlLmN1cnZlTmF0dXJhbCxcbiAgU3RlcDogc2hhcGUuY3VydmVTdGVwLFxuICBTdGVwX0FmdGVyOiBzaGFwZS5jdXJ2ZVN0ZXBBZnRlcixcbiAgU3RlcF9CZWZvcmU6IHNoYXBlLmN1cnZlU3RlcEJlZm9yZSxcbiAgRGVmYXVsdDogc2hhcGUuY3VydmVMaW5lYXIsXG59O1xuaW50ZXJmYWNlIFNlcmllSXRlbSB7XG4gIG5hbWU6IHN0cmluZyB8IERhdGU7XG4gIHZhbHVlOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2hhcnRJbnB1dERhdGEge1xuICBuYW1lOiBzdHJpbmc7XG4gIHNlcmllcz86IFNlcmllSXRlbVtdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENoYXJ0SW5wdXRTdHJlYW0ge1xuICBzdHJlYW06IE9ic2VydmFibGU8bnVtYmVyPjtcbiAgbGFiZWw6IHN0cmluZztcbn1cblxuY29uc3QgREVGQVVMVF9WQUxVRV9DT1VOVF9MSU1JVCA9IDMwO1xuXG5ATW9uaXRvcmluZ0FwcEdlbkNvbXBvbmVudCh7XG4gIGNvbnN0cmFpbnRzOiB7XG4gICAgaXNOdW1iZXI6ICdZRVMnLFxuICB9LFxufSlcbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3RhcC12YXJpYWJsZS1saW5lLWNoYXJ0JyxcbiAgdGVtcGxhdGVVcmw6ICcuL3RhcC12YXJpYWJsZS1saW5lLWNoYXJ0LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vdGFwLXZhcmlhYmxlLWxpbmUtY2hhcnQuY29tcG9uZW50LnNjc3MnXSxcbn0pXG5leHBvcnQgY2xhc3MgVGFwVmFyaWFibGVMaW5lQ2hhcnRDb21wb25lbnRcbiAgZXh0ZW5kcyBMaW5lQ2hhcnRDb21wb25lbnRcbiAgaW1wbGVtZW50cyBPbkRlc3Ryb3ksIE9uSW5pdFxue1xuICBpZD86IEtleVR5cGU7XG5cbiAgQFZpZXdDaGlsZChMaW5lQ2hhcnRDb21wb25lbnQpIGxpbmVDaGFydCE6IExpbmVDaGFydENvbXBvbmVudDtcblxuICAvKipcbiAgICogQGRlcHJlY2F0ZWQgdXNlXG4gICAqL1xuICBASW5wdXQoKVxuICBzZXQgbGluZWFyQ3VydmUoY3VydmU6IHN0cmluZykge1xuICAgIHRoaXMucHJlZGVmaW5lZEN1cnZlID0gY3VydmU7XG4gIH1cblxuICBASW5wdXQoKSBzZXQgcHJlZGVmaW5lZEN1cnZlKGN1cnZlRmN0T3JJZDogc3RyaW5nKSB7XG4gICAgaWYgKE9iamVjdC5rZXlzKENVUlZFUykuaW5jbHVkZXMoY3VydmVGY3RPcklkKSkge1xuICAgICAgdGhpcy5fY3VydmUgPSBDVVJWRVNbY3VydmVGY3RPcklkIGFzIGtleW9mIHR5cGVvZiBDVVJWRVNdO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9jdXJ2ZSA9IENVUlZFUy5EZWZhdWx0O1xuICAgIH1cbiAgfVxuXG4gIF9jdXJ2ZTogc2hhcGUuQ3VydmVGYWN0b3J5IHwgc2hhcGUuQ3VydmVCdW5kbGVGYWN0b3J5ID0gQ1VSVkVTLkRlZmF1bHQ7XG5cbiAgQElucHV0KClcbiAgbGVnZW5kVGl0bGU6IHN0cmluZyA9ICcnO1xuXG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCB1c2Ugc2hvd0xlZ2VuZCBpbnN0ZWFkXG4gICAqL1xuICBASW5wdXQoKVxuICBsZWdlbmQ6IGJvb2xlYW4gPSB0cnVlO1xuXG4gIC8qKlxuICAgKiBDSEFSVFMgT1BUSU9OU1xuICAgKi9cbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIHVzZSBsZWdlbmQgaW5zdGVhZFxuICAgKi9cbiAgQElucHV0KClcbiAgc2V0IHNob3dMZWdlbmQodjogYm9vbGVhbikge1xuICAgIHRoaXMubGVnZW5kID0gdjtcbiAgfVxuXG4gIEBJbnB1dCgpXG4gIGxlZ2VuZFBvc2l0aW9uOiBMZWdlbmRQb3NpdGlvbiA9IExlZ2VuZFBvc2l0aW9uLkJlbG93O1xuXG4gIEBJbnB1dCgpXG4gIHhBeGlzOiBib29sZWFuID0gdHJ1ZTtcblxuICBASW5wdXQoKVxuICBzaG93WEF4aXNMYWJlbDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIEBJbnB1dCgpXG4gIHhBeGlzTGFiZWwgPSAnJztcblxuICBASW5wdXQoKVxuICB5QXhpczogYm9vbGVhbiA9IHRydWU7XG5cbiAgQElucHV0KClcbiAgc2hvd1lBeGlzTGFiZWw6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBASW5wdXQoKVxuICB5QXhpc0xhYmVsID0gJyc7XG5cbiAgQElucHV0KClcbiAgeVNjYWxlTWluOiBudW1iZXIgPSAwO1xuXG4gIEBJbnB1dCgpXG4gIHNob3dFeHBvcnRCdXR0b246IGJvb2xlYW4gPSBmYWxzZTtcblxuICBASW5wdXQoKVxuICBleHBvcnRlZEZpbGVOYW1lPzogc3RyaW5nO1xuXG4gIEBJbnB1dCgpXG4gIHNldCBoaXN0b3J5KGVuYWJsZTogYm9vbGVhbikge1xuICAgIHRoaXMuX2hpc3RvcnkubmV4dChlbmFibGUpO1xuICB9XG5cbiAgQElucHV0KClcbiAgc2V0IHZhbHVlQ291bnRMaW1pdChsaW1pdDogbnVtYmVyIHwgdW5kZWZpbmVkKSB7XG4gICAgaWYgKGxpbWl0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGxpbWl0ID0gREVGQVVMVF9WQUxVRV9DT1VOVF9MSU1JVDtcbiAgICB9XG4gICAgdGhpcy5fdmFsdWVDb3VudExpbWl0Lm5leHQobGltaXQpO1xuICB9XG5cbiAgQElucHV0KCkgeEF4aXNUaWNrRm9ybWF0dGluZzogKGlucHV0OiBhbnkpID0+IHN0cmluZyA9XG4gICAgdGhpcy5kZWZhdWx0RGF0ZVRpY2tGb3JtYXR0aW5nLmJpbmQodGhpcyk7XG5cbiAgQElucHV0KClcbiAgc2V0IGxhYmVsKGluZGV4T3JBcnJheTogc3RyaW5nIHwgc3RyaW5nW10gfCB1bmRlZmluZWQgfCBGdW5jdGlvbikge1xuICAgIHRoaXMuY2hhcnRNb2RlbC5pbml0TGFiZWwoaW5kZXhPckFycmF5KTtcbiAgfVxuXG4gIEBJbnB1dCgpXG4gIGNvbG9yU2NoZW1lID0ge1xuICAgIGRvbWFpbjogW1xuICAgICAgJyM1REFERTInLFxuICAgICAgJyM5QjU5QjYnLFxuICAgICAgJyNGMzlDMTInLFxuICAgICAgJyM1QUE0NTQnLFxuICAgICAgJyNBMTBBMjgnLFxuICAgICAgJyNDN0I0MkMnLFxuICAgICAgJyNBQUFBQUEnLFxuICAgIF0sXG4gIH07XG5cbiAgcHJpdmF0ZSBfaGlzdG9yeSA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4odHJ1ZSk7XG5cbiAgcHJpdmF0ZSBfdmFsdWVDb3VudExpbWl0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxudW1iZXI+KDMwKTtcblxuICBASW5wdXQoKVxuICBzZXQgdmFyaWFibGUoXG4gICAgdmFyaWFibGVPckFycmF5OlxuICAgICAgfCBBYnN0cmFjdFZhcmlhYmxlPG51bWJlciB8IG51bWJlcltdPlxuICAgICAgfCBBYnN0cmFjdFZhcmlhYmxlPG51bWJlciB8IG51bWJlcltdPltdXG4gICAgICB8IHVuZGVmaW5lZFxuICApIHtcbiAgICB0aGlzLm11bHRpcGxlID0gISFBcnJheS5pc0FycmF5KHZhcmlhYmxlT3JBcnJheSk7XG4gICAgdGhpcy5pbnB1dCA9IHRoaXMuY2hhcnRNb2RlbC5pbml0VmFyaWFibGUodmFyaWFibGVPckFycmF5KTtcbiAgfVxuXG4gIHByaXZhdGUgX2lucHV0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxDaGFydElucHV0U3RyZWFtVmFyW10+KFtdKTtcblxuICBASW5wdXQoKVxuICBzZXQgaW5wdXQoaW5wdXRzOiBDaGFydElucHV0U3RyZWFtVmFyW10pIHtcbiAgICB0aGlzLl9pbnB1dC5uZXh0KGlucHV0cyk7XG4gIH1cblxuICBASW5wdXQoKSBzZXQgZGF0YShyZXN1bHRzOiBDaGFydElucHV0TXV0bGlbXSB8IG51bWJlciB8IHN0cmluZykge1xuICAgIC8vIFRPRE8gIHwgQ2hhcnRJbnB1dFNpbmdsZVtdXG4gICAgaWYgKHR5cGVvZiByZXN1bHRzID09PSAnbnVtYmVyJyB8fCB0eXBlb2YgcmVzdWx0cyA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGlmICghdGhpcy5yZXN1bHRzPy5bMF0pIHtcbiAgICAgICAgdGhpcy5yZXN1bHRzID0gW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG5hbWU6ICdWYWx1ZScsXG4gICAgICAgICAgICBzZXJpZXM6IFtdLFxuICAgICAgICAgIH0sXG4gICAgICAgIF07XG4gICAgICB9XG4gICAgICB0aGlzLnJlc3VsdHNbMF0uc2VyaWVzLnB1c2goe1xuICAgICAgICBuYW1lOiBuZXcgRGF0ZSgpLFxuICAgICAgICB2YWx1ZTogcmVzdWx0cyxcbiAgICAgICAgZXh0cmE6IHJlc3VsdHMsXG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHJlc3VsdHMpIHtcbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShyZXN1bHRzKSkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSByZXN1bHRzIGFzIENoYXJ0SW5wdXRNdXRsaTtcbiAgICAgICAgY29uc3QgZXhpc3RpbmdTZXJpZUluZGV4ID0gdGhpcy5yZXN1bHRzLmZpbmRJbmRleCgocikgPT4gcmVzdWx0Lm5hbWUpO1xuICAgICAgICBpZiAoZXhpc3RpbmdTZXJpZUluZGV4ID49IDApIHtcbiAgICAgICAgICB0aGlzLnJlc3VsdHNbZXhpc3RpbmdTZXJpZUluZGV4XSA9IHJlc3VsdDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnJlc3VsdHMucHVzaChyZXN1bHQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnJlc3VsdHMgPSByZXN1bHRzO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZGVzdHJveWVkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICBjb21iaW5lTGF0ZXN0KFt0aGlzLl92YWx1ZUNvdW50TGltaXQsIHRoaXMuX2lucHV0LCB0aGlzLl9oaXN0b3J5XSlcbiAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3llZCkpXG4gICAgICAuc3Vic2NyaWJlKChbdmFsdWVDb3VudExpbWl0LCBpbnB1dCwgaGlzdG9yeV0pID0+IHtcbiAgICAgICAgdGhpcy5jaGFydE1vZGVsLmRlc3Ryb3lDdXJyZW50U3ViKCk7XG4gICAgICAgIGlmICh0aGlzLm11bHRpcGxlKSB7XG4gICAgICAgICAgdGhpcy5zdWJzY3JpcHRpb24gPSB0aGlzLmNoYXJ0TW9kZWxcbiAgICAgICAgICAgIC5kZWZpbmVNdWx0aUlucHV0U3RyZWFtKGlucHV0KVxuICAgICAgICAgICAgLnN1YnNjcmliZSgocmVzdWx0KSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMucmVzdWx0cyA9IHJlc3VsdDtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKGhpc3RvcnkgJiYgIXRoaXMubXVsdGlwbGUpIHtcbiAgICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbiA9IHRoaXMuY2hhcnRNb2RlbFxuICAgICAgICAgICAgLmRlZmluZUlucHV0U3RyZWFtSGlzdG9yeU11bHRpTGVnZW5kKGlucHV0LCB2YWx1ZUNvdW50TGltaXQhISlcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoKHJlc3VsdCkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLnJlc3VsdHMgPSByZXN1bHQ7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIGlmICghdGhpcy5tdWx0aXBsZSkge1xuICAgICAgICAgIHRoaXMuc3Vic2NyaXB0aW9uID0gdGhpcy5jaGFydE1vZGVsXG4gICAgICAgICAgICAuZGVmaW5lSW5wdXRTdHJlYW1NdWx0aShpbnB1dCwgZmFsc2UsIHZhbHVlQ291bnRMaW1pdCEhKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgocmVzdWx0KSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMucmVzdWx0cyA9IHJlc3VsdCBhcyBDaGFydElucHV0TXV0bGlbXTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIHJlc3VsdHM6IENoYXJ0SW5wdXRNdXRsaVtdID0gW1xuICAgIHtcbiAgICAgIG5hbWU6ICdWYWx1ZScsXG4gICAgICBzZXJpZXM6IFtdLFxuICAgIH0sXG4gIF07XG5cbiAgcHJpdmF0ZSBzdWJzY3JpcHRpb24/OiBTdWJzY3JpcHRpb247XG5cbiAgcHJpdmF0ZSBtdWx0aXBsZT86IGJvb2xlYW47XG5cbiAgcHJpdmF0ZSBjaGFydE1vZGVsOiBDaGFydERhdGFNb2RlbCA9IG5ldyBDaGFydERhdGFNb2RlbCgpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIG15Q2hhcnRFbGVtZW50OiBFbGVtZW50UmVmLFxuICAgIHpvbmU6IE5nWm9uZSxcbiAgICBjZDogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgQEluamVjdChQTEFURk9STV9JRCkgcGxhdGZvcm1JZDogc3RyaW5nLFxuICAgIHB1YmxpYyBhbGVydENvbnRyb2xsZXI6IEFsZXJ0Q29udHJvbGxlclxuICApIHtcbiAgICBzdXBlcihteUNoYXJ0RWxlbWVudCwgem9uZSwgY2QsIHBsYXRmb3JtSWQpO1xuICB9XG5cbiAgY3JlYXRlRXhwb3J0ZWREYXRhKCkge1xuICAgIHJldHVybiBkYXRhV2l0aFNlcmllc1RvQ3N2KHRoaXMucmVzdWx0cyk7XG4gIH1cblxuICBkZWZhdWx0RGF0ZVRpY2tGb3JtYXR0aW5nKHZhbDogYW55KTogc3RyaW5nIHtcbiAgICBpZiAodmFsIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgcmV0dXJuIHZhbC50b0xvY2FsZVRpbWVTdHJpbmcoKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbDtcbiAgfVxuXG4gIG9uU2VsZWN0KGV2ZW50OiBPbkNoYXJ0U2VsZWN0RXZlbnQpIHtcbiAgICAvKiBOb3QgaW1wbGVtZW50ZWRcbiAgICB0aGlzLmNoYXJ0TW9kZWwuc2hvd0RldGFpbChldmVudCwgdGhpcy5tb2RhbENvbnRyb2xsZXIsIFRhcFZhcmlhYmxlRGF0YVBvcHVwQ29tcG9uZW50KTtcbiAgICAqL1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5jaGFydE1vZGVsLmRlc3Ryb3lDdXJyZW50U3ViKCk7XG4gICAgdGhpcy5kZXN0cm95ZWQubmV4dCgpO1xuICB9XG59XG4iLCI8ZGl2XG4gIHN0eWxlPVwicG9zaXRpb246IHJlbGF0aXZlXCJcbiAgI2NvbnRhaW5lclJlZlxuICBjbGFzcz1cImNoYXJ0LWNvbnRhaW5lclwiXG4gIFtuZ0NsYXNzXT1cIlxuICAgIGxlZ2VuZFBvc2l0aW9uID09PSAnYmVsb3cnICYmIGxlZ2VuZCA/ICdiZWxvd0xlZ2VuZCcgOiAncmlnaHRMZWdlbmQnXG4gIFwiXG4+XG4gIDxuZ3gtY2hhcnRzLWxpbmUtY2hhcnRcbiAgICBbdmlld109XCJbY29udGFpbmVyUmVmLm9mZnNldFdpZHRoLCBjb250YWluZXJSZWYub2Zmc2V0SGVpZ2h0XVwiXG4gICAgW3NjaGVtZV09XCJjb2xvclNjaGVtZVwiXG4gICAgW3Jlc3VsdHNdPVwicmVzdWx0c1wiXG4gICAgW2dyYWRpZW50XT1cImdyYWRpZW50XCJcbiAgICBbbGVnZW5kUG9zaXRpb25dPVwibGVnZW5kUG9zaXRpb25cIlxuICAgIFt4QXhpc109XCJ4QXhpc1wiXG4gICAgW3lBeGlzXT1cInlBeGlzXCJcbiAgICBbbGVnZW5kVGl0bGVdPVwibGVnZW5kVGl0bGVcIlxuICAgIFtsZWdlbmRdPVwibGVnZW5kXCJcbiAgICBbc2hvd1hBeGlzTGFiZWxdPVwic2hvd1hBeGlzTGFiZWxcIlxuICAgIFtzaG93WUF4aXNMYWJlbF09XCJzaG93WUF4aXNMYWJlbFwiXG4gICAgW3RpbWVsaW5lXT1cInRpbWVsaW5lXCJcbiAgICBbeUF4aXNMYWJlbF09XCJ5QXhpc0xhYmVsXCJcbiAgICBbeEF4aXNMYWJlbF09XCJ4QXhpc0xhYmVsXCJcbiAgICBbeEF4aXNUaWNrRm9ybWF0dGluZ109XCJ4QXhpc1RpY2tGb3JtYXR0aW5nXCJcbiAgICBbY3VydmVdPVwiX2N1cnZlXCJcbiAgICBbYXV0b1NjYWxlXT1cImF1dG9TY2FsZVwiXG4gICAgW3hTY2FsZU1pbl09XCJ4U2NhbGVNaW5cIlxuICAgIFt4U2NhbGVNYXhdPVwieFNjYWxlTWF4XCJcbiAgICBbeVNjYWxlTWluXT1cInlTY2FsZU1pblwiXG4gICAgW3lTY2FsZU1heF09XCJ5U2NhbGVNYXhcIlxuICAgIFtzaG93R3JpZExpbmVzXT1cInNob3dHcmlkTGluZXNcIlxuICAgIFthbmltYXRpb25zXT1cImFuaW1hdGlvbnNcIlxuICAgIFt0cmltWEF4aXNUaWNrc109XCJ0cmltWEF4aXNUaWNrc1wiXG4gICAgW21heFhBeGlzVGlja0xlbmd0aF09XCJtYXhYQXhpc1RpY2tMZW5ndGhcIlxuICAgIFt0cmltWUF4aXNUaWNrc109XCJ0cmltWUF4aXNUaWNrc1wiXG4gICAgW21heFlBeGlzVGlja0xlbmd0aF09XCJtYXhZQXhpc1RpY2tMZW5ndGhcIlxuICAgIFtyYW5nZUZpbGxPcGFjaXR5XT1cInJhbmdlRmlsbE9wYWNpdHlcIlxuICAgIFtyb3VuZERvbWFpbnNdPVwicm91bmREb21haW5zXCJcbiAgICBbc2hvd1JlZkxpbmVzXT1cInNob3dSZWZMaW5lc1wiXG4gICAgW3Nob3dSZWZMYWJlbHNdPVwic2hvd1JlZkxhYmVsc1wiXG4gICAgW3JlZmVyZW5jZUxpbmVzXT1cInJlZmVyZW5jZUxpbmVzXCJcbiAgICAoc2VsZWN0KT1cIm9uU2VsZWN0KCRldmVudClcIlxuICA+XG4gIDwvbmd4LWNoYXJ0cy1saW5lLWNoYXJ0PlxuICA8aW9uLWZhYi1idXR0b25cbiAgICBpZD1cImV4cG9ydEZhYkJ1dHRvblwiXG4gICAgc2l6ZT1cInNtYWxsXCJcbiAgICB0YXBFeHBvcnREYXRhXG4gICAgW2RhdGFUb0V4cG9ydF09XCJjcmVhdGVFeHBvcnRlZERhdGEuYmluZCh0aGlzKVwiXG4gICAgW2V4cG9ydGVkRmlsZU5hbWVdPVwiZXhwb3J0ZWRGaWxlTmFtZVwiXG4gICAgKm5nSWY9XCJzaG93RXhwb3J0QnV0dG9uXCJcbiAgPlxuICAgIDxpb24taWNvbiBuYW1lPVwiZG93bmxvYWRcIj48L2lvbi1pY29uPlxuICA8L2lvbi1mYWItYnV0dG9uPlxuPC9kaXY+XG4iXX0=