UNPKG

52.7 kBJavaScriptView Raw
1import { Component, Input, Output, EventEmitter, ViewEncapsulation, ChangeDetectionStrategy, ContentChild } from '@angular/core';
2import { trigger, style, animate, transition } from '@angular/animations';
3import { scaleLinear, scaleTime, scalePoint } from 'd3-scale';
4import { curveCardinalClosed } from 'd3-shape';
5import { calculateViewDimensions } from '../common/view-dimensions.helper';
6import { ColorHelper } from '../common/color.helper';
7import { BaseChartComponent } from '../common/base-chart.component';
8import { getScaleType } from '../common/domain.helper';
9import { isDate } from '../utils/types';
10import { LegendPosition } from '../common/types/legend.model';
11import { ScaleType } from '../common/types/scale-type.enum';
12import { Orientation } from '../common/types/orientation.enum';
13const twoPI = 2 * Math.PI;
14export class PolarChartComponent extends BaseChartComponent {
15 constructor() {
16 super(...arguments);
17 this.legendTitle = 'Legend';
18 this.legendPosition = LegendPosition.Right;
19 this.showGridLines = true;
20 this.curve = curveCardinalClosed;
21 this.activeEntries = [];
22 this.rangeFillOpacity = 0.15;
23 this.trimYAxisTicks = true;
24 this.maxYAxisTickLength = 16;
25 this.roundDomains = false;
26 this.tooltipDisabled = false;
27 this.showSeriesOnHover = true;
28 this.gradient = false;
29 this.yAxisMinScale = 0;
30 this.labelTrim = true;
31 this.labelTrimSize = 10;
32 this.activate = new EventEmitter();
33 this.deactivate = new EventEmitter();
34 // series: any; // ???
35 this.margin = [10, 20, 10, 20];
36 this.xAxisHeight = 0;
37 this.yAxisWidth = 0;
38 this.orientation = Orientation;
39 }
40 update() {
41 super.update();
42 this.setDims();
43 this.setScales();
44 this.setColors();
45 this.legendOptions = this.getLegendOptions();
46 this.setTicks();
47 }
48 setDims() {
49 this.dims = calculateViewDimensions({
50 width: this.width,
51 height: this.height,
52 margins: this.margin,
53 showXAxis: this.xAxis,
54 showYAxis: this.yAxis,
55 xAxisHeight: this.xAxisHeight,
56 yAxisWidth: this.yAxisWidth,
57 showXLabel: this.showXAxisLabel,
58 showYLabel: this.showYAxisLabel,
59 showLegend: this.legend,
60 legendType: this.schemeType,
61 legendPosition: this.legendPosition
62 });
63 const halfWidth = Math.floor(this.dims.width / 2);
64 const halfHeight = Math.floor(this.dims.height / 2);
65 const outerRadius = (this.outerRadius = Math.min(halfHeight / 1.5, halfWidth / 1.5));
66 const yOffset = Math.max(0, halfHeight - outerRadius);
67 this.yAxisDims = Object.assign(Object.assign({}, this.dims), { width: halfWidth });
68 this.transform = `translate(${this.dims.xOffset}, ${this.margin[0]})`;
69 this.transformYAxis = `translate(0, ${yOffset})`;
70 this.labelOffset = this.dims.height + 40;
71 this.transformPlot = `translate(${halfWidth}, ${halfHeight})`;
72 }
73 setScales() {
74 const xValues = this.getXValues();
75 this.scaleType = getScaleType(xValues);
76 this.xDomain = this.filteredDomain || this.getXDomain(xValues);
77 this.yDomain = this.getYDomain();
78 this.seriesDomain = this.getSeriesDomain();
79 this.xScale = this.getXScale(this.xDomain, twoPI);
80 this.yScale = this.getYScale(this.yDomain, this.outerRadius);
81 this.yAxisScale = this.getYScale(this.yDomain.reverse(), this.outerRadius);
82 }
83 setTicks() {
84 let tickFormat;
85 if (this.xAxisTickFormatting) {
86 tickFormat = this.xAxisTickFormatting;
87 }
88 else if (this.xScale.tickFormat) {
89 tickFormat = this.xScale.tickFormat.apply(this.xScale, [5]);
90 }
91 else {
92 tickFormat = d => {
93 if (isDate(d)) {
94 return d.toLocaleDateString();
95 }
96 return d.toLocaleString();
97 };
98 }
99 const outerRadius = this.outerRadius;
100 const s = 1.1;
101 this.thetaTicks = this.xDomain.map(d => {
102 const startAngle = this.xScale(d);
103 const dd = s * outerRadius * (startAngle > Math.PI ? -1 : 1);
104 const label = tickFormat(d);
105 const startPos = [outerRadius * Math.sin(startAngle), -outerRadius * Math.cos(startAngle)];
106 const pos = [dd, s * startPos[1]];
107 return {
108 innerRadius: 0,
109 outerRadius,
110 startAngle,
111 endAngle: startAngle,
112 value: outerRadius,
113 label,
114 startPos,
115 pos
116 };
117 });
118 const minDistance = 10;
119 /* from pie chart, abstract out -*/
120 for (let i = 0; i < this.thetaTicks.length - 1; i++) {
121 const a = this.thetaTicks[i];
122 for (let j = i + 1; j < this.thetaTicks.length; j++) {
123 const b = this.thetaTicks[j];
124 // if they're on the same side
125 if (b.pos[0] * a.pos[0] > 0) {
126 // if they're overlapping
127 const o = minDistance - Math.abs(b.pos[1] - a.pos[1]);
128 if (o > 0) {
129 // push the second up or down
130 b.pos[1] += Math.sign(b.pos[0]) * o;
131 }
132 }
133 }
134 }
135 this.radiusTicks = this.yAxisScale.ticks(Math.floor(this.dims.height / 50)).map(d => this.yScale(d));
136 }
137 getXValues() {
138 const values = [];
139 for (const results of this.results) {
140 for (const d of results.series) {
141 if (!values.includes(d.name)) {
142 values.push(d.name);
143 }
144 }
145 }
146 return values;
147 }
148 getXDomain(values = this.getXValues()) {
149 if (this.scaleType === ScaleType.Time) {
150 const min = Math.min(...values);
151 const max = Math.max(...values);
152 return [min, max];
153 }
154 else if (this.scaleType === ScaleType.Linear) {
155 values = values.map(v => Number(v));
156 const min = Math.min(...values);
157 const max = Math.max(...values);
158 return [min, max];
159 }
160 return values;
161 }
162 getYValues() {
163 const domain = [];
164 for (const results of this.results) {
165 for (const d of results.series) {
166 if (domain.indexOf(d.value) < 0) {
167 domain.push(d.value);
168 }
169 if (d.min !== undefined) {
170 if (domain.indexOf(d.min) < 0) {
171 domain.push(d.min);
172 }
173 }
174 if (d.max !== undefined) {
175 if (domain.indexOf(d.max) < 0) {
176 domain.push(d.max);
177 }
178 }
179 }
180 }
181 return domain;
182 }
183 getYDomain(domain = this.getYValues()) {
184 let min = Math.min(...domain);
185 const max = Math.max(this.yAxisMinScale, ...domain);
186 min = Math.max(0, min);
187 if (!this.autoScale) {
188 min = Math.min(0, min);
189 }
190 return [min, max];
191 }
192 getSeriesDomain() {
193 return this.results.map(d => d.name);
194 }
195 getXScale(domain, width) {
196 switch (this.scaleType) {
197 case ScaleType.Time:
198 return scaleTime().range([0, width]).domain(domain);
199 case ScaleType.Linear:
200 const scale = scaleLinear().range([0, width]).domain(domain);
201 return this.roundDomains ? scale.nice() : scale;
202 default:
203 return scalePoint()
204 .range([0, width - twoPI / domain.length])
205 .padding(0)
206 .domain(domain);
207 }
208 }
209 getYScale(domain, height) {
210 const scale = scaleLinear().range([0, height]).domain(domain);
211 return this.roundDomains ? scale.nice() : scale;
212 }
213 onClick(data, series) {
214 if (series) {
215 data.series = series.name;
216 }
217 this.select.emit(data);
218 }
219 setColors() {
220 const domain = this.schemeType === ScaleType.Ordinal ? this.seriesDomain : this.yDomain.reverse();
221 this.colors = new ColorHelper(this.scheme, this.schemeType, domain, this.customColors);
222 }
223 getLegendOptions() {
224 if (this.schemeType === ScaleType.Ordinal) {
225 return {
226 scaleType: this.schemeType,
227 colors: this.colors,
228 domain: this.seriesDomain,
229 title: this.legendTitle,
230 position: this.legendPosition
231 };
232 }
233 return {
234 scaleType: this.schemeType,
235 colors: this.colors.scale,
236 domain: this.yDomain,
237 title: undefined,
238 position: this.legendPosition
239 };
240 }
241 updateYAxisWidth({ width }) {
242 this.yAxisWidth = width;
243 this.update();
244 }
245 updateXAxisHeight({ height }) {
246 this.xAxisHeight = height;
247 this.update();
248 }
249 onActivate(item) {
250 const idx = this.activeEntries.findIndex(d => {
251 return d.name === item.name && d.value === item.value;
252 });
253 if (idx > -1) {
254 return;
255 }
256 this.activeEntries = this.showSeriesOnHover ? [item, ...this.activeEntries] : this.activeEntries;
257 this.activate.emit({ value: item, entries: this.activeEntries });
258 }
259 onDeactivate(item) {
260 const idx = this.activeEntries.findIndex(d => {
261 return d.name === item.name && d.value === item.value;
262 });
263 this.activeEntries.splice(idx, 1);
264 this.activeEntries = [...this.activeEntries];
265 this.deactivate.emit({ value: item, entries: this.activeEntries });
266 }
267 deactivateAll() {
268 this.activeEntries = [...this.activeEntries];
269 for (const entry of this.activeEntries) {
270 this.deactivate.emit({ value: entry, entries: [] });
271 }
272 this.activeEntries = [];
273 }
274 trackBy(index, item) {
275 return `${item.name}`;
276 }
277}
278PolarChartComponent.decorators = [
279 { type: Component, args: [{
280 selector: 'ngx-charts-polar-chart',
281 template: `
282 <ngx-charts-chart
283 [view]="[width, height]"
284 [showLegend]="legend"
285 [legendOptions]="legendOptions"
286 [activeEntries]="activeEntries"
287 [animations]="animations"
288 (legendLabelClick)="onClick($event)"
289 (legendLabelActivate)="onActivate($event)"
290 (legendLabelDeactivate)="onDeactivate($event)"
291 >
292 <svg:g class="polar-chart chart" [attr.transform]="transform">
293 <svg:g [attr.transform]="transformPlot">
294 <svg:circle class="polar-chart-background" cx="0" cy="0" [attr.r]="this.outerRadius" />
295 <svg:g *ngIf="showGridLines">
296 <svg:circle
297 *ngFor="let r of radiusTicks"
298 class="gridline-path radial-gridline-path"
299 cx="0"
300 cy="0"
301 [attr.r]="r"
302 />
303 </svg:g>
304 <svg:g *ngIf="xAxis">
305 <svg:g
306 ngx-charts-pie-label
307 *ngFor="let tick of thetaTicks"
308 [data]="tick"
309 [radius]="outerRadius"
310 [label]="tick.label"
311 [max]="outerRadius"
312 [value]="showGridLines ? 1 : outerRadius"
313 [explodeSlices]="true"
314 [animations]="animations"
315 [labelTrim]="labelTrim"
316 [labelTrimSize]="labelTrimSize"
317 ></svg:g>
318 </svg:g>
319 </svg:g>
320 <svg:g
321 ngx-charts-y-axis
322 [attr.transform]="transformYAxis"
323 *ngIf="yAxis"
324 [yScale]="yAxisScale"
325 [dims]="yAxisDims"
326 [showGridLines]="showGridLines"
327 [showLabel]="showYAxisLabel"
328 [labelText]="yAxisLabel"
329 [trimTicks]="trimYAxisTicks"
330 [maxTickLength]="maxYAxisTickLength"
331 [tickFormatting]="yAxisTickFormatting"
332 (dimensionsChanged)="updateYAxisWidth($event)"
333 ></svg:g>
334 <svg:g
335 ngx-charts-axis-label
336 *ngIf="xAxis && showXAxisLabel"
337 [label]="xAxisLabel"
338 [offset]="labelOffset"
339 [orient]="orientation.Bottom"
340 [height]="dims.height"
341 [width]="dims.width"
342 ></svg:g>
343 <svg:g [attr.transform]="transformPlot">
344 <svg:g *ngFor="let series of results; trackBy: trackBy" [@animationState]="'active'">
345 <svg:g
346 ngx-charts-polar-series
347 [gradient]="gradient"
348 [xScale]="xScale"
349 [yScale]="yScale"
350 [colors]="colors"
351 [data]="series"
352 [activeEntries]="activeEntries"
353 [scaleType]="scaleType"
354 [curve]="curve"
355 [rangeFillOpacity]="rangeFillOpacity"
356 [animations]="animations"
357 [tooltipDisabled]="tooltipDisabled"
358 [tooltipTemplate]="tooltipTemplate"
359 (select)="onClick($event)"
360 (activate)="onActivate($event)"
361 (deactivate)="onDeactivate($event)"
362 />
363 </svg:g>
364 </svg:g>
365 </svg:g>
366 </ngx-charts-chart>
367 `,
368 encapsulation: ViewEncapsulation.None,
369 changeDetection: ChangeDetectionStrategy.OnPush,
370 animations: [
371 trigger('animationState', [
372 transition(':leave', [
373 style({
374 opacity: 1
375 }),
376 animate(500, style({
377 opacity: 0
378 }))
379 ])
380 ])
381 ],
382 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)}", ".pie-label{font-size:11px}.pie-label.animation{-webkit-animation:fadeIn .75s ease-in;animation:fadeIn .75s ease-in}@-webkit-keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.pie-label-line{stroke-dasharray:100%}.pie-label-line.animation{-webkit-animation:drawOut 3s linear;animation:drawOut 3s linear;transition:d .75s}@-webkit-keyframes drawOut{0%{stroke-dashoffset:100%}to{stroke-dashoffset:0}}@keyframes drawOut{0%{stroke-dashoffset:100%}to{stroke-dashoffset:0}}", ".polar-chart .polar-chart-background{fill:none}.polar-chart .radial-gridline-path{stroke-dasharray:10 10;fill:none}.polar-chart .pie-label-line{stroke:#2f3646}.polar-charts-series .polar-series-area,.polar-series-path{pointer-events:none}"]
383 },] }
384];
385PolarChartComponent.propDecorators = {
386 legend: [{ type: Input }],
387 legendTitle: [{ type: Input }],
388 legendPosition: [{ type: Input }],
389 xAxis: [{ type: Input }],
390 yAxis: [{ type: Input }],
391 showXAxisLabel: [{ type: Input }],
392 showYAxisLabel: [{ type: Input }],
393 xAxisLabel: [{ type: Input }],
394 yAxisLabel: [{ type: Input }],
395 autoScale: [{ type: Input }],
396 showGridLines: [{ type: Input }],
397 curve: [{ type: Input }],
398 activeEntries: [{ type: Input }],
399 schemeType: [{ type: Input }],
400 rangeFillOpacity: [{ type: Input }],
401 trimYAxisTicks: [{ type: Input }],
402 maxYAxisTickLength: [{ type: Input }],
403 xAxisTickFormatting: [{ type: Input }],
404 yAxisTickFormatting: [{ type: Input }],
405 roundDomains: [{ type: Input }],
406 tooltipDisabled: [{ type: Input }],
407 showSeriesOnHover: [{ type: Input }],
408 gradient: [{ type: Input }],
409 yAxisMinScale: [{ type: Input }],
410 labelTrim: [{ type: Input }],
411 labelTrimSize: [{ type: Input }],
412 activate: [{ type: Output }],
413 deactivate: [{ type: Output }],
414 tooltipTemplate: [{ type: ContentChild, args: ['tooltipTemplate',] }]
415};
416//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9sYXItY2hhcnQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc3dpbWxhbmUvbmd4LWNoYXJ0cy9zcmMvbGliL3BvbGFyLWNoYXJ0L3BvbGFyLWNoYXJ0LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULEtBQUssRUFDTCxNQUFNLEVBQ04sWUFBWSxFQUNaLGlCQUFpQixFQUNqQix1QkFBdUIsRUFDdkIsWUFBWSxFQUViLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUMxRSxPQUFPLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDOUQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sVUFBVSxDQUFDO0FBRS9DLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQzNFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDdkQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3hDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFNUQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBRS9ELE1BQU0sS0FBSyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDO0FBa0gxQixNQUFNLE9BQU8sbUJBQW9CLFNB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aW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBJbnB1dCxcbiAgT3V0cHV0LFxuICBFdmVudEVtaXR0ZXIsXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ29udGVudENoaWxkLFxuICBUZW1wbGF0ZVJlZlxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHRyaWdnZXIsIHN0eWxlLCBhbmltYXRlLCB0cmFuc2l0aW9uIH0gZnJvbSAnQGFuZ3VsYXIvYW5pbWF0aW9ucyc7XG5pbXBvcnQgeyBzY2FsZUxpbmVhciwgc2NhbGVUaW1lLCBzY2FsZVBvaW50IH0gZnJvbSAnZDMtc2NhbGUnO1xuaW1wb3J0IHsgY3VydmVDYXJkaW5hbENsb3NlZCB9IGZyb20gJ2QzLXNoYXBlJztcblxuaW1wb3J0IHsgY2FsY3VsYXRlVmlld0RpbWVuc2lvbnMgfSBmcm9tICcuLi9jb21tb24vdmlldy1kaW1lbnNpb25zLmhlbHBlcic7XG5pbXBvcnQgeyBDb2xvckhlbHBlciB9IGZyb20gJy4uL2NvbW1vbi9jb2xvci5oZWxwZXInO1xuaW1wb3J0IHsgQmFzZUNoYXJ0Q29tcG9uZW50IH0gZnJvbSAnLi4vY29tbW9uL2Jhc2UtY2hhcnQuY29tcG9uZW50JztcbmltcG9ydCB7IGdldFNjYWxlVHlwZSB9IGZyb20gJy4uL2NvbW1vbi9kb21haW4uaGVscGVyJztcbmltcG9ydCB7IGlzRGF0ZSB9IGZyb20gJy4uL3V0aWxzL3R5cGVzJztcbmltcG9ydCB7IExlZ2VuZFBvc2l0aW9uIH0gZnJvbSAnLi4vY29tbW9uL3R5cGVzL2xlZ2VuZC5tb2RlbCc7XG5pbXBvcnQgeyBTY2FsZVR5cGUgfSBmcm9tICcuLi9jb21tb24vdHlwZXMvc2NhbGUtdHlwZS5lbnVtJztcbmltcG9ydCB7IFZpZXdEaW1lbnNpb25zIH0gZnJvbSAnLi4vY29tbW9uL3R5cGVzL3ZpZXctZGltZW5zaW9uLmludGVyZmFjZSc7XG5pbXBvcnQgeyBPcmllbnRhdGlvbiB9IGZyb20gJy4uL2NvbW1vbi90eXBlcy9vcmllbnRhdGlvbi5lbnVtJztcblxuY29uc3QgdHdvUEkgPSAyICogTWF0aC5QSTtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmd4LWNoYXJ0cy1wb2xhci1jaGFydCcsXG4gIHRlbXBsYXRlOiBgXG4gICAgPG5neC1jaGFydHMtY2hhcnRcbiAgICAgIFt2aWV3XT1cIlt3aWR0aCwgaGVpZ2h0XVwiXG4gICAgICBbc2hvd0xlZ2VuZF09XCJsZWdlbmRcIlxuICAgICAgW2xlZ2VuZE9wdGlvbnNdPVwibGVnZW5kT3B0aW9uc1wiXG4gICAgICBbYWN0aXZlRW50cmllc109XCJhY3RpdmVFbnRyaWVzXCJcbiAgICAgIFthbmltYXRpb25zXT1cImFuaW1hdGlvbnNcIlxuICAgICAgKGxlZ2VuZExhYmVsQ2xpY2spPVwib25DbGljaygkZXZlbnQpXCJcbiAgICAgIChsZWdlbmRMYWJlbEFjdGl2YXRlKT1cIm9uQWN0aXZhdGUoJGV2ZW50KVwiXG4gICAgICAobGVnZW5kTGFiZWxEZWFjdGl2YXRlKT1cIm9uRGVhY3RpdmF0ZSgkZXZlbnQpXCJcbiAgICA+XG4gICAgICA8c3ZnOmcgY2xhc3M9XCJwb2xhci1jaGFydCBjaGFydFwiIFthdHRyLnRyYW5zZm9ybV09XCJ0cmFuc2Zvcm1cIj5cbiAgICAgICAgPHN2ZzpnIFthdHRyLnRyYW5zZm9ybV09XCJ0cmFuc2Zvcm1QbG90XCI+XG4gICAgICAgICAgPHN2ZzpjaXJjbGUgY2xhc3M9XCJwb2xhci1jaGFydC1iYWNrZ3JvdW5kXCIgY3g9XCIwXCIgY3k9XCIwXCIgW2F0dHIucl09XCJ0aGlzLm91dGVyUmFkaXVzXCIgLz5cbiAgICAgICAgICA8c3ZnOmcgKm5nSWY9XCJzaG93R3JpZExpbmVzXCI+XG4gICAgICAgICAgICA8c3ZnOmNpcmNsZVxuICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgciBvZiByYWRpdXNUaWNrc1wiXG4gICAgICAgICAgICAgIGNsYXNzPVwiZ3JpZGxpbmUtcGF0aCByYWRpYWwtZ3JpZGxpbmUtcGF0aFwiXG4gICAgICAgICAgICAgIGN4PVwiMFwiXG4gICAgICAgICAgICAgIGN5PVwiMFwiXG4gICAgICAgICAgICAgIFthdHRyLnJdPVwiclwiXG4gICAgICAgICAgICAvPlxuICAgICAgICAgIDwvc3ZnOmc+XG4gICAgICAgICAgPHN2ZzpnICpuZ0lmPVwieEF4aXNcIj5cbiAgICAgICAgICAgIDxzdmc6Z1xuICAgICAgICAgICAgICBuZ3gtY2hhcnRzLXBpZS1sYWJlbFxuICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgdGljayBvZiB0aGV0YVRpY2tzXCJcbiAgICAgICAgICAgICAgW2RhdGFdPVwidGlja1wiXG4gICAgICAgICAgICAgIFtyYWRpdXNdPVwib3V0ZXJSYWRpdXNcIlxuICAgICAgICAgICAgICBbbGFiZWxdPVwidGljay5sYWJlbFwiXG4gICAgICAgICAgICAgIFttYXhdPVwib3V0ZXJSYWRpdXNcIlxuICAgICAgICAgICAgICBbdmFsdWVdPVwic2hvd0dyaWRMaW5lcyA/IDEgOiBvdXRlclJhZGl1c1wiXG4gICAgICAgICAgICAgIFtleHBsb2RlU2xpY2VzXT1cInRydWVcIlxuICAgICAgICAgICAgICBbYW5pbWF0aW9uc109XCJhbmltYXRpb25zXCJcbiAgICAgICAgICAgICAgW2xhYmVsVHJpbV09XCJsYWJlbFRyaW1cIlxuICAgICAgICAgICAgICBbbGFiZWxUcmltU2l6ZV09XCJsYWJlbFRyaW1TaXplXCJcbiAgICAgICAgICAgID48L3N2ZzpnPlxuICAgICAgICAgIDwvc3ZnOmc+XG4gICAgICAgIDwvc3ZnOmc+XG4gICAgICAgIDxzdmc6Z1xuICAgICAgICAgIG5neC1jaGFydHMteS1heGlzXG4gICAgICAgICAgW2F0dHIudHJhbnNmb3JtXT1cInRyYW5zZm9ybVlBeGlzXCJcbiAgICAgICAgICAqbmdJZj1cInlBeGlzXCJcbiAgICAgICAgICBbeVNjYWxlXT1cInlBeGlzU2NhbGVcIlxuICAgICAgICAgIFtkaW1zXT1cInlBeGlzRGltc1wiXG4gICAgICAgICAgW3Nob3dHcmlkTGluZXNdPVwic2hvd0dyaWRMaW5lc1wiXG4gICAgICAgICAgW3Nob3dMYWJlbF09XCJzaG93WUF4aXNMYWJlbFwiXG4gICAgICAgICAgW2xhYmVsVGV4dF09XCJ5QXhpc0xhYmVsXCJcbiAgICAgICAgICBbdHJpbVRpY2tzXT1cInRyaW1ZQXhpc1RpY2tzXCJcbiAgICAgICAgICBbbWF4VGlja0xlbmd0aF09XCJtYXhZQXhpc1RpY2tMZW5ndGhcIlxuICAgICAgICAgIFt0aWNrRm9ybWF0dGluZ109XCJ5QXhpc1RpY2tGb3JtYXR0aW5nXCJcbiAgICAgICAgICAoZGltZW5zaW9uc0NoYW5nZWQpPVwidXBkYXRlWUF4aXNXaWR0aCgkZXZlbnQpXCJcbiAgICAgICAgPjwvc3ZnOmc+XG4gICAgICAgIDxzdmc6Z1xuICAgICAgICAgIG5neC1jaGFydHMtYXhpcy1sYWJlbFxuICAgICAgICAgICpuZ0lmPVwieEF4aXMgJiYgc2hvd1hBeGlzTGFiZWxcIlxuICAgICAgICAgIFtsYWJlbF09XCJ4QXhpc0xhYmVsXCJcbiAgICAgICAgICBbb2Zmc2V0XT1cImxhYmVsT2Zmc2V0XCJcbiAgICAgICAgICBbb3JpZW50XT1cIm9yaWVudGF0aW9uLkJvdHRvbVwiXG4gICAgICAgICAgW2hlaWdodF09XCJkaW1zLmhlaWdodFwiXG4gICAgICAgICAgW3dpZHRoXT1cImRpbXMud2lkdGhcIlxuICAgICAgICA+PC9zdmc6Zz5cbiAgICAgICAgPHN2ZzpnIFthdHRyLnRyYW5zZm9ybV09XCJ0cmFuc2Zvcm1QbG90XCI+XG4gICAgICAgICAgPHN2ZzpnICpuZ0Zvcj1cImxldCBzZXJpZXMgb2YgcmVzdWx0czsgdHJhY2tCeTogdHJhY2tCeVwiIFtAYW5pbWF0aW9uU3RhdGVdPVwiJ2FjdGl2ZSdcIj5cbiAgICAgICAgICAgIDxzdmc6Z1xuICAgICAgICAgICAgICBuZ3gtY2hhcnRzLXBvbGFyLXNlcmllc1xuICAgICAgICAgICAgICBbZ3JhZGllbnRdPVwiZ3JhZGllbnRcIlxuICAgICAgICAgICAgICBbeFNjYWxlXT1cInhTY2FsZVwiXG4gICAgICAgICAgICAgIFt5U2NhbGVdPVwieVNjYWxlXCJcbiAgICAgICAgICAgICAgW2NvbG9yc109XCJjb2xvcnNcIlxuICAgICAgICAgICAgICBbZGF0YV09XCJzZXJpZXNcIlxuICAgICAgICAgICAgICBbYWN0aXZlRW50cmllc109XCJhY3RpdmVFbnRyaWVzXCJcbiAgICAgICAgICAgICAgW3NjYWxlVHlwZV09XCJzY2FsZVR5cGVcIlxuICAgICAgICAgICAgICBbY3VydmVdPVwiY3VydmVcIlxuICAgICAgICAgICAgICBbcmFuZ2VGaWxsT3BhY2l0eV09XCJyYW5nZUZpbGxPcGFjaXR5XCJcbiAgICAgICAgICAgICAgW2FuaW1hdGlvbnNdPVwiYW5pbWF0aW9uc1wiXG4gICAgICAgICAgICAgIFt0b29sdGlwRGlzYWJsZWRdPVwidG9vbHRpcERpc2FibGVkXCJcbiAgICAgICAgICAgICAgW3Rvb2x0aXBUZW1wbGF0ZV09XCJ0b29sdGlwVGVtcGxhdGVcIlxuICAgICAgICAgICAgICAoc2VsZWN0KT1cIm9uQ2xpY2soJGV2ZW50KVwiXG4gICAgICAgICAgICAgIChhY3RpdmF0ZSk9XCJvbkFjdGl2YXRlKCRldmVudClcIlxuICAgICAgICAgICAgICAoZGVhY3RpdmF0ZSk9XCJvbkRlYWN0aXZhdGUoJGV2ZW50KVwiXG4gICAgICAgICAgICAvPlxuICAgICAgICAgIDwvc3ZnOmc+XG4gICAgICAgIDwvc3ZnOmc+XG4gICAgICA8L3N2ZzpnPlxuICAgIDwvbmd4LWNoYXJ0cy1jaGFydD5cbiAgYCxcbiAgc3R5bGVVcmxzOiBbXG4gICAgJy4uL2NvbW1vbi9iYXNlLWNoYXJ0LmNvbXBvbmVudC5zY3NzJyxcbiAgICAnLi4vcGllLWNoYXJ0L3BpZS1jaGFydC5jb21wb25lbnQuc2NzcycsXG4gICAgJy4vcG9sYXItY2hhcnQuY29tcG9uZW50LnNjc3MnXG4gIF0sXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBhbmltYXRpb25zOiBbXG4gICAgdHJpZ2dlcignYW5pbWF0aW9uU3RhdGUnLCBbXG4gICAgICB0cmFuc2l0aW9uKCc6bGVhdmUnLCBbXG4gICAgICAgIHN0eWxlKHtcbiAgICAgICAgICBvcGFjaXR5OiAxXG4gICAgICAgIH0pLFxuICAgICAgICBhbmltYXRlKFxuICAgICAgICAgIDUwMCxcbiAgICAgICAgICBzdHlsZSh7XG4gICAgICAgICAgICBvcGFjaXR5OiAwXG4gICAgICAgICAgfSlcbiAgICAgICAgKVxuICAgICAgXSlcbiAgICBdKVxuICBdXG59KVxuZXhwb3J0IGNsYXNzIFBvbGFyQ2hhcnRDb21wb25lbnQgZXh0ZW5kcyBCYXNlQ2hhcnRDb21wb25lbnQge1xuICBASW5wdXQoKSBsZWdlbmQ6IGJvb2xlYW47XG4gIEBJbnB1dCgpIGxlZ2VuZFRpdGxlOiBzdHJpbmcgPSAnTGVnZW5kJztcbiAgQElucHV0KCkgbGVnZW5kUG9zaXRpb246IExlZ2VuZFBvc2l0aW9uID0gTGVnZW5kUG9zaXRpb24uUmlnaHQ7XG4gIEBJbnB1dCgpIHhBeGlzOiBib29sZWFuO1xuICBASW5wdXQoKSB5QXhpczogYm9vbGVhbjtcbiAgQElucHV0KCkgc2hvd1hBeGlzTGFiZWw6IGJvb2xlYW47XG4gIEBJbnB1dCgpIHNob3dZQXhpc0xhYmVsOiBib29sZWFuO1xuICBASW5wdXQoKSB4QXhpc0xhYmVsOiBzdHJpbmc7XG4gIEBJbnB1dCgpIHlBeGlzTGFiZWw6IHN0cmluZztcbiAgQElucHV0KCkgYXV0b1NjYWxlOiBib29sZWFuO1xuICBASW5wdXQoKSBzaG93R3JpZExpbmVzOiBib29sZWFuID0gdHJ1ZTtcbiAgQElucHV0KCkgY3VydmU6IGFueSA9IGN1cnZlQ2FyZGluYWxDbG9zZWQ7XG4gIEBJbnB1dCgpIGFjdGl2ZUVudHJpZXM6IGFueVtdID0gW107XG4gIEBJbnB1dCgpIHNjaGVtZVR5cGU6IFNjYWxlVHlwZTtcbiAgQElucHV0KCkgcmFuZ2VGaWxsT3BhY2l0eTogbnVtYmVyID0gMC4xNTtcbiAgQElucHV0KCkgdHJpbVlBeGlzVGlja3M6IGJvb2xlYW4gPSB0cnVlO1xuICBASW5wdXQoKSBtYXhZQXhpc1RpY2tMZW5ndGg6IG51bWJlciA9IDE2O1xuICBASW5wdXQoKSB4QXhpc1RpY2tGb3JtYXR0aW5nOiAobzogYW55KSA9PiBhbnk7XG4gIEBJbnB1dCgpIHlBeGlzVGlja0Zvcm1hdHRpbmc6IChvOiBhbnkpID0+IGFueTtcbiAgQElucHV0KCkgcm91bmREb21haW5zOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIHRvb2x0aXBEaXNhYmxlZDogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBzaG93U2VyaWVzT25Ib3ZlcjogYm9vbGVhbiA9IHRydWU7XG4gIEBJbnB1dCgpIGdyYWRpZW50OiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIHlBeGlzTWluU2NhbGU6IG51bWJlciA9IDA7XG4gIEBJbnB1dCgpIGxhYmVsVHJpbTogYm9vbGVhbiA9IHRydWU7XG4gIEBJbnB1dCgpIGxhYmVsVHJpbVNpemU6IG51bWJlciA9IDEwO1xuXG4gIEBPdXRwdXQoKSBhY3RpdmF0ZTogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBkZWFjdGl2YXRlOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICBAQ29udGVudENoaWxkKCd0b29sdGlwVGVtcGxhdGUnKSB0b29sdGlwVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47XG5cbiAgZGltczogVmlld0RpbWVuc2lvbnM7XG4gIHlBeGlzRGltczogVmlld0RpbWVuc2lvbnM7XG4gIGxhYmVsT2Zmc2V0OiBudW1iZXI7XG4gIHhEb21haW46IGFueTtcbiAgeURvbWFpbjogYW55O1xuICBzZXJpZXNEb21haW46IGFueTtcbiAgeVNjYWxlOiBhbnk7IC8vIC0+IHJTY2FsZVxuICB4U2NhbGU6IGFueTsgLy8gLT4gdFNjYWxlXG4gIHlBeGlzU2NhbGU6IGFueTsgLy8gLT4geVNjYWxlXG4gIGNvbG9yczogQ29sb3JIZWxwZXI7XG4gIHNjYWxlVHlwZTogU2NhbGVUeXBlO1xuICB0cmFuc2Zvcm06IHN0cmluZztcbiAgdHJhbnNmb3JtUGxvdDogc3RyaW5nO1xuICB0cmFuc2Zvcm1ZQXhpczogc3RyaW5nO1xuICB0cmFuc2Zvcm1YQXhpczogc3RyaW5nO1xuICAvLyBzZXJpZXM6IGFueTsgLy8gPz8/XG4gIG1hcmdpbjogbnVtYmVyW10gPSBbMTAsIDIwLCAxMCwgMjBdO1xuICB4QXhpc0hlaWdodDogbnVtYmVyID0gMDtcbiAgeUF4aXNXaWR0aDogbnVtYmVyID0gMDtcbiAgZmlsdGVyZWREb21haW46IGFueTtcbiAgbGVnZW5kT3B0aW9uczogYW55O1xuICB0aGV0YVRpY2tzOiBhbnlbXTtcbiAgcmFkaXVzVGlja3M6IG51bWJlcltdO1xuICBvdXRlclJhZGl1czogbnVtYmVyO1xuXG4gIG9yaWVudGF0aW9uID0gT3JpZW50YXRpb247XG5cbiAgdXBkYXRlKCk6IHZvaWQge1xuICAgIHN1cGVyLnVwZGF0ZSgpO1xuXG4gICAgdGhpcy5zZXREaW1zKCk7XG5cbiAgICB0aGlzLnNldFNjYWxlcygpO1xuICAgIHRoaXMuc2V0Q29sb3JzKCk7XG4gICAgdGhpcy5sZWdlbmRPcHRpb25zID0gdGhpcy5nZXRMZWdlbmRPcHRpb25zKCk7XG5cbiAgICB0aGlzLnNldFRpY2tzKCk7XG4gIH1cblxuICBzZXREaW1zKCkge1xuICAgIHRoaXMuZGltcyA9IGNhbGN1bGF0ZVZpZXdEaW1lbnNpb25zKHtcbiAgICAgIHdpZHRoOiB0aGlzLndpZHRoLFxuICAgICAgaGVpZ2h0OiB0aGlzLmhlaWdodCxcbiAgICAgIG1hcmdpbnM6IHRoaXMubWFyZ2luLFxuICAgICAgc2hvd1hBeGlzOiB0aGlzLnhBeGlzLFxuICAgICAgc2hvd1lBeGlzOiB0aGlzLnlBeGlzLFxuICAgICAgeEF4aXNIZWlnaHQ6IHRoaXMueEF4aXNIZWlnaHQsXG4gICAgICB5QXhpc1dpZHRoOiB0aGlzLnlBeGlzV2lkdGgsXG4gICAgICBzaG93WExhYmVsOiB0aGlzLnNob3dYQXhpc0xhYmVsLFxuICAgICAgc2hvd1lMYWJlbDogdGhpcy5zaG93WUF4aXNMYWJlbCxcbiAgICAgIHNob3dMZWdlbmQ6IHRoaXMubGVnZW5kLFxuICAgICAgbGVnZW5kVHlwZTogdGhpcy5zY2hlbWVUeXBlLFxuICAgICAgbGVnZW5kUG9zaXRpb246IHRoaXMubGVnZW5kUG9zaXRpb25cbiAgICB9KTtcblxuICAgIGNvbnN0IGhhbGZXaWR0aCA9IE1hdGguZmxvb3IodGhpcy5kaW1zLndpZHRoIC8gMik7XG4gICAgY29uc3QgaGFsZkhlaWdodCA9IE1hdGguZmxvb3IodGhpcy5kaW1zLmhlaWdodCAvIDIpO1xuXG4gICAgY29uc3Qgb3V0ZXJSYWRpdXMgPSAodGhpcy5vdXRlclJhZGl1cyA9IE1hdGgubWluKGhhbGZIZWlnaHQgLyAxLjUsIGhhbGZXaWR0aCAvIDEuNSkpO1xuXG4gICAgY29uc3QgeU9mZnNldCA9IE1hdGgubWF4KDAsIGhhbGZIZWlnaHQgLSBvdXRlclJhZGl1cyk7XG5cbiAgICB0aGlzLnlBeGlzRGltcyA9IHtcbiAgICAgIC4uLnRoaXMuZGltcyxcbiAgICAgIHdpZHRoOiBoYWxmV2lkdGhcbiAgICB9O1xuXG4gICAgdGhpcy50cmFuc2Zvcm0gPSBgdHJhbnNsYXRlKCR7dGhpcy5kaW1zLnhPZmZzZXR9LCAke3RoaXMubWFyZ2luWzBdfSlgO1xuICAgIHRoaXMudHJhbnNmb3JtWUF4aXMgPSBgdHJhbnNsYXRlKDAsICR7eU9mZnNldH0pYDtcbiAgICB0aGlzLmxhYmVsT2Zmc2V0ID0gdGhpcy5kaW1zLmhlaWdodCArIDQwO1xuICAgIHRoaXMudHJhbnNmb3JtUGxvdCA9IGB0cmFuc2xhdGUoJHtoYWxmV2lkdGh9LCAke2hhbGZIZWlnaHR9KWA7XG4gIH1cblxuICBzZXRTY2FsZXMoKSB7XG4gICAgY29uc3QgeFZhbHVlcyA9IHRoaXMuZ2V0WFZhbHVlcygpO1xuICAgIHRoaXMuc2NhbGVUeXBlID0gZ2V0U2NhbGVUeXBlKHhWYWx1ZXMpO1xuICAgIHRoaXMueERvbWFpbiA9IHRoaXMuZmlsdGVyZWREb21haW4gfHwgdGhpcy5nZXRYRG9tYWluKHhWYWx1ZXMpO1xuXG4gICAgdGhpcy55RG9tYWluID0gdGhpcy5nZXRZRG9tYWluKCk7XG4gICAgdGhpcy5zZXJpZXNEb21haW4gPSB0aGlzLmdldFNlcmllc0RvbWFpbigpO1xuXG4gICAgdGhpcy54U2NhbGUgPSB0aGlzLmdldFhTY2FsZSh0aGlzLnhEb21haW4sIHR3b1BJKTtcbiAgICB0aGlzLnlTY2FsZSA9IHRoaXMuZ2V0WVNjYWxlKHRoaXMueURvbWFpbiwgdGhpcy5vdXRlclJhZGl1cyk7XG4gICAgdGhpcy55QXhpc1NjYWxlID0gdGhpcy5nZXRZU2NhbGUodGhpcy55RG9tYWluLnJldmVyc2UoKSwgdGhpcy5vdXRlclJhZGl1cyk7XG4gIH1cblxuICBzZXRUaWNrcygpIHtcbiAgICBsZXQgdGlja0Zvcm1hdDtcbiAgICBpZiAodGhpcy54QXhpc1RpY2tGb3JtYXR0aW5nKSB7XG4gICAgICB0aWNrRm9ybWF0ID0gdGhpcy54QXhpc1RpY2tGb3JtYXR0aW5nO1xuICAgIH0gZWxzZSBpZiAodGhpcy54U2NhbGUudGlja0Zvcm1hdCkge1xuICAgICAgdGlja0Zvcm1hdCA9IHRoaXMueFNjYWxlLnRpY2tGb3JtYXQuYXBwbHkodGhpcy54U2NhbGUsIFs1XSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRpY2tGb3JtYXQgPSBkID0+IHtcbiAgICAgICAgaWYgKGlzRGF0ZShkKSkge1xuICAgICAgICAgIHJldHVybiBkLnRvTG9jYWxlRGF0ZVN0cmluZygpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkLnRvTG9jYWxlU3RyaW5nKCk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIGNvbnN0IG91dGVyUmFkaXVzID0gdGhpcy5vdXRlclJhZGl1cztcbiAgICBjb25zdCBzID0gMS4xO1xuXG4gICAgdGhpcy50aGV0YVRpY2tzID0gdGhpcy54RG9tYWluLm1hcChkID0+IHtcbiAgICAgIGNvbnN0IHN0YXJ0QW5nbGUgPSB0aGlzLnhTY2FsZShkKTtcbiAgICAgIGNvbnN0IGRkID0gcyAqIG91dGVyUmFkaXVzICogKHN0YXJ0QW5nbGUgPiBNYXRoLlBJID8gLTEgOiAxKTtcbiAgICAgIGNvbnN0IGxhYmVsID0gdGlja0Zvcm1hdChkKTtcblxuICAgICAgY29uc3Qgc3RhcnRQb3MgPSBbb3V0ZXJSYWRpdXMgKiBNYXRoLnNpbihzdGFydEFuZ2xlKSwgLW91dGVyUmFkaXVzICogTWF0aC5jb3Moc3RhcnRBbmdsZSldO1xuICAgICAgY29uc3QgcG9zID0gW2RkLCBzICogc3RhcnRQb3NbMV1dO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgaW5uZXJSYWRpdXM6IDAsXG4gICAgICAgIG91dGVyUmFkaXVzLFxuICAgICAgICBzdGFydEFuZ2xlLFxuICAgICAgICBlbmRBbmdsZTogc3RhcnRBbmdsZSxcbiAgICAgICAgdmFsdWU6IG91dGVyUmFkaXVzLFxuICAgICAgICBsYWJlbCxcbiAgICAgICAgc3RhcnRQb3MsXG4gICAgICAgIHBvc1xuICAgICAgfTtcbiAgICB9KTtcblxuICAgIGNvbnN0IG1pbkRpc3RhbmNlID0gMTA7XG5cbiAgICAvKiBmcm9tIHBpZSBjaGFydCwgYWJzdHJhY3Qgb3V0IC0qL1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy50aGV0YVRpY2tzLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgY29uc3QgYSA9IHRoaXMudGhldGFUaWNrc1tpXTtcblxuICAgICAgZm9yIChsZXQgaiA9IGkgKyAxOyBqIDwgdGhpcy50aGV0YVRpY2tzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgIGNvbnN0IGIgPSB0aGlzLnRoZXRhVGlja3Nbal07XG4gICAgICAgIC8vIGlmIHRoZXkncmUgb24gdGhlIHNhbWUgc2lkZVxuICAgICAgICBpZiAoYi5wb3NbMF0gKiBhLnBvc1swXSA+IDApIHtcbiAgICAgICAgICAvLyBpZiB0aGV5J3JlIG92ZXJsYXBwaW5nXG4gICAgICAgICAgY29uc3QgbyA9IG1pbkRpc3RhbmNlIC0gTWF0aC5hYnMoYi5wb3NbMV0gLSBhLnBvc1sxXSk7XG4gICAgICAgICAgaWYgKG8gPiAwKSB7XG4gICAgICAgICAgICAvLyBwdXNoIHRoZSBzZWNvbmQgdXAgb3IgZG93blxuICAgICAgICAgICAgYi5wb3NbMV0gKz0gTWF0aC5zaWduKGIucG9zWzBdKSAqIG87XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5yYWRpdXNUaWNrcyA9IHRoaXMueUF4aXNTY2FsZS50aWNrcyhNYXRoLmZsb29yKHRoaXMuZGltcy5oZWlnaHQgLyA1MCkpLm1hcChkID0+IHRoaXMueVNjYWxlKGQpKTtcbiAgfVxuXG4gIGdldFhWYWx1ZXMoKTogYW55W10ge1xuICAgIGNvbnN0IHZhbHVlcyA9IFtdO1xuICAgIGZvciAoY29uc3QgcmVzdWx0cyBvZiB0aGlzLnJlc3VsdHMpIHtcbiAgICAgIGZvciAoY29uc3QgZCBvZiByZXN1bHRzLnNlcmllcykge1xuICAgICAgICBpZiAoIXZhbHVlcy5pbmNsdWRlcyhkLm5hbWUpKSB7XG4gICAgICAgICAgdmFsdWVzLnB1c2goZC5uYW1lKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdmFsdWVzO1xuICB9XG5cbiAgZ2V0WERvbWFpbih2YWx1ZXMgPSB0aGlzLmdldFhWYWx1ZXMoKSk6IGFueVtdIHtcbiAgICBpZiAodGhpcy5zY2FsZVR5cGUgPT09IFNjYWxlVHlwZS5UaW1lKSB7XG4gICAgICBjb25zdCBtaW4gPSBNYXRoLm1pbiguLi52YWx1ZXMpO1xuICAgICAgY29uc3QgbWF4ID0gTWF0aC5tYXgoLi4udmFsdWVzKTtcbiAgICAgIHJldHVybiBbbWluLCBtYXhdO1xuICAgIH0gZWxzZSBpZiAodGhpcy5zY2FsZVR5cGUgPT09IFNjYWxlVHlwZS5MaW5lYXIpIHtcbiAgICAgIHZhbHVlcyA9IHZhbHVlcy5tYXAodiA9PiBOdW1iZXIodikpO1xuICAgICAgY29uc3QgbWluID0gTWF0aC5taW4oLi4udmFsdWVzKTtcbiAgICAgIGNvbnN0IG1heCA9IE1hdGgubWF4KC4uLnZhbHVlcyk7XG4gICAgICByZXR1cm4gW21pbiwgbWF4XTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlcztcbiAgfVxuXG4gIGdldFlWYWx1ZXMoKTogYW55W10ge1xuICAgIGNvbnN0IGRvbWFpbiA9IFtdO1xuXG4gICAgZm9yIChjb25zdCByZXN1bHRzIG9mIHRoaXMucmVzdWx0cykge1xuICAgICAgZm9yIChjb25zdCBkIG9mIHJlc3VsdHMuc2VyaWVzKSB7XG4gICAgICAgIGlmIChkb21haW4uaW5kZXhPZihkLnZhbHVlKSA8IDApIHtcbiAgICAgICAgICBkb21haW4ucHVzaChkLnZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZC5taW4gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGlmIChkb21haW4uaW5kZXhPZihkLm1pbikgPCAwKSB7XG4gICAgICAgICAgICBkb21haW4ucHVzaChkLm1pbik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChkLm1heCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaWYgKGRvbWFpbi5pbmRleE9mKGQubWF4KSA8IDApIHtcbiAgICAgICAgICAgIGRvbWFpbi5wdXNoKGQubWF4KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGRvbWFpbjtcbiAgfVxuXG4gIGdldFlEb21haW4oZG9tYWluID0gdGhpcy5nZXRZVmFsdWVzKCkpOiBhbnlbXSB7XG4gICAgbGV0IG1pbiA9IE1hdGgubWluKC4uLmRvbWFpbik7XG4gICAgY29uc3QgbWF4ID0gTWF0aC5tYXgodGhpcy55QXhpc01pblNjYWxlLCAuLi5kb21haW4pO1xuXG4gICAgbWluID0gTWF0aC5tYXgoMCwgbWluKTtcbiAgICBpZiAoIXRoaXMuYXV0b1NjYWxlKSB7XG4gICAgICBtaW4gPSBNYXRoLm1pbigwLCBtaW4pO1xuICAgIH1cblxuICAgIHJldHVybiBbbWluLCBtYXhdO1xuICB9XG5cbiAgZ2V0U2VyaWVzRG9tYWluKCk6IGFueVtdIHtcbiAgICByZXR1cm4gdGhpcy5yZXN1bHRzLm1hcChkID0+IGQubmFtZSk7XG4gIH1cblxuICBnZXRYU2NhbGUoZG9tYWluLCB3aWR0aDogbnVtYmVyKTogYW55IHtcbiAgICBzd2l0Y2ggKHRoaXMuc2NhbGVUeXBlKSB7XG4gICAgICBjYXNlIFNjYWxlVHlwZS5UaW1lOlxuICAgICAgICByZXR1cm4gc2NhbGVUaW1lKCkucmFuZ2UoWzAsIHdpZHRoXSkuZG9tYWluKGRvbWFpbik7XG4gICAgICBjYXNlIFNjYWxlVHlwZS5MaW5lYXI6XG4gICAgICAgIGNvbnN0IHNjYWxlID0gc2NhbGVMaW5lYXIoKS5yYW5nZShbMCwgd2lkdGhdKS5kb21haW4oZG9tYWluKTtcbiAgICAgICAgcmV0dXJuIHRoaXMucm91bmREb21haW5zID8gc2NhbGUubmljZSgpIDogc2NhbGU7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gc2NhbGVQb2ludCgpXG4gICAgICAgICAgLnJhbmdlKFswLCB3aWR0aCAtIHR3b1BJIC8gZG9tYWluLmxlbmd0aF0pXG4gICAgICAgICAgLnBhZGRpbmcoMClcbiAgICAgICAgICAuZG9tYWluKGRvbWFpbik7XG4gICAgfVxuICB9XG5cbiAgZ2V0WVNjYWxlKGRvbWFpbiwgaGVpZ2h0OiBudW1iZXIpOiBhbnkge1xuICAgIGNvbnN0IHNjYWxlID0gc2NhbGVMaW5lYXIoKS5yYW5nZShbMCwgaGVpZ2h0XSkuZG9tYWluKGRvbWFpbik7XG5cbiAgICByZXR1cm4gdGhpcy5yb3VuZERvbWFpbnMgPyBzY2FsZS5uaWNlKCkgOiBzY2FsZTtcbiAgfVxuXG4gIG9uQ2xpY2soZGF0YSwgc2VyaWVzPyk6IHZvaWQge1xuICAgIGlmIChzZXJpZXMpIHtcbiAgICAgIGRhdGEuc2VyaWVzID0gc2VyaWVzLm5hbWU7XG4gICAgfVxuXG4gICAgdGhpcy5zZWxlY3QuZW1pdChkYXRhKTtcbiAgfVxuXG4gIHNldENvbG9ycygpOiB2b2lkIHtcbiAgICBjb25zdCBkb21haW4gPSB0aGlzLnNjaGVtZVR5cGUgPT09IFNjYWxlVHlwZS5PcmRpbmFsID8gdGhpcy5zZXJpZXNEb21haW4gOiB0aGlzLnlEb21haW4ucmV2ZXJzZSgpO1xuICAgIHRoaXMuY29sb3JzID0gbmV3IENvbG9ySGVscGVyKHRoaXMuc2NoZW1lLCB0aGlzLnNjaGVtZVR5cGUsIGRvbWFpbiwgdGhpcy5jdXN0b21Db2xvcnMpO1xuICB9XG5cbiAgZ2V0TGVnZW5kT3B0aW9ucygpIHtcbiAgICBpZiAodGhpcy5zY2hlbWVUeXBlID09PSBTY2FsZVR5cGUuT3JkaW5hbCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc2NhbGVUeXBlOiB0aGlzLnNjaGVtZVR5cGUsXG4gICAgICAgIGNvbG9yczogdGhpcy5jb2xvcnMsXG4gICAgICAgIGRvbWFpbjogdGhpcy5zZXJpZXNEb21haW4sXG4gICAgICAgIHRpdGxlOiB0aGlzLmxlZ2VuZFRpdGxlLFxuICAgICAgICBwb3NpdGlvbjogdGhpcy5sZWdlbmRQb3NpdGlvblxuICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIHNjYWxlVHlwZTogdGhpcy5zY2hlbWVUeXBlLFxuICAgICAgY29sb3JzOiB0aGlzLmNvbG9ycy5zY2FsZSxcbiAgICAgIGRvbWFpbjogdGhpcy55RG9tYWluLFxuICAgICAgdGl0bGU6IHVuZGVmaW5lZCxcbiAgICAgIHBvc2l0aW9uOiB0aGlzLmxlZ2VuZFBvc2l0aW9uXG4gICAgfTtcbiAgfVxuXG4gIHVwZGF0ZVlBeGlzV2lkdGgoeyB3aWR0aCB9OiB7IHdpZHRoOiBudW1iZXIgfSk6IHZvaWQge1xuICAgIHRoaXMueUF4aXNXaWR0aCA9IHdpZHRoO1xuICAgIHRoaXMudXBkYXRlKCk7XG4gIH1cblxuICB1cGRhdGVYQXhpc0hlaWdodCh7IGhlaWdodCB9OiB7IGhlaWdodDogbnVtYmVyIH0pOiB2b2lkIHtcbiAgICB0aGlzLnhBeGlzSGVpZ2h0ID0gaGVpZ2h0O1xuICAgIHRoaXMudXBkYXRlKCk7XG4gIH1cblxuICBvbkFjdGl2YXRlKGl0ZW0pOiB2b2lkIHtcbiAgICBjb25zdCBpZHggPSB0aGlzLmFjdGl2ZUVudHJpZXMuZmluZEluZGV4KGQgPT4ge1xuICAgICAgcmV0dXJuIGQubmFtZSA9PT0gaXRlbS5uYW1lICYmIGQudmFsdWUgPT09IGl0ZW0udmFsdWU7XG4gICAgfSk7XG4gICAgaWYgKGlkeCA+IC0xKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuYWN0aXZlRW50cmllcyA9IHRoaXMuc2hvd1Nlcmllc09uSG92ZXIgPyBbaXRlbSwgLi4udGhpcy5hY3RpdmVFbnRyaWVzXSA6IHRoaXMuYWN0aXZlRW50cmllcztcbiAgICB0aGlzLmFjdGl2YXRlLmVtaXQoeyB2YWx1ZTogaXRlbSwgZW50cmllczogdGhpcy5hY3RpdmVFbnRyaWVzIH0pO1xuICB9XG5cbiAgb25EZWFjdGl2YXRlKGl0ZW0pOiB2b2lkIHtcbiAgICBjb25zdCBpZHggPSB0aGlzLmFjdGl2ZUVudHJpZXMuZmluZEluZGV4KGQgPT4ge1xuICAgICAgcmV0dXJuIGQubmFtZSA9PT0gaXRlbS5uYW1lICYmIGQudmFsdWUgPT09IGl0ZW0udmFsdWU7XG4gICAgfSk7XG5cbiAgICB0aGlzLmFjdGl2ZUVudHJpZXMuc3BsaWNlKGlkeCwgMSk7XG4gICAgdGhpcy5hY3RpdmVFbnRyaWVzID0gWy4uLnRoaXMuYWN0aXZlRW50cmllc107XG5cbiAgICB0aGlzLmRlYWN0aXZhdGUuZW1pdCh7IHZhbHVlOiBpdGVtLCBlbnRyaWVzOiB0aGlzLmFjdGl2ZUVudHJpZXMgfSk7XG4gIH1cblxuICBkZWFjdGl2YXRlQWxsKCk6IHZvaWQge1xuICAgIHRoaXMuYWN0aXZlRW50cmllcyA9IFsuLi50aGlzLmFjdGl2ZUVudHJpZXNdO1xuICAgIGZvciAoY29uc3QgZW50cnkgb2YgdGhpcy5hY3RpdmVFbnRyaWVzKSB7XG4gICAgICB0aGlzLmRlYWN0aXZhdGUuZW1pdCh7IHZhbHVlOiBlbnRyeSwgZW50cmllczogW10gfSk7XG4gICAgfVxuICAgIHRoaXMuYWN0aXZlRW50cmllcyA9IFtdO1xuICB9XG5cbiAgdHJhY2tCeShpbmRleDogbnVtYmVyLCBpdGVtKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYCR7aXRlbS5uYW1lfWA7XG4gIH1cbn1cbiJdfQ==
\No newline at end of file