UNPKG

@senx/warpview

Version:
263 lines 49.8 kB
/* * Copyright 2021 SenX S.A.S. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ import { Component, ElementRef, Input, NgZone, Renderer2, ViewEncapsulation } from '@angular/core'; import { WarpViewComponent } from '../warp-view-component'; import { ColorLib } from '../../utils/color-lib'; import deepEqual from 'deep-equal'; import { SizeService } from '../../services/resize.service'; import { Logger } from '../../utils/logger'; import { ChartLib } from '../../utils/chart-lib'; import { GTSLib } from '../../utils/gts.lib'; import * as i0 from "@angular/core"; import * as i1 from "../../services/resize.service"; import * as i2 from "../warp-view-spinner/warp-view-spinner.component"; import * as i3 from "../../plotly/plotly.component"; import * as i4 from "@angular/common"; export class WarpViewGaugeComponent extends WarpViewComponent { constructor(el, renderer, sizeService, ngZone) { super(el, renderer, sizeService, ngZone); this.el = el; this.renderer = renderer; this.sizeService = sizeService; this.ngZone = ngZone; this.lineHeight = 80; this.gaugeHeight = 200; // tslint:disable-next-line:variable-name this._type = 'gauge'; // gauge or bullet this.layout = { showlegend: false, autosize: false, autoexpand: false, margin: { t: 10, b: 2, r: 10, l: 10 }, }; this.LOG = new Logger(WarpViewGaugeComponent, this._debug); } set type(type) { this._type = type; this.drawChart(); } ngOnInit() { this._options = this._options || this.defOptions; } update(options, refresh) { this.LOG.debug(['onOptions', 'before'], this._options, options); if (!deepEqual(options, this._options)) { this.LOG.debug(['options', 'changed'], options); this._options = ChartLib.mergeDeep(this._options, options); } this.drawChart(); } drawChart() { if (!this.initChart(this.el)) { return; } this._autoResize = this._type !== 'bullet'; this.LOG.debug(['drawChart', 'plotlyData'], this.plotlyData, this._type); // this.layout.autosize = true; this.layout.grid = { rows: Math.ceil(this.plotlyData.length / 2), columns: 2, pattern: 'independent', xgap: 0, ygap: 0 }; this.layout.margin = { t: 25, r: 25, l: 25, b: 25 }; this.loading = false; } convert(data) { this.LOG.debug(['convert'], data); let gtsList = data.data; const dataList = []; let overallMax = this._options.maxValue || Number.MIN_VALUE; this.LOG.debug(['convert', 'gtsList'], gtsList); if (!gtsList || gtsList.length === 0) { return; } gtsList = GTSLib.flatDeep(gtsList); const dataStruct = []; if (GTSLib.isGts(gtsList[0])) { gtsList.forEach((gts, i) => { let max = Number.MIN_VALUE; const values = (gts.v || []); const val = values[values.length - 1] || []; let value = 0; if (val.length > 0) { value = val[val.length - 1]; } if (!!data.params && !!data.params[i] && !!data.params[i].maxValue) { max = data.params[i].maxValue; } else { if (overallMax < value) { overallMax = value; } } dataStruct.push({ key: GTSLib.serializeGtsMetadata(gts), value, max }); }); } else { // custom data format gtsList.forEach((gts, i) => { let max = Number.MIN_VALUE; if (!!data.params && !!data.params[i] && !!data.params[i].maxValue) { max = data.params[i].maxValue; } else { if (overallMax < gts.value || Number.MIN_VALUE) { overallMax = gts.value || Number.MIN_VALUE; } } dataStruct.push({ key: gts.key || '', value: gts.value || Number.MIN_VALUE, max }); }); } // dataStruct.reverse(); this.LOG.debug(['convert', 'dataStruct'], dataStruct); this.layout.annotations = []; let count = Math.ceil(dataStruct.length / 2); this.layout.autosize = true; this.layout.grid = { rows: count, columns: 1, pattern: 'independent', ygap: 0 }; let labelSize = 0.05; if (this._type === 'bullet') { this.layout.height = 100; this.layout.yaxis = { automargin: false }; count = dataStruct.length; this.layout.autosize = false; let calculatedHeight = this.lineHeight * count + this.layout.margin.t + this.layout.margin.b; calculatedHeight += this.layout.grid.ygap * count; this.el.nativeElement.style.height = calculatedHeight + 'px'; this.el.nativeElement.style.height = calculatedHeight + 'px'; this.height = calculatedHeight; this.layout.height = this.height; labelSize = 20.0 / (this.layout.height - (this.layout.margin.t + this.layout.margin.b)); } const itemHeight = 1 / count; let x = 0; let y = 1 + itemHeight; dataStruct.forEach((gts, i) => { if (this._type === 'bullet') { y -= itemHeight; } else { if (i % 2 === 0) { y -= itemHeight; x = 0; } else { x = 0.5; } } const c = ColorLib.getColor(i, this._options.scheme); const color = ((data.params || [])[i] || { datasetColor: c }).datasetColor || c; const domain = dataStruct.length > 1 ? { x: [x + labelSize, x + 0.5 - labelSize], y: [y - itemHeight + labelSize * 2, y - labelSize * 2] } : { x: [0, 1], y: [0, 1] }; if (this._type === 'bullet') { domain.x = [0, 1]; domain.y = [y - itemHeight + labelSize, y - labelSize * 2]; this.layout.annotations.push({ xref: 'x domain', yref: 'y domain', x: 0, xanchor: 'left', y: y - labelSize / 2, yanchor: 'top', text: gts.key, showarrow: false, align: 'left', font: { size: 14, color: this.getLabelColor(this.el.nativeElement) } }); } dataList.push({ domain, align: 'left', value: gts.value, delta: { reference: !!data.params && !!data.params[i] && !!data.params[i].delta ? data.params[i].delta + gts.value : 0, font: { color: this.getLabelColor(this.el.nativeElement) } }, title: { text: this._type === 'bullet' || (!!data.params && !!data.params[i] && !!data.params[i].type && data.params[i].type === 'bullet') ? '' : gts.key, align: 'center', font: { color: this.getLabelColor(this.el.nativeElement) } }, number: { font: { color: this.getLabelColor(this.el.nativeElement) } }, type: 'indicator', mode: !!data.params && !!data.params[i] && !!data.params[i].delta ? 'number+delta+gauge' : 'gauge+number', gauge: { bgcolor: 'transparent', shape: !!data.params && !!data.params[i] && !!data.params[i].type ? data.params[i].type : this._type || 'gauge', bordercolor: this.getGridColor(this.el.nativeElement), axis: { range: [null, overallMax === Number.MIN_VALUE ? gts.max : overallMax], tickcolor: this.getGridColor(this.el.nativeElement), tickfont: { color: this.getGridColor(this.el.nativeElement) } }, bar: { color: ColorLib.transparentize(color), thickness: 1, line: { width: 1, color } } } }); this.LOG.debug(['convert', 'dataList'], i); }); this.LOG.debug(['convert', 'dataList'], dataList); return dataList; } resize(layout) { // } } WarpViewGaugeComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: WarpViewGaugeComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i1.SizeService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); WarpViewGaugeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: WarpViewGaugeComponent, selector: "warpview-gauge", inputs: { type: "type" }, usesInheritance: true, ngImport: i0, template: "<!--\n ~ Copyright 2021 SenX S.A.S.\n ~\n ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~ http://www.apache.org/licenses/LICENSE-2.0\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n ~\n -->\n\n<div id=\"chartContainer\">\n <warpview-spinner *ngIf=\"loading\" message=\"Parsing data\"></warpview-spinner>\n <p class=\"noData\" *ngIf=\"noData\">No data to display</p>\n <div *ngIf=\"!loading && !noData\">\n <warpview-plotly #graph *ngIf=\"plotlyData?.length > 0\"\n [data]=\"plotlyData\" [layout]=\"layout\" [config]=\"plotlyConfig\" (afterPlot)=\"afterPlot()\"\n (relayout)=\"relayout($event)\"\n [updateOnLayoutChange]=\"true\" [updateOnDataChange]=\"true\" [debug]=\"debug\"\n [style]=\"{position: 'relative', width: '100%', height: '100%'}\"></warpview-plotly>\n </div>\n</div>\n", styles: ["/*!\n * Copyright 2021 SenX S.A.S.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */:root{--warp-view-chart-width: 100%;--warp-view-chart-height: 100%;--warp-view-datagrid-cell-padding: 5px;--warp-view-map-margin: 0;--warp-view-switch-height: 30px;--warp-view-switch-width: 100px;--warp-view-switch-radius: 18px;--warp-view-plot-chart-height: 100%;--warp-view-slider-pointer-size: 65px;--warp-view-resize-handle-height: 10px;--warp-view-tile-width: 100%;--warp-view-tile-height: 100%;--warp-view-font-color: #000000;--warp-view-bar-color: #dc3545;--warp-view-datagrid-odd-bg-color: #ffffff;--warp-view-datagrid-odd-color: #404040;--warp-view-datagrid-even-bg-color: #c0c0c0;--warp-view-datagrid-even-color: #000000;--warp-view-pagination-border-color: #c0c0c0;--warp-view-pagination-bg-color: #ffffff;--warp-view-pagination-active-bg-color: #4CAF50;--warp-view-pagination-active-color: #ffffff;--warp-view-pagination-active-border-color: #4CAF50;--warp-view-pagination-hover-bg-color: #c0c0c0;--warp-view-pagination-hover-color: #000000;--warp-view-pagination-hover-border-color: #c0c0c0;--warp-view-pagination-disabled-color: #c0c0c0;--warp-view-switch-inset-color: #c0c0c0;--warp-view-switch-inset-checked-color: #00cd00;--warp-view-switch-handle-color: radial-gradient(#ffffff 15%, #c0c0c0 100%);--warp-view-switch-handle-checked-color: radial-gradient(#ffffff 15%, #00cd00 100%);--warp-view-resize-handle-color: #c0c0c0;--warp-view-chart-legend-bg: #ffffff;--warp-view-chart-legend-color: #404040;--gts-classname-font-color: #004eff;--gts-labelname-font-color: #19A979;--gts-attrname-font-color: #ED4A7B;--gts-separator-font-color: #a0a0a0;--gts-labelvalue-font-color: #000000;--gts-attrvalue-font-color: #000000;--gts-stack-font-color: #000000;--gts-tree-expanded-icon: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA7klEQVQ4T82TMW7CQBBF/0g+QOpINEkVCmpaLoBm5COk5QYoaeAY3MDSei2LGu4QKakiBA1tCpTK8kS2sLVe2xSh8XSrnf9m/s4s4c6gO/UYGEBEXlT1bK396bFGIjIJguA7iqJLkVNbYOZXItoQ0QHAzBhz9CCFeAVgCeAjy7Jpmqa/NUBEEgDzktqGuOKKO47j+KsGhGH4lOf5HsDIg5ycyqVYVd+steuGheLAzM9EtPMgW1VdVGWJ6N0YU1gpozVGH+K+gy/uBHR1crXUqNzbQXXhduJ69sd7cxOZ+UFVH5Mk+exb+YGt8n9+5h8up1sReYC0WAAAAABJRU5ErkJggg==);--gts-tree-collapsed-icon: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA0UlEQVQ4T6WTUW7CQAxEPQdozxYb9Qb94Aj9gQSoVCp6lMr21doDZFCQiFCU3YDY//d2PeOFPHnwJC+zAlVdA/jp+/6YmZ+1S0qCPxF5HUAAO3fvSpKS4ENEvm6gfUS0c5JiBma2Ibm/QiQPmbmdSqohquoA7GqSxRaapmkBjBkAeHP336t0UWBmHcnb+VcR4XcJpjDJLjPHkS4tleqZubmNiDHU6gumDQDYuvvh7hpV9V9EXgaA5Ka2jbMjmNk7yZOIfEfE8eFVfuSDLda4JDsD3FNdEckTC0YAAAAASUVORK5CYII=);--warp-view-popup-bg-color: #ffffff;--warp-view-popup-border-color: rgba(0, 0, 0, .2);--warp-view-popup-header-bg-color: #c0c0c0;--warp-view-popup-title-color: #404040;--warp-view-popup-close-color: #404040;--warp-view-popup-body-bg-color: #ffffff;--warp-view-popup-body-color: #000000;--warp-view-annotationtooltip-value-font-color: #004eff;--warp-view-annotationtooltip-font-color: #404040;--warp-view-spinner-color: #ff9900;--warp-view-tooltip-bg: #ffffff;--warp-view-tooltip-color: #000000;--warp-slider-connect-color: #ff9900;--warp-slider-handle-bg-color: #ffffff;--warp-slider-handle-color: #004eff;--warp-slider-handle-shadow: inset 0 0 1px #ffffff, inset 0 1px 7px #c0c0c0, 0 3px 6px -3px #a0a0a0}.noData{width:100%;text-align:center;color:var(--warp-view-chart-legend-color);position:relative}.js-plotly-plot .plotly .cursor-ew-resize{cursor:default!important}:host{display:block;height:100%}:host #chartContainer{height:100%}:host #chartContainer div{height:100%}:host div.chart{width:var(--warp-view-chart-width, 100%);height:var(--warp-view-chart-height, 100%)}\n"], components: [{ type: i2.WarpViewSpinnerComponent, selector: "warpview-spinner", inputs: ["message"] }, { type: i3.PlotlyComponent, selector: "warpview-plotly", inputs: ["data", "layout", "config", "debug", "frames", "style", "divId", "revision", "className", "useResizeHandler", "updateOnLayoutChange", "updateOnDataChange", "updateOnlyWithRevision"], outputs: ["initialized", "update", "purge", "error", "afterExport", "afterPlot", "animated", "animatingFrame", "animationInterrupted", "autoSize", "beforeExport", "buttonClicked", "click", "plotly_click", "clickAnnotation", "deselect", "doubleClick", "framework", "hover", "legendClick", "legendDoubleClick", "relayout", "restyle", "redraw", "selected", "selecting", "sliderChange", "sliderEnd", "sliderStart", "transitioning", "transitionInterrupted", "unhover", "relayouting"] }], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], encapsulation: i0.ViewEncapsulation.ShadowDom }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: WarpViewGaugeComponent, decorators: [{ type: Component, args: [{ selector: 'warpview-gauge', encapsulation: ViewEncapsulation.ShadowDom, template: "<!--\n ~ Copyright 2021 SenX S.A.S.\n ~\n ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~ http://www.apache.org/licenses/LICENSE-2.0\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n ~\n -->\n\n<div id=\"chartContainer\">\n <warpview-spinner *ngIf=\"loading\" message=\"Parsing data\"></warpview-spinner>\n <p class=\"noData\" *ngIf=\"noData\">No data to display</p>\n <div *ngIf=\"!loading && !noData\">\n <warpview-plotly #graph *ngIf=\"plotlyData?.length > 0\"\n [data]=\"plotlyData\" [layout]=\"layout\" [config]=\"plotlyConfig\" (afterPlot)=\"afterPlot()\"\n (relayout)=\"relayout($event)\"\n [updateOnLayoutChange]=\"true\" [updateOnDataChange]=\"true\" [debug]=\"debug\"\n [style]=\"{position: 'relative', width: '100%', height: '100%'}\"></warpview-plotly>\n </div>\n</div>\n", styles: ["/*!\n * Copyright 2021 SenX S.A.S.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */:root{--warp-view-chart-width: 100%;--warp-view-chart-height: 100%;--warp-view-datagrid-cell-padding: 5px;--warp-view-map-margin: 0;--warp-view-switch-height: 30px;--warp-view-switch-width: 100px;--warp-view-switch-radius: 18px;--warp-view-plot-chart-height: 100%;--warp-view-slider-pointer-size: 65px;--warp-view-resize-handle-height: 10px;--warp-view-tile-width: 100%;--warp-view-tile-height: 100%;--warp-view-font-color: #000000;--warp-view-bar-color: #dc3545;--warp-view-datagrid-odd-bg-color: #ffffff;--warp-view-datagrid-odd-color: #404040;--warp-view-datagrid-even-bg-color: #c0c0c0;--warp-view-datagrid-even-color: #000000;--warp-view-pagination-border-color: #c0c0c0;--warp-view-pagination-bg-color: #ffffff;--warp-view-pagination-active-bg-color: #4CAF50;--warp-view-pagination-active-color: #ffffff;--warp-view-pagination-active-border-color: #4CAF50;--warp-view-pagination-hover-bg-color: #c0c0c0;--warp-view-pagination-hover-color: #000000;--warp-view-pagination-hover-border-color: #c0c0c0;--warp-view-pagination-disabled-color: #c0c0c0;--warp-view-switch-inset-color: #c0c0c0;--warp-view-switch-inset-checked-color: #00cd00;--warp-view-switch-handle-color: radial-gradient(#ffffff 15%, #c0c0c0 100%);--warp-view-switch-handle-checked-color: radial-gradient(#ffffff 15%, #00cd00 100%);--warp-view-resize-handle-color: #c0c0c0;--warp-view-chart-legend-bg: #ffffff;--warp-view-chart-legend-color: #404040;--gts-classname-font-color: #004eff;--gts-labelname-font-color: #19A979;--gts-attrname-font-color: #ED4A7B;--gts-separator-font-color: #a0a0a0;--gts-labelvalue-font-color: #000000;--gts-attrvalue-font-color: #000000;--gts-stack-font-color: #000000;--gts-tree-expanded-icon: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA7klEQVQ4T82TMW7CQBBF/0g+QOpINEkVCmpaLoBm5COk5QYoaeAY3MDSei2LGu4QKakiBA1tCpTK8kS2sLVe2xSh8XSrnf9m/s4s4c6gO/UYGEBEXlT1bK396bFGIjIJguA7iqJLkVNbYOZXItoQ0QHAzBhz9CCFeAVgCeAjy7Jpmqa/NUBEEgDzktqGuOKKO47j+KsGhGH4lOf5HsDIg5ycyqVYVd+steuGheLAzM9EtPMgW1VdVGWJ6N0YU1gpozVGH+K+gy/uBHR1crXUqNzbQXXhduJ69sd7cxOZ+UFVH5Mk+exb+YGt8n9+5h8up1sReYC0WAAAAABJRU5ErkJggg==);--gts-tree-collapsed-icon: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA0UlEQVQ4T6WTUW7CQAxEPQdozxYb9Qb94Aj9gQSoVCp6lMr21doDZFCQiFCU3YDY//d2PeOFPHnwJC+zAlVdA/jp+/6YmZ+1S0qCPxF5HUAAO3fvSpKS4ENEvm6gfUS0c5JiBma2Ibm/QiQPmbmdSqohquoA7GqSxRaapmkBjBkAeHP336t0UWBmHcnb+VcR4XcJpjDJLjPHkS4tleqZubmNiDHU6gumDQDYuvvh7hpV9V9EXgaA5Ka2jbMjmNk7yZOIfEfE8eFVfuSDLda4JDsD3FNdEckTC0YAAAAASUVORK5CYII=);--warp-view-popup-bg-color: #ffffff;--warp-view-popup-border-color: rgba(0, 0, 0, .2);--warp-view-popup-header-bg-color: #c0c0c0;--warp-view-popup-title-color: #404040;--warp-view-popup-close-color: #404040;--warp-view-popup-body-bg-color: #ffffff;--warp-view-popup-body-color: #000000;--warp-view-annotationtooltip-value-font-color: #004eff;--warp-view-annotationtooltip-font-color: #404040;--warp-view-spinner-color: #ff9900;--warp-view-tooltip-bg: #ffffff;--warp-view-tooltip-color: #000000;--warp-slider-connect-color: #ff9900;--warp-slider-handle-bg-color: #ffffff;--warp-slider-handle-color: #004eff;--warp-slider-handle-shadow: inset 0 0 1px #ffffff, inset 0 1px 7px #c0c0c0, 0 3px 6px -3px #a0a0a0}.noData{width:100%;text-align:center;color:var(--warp-view-chart-legend-color);position:relative}.js-plotly-plot .plotly .cursor-ew-resize{cursor:default!important}:host{display:block;height:100%}:host #chartContainer{height:100%}:host #chartContainer div{height:100%}:host div.chart{width:var(--warp-view-chart-width, 100%);height:var(--warp-view-chart-height, 100%)}\n"] }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i1.SizeService }, { type: i0.NgZone }]; }, propDecorators: { type: [{ type: Input, args: ['type'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FycC12aWV3LWdhdWdlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3dhcnB2aWV3LW5nL3NyYy9saWIvZWxlbWVudHMvd2FycC12aWV3LWdhdWdlL3dhcnAtdmlldy1nYXVnZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy93YXJwdmlldy1uZy9zcmMvbGliL2VsZW1lbnRzL3dhcnAtdmlldy1nYXVnZS93YXJwLXZpZXctZ2F1Z2UuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBRUgsT0FBTyxFQUFDLFNBQVMsRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBVSxTQUFTLEVBQUUsaUJBQWlCLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDekcsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0sd0JBQXdCLENBQUM7QUFFekQsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLHVCQUF1QixDQUFDO0FBQy9DLE9BQU8sU0FBUyxNQUFNLFlBQVksQ0FBQztBQUNuQyxPQUFPLEVBQUMsV0FBVyxFQUFDLE1BQU0sK0JBQStCLENBQUM7QUFDMUQsT0FBTyxFQUFDLE1BQU0sRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBQzFDLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQUUvQyxPQUFPLEVBQUMsTUFBTSxFQUFDLE1BQU0scUJBQXFCLENBQUM7Ozs7OztBQVMzQyxNQUFNLE9BQU8sc0JBQXVCLFNBQVEsaUJBQWlCO0lBcUIzRCxZQUNTLEVBQWMsRUFDZCxRQUFtQixFQUNuQixXQUF3QixFQUN4QixNQUFjO1FBRXJCLEtBQUssQ0FBQyxFQUFFLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUxsQyxPQUFFLEdBQUYsRUFBRSxDQUFZ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QUFDLENBQUMsVUFBVSxDQUFDO3dCQUNyRSxTQUFTLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQzt3QkFDbkQsUUFBUSxFQUFFLEVBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLENBQUMsRUFBQztxQkFDNUQ7b0JBQ0QsR0FBRyxFQUFFO3dCQUNILEtBQUssRUFBRSxRQUFRLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQzt3QkFDckMsU0FBUyxFQUFFLENBQUM7d0JBQ1osSUFBSSxFQUFFOzRCQUNKLEtBQUssRUFBRSxDQUFDOzRCQUNSLEtBQUs7eUJBQ047cUJBQ0Y7aUJBQ0Y7YUFDRixDQUFDLENBQUM7WUFDTCxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLFNBQVMsRUFBRSxVQUFVLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM3QyxDQUFDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsU0FBUyxFQUFFLFVBQVUsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ2xELE9BQU8sUUFBUSxDQUFDO0lBQ2xCLENBQUM7SUFFTSxNQUFNLENBQUMsTUFBc0M7UUFDbEQsRUFBRTtJQUNKLENBQUM7O21IQW5PVSxzQkFBc0I7dUdBQXRCLHNCQUFzQix1R0NuQ25DLDZ5Q0E0QkE7MkZET2Esc0JBQXNCO2tCQU5sQyxTQUFTOytCQUNFLGdCQUFnQixpQkFHWCxpQkFBaUIsQ0FBQyxTQUFTO3dLQUd2QixJQUFJO3NCQUF0QixLQUFLO3VCQUFDLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogIENvcHlyaWdodCAyMDIxICBTZW5YIFMuQS5TLlxuICpcbiAqICBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7Q29tcG9uZW50LCBFbGVtZW50UmVmLCBJbnB1dCwgTmdab25lLCBPbkluaXQsIFJlbmRlcmVyMiwgVmlld0VuY2Fwc3VsYXRpb259IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtXYXJwVmlld0NvbXBvbmVudH0gZnJvbSAnLi4vd2FycC12aWV3LWNvbXBvbmVudCc7XG5pbXBvcnQge0RhdGFNb2RlbH0gZnJvbSAnLi4vLi4vbW9kZWwvZGF0YU1vZGVsJztcbmltcG9ydCB7Q29sb3JMaWJ9IGZyb20gJy4uLy4uL3V0aWxzL2NvbG9yLWxpYic7XG5pbXBvcnQgZGVlcEVxdWFsIGZyb20gJ2RlZXAtZXF1YWwnO1xuaW1wb3J0IHtTaXplU2VydmljZX0gZnJvbSAnLi4vLi4vc2VydmljZXMvcmVzaXplLnNlcnZpY2UnO1xuaW1wb3J0IHtMb2dnZXJ9IGZyb20gJy4uLy4uL3V0aWxzL2xvZ2dlcic7XG5pbXBvcnQge0NoYXJ0TGlifSBmcm9tICcuLi8uLi91dGlscy9jaGFydC1saWInO1xuaW1wb3J0IHtQYXJhbX0gZnJvbSAnLi4vLi4vbW9kZWwvcGFyYW0nO1xuaW1wb3J0IHtHVFNMaWJ9IGZyb20gJy4uLy4uL3V0aWxzL2d0cy5saWInO1xuaW1wb3J0IHtHVFN9IGZyb20gJy4uLy4uL21vZGVsL0dUUyc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3dhcnB2aWV3LWdhdWdlJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3dhcnAtdmlldy1nYXVnZS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3dhcnAtdmlldy1nYXVnZS5jb21wb25lbnQuc2NzcyddLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5TaGFkb3dEb21cbn0pXG5leHBvcnQgY2xhc3MgV2FycFZpZXdHYXVnZUNvbXBvbmVudCBleHRlbmRzIFdhcnBWaWV3Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgQElucHV0KCd0eXBlJykgc2V0IHR5cGUodHlwZTogc3RyaW5nKSB7XG4gICAgdGhpcy5fdHlwZSA9IHR5cGU7XG4gICAgdGhpcy5kcmF3Q2hhcnQoKTtcbiAgfVxuICBwcml2YXRlIGxpbmVIZWlnaHQgPSA4MDtcbiAgcHJpdmF0ZSBnYXVnZUhlaWdodCA9IDIwMDtcbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOnZhcmlhYmxlLW5hbWVcbiAgcHJvdGVjdGVkIF90eXBlID0gJ2dhdWdlJzsgLy8gZ2F1Z2Ugb3IgYnVsbGV0XG4gIGxheW91dDogUGFydGlhbDxhbnk+ID0ge1xuICAgIHNob3dsZWdlbmQ6IGZhbHNlLFxuICAgIGF1dG9zaXplOiBmYWxzZSxcbiAgICBhdXRvZXhwYW5kOiBmYWxzZSxcbiAgICBtYXJnaW46IHtcbiAgICAgIHQ6IDEwLFxuICAgICAgYjogMixcbiAgICAgIHI6IDEwLFxuICAgICAgbDogMTBcbiAgICB9LFxuICB9O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBlbDogRWxlbWVudFJlZixcbiAgICBwdWJsaWMgcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICBwdWJsaWMgc2l6ZVNlcnZpY2U6IFNpemVTZXJ2aWNlLFxuICAgIHB1YmxpYyBuZ1pvbmU6IE5nWm9uZVxuICApIHtcbiAgICBzdXBlcihlbCwgcmVuZGVyZXIsIHNpemVTZXJ2aWNlLCBuZ1pvbmUpO1xuICAgIHRoaXMuTE9HID0gbmV3IExvZ2dlcihXYXJwVmlld0dhdWdlQ29tcG9uZW50LCB0aGlzLl9kZWJ1Zyk7XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLl9vcHRpb25zID0gdGhpcy5fb3B0aW9ucyB8fCB0aGlzLmRlZk9wdGlvbnM7XG4gIH1cblxuICB1cGRhdGUob3B0aW9ucywgcmVmcmVzaCk6IHZvaWQge1xuICAgIHRoaXMuTE9HLmRlYnVnKFsnb25PcHRpb25zJywgJ2JlZm9yZSddLCB0aGlzLl9vcHRpb25zLCBvcHRpb25zKTtcbiAgICBpZiAoIWRlZXBFcXVhbChvcHRpb25zLCB0aGlzLl9vcHRpb25zKSkge1xuICAgICAgdGhpcy5MT0cuZGVidWcoWydvcHRpb25zJywgJ2NoYW5nZWQnXSwgb3B0aW9ucyk7XG4gICAgICB0aGlzLl9vcHRpb25zID0gQ2hhcnRMaWIubWVyZ2VEZWVwKHRoaXMuX29wdGlvbnMsIG9wdGlvbnMgYXMgUGFyYW0pIGFzIFBhcmFtO1xuICAgIH1cbiAgICB0aGlzLmRyYXdDaGFydCgpO1xuICB9XG5cbiAgZHJhd0NoYXJ0KCkge1xuICAgIGlmICghdGhpcy5pbml0Q2hhcnQodGhpcy5lbCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5fYXV0b1Jlc2l6ZSA9IHRoaXMuX3R5cGUgIT09ICdidWxsZXQnO1xuICAgIHRoaXMuTE9HLmRlYnVnKFsnZHJhd0NoYXJ0JywgJ3Bsb3RseURhdGEnXSwgdGhpcy5wbG90bHlEYXRhLCB0aGlzLl90eXBlKTtcbiAgICAvLyB0aGlzLmxheW91dC5hdXRvc2l6ZSA9IHRydWU7XG4gICAgdGhpcy5sYXlvdXQuZ3JpZCA9IHtcbiAgICAgIHJvd3M6IE1hdGguY2VpbCh0aGlzLnBsb3RseURhdGEubGVuZ3RoIC8gMiksXG4gICAgICBjb2x1bW5zOiAyLFxuICAgICAgcGF0dGVybjogJ2luZGVwZW5kZW50JyxcbiAgICAgIHhnYXA6IDAsXG4gICAgICB5Z2FwOiAwXG4gICAgfTtcbiAgICB0aGlzLmxheW91dC5tYXJnaW4gPSB7dDogMjUsIHI6IDI1LCBsOiAyNSwgYjogMjV9O1xuXG4gICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gIH1cblxuICBwcm90ZWN0ZWQgY29udmVydChkYXRhOiBEYXRhTW9kZWwpOiBhbnlbXSB7XG4gICAgdGhpcy5MT0cuZGVidWcoWydjb252ZXJ0J10sIGRhdGEpO1xuICAgIGxldCBndHNMaXN0ID0gZGF0YS5kYXRhIGFzIGFueVtdO1xuICAgIGNvbnN0IGRhdGFMaXN0ID0gW107XG4gICAgbGV0IG92ZXJhbGxNYXggPSB0aGlzLl9vcHRpb25zLm1heFZhbHVlIHx8IE51bWJlci5NSU5fVkFMVUU7XG4gICAgdGhpcy5MT0cuZGVidWcoWydjb252ZXJ0JywgJ2d0c0xpc3QnXSwgZ3RzTGlzdCk7XG4gICAgaWYgKCFndHNMaXN0IHx8IGd0c0xpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGd0c0xpc3QgPSBHVFNMaWIuZmxhdERlZXAoZ3RzTGlzdCk7XG4gICAgY29uc3QgZGF0YVN0cnVjdCA9IFtdO1xuICAgIGlmIChHVFNMaWIuaXNHdHMoZ3RzTGlzdFswXSkpIHtcbiAgICAgIGd0c0xpc3QuZm9yRWFjaCgoZ3RzOiBHVFMsIGkpID0+IHtcbiAgICAgICAgbGV0IG1heDogbnVtYmVyID0gTnVtYmVyLk1JTl9WQUxVRTtcbiAgICAgICAgY29uc3QgdmFsdWVzID0gKGd0cy52IHx8IFtdKTtcbiAgICAgICAgY29uc3QgdmFsID0gdmFsdWVzW3ZhbHVlcy5sZW5ndGggLSAxXSB8fCBbXTtcbiAgICAgICAgbGV0IHZhbHVlID0gMDtcbiAgICAgICAgaWYgKHZhbC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgdmFsdWUgPSB2YWxbdmFsLmxlbmd0aCAtIDFdO1xuICAgICAgICB9XG4gICAgICAgIGlmICghIWRhdGEucGFyYW1zICYmICEhZGF0YS5wYXJhbXNbaV0gJiYgISFkYXRhLnBhcmFtc1tpXS5tYXhWYWx1ZSkge1xuICAgICAgICAgIG1heCA9IGRhdGEucGFyYW1zW2ldLm1heFZhbHVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChvdmVyYWxsTWF4IDwgdmFsdWUpIHtcbiAgICAgICAgICAgIG92ZXJhbGxNYXggPSB2YWx1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZGF0YVN0cnVjdC5wdXNoKHtcbiAgICAgICAgICBrZXk6IEdUU0xpYi5zZXJpYWxpemVHdHNNZXRhZGF0YShndHMpLFxuICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgIG1heFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBjdXN0b20gZGF0YSBmb3JtYXRcbiAgICAgIGd0c0xpc3QuZm9yRWFjaCgoZ3RzLCBpKSA9PiB7XG4gICAgICAgIGxldCBtYXg6IG51bWJlciA9IE51bWJlci5NSU5fVkFMVUU7XG4gICAgICAgIGlmICghIWRhdGEucGFyYW1zICYmICEhZGF0YS5wYXJhbXNbaV0gJiYgISFkYXRhLnBhcmFtc1tpXS5tYXhWYWx1ZSkge1xuICAgICAgICAgIG1heCA9IGRhdGEucGFyYW1zW2ldLm1heFZhbHVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChvdmVyYWxsTWF4IDwgZ3RzLnZhbHVlIHx8IE51bWJlci5NSU5fVkFMVUUpIHtcbiAgICAgICAgICAgIG92ZXJhbGxNYXggPSBndHMudmFsdWUgfHwgTnVtYmVyLk1JTl9WQUxVRTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZGF0YVN0cnVjdC5wdXNoKHtcbiAgICAgICAgICBrZXk6IGd0cy5rZXkgfHwgJycsXG4gICAgICAgICAgdmFsdWU6IGd0cy52YWx1ZSB8fCBOdW1iZXIuTUlOX1ZBTFVFLFxuICAgICAgICAgIG1heFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICAvLyAgZGF0YVN0cnVjdC5yZXZlcnNlKCk7XG4gICAgdGhpcy5MT0cuZGVidWcoWydjb252ZXJ0JywgJ2RhdGFTdHJ1Y3QnXSwgZGF0YVN0cnVjdCk7XG4gICAgdGhpcy5sYXlvdXQuYW5ub3RhdGlvbnMgPSBbXTtcbiAgICBsZXQgY291bnQgPSBNYXRoLmNlaWwoZGF0YVN0cnVjdC5sZW5ndGggLyAyKTtcbiAgICB0aGlzLmxheW91dC5hdXRvc2l6ZSA9IHRydWU7XG5cbiAgICB0aGlzLmxheW91dC5ncmlkID0ge1xuICAgICAgcm93czogY291bnQsIGNvbHVtbnM6IDEsIHBhdHRlcm46ICdpbmRlcGVuZGVudCcsXG4gICAgICB5Z2FwOiAwXG4gICAgfTtcbiAgICBsZXQgbGFiZWxTaXplID0gMC4wNTtcbiAgICBpZiAodGhpcy5fdHlwZSA9PT0gJ2J1bGxldCcpIHtcbiAgICAgIHRoaXMubGF5b3V0LmhlaWdodCA9IDEwMDtcbiAgICAgIHRoaXMubGF5b3V0LnlheGlzID0ge2F1dG9tYXJnaW46IGZhbHNlfTtcbiAgICAgIGNvdW50ID0gZGF0YVN0cnVjdC5sZW5ndGg7XG4gICAgICB0aGlzLmxheW91dC5hdXRvc2l6ZSA9IGZhbHNlO1xuICAgICAgbGV0IGNhbGN1bGF0ZWRIZWlnaHQgPSB0aGlzLmxpbmVIZWlnaHQgKiBjb3VudCArIHRoaXMubGF5b3V0Lm1hcmdpbi50ICsgdGhpcy5sYXlvdXQubWFyZ2luLmI7XG4gICAgICBjYWxjdWxhdGVkSGVpZ2h0ICs9IHRoaXMubGF5b3V0LmdyaWQueWdhcCAqIGNvdW50O1xuICAgICAgdGhpcy5lbC5uYXRpdmVFbGVtZW50LnN0eWxlLmhlaWdodCA9IGNhbGN1bGF0ZWRIZWlnaHQgKyAncHgnO1xuICAgICAgKHRoaXMuZWwubmF0aXZlRWxlbWVudCBhcyBIVE1MRGl2RWxlbWVudCkuc3R5bGUuaGVpZ2h0ID0gY2FsY3VsYXRlZEhlaWdodCArICdweCc7XG4gICAgICB0aGlzLmhlaWdodCA9IGNhbGN1bGF0ZWRIZWlnaHQ7XG4gICAgICB0aGlzLmxheW91dC5oZWlnaHQgPSB0aGlzLmhlaWdodDtcbiAgICAgIGxhYmVsU2l6ZSA9IDIwLjAgLyAodGhpcy5sYXlvdXQuaGVpZ2h0IC0gKHRoaXMubGF5b3V0Lm1hcmdpbi50ICsgdGhpcy5sYXlvdXQubWFyZ2luLmIpKTtcbiAgICB9XG4gICAgY29uc3QgaXRlbUhlaWdodCA9IDEgLyBjb3VudDtcbiAgICBsZXQgeCA9IDA7XG4gICAgbGV0IHkgPSAxICsgaXRlbUhlaWdodDtcbiAgICBkYXRhU3RydWN0LmZvckVhY2goKGd0cywgaSkgPT4ge1xuICAgICAgaWYgKHRoaXMuX3R5cGUgPT09ICdidWxsZXQnKSB7XG4gICAgICAgIHkgLT0gaXRlbUhlaWdodDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChpICUgMiA9PT0gMCkge1xuICAgICAgICAgIHkgLT0gaXRlbUhlaWdodDtcbiAgICAgICAgICB4ID0gMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB4ID0gMC41O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjb25zdCBjID0gQ29sb3JMaWIuZ2V0Q29sb3IoaSwgdGhpcy5fb3B0aW9ucy5zY2hlbWUpO1xuICAgICAgY29uc3QgY29sb3IgPSAoKGRhdGEucGFyYW1zIHx8IFtdKVtpXSB8fCB7ZGF0YXNldENvbG9yOiBjfSkuZGF0YXNldENvbG9yIHx8IGM7XG4gICAgICBjb25zdCBkb21haW4gPSBkYXRhU3RydWN0Lmxlbmd0aCA+IDEgPyB7XG4gICAgICAgIHg6IFt4ICsgbGFiZWxTaXplLCB4ICsgMC41IC0gbGFiZWxTaXplXSxcbiAgICAgICAgeTogW3kgLSBpdGVtSGVpZ2h0ICsgbGFiZWxTaXplICogMiwgeSAtIGxhYmVsU2l6ZSAqIDJdXG4gICAgICB9IDoge1xuICAgICAgICB4OiBbMCwgMV0sXG4gICAgICAgIHk6IFswLCAxXVxuICAgICAgfTtcbiAgICAgIGlmICh0aGlzLl90eXBlID09PSAnYnVsbGV0Jykge1xuICAgICAgICBkb21haW4ueCA9IFswLCAxXTtcbiAgICAgICAgZG9tYWluLnkgPSBbeSAtIGl0ZW1IZWlnaHQgKyBsYWJlbFNpemUsIHkgLSBsYWJlbFNpemUgKiAyXTtcbiAgICAgICAgdGhpcy5sYXlvdXQuYW5ub3RhdGlvbnMucHVzaCh7XG4gICAgICAgICAgeHJlZjogJ3ggZG9tYWluJyxcbiAgICAgICAgICB5cmVmOiAneSBkb21haW4nLFxuICAgICAgICAgIHg6IDAsXG4gICAgICAgICAgeGFuY2hvcjogJ2xlZnQnLFxuICAgICAgICAgIHk6IHkgLSBsYWJlbFNpemUgLyAyLFxuICAgICAgICAgIHlhbmNob3I6ICd0b3AnLFxuICAgICAgICAgIHRleHQ6IGd0cy5rZXksXG4gICAgICAgICAgc2hvd2Fycm93OiBmYWxzZSxcbiAgICAgICAgICBhbGlnbjogJ2xlZnQnLFxuICAgICAgICAgIGZvbnQ6IHtcbiAgICAgICAgICAgIHNpemU6IDE0LFxuICAgICAgICAgICAgY29sb3I6IHRoaXMuZ2V0TGFiZWxDb2xvcih0aGlzLmVsLm5hdGl2ZUVsZW1lbnQpXG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGRhdGFMaXN0LnB1c2goXG4gICAgICAgIHtcbiAgICAgICAgICBkb21haW4sXG4gICAgICAgICAgYWxpZ246ICdsZWZ0JyxcbiAgICAgICAgICB2YWx1ZTogZ3RzLnZhbHVlLFxuICAgICAgICAgIGRlbHRhOiB7XG4gICAgICAgICAgICByZWZlcmVuY2U6ICEhZGF0YS5wYXJhbXMgJiYgISFkYXRhLnBhcmFtc1tpXSAmJiAhIWRhdGEucGFyYW1zW2ldLmRlbHRhID8gZGF0YS5wYXJhbXNbaV0uZGVsdGEgKyBndHMudmFsdWUgOiAwLFxuICAgICAgICAgICAgZm9udDoge2NvbG9yOiB0aGlzLmdldExhYmVsQ29sb3IodGhpcy5lbC5uYXRpdmVFbGVtZW50KX1cbiAgICAgICAgICB9LFxuICAgICAgICAgIHRpdGxlOiB7XG4gICAgICAgICAgICB0ZXh0OiB0aGlzLl90eXBlID09PSAnYnVsbGV0J1xuICAgICAgICAgICAgfHwgKCEhZGF0YS5wYXJhbXMgJiYgISFkYXRhLnBhcmFtc1tpXSAmJiAhIWRhdGEucGFyYW1zW2ldLnR5cGUgJiYgZGF0YS5wYXJhbXNbaV0udHlwZSA9PT0gJ2J1bGxldCcpID8gJycgOiBndHMua2V5LFxuICAgICAgICAgICAgYWxpZ246ICdjZW50ZXInLFxuICAgICAgICAgICAgZm9udDoge2NvbG9yOiB0aGlzLmdldExhYmVsQ29sb3IodGhpcy5lbC5uYXRpdmVFbGVtZW50KX1cbiAgICAgICAgICB9LFxuICAgICAgICAgIG51bWJlcjoge1xuICAgICAgICAgICAgZm9udDoge2NvbG9yOiB0aGlzLmdldExhYmVsQ29sb3IodGhpcy5lbC5uYXRpdmVFbGVtZW50KX1cbiAgICAgICAgICB9LFxuICAgICAgICAgIHR5cGU6ICdpbmRpY2F0b3InLFxuICAgICAgICAgIG1vZGU6ICEhZGF0YS5wYXJhbXMgJiYgISFkYXRhLnBhcmFtc1tpXSAmJiAhIWRhdGEucGFyYW1zW2ldLmRlbHRhID8gJ251bWJlcitkZWx0YStnYXVnZScgOiAnZ2F1Z2UrbnVtYmVyJyxcbiAgICAgICAgICBnYXVnZToge1xuICAgICAgICAgICAgYmdjb2xvcjogJ3RyYW5zcGFyZW50JyxcbiAgICAgICAgICAgIHNoYXBlOiAhIWRhdGEucGFyYW1zICYmICEhZGF0YS5wYXJhbXNbaV0gJiYgISFkYXRhLnBhcmFtc1tpXS50eXBlID8gZGF0YS5wYXJhbXNbaV0udHlwZSA6IHRoaXMuX3R5cGUgfHwgJ2dhdWdlJyxcbiAgICAgICAgICAgIGJvcmRlcmNvbG9yOiB0aGlzLmdldEdyaWRDb2xvcih0aGlzLmVsLm5hdGl2ZUVsZW1lbnQpLFxuICAgICAgICAgICAgYXhpczoge1xuICAgICAgICAgICAgICByYW5nZTogW251bGwsIG92ZXJhbGxNYXggPT09IE51bWJlci5NSU5fVkFMVUUgPyBndHMubWF4IDogb3ZlcmFsbE1heF0sXG4gICAgICAgICAgICAgIHRpY2tjb2xvcjogdGhpcy5nZXRHcmlkQ29sb3IodGhpcy5lbC5uYXRpdmVFbGVtZW50KSxcbiAgICAgICAgICAgICAgdGlja2ZvbnQ6IHtjb2xvcjogdGhpcy5nZXRHcmlkQ29sb3IodGhpcy5lbC5uYXRpdmVFbGVtZW50KX1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBiYXI6IHtcbiAgICAgICAgICAgICAgY29sb3I6IENvbG9yTGliLnRyYW5zcGFyZW50aXplKGNvbG9yKSxcbiAgICAgICAgICAgICAgdGhpY2tuZXNzOiAxLFxuICAgICAgICAgICAgICBsaW5lOiB7XG4gICAgICAgICAgICAgICAgd2lkdGg6IDEsXG4gICAgICAgICAgICAgICAgY29sb3JcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB0aGlzLkxPRy5kZWJ1ZyhbJ2NvbnZlcnQnLCAnZGF0YUxpc3QnXSwgaSk7XG4gICAgfSk7XG4gICAgdGhpcy5MT0cuZGVidWcoWydjb252ZXJ0JywgJ2RhdGFMaXN0J10sIGRhdGFMaXN0KTtcbiAgICByZXR1cm4gZGF0YUxpc3Q7XG4gIH1cblxuICBwdWJsaWMgcmVzaXplKGxheW91dDogeyB3aWR0aDogbnVtYmVyOyBoZWlnaHQ6IGFueSB9KSB7XG4gICAgLy9cbiAgfVxufVxuIiwiPCEtLVxuICB+ICBDb3B5cmlnaHQgMjAyMSAgU2VuWCBTLkEuUy5cbiAgflxuICB+ICBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICB+ICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gIH4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICB+XG4gIH4gICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gIH5cbiAgfiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICB+ICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gIH4gIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICB+ICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gIH4gIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICB+XG4gIC0tPlxuXG48ZGl2IGlkPVwiY2hhcnRDb250YWluZXJcIj5cbiAgPHdhcnB2aWV3LXNwaW5uZXIgKm5nSWY9XCJsb2FkaW5nXCIgbWVzc2FnZT1cIlBhcnNpbmcgZGF0YVwiPjwvd2FycHZpZXctc3Bpbm5lcj5cbiAgPHAgY2xhc3M9XCJub0RhdGFcIiAqbmdJZj1cIm5vRGF0YVwiPk5vIGRhdGEgdG8gZGlzcGxheTwvcD5cbiAgPGRpdiAqbmdJZj1cIiFsb2FkaW5nICYmICFub0RhdGFcIj5cbiAgICA8d2FycHZpZXctcGxvdGx5ICNncmFwaCAqbmdJZj1cInBsb3RseURhdGE/Lmxlbmd0aCA+IDBcIlxuICAgICAgICAgICAgICAgICAgICAgW2RhdGFdPVwicGxvdGx5RGF0YVwiIFtsYXlvdXRdPVwibGF5b3V0XCIgW2NvbmZpZ109XCJwbG90bHlDb25maWdcIiAoYWZ0ZXJQbG90KT1cImFmdGVyUGxvdCgpXCJcbiAgICAgICAgICAgICAgICAgICAgIChyZWxheW91dCk9XCJyZWxheW91dCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgIFt1cGRhdGVPbkxheW91dENoYW5nZV09XCJ0cnVlXCIgW3VwZGF0ZU9uRGF0YUNoYW5nZV09XCJ0cnVlXCIgW2RlYnVnXT1cImRlYnVnXCJcbiAgICAgICAgICAgICAgICAgICAgIFtzdHlsZV09XCJ7cG9zaXRpb246ICdyZWxhdGl2ZScsIHdpZHRoOiAnMTAwJScsIGhlaWdodDogJzEwMCUnfVwiPjwvd2FycHZpZXctcGxvdGx5PlxuICA8L2Rpdj5cbjwvZGl2PlxuIl19