@iotize/ionic
Version:
Iotize specific building blocks on top of @ionic/angular.
270 lines • 38.6 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 {
/**
* @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==