@senx/warpview
Version:
WarpView Elements
133 lines • 34.8 kB
JavaScript
/*
* 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, NgZone, Renderer2, ViewEncapsulation } from '@angular/core';
import { WarpViewComponent } from '../warp-view-component';
import { GTSLib } from '../../utils/gts.lib';
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 * 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 WarpViewRadarComponent 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.layout = {
paper_bgcolor: 'transparent',
showlegend: true,
legend: { orientation: 'h' },
font: { size: 12 },
polar: {
bgcolor: 'transparent',
angularaxis: { type: 'category' },
radialaxis: { visible: true }
},
margin: {
t: 0,
b: 25,
r: 10,
l: 10
}
};
this.LOG = new Logger(WarpViewRadarComponent, this._debug);
}
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();
}
ngOnInit() {
this._options = this._options || this.defOptions;
}
drawChart() {
if (!this.initChart(this.el)) {
return;
}
this.layout.polar.radialaxis.color = this.getGridColor(this.el.nativeElement);
this.layout.polar.angularaxis.color = this.getGridColor(this.el.nativeElement);
this.LOG.debug(['drawChart', 'this.layout'], this.layout);
this.LOG.debug(['drawChart', 'this.plotlyConfig'], this.plotlyConfig);
this.LOG.debug(['drawChart', 'this.plotlyData'], this.plotlyData);
this.loading = false;
}
convert(data) {
const dataset = [];
const divider = GTSLib.getDivider(this._options.timeUnit);
const gtsList = GTSLib.flatDeep(GTSLib.flattenGtsIdArray(data.data, 0).res);
this.LOG.debug(['convert', 'gtsList'], gtsList);
let minVal = Number.MAX_VALUE;
let maxVal = Number.MIN_VALUE;
gtsList.forEach((gts, i) => {
const c = ColorLib.getColor(i, this._options.scheme);
const color = ((data.params || [])[gts.id] || { datasetColor: c }).datasetColor || c;
const series = {
r: [],
theta: [],
line: { color },
marker: {
line: { color, width: 1 },
color: ColorLib.transparentize(color)
},
fillcolor: ColorLib.transparentize(color),
hoverinfo: 'none',
name: GTSLib.serializeGtsMetadata(gts),
text: GTSLib.serializeGtsMetadata(gts),
type: 'scatterpolar',
fill: 'toself'
};
gts.v.forEach(value => {
const ts = value[0];
series.r.push(value[value.length - 1]);
minVal = Math.min(minVal, value[value.length - 1]);
maxVal = Math.max(maxVal, value[value.length - 1]);
if (this._options.timeMode && this._options.timeMode === 'timestamp') {
series.theta.push(ts.toString());
}
else {
series.theta.push(GTSLib.toISOString(ts, this.divider, this._options.timeZone));
}
});
dataset.push(series);
});
this.layout.polar.radialaxis.range = [minVal, maxVal];
return dataset;
}
resize(layout) {
//
}
}
WarpViewRadarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: WarpViewRadarComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i1.SizeService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
WarpViewRadarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: WarpViewRadarComponent, selector: "warpview-radar", 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\" #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)\" (hover)=\"hover($event)\" (unhover)=\"unhover($event)\"\n [updateOnLayoutChange]=\"true\" [updateOnDataChange]=\"true\" [debug]=\"debug\"\n [style]=\"{position: 'relative', width: '100%', height: '100%'}\"></warpview-plotly>\n </div>\n <div #toolTip class=\"wv-tooltip\" [ngStyle]=\"getTooltipPosition()\"></div>\n</div>\n", styles: [":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}/*!\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 */.gts-classname{color:var(--gts-classname-font-color)}.gts-labelname{color:var(--gts-labelname-font-color)}.gts-attrname{color:var(--gts-attrname-font-color)}.gts-separator{color:var(--gts-separator-font-color)}.gts-labelvalue{color:var(--gts-labelvalue-font-color);font-style:italic}.gts-attrvalue{color:var(--gts-attrvalue-font-color);font-style:italic}.wv-tooltip{background-color:var(--warp-view-tooltip-bg)!important;color:var(--warp-view-tooltip-color)!important;text-align:left;position:absolute;display:none;padding:10px;border:1px solid grey;border-radius:5px;box-shadow:none;pointer-events:none;font-size:10px;min-width:100px;width:auto;max-width:50%;z-index:999;height:auto!important;left:-1000px}.wv-tooltip .chip{border-radius:50%;background-color:#bbb;display:inline-block;width:5px;height:5px;border:2px solid #454545;margin-top:auto;margin-bottom:auto;vertical-align:middle;cursor:pointer}:host{display:block;height:100%}:host .bglayer{display:none}:host #chartContainer{height:100%}:host #chartContainer div{height:100%}:host div.chart{width:var(--warp-view-chart-width);height:var(--warp-view-chart-height)}\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"] }, { type: i4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], encapsulation: i0.ViewEncapsulation.ShadowDom });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: WarpViewRadarComponent, decorators: [{
type: Component,
args: [{ selector: 'warpview-radar', 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\" #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)\" (hover)=\"hover($event)\" (unhover)=\"unhover($event)\"\n [updateOnLayoutChange]=\"true\" [updateOnDataChange]=\"true\" [debug]=\"debug\"\n [style]=\"{position: 'relative', width: '100%', height: '100%'}\"></warpview-plotly>\n </div>\n <div #toolTip class=\"wv-tooltip\" [ngStyle]=\"getTooltipPosition()\"></div>\n</div>\n", styles: [":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}/*!\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 */.gts-classname{color:var(--gts-classname-font-color)}.gts-labelname{color:var(--gts-labelname-font-color)}.gts-attrname{color:var(--gts-attrname-font-color)}.gts-separator{color:var(--gts-separator-font-color)}.gts-labelvalue{color:var(--gts-labelvalue-font-color);font-style:italic}.gts-attrvalue{color:var(--gts-attrvalue-font-color);font-style:italic}.wv-tooltip{background-color:var(--warp-view-tooltip-bg)!important;color:var(--warp-view-tooltip-color)!important;text-align:left;position:absolute;display:none;padding:10px;border:1px solid grey;border-radius:5px;box-shadow:none;pointer-events:none;font-size:10px;min-width:100px;width:auto;max-width:50%;z-index:999;height:auto!important;left:-1000px}.wv-tooltip .chip{border-radius:50%;background-color:#bbb;display:inline-block;width:5px;height:5px;border:2px solid #454545;margin-top:auto;margin-bottom:auto;vertical-align:middle;cursor:pointer}:host{display:block;height:100%}:host .bglayer{display:none}:host #chartContainer{height:100%}:host #chartContainer div{height:100%}:host div.chart{width:var(--warp-view-chart-width);height:var(--warp-view-chart-height)}\n"] }]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i1.SizeService }, { type: i0.NgZone }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FycC12aWV3LXJhZGFyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3dhcnB2aWV3LW5nL3NyYy9saWIvZWxlbWVudHMvd2FycC12aWV3LXJhZGFyL3dhcnAtdmlldy1yYWRhci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy93YXJwdmlldy1uZy9zcmMvbGliL2VsZW1lbnRzL3dhcnAtdmlldy1yYWRhci93YXJwLXZpZXctcmFkYXIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBRUgsT0FBTyxFQUFDLFNBQVMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFVLFNBQVMsRUFBRSxpQkFBaUIsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUNsRyxPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSx3QkFBd0IsQ0FBQztBQUV6RCxPQUFPLEVBQUMsTUFBTSxFQUFDLE1BQU0scUJBQXFCLENBQUM7QUFFM0MsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLHVCQUF1QixDQUFDO0FBQy9DLE9BQU8sU0FBUyxNQUFNLFlBQVksQ0FBQztBQUNuQyxPQUFPLEVBQUMsV0FBVyxFQUFDLE1BQU0sK0JBQStCLENBQUM7QUFDMUQsT0FBTyxFQUFDLE1BQU0sRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBQzFDLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQzs7Ozs7O0FBUy9DOztHQUVHO0FBQ0gsTUFBTSxPQUFPLHNCQUF1QixTQUFRLGlCQUFpQjtJQTZCM0QsWUFDUyxFQUFjLEVBQ2QsUUFBbUIsRUFDbkIsV0FBd0IsRUFDeEIsTUFBYztRQUVyQixLQUFLLENBQUMsRUFBRSxFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFMbEMsT0FBRSxHQUFGLEVBQUUsQ0FB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QUssR0FBRyxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztRQUN0RCxPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0lBRU0sTUFBTSxDQUFDLE1BQXNDO1FBQ2xELEVBQUU7SUFDSixDQUFDOzttSEFuR1Usc0JBQXNCO3VHQUF0QixzQkFBc0IsNkVDdENuQyxxOENBNkJBOzJGRFNhLHNCQUFzQjtrQkFUbEMsU0FBUzsrQkFDRSxnQkFBZ0IsaUJBR1gsaUJBQWlCLENBQUMsU0FBUyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiAgQ29weXJpZ2h0IDIwMjEgIFNlblggUy5BLlMuXG4gKlxuICogIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiAgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHtDb21wb25lbnQsIEVsZW1lbnRSZWYsIE5nWm9uZSwgT25Jbml0LCBSZW5kZXJlcjIsIFZpZXdFbmNhcHN1bGF0aW9ufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7V2FycFZpZXdDb21wb25lbnR9IGZyb20gJy4uL3dhcnAtdmlldy1jb21wb25lbnQnO1xuaW1wb3J0IHtEYXRhTW9kZWx9IGZyb20gJy4uLy4uL21vZGVsL2RhdGFNb2RlbCc7XG5pbXBvcnQge0dUU0xpYn0gZnJvbSAnLi4vLi4vdXRpbHMvZ3RzLmxpYic7XG5pbXBvcnQge0dUU30gZnJvbSAnLi4vLi4vbW9kZWwvR1RTJztcbmltcG9ydCB7Q29sb3JMaWJ9IGZyb20gJy4uLy4uL3V0aWxzL2NvbG9yLWxpYic7XG5pbXBvcnQgZGVlcEVxdWFsIGZyb20gJ2RlZXAtZXF1YWwnO1xuaW1wb3J0IHtTaXplU2VydmljZX0gZnJvbSAnLi4vLi4vc2VydmljZXMvcmVzaXplLnNlcnZpY2UnO1xuaW1wb3J0IHtMb2dnZXJ9IGZyb20gJy4uLy4uL3V0aWxzL2xvZ2dlcic7XG5pbXBvcnQge0NoYXJ0TGlifSBmcm9tICcuLi8uLi91dGlscy9jaGFydC1saWInO1xuaW1wb3J0IHtQYXJhbX0gZnJvbSAnLi4vLi4vbW9kZWwvcGFyYW0nO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd3YXJwdmlldy1yYWRhcicsXG4gIHRlbXBsYXRlVXJsOiAnLi93YXJwLXZpZXctcmFkYXIuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi93YXJwLXZpZXctcmFkYXIuY29tcG9uZW50LnNjc3MnXSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uU2hhZG93RG9tXG59KVxuLyoqXG4gKlxuICovXG5leHBvcnQgY2xhc3MgV2FycFZpZXdSYWRhckNvbXBvbmVudCBleHRlbmRzIFdhcnBWaWV3Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcblxuICBsYXlvdXQ6IFBhcnRpYWw8YW55PiA9IHtcbiAgICBwYXBlcl9iZ2NvbG9yOiAndHJhbnNwYXJlbnQnLFxuICAgIHNob3dsZWdlbmQ6IHRydWUsXG4gICAgbGVnZW5kOiB7b3JpZW50YXRpb246ICdoJ30sXG4gICAgZm9udDoge3NpemU6IDEyfSxcbiAgICBwb2xhcjoge1xuICAgICAgYmdjb2xvcjogJ3RyYW5zcGFyZW50JyxcbiAgICAgIGFuZ3VsYXJheGlzOiB7dHlwZTogJ2NhdGVnb3J5J30sXG4gICAgICByYWRpYWxheGlzOiB7dmlzaWJsZTogdHJ1ZX1cbiAgICB9LFxuICAgIG1hcmdpbjoge1xuICAgICAgdDogMCxcbiAgICAgIGI6IDI1LFxuICAgICAgcjogMTAsXG4gICAgICBsOiAxMFxuICAgIH1cbiAgfTtcblxuICB1cGRhdGUob3B0aW9ucywgcmVmcmVzaCk6IHZvaWQge1xuICAgIHRoaXMuTE9HLmRlYnVnKFsnb25PcHRpb25zJywgJ2JlZm9yZSddLCB0aGlzLl9vcHRpb25zLCBvcHRpb25zKTtcbiAgICBpZiAoIWRlZXBFcXVhbChvcHRpb25zLCB0aGlzLl9vcHRpb25zKSkge1xuICAgICAgdGhpcy5MT0cuZGVidWcoWydvcHRpb25zJywgJ2NoYW5nZWQnXSwgb3B0aW9ucyk7XG4gICAgICB0aGlzLl9vcHRpb25zID0gQ2hhcnRMaWIubWVyZ2VEZWVwKHRoaXMuX29wdGlvbnMsIG9wdGlvbnMgYXMgUGFyYW0pIGFzIFBhcmFtO1xuICAgIH1cbiAgICB0aGlzLmRyYXdDaGFydCgpO1xuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIGVsOiBFbGVtZW50UmVmLFxuICAgIHB1YmxpYyByZW5kZXJlcjogUmVuZGVyZXIyLFxuICAgIHB1YmxpYyBzaXplU2VydmljZTogU2l6ZVNlcnZpY2UsXG4gICAgcHVibGljIG5nWm9uZTogTmdab25lXG4gICkge1xuICAgIHN1cGVyKGVsLCByZW5kZXJlciwgc2l6ZVNlcnZpY2UsIG5nWm9uZSk7XG4gICAgdGhpcy5MT0cgPSBuZXcgTG9nZ2VyKFdhcnBWaWV3UmFkYXJDb21wb25lbnQsIHRoaXMuX2RlYnVnKTtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuX29wdGlvbnMgPSB0aGlzLl9vcHRpb25zIHx8IHRoaXMuZGVmT3B0aW9ucztcbiAgfVxuXG4gIHByaXZhdGUgZHJhd0NoYXJ0KCkge1xuICAgIGlmICghdGhpcy5pbml0Q2hhcnQodGhpcy5lbCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5sYXlvdXQucG9sYXIucmFkaWFsYXhpcy5jb2xvciA9IHRoaXMuZ2V0R3JpZENvbG9yKHRoaXMuZWwubmF0aXZlRWxlbWVudCk7XG4gICAgdGhpcy5sYXlvdXQucG9sYXIuYW5ndWxhcmF4aXMuY29sb3IgPSB0aGlzLmdldEdyaWRDb2xvcih0aGlzLmVsLm5hdGl2ZUVsZW1lbnQpO1xuICAgIHRoaXMuTE9HLmRlYnVnKFsnZHJhd0NoYXJ0JywgJ3RoaXMubGF5b3V0J10sIHRoaXMubGF5b3V0KTtcbiAgICB0aGlzLkxPRy5kZWJ1ZyhbJ2RyYXdDaGFydCcsICd0aGlzLnBsb3RseUNvbmZpZyddLCB0aGlzLnBsb3RseUNvbmZpZyk7XG4gICAgdGhpcy5MT0cuZGVidWcoWydkcmF3Q2hhcnQnLCAndGhpcy5wbG90bHlEYXRhJ10sIHRoaXMucGxvdGx5RGF0YSk7XG4gICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gIH1cblxuICBwcm90ZWN0ZWQgY29udmVydChkYXRhOiBEYXRhTW9kZWwpOiBhbnlbXSB7XG4gICAgY29uc3QgZGF0YXNldDogYW55W10gPSBbXTtcbiAgICBjb25zdCBkaXZpZGVyID0gR1RTTGliLmdldERpdmlkZXIodGhpcy5fb3B0aW9ucy50aW1lVW5pdCk7XG4gICAgY29uc3QgZ3RzTGlzdCA9IEdUU0xpYi5mbGF0RGVlcChHVFNMaWIuZmxhdHRlbkd0c0lkQXJyYXkoZGF0YS5kYXRhIGFzIGFueVtdLCAwKS5yZXMpO1xuICAgIHRoaXMuTE9HLmRlYnVnKFsnY29udmVydCcsICdndHNMaXN0J10sIGd0c0xpc3QpO1xuICAgIGxldCBtaW5WYWwgPSBOdW1iZXIuTUFYX1ZBTFVFO1xuICAgIGxldCBtYXhWYWwgPSBOdW1iZXIuTUlOX1ZBTFVFO1xuICAgIGd0c0xpc3QuZm9yRWFjaCgoZ3RzOiBHVFMsIGkpID0+IHtcbiAgICAgIGNvbnN0IGMgPSBDb2xvckxpYi5nZXRDb2xvcihpLCB0aGlzLl9vcHRpb25zLnNjaGVtZSk7XG4gICAgICBjb25zdCBjb2xvciA9ICgoZGF0YS5wYXJhbXMgfHwgW10pW2d0cy5pZF0gfHwge2RhdGFzZXRDb2xvcjogY30pLmRhdGFzZXRDb2xvciB8fCBjO1xuICAgICAgY29uc3Qgc2VyaWVzOiBhbnkgPSB7XG4gICAgICAgIHI6IFtdLFxuICAgICAgICB0aGV0YTogW10sXG4gICAgICAgIGxpbmU6IHtjb2xvcn0sXG4gICAgICAgIG1hcmtlcjoge1xuICAgICAgICAgIGxpbmU6IHtjb2xvciwgd2lkdGg6IDF9LFxuICAgICAgICAgIGNvbG9yOiBDb2xvckxpYi50cmFuc3BhcmVudGl6ZShjb2xvcilcbiAgICAgICAgfSxcbiAgICAgICAgZmlsbGNvbG9yOiBDb2xvckxpYi50cmFuc3BhcmVudGl6ZShjb2xvciksXG4gICAgICAgIGhvdmVyaW5mbzogJ25vbmUnLFxuICAgICAgICBuYW1lOiBHVFNMaWIuc2VyaWFsaXplR3RzTWV0YWRhdGEoZ3RzKSxcbiAgICAgICAgdGV4dDogR1RTTGliLnNlcmlhbGl6ZUd0c01ldGFkYXRhKGd0cyksXG4gICAgICAgIHR5cGU6ICdzY2F0dGVycG9sYXInLFxuICAgICAgICBmaWxsOiAndG9zZWxmJ1xuICAgICAgfTtcbiAgICAgIGd0cy52LmZvckVhY2godmFsdWUgPT4ge1xuICAgICAgICBjb25zdCB0cyA9IHZhbHVlWzBdO1xuICAgICAgICBzZXJpZXMuci5wdXNoKHZhbHVlW3ZhbHVlLmxlbmd0aCAtIDFdKTtcbiAgICAgICAgbWluVmFsID0gTWF0aC5taW4obWluVmFsLCB2YWx1ZVt2YWx1ZS5sZW5ndGggLSAxXSk7XG4gICAgICAgIG1heFZhbCA9IE1hdGgubWF4KG1heFZhbCwgdmFsdWVbdmFsdWUubGVuZ3RoIC0gMV0pO1xuICAgICAgICBpZiAodGhpcy5fb3B0aW9ucy50aW1lTW9kZSAmJiB0aGlzLl9vcHRpb25zLnRpbWVNb2RlID09PSAndGltZXN0YW1wJykge1xuICAgICAgICAgIHNlcmllcy50aGV0YS5wdXNoKHRzLnRvU3RyaW5nKCkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNlcmllcy50aGV0YS5wdXNoKEdUU0xpYi50b0lTT1N0cmluZyh0cywgdGhpcy5kaXZpZGVyLCB0aGlzLl9vcHRpb25zLnRpbWVab25lKSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgZGF0YXNldC5wdXNoKHNlcmllcyk7XG4gICAgfSk7XG4gICAgdGhpcy5sYXlvdXQucG9sYXIucmFkaWFsYXhpcy5yYW5nZSA9IFttaW5WYWwsIG1heFZhbF07XG4gICAgcmV0dXJuIGRhdGFzZXQ7XG4gIH1cblxuICBwdWJsaWMgcmVzaXplKGxheW91dDogeyB3aWR0aDogbnVtYmVyOyBoZWlnaHQ6IGFueSB9KSB7XG4gICAgLy9cbiAgfVxufVxuIiwiPCEtLVxuICB+ICBDb3B5cmlnaHQgMjAyMSAgU2VuWCBTLkEuUy5cbiAgflxuICB+ICBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICB+ICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gIH4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICB+XG4gIH4gICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gIH5cbiAgfiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICB+ICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gIH4gIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICB+ICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gIH4gIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICB+XG4gIC0tPlxuXG48ZGl2IGlkPVwiY2hhcnRDb250YWluZXJcIiAjY2hhcnRDb250YWluZXI+XG4gIDx3YXJwdmlldy1zcGlubmVyICpuZ0lmPVwibG9hZGluZ1wiIG1lc3NhZ2U9XCJQYXJzaW5nIGRhdGFcIj48L3dhcnB2aWV3LXNwaW5uZXI+XG4gIDxwIGNsYXNzPVwibm9EYXRhXCIgKm5nSWY9XCJub0RhdGFcIj5ObyBkYXRhIHRvIGRpc3BsYXk8L3A+XG4gIDxkaXYgKm5nSWY9XCIhbG9hZGluZyAmJiAhbm9EYXRhXCI+XG4gICAgPHdhcnB2aWV3LXBsb3RseSAjZ3JhcGggKm5nSWY9XCJwbG90bHlEYXRhPy5sZW5ndGggPiAwXCJcbiAgICAgICAgICAgICAgICAgICAgIFtkYXRhXT1cInBsb3RseURhdGFcIiBbbGF5b3V0XT1cImxheW91dFwiIFtjb25maWddPVwicGxvdGx5Q29uZmlnXCIgKGFmdGVyUGxvdCk9XCJhZnRlclBsb3QoKVwiXG4gICAgICAgICAgICAgICAgICAgICAocmVsYXlvdXQpPVwicmVsYXlvdXQoJGV2ZW50KVwiIChob3Zlcik9XCJob3ZlcigkZXZlbnQpXCIgKHVuaG92ZXIpPVwidW5ob3ZlcigkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgIFt1cGRhdGVPbkxheW91dENoYW5nZV09XCJ0cnVlXCIgW3VwZGF0ZU9uRGF0YUNoYW5nZV09XCJ0cnVlXCIgW2RlYnVnXT1cImRlYnVnXCJcbiAgICAgICAgICAgICAgICAgICAgIFtzdHlsZV09XCJ7cG9zaXRpb246ICdyZWxhdGl2ZScsIHdpZHRoOiAnMTAwJScsIGhlaWdodDogJzEwMCUnfVwiPjwvd2FycHZpZXctcGxvdGx5PlxuICA8L2Rpdj5cbiAgPGRpdiAjdG9vbFRpcCBjbGFzcz1cInd2LXRvb2x0aXBcIiBbbmdTdHlsZV09XCJnZXRUb29sdGlwUG9zaXRpb24oKVwiPjwvZGl2PlxuPC9kaXY+XG4iXX0=