@libs-ui/components-draw-line 0.1.1-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,672 @@
1
+ import { ChangeDetectorRef, Directive, ElementRef, EventEmitter, Input, NgZone, Output, inject } from '@angular/core';
2
+ import { checkMouseOverInContainer, cloneDeep, get, getDragEventByElement } from '@libs-ui/utils';
3
+ import { Subject, takeUntil, tap } from 'rxjs';
4
+ import { MoCanvasConnectNavigationNewElementUtil } from './util/connect-navigation-new-element.util';
5
+ import * as i0 from "@angular/core";
6
+ export * from './draw-line.interface';
7
+ export class LibsUiComponentsDrawLineDirective {
8
+ cdr = inject(ChangeDetectorRef);
9
+ zone = inject(NgZone);
10
+ elementRef = inject(ElementRef);
11
+ intervalScrollToElement;
12
+ dataDraw = [];
13
+ dataReachablePointRange = [];
14
+ onDrawLineEnd = new Subject();
15
+ onDestroy = new Subject();
16
+ viewBoxConfig;
17
+ svgElement;
18
+ drawRectDebug;
19
+ outDrawLineFunctionControl = new EventEmitter();
20
+ outConnected = new EventEmitter();
21
+ ngAfterViewInit() {
22
+ this.svgElement = this.svgElement || document.createElementNS('http://www.w3.org/2000/svg', 'svg');
23
+ this.elementRef.nativeElement.append(this.svgElement);
24
+ this.outDrawLineFunctionControl.emit(this.FunctionsControl);
25
+ }
26
+ get FunctionsControl() {
27
+ return {
28
+ setData: this.setData.bind(this),
29
+ setReachablePointRange: this.setReachablePointRange.bind(this),
30
+ removeLine: this.removeLine.bind(this),
31
+ removeReachablePointRange: this.removeReachablePointRange.bind(this),
32
+ updateViewBox: this.updateViewBox.bind(this),
33
+ };
34
+ }
35
+ setData(data) {
36
+ const newData = [];
37
+ data.forEach((item) => {
38
+ if (this.dataDraw.find((dataDraw) => dataDraw.id === item.id && item.points.start.x === dataDraw.points.start.x && item.points.start.y === dataDraw.points.start.y && item.points.end.x === dataDraw.points.end.x && item.points.end.y === dataDraw.points.end.y)) {
39
+ return;
40
+ }
41
+ const itemClone = cloneDeep(item);
42
+ itemClone.ref = item;
43
+ newData.push(itemClone);
44
+ });
45
+ this.dataDraw.push(...newData);
46
+ this.startProcessDataRow(newData);
47
+ }
48
+ setReachablePointRange(data) {
49
+ const newData = [];
50
+ data.forEach((item) => {
51
+ if (this.dataReachablePointRange.find((dataDraw) => dataDraw.id === item.id || (item.x === dataDraw.x && item.y === dataDraw.y))) {
52
+ return;
53
+ }
54
+ const itemClone = cloneDeep(item);
55
+ itemClone.ref = item;
56
+ newData.push(itemClone);
57
+ });
58
+ this.dataReachablePointRange.push(...newData);
59
+ this.startProcessDataReachablePointRange(newData);
60
+ }
61
+ removeLine(id, points) {
62
+ const dataDrawById = this.dataDraw.filter((item) => item.id === id);
63
+ if (!dataDrawById?.length) {
64
+ return;
65
+ }
66
+ const removeByItem = (item) => {
67
+ this.removeElementOfPoints(item.points);
68
+ item.points.separatedPoints?.forEach((separatedPoints) => this.removeElementOfPoints(separatedPoints));
69
+ };
70
+ if (!points?.length) {
71
+ dataDrawById.forEach((item) => removeByItem(item));
72
+ this.dataDraw = this.dataDraw.filter((item) => item.id !== id);
73
+ this.updateViewBox();
74
+ return;
75
+ }
76
+ points.forEach((point) => {
77
+ const dataDrawRemoveByPoint = dataDrawById.find((item) => item.points.start.x === point.start.x && item.points.start.y === point.start.y && item.points.end.x === point.end.x && item.points.end.y === point.end.y);
78
+ if (dataDrawRemoveByPoint) {
79
+ dataDrawRemoveByPoint.isRemove = true;
80
+ removeByItem(dataDrawRemoveByPoint);
81
+ this.dataDraw = this.dataDraw.filter((item) => item.id !== id && !item.isRemove);
82
+ }
83
+ });
84
+ this.updateViewBox();
85
+ }
86
+ removeReachablePointRange(ids) {
87
+ this.clearRect();
88
+ if (!ids.length) {
89
+ return;
90
+ }
91
+ ids.forEach((id) => {
92
+ const itemRemove = this.dataReachablePointRange?.find((item) => item.id === id);
93
+ if (!itemRemove) {
94
+ return;
95
+ }
96
+ itemRemove.onDestroyEvent?.next();
97
+ itemRemove.element?.remove();
98
+ this.dataReachablePointRange = this.dataReachablePointRange?.filter((item) => item.id !== id);
99
+ });
100
+ }
101
+ startProcessDataRow(dataDraw) {
102
+ this.zone.runOutsideAngular(() => {
103
+ dataDraw.forEach((item) => {
104
+ const { pathElement, arrowElement, circleStartElement, circleEndElement } = this.createPathAndArrowElement(item.id);
105
+ item.points.obstacleRect?.forEach((data) => this.addRect('rect', data));
106
+ item.points.pathElement = pathElement;
107
+ item.points.arrowElement = arrowElement;
108
+ if (item.startCircle) {
109
+ item.points.circleStartElement = circleStartElement;
110
+ this.svgElement.append(circleStartElement);
111
+ }
112
+ if (item.endCircle) {
113
+ item.points.circleEndElement = circleEndElement;
114
+ this.svgElement.append(circleEndElement);
115
+ }
116
+ item.points.onDestroyEvent = new Subject();
117
+ this.drawLine(item);
118
+ });
119
+ this.updateViewBox();
120
+ });
121
+ }
122
+ startProcessDataReachablePointRange(data) {
123
+ this.zone.runOutsideAngular(() => {
124
+ data.forEach((item) => {
125
+ item.onDestroyEvent = new Subject();
126
+ item.element = this.createPathAndArrowElement(item.id).circleEndElement;
127
+ this.svgElement.append(item.element);
128
+ this.updateAttributeCircle(item.element, item.id, item, item.style);
129
+ this.onDrawLineEnd.pipe(takeUntil(item.onDestroyEvent), takeUntil(this.onDestroy)).subscribe((eventData) => {
130
+ const { dataLine, event } = eventData;
131
+ if (!checkMouseOverInContainer(event, item.element) || !dataLine.ref || !item.ref) {
132
+ return;
133
+ }
134
+ item.idConnected = eventData.dataLine.id;
135
+ eventData.dataLine.idConnected = item.id;
136
+ this.outConnected.emit({
137
+ dataLine: dataLine.ref,
138
+ dataReachablePointRange: item.ref,
139
+ });
140
+ });
141
+ });
142
+ this.updateViewBox();
143
+ });
144
+ }
145
+ removeElementOfPoints(points) {
146
+ this.zone.runOutsideAngular(() => {
147
+ points.onDestroyEvent?.next();
148
+ points.onDestroyEvent?.complete();
149
+ points?.pathElement?.remove();
150
+ points?.arrowElement?.remove();
151
+ points?.circleStartElement?.remove();
152
+ points.circleEndElement?.remove();
153
+ });
154
+ }
155
+ drawLine(data) {
156
+ this.zone.runOutsideAngular(() => {
157
+ const { points, mode } = data;
158
+ let { curve } = data?.lineStyle || {};
159
+ if (mode !== 'quart-in') {
160
+ curve = curve ?? 10;
161
+ }
162
+ const preLengthSeparatedPoints = points.separatedPoints?.length;
163
+ points.separatedPoints?.forEach((separatedPoints) => this.removeElementOfPoints(separatedPoints));
164
+ points.separatedPoints = [];
165
+ MoCanvasConnectNavigationNewElementUtil.START_MODE = 'right-left';
166
+ if (data.startEndMode) {
167
+ MoCanvasConnectNavigationNewElementUtil.START_MODE = data.startEndMode;
168
+ }
169
+ this.calculatorSeparatedPoints(data.id, points, curve || 10, points.separatedPoints, points.obstacleRect || []);
170
+ if (!preLengthSeparatedPoints && points.separatedPoints.length) {
171
+ this.removeElementOfPoints(points);
172
+ const { pathElement, arrowElement } = this.createPathAndArrowElement(data.id);
173
+ points.pathElement = pathElement;
174
+ points.arrowElement = arrowElement;
175
+ points.initialized = false;
176
+ }
177
+ if (!points.separatedPoints?.length) {
178
+ this.buildPathAndDraw(data, points, mode);
179
+ return;
180
+ }
181
+ let path = '';
182
+ points.separatedPoints.forEach((separatedPoints) => {
183
+ path += this.buildPathAndDrawSeparatedPoints(data, separatedPoints, separatedPoints.mode || mode);
184
+ });
185
+ const pathElement = document.createElementNS('http://www.w3.org/2000/svg', 'path');
186
+ this.svgElement.append(pathElement);
187
+ points.pathElement = pathElement;
188
+ const styleConfig = {
189
+ stroke: data.lineStyle?.stroke ?? '#9CA2AD',
190
+ strokeDasharray: data.lineStyle?.strokeDasharray,
191
+ strokeWidth: data.lineStyle?.strokeWidth ?? '1px',
192
+ fill: data.lineStyle?.fill ?? 'none',
193
+ curve: data.lineStyle?.curve ?? 10,
194
+ distancePoint: data.lineStyle?.distancePoint ?? 10,
195
+ };
196
+ points.pathElement?.setAttribute('stroke', styleConfig.stroke);
197
+ points.pathElement?.setAttribute('fill', styleConfig.fill);
198
+ points.pathElement?.setAttribute('stroke-width', styleConfig.strokeWidth);
199
+ if (styleConfig.strokeDasharray) {
200
+ points.pathElement?.setAttribute('stroke-dasharray', styleConfig.strokeDasharray);
201
+ }
202
+ points.pathElement?.setAttribute('d', path);
203
+ this.drawRectAndInitEvent(data, mode);
204
+ });
205
+ }
206
+ updateViewBox(viewBoxConfig) {
207
+ if (viewBoxConfig) {
208
+ this.viewBoxConfig = viewBoxConfig;
209
+ }
210
+ const xPoints = new Set([0]);
211
+ const yPoints = new Set([0]);
212
+ const addPoints = (points) => {
213
+ xPoints.add(points.start.x);
214
+ xPoints.add(points.end.x);
215
+ yPoints.add(points.start.y);
216
+ yPoints.add(points.end.y);
217
+ };
218
+ this.dataDraw?.forEach((item) => {
219
+ const points = item.points;
220
+ addPoints(points);
221
+ points.separatedPoints?.forEach((separatedPoints) => addPoints(separatedPoints));
222
+ points.obstacleRect?.forEach((obstacleRect) => {
223
+ addPoints({
224
+ start: { x: obstacleRect.x - (obstacleRect.gapXObstacleRect || 8), y: obstacleRect.y - (obstacleRect.gapYObstacleRect || 8) },
225
+ end: { x: obstacleRect.x + obstacleRect.width + (obstacleRect.gapXObstacleRect || 8) * 2, y: obstacleRect.y + obstacleRect.height + (obstacleRect.gapYObstacleRect || 8) * 2 },
226
+ });
227
+ });
228
+ });
229
+ const xMax = this.viewBoxConfig?.width ?? (xPoints.size ? Math.max(...xPoints) : 0) + 14;
230
+ const yMax = this.viewBoxConfig?.height ?? (yPoints.size ? Math.max(...yPoints) : 0) + 14;
231
+ if (!this.viewBoxConfig?.ignoreViewBox) {
232
+ const rectSvgElement = this.svgElement.getBoundingClientRect();
233
+ this.svgElement?.setAttribute('viewBox', `${this.viewBoxConfig?.minX ?? rectSvgElement.x} ${this.viewBoxConfig?.minY ?? rectSvgElement.y} ${xMax} ${yMax}`);
234
+ }
235
+ this.svgElement?.setAttribute('width', `${xMax ?? 0}`);
236
+ this.svgElement?.setAttribute('height', `${yMax ?? 0}`);
237
+ }
238
+ isPointInsideSquare(point, square) {
239
+ const { x, y } = point;
240
+ const { x: squareX, y: squareY, width, height } = square;
241
+ return x >= squareX && x <= squareX + width && y >= squareY && y <= squareY + height;
242
+ }
243
+ calculatorSeparatedPoints(name, points, curve, separatedPoints, obstacleRects) {
244
+ if (!obstacleRects.length) {
245
+ return;
246
+ }
247
+ const elementStart = obstacleRects.find((item) => this.isPointInsideSquare(points.start, item));
248
+ const elementEnd = obstacleRects.find((item) => this.isPointInsideSquare(points.end, item));
249
+ if (this.viewBoxConfig?.marginBetweenElement) {
250
+ MoCanvasConnectNavigationNewElementUtil.ELEMENT_MARGIN_BETWEEN_BRANCH_DEFAULT = this.viewBoxConfig?.marginBetweenElement ?? 32;
251
+ }
252
+ MoCanvasConnectNavigationNewElementUtil.setXYConnectElements(elementStart ?? { ...points.start, width: 1, height: 1 }, elementEnd ?? { ...points.end, width: 1, height: 1 }, obstacleRects, separatedPoints, curve);
253
+ }
254
+ buildPathAndDraw(data, points, mode) {
255
+ let dPath = {};
256
+ const styleConfig = {
257
+ stroke: data.lineStyle?.stroke ?? '#9CA2AD',
258
+ strokeDasharray: data.lineStyle?.strokeDasharray,
259
+ strokeWidth: data.lineStyle?.strokeWidth ?? '1px',
260
+ fill: data.lineStyle?.fill ?? 'none',
261
+ curve: data.lineStyle?.curve ?? 10,
262
+ distancePoint: data.lineStyle?.distancePoint ?? 10,
263
+ };
264
+ points.pathElement?.setAttribute('stroke', styleConfig.stroke);
265
+ points.pathElement?.setAttribute('fill', styleConfig.fill);
266
+ points.pathElement?.setAttribute('stroke-width', styleConfig.strokeWidth);
267
+ if (styleConfig.strokeDasharray) {
268
+ points.pathElement?.setAttribute('stroke-dasharray', styleConfig.strokeDasharray);
269
+ }
270
+ let { curve, distancePoint } = styleConfig;
271
+ mode = mode || 'quart-in';
272
+ if (mode !== 'quart-in') {
273
+ curve = curve ?? 10;
274
+ distancePoint = distancePoint ?? 10;
275
+ }
276
+ if (mode === 'quart-in' || points.start.x === points.end.x || points.start.y === points.end.y) {
277
+ this.drawBalancedCurve(dPath, points);
278
+ if (mode === 'quart-in') {
279
+ dPath = {};
280
+ this.drawBendBothEndsCurve(dPath, points);
281
+ }
282
+ points.pathElement?.setAttribute('d', this.builDAttributeToString(dPath));
283
+ this.drawRectAndInitEvent(data, mode);
284
+ return;
285
+ }
286
+ const result = this.calculatorDistancePointAndCurve(points, distancePoint, curve, mode);
287
+ distancePoint = result.distancePoint;
288
+ curve = result.curve;
289
+ this.buildDAttributeByPointEndModeHorizontal(dPath, points, distancePoint || 0, curve || 0, mode);
290
+ this.buildDAttributeByPointEndModeVertical(dPath, points, distancePoint || 0, curve || 0, mode);
291
+ points.pathElement?.setAttribute('d', this.builDAttributeToString(dPath));
292
+ this.drawRectAndInitEvent(data, mode);
293
+ }
294
+ calculatorDistancePointAndCurve(points, distancePoint, curve, mode) {
295
+ if (!mode.includes('vertical') && !mode.includes('horizontal')) {
296
+ return { curve, distancePoint };
297
+ }
298
+ const gapX = Math.abs(points.start.x - points.end.x);
299
+ const gapY = Math.abs(points.start.y - points.end.y);
300
+ const multiplierCurve = mode.includes('horizontal') ? 1 : 2;
301
+ const multiplierDistance = mode.includes('horizontal') ? 2 : 1;
302
+ if (!mode.includes('single-curve')) {
303
+ if (gapX < distancePoint * multiplierDistance + curve * multiplierCurve) {
304
+ distancePoint = curve = gapX / 3;
305
+ }
306
+ if (gapY < distancePoint * multiplierDistance + curve * multiplierCurve) {
307
+ distancePoint = curve = gapY / 3;
308
+ }
309
+ return { curve, distancePoint };
310
+ }
311
+ const minGap = Math.min(gapX, gapY);
312
+ if (minGap < distancePoint) {
313
+ distancePoint = minGap;
314
+ }
315
+ if (minGap < curve) {
316
+ curve = minGap;
317
+ }
318
+ return { curve, distancePoint };
319
+ }
320
+ drawRectAndInitEvent(data, mode) {
321
+ const points = data.points;
322
+ this.updateStyleArrow(points, mode, data);
323
+ if (data.startCircle && points.circleStartElement) {
324
+ this.updateAttributeCircle(points.circleStartElement, data.id, points.start, data.startCircleStyle);
325
+ }
326
+ if (data.endCircle && points.circleEndElement) {
327
+ this.updateAttributeCircle(points.circleEndElement, data.id, points.end, data.endCircleStyle);
328
+ }
329
+ this.initEvent(data);
330
+ }
331
+ drawBalancedCurve(dPath, points) {
332
+ dPath.M = { x: points.start.x, y: points.start.y };
333
+ dPath.Q = [
334
+ { x: points.start.x + (points.end.x - points.start.x) / 4, y: points.start.y + (points.end.y - points.start.y) / 2 },
335
+ { x: points.start.x + (points.end.x - points.start.x) / 2, y: points.start.y + (points.end.y - points.start.y) / 2 },
336
+ ];
337
+ dPath.Q2 = [
338
+ { x: points.end.x - (points.end.x - points.start.x) / 4, y: points.start.y + (points.end.y - points.start.y) / 2 },
339
+ { x: points.end.x, y: points.end.y },
340
+ ];
341
+ }
342
+ drawBendBothEndsCurve(dPath, points) {
343
+ const pointXCurve = (points.start.x + points.end.x) * 0.5;
344
+ const pointControl1 = { x: pointXCurve, y: points.start.y };
345
+ const pointControl2 = { x: pointXCurve, y: points.end.y };
346
+ dPath.M = { x: points.start.x, y: points.start.y };
347
+ dPath.C = [
348
+ { x: pointControl1.x, y: pointControl1.y },
349
+ { x: pointControl2.x, y: pointControl2.y },
350
+ { x: points.end.x, y: points.end.y },
351
+ ];
352
+ }
353
+ buildDAttributeByPointEndModeHorizontal(dPath, points, distancePoint, curve, mode) {
354
+ if (!mode.includes('horizontal')) {
355
+ return;
356
+ }
357
+ const multiplierX = points.start.x < points.end.x ? -1 : 1;
358
+ const multiplierY = points.start.y < points.end.y ? 1 : -1;
359
+ const reverseMultiplier = -1;
360
+ dPath.M = { x: points.start.x, y: points.start.y };
361
+ dPath.L = { x: points.end.x + (distancePoint * 2 + curve) * multiplierX, y: points.start.y };
362
+ if (mode.includes('horizontal-single')) {
363
+ dPath.L.x = points.end.x + curve * multiplierX;
364
+ }
365
+ dPath.Q = [
366
+ { x: dPath.L.x + curve * multiplierX * reverseMultiplier, y: points.start.y },
367
+ { x: dPath.L.x + curve * multiplierX * reverseMultiplier, y: points.start.y + curve * multiplierY },
368
+ ];
369
+ dPath.L2 = { x: dPath.Q[1].x, y: points.end.y + curve * multiplierY * reverseMultiplier };
370
+ if (mode.includes('horizontal-single')) {
371
+ dPath.L2 = points.end;
372
+ }
373
+ if (mode === 'horizontal') {
374
+ dPath.Q2 = [
375
+ { x: dPath.L2.x, y: points.end.y },
376
+ { x: dPath.L2.x + distancePoint * multiplierX * reverseMultiplier, y: points.end.y },
377
+ ];
378
+ dPath.L3 = { x: points.end.x, y: points.end.y };
379
+ }
380
+ }
381
+ buildDAttributeByPointEndModeVertical(dPath, points, distancePoint, curve, mode) {
382
+ if (!mode.includes('vertical')) {
383
+ return;
384
+ }
385
+ const multiplierX = points.start.x < points.end.x ? -1 : 1;
386
+ const multiplierY = points.start.y < points.end.y ? 1 : -1;
387
+ const reverseMultiplier = -1;
388
+ dPath.M = points.start;
389
+ dPath.L = { x: points.start.x, y: points.start.y + distancePoint * multiplierY };
390
+ if (mode.includes('vertical-single')) {
391
+ dPath.L.y = points.end.y + distancePoint * multiplierY * reverseMultiplier;
392
+ }
393
+ dPath.Q = [
394
+ { x: dPath.L.x, y: dPath.L.y + curve * multiplierY },
395
+ { x: dPath.L.x + curve * multiplierX * reverseMultiplier, y: dPath.L.y + curve * multiplierY },
396
+ ];
397
+ dPath.L2 = { x: points.end.x + curve * 2 * multiplierX, y: dPath.Q[1].y };
398
+ if (mode.includes('vertical-single')) {
399
+ dPath.L2 = points.end;
400
+ }
401
+ if (mode === 'vertical') {
402
+ dPath.Q2 = [
403
+ { x: points.end.x, y: dPath.L2.y },
404
+ { x: points.end.x, y: dPath.L2.y + curve * multiplierY },
405
+ ];
406
+ dPath.L3 = { x: points.end.x, y: points.end.y };
407
+ }
408
+ }
409
+ builDAttributeToString(dAttribute) {
410
+ let dString = '';
411
+ Object.keys(dAttribute).forEach((key) => {
412
+ const data = get(dAttribute, key);
413
+ if (Array.isArray(data)) {
414
+ const [point1, point2, point3] = data;
415
+ dString = `${dString}${key.replace(/\d/g, '')}${point1.x},${point1.y} ${point2.x},${point2.y}${point3 ? ' ' + point3.x + ',' + point3.y : ''}
416
+ `;
417
+ return;
418
+ }
419
+ dString = `${dString}${key.replace(/\d/g, '')}${data?.x},${data?.y}
420
+ `;
421
+ });
422
+ return dString;
423
+ }
424
+ updateStyleArrow(points, mode, data) {
425
+ if (!points.arrowElement || data.ignoreDrawArrow) {
426
+ return;
427
+ }
428
+ const styleConfig = {
429
+ fill: data.arrowStyle?.fill ?? '#9CA2AD',
430
+ stroke: data.arrowStyle?.stroke ?? 'none',
431
+ strokeWidth: data.arrowStyle?.strokeWidth ?? '0',
432
+ width: data.arrowStyle?.width ?? 6,
433
+ height: data.arrowStyle?.height ?? 8,
434
+ };
435
+ const pointEnd = cloneDeep(points.end);
436
+ const arrowElement = points.arrowElement;
437
+ const direction = data.arrowDirection || this.getDirection(points, data.startEndMode);
438
+ switch (direction) {
439
+ case 'right':
440
+ if (mode.includes('horizontal') || mode.includes('vertical')) {
441
+ pointEnd.x -= styleConfig.height;
442
+ }
443
+ arrowElement?.setAttribute('points', `${pointEnd.x},${pointEnd.y - styleConfig.width} ${pointEnd.x + styleConfig.height},${pointEnd.y} ${pointEnd.x},${pointEnd.y + styleConfig.width} `);
444
+ break;
445
+ case 'left':
446
+ if (mode.includes('horizontal') || mode.includes('vertical')) {
447
+ pointEnd.x += styleConfig.height;
448
+ }
449
+ arrowElement?.setAttribute('points', `${pointEnd.x},${pointEnd.y - styleConfig.width} ${pointEnd.x - styleConfig.height},${pointEnd.y} ${pointEnd.x},${pointEnd.y + styleConfig.width} `);
450
+ break;
451
+ case 'top':
452
+ if (mode.includes('horizontal') || mode.includes('vertical')) {
453
+ pointEnd.y += styleConfig.height;
454
+ }
455
+ arrowElement?.setAttribute('points', `${pointEnd.x - styleConfig.width},${pointEnd.y} ${pointEnd.x},${pointEnd.y - styleConfig.height} ${pointEnd.x + styleConfig.width},${pointEnd.y} `);
456
+ break;
457
+ case 'bottom':
458
+ if (mode.includes('horizontal') || mode.includes('vertical')) {
459
+ pointEnd.y -= styleConfig.height;
460
+ }
461
+ arrowElement?.setAttribute('points', `${pointEnd.x - styleConfig.width},${pointEnd.y} ${pointEnd.x},${pointEnd.y + styleConfig.height} ${pointEnd.x + styleConfig.width},${pointEnd.y} `);
462
+ break;
463
+ }
464
+ arrowElement?.setAttribute('fill', styleConfig.fill);
465
+ arrowElement?.setAttribute('stroke', styleConfig.stroke);
466
+ arrowElement?.setAttribute('stroke-width', styleConfig.strokeWidth);
467
+ }
468
+ updateAttributeCircle(circleElement, name, point, circleStyle) {
469
+ circleElement.setAttribute('name', name);
470
+ circleElement.setAttribute('cx', `${point.x}`);
471
+ circleElement.setAttribute('cy', `${point.y}`);
472
+ circleElement.setAttribute('r', `${circleStyle?.r ?? 2}`);
473
+ circleElement.setAttribute('fill', `${circleStyle?.fill ?? 'green'}`);
474
+ circleElement.setAttribute('stroke', `${circleStyle?.stroke ?? '#9CA2AD'}`);
475
+ circleElement.setAttribute('stroke-width', `${circleStyle?.strokeWidth ?? '1px'}`);
476
+ return circleElement;
477
+ }
478
+ getDirection(points, startEndMode) {
479
+ let pointStart = { ...points.start };
480
+ if (points.separatedPoints) {
481
+ const lineToEnd = points.separatedPoints.find((item) => item.end.x === points.end.x && item.end.y === points.end.y);
482
+ if (lineToEnd) {
483
+ pointStart = lineToEnd.start;
484
+ }
485
+ }
486
+ const modeHorizontal = pointStart.x < points.end.x ? 'right' : 'left';
487
+ const modeVertical = pointStart.y < points.end.y ? 'bottom' : 'top';
488
+ if (!startEndMode) {
489
+ if (Math.abs(points.end.x - pointStart.x) > Math.abs(points.end.y - pointStart.y)) {
490
+ return modeHorizontal;
491
+ }
492
+ return modeVertical;
493
+ }
494
+ switch (startEndMode) {
495
+ case 'bottom-left':
496
+ return modeHorizontal;
497
+ case 'right-left':
498
+ return modeHorizontal;
499
+ case 'bottom-top':
500
+ return modeVertical;
501
+ }
502
+ }
503
+ initEvent(data) {
504
+ const points = data.points;
505
+ let preEvent = undefined;
506
+ if ((!points.arrowElement && !points.circleEndElement) || !points.onDestroyEvent || points.initialized) {
507
+ return;
508
+ }
509
+ points.initialized = true;
510
+ const functionMouseUp = (mouseEvent) => {
511
+ if (preEvent) {
512
+ preEvent = undefined;
513
+ this.onDrawLineEnd.next({ dataLine: data, event: mouseEvent });
514
+ }
515
+ };
516
+ const handlerDrag = (dragMouseEvent) => {
517
+ if (!preEvent) {
518
+ preEvent = dragMouseEvent;
519
+ }
520
+ const pointEnd = cloneDeep(points.end);
521
+ const movementX = dragMouseEvent.clientX - preEvent.clientX;
522
+ const movementY = dragMouseEvent.clientY - preEvent.clientY;
523
+ preEvent = dragMouseEvent;
524
+ pointEnd.x += movementX;
525
+ pointEnd.y += movementY;
526
+ if (data.points?.obstacleRect?.length && data.points?.obstacleRect.some((obstacleRect) => this.checkPointIncludeRect(pointEnd, obstacleRect))) {
527
+ return;
528
+ }
529
+ points.end.x = pointEnd.x;
530
+ points.end.y = pointEnd.y;
531
+ this.drawLine(data);
532
+ this.updateViewBox();
533
+ };
534
+ if (points.arrowElement) {
535
+ getDragEventByElement({
536
+ elementMouseDown: points.arrowElement,
537
+ functionMouseUp: functionMouseUp,
538
+ onDestroy: this.onDestroy,
539
+ })
540
+ .pipe(tap(handlerDrag), takeUntil(points.onDestroyEvent))
541
+ .subscribe();
542
+ }
543
+ if (points.circleEndElement) {
544
+ getDragEventByElement({
545
+ elementMouseDown: points.circleEndElement,
546
+ functionMouseUp: functionMouseUp,
547
+ onDestroy: this.onDestroy,
548
+ })
549
+ .pipe(tap(handlerDrag), takeUntil(points.onDestroyEvent))
550
+ .subscribe();
551
+ }
552
+ }
553
+ checkPointIncludeRect(point, obstacleRect) {
554
+ const gapDefault = 8;
555
+ obstacleRect = {
556
+ x: obstacleRect.x - (obstacleRect.gapXObstacleRect || gapDefault),
557
+ y: obstacleRect.y - (obstacleRect.gapYObstacleRect || gapDefault),
558
+ width: obstacleRect.width + (obstacleRect.gapXObstacleRect || gapDefault) * 2,
559
+ height: obstacleRect.height + (obstacleRect.gapYObstacleRect || gapDefault) * 2,
560
+ };
561
+ if (obstacleRect.x <= point.x && point.x <= obstacleRect.x + obstacleRect.width && obstacleRect.y <= point.y && point.y <= obstacleRect.y + obstacleRect.height) {
562
+ return true;
563
+ }
564
+ return false;
565
+ }
566
+ createPathAndArrowElement(name) {
567
+ const pathElement = document.createElementNS('http://www.w3.org/2000/svg', 'path');
568
+ const arrowElement = document.createElementNS('http://www.w3.org/2000/svg', 'polyline');
569
+ const circleStartElement = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
570
+ const circleEndElement = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
571
+ pathElement.setAttribute('name', name);
572
+ arrowElement.setAttribute('name', name);
573
+ this.svgElement.append(pathElement);
574
+ this.svgElement.append(arrowElement);
575
+ return { pathElement, arrowElement, circleStartElement, circleEndElement };
576
+ }
577
+ addCircle(name, point) {
578
+ if (!this.drawRectDebug) {
579
+ return;
580
+ }
581
+ const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
582
+ circle.setAttribute('name', name);
583
+ circle.setAttribute('cx', `${point.x}`);
584
+ circle.setAttribute('cy', `${point.y}`);
585
+ circle.setAttribute('r', '2');
586
+ circle.setAttribute('style', 'fill: none; stroke: blue; stroke-width: 1px;');
587
+ this.svgElement.appendChild(circle);
588
+ }
589
+ clearCircle() {
590
+ if (!this.drawRectDebug) {
591
+ return;
592
+ }
593
+ Array.from(this.svgElement.getElementsByTagName('circle'))?.forEach((item) => item.remove());
594
+ }
595
+ addRect(name, rect) {
596
+ if (!this.drawRectDebug) {
597
+ return;
598
+ }
599
+ const rectElement = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
600
+ const textElement = document.createElementNS('http://www.w3.org/2000/svg', 'text');
601
+ rectElement.setAttribute('name', name);
602
+ rectElement.setAttribute('x', `${rect.x}`);
603
+ rectElement.setAttribute('y', `${rect.y}`);
604
+ rectElement.setAttribute('width', `${rect.width}`);
605
+ rectElement.setAttribute('height', `${rect.height}`);
606
+ rectElement.setAttribute('style', 'fill: blue; stroke: blue;');
607
+ this.svgElement.appendChild(rectElement);
608
+ textElement.setAttribute('x', `${rect.x}`);
609
+ textElement.setAttribute('y', `${rect.y}`);
610
+ textElement.textContent = rect.id ?? '';
611
+ this.svgElement.appendChild(textElement);
612
+ }
613
+ clearRect() {
614
+ if (!this.drawRectDebug) {
615
+ return;
616
+ }
617
+ Array.from(this.svgElement.getElementsByTagName('rect'))?.forEach((item) => item.remove());
618
+ Array.from(this.svgElement.getElementsByTagName('text'))?.forEach((item) => item.remove());
619
+ }
620
+ buildPathAndDrawSeparatedPoints(data, points, mode) {
621
+ let dPath = {};
622
+ const styleConfig = {
623
+ curve: data.lineStyle?.curve ?? 10,
624
+ distancePoint: data.lineStyle?.distancePoint ?? 10,
625
+ };
626
+ let { curve, distancePoint } = styleConfig;
627
+ mode = mode || 'quart-in';
628
+ if (mode !== 'quart-in') {
629
+ curve = curve ?? 10;
630
+ distancePoint = distancePoint ?? 10;
631
+ }
632
+ if (mode === 'quart-in' || points.start.x === points.end.x || points.start.y === points.end.y) {
633
+ this.drawBalancedCurve(dPath, points);
634
+ if (mode === 'quart-in') {
635
+ dPath = {};
636
+ this.drawBendBothEndsCurve(dPath, points);
637
+ }
638
+ return this.builDAttributeToString(dPath);
639
+ }
640
+ const result = this.calculatorDistancePointAndCurve(points, distancePoint, curve, mode);
641
+ distancePoint = result.distancePoint;
642
+ curve = result.curve;
643
+ this.buildDAttributeByPointEndModeHorizontal(dPath, points, distancePoint || 0, curve || 0, mode);
644
+ this.buildDAttributeByPointEndModeVertical(dPath, points, distancePoint || 0, curve || 0, mode);
645
+ return this.builDAttributeToString(dPath);
646
+ }
647
+ ngOnDestroy() {
648
+ this.onDestroy.next();
649
+ this.onDestroy.complete();
650
+ }
651
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiComponentsDrawLineDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
652
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: LibsUiComponentsDrawLineDirective, isStandalone: true, selector: "[LibsUiComponentsDrawLineDirective]", inputs: { viewBoxConfig: "viewBoxConfig", svgElement: "svgElement", drawRectDebug: "drawRectDebug" }, outputs: { outDrawLineFunctionControl: "outDrawLineFunctionControl", outConnected: "outConnected" }, ngImport: i0 });
653
+ }
654
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiComponentsDrawLineDirective, decorators: [{
655
+ type: Directive,
656
+ args: [{
657
+ // eslint-disable-next-line @angular-eslint/directive-selector
658
+ selector: '[LibsUiComponentsDrawLineDirective]',
659
+ standalone: true,
660
+ }]
661
+ }], propDecorators: { viewBoxConfig: [{
662
+ type: Input
663
+ }], svgElement: [{
664
+ type: Input
665
+ }], drawRectDebug: [{
666
+ type: Input
667
+ }], outDrawLineFunctionControl: [{
668
+ type: Output
669
+ }], outConnected: [{
670
+ type: Output
671
+ }] } });
672
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJhdy1saW5lLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2xpYnMtdWkvY29tcG9uZW50cy9kcmF3LWxpbmUvc3JjL2RyYXctbGluZS5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFpQixpQkFBaUIsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFhLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDaEosT0FBTyxFQUFFLHlCQUF5QixFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNsRyxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFL0MsT0FBTyxFQUFFLHVDQUF1QyxFQUFFLE1BQU0sNENBQTRDLENBQUM7O0FBRXJHLGNBQWMsdUJBQXVCLENBQUM7QUFNdEMsTUFBTSxPQUFPLGlDQUFpQztJQUNsQyxHQUFHLEdBQUcsTUFBTSxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDaEMsSUFBSSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN0QixVQUFVLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ2hDLHVCQUF1QixDQUFVO0lBQ25DLFFBQVEsR0FBOEIsRUFBRSxDQUFDO0lBQ3pDLHVCQUF1QixHQUFnQyxFQUFFLENBQUM7SUFDMUQsYUFBYSxHQUdoQixJQUFJLE9BQU8sRUFBRSxDQUFDO0lBQ1gsU0FBUyxHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7SUFFL0IsYUFBYSxDQUFrQjtJQUMvQixVQUFVLENBQWlCO0lBQzNCLGFBQWEsQ0FBVztJQUV2QiwwQkFBMEIsR0FBNkMsSUFBSSxZQUFZLEVBQUUsQ0FBQztJQUMxRixZQUFZLEdBQWtHLElBQUksWUFBWSxF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RyxRQUFRLENBQUMsQ0FBQyxJQUFJLFFBQVEsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDLEtBQUssS0FBSyxRQUFRLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxNQUFNLElBQUksUUFBUSxDQUFDLENBQUMsSUFBSSxRQUFRLENBQUMsQ0FBQyxJQUFJLFFBQVEsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUM7Z0JBQzNMLE1BQU07WUFFUixLQUFLLE1BQU07Z0JBQ1QsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztvQkFDN0QsUUFBUSxDQUFDLENBQUMsSUFBSSxXQUFXLENBQUMsTUFBTSxDQUFDO2dCQUNuQyxDQUFDO2dCQUNELFlBQVksRUFBRSxZQUFZLENBQUMsUUFBUSxFQUFFLEdBQUcsUUFBUSxDQUFDLENBQUMsSUFBSSxRQUFRLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxLQUFLLEtBQUssUUFBUSxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUMsTUFBTSxJQUFJLFFBQVEsQ0FBQyxDQUFDLElBQUksUUFBUSxDQUFDLENBQUMsSUFBSSxRQUFRLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDO2dCQUMzTCxNQUFNO1lBRVIsS0FBSyxLQUFLO2dCQUNSLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7b0JBQzdELFFBQVEsQ0FBQyxDQUFDLElBQUksV0FBVyxDQUFDLE1BQU0sQ0FBQztnQkFDbkMsQ0FBQztnQkFDRCxZQUFZLEVBQUUsWUFBWSxDQUFDLFFBQVEsRUFBRSxHQUFHLFFBQVEsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDLEtBQUssSUFBSSxRQUFRLENBQUMsQ0FBQyxLQUFLLFFBQVEsQ0FBQyxDQUFDLElBQUksUUFBUSxDQUFDLENB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MEJBQTBCO3NCQUFuQyxNQUFNO2dCQUNHLFlBQVk7c0JBQXJCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBZnRlclZpZXdJbml0LCBDaGFuZ2VEZXRlY3RvclJlZiwgRGlyZWN0aXZlLCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIElucHV0LCBOZ1pvbmUsIE9uRGVzdHJveSwgT3V0cHV0LCBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGNoZWNrTW91c2VPdmVySW5Db250YWluZXIsIGNsb25lRGVlcCwgZ2V0LCBnZXREcmFnRXZlbnRCeUVsZW1lbnQgfSBmcm9tICdAbGlicy11aS91dGlscyc7XG5pbXBvcnQgeyBTdWJqZWN0LCB0YWtlVW50aWwsIHRhcCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgSUF0dHJpYnV0ZURPblBhdGgsIElDaXJjbGVTdHlsZSwgSURyYXdMaW5lRGF0YUlucHV0LCBJTW9EcmF3TGluZUZ1bmN0aW9uQ29udHJvbCwgSVBvaW50LCBJUG9pbnRzLCBJUmVhY2hhYmxlUG9pbnRSYW5nZSwgSVJlY3QsIElWaWV3Qm94Q29uZmlnLCBUWVBFX0RJUkVDVElPTiwgVFlQRV9NT0RFIH0gZnJvbSAnLi9kcmF3LWxpbmUuaW50ZXJmYWNlJztcbmltcG9ydCB7IE1vQ2FudmFzQ29ubmVjdE5hdmlnYXRpb25OZXdFbGVtZW50VXRpbCB9IGZyb20gJy4vdXRpbC9jb25uZWN0LW5hdmlnYXRpb24tbmV3LWVsZW1lbnQudXRpbCc7XG5cbmV4cG9ydCAqIGZyb20gJy4vZHJhdy1saW5lLmludGVyZmFjZSc7XG5ARGlyZWN0aXZlKHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9kaXJlY3RpdmUtc2VsZWN0b3JcbiAgc2VsZWN0b3I6ICdbTGlic1VpQ29tcG9uZW50c0RyYXdMaW5lRGlyZWN0aXZlXScsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG59KVxuZXhwb3J0IGNsYXNzIExpYnNVaUNvbXBvbmVudHNEcmF3TGluZURpcmVjdGl2ZSBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XG4gIHByb3RlY3RlZCBjZHIgPSBpbmplY3QoQ2hhbmdlRGV0ZWN0b3JSZWYpO1xuICBwcm90ZWN0ZWQgem9uZSA9IGluamVjdChOZ1pvbmUpO1xuICBwcm90ZWN0ZWQgZWxlbWVudFJlZiA9IGluamVjdChFbGVtZW50UmVmKTtcbiAgcHJvdGVjdGVkIGludGVydmFsU2Nyb2xsVG9FbGVtZW50PzogbnVtYmVyO1xuICBwcml2YXRlIGRhdGFEcmF3OiBBcnJheTxJRHJhd0xpbmVEYXRhSW5wdXQ+ID0gW107XG4gIHByaXZhdGUgZGF0YVJlYWNoYWJsZVBvaW50UmFuZ2U6IEFycmF5PElSZWFjaGFibGVQb2ludFJhbmdlPiA9IFtdO1xuICBwcml2YXRlIG9uRHJhd0xpbmVFbmQ6IFN1YmplY3Q8e1xuICAgIGRhdGFMaW5lOiBJRHJhd0xpbmVEYXRhSW5wdXQ7XG4gICAgZXZlbnQ6IE1vdXNlRXZlbnQ7XG4gIH0+ID0gbmV3IFN1YmplY3QoKTtcbiAgcHJpdmF0ZSBvbkRlc3Ryb3kgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIEBJbnB1dCgpIHZpZXdCb3hDb25maWc/OiBJVmlld0JveENvbmZpZztcbiAgQElucHV0KCkgc3ZnRWxlbWVudCE6IFNWR1NWR0VsZW1lbnQ7XG4gIEBJbnB1dCgpIGRyYXdSZWN0RGVidWc/OiBib29sZWFuO1xuXG4gIEBPdXRwdXQoKSBvdXREcmF3TGluZUZ1bmN0aW9uQ29udHJvbDogRXZlbnRFbWl0dGVyPElNb0RyYXdMaW5lRnVuY3Rpb25Db250cm9sPiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIG91dENvbm5lY3RlZDogRXZlbnRFbWl0dGVyPHsgZGF0YUxpbmU6IElEcmF3TGluZURhdGFJbnB1dDsgZGF0YVJlYWNoYWJsZVBvaW50UmFuZ2U6IElSZWFjaGFibGVQb2ludFJhbmdlIH0+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLnN2Z0VsZW1lbnQgPSB0aGlzLnN2Z0VsZW1lbnQgfHwgZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsICdzdmcnKTtcbiAgICB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5hcHBlbmQodGhpcy5zdmdFbGVtZW50KTtcbiAgICB0aGlzLm91dERyYXdMaW5lRnVuY3Rpb25Db250cm9sLmVtaXQodGhpcy5GdW5jdGlvbnNDb250cm9sKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgRnVuY3Rpb25zQ29udHJvbCgpOiBJTW9EcmF3TGluZUZ1bmN0aW9uQ29udHJvbCB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNldERhdGE6IHRoaXMuc2V0RGF0YS5iaW5kKHRoaXMpLFxuICAgICAgc2V0UmVhY2hhYmxlUG9pbnRSYW5nZTogdGhpcy5zZXRSZWFjaGFibGVQb2ludFJhbmdlLmJpbmQodGhpcyksXG4gICAgICByZW1vdmVMaW5lOiB0aGlzLnJlbW92ZUxpbmUuYmluZCh0aGlzKSxcbiAgICAgIHJlbW92ZVJlYWNoYWJsZVBvaW50UmFuZ2U6IHRoaXMucmVtb3ZlUmVhY2hhYmxlUG9pbnRSYW5nZS5iaW5kKHRoaXMpLFxuICAgICAgdXBkYXRlVmlld0JveDogdGhpcy51cGRhdGVWaWV3Qm94LmJpbmQodGhpcyksXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0RGF0YShkYXRhOiBBcnJheTxJRHJhd0xpbmVEYXRhSW5wdXQ+KSB7XG4gICAgY29uc3QgbmV3RGF0YTogQXJyYXk8SURyYXdMaW5lRGF0YUlucHV0PiA9IFtdO1xuXG4gICAgZGF0YS5mb3JFYWNoKChpdGVtKSA9PiB7XG4gICAgICBpZiAoXG4gICAgICAgIHRoaXMuZGF0YURyYXcuZmluZChcbiAgICAgICAgICAoZGF0YURyYXcpID0+IGRhdGFEcmF3LmlkID09PSBpdGVtLmlkICYmIGl0ZW0ucG9pbnRzLnN0YXJ0LnggPT09IGRhdGFEcmF3LnBvaW50cy5zdGFydC54ICYmIGl0ZW0ucG9pbnRzLnN0YXJ0LnkgPT09IGRhdGFEcmF3LnBvaW50cy5zdGFydC55ICYmIGl0ZW0ucG9pbnRzLmVuZC54ID09PSBkYXRhRHJhdy5wb2ludHMuZW5kLnggJiYgaXRlbS5wb2ludHMuZW5kLnkgPT09IGRhdGFEcmF3LnBvaW50cy5lbmQueVxuICAgICAgICApXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgaXRlbUNsb25lID0gY2xvbmVEZWVwKGl0ZW0pO1xuXG4gICAgICBpdGVtQ2xvbmUucmVmID0gaXRlbTtcbiAgICAgIG5ld0RhdGEucHVzaChpdGVtQ2xvbmUpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5kYXRhRHJhdy5wdXNoKC4uLm5ld0RhdGEpO1xuICAgIHRoaXMuc3RhcnRQcm9jZXNzRGF0YVJvdyhuZXdEYXRhKTtcbiAgfVxuXG4gIHNldFJlYWNoYWJsZVBvaW50UmFuZ2UoZGF0YTogQXJyYXk8SVJlYWNoYWJsZVBvaW50UmFuZ2U+KSB7XG4gICAgY29uc3QgbmV3RGF0YTogQXJyYXk8SVJlYWNoYWJsZVBvaW50UmFuZ2U+ID0gW107XG5cbiAgICBkYXRhLmZvckVhY2goKGl0ZW0pID0+IHtcbiAgICAgIGlmICh0aGlzLmRhdGFSZWFjaGFibGVQb2ludFJhbmdlLmZpbmQoKGRhdGFEcmF3KSA9PiBkYXRhRHJhdy5pZCA9PT0gaXRlbS5pZCB8fCAoaXRlbS54ID09PSBkYXRhRHJhdy54ICYmIGl0ZW0ueSA9PT0gZGF0YURyYXcueSkpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGl0ZW1DbG9uZSA9IGNsb25lRGVlcChpdGVtKTtcblxuICAgICAgaXRlbUNsb25lLnJlZiA9IGl0ZW07XG4gICAgICBuZXdEYXRhLnB1c2goaXRlbUNsb25lKTtcbiAgICB9KTtcblxuICAgIHRoaXMuZGF0YVJlYWNoYWJsZVBvaW50UmFuZ2UucHVzaCguLi5uZXdEYXRhKTtcbiAgICB0aGlzLnN0YXJ0UHJvY2Vzc0RhdGFSZWFjaGFibGVQb2ludFJhbmdlKG5ld0RhdGEpO1xuICB9XG5cbiAgcHJpdmF0ZSByZW1vdmVMaW5lKGlkOiBzdHJpbmcsIHBvaW50cz86IEFycmF5PElQb2ludHM+KSB7XG4gICAgY29uc3QgZGF0YURyYXdCeUlkID0gdGhpcy5kYXRhRHJhdy5maWx0ZXIoKGl0ZW0pID0+IGl0ZW0uaWQgPT09IGlkKTtcblxuICAgIGlmICghZGF0YURyYXdCeUlkPy5sZW5ndGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCByZW1vdmVCeUl0ZW0gPSAoaXRlbTogSURyYXdMaW5lRGF0YUlucHV0KSA9PiB7XG4gICAgICB0aGlzLnJlbW92ZUVsZW1lbnRPZlBvaW50cyhpdGVtLnBvaW50cyk7XG4gICAgICBpdGVtLnBvaW50cy5zZXBhcmF0ZWRQb2ludHM/LmZvckVhY2goKHNlcGFyYXRlZFBvaW50cykgPT4gdGhpcy5yZW1vdmVFbGVtZW50T2ZQb2ludHMoc2VwYXJhdGVkUG9pbnRzKSk7XG4gICAgfTtcblxuICAgIGlmICghcG9pbnRzPy5sZW5ndGgpIHtcbiAgICAgIGRhdGFEcmF3QnlJZC5mb3JFYWNoKChpdGVtKSA9PiByZW1vdmVCeUl0ZW0oaXRlbSkpO1xuICAgICAgdGhpcy5kYXRhRHJhdyA9IHRoaXMuZGF0YURyYXcuZmlsdGVyKChpdGVtKSA9PiBpdGVtLmlkICE9PSBpZCk7XG4gICAgICB0aGlzLnVwZGF0ZVZpZXdCb3goKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHBvaW50cy5mb3JFYWNoKChwb2ludCkgPT4ge1xuICAgICAgY29uc3QgZGF0YURyYXdSZW1vdmVCeVBvaW50ID0gZGF0YURyYXdCeUlkLmZpbmQoKGl0ZW0pID0+IGl0ZW0ucG9pbnRzLnN0YXJ0LnggPT09IHBvaW50LnN0YXJ0LnggJiYgaXRlbS5wb2ludHMuc3RhcnQueSA9PT0gcG9pbnQuc3RhcnQueSAmJiBpdGVtLnBvaW50cy5lbmQueCA9PT0gcG9pbnQuZW5kLnggJiYgaXRlbS5wb2ludHMuZW5kLnkgPT09IHBvaW50LmVuZC55KTtcblxuICAgICAgaWYgKGRhdGFEcmF3UmVtb3ZlQnlQb2ludCkge1xuICAgICAgICBkYXRhRHJhd1JlbW92ZUJ5UG9pbnQuaXNSZW1vdmUgPSB0cnVlO1xuICAgICAgICByZW1vdmVCeUl0ZW0oZGF0YURyYXdSZW1vdmVCeVBvaW50KTtcbiAgICAgICAgdGhpcy5kYXRhRHJhdyA9IHRoaXMuZGF0YURyYXcuZmlsdGVyKChpdGVtKSA9PiBpdGVtLmlkICE9PSBpZCAmJiAhaXRlbS5pc1JlbW92ZSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy51cGRhdGVWaWV3Qm94KCk7XG4gIH1cblxuICBwcml2YXRlIHJlbW92ZVJlYWNoYWJsZVBvaW50UmFuZ2UoaWRzOiBBcnJheTxzdHJpbmc+KSB7XG4gICAgdGhpcy5jbGVhclJlY3QoKTtcbiAgICBpZiAoIWlkcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZHMuZm9yRWFjaCgoaWQpID0+IHtcbiAgICAgIGNvbnN0IGl0ZW1SZW1vdmUgPSB0aGlzLmRhdGFSZWFjaGFibGVQb2ludFJhbmdlPy5maW5kKChpdGVtKSA9PiBpdGVtLmlkID09PSBpZCk7XG5cbiAgICAgIGlmICghaXRlbVJlbW92ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpdGVtUmVtb3ZlLm9uRGVzdHJveUV2ZW50Py5uZXh0KCk7XG4gICAgICBpdGVtUmVtb3ZlLmVsZW1lbnQ/LnJlbW92ZSgpO1xuICAgICAgdGhpcy5kYXRhUmVhY2hhYmxlUG9pbnRSYW5nZSA9IHRoaXMuZGF0YVJlYWNoYWJsZVBvaW50UmFuZ2U/LmZpbHRlcigoaXRlbSkgPT4gaXRlbS5pZCAhPT0gaWQpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGFydFByb2Nlc3NEYXRhUm93KGRhdGFEcmF3OiBBcnJheTxJRHJhd0xpbmVEYXRhSW5wdXQ+KSB7XG4gICAgdGhpcy56b25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgIGRhdGFEcmF3LmZvckVhY2goKGl0ZW0pID0+IHtcbiAgICAgICAgY29uc3QgeyBwYXRoRWxlbWVudCwgYXJyb3dFbGVtZW50LCBjaXJjbGVTdGFydEVsZW1lbnQsIGNpcmNsZUVuZEVsZW1lbnQgfSA9IHRoaXMuY3JlYXRlUGF0aEFuZEFycm93RWxlbWVudChpdGVtLmlkKTtcblxuICAgICAgICBpdGVtLnBvaW50cy5vYnN0YWNsZVJlY3Q/LmZvckVhY2goKGRhdGEpID0+IHRoaXMuYWRkUmVjdCgncmVjdCcsIGRhdGEpKTtcbiAgICAgICAgaXRlbS5wb2ludHMucGF0aEVsZW1lbnQgPSBwYXRoRWxlbWVudDtcbiAgICAgICAgaXRlbS5wb2ludHMuYXJyb3dFbGVtZW50ID0gYXJyb3dFbGVtZW50O1xuICAgICAgICBpZiAoaXRlbS5zdGFydENpcmNsZSkge1xuICAgICAgICAgIGl0ZW0ucG9pbnRzLmNpcmNsZVN0YXJ0RWxlbWVudCA9IGNpcmNsZVN0YXJ0RWxlbWVudDtcbiAgICAgICAgICB0aGlzLnN2Z0VsZW1lbnQuYXBwZW5kKGNpcmNsZVN0YXJ0RWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGl0ZW0uZW5kQ2lyY2xlKSB7XG4gICAgICAgICAgaXRlbS5wb2ludHMuY2lyY2xlRW5kRWxlbWVudCA9IGNpcmNsZUVuZEVsZW1lbnQ7XG4gICAgICAgICAgdGhpcy5zdmdFbGVtZW50LmFwcGVuZChjaXJjbGVFbmRFbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgICBpdGVtLnBvaW50cy5vbkRlc3Ryb3lFdmVudCA9IG5ldyBTdWJqZWN0KCk7XG4gICAgICAgIHRoaXMuZHJhd0xpbmUoaXRlbSk7XG4gICAgICB9KTtcbiAgICAgIHRoaXMudXBkYXRlVmlld0JveCgpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGFydFByb2Nlc3NEYXRhUmVhY2hhYmxlUG9pbnRSYW5nZShkYXRhOiBBcnJheTxJUmVhY2hhYmxlUG9pbnRSYW5nZT4pIHtcbiAgICB0aGlzLnpvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgZGF0YS5mb3JFYWNoKChpdGVtKSA9PiB7XG4gICAgICAgIGl0ZW0ub25EZXN0cm95RXZlbnQgPSBuZXcgU3ViamVjdCgpO1xuICAgICAgICBpdGVtLmVsZW1lbnQgPSB0aGlzLmNyZWF0ZVBhdGhBbmRBcnJvd0VsZW1lbnQoaXRlbS5pZCkuY2lyY2xlRW5kRWxlbWVudDtcbiAgICAgICAgdGhpcy5zdmdFbGVtZW50LmFwcGVuZChpdGVtLmVsZW1lbnQpO1xuICAgICAgICB0aGlzLnVwZGF0ZUF0dHJpYnV0ZUNpcmNsZShpdGVtLmVsZW1lbnQsIGl0ZW0uaWQsIGl0ZW0sIGl0ZW0uc3R5bGUpO1xuICAgICAgICB0aGlzLm9uRHJhd0xpbmVFbmQucGlwZSh0YWtlVW50aWwoaXRlbS5vbkRlc3Ryb3lFdmVudCksIHRha2VVbnRpbCh0aGlzLm9uRGVzdHJveSkpLnN1YnNjcmliZSgoZXZlbnREYXRhKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBkYXRhTGluZSwgZXZlbnQgfSA9IGV2ZW50RGF0YTtcblxuICAgICAgICAgIGlmICghY2hlY2tNb3VzZU92ZXJJbkNvbnRhaW5lcihldmVudCwgaXRlbS5lbGVtZW50IGFzIHVua25vd24gYXMgSFRNTEVsZW1lbnQpIHx8ICFkYXRhTGluZS5yZWYgfHwgIWl0ZW0ucmVmKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaXRlbS5pZENvbm5lY3RlZCA9IGV2ZW50RGF0YS5kYXRhTGluZS5pZDtcbiAgICAgICAgICBldmVudERhdGEuZGF0YUxpbmUuaWRDb25uZWN0ZWQgPSBpdGVtLmlkO1xuICAgICAgICAgIHRoaXMub3V0Q29ubmVjdGVkLmVtaXQoe1xuICAgICAgICAgICAgZGF0YUxpbmU6IGRhdGFMaW5lLnJlZixcbiAgICAgICAgICAgIGRhdGFSZWFjaGFibGVQb2ludFJhbmdlOiBpdGVtLnJlZixcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIHRoaXMudXBkYXRlVmlld0JveCgpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSByZW1vdmVFbGVtZW50T2ZQb2ludHMocG9pbnRzOiBJUG9pbnRzKSB7XG4gICAgdGhpcy56b25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgIHBvaW50cy5vbkRlc3Ryb3lFdmVudD8ubmV4dCgpO1xuICAgICAgcG9pbnRzLm9uRGVzdHJveUV2ZW50Py5jb21wbGV0ZSgpO1xuICAgICAgcG9pbnRzPy5wYXRoRWxlbWVudD8ucmVtb3ZlKCk7XG4gICAgICBwb2ludHM/LmFycm93RWxlbWVudD8ucmVtb3ZlKCk7XG4gICAgICBwb2ludHM/LmNpcmNsZVN0YXJ0RWxlbWVudD8ucmVtb3ZlKCk7XG4gICAgICBwb2ludHMuY2lyY2xlRW5kRWxlbWVudD8ucmVtb3ZlKCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGRyYXdMaW5lKGRhdGE6IElEcmF3TGluZURhdGFJbnB1dCkge1xuICAgIHRoaXMuem9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICBjb25zdCB7IHBvaW50cywgbW9kZSB9ID0gZGF0YTtcbiAgICAgIGxldCB7IGN1cnZlIH0gPSBkYXRhPy5saW5lU3R5bGUgfHwge307XG5cbiAgICAgIGlmIChtb2RlICE9PSAncXVhcnQtaW4nKSB7XG4gICAgICAgIGN1cnZlID0gY3VydmUgPz8gMTA7XG4gICAgICB9XG4gICAgICBjb25zdCBwcmVMZW5ndGhTZXBhcmF0ZWRQb2ludHMgPSBwb2ludHMuc2VwYXJhdGVkUG9pbnRzPy5sZW5ndGg7XG5cbiAgICAgIHBvaW50cy5zZXBhcmF0ZWRQb2ludHM/LmZvckVhY2goKHNlcGFyYXRlZFBvaW50cykgPT4gdGhpcy5yZW1vdmVFbGVtZW50T2ZQb2ludHMoc2VwYXJhdGVkUG9pbnRzKSk7XG4gICAgICBwb2ludHMuc2VwYXJhdGVkUG9pbnRzID0gW107XG4gICAgICBNb0NhbnZhc0Nvbm5lY3ROYXZpZ2F0aW9uTmV3RWxlbWVudFV0aWwuU1RBUlRfTU9ERSA9ICdyaWdodC1sZWZ0JztcbiAgICAgIGlmIChkYXRhLnN0YXJ0RW5kTW9kZSkge1xuICAgICAgICBNb0NhbnZhc0Nvbm5lY3ROYXZpZ2F0aW9uTmV3RWxlbWVudFV0aWwuU1RBUlRfTU9ERSA9IGRhdGEuc3RhcnRFbmRNb2RlO1xuICAgICAgfVxuICAgICAgdGhpcy5jYWxjdWxhdG9yU2VwYXJhdGVkUG9pbnRzKGRhdGEuaWQsIHBvaW50cywgY3VydmUgfHwgMTAsIHBvaW50cy5zZXBhcmF0ZWRQb2ludHMsIHBvaW50cy5vYnN0YWNsZVJlY3QgfHwgW10pO1xuICAgICAgaWYgKCFwcmVMZW5ndGhTZXBhcmF0ZWRQb2ludHMgJiYgcG9pbnRzLnNlcGFyYXRlZFBvaW50cy5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5yZW1vdmVFbGVtZW50T2ZQb2ludHMocG9pbnRzKTtcbiAgICAgICAgY29uc3QgeyBwYXRoRWxlbWVudCwgYXJyb3dFbGVtZW50IH0gPSB0aGlzLmNyZWF0ZVBhdGhBbmRBcnJvd0VsZW1lbnQoZGF0YS5pZCk7XG5cbiAgICAgICAgcG9pbnRzLnBhdGhFbGVtZW50ID0gcGF0aEVsZW1lbnQ7XG4gICAgICAgIHBvaW50cy5hcnJvd0VsZW1lbnQgPSBhcnJvd0VsZW1lbnQ7XG4gICAgICAgIHBvaW50cy5pbml0aWFsaXplZCA9IGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKCFwb2ludHMuc2VwYXJhdGVkUG9pbnRzPy5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5idWlsZFBhdGhBbmREcmF3KGRhdGEsIHBvaW50cywgbW9kZSk7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBsZXQgcGF0aCA9ICcnO1xuXG4gICAgICBwb2ludHMuc2VwYXJhdGVkUG9pbnRzLmZvckVhY2goKHNlcGFyYXRlZFBvaW50cykgPT4ge1xuICAgICAgICBwYXRoICs9IHRoaXMuYnVpbGRQYXRoQW5kRHJhd1NlcGFyYXRlZFBvaW50cyhkYXRhLCBzZXBhcmF0ZWRQb2ludHMsIHNlcGFyYXRlZFBvaW50cy5tb2RlIHx8IG1vZGUpO1xuICAgICAgfSk7XG4gICAgICBjb25zdCBwYXRoRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCAncGF0aCcpO1xuXG4gICAgICB0aGlzLnN2Z0VsZW1lbnQuYXBwZW5kKHBhdGhFbGVtZW50KTtcbiAgICAgIHBvaW50cy5wYXRoRWxlbWVudCA9IHBhdGhFbGVtZW50O1xuICAgICAgY29uc3Qgc3R5bGVDb25maWcgPSB7XG4gICAgICAgIHN0cm9rZTogZGF0YS5saW5lU3R5bGU/LnN0cm9rZSA/PyAnIzlDQTJBRCcsXG4gICAgICAgIHN0cm9rZURhc2hhcnJheTogZGF0YS5saW5lU3R5bGU/LnN0cm9rZURhc2hhcnJheSxcbiAgICAgICAgc3Ryb2tlV2lkdGg6IGRhdGEubGluZVN0eWxlPy5zdHJva2VXaWR0aCA/PyAnMXB4JyxcbiAgICAgICAgZmlsbDogZGF0YS5saW5lU3R5bGU/LmZpbGwgPz8gJ25vbmUnLFxuICAgICAgICBjdXJ2ZTogZGF0YS5saW5lU3R5bGU/LmN1cnZlID8/IDEwLFxuICAgICAgICBkaXN0YW5jZVBvaW50OiBkYXRhLmxpbmVTdHlsZT8uZGlzdGFuY2VQb2ludCA/PyAxMCxcbiAgICAgIH07XG5cbiAgICAgIHBvaW50cy5wYXRoRWxlbWVudD8uc2V0QXR0cmlidXRlKCdzdHJva2UnLCBzdHlsZUNvbmZpZy5zdHJva2UpO1xuICAgICAgcG9pbnRzLnBhdGhFbGVtZW50Py5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCBzdHlsZUNvbmZpZy5maWxsKTtcbiAgICAgIHBvaW50cy5wYXRoRWxlbWVudD8uc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCBzdHlsZUNvbmZpZy5zdHJva2VXaWR0aCk7XG4gICAgICBpZiAoc3R5bGVDb25maWcuc3Ryb2tlRGFzaGFycmF5KSB7XG4gICAgICAgIHBvaW50cy5wYXRoRWxlbWVudD8uc2V0QXR0cmlidXRlKCdzdHJva2UtZGFzaGFycmF5Jywgc3R5bGVDb25maWcuc3Ryb2tlRGFzaGFycmF5KTtcbiAgICAgIH1cbiAgICAgIHBvaW50cy5wYXRoRWxlbWVudD8uc2V0QXR0cmlidXRlKCdkJywgcGF0aCk7XG4gICAgICB0aGlzLmRyYXdSZWN0QW5kSW5pdEV2ZW50KGRhdGEsIG1vZGUpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVWaWV3Qm94KHZpZXdCb3hDb25maWc/OiBJVmlld0JveENvbmZpZykge1xuICAgIGlmICh2aWV3Qm94Q29uZmlnKSB7XG4gICAgICB0aGlzLnZpZXdCb3hDb25maWcgPSB2aWV3Qm94Q29uZmlnO1xuICAgIH1cbiAgICBjb25zdCB4UG9pbnRzOiBTZXQ8bnVtYmVyPiA9IG5ldyBTZXQoWzBdKTtcbiAgICBjb25zdCB5UG9pbnRzOiBTZXQ8bnVtYmVyPiA9IG5ldyBTZXQoWzBdKTtcblxuICAgIGNvbnN0IGFkZFBvaW50cyA9IChwb2ludHM6IElQb2ludHMpID0+IHtcbiAgICAgIHhQb2ludHMuYWRkKHBvaW50cy5zdGFydC54KTtcbiAgICAgIHhQb2ludHMuYWRkKHBvaW50cy5lbmQueCk7XG4gICAgICB5UG9pbnRzLmFkZChwb2ludHMuc3RhcnQueSk7XG4gICAgICB5UG9pbnRzLmFkZChwb2ludHMuZW5kLnkpO1xuICAgIH07XG5cbiAgICB0aGlzLmRhdGFEcmF3Py5mb3JFYWNoKChpdGVtKSA9PiB7XG4gICAgICBjb25zdCBwb2ludHMgPSBpdGVtLnBvaW50cztcblxuICAgICAgYWRkUG9pbnRzKHBvaW50cyk7XG4gICAgICBwb2ludHMuc2VwYXJhdGVkUG9pbnRzPy5mb3JFYWNoKChzZXBhcmF0ZWRQb2ludHMpID0+IGFkZFBvaW50cyhzZXBhcmF0ZWRQb2ludHMpKTtcbiAgICAgIHBvaW50cy5vYnN0YWNsZVJlY3Q/LmZvckVhY2goKG9ic3RhY2xlUmVjdCkgPT4ge1xuICAgICAgICBhZGRQb2ludHMoe1xuICAgICAgICAgIHN0YXJ0OiB7IHg6IG9ic3RhY2xlUmVjdC54IC0gKG9ic3RhY2xlUmVjdC5nYXBYT2JzdGFjbGVSZWN0IHx8IDgpLCB5OiBvYnN0YWNsZVJlY3QueSAtIChvYnN0YWNsZVJlY3QuZ2FwWU9ic3RhY2xlUmVjdCB8fCA4KSB9LFxuICAgICAgICAgIGVuZDogeyB4OiBvYnN0YWNsZVJlY3QueCArIG9ic3RhY2xlUmVjdC53aWR0aCArIChvYnN0YWNsZVJlY3QuZ2FwWE9ic3RhY2xlUmVjdCB8fCA4KSAqIDIsIHk6IG9ic3RhY2xlUmVjdC55ICsgb2JzdGFjbGVSZWN0LmhlaWdodCArIChvYnN0YWNsZVJlY3QuZ2FwWU9ic3RhY2xlUmVjdCB8fCA4KSAqIDIgfSxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHhNYXggPSB0aGlzLnZpZXdCb3hDb25maWc/LndpZHRoID8/ICh4UG9pbnRzLnNpemUgPyBNYXRoLm1heCguLi54UG9pbnRzKSA6IDApICsgMTQ7XG4gICAgY29uc3QgeU1heCA9IHRoaXMudmlld0JveENvbmZpZz8uaGVpZ2h0ID8/ICh5UG9pbnRzLnNpemUgPyBNYXRoLm1heCguLi55UG9pbnRzKSA6IDApICsgMTQ7XG5cbiAgICBpZiAoIXRoaXMudmlld0JveENvbmZpZz8uaWdub3JlVmlld0JveCkge1xuICAgICAgY29uc3QgcmVjdFN2Z0VsZW1lbnQgPSB0aGlzLnN2Z0VsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICAgIHRoaXMuc3ZnRWxlbWVudD8uc2V0QXR0cmlidXRlKCd2aWV3Qm94JywgYCR7dGhpcy52aWV3Qm94Q29uZmlnPy5taW5YID8/IHJlY3RTdmdFbGVtZW50Lnh9ICR7dGhpcy52aWV3Qm94Q29uZmlnPy5taW5ZID8/IHJlY3RTdmdFbGVtZW50Lnl9ICR7eE1heH0gJHt5TWF4fWApO1xuICAgIH1cbiAgICB0aGlzLnN2Z0VsZW1lbnQ/LnNldEF0dHJpYnV0ZSgnd2lkdGgnLCBgJHt4TWF4ID8/IDB9YCk7XG4gICAgdGhpcy5zdmdFbGVtZW50Py5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsIGAke3lNYXggPz8gMH1gKTtcbiAgfVxuXG4gIHByaXZhdGUgaXNQb2ludEluc2lkZVNxdWFyZShwb2ludDogSVBvaW50LCBzcXVhcmU6IElSZWN0KTogYm9vbGVhbiB7XG4gICAgY29uc3QgeyB4LCB5IH0gPSBwb2ludDtcbiAgICBjb25zdCB7IHg6IHNxdWFyZVgsIHk6IHNxdWFyZVksIHdpZHRoLCBoZWlnaHQgfSA9IHNxdWFyZTtcblxuICAgIHJldHVybiB4ID49IHNxdWFyZVggJiYgeCA8PSBzcXVhcmVYICsgd2lkdGggJiYgeSA+PSBzcXVhcmVZICYmIHkgPD0gc3F1YXJlWSArIGhlaWdodDtcbiAgfVxuXG4gIHByaXZhdGUgY2FsY3VsYXRvclNlcGFyYXRlZFBvaW50cyhuYW1lOiBzdHJpbmcsIHBvaW50czogSVBvaW50cywgY3VydmU6IG51bWJlciwgc2VwYXJhdGVkUG9pbnRzOiBBcnJheTxJUG9pbnRzPiwgb2JzdGFjbGVSZWN0czogQXJyYXk8SVJlY3Q+KSB7XG4gICAgaWYgKCFvYnN0YWNsZVJlY3RzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGVsZW1lbnRTdGFydCA9IG9ic3RhY2xlUmVjdHMuZmluZCgoaXRlbSkgPT4gdGhpcy5pc1BvaW50SW5zaWRlU3F1YXJlKHBvaW50cy5zdGFydCwgaXRlbSkpO1xuICAgIGNvbnN0IGVsZW1lbnRFbmQgPSBvYnN0YWNsZVJlY3RzLmZpbmQoKGl0ZW0pID0+IHRoaXMuaXNQb2ludEluc2lkZVNxdWFyZShwb2ludHMuZW5kLCBpdGVtKSk7XG5cbiAgICBpZiAodGhpcy52aWV3Qm94Q29uZmlnPy5tYXJnaW5CZXR3ZWVuRWxlbWVudCkge1xuICAgICAgTW9DYW52YXNDb25uZWN0TmF2aWdhdGlvbk5ld0VsZW1lbnRVdGlsLkVMRU1FTlRfTUFSR0lOX0JFVFdFRU5fQlJBTkNIX0RFRkFVTFQgPSB0aGlzLnZpZXdCb3hDb25maWc/Lm1hcmdpbkJldHdlZW5FbGVtZW50ID8/IDMyO1xuICAgIH1cbiAgICBNb0NhbnZhc0Nvbm5lY3ROYXZpZ2F0aW9uTmV3RWxlbWVudFV0aWwuc2V0WFlDb25uZWN0RWxlbWVudHMoZWxlbWVudFN0YXJ0ID8/IHsgLi4ucG9pbnRzLnN0YXJ0LCB3aWR0aDogMSwgaGVpZ2h0OiAxIH0sIGVsZW1lbnRFbmQgPz8geyAuLi5wb2ludHMuZW5kLCB3aWR0aDogMSwgaGVpZ2h0OiAxIH0sIG9ic3RhY2xlUmVjdHMsIHNlcGFyYXRlZFBvaW50cywgY3VydmUpO1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZFBhdGhBbmREcmF3KGRhdGE6IElEcmF3TGluZURhdGFJbnB1dCwgcG9pbnRzOiBJUG9pbnRzLCBtb2RlPzogVFlQRV9NT0RFKSB7XG4gICAgbGV0IGRQYXRoID0ge30gYXMgSUF0dHJpYnV0ZURPblBhdGg7XG4gICAgY29uc3Qgc3R5bGVDb25maWcgPSB7XG4gICAgICBzdHJva2U6IGRhdGEubGluZVN0eWxlPy5zdHJva2UgPz8gJyM5Q0EyQUQnLFxuICAgICAgc3Ryb2tlRGFzaGFycmF5OiBkYXRhLmxpbmVTdHlsZT8uc3Ryb2tlRGFzaGFycmF5LFxuICAgICAgc3Ryb2tlV2lkdGg6IGRhdGEubGluZVN0eWxlPy5zdHJva2VXaWR0aCA/PyAnMXB4JyxcbiAgICAgIGZpbGw6IGRhdGEubGluZVN0eWxlPy5maWxsID8/ICdub25lJyxcbiAgICAgIGN1cnZlOiBkYXRhLmxpbmVTdHlsZT8uY3VydmUgPz8gMTAsXG4gICAgICBkaXN0YW5jZVBvaW50OiBkYXRhLmxpbmVTdHlsZT8uZGlzdGFuY2VQb2ludCA/PyAxMCxcbiAgICB9O1xuXG4gICAgcG9pbnRzLnBhdGhFbGVtZW50Py5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsIHN0eWxlQ29uZmlnLnN0cm9rZSk7XG4gICAgcG9pbnRzLnBhdGhFbGVtZW50Py5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCBzdHlsZUNvbmZpZy5maWxsKTtcbiAgICBwb2ludHMucGF0aEVsZW1lbnQ/LnNldEF0dHJpYnV0ZSgnc3Ryb2tlLXdpZHRoJywgc3R5bGVDb25maWcuc3Ryb2tlV2lkdGgpO1xuICAgIGlmIChzdHlsZUNvbmZpZy5zdHJva2VEYXNoYXJyYXkpIHtcbiAgICAgIHBvaW50cy5wYXRoRWxlbWVudD8uc2V0QXR0cmlidXRlKCdzdHJva2UtZGFzaGFycmF5Jywgc3R5bGVDb25maWcuc3Ryb2tlRGFzaGFycmF5KTtcbiAgICB9XG4gICAgbGV0IHsgY3VydmUsIGRpc3RhbmNlUG9pbnQgfSA9IHN0eWxlQ29uZmlnO1xuXG4gICAgbW9kZSA9IG1vZGUgfHwgJ3F1YXJ0LWluJztcbiAgICBpZiAobW9kZSAhPT0gJ3F1YXJ0LWluJykge1xuICAgICAgY3VydmUgPSBjdXJ2ZSA/PyAxMDtcbiAgICAgIGRpc3RhbmNlUG9pbnQgPSBkaXN0YW5jZVBvaW50ID8/IDEwO1xuICAgIH1cbiAgICBpZiAobW9kZSA9PT0gJ3F1YXJ0LWluJyB8fCBwb2ludHMuc3RhcnQueCA9PT0gcG9pbnRzLmVuZC54IHx8IHBvaW50cy5zdGFydC55ID09PSBwb2ludHMuZW5kLnkpIHtcbiAgICAgIHRoaXMuZHJhd0JhbGFuY2VkQ3VydmUoZFBhdGgsIHBvaW50cyk7XG5cbiAgICAgIGlmIChtb2RlID09PSAncXVhcnQtaW4nKSB7XG4gICAgICAgIGRQYXRoID0ge30gYXMgSUF0dHJpYnV0ZURPblBhdGg7XG4gICAgICAgIHRoaXMuZHJhd0JlbmRCb3RoRW5kc0N1cnZlKGRQYXRoLCBwb2ludHMpO1xuICAgICAgfVxuICAgICAgcG9pbnRzLnBhdGhFbGVtZW50Py5zZXRBdHRyaWJ1dGUoJ2QnLCB0aGlzLmJ1aWxEQXR0cmlidXRlVG9TdHJpbmcoZFBhdGgpKTtcbiAgICAgIHRoaXMuZHJhd1JlY3RBbmRJbml0RXZlbnQoZGF0YSwgbW9kZSk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcmVzdWx0ID0gdGhpcy5jYWxjdWxhdG9yRGlzdGFuY2VQb2ludEFuZEN1cnZlKHBvaW50cywgZGlzdGFuY2VQb2ludCwgY3VydmUsIG1vZGUpO1xuXG4gICAgZGlzdGFuY2VQb2ludCA9IHJlc3VsdC5kaXN0YW5jZVBvaW50O1xuICAgIGN1cnZlID0gcmVzdWx0LmN1cnZlO1xuXG4gICAgdGhpcy5idWlsZERBdHRyaWJ1dGVCeVBvaW50RW5kTW9kZUhvcml6b250YWwoZFBhdGgsIHBvaW50cywgZGlzdGFuY2VQb2ludCB8fCAwLCBjdXJ2ZSB8fCAwLCBtb2RlKTtcbiAgICB0aGlzLmJ1aWxkREF0dHJpYnV0ZUJ5UG9pbnRFbmRNb2RlVmVydGljYWwoZFBhdGgsIHBvaW50cywgZGlzdGFuY2VQb2ludCB8fCAwLCBjdXJ2ZSB8fCAwLCBtb2RlKTtcbiAgICBwb2ludHMucGF0aEVsZW1lbnQ/LnNldEF0dHJpYnV0ZSgnZCcsIHRoaXMuYnVpbERBdHRyaWJ1dGVUb1N0cmluZyhkUGF0aCkpO1xuICAgIHRoaXMuZHJhd1JlY3RBbmRJbml0RXZlbnQoZGF0YSwgbW9kZSk7XG4gIH1cblxuICBwcml2YXRlIGNhbGN1bGF0b3JEaXN0YW5jZVBvaW50QW5kQ3VydmUocG9pbnRzOiBJUG9pbnRzLCBkaXN0YW5jZVBvaW50OiBudW1iZXIsIGN1cnZlOiBudW1iZXIsIG1vZGU6IFRZUEVfTU9ERSkge1xuICAgIGlmICghbW9kZS5pbmNsdWRlcygndmVydGljYWwnKSAmJiAhbW9kZS5pbmNsdWRlcygnaG9yaXpvbnRhbCcpKSB7XG4gICAgICByZXR1cm4geyBjdXJ2ZSwgZGlzdGFuY2VQb2ludCB9O1xuICAgIH1cbiAgICBjb25zdCBnYXBYID0gTWF0aC5hYnMocG9pbnRzLnN0YXJ0LnggLSBwb2ludHMuZW5kLngpO1xuICAgIGNvbnN0IGdhcFkgPSBNYXRoLmFicyhwb2ludHMuc3RhcnQueSAtIHBvaW50cy5lbmQueSk7XG4gICAgY29uc3QgbXVsdGlwbGllckN1cnZlID0gbW9kZS5pbmNsdWRlcygnaG9yaXpvbnRhbCcpID8gMSA6IDI7XG4gICAgY29uc3QgbXVsdGlwbGllckRpc3RhbmNlID0gbW9kZS5pbmNsdWRlcygnaG9yaXpvbnRhbCcpID8gMiA6IDE7XG5cbiAgICBpZiAoIW1vZGUuaW5jbHVkZXMoJ3NpbmdsZS1jdXJ2ZScpKSB7XG4gICAgICBpZiAoZ2FwWCA8IGRpc3RhbmNlUG9pbnQgKiBtdWx0aXBsaWVyRGlzdGFuY2UgKyBjdXJ2ZSAqIG11bHRpcGxpZXJDdXJ2ZSkge1xuICAgICAgICBkaXN0YW5jZVBvaW50ID0gY3VydmUgPSBnYXBYIC8gMztcbiAgICAgIH1cbiAgICAgIGlmIChnYXBZIDwgZGlzdGFuY2VQb2ludCAqIG11bHRpcGxpZXJEaXN0YW5jZSArIGN1cnZlICogbXVsdGlwbGllckN1cnZlKSB7XG4gICAgICAgIGRpc3RhbmNlUG9pbnQgPSBjdXJ2ZSA9IGdhcFkgLyAzO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4geyBjdXJ2ZSwgZGlzdGFuY2VQb2ludCB9O1xuICAgIH1cbiAgICBjb25zdCBtaW5HYXAgPSBNYXRoLm1pbihnYXBYLCBnYXBZKTtcblxuICAgIGlmIChtaW5HYXAgPCBkaXN0YW5jZVBvaW50KSB7XG4gICAgICBkaXN0YW5jZVBvaW50ID0gbWluR2FwO1xuICAgIH1cbiAgICBpZiAobWluR2FwIDwgY3VydmUpIHtcbiAgICAgIGN1cnZlID0gbWluR2FwO1xuICAgIH1cblxuICAgIHJldHVybiB7IGN1cnZlLCBkaXN0YW5jZVBvaW50IH07XG4gIH1cblxuICBwcml2YXRlIGRyYXdSZWN0QW5kSW5pdEV2ZW50KGRhdGE6IElEcmF3TGluZURhdGFJbnB1dCwgbW9kZTogVFlQRV9NT0RFKSB7XG4gICAgY29uc3QgcG9pbnRzID0gZGF0YS5wb2ludHM7XG5cbiAgICB0aGlzLnVwZGF0ZVN0eWxlQXJyb3cocG9pbnRzLCBtb2RlLCBkYXRhKTtcbiAgICBpZiAoZGF0YS5zdGFydENpcmNsZSAmJiBwb2ludHMuY2lyY2xlU3RhcnRFbGVtZW50KSB7XG4gICAgICB0aGlzLnVwZGF0ZUF0dHJpYnV0ZUNpcmNsZShwb2ludHMuY2lyY2xlU3RhcnRFbGVtZW50LCBkYXRhLmlkLCBwb2ludHMuc3RhcnQsIGRhdGEuc3RhcnRDaXJjbGVTdHlsZSk7XG4gICAgfVxuICAgIGlmIChkYXRhLmVuZENpcmNsZSAmJiBwb2ludHMuY2lyY2xlRW5kRWxlbWVudCkge1xuICAgICAgdGhpcy51cGRhdGVBdHRyaWJ1dGVDaXJjbGUocG9pbnRzLmNpcmNsZUVuZEVsZW1lbnQsIGRhdGEuaWQsIHBvaW50cy5lbmQsIGRhdGEuZW5kQ2lyY2xlU3R5bGUpO1xuICAgIH1cbiAgICB0aGlzLmluaXRFdmVudChkYXRhKTtcbiAgfVxuXG4gIHByaXZhdGUgZHJhd0JhbGFuY2VkQ3VydmUoZFBhdGg6IElBdHRyaWJ1dGVET25QYXRoLCBwb2ludHM6IElQb2ludHMpIHtcbiAgICBkUGF0aC5NID0geyB4OiBwb2ludHMuc3RhcnQueCwgeTogcG9pbnRzLnN0YXJ0LnkgfTtcbiAgICBkUGF0aC5RID0gW1xuICAgICAgeyB4OiBwb2ludHMuc3RhcnQueCArIChwb2ludHMuZW5kLnggLSBwb2ludHMuc3RhcnQueCkgLyA0LCB5OiBwb2ludHMuc3RhcnQueSArIChwb2ludHMuZW5kLnkgLSBwb2ludHMuc3RhcnQueSkgLyAyIH0sXG4gICAgICB7IHg6IHBvaW50cy5zdGFydC54ICsgKHBvaW50cy5lbmQueCAtIHBvaW50cy5zdGFydC54KSAvIDIsIHk6IHBvaW50cy5zdGFydC55ICsgKHBvaW50cy5lbmQueSAtIHBvaW50cy5zdGFydC55KSAvIDIgfSxcbiAgICBdO1xuICAgIGRQYXRoLlEyID0gW1xuICAgICAgeyB4OiBwb2ludHMuZW5kLnggLSAocG9pbnRzLmVuZC54IC0gcG9pbnRzLnN0YXJ0LngpIC8gNCwgeTogcG9pbnRzLnN0YXJ0LnkgKyAocG9pbnRzLmVuZC55IC0gcG9pbnRzLnN0YXJ0LnkpIC8gMiB9LFxuICAgICAgeyB4OiBwb2ludHMuZW5kLngsIHk6IHBvaW50cy5lbmQueSB9LFxuICAgIF07XG4gIH1cblxuICBwcml2YXRlIGRyYXdCZW5kQm90aEVuZHNDdXJ2ZShkUGF0aDogSUF0dHJpYnV0ZURPblBhdGgsIHBvaW50czogSVBvaW50cykge1xuICAgIGNvbnN0IHBvaW50WEN1cnZlID0gKHBvaW50cy5zdGFydC54ICsgcG9pbnRzLmVuZC54KSAqIDAuNTtcbiAgICBjb25zdCBwb2ludENvbnRyb2wxID0geyB4OiBwb2ludFhDdXJ2ZSwgeTogcG9pbnRzLnN0YXJ0LnkgfTtcbiAgICBjb25zdCBwb2ludENvbnRyb2wyID0geyB4OiBwb2ludFhDdXJ2ZSwgeTogcG9pbnRzLmVuZC55IH07XG5cbiAgICBkUGF0aC5NID0geyB4OiBwb2ludHMuc3RhcnQueCwgeTogcG9pbnRzLnN0YXJ0LnkgfTtcbiAgICBkUGF0aC5DID0gW1xuICAgICAgeyB4OiBwb2ludENvbnRyb2wxLngsIHk6IHBvaW50Q29udHJvbDEueSB9LFxuICAgICAgeyB4OiBwb2ludENvbnRyb2wyLngsIHk6IHBvaW50Q29udHJvbDIueSB9LFxuICAgICAgeyB4OiBwb2ludHMuZW5kLngsIHk6IHBvaW50cy5lbmQueSB9LFxuICAgIF07XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkREF0dHJpYnV0ZUJ5UG9pbnRFbmRNb2RlSG9yaXpvbnRhbChkUGF0aDogSUF0dHJpYnV0ZURPblBhdGgsIHBvaW50czogSVBvaW50cywgZGlzdGFuY2VQb2ludDogbnVtYmVyLCBjdXJ2ZTogbnVtYmVyLCBtb2RlOiBUWVBFX01PREUpIHtcbiAgICBpZiAoIW1vZGUuaW5jbHVkZXMoJ2hvcml6b250YWwnKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBtdWx0aXBsaWVyWCA9IHBvaW50cy5zdGFydC54IDwgcG9pbnRzLmVuZC54ID8gLTEgOiAxO1xuICAgIGNvbnN0IG11bHRpcGxpZXJZID0gcG9pbnRzLnN0YXJ0LnkgPCBwb2ludHMuZW5kLnkgPyAxIDogLTE7XG4gICAgY29uc3QgcmV2ZXJzZU11bHRpcGxpZXIgPSAtMTtcblxuICAgIGRQYXRoLk0gPSB7IHg6IHBvaW50cy5zdGFydC54LCB5OiBwb2ludHMuc3RhcnQueSB9O1xuICAgIGRQYXRoLkwgPSB7IHg6IHBvaW50cy5lbmQueCArIChkaXN0YW5jZVBvaW50ICogMiArIGN1cnZlKSAqIG11bHRpcGxpZXJYLCB5OiBwb2ludHMuc3RhcnQueSB9O1xuICAgIGlmIChtb2RlLmluY2x1ZGVzKCdob3Jpem9udGFsLXNpbmdsZScpKSB7XG4gICAgICBkUGF0aC5MLnggPSBwb2ludHMuZW5kLnggKyBjdXJ2ZSAqIG11bHRpcGxpZXJYO1xuICAgIH1cbiAgICBkUGF0aC5RID0gW1xuICAgICAgeyB4OiBkUGF0aC5MLnggKyBjdXJ2ZSAqIG11bHRpcGxpZXJYICogcmV2ZXJzZU11bHRpcGxpZXIsIHk6IHBvaW50cy5zdGFydC55IH0sXG4gICAgICB7IHg6IGRQYXRoLkwueCArIGN1cnZlICogbXVsdGlwbGllclggKiByZXZlcnNlTXVsdGlwbGllciwgeTogcG9pbnRzLnN0YXJ0LnkgKyBjdXJ2ZSAqIG11bHRpcGxpZXJZIH0sXG4gICAgXTtcbiAgICBkUGF0aC5MMiA9IHsgeDogZFBhdGguUVsxXS54LCB5OiBwb2ludHMuZW5kLnkgKyBjdXJ2ZSAqIG11bHRpcGxpZXJZICogcmV2ZXJzZU11bHRpcGxpZXIgfTtcbiAgICBpZiAobW9kZS5pbmNsdWRlcygnaG9yaXpvbnRhbC1zaW5nbGUnKSkge1xuICAgICAgZFBhdGguTDIgPSBwb2ludHMuZW5kO1xuICAgIH1cbiAgICBpZiAobW9kZSA9PT0gJ2hvcml6b250YWwnKSB7XG4gICAgICBkUGF0aC5RMiA9IFtcbiAgICAgICAgeyB4OiBkUGF0aC5MMi54LCB5OiBwb2ludHMuZW5kLnkgfSxcbiAgICAgICAgeyB4OiBkUGF0aC5MMi54ICsgZGlzdGFuY2VQb2ludCAqIG11bHRpcGxpZXJYICogcmV2ZXJzZU11bHRpcGxpZXIsIHk6IHBvaW50cy5lbmQueSB9LFxuICAgICAgXTtcbiAgICAgIGRQYXRoLkwzID0geyB4OiBwb2ludHMuZW5kLngsIHk6IHBvaW50cy5lbmQueSB9O1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYnVpbGREQXR0cmlidXRlQnlQb2ludEVuZE1vZGVWZXJ0aWNhbChkUGF0aDogSUF0dHJpYnV0ZURPblBhdGgsIHBvaW50czogSVBvaW50cywgZGlzdGFuY2VQb2ludDogbnVtYmVyLCBjdXJ2ZTogbnVtYmVyLCBtb2RlOiBUWVBFX01PREUpIHtcbiAgICBpZiAoIW1vZGUuaW5jbHVkZXMoJ3ZlcnRpY2FsJykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgbXVsdGlwbGllclggPSBwb2ludHMuc3RhcnQueCA8IHBvaW50cy5lbmQueCA/IC0xIDogMTtcbiAgICBjb25zdCBtdWx0aXBsaWVyWSA9IHBvaW50cy5zdGFydC55IDwgcG9pbnRzLmVuZC55ID8gMSA6IC0xO1xuICAgIGNvbnN0IHJldmVyc2VNdWx0aXBsaWVyID0gLTE7XG5cbiAgICBkUGF0aC5NID0gcG9pbnRzLnN0YXJ0O1xuICAgIGRQYXRoLkwgPSB7IHg6IHBvaW50cy5zdGFydC54LCB5OiBwb2ludHMuc3RhcnQueSArIGRpc3RhbmNlUG9pbnQgKiBtdWx0aXBsaWVyWSB9O1xuICAgIGlmIChtb2RlLmluY2x1ZGVzKCd2ZXJ0aWNhbC1zaW5nbGUnKSkge1xuICAgICAgZFBhdGguTC55ID0gcG9pbnRzLmVuZC55ICsgZGlzdGFuY2VQb2ludCAqIG11bHRpcGxpZXJZICogcmV2ZXJzZU11bHRpcGxpZXI7XG4gICAgfVxuICAgIGRQYXRoLlEgPSBbXG4gICAgICB7IHg6IGRQYXRoLkwueCwgeTogZFBhdGguTC55ICsgY3VydmUgKiBtdWx0aXBsaWVyWSB9LFxuICAgICAgeyB4OiBkUGF0aC5MLnggKyBjdXJ2ZSAqIG11bHRpcGxpZXJYICogcmV2ZXJzZU11bHRpcGxpZXIsIHk6IGRQYXRoLkwueSArIGN1cnZlICogbXVsdGlwbGllclkgfSxcbiAgICBdO1xuICAgIGRQYXRoLkwyID0geyB4OiBwb2ludHMuZW5kLnggKyBjdXJ2ZSAqIDIgKiBtdWx0aXBsaWVyWCwgeTogZFBhdGguUVsxXS55IH07XG4gICAgaWYgKG1vZGUuaW5jbHVkZXMoJ3ZlcnRpY2FsLXNpbmdsZScpKSB7XG4gICAgICBkUGF0aC5MMiA9IHBvaW50cy5lbmQ7XG4gICAgfVxuICAgIGlmIChtb2RlID09PSAndmVydGljYWwnKSB7XG4gICAgICBkUGF0aC5RMiA9IFtcbiAgICAgICAgeyB4OiBwb2ludHMuZW5kLngsIHk6IGRQYXRoLkwyLnkgfSxcbiAgICAgICAgeyB4OiBwb2ludHMuZW5kLngsIHk6IGRQYXRoLkwyLnkgKyBjdXJ2ZSAqIG11bHRpcGxpZXJZIH0sXG4gICAgICBdO1xuICAgICAgZFBhdGguTDMgPSB7IHg6IHBvaW50cy5lbmQueCwgeTogcG9pbnRzLmVuZC55IH07XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBidWlsREF0dHJpYnV0ZVRvU3RyaW5nKGRBdHRyaWJ1dGU6IElBdHRyaWJ1dGVET25QYXRoKTogc3RyaW5nIHtcbiAgICBsZXQgZFN0cmluZyA9ICcnO1xuXG4gICAgT2JqZWN0LmtleXMoZEF0dHJpYnV0ZSkuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICBjb25zdCBkYXRhID0gZ2V0KGRBdHRyaWJ1dGUsIGtleSBhcyBrZXlvZiBJQXR0cmlidXRlRE9uUGF0aCk7XG5cbiAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgIGNvbnN0IFtwb2ludDEsIHBvaW50MiwgcG9pbnQzXSA9IGRhdGE7XG5cbiAgICAgICAgZFN0cmluZyA9IGAke2RTdHJpbmd9JHtrZXkucmVwbGFjZSgvXFxkL2csICcnKX0ke3BvaW50MS54fSwke3BvaW50MS55fSAke3BvaW50Mi54fSwke3BvaW50Mi55fSR7cG9pbnQzID8gJyAnICsgcG9pbnQzLnggKyAnLCcgKyBwb2ludDMueSA6ICcnfVxuICAgICAgICBgO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGRTdHJpbmcgPSBgJHtkU3RyaW5nfSR7a2V5LnJlcGxhY2UoL1xcZC9nLCAnJyl9JHtkYXRhPy54fSwke2RhdGE/Lnl9XG4gICAgICBgO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIGRTdHJpbmc7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZVN0eWxlQXJyb3cocG9pbnRzOiBJUG9pbnRzLCBtb2RlOiBUWVBFX01PREUsIGRhdGE6IElEcmF3TGluZURhdGFJbnB1dCkge1xuICAgIGlmICghcG9pbnRzLmFycm93RWxlbWVudCB8fCBkYXRhLmlnbm9yZURyYXdBcnJvdykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBzdHlsZUNvbmZpZyA9IHtcbiAgICAgIGZpbGw6IGRhdGEuYXJyb3dTdHlsZT8uZmlsbCA/PyAnIzlDQTJBRCcsXG4gICAgICBzdHJva2U6IGRhdGEuYXJyb3dTdHlsZT8uc3Ryb2tlID8/ICdub25lJyxcbiAgICAgIHN0cm9rZVdpZHRoOiBkYXRhLmFycm93U3R5bGU/LnN0cm9rZVdpZHRoID8/ICcwJyxcbiAgICAgIHdpZHRoOiBkYXRhLmFycm93U3R5bGU/LndpZHRoID8/IDYsXG4gICAgICBoZWlnaHQ6IGRhdGEuYXJyb3dTdHlsZT8uaGVpZ2h0ID8/IDgsXG4gICAgfTtcbiAgICBjb25zdCBwb2ludEVuZCA9IGNsb25lRGVlcChwb2ludHMuZW5kKTtcbiAgICBjb25zdCBhcnJvd0VsZW1lbnQgPSBwb2ludHMuYXJyb3dFbGVtZW50O1xuICAgIGNvbnN0IGRpcmVjdGlvbiA9IGRhdGEuYXJyb3dEaXJlY3Rpb24gfHwgdGhpcy5nZXREaXJlY3Rpb24ocG9pbnRzLCBkYXRhLnN0YXJ0RW5kTW9kZSk7XG5cbiAgICBzd2l0Y2ggKGRpcmVjdGlvbikge1xuICAgICAgY2FzZSAncmlnaHQnOlxuICAgICAgICBpZiAobW9kZS5pbmNsdWRlcygnaG9yaXpvbnRhbCcpIHx8IG1vZGUuaW5jbHVkZXMoJ3ZlcnRpY2FsJykpIHtcbiAgICAgICAgICBwb2ludEVuZC54IC09IHN0eWxlQ29uZmlnLmhlaWdodDtcbiAgICAgICAgfVxuICAgICAgICBhcnJvd0VsZW1lbnQ/LnNldEF0dHJpYnV0ZSgncG9pbnRzJywgYCR7cG9pbnRFbmQueH0sJHtwb2ludEVuZC55IC0gc3R5bGVDb25maWcud2lkdGh9ICAke3BvaW50RW5kLnggKyBzdHlsZUNvbmZpZy5oZWlnaHR9LCR7cG9pbnRFbmQueX0gJHtwb2ludEVuZC54fSwke3BvaW50RW5kLnkgKyBzdHlsZUNvbmZpZy53aWR0aH0gYCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdsZWZ0JzpcbiAgICAgICAgaWYgKG1vZGUuaW5jbHVkZXMoJ2hvcml6b250YWwnKSB8fCBtb2RlLmluY2x1ZGVzKCd2ZXJ0aWNhbCcpKSB7XG4gICAgICAgICAgcG9pbnRFbmQueCArPSBzdHlsZUNvbmZpZy5oZWlnaHQ7XG4gICAgICAgIH1cbiAgICAgICAgYXJyb3dFbGVtZW50Py5zZXRBdHRyaWJ1dGUoJ3BvaW50cycsIGAke3BvaW50RW5kLnh9LCR7cG9pbnRFbmQueSAtIHN0eWxlQ29uZmlnLndpZHRofSAgJHtwb2ludEVuZC54IC0gc3R5bGVDb25maWcuaGVpZ2h0fSwke3BvaW50RW5kLnl9ICR7cG9pbnRFbmQueH0sJHtwb2ludEVuZC55ICsgc3R5bGVDb25maWcud2lkdGh9IGApO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAndG9wJzpcbiAgICAgICAgaWYgKG1vZGUuaW5jbHVkZXMoJ2hvcml6b250YWwnKSB8fCBtb2RlLmluY2x1ZGVzKCd2ZXJ0aWNhbCcpKSB7XG4gICAgICAgICAgcG9pbnRFbmQueSArPSBzdHlsZUNvbmZpZy5oZWlnaHQ7XG4gICAgICAgIH1cbiAgICAgICAgYXJyb3dFbGVtZW50Py5zZXRBdHRyaWJ1dGUoJ3BvaW50cycsIGAke3BvaW50RW5kLnggLSBzdHlsZUNvbmZpZy53aWR0aH0sJHtwb2ludEVuZC55fSAgJHtwb2ludEVuZC54fSwke3BvaW50RW5kLnkgLSBzdHlsZUNvbmZpZy5oZWlnaHR9ICR7cG9pbnRFbmQueCArIHN0eWxlQ29uZmlnLndpZHRofSwke3BvaW50RW5kLnl9IGApO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnYm90dG9tJzpcbiAgICAgICAgaWYgKG1vZGUuaW5jbHVkZXMoJ2hvcml6b250YWwnKSB8fCBtb2RlLmluY2x1ZGVzKCd2ZXJ0aWNhbCcpKSB7XG4gICAgICAgICAgcG9pbnRFbmQueSAtPSBzdHlsZUNvbmZpZy5oZWlnaHQ7XG4gICAgICAgIH1cbiAgICAgICAgYXJyb3dFbGVtZW50Py5zZXRBdHRyaWJ1dGUoJ3BvaW50cycsIGAke3BvaW50RW5kLnggLSBzdHlsZUNvbmZpZy53aWR0aH0sJHtwb2ludEVuZC55fSAgJHtwb2ludEVuZC54fSwke3BvaW50RW5kLnkgKyBzdHlsZUNvbmZpZy5oZWlnaHR9ICR7cG9pbnRFbmQueCArIHN0eWxlQ29uZmlnLndpZHRofSwke3BvaW50RW5kLnl9IGApO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBhcnJvd0VsZW1lbnQ/LnNldEF0dHJpYnV0ZSgnZmlsbCcsIHN0eWxlQ29uZmlnLmZpbGwpO1xuICAgIGFycm93RWxlbWVudD8uc2V0QXR0cmlidXRlKCdzdHJva2UnLCBzdHlsZUNvbmZpZy5zdHJva2UpO1xuICAgIGFycm93RWxlbWVudD8uc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCBzdHlsZUNvbmZpZy5zdHJva2VXaWR0aCk7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZUF0dHJpYnV0ZUNpcmNsZShjaXJjbGVFbGVtZW50OiBTVkdDaXJjbGVFbGVtZW50LCBuYW1lOiBzdHJpbmcsIHBvaW50OiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0sIGNpcmNsZVN0eWxlPzogSUNpcmNsZVN0eWxlKSB7XG4gICAgY2lyY2xlRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ25hbWUnLCBuYW1lKTtcbiAgICBjaXJjbGVFbGVtZW50LnNldEF0dHJpYnV0ZSgnY3gnLCBgJHtwb2ludC54fWApO1xuICAgIGNpcmNsZUVsZW1lbnQuc2V0QXR0cmlidXRlKCdjeScsIGAke3BvaW50Lnl9YCk7XG4gICAgY2lyY2xlRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3InLCBgJHtjaXJjbGVTdHlsZT8uciA/PyAyfWApO1xuICAgIGNpcmNsZUVsZW1lbnQuc2V0QXR0cmlidXRlKCdmaWxsJywgYCR7Y2lyY2xlU3R5bGU/LmZpbGwgPz8gJ2dyZWVuJ31gKTtcbiAgICBjaXJjbGVFbGVtZW50LnNldEF0dHJpYnV0ZSgnc3Ryb2tlJywgYCR7Y2lyY2xlU3R5bGU/LnN0cm9rZSA/PyAnIzlDQTJBRCd9YCk7XG4gICAgY2lyY2xlRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZS13aWR0aCcsIGAke2NpcmNsZVN0eWxlPy5zdHJva2VXaWR0aCA/PyAnMXB4J31gKTtcblxuICAgIHJldHVybiBjaXJjbGVFbGVtZW50O1xuICB9XG5cbiAgcHJpdmF0ZSBnZXREaXJlY3Rpb24ocG9pbnRzOiBJUG9pbnRzLCBzdGFydEVuZE1vZGU6ICdyaWdodC1sZWZ0JyB8ICdib3R0b20tdG9wJyB8ICdib3R0b20tbGVmdCcgfCB1bmRlZmluZWQpOiBUWVBFX0RJUkVDVElPTiB7XG4gICAgbGV0IHBvaW50U3RhcnQgPSB7IC4uLnBvaW50cy5zdGFydCB9O1xuXG4gICAgaWYgKHBvaW50cy5zZXBhcmF0ZWRQb2ludHMpIHtcbiAgICAgIGNvbnN0IGxpbmVUb0VuZCA9IHBvaW50cy5zZXBhcmF0ZWRQb2ludHMuZmluZCgoaXRlbSkgPT4gaXRlbS5lbmQueCA9PT0gcG9pbnRzLmVuZC54ICYmIGl0ZW0uZW5kLnkgPT09IHBvaW50cy5lbmQueSk7XG5cbiAgICAgIGlmIChsaW5lVG9FbmQpIHtcbiAgICAgICAgcG9pbnRTdGFydCA9IGxpbmVUb0VuZC5zdGFydDtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgbW9kZUhvcml6b250YWwgPSBwb2ludFN0YXJ0LnggPCBwb2ludHMuZW5kLnggPyAncmlnaHQnIDogJ2xlZnQnO1xuICAgIGNvbnN0IG1vZGVWZXJ0aWNhbCA9IHBvaW50U3RhcnQueSA8IHBvaW50cy5lbmQueSA/ICdib3R0b20nIDogJ3RvcCc7XG5cbiAgICBpZiAoIXN0YXJ0RW5kTW9kZSkge1xuICAgICAgaWYgKE1hdGguYWJzKHBvaW50cy5lbmQueCAtIHBvaW50U3RhcnQueCkgPiBNYXRoLmFicyhwb2ludHMuZW5kLnkgLSBwb2ludFN0YXJ0LnkpKSB7XG4gICAgICAgIHJldHVybiBtb2RlSG9yaXpvbnRhbDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG1vZGVWZXJ0aWNhbDtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKHN0YXJ0RW5kTW9kZSkge1xuICAgICAgY2FzZSAnYm90dG9tLWxlZnQnOlxuICAgICAgICByZXR1cm4gbW9kZUhvcml6b250YWw7XG5cbiAgICAgIGNhc2UgJ3JpZ2h0LWxlZnQnOlxuICAgICAgICByZXR1cm4gbW9kZUhvcml6b250YWw7XG5cbiAgICAgIGNhc2UgJ2JvdHRvbS10b3AnOlxuICAgICAgICByZXR1cm4gbW9kZVZlcnRpY2FsO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaW5pdEV2ZW50KGRhdGE6IElEcmF3TGluZURhdGFJbnB1dCkge1xuICAgIGNvbnN0IHBvaW50czogSVBvaW50cyA9IGRhdGEucG9pbnRzO1xuICAgIGxldCBwcmVFdmVudDogTW91c2VFdmVudCB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcblxuICAgIGlmICgoIXBvaW50cy5hcnJvd0VsZW1lbnQgJiYgIXBvaW50cy5jaXJjbGVFbmRFbGVtZW50KSB8fCAhcG9pbnRzLm9uRGVzdHJveUV2ZW50IHx8IHBvaW50cy5pbml0aWFsaXplZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHBvaW50cy5pbml0aWFsaXplZCA9IHRydWU7XG4gICAgY29uc3QgZnVuY3Rpb25Nb3VzZVVwID0gKG1vdXNlRXZlbnQ6IE1vdXNlRXZlbnQpID0+IHtcbiAgICAgIGlmIChwcmVFdmVudCkge1xuICAgICAgICBwcmVFdmVudCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5vbkRyYXdMaW5lRW5kLm5leHQoeyBkYXRhTGluZTogZGF0YSwgZXZlbnQ6IG1vdXNlRXZlbnQgfSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGNvbnN0IGhhbmRsZXJEcmFnID0gKGRyYWdNb3VzZUV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgICBpZiAoIXByZUV2ZW50KSB7XG4gICAgICAgIHByZUV2ZW50ID0gZHJhZ01vdXNlRXZlbnQ7XG4gICAgICB9XG4gICAgICBjb25zdCBwb2ludEVuZCA9IGNsb25lRGVlcChwb2ludHMuZW5kKTtcblxuICAgICAgY29uc3QgbW92ZW1lbnRYID0gZHJhZ01vdXNlRXZlbnQuY2xpZW50WCAtIHByZUV2ZW50LmNsaWVudFg7XG4gICAgICBjb25zdCBtb3ZlbWVudFkgPSBkcmFnTW91c2VFdmVudC5jbGllbnRZIC0gcHJlRXZlbnQuY2xpZW50WTtcblxuICAgICAgcHJlRXZlbnQgPSBkcmFnTW91c2VFdmVudDtcbiAgICAgIHBvaW50RW5kLnggKz0gbW92ZW1lbnRYO1xuICAgICAgcG9pbnRFbmQueSArPSBtb3ZlbWVudFk7XG4gICAgICBpZiAoZGF0YS5wb2ludHM/Lm9ic3RhY2xlUmVjdD8ubGVuZ3RoICYmIGRhdGEucG9pbnRzPy5vYnN0YWNsZVJlY3Quc29tZSgob2JzdGFjbGVSZWN0KSA9PiB0aGlzLmNoZWNrUG9pbnRJbmNsdWRlUmVjdChwb2ludEVuZCwgb2JzdGFjbGVSZWN0KSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcG9pbnRzLmVuZC54ID0gcG9pbnRFbmQueDtcbiAgICAgIHBvaW50cy5lbmQueSA9IHBvaW50RW5kLnk7XG4gICAgICB0aGlzLmRyYXdMaW5lKGRhdGEpO1xuICAgICAgdGhpcy51cGRhdGVWaWV3Qm94KCk7XG4gICAgfTtcblxuICAgIGlmIChwb2ludHMuYXJyb3dFbGVtZW50KSB7XG4gICAgICBnZXREcmFnRXZlbnRCeUVsZW1lbnQoe1xuICAgICAgICBlbGVtZW50TW91c2VEb3duOiBwb2ludHMuYXJyb3dFbGVtZW50IGFzIHVua25vd24gYXMgSFRNTEVsZW1lbnQsXG4gICAgICAgIGZ1bmN0aW9uTW91c2VVcDogZnVuY3Rpb25Nb3VzZVVwLFxuICAgICAgICBvbkRlc3Ryb3k6IHRoaXMub25EZXN0cm95LFxuICAgICAgfSlcbiAgICAgICAgLnBpcGUodGFwKGhhbmRsZXJEcmFnKSwgdGFrZVVudGlsKHBvaW50cy5vbkRlc3Ryb3lFdmVudCkpXG4gICAgICAgIC5zdWJzY3JpYmUoKTtcbiAgICB9XG5cbiAgICBpZiAocG9pbnRzLmNpcmNsZUVuZEVsZW1lbnQpIHtcbiAgICAgIGdldERyYWdFdmVudEJ5RWxlbWVudCh7XG4gICAgICAgIGVsZW1lbnRNb3VzZURvd246IHBvaW50cy5jaXJjbGVFbmRFbGVtZW50IGFzIHVua25vd24gYXMgSFRNTEVsZW1lbnQsXG4gICAgICAgIGZ1bmN0aW9uTW91c2VVcDogZnVuY3Rpb25Nb3VzZVVwLFxuICAgICAgICBvbkRlc3Ryb3k6IHRoaXMub25EZXN0cm95LFxuICAgICAgfSlcbiAgICAgICAgLnBpcGUodGFwKGhhbmRsZXJEcmFnKSwgdGFrZVVudGlsKHBvaW50cy5vbkRlc3Ryb3lFdmVudCkpXG4gICAgICAgIC5zdWJzY3JpYmUoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNoZWNrUG9pbnRJbmNsdWRlUmVjdChwb2ludDogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9LCBvYnN0YWNsZVJlY3Q6IElSZWN0KTogYm9vbGVhbiB7XG4gICAgY29uc3QgZ2FwRGVmYXVsdCA9IDg7XG5cbiAgICBvYnN0YWNsZVJlY3QgPSB7XG4gICAgICB4OiBvYnN0YWNsZVJlY3QueCAtIChvYnN0YWNsZVJlY3QuZ2FwWE9ic3RhY2xlUmVjdCB8fCBnYXBEZWZhdWx0KSxcbiAgICAgIHk6IG9ic3RhY2xlUmVjdC55IC0gKG9ic3RhY2xlUmVjdC5nYXBZT2JzdGFjbGVSZWN0IHx8IGdhcERlZmF1bHQpLFxuICAgICAgd2lkdGg6IG9ic3RhY2xlUmVjdC53aWR0aCArIChvYnN0YWNsZVJlY3QuZ2FwWE9ic3RhY2xlUmVjdCB8fCBnYXBEZWZhdWx0KSAqIDIsXG4gICAgICBoZWlnaHQ6IG9ic3RhY2xlUmVjdC5oZWlnaHQgKyAob2JzdGFjbGVSZWN0LmdhcFlPYnN0YWNsZVJlY3QgfHwgZ2FwRGVmYXVsdCkgKiAyLFxuICAgIH07XG4gICAgaWYgKG9ic3RhY2xlUmVjdC54IDw9IHBvaW50LnggJiYgcG9pbnQueCA8PSBvYnN0YWNsZVJlY3QueCArIG9ic3RhY2xlUmVjdC53aWR0aCAmJiBvYnN0YWNsZVJlY3QueSA8PSBwb2ludC55ICYmIHBvaW50LnkgPD0gb2JzdGFjbGVSZWN0LnkgKyBvYnN0YWNsZVJlY3QuaGVpZ2h0KSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZVBhdGhBbmRBcnJvd0VsZW1lbnQobmFtZTogc3RyaW5nKSB7XG4gICAgY29uc3QgcGF0aEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJywgJ3BhdGgnKTtcbiAgICBjb25zdCBhcnJvd0VsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJywgJ3BvbHlsaW5lJyk7XG4gICAgY29uc3QgY2lyY2xlU3RhcnRFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsICdjaXJjbGUnKTtcbiAgICBjb25zdCBjaXJjbGVFbmRFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsICdjaXJjbGUnKTtcblxuICAgIHBhdGhFbGVtZW50LnNldEF0dHJpYnV0ZSgnbmFtZScsIG5hbWUpO1xuICAgIGFycm93RWxlbWVudC5zZXRBdHRyaWJ1dGUoJ25hbWUnLCBuYW1lKTtcbiAgICB0aGlzLnN2Z0VsZW1lbnQuYXBwZW5kKHBhdGhFbGVtZW50KTtcbiAgICB0aGlzLnN2Z0VsZW1lbnQuYXBwZW5kKGFycm93RWxlbWVudCk7XG5cbiAgICByZXR1cm4geyBwYXRoRWxlbWVudCwgYXJyb3dFbGVtZW50LCBjaXJjbGVTdGFydEVsZW1lbnQsIGNpcmNsZUVuZEVsZW1lbnQgfTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkQ2lyY2xlKG5hbWU6IHN0cmluZywgcG9pbnQ6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSkge1xuICAgIGlmICghdGhpcy5kcmF3UmVjdERlYnVnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGNpcmNsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCAnY2lyY2xlJyk7XG5cbiAgICBjaXJjbGUuc2V0QXR0cmlidXRlKCduYW1lJywgbmFtZSk7XG4gICAgY2lyY2xlLnNldEF0dHJpYnV0ZSgnY3gnLCBgJHtwb2ludC54fWApO1xuICAgIGNpcmNsZS5zZXRBdHRyaWJ1dGUoJ2N5JywgYCR7cG9pbnQueX1gKTtcbiAgICBjaXJjbGUuc2V0QXR0cmlidXRlKCdyJywgJzInKTtcbiAgICBjaXJjbGUuc2V0QXR0cmlidXRlKCdzdHlsZScsICdmaWxsOiBub25lOyBzdHJva2U6IGJsdWU7IHN0cm9rZS13aWR0aDogMXB4OycpO1xuICAgIHRoaXMuc3ZnRWxlbWVudC5hcHBlbmRDaGlsZChjaXJjbGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBjbGVhckNpcmNsZSgpIHtcbiAgICBpZiAoIXRoaXMuZHJhd1JlY3REZWJ1Zykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBBcnJheS5mcm9tKHRoaXMuc3ZnRWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnY2lyY2xlJykpPy5mb3JFYWNoKChpdGVtKSA9PiBpdGVtLnJlbW92ZSgpKTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkUmVjdChuYW1lOiBzdHJpbmcsIHJlY3Q6IElSZWN0KSB7XG4gICAgaWYgKCF0aGlzLmRyYXdSZWN0RGVidWcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcmVjdEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJywgJ3JlY3QnKTtcbiAgICBjb25zdCB0ZXh0RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCAndGV4dCcpO1xuXG4gICAgcmVjdEVsZW1lbnQuc2V0QXR0cmlidXRlKCduYW1lJywgbmFtZSk7XG4gICAgcmVjdEVsZW1lbnQuc2V0QXR0cmlidXRlKCd4JywgYCR7cmVjdC54fWApO1xuICAgIHJlY3RFbGVtZW50LnNldEF0dHJpYnV0ZSgneScsIGAke3JlY3QueX1gKTtcbiAgICByZWN0RWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3dpZHRoJywgYCR7cmVjdC53aWR0aH1gKTtcbiAgICByZWN0RWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsIGAke3JlY3QuaGVpZ2h0fWApO1xuICAgIHJlY3RFbGVtZW50LnNldEF0dHJpYnV0ZSgnc3R5bGUnLCAnZmlsbDogYmx1ZTsgc3Ryb2tlOiBibHVlOycpO1xuICAgIHRoaXMuc3ZnRWxlbWVudC5hcHBlbmRDaGlsZChyZWN0RWxlbWVudCk7XG5cbiAgICB0ZXh0RWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3gnLCBgJHtyZWN0Lnh9YCk7XG4gICAgdGV4dEVsZW1lbnQuc2V0QXR0cmlidXRlKCd5JywgYCR7cmVjdC55fWApO1xuICAgIHRleHRFbGVtZW50LnRleHRDb250ZW50ID0gcmVjdC5pZCA/PyAnJztcbiAgICB0aGlzLnN2Z0VsZW1lbnQuYXBwZW5kQ2hpbGQodGV4dEVsZW1lbnQpO1xuICB9XG5cbiAgcHJpdmF0ZSBjbGVhclJlY3QoKSB7XG4gICAgaWYgKCF0aGlzLmRyYXdSZWN0RGVidWcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgQXJyYXkuZnJvbSh0aGlzLnN2Z0VsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3JlY3QnKSk/LmZvckVhY2goKGl0ZW0pID0+IGl0ZW0ucmVtb3ZlKCkpO1xuICAgIEFycmF5LmZyb20odGhpcy5zdmdFbGVtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCd0ZXh0JykpPy5mb3JFYWNoKChpdGVtKSA9PiBpdGVtLnJlbW92ZSgpKTtcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRQYXRoQW5kRHJhd1NlcGFyYXRlZFBvaW50cyhkYXRhOiBJRHJhd0xpbmVEYXRhSW5wdXQsIHBvaW50czogSVBvaW50cywgbW9kZT86IFRZUEVfTU9ERSkge1xuICAgIGxldCBkUGF0aCA9IHt9IGFzIElBdHRyaWJ1dGVET25QYXRoO1xuICAgIGNvbnN0IHN0eWxlQ29uZmlnID0ge1xuICAgICAgY3VydmU6IGRhdGEubGluZVN0eWxlPy5jdXJ2ZSA/PyAxMCxcbiAgICAgIGRpc3RhbmNlUG9pbnQ6IGRhdGEubGluZVN0eWxlPy5kaXN0YW5jZVBvaW50ID8/IDEwLFxuICAgIH07XG5cbiAgICBsZXQgeyBjdXJ2ZSwgZGlzdGFuY2VQb2ludCB9ID0gc3R5bGVDb25maWc7XG5cbiAgICBtb2RlID0gbW9kZSB8fCAncXVhcnQtaW4nO1xuICAgIGlmIChtb2RlICE9PSAncXVhcnQtaW4nKSB7XG4gICAgICBjdXJ2ZSA9IGN1cnZlID8/IDEwO1xuICAgICAgZGlzdGFuY2VQb2ludCA9IGRpc3RhbmNlUG9pbnQgPz8gMTA7XG4gICAgfVxuICAgIGlmIChtb2RlID09PSAncXVhcnQtaW4nIHx8IHBvaW50cy5zdGFydC54ID09PSBwb2ludHMuZW5kLnggfHwgcG9pbnRzLnN0YXJ0LnkgPT09IHBvaW50cy5lbmQueSkge1xuICAgICAgdGhpcy5kcmF3QmFsYW5jZWRDdXJ2ZShkUGF0aCwgcG9pbnRzKTtcblxuICAgICAgaWYgKG1vZGUgPT09ICdxdWFydC1pbicpIHtcbiAgICAgICAgZFBhdGggPSB7fSBhcyBJQXR0cmlidXRlRE9uUGF0aDtcbiAgICAgICAgdGhpcy5kcmF3QmVuZEJvdGhFbmRzQ3VydmUoZFBhdGgsIHBvaW50cyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLmJ1aWxEQXR0cmlidXRlVG9TdHJpbmcoZFBhdGgpO1xuICAgIH1cbiAgICBjb25zdCByZXN1bHQgPSB0aGlzLmNhbGN1bGF0b3JEaXN0YW5jZVBvaW50QW5kQ3VydmUocG9pbnRzLCBkaXN0YW5jZVBvaW50LCBjdXJ2ZSwgbW9kZSk7XG5cbiAgICBkaXN0YW5jZVBvaW50ID0gcmVzdWx0LmRpc3RhbmNlUG9pbnQ7XG4gICAgY3VydmUgPSByZXN1bHQuY3VydmU7XG5cbiAgICB0aGlzLmJ1aWxkREF0dHJpYnV0ZUJ5UG9pbnRFbmRNb2RlSG9yaXpvbnRhbChkUGF0aCwgcG9pbnRzLCBkaXN0YW5jZVBvaW50IHx8IDAsIGN1cnZlIHx8IDAsIG1vZGUpO1xuICAgIHRoaXMuYnVpbGREQXR0cmlidXRlQnlQb2ludEVuZE1vZGVWZXJ0aWNhbChkUGF0aCwgcG9pbnRzLCBkaXN0YW5jZVBvaW50IHx8IDAsIGN1cnZlIHx8IDAsIG1vZGUpO1xuXG4gICAgcmV0dXJuIHRoaXMuYnVpbERBdHRyaWJ1dGVUb1N0cmluZyhkUGF0aCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLm9uRGVzdHJveS5uZXh0KCk7XG4gICAgdGhpcy5vbkRlc3Ryb3kuY29tcGxldGUoKTtcbiAgfVxufVxuIl19