1 | import { Component, Input, ViewEncapsulation, ChangeDetectionStrategy, ContentChild, Output, EventEmitter } from '@angular/core';
|
2 | import { scaleBand } from 'd3-scale';
|
3 | import { BaseChartComponent } from '../common/base-chart.component';
|
4 | import { calculateViewDimensions } from '../common/view-dimensions.helper';
|
5 | import { ColorHelper } from '../common/color.helper';
|
6 | import { getScaleType } from '../common/domain.helper';
|
7 | import { LegendPosition } from '../common/types/legend.model';
|
8 | import { ScaleType } from '../common/types/scale-type.enum';
|
9 | export class HeatMapComponent extends BaseChartComponent {
|
10 | constructor() {
|
11 | super(...arguments);
|
12 | this.legendTitle = 'Legend';
|
13 | this.legendPosition = LegendPosition.Right;
|
14 | this.innerPadding = 8;
|
15 | this.trimXAxisTicks = true;
|
16 | this.trimYAxisTicks = true;
|
17 | this.rotateXAxisTicks = true;
|
18 | this.maxXAxisTickLength = 16;
|
19 | this.maxYAxisTickLength = 16;
|
20 | this.tooltipDisabled = false;
|
21 | this.activeEntries = [];
|
22 | this.activate = new EventEmitter();
|
23 | this.deactivate = new EventEmitter();
|
24 | this.margin = [10, 20, 10, 20];
|
25 | this.xAxisHeight = 0;
|
26 | this.yAxisWidth = 0;
|
27 | this.scaleType = ScaleType.Linear;
|
28 | }
|
29 | update() {
|
30 | super.update();
|
31 | this.formatDates();
|
32 | this.xDomain = this.getXDomain();
|
33 | this.yDomain = this.getYDomain();
|
34 | this.valueDomain = this.getValueDomain();
|
35 | this.scaleType = getScaleType(this.valueDomain, false);
|
36 | this.dims = calculateViewDimensions({
|
37 | width: this.width,
|
38 | height: this.height,
|
39 | margins: this.margin,
|
40 | showXAxis: this.xAxis,
|
41 | showYAxis: this.yAxis,
|
42 | xAxisHeight: this.xAxisHeight,
|
43 | yAxisWidth: this.yAxisWidth,
|
44 | showXLabel: this.showXAxisLabel,
|
45 | showYLabel: this.showYAxisLabel,
|
46 | showLegend: this.legend,
|
47 | legendType: this.scaleType,
|
48 | legendPosition: this.legendPosition
|
49 | });
|
50 | if (this.scaleType === ScaleType.Linear) {
|
51 | let min = this.min;
|
52 | let max = this.max;
|
53 | if (!this.min) {
|
54 | min = Math.min(0, ...this.valueDomain);
|
55 | }
|
56 | if (!this.max) {
|
57 | max = Math.max(...this.valueDomain);
|
58 | }
|
59 | this.valueDomain = [min, max];
|
60 | }
|
61 | this.xScale = this.getXScale();
|
62 | this.yScale = this.getYScale();
|
63 | this.setColors();
|
64 | this.legendOptions = this.getLegendOptions();
|
65 | this.transform = `translate(${this.dims.xOffset} , ${this.margin[0]})`;
|
66 | this.rects = this.getRects();
|
67 | }
|
68 | getXDomain() {
|
69 | const domain = [];
|
70 | for (const group of this.results) {
|
71 | if (!domain.includes(group.name)) {
|
72 | domain.push(group.name);
|
73 | }
|
74 | }
|
75 | return domain;
|
76 | }
|
77 | getYDomain() {
|
78 | const domain = [];
|
79 | for (const group of this.results) {
|
80 | for (const d of group.series) {
|
81 | if (!domain.includes(d.name)) {
|
82 | domain.push(d.name);
|
83 | }
|
84 | }
|
85 | }
|
86 | return domain;
|
87 | }
|
88 | getValueDomain() {
|
89 | const domain = [];
|
90 | for (const group of this.results) {
|
91 | for (const d of group.series) {
|
92 | if (!domain.includes(d.value)) {
|
93 | domain.push(d.value);
|
94 | }
|
95 | }
|
96 | }
|
97 | return domain;
|
98 | }
|
99 | /**
|
100 | * Converts the input to gap paddingInner in fraction
|
101 | * Supports the following inputs:
|
102 | * Numbers: 8
|
103 | * Strings: "8", "8px", "8%"
|
104 | * Arrays: [8,2], "8,2", "[8,2]"
|
105 | * Mixed: [8,"2%"], ["8px","2%"], "8,2%", "[8,2%]"
|
106 | *
|
107 | * @memberOf HeatMapComponent
|
108 | */
|
109 | getDimension(value, index = 0, N, L) {
|
110 | if (typeof value === 'string') {
|
111 | value = value
|
112 | .replace('[', '')
|
113 | .replace(']', '')
|
114 | .replace('px', '')
|
115 | // tslint:disable-next-line: quotemark
|
116 | .replace("'", '');
|
117 | if (value.includes(',')) {
|
118 | value = value.split(',');
|
119 | }
|
120 | }
|
121 | if (Array.isArray(value) && typeof index === 'number') {
|
122 | return this.getDimension(value[index], null, N, L);
|
123 | }
|
124 | if (typeof value === 'string' && value.includes('%')) {
|
125 | return +value.replace('%', '') / 100;
|
126 | }
|
127 | return N / (L / +value + 1);
|
128 | }
|
129 | getXScale() {
|
130 | const f = this.getDimension(this.innerPadding, 0, this.xDomain.length, this.dims.width);
|
131 | return scaleBand().rangeRound([0, this.dims.width]).domain(this.xDomain).paddingInner(f);
|
132 | }
|
133 | getYScale() {
|
134 | const f = this.getDimension(this.innerPadding, 1, this.yDomain.length, this.dims.height);
|
135 | return scaleBand().rangeRound([this.dims.height, 0]).domain(this.yDomain).paddingInner(f);
|
136 | }
|
137 | getRects() {
|
138 | const rects = [];
|
139 | this.xDomain.map(xVal => {
|
140 | this.yDomain.map(yVal => {
|
141 | rects.push({
|
142 | x: this.xScale(xVal),
|
143 | y: this.yScale(yVal),
|
144 | rx: 3,
|
145 | width: this.xScale.bandwidth(),
|
146 | height: this.yScale.bandwidth(),
|
147 | fill: 'rgba(200,200,200,0.03)'
|
148 | });
|
149 | });
|
150 | });
|
151 | return rects;
|
152 | }
|
153 | onClick(data) {
|
154 | this.select.emit(data);
|
155 | }
|
156 | setColors() {
|
157 | this.colors = new ColorHelper(this.scheme, this.scaleType, this.valueDomain);
|
158 | }
|
159 | getLegendOptions() {
|
160 | return {
|
161 | scaleType: this.scaleType,
|
162 | domain: this.valueDomain,
|
163 | colors: this.scaleType === ScaleType.Ordinal ? this.colors : this.colors.scale,
|
164 | title: this.scaleType === ScaleType.Ordinal ? this.legendTitle : undefined,
|
165 | position: this.legendPosition
|
166 | };
|
167 | }
|
168 | updateYAxisWidth({ width }) {
|
169 | this.yAxisWidth = width;
|
170 | this.update();
|
171 | }
|
172 | updateXAxisHeight({ height }) {
|
173 | this.xAxisHeight = height;
|
174 | this.update();
|
175 | }
|
176 | onActivate(event, group, fromLegend = false) {
|
177 | const item = Object.assign({}, event);
|
178 | if (group) {
|
179 | item.series = group.name;
|
180 | }
|
181 | const items = this.results
|
182 | .map(g => g.series)
|
183 | .flat()
|
184 | .filter(i => {
|
185 | if (fromLegend) {
|
186 | return i.label === item.name;
|
187 | }
|
188 | else {
|
189 | return i.name === item.name && i.series === item.series;
|
190 | }
|
191 | });
|
192 | this.activeEntries = [...items];
|
193 | this.activate.emit({ value: item, entries: this.activeEntries });
|
194 | }
|
195 | onDeactivate(event, group, fromLegend = false) {
|
196 | const item = Object.assign({}, event);
|
197 | if (group) {
|
198 | item.series = group.name;
|
199 | }
|
200 | this.activeEntries = this.activeEntries.filter(i => {
|
201 | if (fromLegend) {
|
202 | return i.label !== item.name;
|
203 | }
|
204 | else {
|
205 | return !(i.name === item.name && i.series === item.series);
|
206 | }
|
207 | });
|
208 | this.deactivate.emit({ value: item, entries: this.activeEntries });
|
209 | }
|
210 | }
|
211 | HeatMapComponent.decorators = [
|
212 | { type: Component, args: [{
|
213 | selector: 'ngx-charts-heat-map',
|
214 | template: `
|
215 | <ngx-charts-chart
|
216 | [view]="[width, height]"
|
217 | [showLegend]="legend"
|
218 | [animations]="animations"
|
219 | [legendOptions]="legendOptions"
|
220 | (legendLabelClick)="onClick($event)"
|
221 | >
|
222 | <svg:g [attr.transform]="transform" class="heat-map chart">
|
223 | <svg:g
|
224 | ngx-charts-x-axis
|
225 | *ngIf="xAxis"
|
226 | [xScale]="xScale"
|
227 | [dims]="dims"
|
228 | [showLabel]="showXAxisLabel"
|
229 | [labelText]="xAxisLabel"
|
230 | [trimTicks]="trimXAxisTicks"
|
231 | [rotateTicks]="rotateXAxisTicks"
|
232 | [maxTickLength]="maxXAxisTickLength"
|
233 | [tickFormatting]="xAxisTickFormatting"
|
234 | [ticks]="xAxisTicks"
|
235 | (dimensionsChanged)="updateXAxisHeight($event)"
|
236 | ></svg:g>
|
237 | <svg:g
|
238 | ngx-charts-y-axis
|
239 | *ngIf="yAxis"
|
240 | [yScale]="yScale"
|
241 | [dims]="dims"
|
242 | [showLabel]="showYAxisLabel"
|
243 | [labelText]="yAxisLabel"
|
244 | [trimTicks]="trimYAxisTicks"
|
245 | [maxTickLength]="maxYAxisTickLength"
|
246 | [tickFormatting]="yAxisTickFormatting"
|
247 | [ticks]="yAxisTicks"
|
248 | (dimensionsChanged)="updateYAxisWidth($event)"
|
249 | ></svg:g>
|
250 | <svg:rect
|
251 | *ngFor="let rect of rects"
|
252 | [attr.x]="rect.x"
|
253 | [attr.y]="rect.y"
|
254 | [attr.rx]="rect.rx"
|
255 | [attr.width]="rect.width"
|
256 | [attr.height]="rect.height"
|
257 | [attr.fill]="rect.fill"
|
258 | />
|
259 | <svg:g
|
260 | ngx-charts-heat-map-cell-series
|
261 | [xScale]="xScale"
|
262 | [yScale]="yScale"
|
263 | [colors]="colors"
|
264 | [data]="results"
|
265 | [gradient]="gradient"
|
266 | [animations]="animations"
|
267 | [tooltipDisabled]="tooltipDisabled"
|
268 | [tooltipTemplate]="tooltipTemplate"
|
269 | [tooltipText]="tooltipText"
|
270 | (select)="onClick($event)"
|
271 | (activate)="onActivate($event, undefined)"
|
272 | (deactivate)="onDeactivate($event, undefined)"
|
273 | />
|
274 | </svg:g>
|
275 | </ngx-charts-chart>
|
276 | `,
|
277 | changeDetection: ChangeDetectionStrategy.OnPush,
|
278 | encapsulation: ViewEncapsulation.None,
|
279 | styles: [".ngx-charts{float:left;overflow:visible}.ngx-charts .arc,.ngx-charts .bar,.ngx-charts .cell,.ngx-charts .circle{cursor:pointer}.ngx-charts .arc.active,.ngx-charts .arc:hover,.ngx-charts .bar.active,.ngx-charts .bar:hover,.ngx-charts .card.active,.ngx-charts .card:hover,.ngx-charts .cell.active,.ngx-charts .cell:hover{opacity:.8;transition:opacity .1s ease-in-out}.ngx-charts .arc:focus,.ngx-charts .bar:focus,.ngx-charts .card:focus,.ngx-charts .cell:focus{outline:none}.ngx-charts .arc.hidden,.ngx-charts .bar.hidden,.ngx-charts .card.hidden,.ngx-charts .cell.hidden{display:none}.ngx-charts g:focus{outline:none}.ngx-charts .area-series.inactive,.ngx-charts .line-series-range.inactive,.ngx-charts .line-series.inactive,.ngx-charts .polar-series-area.inactive,.ngx-charts .polar-series-path.inactive{transition:opacity .1s ease-in-out;opacity:.2}.ngx-charts .line-highlight{display:none}.ngx-charts .line-highlight.active{display:block}.ngx-charts .area{opacity:.6}.ngx-charts .circle:hover{cursor:pointer}.ngx-charts .label{font-size:12px;font-weight:400}.ngx-charts .tooltip-anchor{fill:#000}.ngx-charts .gridline-path{stroke:#ddd;stroke-width:1;fill:none}.ngx-charts .refline-path{stroke:#a8b2c7;stroke-width:1;stroke-dasharray:5;stroke-dashoffset:5}.ngx-charts .refline-label{font-size:9px}.ngx-charts .reference-area{fill-opacity:.05;fill:#000}.ngx-charts .gridline-path-dotted{stroke:#ddd;stroke-width:1;fill:none;stroke-dasharray:1,20;stroke-dashoffset:3}.ngx-charts .grid-panel rect{fill:none}.ngx-charts .grid-panel.odd rect{fill:rgba(0,0,0,.05)}"]
|
280 | },] }
|
281 | ];
|
282 | HeatMapComponent.propDecorators = {
|
283 | legend: [{ type: Input }],
|
284 | legendTitle: [{ type: Input }],
|
285 | legendPosition: [{ type: Input }],
|
286 | xAxis: [{ type: Input }],
|
287 | yAxis: [{ type: Input }],
|
288 | showXAxisLabel: [{ type: Input }],
|
289 | showYAxisLabel: [{ type: Input }],
|
290 | xAxisLabel: [{ type: Input }],
|
291 | yAxisLabel: [{ type: Input }],
|
292 | gradient: [{ type: Input }],
|
293 | innerPadding: [{ type: Input }],
|
294 | trimXAxisTicks: [{ type: Input }],
|
295 | trimYAxisTicks: [{ type: Input }],
|
296 | rotateXAxisTicks: [{ type: Input }],
|
297 | maxXAxisTickLength: [{ type: Input }],
|
298 | maxYAxisTickLength: [{ type: Input }],
|
299 | xAxisTickFormatting: [{ type: Input }],
|
300 | yAxisTickFormatting: [{ type: Input }],
|
301 | xAxisTicks: [{ type: Input }],
|
302 | yAxisTicks: [{ type: Input }],
|
303 | tooltipDisabled: [{ type: Input }],
|
304 | tooltipText: [{ type: Input }],
|
305 | min: [{ type: Input }],
|
306 | max: [{ type: Input }],
|
307 | activeEntries: [{ type: Input }],
|
308 | activate: [{ type: Output }],
|
309 | deactivate: [{ type: Output }],
|
310 | tooltipTemplate: [{ type: ContentChild, args: ['tooltipTemplate',] }]
|
311 | };
|
312 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVhdC1tYXAuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc3dpbWxhbmUvbmd4LWNoYXJ0cy9zcmMvbGliL2hlYXQtbWFwL2hlYXQtbWFwLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULEtBQUssRUFDTCxpQkFBaUIsRUFDakIsdUJBQXVCLEVBQ3ZCLFlBQVksRUFFWixNQUFNLEVBQ04sWUFBWSxFQUNiLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFFckMsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDcEUsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDM0UsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3JELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN2RCxPQUFPLEVBQWlCLGNBQWMsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBRTdFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQWdGNUQsTUFBTSxPQUFPLGdCQUFpQixTQUFRLGtCQUFrQjtJQXJFeEQ7O1FBdUVXLGdCQUFXLEdBQVcsUUFBUSxDQUFDO1FBQy9CLG1CQUFjLEdBQW1CLGNBQWMsQ0FBQyxLQUFLLENBQUM7UUFRdEQsaUJBQVksR0FBMEMsQ0FBQyxDQUFDO1FBQ3hELG1CQUFjLEdBQVksSUFBSSxDQUFDO1FBQy9CLG1CQUFjLEdBQVksSUFBSSxDQUFDO1FBQy9CLHFCQUFnQixHQUFZLElBQUksQ0FBQztRQUNqQyx1QkFBa0IsR0FBVyxFQUFFLENBQUM7UUFDaEMsdUJBQWtCLEdBQVcsRUFBRSxDQUFDO1FBS2hDLG9CQUFlLEdBQVksS0FBSyxDQUFDO1FBSWpD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QyxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsTUFBTSxLQUFLLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQzthQUM1RDtRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUMsQ0FBQztJQUNyRSxDQUFDOzs7WUF6VUYsU0FBUyxTQUFDO2dCQUNULFFBQVEsRUFBRSxxQkFBcUI7Z0JBQy9CLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E4RFQ7Z0JBQ0QsZUFBZSxFQUFFLHVCQUF1QixDQUFDLE1BQU07Z0JBRS9DLGFBQWEsRUFBRSxpQkFBaUIsQ0FBQyxJQUFJOzthQUN0Qzs7O3FCQUVFLEtBQUs7MEJBQ0wsS0FBSzs2QkFDTCxLQUFLO29CQUNMLEtBQUs7b0JBQ0wsS0FBSzs2QkFDTCxLQUFLOzZCQUNMLEtBQUs7eUJBQ0wsS0FBSzt5QkFDTCxLQUFLO3VCQUNMLEtBQUs7MkJBQ0wsS0FBSzs2QkFDTCxLQUFLOzZCQUNMLEtBQUs7K0JBQ0wsS0FBSztpQ0FDTCxLQUFLO2lDQUNMLEtBQUs7a0NBQ0wsS0FBSztrQ0FDTCxLQUFLO3lCQUNMLEtBQUs7eUJBQ0wsS0FBSzs4QkFDTCxLQUFLOzBCQUNMLEtBQUs7a0JBQ0wsS0FBSztrQkFDTCxLQUFLOzRCQUNMLEtBQUs7dUJBRUwsTUFBTTt5QkFDTixNQUFNOzhCQUVOLFlBQVksU0FBQyxpQkFBaUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb21wb25lbnQsXG4gIElucHV0LFxuICBWaWV3RW5jYXBzdWxhdGlvbixcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbnRlbnRDaGlsZCxcbiAgVGVtcGxhdGVSZWYsXG4gIE91dHB1dCxcbiAgRXZlbnRFbWl0dGVyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgc2NhbGVCYW5kIH0gZnJvbSAnZDMtc2NhbGUnO1xuXG5pbXBvcnQgeyBCYXNlQ2hhcnRDb21wb25lbnQgfSBmcm9tICcuLi9jb21tb24vYmFzZS1jaGFydC5jb21wb25lbnQnO1xuaW1wb3J0IHsgY2FsY3VsYXRlVmlld0RpbWVuc2lvbnMgfSBmcm9tICcuLi9jb21tb24vdmlldy1kaW1lbnNpb25zLmhlbHBlcic7XG5pbXBvcnQgeyBDb2xvckhlbHBlciB9IGZyb20gJy4uL2NvbW1vbi9jb2xvci5oZWxwZXInO1xuaW1wb3J0IHsgZ2V0U2NhbGVUeXBlIH0gZnJvbSAnLi4vY29tbW9uL2RvbWFpbi5oZWxwZXInO1xuaW1wb3J0IHsgTGVnZW5kT3B0aW9ucywgTGVnZW5kUG9zaXRpb24gfSBmcm9tICcuLi9jb21tb24vdHlwZXMvbGVnZW5kLm1vZGVsJztcbmltcG9ydCB7IFZpZXdEaW1lbnNpb25zIH0gZnJvbSAnLi4vY29tbW9uL3R5cGVzL3ZpZXctZGltZW5zaW9uLmludGVyZmFjZSc7XG5pbXBvcnQgeyBTY2FsZVR5cGUgfSBmcm9tICcuLi9jb21tb24vdHlwZXMvc2NhbGUtdHlwZS5lbnVtJztcblxuaW50ZXJmYWNlIFJlY3RJdGVtIHtcbiAgZmlsbDogc3RyaW5nO1xuICBoZWlnaHQ6IG51bWJlcjtcbiAgcng6IG51bWJlcjtcbiAgd2lkdGg6IG51bWJlcjtcbiAgeDogbnVtYmVyO1xuICB5OiBudW1iZXI7XG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25neC1jaGFydHMtaGVhdC1tYXAnLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxuZ3gtY2hhcnRzLWNoYXJ0XG4gICAgICBbdmlld109XCJbd2lkdGgsIGhlaWdodF1cIlxuICAgICAgW3Nob3dMZWdlbmRdPVwibGVnZW5kXCJcbiAgICAgIFthbmltYXRpb25zXT1cImFuaW1hdGlvbnNcIlxuICAgICAgW2xlZ2VuZE9wdGlvbnNdPVwibGVnZW5kT3B0aW9uc1wiXG4gICAgICAobGVnZW5kTGFiZWxDbGljayk9XCJvbkNsaWNrKCRldmVudClcIlxuICAgID5cbiAgICAgIDxzdmc6ZyBbYXR0ci50cmFuc2Zvcm1dPVwidHJhbnNmb3JtXCIgY2xhc3M9XCJoZWF0LW1hcCBjaGFydFwiPlxuICAgICAgICA8c3ZnOmdcbiAgICAgICAgICBuZ3gtY2hhcnRzLXgtYXhpc1xuICAgICAgICAgICpuZ0lmPVwieEF4aXNcIlxuICAgICAgICAgIFt4U2NhbGVdPVwieFNjYWxlXCJcbiAgICAgICAgICBbZGltc109XCJkaW1zXCJcbiAgICAgICAgICBbc2hvd0xhYmVsXT1cInNob3dYQXhpc0xhYmVsXCJcbiAgICAgICAgICBbbGFiZWxUZXh0XT1cInhBeGlzTGFiZWxcIlxuICAgICAgICAgIFt0cmltVGlja3NdPVwidHJpbVhBeGlzVGlja3NcIlxuICAgICAgICAgIFtyb3RhdGVUaWNrc109XCJyb3RhdGVYQXhpc1RpY2tzXCJcbiAgICAgICAgICBbbWF4VGlja0xlbmd0aF09XCJtYXhYQXhpc1RpY2tMZW5ndGhcIlxuICAgICAgICAgIFt0aWNrRm9ybWF0dGluZ109XCJ4QXhpc1RpY2tGb3JtYXR0aW5nXCJcbiAgICAgICAgICBbdGlja3NdPVwieEF4aXNUaWNrc1wiXG4gICAgICAgICAgKGRpbWVuc2lvbnNDaGFuZ2VkKT1cInVwZGF0ZVhBeGlzSGVpZ2h0KCRldmVudClcIlxuICAgICAgICA+PC9zdmc6Zz5cbiAgICAgICAgPHN2ZzpnXG4gICAgICAgICAgbmd4LWNoYXJ0cy15LWF4aXNcbiAgICAgICAgICAqbmdJZj1cInlBeGlzXCJcbiAgICAgICAgICBbeVNjYWxlXT1cInlTY2FsZVwiXG4gICAgICAgICAgW2RpbXNdPVwiZGltc1wiXG4gICAgICAgICAgW3Nob3dMYWJlbF09XCJzaG93WUF4aXNMYWJlbFwiXG4gICAgICAgICAgW2xhYmVsVGV4dF09XCJ5QXhpc0xhYmVsXCJcbiAgICAgICAgICBbdHJpbVRpY2tzXT1cInRyaW1ZQXhpc1RpY2tzXCJcbiAgICAgICAgICBbbWF4VGlja0xlbmd0aF09XCJtYXhZQXhpc1RpY2tMZW5ndGhcIlxuICAgICAgICAgIFt0aWNrRm9ybWF0dGluZ109XCJ5QXhpc1RpY2tGb3JtYXR0aW5nXCJcbiAgICAgICAgICBbdGlja3NdPVwieUF4aXNUaWNrc1wiXG4gICAgICAgICAgKGRpbWVuc2lvbnNDaGFuZ2VkKT1cInVwZGF0ZVlBeGlzV2lkdGgoJGV2ZW50KVwiXG4gICAgICAgID48L3N2ZzpnPlxuICAgICAgICA8c3ZnOnJlY3RcbiAgICAgICAgICAqbmdGb3I9XCJsZXQgcmVjdCBvZiByZWN0c1wiXG4gICAgICAgICAgW2F0dHIueF09XCJyZWN0LnhcIlxuICAgICAgICAgIFthdHRyLnldPVwicmVjdC55XCJcbiAgICAgICAgICBbYXR0ci5yeF09XCJyZWN0LnJ4XCJcbiAgICAgICAgICBbYXR0ci53aWR0aF09XCJyZWN0LndpZHRoXCJcbiAgICAgICAgICBbYXR0ci5oZWlnaHRdPVwicmVjdC5oZWlnaHRcIlxuICAgICAgICAgIFthdHRyLmZpbGxdPVwicmVjdC5maWxsXCJcbiAgICAgICAgLz5cbiAgICAgICAgPHN2ZzpnXG4gICAgICAgICAgbmd4LWNoYXJ0cy1oZWF0LW1hcC1jZWxsLXNlcmllc1xuICAgICAgICAgIFt4U2NhbGVdPVwieFNjYWxlXCJcbiAgICAgICAgICBbeVNjYWxlXT1cInlTY2FsZVwiXG4gICAgICAgICAgW2NvbG9yc109XCJjb2xvcnNcIlxuICAgICAgICAgIFtkYXRhXT1cInJlc3VsdHNcIlxuICAgICAgICAgIFtncmFkaWVudF09XCJncmFkaWVudFwiXG4gICAgICAgICAgW2FuaW1hdGlvbnNdPVwiYW5pbWF0aW9uc1wiXG4gICAgICAgICAgW3Rvb2x0aXBEaXNhYmxlZF09XCJ0b29sdGlwRGlzYWJsZWRcIlxuICAgICAgICAgIFt0b29sdGlwVGVtcGxhdGVdPVwidG9vbHRpcFRlbXBsYXRlXCJcbiAgICAgICAgICBbdG9vbHRpcFRleHRdPVwidG9vbHRpcFRleHRcIlxuICAgICAgICAgIChzZWxlY3QpPVwib25DbGljaygkZXZlbnQpXCJcbiAgICAgICAgICAoYWN0aXZhdGUpPVwib25BY3RpdmF0ZSgkZXZlbnQsIHVuZGVmaW5lZClcIlxuICAgICAgICAgIChkZWFjdGl2YXRlKT1cIm9uRGVhY3RpdmF0ZSgkZXZlbnQsIHVuZGVmaW5lZClcIlxuICAgICAgICAvPlxuICAgICAgPC9zdmc6Zz5cbiAgICA8L25neC1jaGFydHMtY2hhcnQ+XG4gIGAsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBzdHlsZVVybHM6IFsnLi4vY29tbW9uL2Jhc2UtY2hhcnQuY29tcG9uZW50LnNjc3MnXSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZVxufSlcbmV4cG9ydCBjbGFzcyBIZWF0TWFwQ29tcG9uZW50IGV4dGVuZHMgQmFzZUNoYXJ0Q29tcG9uZW50IHtcbiAgQElucHV0KCkgbGVnZW5kOiBib29sZWFuO1xuICBASW5wdXQoKSBsZWdlbmRUaXRsZTogc3RyaW5nID0gJ0xlZ2VuZCc7XG4gIEBJbnB1dCgpIGxlZ2VuZFBvc2l0aW9uOiBMZWdlbmRQb3NpdGlvbiA9IExlZ2VuZFBvc2l0aW9uLlJpZ2h0O1xuICBASW5wdXQoKSB4QXhpczogYm9vbGVhbjtcbiAgQElucHV0KCkgeUF4aXM6IGJvb2xlYW47XG4gIEBJbnB1dCgpIHNob3dYQXhpc0xhYmVsOiBib29sZWFuO1xuICBASW5wdXQoKSBzaG93WUF4aXNMYWJlbDogYm9vbGVhbjtcbiAgQElucHV0KCkgeEF4aXNMYWJlbDogc3RyaW5nO1xuICBASW5wdXQoKSB5QXhpc0xhYmVsOiBzdHJpbmc7XG4gIEBJbnB1dCgpIGdyYWRpZW50OiBib29sZWFuO1xuICBASW5wdXQoKSBpbm5lclBhZGRpbmc6IG51bWJlciB8IG51bWJlcltdIHwgc3RyaW5nIHwgc3RyaW5nW10gPSA4O1xuICBASW5wdXQoKSB0cmltWEF4aXNUaWNrczogYm9vbGVhbiA9IHRydWU7XG4gIEBJbnB1dCgpIHRyaW1ZQXhpc1RpY2tzOiBib29sZWFuID0gdHJ1ZTtcbiAgQElucHV0KCkgcm90YXRlWEF4aXNUaWNrczogYm9vbGVhbiA9IHRydWU7XG4gIEBJbnB1dCgpIG1heFhBeGlzVGlja0xlbmd0aDogbnVtYmVyID0gMTY7XG4gIEBJbnB1dCgpIG1heFlBeGlzVGlja0xlbmd0aDogbnVtYmVyID0gMTY7XG4gIEBJbnB1dCgpIHhBeGlzVGlja0Zvcm1hdHRpbmc6IGFueTtcbiAgQElucHV0KCkgeUF4aXNUaWNrRm9ybWF0dGluZzogYW55O1xuICBASW5wdXQoKSB4QXhpc1RpY2tzOiBhbnlbXTtcbiAgQElucHV0KCkgeUF4aXNUaWNrczogYW55W107XG4gIEBJbnB1dCgpIHRvb2x0aXBEaXNhYmxlZDogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSB0b29sdGlwVGV4dDogYW55O1xuICBASW5wdXQoKSBtaW46IG51bWJlcjtcbiAgQElucHV0KCkgbWF4OiBudW1iZXI7XG4gIEBJbnB1dCgpIGFjdGl2ZUVudHJpZXM6IGFueVtdID0gW107XG5cbiAgQE91dHB1dCgpIGFjdGl2YXRlOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIGRlYWN0aXZhdGU6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIEBDb250ZW50Q2hpbGQoJ3Rvb2x0aXBUZW1wbGF0ZScpIHRvb2x0aXBUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PjtcblxuICBkaW1zOiBWaWV3RGltZW5zaW9ucztcbiAgeERvbWFpbjogc3RyaW5nW107XG4gIHlEb21haW46IHN0cmluZ1tdO1xuICB2YWx1ZURvbWFpbjogYW55W107XG4gIHhTY2FsZTogYW55O1xuICB5U2NhbGU6IGFueTtcbiAgY29sb3JzOiBDb2xvckhlbHBlcjtcbiAgY29sb3JTY2FsZTogYW55O1xuICB0cmFuc2Zvcm06IHN0cmluZztcbiAgcmVjdHM6IFJlY3RJdGVtW107XG4gIG1hcmdpbjogbnVtYmVyW10gPSBbMTAsIDIwLCAxMCwgMjBdO1xuICB4QXhpc0hlaWdodDogbnVtYmVyID0gMDtcbiAgeUF4aXNXaWR0aDogbnVtYmVyID0gMDtcbiAgbGVnZW5kT3B0aW9uczogTGVnZW5kT3B0aW9ucztcbiAgc2NhbGVUeXBlOiBTY2FsZVR5cGUgPSBTY2FsZVR5cGUuTGluZWFyO1xuXG4gIHVwZGF0ZSgpOiB2b2lkIHtcbiAgICBzdXBlci51cGRhdGUoKTtcblxuICAgIHRoaXMuZm9ybWF0RGF0ZXMoKTtcblxuICAgIHRoaXMueERvbWFpbiA9IHRoaXMuZ2V0WERvbWFpbigpO1xuICAgIHRoaXMueURvbWFpbiA9IHRoaXMuZ2V0WURvbWFpbigpO1xuICAgIHRoaXMudmFsdWVEb21haW4gPSB0aGlzLmdldFZhbHVlRG9tYWluKCk7XG5cbiAgICB0aGlzLnNjYWxlVHlwZSA9IGdldFNjYWxlVHlwZSh0aGlzLnZhbHVlRG9tYWluLCBmYWxzZSk7XG5cbiAgICB0aGlzLmRpbXMgPSBjYWxjdWxhdGVWaWV3RGltZW5zaW9ucyh7XG4gICAgICB3aWR0aDogdGhpcy53aWR0aCxcbiAgICAgIGhlaWdodDogdGhpcy5oZWlnaHQsXG4gICAgICBtYXJnaW5zOiB0aGlzLm1hcmdpbixcbiAgICAgIHNob3dYQXhpczogdGhpcy54QXhpcyxcbiAgICAgIHNob3dZQXhpczogdGhpcy55QXhpcyxcbiAgICAgIHhBeGlzSGVpZ2h0OiB0aGlzLnhBeGlzSGVpZ2h0LFxuICAgICAgeUF4aXNXaWR0aDogdGhpcy55QXhpc1dpZHRoLFxuICAgICAgc2hvd1hMYWJlbDogdGhpcy5zaG93WEF4aXNMYWJlbCxcbiAgICAgIHNob3dZTGFiZWw6IHRoaXMuc2hvd1lBeGlzTGFiZWwsXG4gICAgICBzaG93TGVnZW5kOiB0aGlzLmxlZ2VuZCxcbiAgICAgIGxlZ2VuZFR5cGU6IHRoaXMuc2NhbGVUeXBlIGFzIGFueSxcbiAgICAgIGxlZ2VuZFBvc2l0aW9uOiB0aGlzLmxlZ2VuZFBvc2l0aW9uXG4gICAgfSk7XG5cbiAgICBpZiAodGhpcy5zY2FsZVR5cGUgPT09IFNjYWxlVHlwZS5MaW5lYXIpIHtcbiAgICAgIGxldCBtaW4gPSB0aGlzLm1pbjtcbiAgICAgIGxldCBtYXggPSB0aGlzLm1heDtcbiAgICAgIGlmICghdGhpcy5taW4pIHtcbiAgICAgICAgbWluID0gTWF0aC5taW4oMCwgLi4udGhpcy52YWx1ZURvbWFpbik7XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMubWF4KSB7XG4gICAgICAgIG1heCA9IE1hdGgubWF4KC4uLnRoaXMudmFsdWVEb21haW4pO1xuICAgICAgfVxuICAgICAgdGhpcy52YWx1ZURvbWFpbiA9IFttaW4sIG1heF07XG4gICAgfVxuXG4gICAgdGhpcy54U2NhbGUgPSB0aGlzLmdldFhTY2FsZSgpO1xuICAgIHRoaXMueVNjYWxlID0gdGhpcy5nZXRZU2NhbGUoKTtcblxuICAgIHRoaXMuc2V0Q29sb3JzKCk7XG4gICAgdGhpcy5sZWdlbmRPcHRpb25zID0gdGhpcy5nZXRMZWdlbmRPcHRpb25zKCk7XG5cbiAgICB0aGlzLnRyYW5zZm9ybSA9IGB0cmFuc2xhdGUoJHt0aGlzLmRpbXMueE9mZnNldH0gLCAke3RoaXMubWFyZ2luWzBdfSlgO1xuICAgIHRoaXMucmVjdHMgPSB0aGlzLmdldFJlY3RzKCk7XG4gIH1cblxuICBnZXRYRG9tYWluKCk6IHN0cmluZ1tdIHtcbiAgICBjb25zdCBkb21haW4gPSBbXTtcbiAgICBmb3IgKGNvbnN0IGdyb3VwIG9mIHRoaXMucmVzdWx0cykge1xuICAgICAgaWYgKCFkb21haW4uaW5jbHVkZXMoZ3JvdXAubmFtZSkpIHtcbiAgICAgICAgZG9tYWluLnB1c2goZ3JvdXAubmFtZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGRvbWFpbjtcbiAgfVxuXG4gIGdldFlEb21haW4oKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IGRvbWFpbiA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBncm91cCBvZiB0aGlzLnJlc3VsdHMpIHtcbiAgICAgIGZvciAoY29uc3QgZCBvZiBncm91cC5zZXJpZXMpIHtcbiAgICAgICAgaWYgKCFkb21haW4uaW5jbHVkZXMoZC5uYW1lKSkge1xuICAgICAgICAgIGRvbWFpbi5wdXNoKGQubmFtZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZG9tYWluO1xuICB9XG5cbiAgZ2V0VmFsdWVEb21haW4oKTogYW55W10ge1xuICAgIGNvbnN0IGRvbWFpbiA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBncm91cCBvZiB0aGlzLnJlc3VsdHMpIHtcbiAgICAgIGZvciAoY29uc3QgZCBvZiBncm91cC5zZXJpZXMpIHtcbiAgICAgICAgaWYgKCFkb21haW4uaW5jbHVkZXMoZC52YWx1ZSkpIHtcbiAgICAgICAgICBkb21haW4ucHVzaChkLnZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBkb21haW47XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgdGhlIGlucHV0IHRvIGdhcCBwYWRkaW5nSW5uZXIgaW4gZnJhY3Rpb25cbiAgICogU3VwcG9ydHMgdGhlIGZvbGxvd2luZyBpbnB1dHM6XG4gICAqICAgIE51bWJlcnM6IDhcbiAgICogICAgU3RyaW5nczogXCI4XCIsIFwiOHB4XCIsIFwiOCVcIlxuICAgKiAgICBBcnJheXM6IFs4LDJdLCBcIjgsMlwiLCBcIls4LDJdXCJcbiAgICogICAgTWl4ZWQ6IFs4LFwiMiVcIl0sIFtcIjhweFwiLFwiMiVcIl0sIFwiOCwyJVwiLCBcIls4LDIlXVwiXG4gICAqXG4gICAqIEBtZW1iZXJPZiBIZWF0TWFwQ29tcG9uZW50XG4gICAqL1xuICBnZXREaW1lbnNpb24odmFsdWU6IHN0cmluZyB8IG51bWJlciB8IEFycmF5PHN0cmluZyB8IG51bWJlcj4sIGluZGV4OiBudW1iZXIgPSAwLCBOOiBudW1iZXIsIEw6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHZhbHVlID0gdmFsdWVcbiAgICAgICAgLnJlcGxhY2UoJ1snLCAnJylcbiAgICAgICAgLnJlcGxhY2UoJ10nLCAnJylcbiAgICAgICAgLnJlcGxhY2UoJ3B4JywgJycpXG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogcXVvdGVtYXJrXG4gICAgICAgIC5yZXBsYWNlKFwiJ1wiLCAnJyk7XG5cbiAgICAgIGlmICh2YWx1ZS5pbmNsdWRlcygnLCcpKSB7XG4gICAgICAgIHZhbHVlID0gdmFsdWUuc3BsaXQoJywnKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpICYmIHR5cGVvZiBpbmRleCA9PT0gJ251bWJlcicpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldERpbWVuc2lvbih2YWx1ZVtpbmRleF0sIG51bGwsIE4sIEwpO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyAmJiB2YWx1ZS5pbmNsdWRlcygnJScpKSB7XG4gICAgICByZXR1cm4gK3ZhbHVlLnJlcGxhY2UoJyUnLCAnJykgLyAxMDA7XG4gICAgfVxuICAgIHJldHVybiBOIC8gKEwgLyArdmFsdWUgKyAxKTtcbiAgfVxuXG4gIGdldFhTY2FsZSgpOiBhbnkge1xuICAgIGNvbnN0IGYgPSB0aGlzLmdldERpbWVuc2lvbih0aGlzLmlubmVyUGFkZGluZywgMCwgdGhpcy54RG9tYWluLmxlbmd0aCwgdGhpcy5kaW1zLndpZHRoKTtcbiAgICByZXR1cm4gc2NhbGVCYW5kKCkucmFuZ2VSb3VuZChbMCwgdGhpcy5kaW1zLndpZHRoXSkuZG9tYWluKHRoaXMueERvbWFpbikucGFkZGluZ0lubmVyKGYpO1xuICB9XG5cbiAgZ2V0WVNjYWxlKCk6IGFueSB7XG4gICAgY29uc3QgZiA9IHRoaXMuZ2V0RGltZW5zaW9uKHRoaXMuaW5uZXJQYWRkaW5nLCAxLCB0aGlzLnlEb21haW4ubGVuZ3RoLCB0aGlzLmRpbXMuaGVpZ2h0KTtcbiAgICByZXR1cm4gc2NhbGVCYW5kKCkucmFuZ2VSb3VuZChbdGhpcy5kaW1zLmhlaWdodCwgMF0pLmRvbWFpbih0aGlzLnlEb21haW4pLnBhZGRpbmdJbm5lcihmKTtcbiAgfVxuXG4gIGdldFJlY3RzKCk6IFJlY3RJdGVtW10ge1xuICAgIGNvbnN0IHJlY3RzID0gW107XG5cbiAgICB0aGlzLnhEb21haW4ubWFwKHhWYWwgPT4ge1xuICAgICAgdGhpcy55RG9tYWluLm1hcCh5VmFsID0+IHtcbiAgICAgICAgcmVjdHMucHVzaCh7XG4gICAgICAgICAgeDogdGhpcy54U2NhbGUoeFZhbCksXG4gICAgICAgICAgeTogdGhpcy55U2NhbGUoeVZhbCksXG4gICAgICAgICAgcng6IDMsXG4gICAgICAgICAgd2lkdGg6IHRoaXMueFNjYWxlLmJhbmR3aWR0aCgpLFxuICAgICAgICAgIGhlaWdodDogdGhpcy55U2NhbGUuYmFuZHdpZHRoKCksXG4gICAgICAgICAgZmlsbDogJ3JnYmEoMjAwLDIwMCwyMDAsMC4wMyknXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gcmVjdHM7XG4gIH1cblxuICBvbkNsaWNrKGRhdGEpOiB2b2lkIHtcbiAgICB0aGlzLnNlbGVjdC5lbWl0KGRhdGEpO1xuICB9XG5cbiAgc2V0Q29sb3JzKCk6IHZvaWQge1xuICAgIHRoaXMuY29sb3JzID0gbmV3IENvbG9ySGVscGVyKHRoaXMuc2NoZW1lLCB0aGlzLnNjYWxlVHlwZSwgdGhpcy52YWx1ZURvbWFpbik7XG4gIH1cblxuICBnZXRMZWdlbmRPcHRpb25zKCk6IExlZ2VuZE9wdGlvbnMge1xuICAgIHJldHVybiB7XG4gICAgICBzY2FsZVR5cGU6IHRoaXMuc2NhbGVUeXBlLFxuICAgICAgZG9tYWluOiB0aGlzLnZhbHVlRG9tYWluLFxuICAgICAgY29sb3JzOiB0aGlzLnNjYWxlVHlwZSA9PT0gU2NhbGVUeXBlLk9yZGluYWwgPyB0aGlzLmNvbG9ycyA6IHRoaXMuY29sb3JzLnNjYWxlLFxuICAgICAgdGl0bGU6IHRoaXMuc2NhbGVUeXBlID09PSBTY2FsZVR5cGUuT3JkaW5hbCA/IHRoaXMubGVnZW5kVGl0bGUgOiB1bmRlZmluZWQsXG4gICAgICBwb3NpdGlvbjogdGhpcy5sZWdlbmRQb3NpdGlvblxuICAgIH07XG4gIH1cblxuICB1cGRhdGVZQXhpc1dpZHRoKHsgd2lkdGggfTogeyB3aWR0aDogbnVtYmVyIH0pOiB2b2lkIHtcbiAgICB0aGlzLnlBeGlzV2lkdGggPSB3aWR0aDtcbiAgICB0aGlzLnVwZGF0ZSgpO1xuICB9XG5cbiAgdXBkYXRlWEF4aXNIZWlnaHQoeyBoZWlnaHQgfTogeyBoZWlnaHQ6IG51bWJlciB9KTogdm9pZCB7XG4gICAgdGhpcy54QXhpc0hlaWdodCA9IGhlaWdodDtcbiAgICB0aGlzLnVwZGF0ZSgpO1xuICB9XG5cbiAgb25BY3RpdmF0ZShldmVudCwgZ3JvdXAsIGZyb21MZWdlbmQ6IGJvb2xlYW4gPSBmYWxzZSkge1xuICAgIGNvbnN0IGl0ZW0gPSBPYmplY3QuYXNzaWduKHt9LCBldmVudCk7XG4gICAgaWYgKGdyb3VwKSB7XG4gICAgICBpdGVtLnNlcmllcyA9IGdyb3VwLm5hbWU7XG4gICAgfVxuXG4gICAgY29uc3QgaXRlbXMgPSB0aGlzLnJlc3VsdHNcbiAgICAgIC5tYXAoZyA9PiBnLnNlcmllcylcbiAgICAgIC5mbGF0KClcbiAgICAgIC5maWx0ZXIoaSA9PiB7XG4gICAgICAgIGlmIChmcm9tTGVnZW5kKSB7XG4gICAgICAgICAgcmV0dXJuIGkubGFiZWwgPT09IGl0ZW0ubmFtZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gaS5uYW1lID09PSBpdGVtLm5hbWUgJiYgaS5zZXJpZXMgPT09IGl0ZW0uc2VyaWVzO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgIHRoaXMuYWN0aXZlRW50cmllcyA9IFsuLi5pdGVtc107XG4gICAgdGhpcy5hY3RpdmF0ZS5lbWl0KHsgdmFsdWU6IGl0ZW0sIGVudHJpZXM6IHRoaXMuYWN0aXZlRW50cmllcyB9KTtcbiAgfVxuXG4gIG9uRGVhY3RpdmF0ZShldmVudCwgZ3JvdXAsIGZyb21MZWdlbmQ6IGJvb2xlYW4gPSBmYWxzZSkge1xuICAgIGNvbnN0IGl0ZW0gPSBPYmplY3QuYXNzaWduKHt9LCBldmVudCk7XG4gICAgaWYgKGdyb3VwKSB7XG4gICAgICBpdGVtLnNlcmllcyA9IGdyb3VwLm5hbWU7XG4gICAgfVxuXG4gICAgdGhpcy5hY3RpdmVFbnRyaWVzID0gdGhpcy5hY3RpdmVFbnRyaWVzLmZpbHRlcihpID0+IHtcbiAgICAgIGlmIChmcm9tTGVnZW5kKSB7XG4gICAgICAgIHJldHVybiBpLmxhYmVsICE9PSBpdGVtLm5hbWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gIShpLm5hbWUgPT09IGl0ZW0ubmFtZSAmJiBpLnNlcmllcyA9PT0gaXRlbS5zZXJpZXMpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdGhpcy5kZWFjdGl2YXRlLmVtaXQoeyB2YWx1ZTogaXRlbSwgZW50cmllczogdGhpcy5hY3RpdmVFbnRyaWVzIH0pO1xuICB9XG59XG4iXX0= |
\ | No newline at end of file |