@datagrok-libraries/statistics 1.10.0 → 1.12.0

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,583 @@
1
+ /* eslint-disable max-len */
2
+ import * as grok from 'datagrok-api/grok';
3
+ import * as ui from 'datagrok-api/ui';
4
+ import * as DG from 'datagrok-api/dg';
5
+ import { Subject } from 'rxjs';
6
+ let _konva;
7
+ async function getKonva() {
8
+ if (!_konva)
9
+ _konva = (await import('konva')).default;
10
+ return _konva;
11
+ }
12
+ // Constants for the editor layout
13
+ const EDITOR_PADDING = { top: 10, right: 10, bottom: 20, left: 30 };
14
+ const POINT_RADIUS = 3;
15
+ const COLORS = {
16
+ line: DG.Color.toHtml(DG.Color.filteredRows),
17
+ handle: DG.Color.toHtml(DG.Color.selectedRows),
18
+ barFill: DG.Color.toHtml(DG.Color.histogramBar),
19
+ barStroke: DG.Color.toHtml(DG.Color.lightGray),
20
+ };
21
+ class CoordMapper {
22
+ constructor(minX, maxX, width, height) {
23
+ this.minX = minX;
24
+ this.maxX = maxX;
25
+ this.width = width;
26
+ this.height = height;
27
+ this.plotWidth = width - EDITOR_PADDING.left - EDITOR_PADDING.right;
28
+ this.plotHeight = height - EDITOR_PADDING.top - EDITOR_PADDING.bottom;
29
+ this.scaleX = (this.maxX - this.minX === 0) ? 1 : this.plotWidth / (this.maxX - this.minX);
30
+ this.scaleY = this.plotHeight;
31
+ }
32
+ toCanvasCoords(p) {
33
+ const canvasX = EDITOR_PADDING.left + (p[0] - this.minX) * this.scaleX;
34
+ const canvasY = EDITOR_PADDING.top + this.plotHeight - (p[1] * this.scaleY);
35
+ return { x: canvasX, y: canvasY };
36
+ }
37
+ toDataCoords(canvasX, canvasY) {
38
+ let dataX = this.minX + (canvasX - EDITOR_PADDING.left) / this.scaleX;
39
+ let dataY = (EDITOR_PADDING.top + this.plotHeight - canvasY) / this.scaleY;
40
+ dataX = Math.max(this.minX, Math.min(this.maxX, dataX));
41
+ dataY = Math.max(0, Math.min(1, dataY));
42
+ return { x: dataX, y: dataY };
43
+ }
44
+ }
45
+ export class MpoDesirabilityLineEditor {
46
+ constructor(prop, width, height) {
47
+ this.root = ui.div();
48
+ this.onChanged = new Subject();
49
+ this.supportsModeDialog = true;
50
+ // Flag to prevent touchpad right-click from adding a new point
51
+ this.ignoreNextClick = false;
52
+ this.dragScaleX = 0;
53
+ this.dragScaleY = 0;
54
+ this._prop = prop;
55
+ this._width = width;
56
+ this._height = height;
57
+ this.ensureDefaultLine();
58
+ this.root.style.width = `${width}px`;
59
+ this.root.style.height = `${height}px`;
60
+ this.root.style.position = 'relative';
61
+ requestAnimationFrame(() => this.initKonva(width, height));
62
+ }
63
+ ensureDefaultLine() {
64
+ var _a, _b;
65
+ if (this._prop.line.length > 0)
66
+ return;
67
+ const min = (_a = this._prop.min) !== null && _a !== void 0 ? _a : 0;
68
+ const max = (_b = this._prop.max) !== null && _b !== void 0 ? _b : 1;
69
+ this._prop.line = [[min, 0.5], [max, 0.5]];
70
+ }
71
+ updateDragScales() {
72
+ const plotWidth = this._width - EDITOR_PADDING.left - EDITOR_PADDING.right;
73
+ const plotHeight = this._height - EDITOR_PADDING.top - EDITOR_PADDING.bottom;
74
+ this.dragScaleX = (this.getMaxX() - this.getMinX()) / plotWidth;
75
+ this.dragScaleY = 1 / plotHeight;
76
+ }
77
+ isInPlotArea(pos, width, height) {
78
+ return (pos.x >= EDITOR_PADDING.left &&
79
+ pos.x <= width - EDITOR_PADDING.right &&
80
+ pos.y >= EDITOR_PADDING.top &&
81
+ pos.y <= height - EDITOR_PADDING.bottom);
82
+ }
83
+ async initKonva(width, height) {
84
+ var _a;
85
+ if (!this.root.parentElement) {
86
+ console.warn('Konva container not attached to DOM yet.');
87
+ return;
88
+ }
89
+ const Konva = await getKonva();
90
+ this.barsLayer = new Konva.Layer();
91
+ this.stage = new Konva.Stage({
92
+ container: this.root,
93
+ width,
94
+ height,
95
+ });
96
+ this.stage.add(this.barsLayer);
97
+ this.layer = new Konva.Layer();
98
+ this.stage.add(this.layer);
99
+ const minX = this.getMinX();
100
+ const maxX = this.getMaxX();
101
+ // --- Draw Axes ---
102
+ this.drawAxes(minX, maxX, width, height);
103
+ // --- Draw Line and Points ---
104
+ this.konvaLine = new Konva.Line({
105
+ points: [],
106
+ stroke: COLORS.line,
107
+ strokeWidth: 2,
108
+ lineCap: 'round',
109
+ lineJoin: 'round',
110
+ });
111
+ this.layer.add(this.konvaLine);
112
+ this.pointsGroup = new Konva.Group();
113
+ this.layer.add(this.pointsGroup);
114
+ // --- Redraw Function ---
115
+ this.redrawFn = (notify = true) => {
116
+ const minX = this.getMinX();
117
+ const maxX = this.getMaxX();
118
+ if (this._prop.mode === 'freeform' && this._prop.freeformLine)
119
+ this._prop.line = this._prop.freeformLine;
120
+ if (this._prop.mode !== 'freeform') {
121
+ if (!this._prop.freeformLine)
122
+ this._prop.freeformLine = [...this._prop.line];
123
+ this._prop.line = this.computeLine();
124
+ }
125
+ this.pointsGroup.destroyChildren();
126
+ const konvaPoints = [];
127
+ const mapper = new CoordMapper(minX, maxX, width, height);
128
+ const sortedIndices = [...this._prop.line.keys()]
129
+ .sort((a, b) => this._prop.line[a][0] - this._prop.line[b][0]);
130
+ const sortedLine = sortedIndices.map((idx) => this._prop.line[idx]);
131
+ sortedLine.forEach((p, index) => {
132
+ const coords = mapper.toCanvasCoords([p[0], p[1]]);
133
+ konvaPoints.push(coords.x, coords.y);
134
+ if (this._prop.mode !== 'freeform')
135
+ return;
136
+ const pointCircle = new Konva.Circle({
137
+ x: coords.x,
138
+ y: coords.y,
139
+ radius: POINT_RADIUS,
140
+ fill: 'white',
141
+ stroke: COLORS.line,
142
+ strokeWidth: 1,
143
+ draggable: true,
144
+ hitStrokeWidth: 5,
145
+ });
146
+ // Store index directly on the node for easy access
147
+ pointCircle.setAttr('_dataIndex', sortedIndices[index]);
148
+ pointCircle.on('dragmove', (evt) => {
149
+ const circle = evt.target;
150
+ const pos = circle.position();
151
+ const dataIndex = circle.getAttr('_dataIndex');
152
+ const sortedPos = sortedIndices.indexOf(dataIndex);
153
+ // Constrain dragging horizontally between neighbors (or bounds)
154
+ const prevX = sortedPos > 0 ? this._prop.line[sortedIndices[sortedPos - 1]][0] : minX;
155
+ const nextX = sortedPos < sortedIndices.length - 1 ?
156
+ this._prop.line[sortedIndices[sortedPos + 1]][0] :
157
+ maxX;
158
+ // Add a small buffer to avoid points overlapping exactly
159
+ const buffer = (maxX - minX === 0) ? 0 : 0.001 * (maxX - minX); // Avoid NaN if minX === maxX
160
+ const minCanvasX = mapper.toCanvasCoords([prevX + (sortedPos > 0 ? buffer : 0), 0]).x;
161
+ const maxCanvasX = mapper.toCanvasCoords([nextX - (sortedPos < sortedIndices.length - 1 ? buffer : 0), 0]).x;
162
+ pos.x = Math.max(minCanvasX, Math.min(maxCanvasX, pos.x));
163
+ const plotTop = EDITOR_PADDING.top;
164
+ const plotBottom = height - EDITOR_PADDING.bottom;
165
+ pos.y = Math.max(plotTop, Math.min(plotBottom, pos.y));
166
+ circle.position(pos);
167
+ const dataCoords = mapper.toDataCoords(pos.x, pos.y);
168
+ this._prop.line[dataIndex][0] = dataCoords.x;
169
+ this._prop.line[dataIndex][1] = dataCoords.y;
170
+ const currentKonvaPoints = this._prop.line.map((pData, idx) => {
171
+ // Use dragged circle position directly for the point being dragged
172
+ if (idx === dataIndex)
173
+ return [pos.x, pos.y];
174
+ else {
175
+ const c = mapper.toCanvasCoords([pData[0], pData[1]]);
176
+ return [c.x, c.y];
177
+ }
178
+ }).flat();
179
+ this.konvaLine.points(currentKonvaPoints);
180
+ this.layer.batchDraw();
181
+ });
182
+ pointCircle.on('dragend', () => {
183
+ var _a;
184
+ this._prop.line.sort((a, b) => a[0] - b[0]);
185
+ (_a = this.redrawFn) === null || _a === void 0 ? void 0 : _a.call(this);
186
+ });
187
+ pointCircle.on('contextmenu', (evt) => {
188
+ var _a;
189
+ evt.evt.preventDefault();
190
+ if (this._prop.line.length <= 2) {
191
+ grok.shell.warning('Cannot remove points, minimum of 2 required.');
192
+ return;
193
+ }
194
+ this.ignoreNextClick = true;
195
+ const circle = evt.target;
196
+ const dataIndex = circle.getAttr('_dataIndex');
197
+ if (dataIndex >= 0) {
198
+ if (this._prop.min == null)
199
+ this._prop.min = this.getMinX();
200
+ if (this._prop.max == null)
201
+ this._prop.max = this.getMaxX();
202
+ this._prop.line.splice(dataIndex, 1);
203
+ (_a = this.redrawFn) === null || _a === void 0 ? void 0 : _a.call(this);
204
+ }
205
+ });
206
+ pointCircle.on('mouseenter', (evt) => {
207
+ this.stage.container().style.cursor = 'pointer';
208
+ const circle = evt.target;
209
+ const pos = circle.position();
210
+ const dataCoords = mapper.toDataCoords(pos.x, pos.y);
211
+ const tooltipText = `X: ${dataCoords.x.toFixed(2)}, Y: ${dataCoords.y.toFixed(2)}<br><br>Drag to move, double-click to edit, right-click to delete`;
212
+ ui.tooltip.show(tooltipText, evt.evt.clientX, evt.evt.clientY);
213
+ });
214
+ pointCircle.on('mouseleave', () => {
215
+ this.stage.container().style.cursor = 'default';
216
+ ui.tooltip.hide();
217
+ });
218
+ pointCircle.on('dblclick dbltap', (evt) => {
219
+ this.ignoreNextClick = true;
220
+ ui.tooltip.hide();
221
+ const dataIndex = evt.target.getAttr('_dataIndex');
222
+ this.showPointEditor(dataIndex, evt.evt.clientX, evt.evt.clientY);
223
+ });
224
+ this.pointsGroup.add(pointCircle);
225
+ });
226
+ this.konvaLine.points(konvaPoints);
227
+ this.layer.batchDraw();
228
+ // --- Add special handle (Gaussian peak / Sigmoid inflection) ---
229
+ this.addSpecialHandle(width, height);
230
+ if (notify)
231
+ this.onChanged.next(this._prop.line);
232
+ };
233
+ // --- Left-click to Add Point ---
234
+ this.stage.on('click tap', (evt) => {
235
+ var _a, _b;
236
+ if (this.ignoreNextClick) {
237
+ this.ignoreNextClick = false;
238
+ return;
239
+ }
240
+ if (evt.target instanceof Konva.Circle || evt.evt.button !== 0)
241
+ return;
242
+ const pos = (_a = this.stage) === null || _a === void 0 ? void 0 : _a.getPointerPosition();
243
+ if (!pos)
244
+ return;
245
+ const minX = this.getMinX();
246
+ const maxX = this.getMaxX();
247
+ if (!this.isInPlotArea(pos, this.stage.width(), this.stage.height()))
248
+ return;
249
+ const mapper = new CoordMapper(minX, maxX, this.stage.width(), this.stage.height());
250
+ const dataCoords = mapper.toDataCoords(pos.x, pos.y);
251
+ this._prop.line.push([dataCoords.x, dataCoords.y]);
252
+ this._prop.line.sort((a, b) => a[0] - b[0]);
253
+ (_b = this.redrawFn) === null || _b === void 0 ? void 0 : _b.call(this);
254
+ });
255
+ // Cursor change
256
+ this.stage.on('mousemove', (evt) => {
257
+ if (!this.stage)
258
+ return;
259
+ const pos = this.stage.getPointerPosition();
260
+ if (!pos)
261
+ return;
262
+ if (this._prop.mode !== 'freeform') {
263
+ if (this.isInPlotArea(pos, width, height))
264
+ this.stage.container().style.cursor = 'grab';
265
+ else
266
+ this.stage.container().style.cursor = 'default';
267
+ }
268
+ });
269
+ this.stage.on('mouseout', () => ui.tooltip.hide());
270
+ // Enable curve drag (smooth)
271
+ this.enableCurveDrag(width, height);
272
+ this.updateDragScales();
273
+ // Initial draw
274
+ if (this.pendingBarValues) {
275
+ this.drawBars(this.pendingBarValues);
276
+ this.pendingBarValues = undefined;
277
+ }
278
+ (_a = this.redrawFn) === null || _a === void 0 ? void 0 : _a.call(this, false);
279
+ }
280
+ get line() {
281
+ return this._prop.line;
282
+ }
283
+ computeLine() {
284
+ var _a, _b, _c, _d;
285
+ var _e, _f, _g, _h;
286
+ if (this._prop.mode === 'freeform')
287
+ return this._prop.line;
288
+ const minX = this.getMinX();
289
+ const maxX = this.getMaxX();
290
+ const n = 60;
291
+ const line = [];
292
+ for (let i = 0; i <= n; i++) {
293
+ const x = minX + (maxX - minX) * (i / n);
294
+ let y = 0;
295
+ if (this._prop.mode === 'gaussian') {
296
+ (_a = (_e = this._prop).mean) !== null && _a !== void 0 ? _a : (_e.mean = (minX + maxX) / 2);
297
+ (_b = (_f = this._prop).sigma) !== null && _b !== void 0 ? _b : (_f.sigma = (maxX - minX) / 6);
298
+ const mean = this._prop.mean;
299
+ const sigma = this._prop.sigma;
300
+ const z = (x - mean) / sigma;
301
+ y = Math.exp(-0.5 * z * z);
302
+ }
303
+ if (this._prop.mode === 'sigmoid') {
304
+ (_c = (_g = this._prop).x0) !== null && _c !== void 0 ? _c : (_g.x0 = (minX + maxX) / 2);
305
+ (_d = (_h = this._prop).k) !== null && _d !== void 0 ? _d : (_h.k = 10);
306
+ const x0 = this._prop.x0;
307
+ const k = this._prop.k;
308
+ y = 1 / (1 + Math.exp(-k * (x - x0)));
309
+ }
310
+ line.push([x, y]);
311
+ }
312
+ return line;
313
+ }
314
+ drawAxes(minX, maxX, width, height) {
315
+ const axisColor = getComputedStyle(document.documentElement).getPropertyValue('--grey-2').trim() || '#DBDCDF';
316
+ this.layer.add(new _konva.Line({
317
+ points: [EDITOR_PADDING.left, height - EDITOR_PADDING.bottom, width - EDITOR_PADDING.right, height - EDITOR_PADDING.bottom],
318
+ stroke: axisColor,
319
+ strokeWidth: 1,
320
+ }), new _konva.Line({
321
+ points: [EDITOR_PADDING.left, EDITOR_PADDING.top, EDITOR_PADDING.left, height - EDITOR_PADDING.bottom],
322
+ stroke: axisColor,
323
+ strokeWidth: 1,
324
+ }), new _konva.Text({ x: EDITOR_PADDING.left, y: height - EDITOR_PADDING.bottom + 3, text: minX.toFixed(1), fontSize: 9, fill: 'grey' }), new _konva.Text({ x: width - EDITOR_PADDING.right - 15, y: height - EDITOR_PADDING.bottom + 3, text: maxX.toFixed(1), fontSize: 9, fill: 'grey' }));
325
+ }
326
+ getMinX() {
327
+ var _a, _b;
328
+ return (_b = (_a = this._prop.min) !== null && _a !== void 0 ? _a : Math.min(...this._prop.line.map((p) => p[0]))) !== null && _b !== void 0 ? _b : 0;
329
+ }
330
+ getMaxX() {
331
+ var _a, _b;
332
+ return (_b = (_a = this._prop.max) !== null && _a !== void 0 ? _a : Math.max(...this._prop.line.map((p) => p[0]))) !== null && _b !== void 0 ? _b : 1;
333
+ }
334
+ getDefaultMean() {
335
+ return (this.getMinX() + this.getMaxX()) / 2;
336
+ }
337
+ getDefaultSigma() {
338
+ return Math.max(0.01, (this.getMaxX() - this.getMinX()) / 6);
339
+ }
340
+ getDefaultX0() {
341
+ return (this.getMinX() + this.getMaxX()) / 2;
342
+ }
343
+ getDefaultK() {
344
+ return 10;
345
+ }
346
+ redrawAll(notify = true) {
347
+ if (!this.stage || !this.layer || !this.redrawFn)
348
+ return;
349
+ const width = this.stage.width();
350
+ const height = this.stage.height();
351
+ const minX = this.getMinX();
352
+ const maxX = this.getMaxX();
353
+ this.layer.destroyChildren();
354
+ this.drawAxes(minX, maxX, width, height);
355
+ this.layer.add(this.konvaLine, this.pointsGroup);
356
+ this.redrawFn(notify);
357
+ if (this.barValues)
358
+ this.drawBars();
359
+ }
360
+ drawBars(values) {
361
+ var _a;
362
+ if (values)
363
+ this.barValues = values;
364
+ if (!this.barsLayer) {
365
+ this.pendingBarValues = values;
366
+ return;
367
+ }
368
+ this.barsLayer.destroyChildren();
369
+ if (!this.barValues || this.barValues.length === 0)
370
+ return;
371
+ const stage = this.barsLayer.getStage();
372
+ if (!stage) {
373
+ this.pendingBarValues = values;
374
+ return;
375
+ }
376
+ const width = stage.width();
377
+ const height = stage.height();
378
+ const minX = this.getMinX();
379
+ const maxX = this.getMaxX();
380
+ if (maxX === minX)
381
+ return;
382
+ const numBins = 20;
383
+ const plotWidth = width - EDITOR_PADDING.left - EDITOR_PADDING.right;
384
+ const plotHeight = height - EDITOR_PADDING.top - EDITOR_PADDING.bottom;
385
+ const binWidth = Math.max(1e-9, (maxX - minX) / numBins);
386
+ const bins = new Array(numBins).fill(0);
387
+ ((_a = this.barValues) !== null && _a !== void 0 ? _a : []).forEach((v) => {
388
+ const idx = Math.min(Math.floor((v - minX) / binWidth), numBins - 1);
389
+ bins[idx]++;
390
+ });
391
+ const maxCount = Math.max(...bins) || 1;
392
+ bins.forEach((count, i) => {
393
+ const barX = EDITOR_PADDING.left + (i * binWidth / (maxX - minX)) * plotWidth;
394
+ const barW = (binWidth / (maxX - minX)) * plotWidth - 1;
395
+ const barH = (count / maxCount) * plotHeight;
396
+ const rect = new _konva.Rect({
397
+ x: barX,
398
+ y: EDITOR_PADDING.top + plotHeight - barH,
399
+ width: barW,
400
+ height: barH,
401
+ fill: COLORS.barFill,
402
+ opacity: 0.25,
403
+ stroke: COLORS.barStroke,
404
+ strokeWidth: 0.5,
405
+ });
406
+ this.barsLayer.add(rect);
407
+ });
408
+ this.barsLayer.batchDraw();
409
+ }
410
+ enableCurveDrag(width, height) {
411
+ if (!this.stage)
412
+ return;
413
+ let dragging = false;
414
+ let startPointer = null;
415
+ let startMean = 0;
416
+ let startSigma = 0;
417
+ let startX0 = 0;
418
+ let startK = 0;
419
+ this.stage.on('mousedown touchstart', (evt) => {
420
+ var _a, _b, _c, _d;
421
+ if (this._prop.mode === 'freeform')
422
+ return;
423
+ if (!evt.evt)
424
+ return;
425
+ const pos = this.stage.getPointerPosition();
426
+ if (!pos)
427
+ return;
428
+ if (!this.isInPlotArea(pos, width, height))
429
+ return;
430
+ dragging = true;
431
+ startPointer = pos;
432
+ startMean = (_a = this._prop.mean) !== null && _a !== void 0 ? _a : (this.getMinX() + this.getMaxX()) / 2;
433
+ startSigma = (_b = this._prop.sigma) !== null && _b !== void 0 ? _b : (this.getMaxX() - this.getMinX()) / 6;
434
+ startX0 = (_c = this._prop.x0) !== null && _c !== void 0 ? _c : (this.getMinX() + this.getMaxX()) / 2;
435
+ startK = (_d = this._prop.k) !== null && _d !== void 0 ? _d : 10;
436
+ this.stage.container().style.cursor = 'grabbing';
437
+ });
438
+ this.stage.on('mousemove touchmove', (evt) => {
439
+ var _a, _b;
440
+ if (!dragging || !startPointer)
441
+ return;
442
+ const pos = this.stage.getPointerPosition();
443
+ if (!pos)
444
+ return;
445
+ const dx = pos.x - startPointer.x;
446
+ const dy = pos.y - startPointer.y;
447
+ if (this._prop.mode === 'gaussian') {
448
+ this._prop.mean = startMean + dx * this.dragScaleX;
449
+ this._prop.sigma = Math.max(0.01, startSigma + (-dy) * this.dragScaleY * (this.getMaxX() - this.getMinX()));
450
+ }
451
+ if (this._prop.mode === 'sigmoid') {
452
+ this._prop.x0 = startX0 + dx * this.dragScaleX;
453
+ this._prop.k = Math.max(0.1, startK + (-dy) * this.dragScaleY * 50);
454
+ }
455
+ this._prop.line = this.computeLine();
456
+ (_a = this.redrawFn) === null || _a === void 0 ? void 0 : _a.call(this);
457
+ (_b = this.onParamsChanged) === null || _b === void 0 ? void 0 : _b.call(this, this._prop);
458
+ });
459
+ this.stage.on('mouseup touchend', () => {
460
+ dragging = false;
461
+ startPointer = null;
462
+ this.stage.container().style.cursor = 'default';
463
+ });
464
+ }
465
+ addSpecialHandle(width, height) {
466
+ var _a, _b;
467
+ const clamp = (v, min, max) => Math.max(min, Math.min(max, v));
468
+ if (this._prop.mode === 'freeform')
469
+ return;
470
+ const minX = this.getMinX();
471
+ const maxX = this.getMaxX();
472
+ const mapper = new CoordMapper(minX, maxX, width, height);
473
+ let x = (minX + maxX) / 2;
474
+ let y = 0.5;
475
+ if (this._prop.mode === 'gaussian') {
476
+ x = (_a = this._prop.mean) !== null && _a !== void 0 ? _a : (minX + maxX) / 2;
477
+ y = 1;
478
+ }
479
+ else if (this._prop.mode === 'sigmoid') {
480
+ x = (_b = this._prop.x0) !== null && _b !== void 0 ? _b : (minX + maxX) / 2;
481
+ y = 0.5;
482
+ }
483
+ const coords = mapper.toCanvasCoords([x, y]);
484
+ if (!this.specialHandle) {
485
+ this.specialHandle = new _konva.Circle({
486
+ x: coords.x,
487
+ y: coords.y,
488
+ radius: 7,
489
+ fill: COLORS.handle,
490
+ draggable: true,
491
+ hitStrokeWidth: 15,
492
+ });
493
+ this.specialHandle.on('dragmove', (evt) => {
494
+ var _a, _b;
495
+ const pos = evt.target.position();
496
+ const data = mapper.toDataCoords(pos.x, pos.y);
497
+ if (this._prop.mode === 'gaussian') {
498
+ this._prop.mean = data.x;
499
+ this._prop.sigma = Math.max(0.01, Math.abs(data.y - 1));
500
+ }
501
+ else if (this._prop.mode === 'sigmoid') {
502
+ this._prop.x0 = data.x;
503
+ this._prop.k = clamp(Math.abs(data.y - 0.5) * 30, 0.1, 30);
504
+ }
505
+ this._prop.line = this.computeLine();
506
+ (_a = this.redrawFn) === null || _a === void 0 ? void 0 : _a.call(this);
507
+ (_b = this.onParamsChanged) === null || _b === void 0 ? void 0 : _b.call(this, this._prop);
508
+ });
509
+ this.layer.add(this.specialHandle);
510
+ }
511
+ else {
512
+ if (!this.specialHandle.getLayer())
513
+ this.layer.add(this.specialHandle);
514
+ this.specialHandle.position(coords);
515
+ }
516
+ this.layer.batchDraw();
517
+ }
518
+ showPointEditor(dataIndex, clientX, clientY) {
519
+ const point = this._prop.line[dataIndex];
520
+ const xInput = ui.input.float('X', { value: point[0], min: this.getMinX(), max: this.getMaxX(), format: '#0.00', step: 0.01 });
521
+ const yInput = ui.input.float('Y', { value: point[1], min: 0, max: 1, format: '#0.00', step: 0.01 });
522
+ const close = () => {
523
+ content.removeEventListener('keydown', onKey);
524
+ popup.remove();
525
+ };
526
+ const apply = () => {
527
+ const x = xInput.value;
528
+ const y = yInput.value;
529
+ if (x == null || y == null || isNaN(x) || isNaN(y))
530
+ return;
531
+ this._prop.line[dataIndex] = [x, y];
532
+ this.redrawAll();
533
+ };
534
+ const onKey = (e) => {
535
+ if (e.key === 'Enter') {
536
+ apply();
537
+ close();
538
+ }
539
+ if (e.key === 'Escape')
540
+ close();
541
+ };
542
+ const content = ui.inputs([xInput, yInput]);
543
+ content.style.overflow = 'hidden';
544
+ content.addEventListener('keydown', onKey);
545
+ const rootRect = this.root.getBoundingClientRect();
546
+ const popup = ui.showPopup(content, this.root, { dx: clientX - rootRect.left, dy: clientY - rootRect.bottom, smart: false });
547
+ }
548
+ setRange(min, max) {
549
+ const oldMin = this.getMinX();
550
+ const oldMax = this.getMaxX();
551
+ const oldRange = oldMax - oldMin;
552
+ const newRange = max - min;
553
+ if (oldRange !== 0 && newRange !== 0) {
554
+ const scale = newRange / oldRange;
555
+ const remap = (x) => min + (x - oldMin) * scale;
556
+ if (this._prop.mean != null)
557
+ this._prop.mean = remap(this._prop.mean);
558
+ if (this._prop.sigma != null)
559
+ this._prop.sigma *= scale;
560
+ if (this._prop.x0 != null)
561
+ this._prop.x0 = remap(this._prop.x0);
562
+ if (this._prop.k != null)
563
+ this._prop.k /= scale;
564
+ for (const p of this._prop.line)
565
+ p[0] = remap(p[0]);
566
+ if (this._prop.freeformLine) {
567
+ for (const p of this._prop.freeformLine)
568
+ p[0] = remap(p[0]);
569
+ }
570
+ }
571
+ this._prop.min = min;
572
+ this._prop.max = max;
573
+ this.updateDragScales();
574
+ this.redrawAll(false);
575
+ }
576
+ setColumn(col) {
577
+ if (!col)
578
+ return;
579
+ const values = col.toList();
580
+ this.drawBars(values);
581
+ }
582
+ }
583
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXBvLWxpbmUtZWRpdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsibXBvLWxpbmUtZWRpdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDRCQUE0QjtBQUM1QixPQUFPLEtBQUssSUFBSSxNQUFNLG1CQUFtQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDdEMsT0FBTyxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUl0QyxPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBRTdCLElBQUksTUFBZ0MsQ0FBQztBQUVyQyxLQUFLLFVBQVUsUUFBUTtJQUNyQixJQUFJLENBQUMsTUFBTTtRQUNULE1BQU0sR0FBRyxDQUFDLE1BQU0sTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO0lBQzNDLE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFJRCxrQ0FBa0M7QUFDbEMsTUFBTSxjQUFjLEdBQUcsRUFBQyxHQUFHLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFDLENBQUM7QUFDbEUsTUFBTSxZQUFZLEdBQUcsQ0FBQyxDQUFDO0FBRXZCLE1BQU0sTUFBTSxHQUFHO0lBQ2IsSUFBSSxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDO0lBQzVDLE1BQU0sRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQztJQUM5QyxPQUFPLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUM7SUFDL0MsU0FBUyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxL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R0FBRyxHQUFHLENBQUM7UUFDckIsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDO1FBQ3JCLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDeEIsQ0FBQztJQUVELFNBQVMsQ0FBQyxHQUFxQjtRQUM3QixJQUFJLENBQUMsR0FBRztZQUNOLE9BQU87UUFFVCxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDNUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN4QixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBtYXgtbGVuICovXG5pbXBvcnQgKiBhcyBncm9rIGZyb20gJ2RhdGFncm9rLWFwaS9ncm9rJztcbmltcG9ydCAqIGFzIHVpIGZyb20gJ2RhdGFncm9rLWFwaS91aSc7XG5pbXBvcnQgKiBhcyBERyBmcm9tICdkYXRhZ3Jvay1hcGkvZGcnO1xuXG5pbXBvcnQgdHlwZSBLb252YSBmcm9tICdrb252YSc7XG5pbXBvcnQge0Rlc2lyYWJpbGl0eUxpbmUsIE51bWVyaWNhbERlc2lyYWJpbGl0eX0gZnJvbSAnLi4vbXBvJztcbmltcG9ydCB7U3ViamVjdH0gZnJvbSAncnhqcyc7XG5cbmxldCBfa29udmE6IHR5cGVvZiBLb252YSB8IHVuZGVmaW5lZDtcblxuYXN5bmMgZnVuY3Rpb24gZ2V0S29udmEoKTogUHJvbWlzZTx0eXBlb2YgS29udmE+IHtcbiAgaWYgKCFfa29udmEpXG4gICAgX2tvbnZhID0gKGF3YWl0IGltcG9ydCgna29udmEnKSkuZGVmYXVsdDtcbiAgcmV0dXJuIF9rb252YTtcbn1cblxudHlwZSBQb2ludCA9IFtudW1iZXIsIG51bWJlcl07XG5cbi8vIENvbnN0YW50cyBmb3IgdGhlIGVkaXRvciBsYXlvdXRcbmNvbnN0IEVESVRPUl9QQURESU5HID0ge3RvcDogMTAsIHJpZ2h0OiAxMCwgYm90dG9tOiAyMCwgbGVmdDogMzB9O1xuY29uc3QgUE9JTlRfUkFESVVTID0gMztcblxuY29uc3QgQ09MT1JTID0ge1xuICBsaW5lOiBERy5Db2xvci50b0h0bWwoREcuQ29sb3IuZmlsdGVyZWRSb3dzKSxcbiAgaGFuZGxlOiBERy5Db2xvci50b0h0bWwoREcuQ29sb3Iuc2VsZWN0ZWRSb3dzKSxcbiAgYmFyRmlsbDogREcuQ29sb3IudG9IdG1sKERHLkNvbG9yLmhpc3RvZ3JhbUJhciksXG4gIGJhclN0cm9rZTogREcuQ29sb3IudG9IdG1sKERHLkNvbG9yLmxpZ2h0R3JheSksXG59O1xuXG5jbGFzcyBDb29yZE1hcHBlciB7XG4gIHByaXZhdGUgcGxvdFdpZHRoOiBudW1iZXI7XG4gIHByaXZhdGUgcGxvdEhlaWdodDogbnVtYmVyO1xuICBwcml2YXRlIHNjYWxlWDogbnVtYmVyO1xuICBwcml2YXRlIHNjYWxlWTogbnVtYmVyO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgbWluWDogbnVtYmVyLFxuICAgIHByaXZhdGUgbWF4WDogbnVtYmVyLFxuICAgIHByaXZhdGUgd2lkdGg6IG51bWJlcixcbiAgICBwcml2YXRlIGhlaWdodDogbnVtYmVyLFxuICApIHtcbiAgICB0aGlzLnBsb3RXaWR0aCA9IHdpZHRoIC0gRURJVE9SX1BBRERJTkcubGVmdCAtIEVESVRPUl9QQURESU5HLnJpZ2h0O1xuICAgIHRoaXMucGxvdEhlaWdodCA9IGhlaWdodCAtIEVESVRPUl9QQURESU5HLnRvcCAtIEVESVRPUl9QQURESU5HLmJvdHRvbTtcbiAgICB0aGlzLnNjYWxlWCA9ICh0aGlzLm1heFggLSB0aGlzLm1pblggPT09IDApID8gMSA6IHRoaXMucGxvdFdpZHRoIC8gKHRoaXMubWF4WCAtIHRoaXMubWluWCk7XG4gICAgdGhpcy5zY2FsZVkgPSB0aGlzLnBsb3RIZWlnaHQ7XG4gIH1cblxuICB0b0NhbnZhc0Nvb3JkcyhwOiBQb2ludCk6IHt4OiBudW1iZXIsIHk6IG51bWJlcn0ge1xuICAgIGNvbnN0IGNhbnZhc1ggPSBFRElUT1JfUEFERElORy5sZWZ0ICsgKHBbMF0gLSB0aGlzLm1pblgpICogdGhpcy5zY2FsZVg7XG4gICAgY29uc3QgY2FudmFzWSA9IEVESVRPUl9QQURESU5HLnRvcCArIHRoaXMucGxvdEhlaWdodCAtIChwWzFdICogdGhpcy5zY2FsZVkpO1xuXG4gICAgcmV0dXJuIHt4OiBjYW52YXNYLCB5OiBjYW52YXNZfTtcbiAgfVxuXG4gIHRvRGF0YUNvb3JkcyhjYW52YXNYOiBudW1iZXIsIGNhbnZhc1k6IG51bWJlcik6IHt4OiBudW1iZXIsIHk6IG51bWJlcn0ge1xuICAgIGxldCBkYXRhWCA9IHRoaXMubWluWCArIChjYW52YXNYIC0gRURJVE9SX1BBRERJTkcubGVmdCkgLyB0aGlzLnNjYWxlWDtcbiAgICBsZXQgZGF0YVkgPSAoRURJVE9SX1BBRERJTkcudG9wICsgdGhpcy5wbG90SGVpZ2h0IC0gY2FudmFzWSkgLyB0aGlzLnNjYWxlWTtcblxuICAgIGRhdGFYID0gTWF0aC5tYXgodGhpcy5taW5YLCBNYXRoLm1pbih0aGlzLm1heFgsIGRhdGFYKSk7XG4gICAgZGF0YVkgPSBNYXRoLm1heCgwLCBNYXRoLm1pbigxLCBkYXRhWSkpO1xuXG4gICAgcmV0dXJuIHt4OiBkYXRhWCwgeTogZGF0YVl9O1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBNcG9EZXNpcmFiaWxpdHlMaW5lRWRpdG9yIHtcbiAgcm9vdCA9IHVpLmRpdigpO1xuICBvbkNoYW5nZWQgPSBuZXcgU3ViamVjdDxEZXNpcmFiaWxpdHlMaW5lPigpO1xuICBzdXBwb3J0c01vZGVEaWFsb2c6IGJvb2xlYW4gPSB0cnVlO1xuXG4gIHByaXZhdGUgX3Byb3A6IE51bWVyaWNhbERlc2lyYWJpbGl0eTtcbiAgcHJpdmF0ZSBiYXJzTGF5ZXI/OiBLb252YS5MYXllcjtcbiAgcHJpdmF0ZSBwZW5kaW5nQmFyVmFsdWVzPzogbnVtYmVyW107XG5cbiAgcHJpdmF0ZSBzdGFnZT86IEtvbnZhLlN0YWdlO1xuICBwcml2YXRlIGxheWVyPzogS29udmEuTGF5ZXI7XG5cbiAgcHJpdmF0ZSBrb252YUxpbmU/OiBLb252YS5MaW5lO1xuICBwcml2YXRlIHBvaW50c0dyb3VwPzogS29udmEuR3JvdXA7XG4gIHByaXZhdGUgYmFyVmFsdWVzPzogbnVtYmVyW107XG5cbiAgcHJpdmF0ZSByZWRyYXdGbiE6IChub3RpZnk/OiBib29sZWFuKSA9PiB2b2lkO1xuXG4gIHByaXZhdGUgc3BlY2lhbEhhbmRsZT86IEtvbnZhLkNpcmNsZTtcbiAgb25QYXJhbXNDaGFuZ2VkPzogKHByb3A6IE51bWVyaWNhbERlc2lyYWJpbGl0eSkgPT4gdm9pZDtcblxuICAvLyBGbGFnIHRvIHByZXZlbnQgdG91Y2hwYWQgcmlnaHQtY2xpY2sgZnJvbSBhZGRpbmcgYSBuZXcgcG9pbnRcbiAgcHJpdmF0ZSBpZ25vcmVOZXh0Q2xpY2sgPSBmYWxzZTtcbiAgcHJpdmF0ZSBkcmFnU2NhbGVYID0gMDtcbiAgcHJpdmF0ZSBkcmFnU2NhbGVZID0gMDtcbiAgcHJpdmF0ZSBfd2lkdGg6IG51bWJlcjtcbiAgcHJpdmF0ZSBfaGVpZ2h0OiBudW1iZXI7XG5cbiAgY29uc3RydWN0b3IocHJvcDogTnVtZXJpY2FsRGVzaXJhYmlsaXR5LCB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHRoaXMuX3Byb3AgPSBwcm9wO1xuICAgIHRoaXMuX3dpZHRoID0gd2lkdGg7XG4gICAgdGhpcy5faGVpZ2h0ID0gaGVpZ2h0O1xuICAgIHRoaXMuZW5zdXJlRGVmYXVsdExpbmUoKTtcbiAgICB0aGlzLnJvb3Quc3R5bGUud2lkdGggPSBgJHt3aWR0aH1weGA7XG4gICAgdGhpcy5yb290LnN0eWxlLmhlaWdodCA9IGAke2hlaWdodH1weGA7XG4gICAgdGhpcy5yb290LnN0eWxlLnBvc2l0aW9uID0gJ3JlbGF0aXZlJztcblxuICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB0aGlzLmluaXRLb252YSh3aWR0aCwgaGVpZ2h0KSk7XG4gIH1cblxuICBwcml2YXRlIGVuc3VyZURlZmF1bHRMaW5lKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9wcm9wLmxpbmUubGVuZ3RoID4gMClcbiAgICAgIHJldHVybjtcblxuICAgIGNvbnN0IG1pbiA9IHRoaXMuX3Byb3AubWluID8/IDA7XG4gICAgY29uc3QgbWF4ID0gdGhpcy5fcHJvcC5tYXggPz8gMTtcbiAgICB0aGlzLl9wcm9wLmxpbmUgPSBbW21pbiwgMC41XSwgW21heCwgMC41XV07XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZURyYWdTY2FsZXMoKTogdm9pZCB7XG4gICAgY29uc3QgcGxvdFdpZHRoID0gdGhpcy5fd2lkdGggLSBFRElUT1JfUEFERElORy5sZWZ0IC0gRURJVE9SX1BBRERJTkcucmlnaHQ7XG4gICAgY29uc3QgcGxvdEhlaWdodCA9IHRoaXMuX2hlaWdodCAtIEVESVRPUl9QQURESU5HLnRvcCAtIEVESVRPUl9QQURESU5HLmJvdHRvbTtcbiAgICB0aGlzLmRyYWdTY2FsZVggPSAodGhpcy5nZXRNYXhYKCkgLSB0aGlzLmdldE1pblgoKSkgLyBwbG90V2lkdGg7XG4gICAgdGhpcy5kcmFnU2NhbGVZID0gMSAvIHBsb3RIZWlnaHQ7XG4gIH1cblxuICBwcml2YXRlIGlzSW5QbG90QXJlYShwb3M6IHt4OiBudW1iZXIsIHk6IG51bWJlcn0sIHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHBvcy54ID49IEVESVRPUl9QQURESU5HLmxlZnQgJiZcbiAgICAgIHBvcy54IDw9IHdpZHRoIC0gRURJVE9SX1BBRERJTkcucmlnaHQgJiZcbiAgICAgIHBvcy55ID49IEVESVRPUl9QQURESU5HLnRvcCAmJlxuICAgICAgcG9zLnkgPD0gaGVpZ2h0IC0gRURJVE9SX1BBRERJTkcuYm90dG9tXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaW5pdEtvbnZhKHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgaWYgKCF0aGlzLnJvb3QucGFyZW50RWxlbWVudCkge1xuICAgICAgY29uc29sZS53YXJuKCdLb252YSBjb250YWluZXIgbm90IGF0dGFjaGVkIHRvIERPTSB5ZXQuJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgS29udmEgPSBhd2FpdCBnZXRLb252YSgpO1xuICAgIHRoaXMuYmFyc0xheWVyID0gbmV3IEtvbnZhLkxheWVyKCk7XG5cbiAgICB0aGlzLnN0YWdlID0gbmV3IEtvbnZhLlN0YWdlKHtcbiAgICAgIGNvbnRhaW5lcjogdGhpcy5yb290LFxuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgfSk7XG5cbiAgICB0aGlzLnN0YWdlLmFkZCh0aGlzLmJhcnNMYXllcik7XG4gICAgdGhpcy5sYXllciA9IG5ldyBLb252YS5MYXllcigpO1xuICAgIHRoaXMuc3RhZ2UuYWRkKHRoaXMubGF5ZXIpO1xuXG4gICAgY29uc3QgbWluWCA9IHRoaXMuZ2V0TWluWCgpO1xuICAgIGNvbnN0IG1heFggPSB0aGlzLmdldE1heFgoKTtcblxuICAgIC8vIC0tLSBEcmF3IEF4ZXMgLS0tXG4gICAgdGhpcy5kcmF3QXhlcyhtaW5YLCBtYXhYLCB3aWR0aCwgaGVpZ2h0KTtcblxuICAgIC8vIC0tLSBEcmF3IExpbmUgYW5kIFBvaW50cyAtLS1cbiAgICB0aGlzLmtvbnZhTGluZSA9IG5ldyBLb252YS5MaW5lKHtcbiAgICAgIHBvaW50czogW10sXG4gICAgICBzdHJva2U6IENPTE9SUy5saW5lLFxuICAgICAgc3Ryb2tlV2lkdGg6IDIsXG4gICAgICBsaW5lQ2FwOiAncm91bmQnLFxuICAgICAgbGluZUpvaW46ICdyb3VuZCcsXG4gICAgfSk7XG4gICAgdGhpcy5sYXllci5hZGQodGhpcy5rb252YUxpbmUpO1xuXG4gICAgdGhpcy5wb2ludHNHcm91cCA9IG5ldyBLb252YS5Hcm91cCgpO1xuICAgIHRoaXMubGF5ZXIuYWRkKHRoaXMucG9pbnRzR3JvdXApO1xuXG4gICAgLy8gLS0tIFJlZHJhdyBGdW5jdGlvbiAtLS1cbiAgICB0aGlzLnJlZHJhd0ZuID0gKG5vdGlmeTogYm9vbGVhbiA9IHRydWUpID0+IHtcbiAgICAgIGNvbnN0IG1pblggPSB0aGlzLmdldE1pblgoKTtcbiAgICAgIGNvbnN0IG1heFggPSB0aGlzLmdldE1heFgoKTtcblxuICAgICAgaWYgKHRoaXMuX3Byb3AubW9kZSA9PT0gJ2ZyZWVmb3JtJyAmJiB0aGlzLl9wcm9wLmZyZWVmb3JtTGluZSlcbiAgICAgICAgdGhpcy5fcHJvcC5saW5lID0gdGhpcy5fcHJvcC5mcmVlZm9ybUxpbmU7XG5cbiAgICAgIGlmICh0aGlzLl9wcm9wLm1vZGUgIT09ICdmcmVlZm9ybScpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9wcm9wLmZyZWVmb3JtTGluZSlcbiAgICAgICAgICB0aGlzLl9wcm9wLmZyZWVmb3JtTGluZSA9IFsuLi50aGlzLl9wcm9wLmxpbmVdO1xuICAgICAgICB0aGlzLl9wcm9wLmxpbmUgPSB0aGlzLmNvbXB1dGVMaW5lKCk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMucG9pbnRzR3JvdXAhLmRlc3Ryb3lDaGlsZHJlbigpO1xuICAgICAgY29uc3Qga29udmFQb2ludHM6IG51bWJlcltdID0gW107XG5cbiAgICAgIGNvbnN0IG1hcHBlciA9IG5ldyBDb29yZE1hcHBlcihtaW5YLCBtYXhYLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICAgIGNvbnN0IHNvcnRlZEluZGljZXMgPSBbLi4udGhpcy5fcHJvcC5saW5lLmtleXMoKV1cbiAgICAgICAgLnNvcnQoKGEsIGIpID0+IHRoaXMuX3Byb3AubGluZVthXVswXSAtIHRoaXMuX3Byb3AubGluZVtiXVswXSk7XG4gICAgICBjb25zdCBzb3J0ZWRMaW5lID0gc29ydGVkSW5kaWNlcy5tYXAoKGlkeCkgPT4gdGhpcy5fcHJvcC5saW5lW2lkeF0pO1xuXG4gICAgICBzb3J0ZWRMaW5lLmZvckVhY2goKHAsIGluZGV4KSA9PiB7XG4gICAgICAgIGNvbnN0IGNvb3JkcyA9IG1hcHBlci50b0NhbnZhc0Nvb3JkcyhbcFswXSwgcFsxXV0pO1xuICAgICAgICBrb252YVBvaW50cy5wdXNoKGNvb3Jkcy54LCBjb29yZHMueSk7XG5cbiAgICAgICAgaWYgKHRoaXMuX3Byb3AubW9kZSAhPT0gJ2ZyZWVmb3JtJylcbiAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgY29uc3QgcG9pbnRDaXJjbGUgPSBuZXcgS29udmEuQ2lyY2xlKHtcbiAgICAgICAgICB4OiBjb29yZHMueCxcbiAgICAgICAgICB5OiBjb29yZHMueSxcbiAgICAgICAgICByYWRpdXM6IFBPSU5UX1JBRElVUyxcbiAgICAgICAgICBmaWxsOiAnd2hpdGUnLFxuICAgICAgICAgIHN0cm9rZTogQ09MT1JTLmxpbmUsXG4gICAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgICAgZHJhZ2dhYmxlOiB0cnVlLFxuICAgICAgICAgIGhpdFN0cm9rZVdpZHRoOiA1LFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTdG9yZSBpbmRleCBkaXJlY3RseSBvbiB0aGUgbm9kZSBmb3IgZWFzeSBhY2Nlc3NcbiAgICAgICAgcG9pbnRDaXJjbGUuc2V0QXR0cignX2RhdGFJbmRleCcsIHNvcnRlZEluZGljZXNbaW5kZXhdKTtcblxuICAgICAgICBwb2ludENpcmNsZS5vbignZHJhZ21vdmUnLCAoZXZ0KSA9PiB7XG4gICAgICAgICAgY29uc3QgY2lyY2xlID0gZXZ0LnRhcmdldCBhcyBLb252YS5DaXJjbGU7XG4gICAgICAgICAgY29uc3QgcG9zID0gY2lyY2xlLnBvc2l0aW9uKCk7XG4gICAgICAgICAgY29uc3QgZGF0YUluZGV4ID0gY2lyY2xlLmdldEF0dHIoJ19kYXRhSW5kZXgnKTtcbiAgICAgICAgICBjb25zdCBzb3J0ZWRQb3MgPSBzb3J0ZWRJbmRpY2VzLmluZGV4T2YoZGF0YUluZGV4KTtcblxuICAgICAgICAgIC8vIENvbnN0cmFpbiBkcmFnZ2luZyBob3Jpem9udGFsbHkgYmV0d2VlbiBuZWlnaGJvcnMgKG9yIGJvdW5kcylcbiAgICAgICAgICBjb25zdCBwcmV2WCA9IHNvcnRlZFBvcyA+IDAgPyB0aGlzLl9wcm9wLmxpbmVbc29ydGVkSW5kaWNlc1tzb3J0ZWRQb3MgLSAxXV1bMF0gOiBtaW5YO1xuICAgICAgICAgIGNvbnN0IG5leHRYID0gc29ydGVkUG9zIDwgc29ydGVkSW5kaWNlcy5sZW5ndGggLSAxID9cbiAgICAgICAgICAgIHRoaXMuX3Byb3AubGluZVtzb3J0ZWRJbmRpY2VzW3NvcnRlZFBvcyArIDFdXVswXSA6XG4gICAgICAgICAgICBtYXhYO1xuXG4gICAgICAgICAgLy8gQWRkIGEgc21hbGwgYnVmZmVyIHRvIGF2b2lkIHBvaW50cyBvdmVybGFwcGluZyBleGFjdGx5XG4gICAgICAgICAgY29uc3QgYnVmZmVyID0gKG1heFggLSBtaW5YID09PSAwKSA/IDAgOiAwLjAwMSAqIChtYXhYIC0gbWluWCk7IC8vIEF2b2lkIE5hTiBpZiBtaW5YID09PSBtYXhYXG4gICAgICAgICAgY29uc3QgbWluQ2FudmFzWCA9IG1hcHBlci50b0NhbnZhc0Nvb3JkcyhbcHJldlggKyAoc29ydGVkUG9zID4gMCA/IGJ1ZmZlciA6IDApLCAwXSkueDtcbiAgICAgICAgICBjb25zdCBtYXhDYW52YXNYID0gbWFwcGVyLnRvQ2FudmFzQ29vcmRzKFtuZXh0WCAtIChzb3J0ZWRQb3MgPCBzb3J0ZWRJbmRpY2VzLmxlbmd0aCAtIDEgPyBidWZmZXIgOiAwKSwgMF0pLng7XG5cbiAgICAgICAgICBwb3MueCA9IE1hdGgubWF4KG1pbkNhbnZhc1gsIE1hdGgubWluKG1heENhbnZhc1gsIHBvcy54KSk7XG5cbiAgICAgICAgICBjb25zdCBwbG90VG9wID0gRURJVE9SX1BBRERJTkcudG9wO1xuICAgICAgICAgIGNvbnN0IHBsb3RCb3R0b20gPSBoZWlnaHQgLSBFRElUT1JfUEFERElORy5ib3R0b207XG4gICAgICAgICAgcG9zLnkgPSBNYXRoLm1heChwbG90VG9wLCBNYXRoLm1pbihwbG90Qm90dG9tLCBwb3MueSkpO1xuXG4gICAgICAgICAgY2lyY2xlLnBvc2l0aW9uKHBvcyk7XG5cbiAgICAgICAgICBjb25zdCBkYXRhQ29vcmRzID0gbWFwcGVyLnRvRGF0YUNvb3Jkcyhwb3MueCwgcG9zLnkpO1xuICAgICAgICAgIHRoaXMuX3Byb3AubGluZVtkYXRhSW5kZXhdWzBdID0gZGF0YUNvb3Jkcy54O1xuICAgICAgICAgIHRoaXMuX3Byb3AubGluZVtkYXRhSW5kZXhdWzFdID0gZGF0YUNvb3Jkcy55O1xuXG4gICAgICAgICAgY29uc3QgY3VycmVudEtvbnZhUG9pbnRzID0gdGhpcy5fcHJvcC5saW5lLm1hcCgocERhdGEsIGlkeCkgPT4ge1xuICAgICAgICAgICAgLy8gVXNlIGRyYWdnZWQgY2lyY2xlIHBvc2l0aW9uIGRpcmVjdGx5IGZvciB0aGUgcG9pbnQgYmVpbmcgZHJhZ2dlZFxuICAgICAgICAgICAgaWYgKGlkeCA9PT0gZGF0YUluZGV4KVxuICAgICAgICAgICAgICByZXR1cm4gW3Bvcy54LCBwb3MueV07XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgY29uc3QgYyA9IG1hcHBlci50b0NhbnZhc0Nvb3JkcyhbcERhdGFbMF0sIHBEYXRhWzFdXSk7XG4gICAgICAgICAgICAgIHJldHVybiBbYy54LCBjLnldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pLmZsYXQoKTtcblxuICAgICAgICAgIHRoaXMua29udmFMaW5lIS5wb2ludHMoY3VycmVudEtvbnZhUG9pbnRzKTtcbiAgICAgICAgICB0aGlzLmxheWVyIS5iYXRjaERyYXcoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcG9pbnRDaXJjbGUub24oJ2RyYWdlbmQnLCAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5fcHJvcC5saW5lLnNvcnQoKGEsIGIpID0+IGFbMF0gLSBiWzBdKTtcbiAgICAgICAgICB0aGlzLnJlZHJhd0ZuPy4oKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcG9pbnRDaXJjbGUub24oJ2NvbnRleHRtZW51JywgKGV2dCkgPT4ge1xuICAgICAgICAgIGV2dC5ldnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICBpZiAodGhpcy5fcHJvcC5saW5lLmxlbmd0aCA8PSAyKSB7XG4gICAgICAgICAgICBncm9rLnNoZWxsLndhcm5pbmcoJ0Nhbm5vdCByZW1vdmUgcG9pbnRzLCBtaW5pbXVtIG9mIDIgcmVxdWlyZWQuJyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGhpcy5pZ25vcmVOZXh0Q2xpY2sgPSB0cnVlO1xuICAgICAgICAgIGNvbnN0IGNpcmNsZSA9IGV2dC50YXJnZXQgYXMgS29udmEuQ2lyY2xlO1xuICAgICAgICAgIGNvbnN0IGRhdGFJbmRleCA9IGNpcmNsZS5nZXRBdHRyKCdfZGF0YUluZGV4JykgYXMgbnVtYmVyO1xuXG4gICAgICAgICAgaWYgKGRhdGFJbmRleCA+PSAwKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5fcHJvcC5taW4gPT0gbnVsbClcbiAgICAgICAgICAgICAgdGhpcy5fcHJvcC5taW4gPSB0aGlzLmdldE1pblgoKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9wcm9wLm1heCA9PSBudWxsKVxuICAgICAgICAgICAgICB0aGlzLl9wcm9wLm1heCA9IHRoaXMuZ2V0TWF4WCgpO1xuICAgICAgICAgICAgdGhpcy5fcHJvcC5saW5lLnNwbGljZShkYXRhSW5kZXgsIDEpO1xuICAgICAgICAgICAgdGhpcy5yZWRyYXdGbj8uKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBwb2ludENpcmNsZS5vbignbW91c2VlbnRlcicsIChldnQpID0+IHtcbiAgICAgICAgICB0aGlzLnN0YWdlIS5jb250YWluZXIoKS5zdHlsZS5jdXJzb3IgPSAncG9pbnRlcic7XG4gICAgICAgICAgY29uc3QgY2lyY2xlID0gZXZ0LnRhcmdldCBhcyBLb252YS5DaXJjbGU7XG4gICAgICAgICAgY29uc3QgcG9zID0gY2lyY2xlLnBvc2l0aW9uKCk7XG4gICAgICAgICAgY29uc3QgZGF0YUNvb3JkcyA9IG1hcHBlci50b0RhdGFDb29yZHMocG9zLngsIHBvcy55KTtcbiAgICAgICAgICBjb25zdCB0b29sdGlwVGV4dCA9IGBYOiAke2RhdGFDb29yZHMueC50b0ZpeGVkKDIpfSwgWTogJHtkYXRhQ29vcmRzLnkudG9GaXhlZCgyKX08YnI+PGJyPkRyYWcgdG8gbW92ZSwgZG91YmxlLWNsaWNrIHRvIGVkaXQsIHJpZ2h0LWNsaWNrIHRvIGRlbGV0ZWA7XG4gICAgICAgICAgdWkudG9vbHRpcC5zaG93KHRvb2x0aXBUZXh0LCBldnQuZXZ0LmNsaWVudFgsIGV2dC5ldnQuY2xpZW50WSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHBvaW50Q2lyY2xlLm9uKCdtb3VzZWxlYXZlJywgKCkgPT4ge1xuICAgICAgICAgIHRoaXMuc3RhZ2UhLmNvbnRhaW5lcigpLnN0eWxlLmN1cnNvciA9ICdkZWZhdWx0JztcbiAgICAgICAgICB1aS50b29sdGlwLmhpZGUoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcG9pbnRDaXJjbGUub24oJ2RibGNsaWNrIGRibHRhcCcsIChldnQpID0+IHtcbiAgICAgICAgICB0aGlzLmlnbm9yZU5leHRDbGljayA9IHRydWU7XG4gICAgICAgICAgdWkudG9vbHRpcC5oaWRlKCk7XG4gICAgICAgICAgY29uc3QgZGF0YUluZGV4ID0gKGV2dC50YXJnZXQgYXMgS29udmEuQ2lyY2xlKS5nZXRBdHRyKCdfZGF0YUluZGV4JykgYXMgbnVtYmVyO1xuICAgICAgICAgIHRoaXMuc2hvd1BvaW50RWRpdG9yKGRhdGFJbmRleCwgZXZ0LmV2dC5jbGllbnRYLCBldnQuZXZ0LmNsaWVudFkpO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLnBvaW50c0dyb3VwIS5hZGQocG9pbnRDaXJjbGUpO1xuICAgICAgfSk7XG5cbiAgICAgIHRoaXMua29udmFMaW5lIS5wb2ludHMoa29udmFQb2ludHMpO1xuICAgICAgdGhpcy5sYXllciEuYmF0Y2hEcmF3KCk7XG5cbiAgICAgIC8vIC0tLSBBZGQgc3BlY2lhbCBoYW5kbGUgKEdhdXNzaWFuIHBlYWsgLyBTaWdtb2lkIGluZmxlY3Rpb24pIC0tLVxuICAgICAgdGhpcy5hZGRTcGVjaWFsSGFuZGxlKHdpZHRoLCBoZWlnaHQpO1xuXG4gICAgICBpZiAobm90aWZ5KVxuICAgICAgICB0aGlzLm9uQ2hhbmdlZC5uZXh0KHRoaXMuX3Byb3AubGluZSk7XG4gICAgfTtcblxuICAgIC8vIC0tLSBMZWZ0LWNsaWNrIHRvIEFkZCBQb2ludCAtLS1cbiAgICB0aGlzLnN0YWdlLm9uKCdjbGljayB0YXAnLCAoZXZ0KSA9PiB7XG4gICAgICBpZiAodGhpcy5pZ25vcmVOZXh0Q2xpY2spIHtcbiAgICAgICAgdGhpcy5pZ25vcmVOZXh0Q2xpY2sgPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZXZ0LnRhcmdldCBpbnN0YW5jZW9mIEtvbnZhLkNpcmNsZSB8fCBldnQuZXZ0LmJ1dHRvbiAhPT0gMClcbiAgICAgICAgcmV0dXJuO1xuXG4gICAgICBjb25zdCBwb3MgPSB0aGlzLnN0YWdlPy5nZXRQb2ludGVyUG9zaXRpb24oKTtcbiAgICAgIGlmICghcG9zKVxuICAgICAgICByZXR1cm47XG5cbiAgICAgIGNvbnN0IG1pblggPSB0aGlzLmdldE1pblgoKTtcbiAgICAgIGNvbnN0IG1heFggPSB0aGlzLmdldE1heFgoKTtcblxuICAgICAgaWYgKCF0aGlzLmlzSW5QbG90QXJlYShwb3MsIHRoaXMuc3RhZ2UhLndpZHRoKCksIHRoaXMuc3RhZ2UhLmhlaWdodCgpKSlcbiAgICAgICAgcmV0dXJuO1xuXG4gICAgICBjb25zdCBtYXBwZXIgPSBuZXcgQ29vcmRNYXBwZXIobWluWCwgbWF4WCwgdGhpcy5zdGFnZSEud2lkdGgoKSwgdGhpcy5zdGFnZSEuaGVpZ2h0KCkpO1xuICAgICAgY29uc3QgZGF0YUNvb3JkcyA9IG1hcHBlci50b0RhdGFDb29yZHMocG9zLngsIHBvcy55KTtcblxuICAgICAgdGhpcy5fcHJvcC5saW5lLnB1c2goW2RhdGFDb29yZHMueCwgZGF0YUNvb3Jkcy55XSk7XG4gICAgICB0aGlzLl9wcm9wLmxpbmUuc29ydCgoYSwgYikgPT4gYVswXSAtIGJbMF0pO1xuICAgICAgdGhpcy5yZWRyYXdGbj8uKCk7XG4gICAgfSk7XG5cbiAgICAvLyBDdXJzb3IgY2hhbmdlXG4gICAgdGhpcy5zdGFnZS5vbignbW91c2Vtb3ZlJywgKGV2dCkgPT4ge1xuICAgICAgaWYgKCF0aGlzLnN0YWdlKVxuICAgICAgICByZXR1cm47XG4gICAgICBjb25zdCBwb3MgPSB0aGlzLnN0YWdlLmdldFBvaW50ZXJQb3NpdGlvbigpO1xuICAgICAgaWYgKCFwb3MpXG4gICAgICAgIHJldHVybjtcblxuICAgICAgaWYgKHRoaXMuX3Byb3AubW9kZSAhPT0gJ2ZyZWVmb3JtJykge1xuICAgICAgICBpZiAodGhpcy5pc0luUGxvdEFyZWEocG9zLCB3aWR0aCwgaGVpZ2h0KSlcbiAgICAgICAgICB0aGlzLnN0YWdlLmNvbnRhaW5lcigpLnN0eWxlLmN1cnNvciA9ICdncmFiJztcbiAgICAgICAgZWxzZVxuICAgICAgICAgIHRoaXMuc3RhZ2UuY29udGFpbmVyKCkuc3R5bGUuY3Vyc29yID0gJ2RlZmF1bHQnO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdGhpcy5zdGFnZS5vbignbW91c2VvdXQnLCAoKSA9PiB1aS50b29sdGlwLmhpZGUoKSk7XG5cbiAgICAvLyBFbmFibGUgY3VydmUgZHJhZyAoc21vb3RoKVxuICAgIHRoaXMuZW5hYmxlQ3VydmVEcmFnKHdpZHRoLCBoZWlnaHQpO1xuICAgIHRoaXMudXBkYXRlRHJhZ1NjYWxlcygpO1xuXG4gICAgLy8gSW5pdGlhbCBkcmF3XG4gICAgaWYgKHRoaXMucGVuZGluZ0JhclZhbHVlcykge1xuICAgICAgdGhpcy5kcmF3QmFycyh0aGlzLnBlbmRpbmdCYXJWYWx1ZXMpO1xuICAgICAgdGhpcy5wZW5kaW5nQmFyVmFsdWVzID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgICB0aGlzLnJlZHJhd0ZuPy4oZmFsc2UpO1xuICB9XG5cbiAgZ2V0IGxpbmUoKTogRGVzaXJhYmlsaXR5TGluZSB7XG4gICAgcmV0dXJuIHRoaXMuX3Byb3AubGluZTtcbiAgfVxuXG4gIHByaXZhdGUgY29tcHV0ZUxpbmUoKTogRGVzaXJhYmlsaXR5TGluZSB7XG4gICAgaWYgKHRoaXMuX3Byb3AubW9kZSA9PT0gJ2ZyZWVmb3JtJylcbiAgICAgIHJldHVybiB0aGlzLl9wcm9wLmxpbmU7XG5cbiAgICBjb25zdCBtaW5YID0gdGhpcy5nZXRNaW5YKCk7XG4gICAgY29uc3QgbWF4WCA9IHRoaXMuZ2V0TWF4WCgpO1xuICAgIGNvbnN0IG4gPSA2MDtcbiAgICBjb25zdCBsaW5lOiBEZXNpcmFiaWxpdHlMaW5lID0gW107XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8PSBuOyBpKyspIHtcbiAgICAgIGNvbnN0IHggPSBtaW5YICsgKG1heFggLSBtaW5YKSAqIChpIC8gbik7XG4gICAgICBsZXQgeSA9IDA7XG5cbiAgICAgIGlmICh0aGlzLl9wcm9wLm1vZGUgPT09ICdnYXVzc2lhbicpIHtcbiAgICAgICAgdGhpcy5fcHJvcC5tZWFuID8/PSAobWluWCArIG1heFgpIC8gMjtcbiAgICAgICAgdGhpcy5fcHJvcC5zaWdtYSA/Pz0gKG1heFggLSBtaW5YKSAvIDY7XG4gICAgICAgIGNvbnN0IG1lYW4gPSB0aGlzLl9wcm9wLm1lYW47XG4gICAgICAgIGNvbnN0IHNpZ21hID0gdGhpcy5fcHJvcC5zaWdtYTtcbiAgICAgICAgY29uc3QgeiA9ICh4IC0gbWVhbikgLyBzaWdtYTtcbiAgICAgICAgeSA9IE1hdGguZXhwKC0wLjUgKiB6ICogeik7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLl9wcm9wLm1vZGUgPT09ICdzaWdtb2lkJykge1xuICAgICAgICB0aGlzLl9wcm9wLngwID8/PSAobWluWCArIG1heFgpIC8gMjtcbiAgICAgICAgdGhpcy5fcHJvcC5rID8/PSAxMDtcbiAgICAgICAgY29uc3QgeDAgPSB0aGlzLl9wcm9wLngwO1xuICAgICAgICBjb25zdCBrID0gdGhpcy5fcHJvcC5rO1xuICAgICAgICB5ID0gMSAvICgxICsgTWF0aC5leHAoLWsgKiAoeCAtIHgwKSkpO1xuICAgICAgfVxuXG4gICAgICBsaW5lLnB1c2goW3gsIHldKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbGluZTtcbiAgfVxuXG4gIHByaXZhdGUgZHJhd0F4ZXMobWluWDogbnVtYmVyLCBtYXhYOiBudW1iZXIsIHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgY29uc3QgYXhpc0NvbG9yID0gZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpLmdldFByb3BlcnR5VmFsdWUoJy0tZ3JleS0yJykudHJpbSgpIHx8ICcjREJEQ0RGJztcbiAgICB0aGlzLmxheWVyIS5hZGQoXG4gICAgICBuZXcgX2tvbnZhIS5MaW5lKHtcbiAgICAgICAgcG9pbnRzOiBbRURJVE9SX1BBRERJTkcubGVmdCwgaGVpZ2h0IC0gRURJVE9SX1BBRERJTkcuYm90dG9tLCB3aWR0aCAtIEVESVRPUl9QQURESU5HLnJpZ2h0LCBoZWlnaHQgLSBFRElUT1JfUEFERElORy5ib3R0b21dLFxuICAgICAgICBzdHJva2U6IGF4aXNDb2xvcixcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICB9KSxcbiAgICAgIG5ldyBfa29udmEhLkxpbmUoe1xuICAgICAgICBwb2ludHM6IFtFRElUT1JfUEFERElORy5sZWZ0LCBFRElUT1JfUEFERElORy50b3AsIEVESVRPUl9QQURESU5HLmxlZnQsIGhlaWdodCAtIEVESVRPUl9QQURESU5HLmJvdHRvbV0sXG4gICAgICAgIHN0cm9rZTogYXhpc0NvbG9yLFxuICAgICAgICBzdHJva2VXaWR0aDogMSxcbiAgICAgIH0pLFxuICAgICAgbmV3IF9rb252YSEuVGV4dCh7eDogRURJVE9SX1BBRERJTkcubGVmdCwgeTogaGVpZ2h0IC0gRURJVE9SX1BBRERJTkcuYm90dG9tICsgMywgdGV4dDogbWluWC50b0ZpeGVkKDEpLCBmb250U2l6ZTogOSwgZmlsbDogJ2dyZXknfSksXG4gICAgICBuZXcgX2tvbnZhIS5UZXh0KHt4OiB3aWR0aCAtIEVESVRPUl9QQURESU5HLnJpZ2h0IC0gMTUsIHk6IGhlaWdodCAtIEVESVRPUl9QQURESU5HLmJvdHRvbSArIDMsIHRleHQ6IG1heFgudG9GaXhlZCgxKSwgZm9udFNpemU6IDksIGZpbGw6ICdncmV5J30pLFxuICAgICk7XG4gIH1cblxuICBnZXRNaW5YKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuX3Byb3AubWluID8/IE1hdGgubWluKC4uLnRoaXMuX3Byb3AubGluZS5tYXAoKHApID0+IHBbMF0pKSA/PyAwO1xuICB9XG5cbiAgZ2V0TWF4WCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLl9wcm9wLm1heCA/PyBNYXRoLm1heCguLi50aGlzLl9wcm9wLmxpbmUubWFwKChwKSA9PiBwWzBdKSkgPz8gMTtcbiAgfVxuXG4gIGdldERlZmF1bHRNZWFuKCk6IG51bWJlciB7XG4gICAgcmV0dXJuICh0aGlzLmdldE1pblgoKSArIHRoaXMuZ2V0TWF4WCgpKSAvIDI7XG4gIH1cblxuICBnZXREZWZhdWx0U2lnbWEoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gTWF0aC5tYXgoMC4wMSwgKHRoaXMuZ2V0TWF4WCgpIC0gdGhpcy5nZXRNaW5YKCkpIC8gNik7XG4gIH1cblxuICBnZXREZWZhdWx0WDAoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gKHRoaXMuZ2V0TWluWCgpICsgdGhpcy5nZXRNYXhYKCkpIC8gMjtcbiAgfVxuXG4gIGdldERlZmF1bHRLKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIDEwO1xuICB9XG5cbiAgcmVkcmF3QWxsKG5vdGlmeTogYm9vbGVhbiA9IHRydWUpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuc3RhZ2UgfHwgIXRoaXMubGF5ZXIgfHwgIXRoaXMucmVkcmF3Rm4pXG4gICAgICByZXR1cm47XG5cbiAgICBjb25zdCB3aWR0aCA9IHRoaXMuc3RhZ2Uud2lkdGgoKTtcbiAgICBjb25zdCBoZWlnaHQgPSB0aGlzLnN0YWdlLmhlaWdodCgpO1xuICAgIGNvbnN0IG1pblggPSB0aGlzLmdldE1pblgoKTtcbiAgICBjb25zdCBtYXhYID0gdGhpcy5nZXRNYXhYKCk7XG5cbiAgICB0aGlzLmxheWVyLmRlc3Ryb3lDaGlsZHJlbigpO1xuXG4gICAgdGhpcy5kcmF3QXhlcyhtaW5YLCBtYXhYLCB3aWR0aCwgaGVpZ2h0KTtcblxuICAgIHRoaXMubGF5ZXIuYWRkKHRoaXMua29udmFMaW5lISwgdGhpcy5wb2ludHNHcm91cCEpO1xuXG4gICAgdGhpcy5yZWRyYXdGbihub3RpZnkpO1xuXG4gICAgaWYgKHRoaXMuYmFyVmFsdWVzKVxuICAgICAgdGhpcy5kcmF3QmFycygpO1xuICB9XG5cbiAgZHJhd0JhcnModmFsdWVzPzogbnVtYmVyW10pIHtcbiAgICBpZiAodmFsdWVzKVxuICAgICAgdGhpcy5iYXJWYWx1ZXMgPSB2YWx1ZXM7XG5cbiAgICBpZiAoIXRoaXMuYmFyc0xheWVyKSB7XG4gICAgICB0aGlzLnBlbmRpbmdCYXJWYWx1ZXMgPSB2YWx1ZXM7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuYmFyc0xheWVyLmRlc3Ryb3lDaGlsZHJlbigpO1xuXG4gICAgaWYgKCF0aGlzLmJhclZhbHVlcyB8fCB0aGlzLmJhclZhbHVlcy5sZW5ndGggPT09IDApXG4gICAgICByZXR1cm47XG5cbiAgICBjb25zdCBzdGFnZSA9IHRoaXMuYmFyc0xheWVyLmdldFN0YWdlKCk7XG4gICAgaWYgKCFzdGFnZSkge1xuICAgICAgdGhpcy5wZW5kaW5nQmFyVmFsdWVzID0gdmFsdWVzO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHdpZHRoID0gc3RhZ2Uud2lkdGgoKTtcbiAgICBjb25zdCBoZWlnaHQgPSBzdGFnZS5oZWlnaHQoKTtcblxuICAgIGNvbnN0IG1pblggPSB0aGlzLmdldE1pblgoKTtcbiAgICBjb25zdCBtYXhYID0gdGhpcy5nZXRNYXhYKCk7XG5cbiAgICBpZiAobWF4WCA9PT0gbWluWClcbiAgICAgIHJldHVybjtcblxuICAgIGNvbnN0IG51bUJpbnMgPSAyMDtcbiAgICBjb25zdCBwbG90V2lkdGggPSB3aWR0aCAtIEVESVRPUl9QQURESU5HLmxlZnQgLSBFRElUT1JfUEFERElORy5yaWdodDtcbiAgICBjb25zdCBwbG90SGVpZ2h0ID0gaGVpZ2h0IC0gRURJVE9SX1BBRERJTkcudG9wIC0gRURJVE9SX1BBRERJTkcuYm90dG9tO1xuXG4gICAgY29uc3QgYmluV2lkdGggPSBNYXRoLm1heCgxZS05LCAobWF4WCAtIG1pblgpIC8gbnVtQmlucyk7XG4gICAgY29uc3QgYmlucyA9IG5ldyBBcnJheShudW1CaW5zKS5maWxsKDApO1xuXG4gICAgKHRoaXMuYmFyVmFsdWVzID8/IFtdKS5mb3JFYWNoKCh2KSA9PiB7XG4gICAgICBjb25zdCBpZHggPSBNYXRoLm1pbihNYXRoLmZsb29yKCh2IC0gbWluWCkgLyBiaW5XaWR0aCksIG51bUJpbnMgLSAxKTtcbiAgICAgIGJpbnNbaWR4XSsrO1xuICAgIH0pO1xuXG4gICAgY29uc3QgbWF4Q291bnQgPSBNYXRoLm1heCguLi5iaW5zKSB8fCAxO1xuXG4gICAgYmlucy5mb3JFYWNoKChjb3VudCwgaSkgPT4ge1xuICAgICAgY29uc3QgYmFyWCA9IEVESVRPUl9QQURESU5HLmxlZnQgKyAoaSAqIGJpbldpZHRoIC8gKG1heFggLSBtaW5YKSkgKiBwbG90V2lkdGg7XG4gICAgICBjb25zdCBiYXJXID0gKGJpbldpZHRoIC8gKG1heFggLSBtaW5YKSkgKiBwbG90V2lkdGggLSAxO1xuICAgICAgY29uc3QgYmFySCA9IChjb3VudCAvIG1heENvdW50KSAqIHBsb3RIZWlnaHQ7XG5cbiAgICAgIGNvbnN0IHJlY3QgPSBuZXcgX2tvbnZhIS5SZWN0KHtcbiAgICAgICAgeDogYmFyWCxcbiAgICAgICAgeTogRURJVE9SX1BBRERJTkcudG9wICsgcGxvdEhlaWdodCAtIGJhckgsXG4gICAgICAgIHdpZHRoOiBiYXJXLFxuICAgICAgICBoZWlnaHQ6IGJhckgsXG4gICAgICAgIGZpbGw6IENPTE9SUy5iYXJGaWxsLFxuICAgICAgICBvcGFjaXR5OiAwLjI1LFxuICAgICAgICBzdHJva2U6IENPTE9SUy5iYXJTdHJva2UsXG4gICAgICAgIHN0cm9rZVdpZHRoOiAwLjUsXG4gICAgICB9KTtcblxuICAgICAgdGhpcy5iYXJzTGF5ZXIhLmFkZChyZWN0KTtcbiAgICB9KTtcblxuICAgIHRoaXMuYmFyc0xheWVyIS5iYXRjaERyYXcoKTtcbiAgfVxuXG4gIHByaXZhdGUgZW5hYmxlQ3VydmVEcmFnKHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgaWYgKCF0aGlzLnN0YWdlKVxuICAgICAgcmV0dXJuO1xuXG4gICAgbGV0IGRyYWdnaW5nID0gZmFsc2U7XG4gICAgbGV0IHN0YXJ0UG9pbnRlcjoge3g6IG51bWJlciwgeTogbnVtYmVyfSB8IG51bGwgPSBudWxsO1xuICAgIGxldCBzdGFydE1lYW4gPSAwO1xuICAgIGxldCBzdGFydFNpZ21hID0gMDtcbiAgICBsZXQgc3RhcnRYMCA9IDA7XG4gICAgbGV0IHN0YXJ0SyA9IDA7XG5cbiAgICB0aGlzLnN0YWdlLm9uKCdtb3VzZWRvd24gdG91Y2hzdGFydCcsIChldnQpID0+IHtcbiAgICAgIGlmICh0aGlzLl9wcm9wLm1vZGUgPT09ICdmcmVlZm9ybScpXG4gICAgICAgIHJldHVybjtcbiAgICAgIGlmICghZXZ0LmV2dClcbiAgICAgICAgcmV0dXJuO1xuXG4gICAgICBjb25zdCBwb3MgPSB0aGlzLnN0YWdlIS5nZXRQb2ludGVyUG9zaXRpb24oKTtcbiAgICAgIGlmICghcG9zKVxuICAgICAgICByZXR1cm47XG5cbiAgICAgIGlmICghdGhpcy5pc0luUGxvdEFyZWEocG9zLCB3aWR0aCwgaGVpZ2h0KSlcbiAgICAgICAgcmV0dXJuO1xuXG4gICAgICBkcmFnZ2luZyA9IHRydWU7XG4gICAgICBzdGFydFBvaW50ZXIgPSBwb3M7XG5cbiAgICAgIHN0YXJ0TWVhbiA9IHRoaXMuX3Byb3AubWVhbiA/PyAodGhpcy5nZXRNaW5YKCkgKyB0aGlzLmdldE1heFgoKSkgLyAyO1xuICAgICAgc3RhcnRTaWdtYSA9IHRoaXMuX3Byb3Auc2lnbWEgPz8gKHRoaXMuZ2V0TWF4WCgpIC0gdGhpcy5nZXRNaW5YKCkpIC8gNjtcbiAgICAgIHN0YXJ0WDAgPSB0aGlzLl9wcm9wLngwID8/ICh0aGlzLmdldE1pblgoKSArIHRoaXMuZ2V0TWF4WCgpKSAvIDI7XG4gICAgICBzdGFydEsgPSB0aGlzLl9wcm9wLmsgPz8gMTA7XG5cbiAgICAgIHRoaXMuc3RhZ2UhLmNvbnRhaW5lcigpLnN0eWxlLmN1cnNvciA9ICdncmFiYmluZyc7XG4gICAgfSk7XG5cbiAgICB0aGlzLnN0YWdlLm9uKCdtb3VzZW1vdmUgdG91Y2htb3ZlJywgKGV2dCkgPT4ge1xuICAgICAgaWYgKCFkcmFnZ2luZyB8fCAhc3RhcnRQb2ludGVyKVxuICAgICAgICByZXR1cm47XG5cbiAgICAgIGNvbnN0IHBvcyA9IHRoaXMuc3RhZ2UhLmdldFBvaW50ZXJQb3NpdGlvbigpO1xuICAgICAgaWYgKCFwb3MpXG4gICAgICAgIHJldHVybjtcblxuICAgICAgY29uc3QgZHggPSBwb3MueCAtIHN0YXJ0UG9pbnRlci54O1xuICAgICAgY29uc3QgZHkgPSBwb3MueSAtIHN0YXJ0UG9pbnRlci55O1xuXG4gICAgICBpZiAodGhpcy5fcHJvcC5tb2RlID09PSAnZ2F1c3NpYW4nKSB7XG4gICAgICAgIHRoaXMuX3Byb3AubWVhbiA9IHN0YXJ0TWVhbiArIGR4ICogdGhpcy5kcmFnU2NhbGVYO1xuICAgICAgICB0aGlzLl9wcm9wLnNpZ21hID0gTWF0aC5tYXgoMC4wMSwgc3RhcnRTaWdtYSArICgtZHkpICogdGhpcy5kcmFnU2NhbGVZICogKHRoaXMuZ2V0TWF4WCgpIC0gdGhpcy5nZXRNaW5YKCkpKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuX3Byb3AubW9kZSA9PT0gJ3NpZ21vaWQnKSB7XG4gICAgICAgIHRoaXMuX3Byb3AueDAgPSBzdGFydFgwICsgZHggKiB0aGlzLmRyYWdTY2FsZVg7XG4gICAgICAgIHRoaXMuX3Byb3AuayA9IE1hdGgubWF4KDAuMSwgc3RhcnRLICsgKC1keSkgKiB0aGlzLmRyYWdTY2FsZVkgKiA1MCk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX3Byb3AubGluZSA9IHRoaXMuY29tcHV0ZUxpbmUoKTtcbiAgICAgIHRoaXMucmVkcmF3Rm4/LigpO1xuICAgICAgdGhpcy5vblBhcmFtc0NoYW5nZWQ/Lih0aGlzLl9wcm9wKTtcbiAgICB9KTtcblxuICAgIHRoaXMuc3RhZ2Uub24oJ21vdXNldXAgdG91Y2hlbmQnLCAoKSA9PiB7XG4gICAgICBkcmFnZ2luZyA9IGZhbHNlO1xuICAgICAgc3RhcnRQb2ludGVyID0gbnVsbDtcbiAgICAgIHRoaXMuc3RhZ2UhLmNvbnRhaW5lcigpLnN0eWxlLmN1cnNvciA9ICdkZWZhdWx0JztcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkU3BlY2lhbEhhbmRsZSh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIGNvbnN0IGNsYW1wID0gKHY6IG51bWJlciwgbWluOiBudW1iZXIsIG1heDogbnVtYmVyKSA9PiBNYXRoLm1heChtaW4sIE1hdGgubWluKG1heCwgdikpO1xuXG4gICAgaWYgKHRoaXMuX3Byb3AubW9kZSA9PT0gJ2ZyZWVmb3JtJylcbiAgICAgIHJldHVybjtcblxuICAgIGNvbnN0IG1pblggPSB0aGlzLmdldE1pblgoKTtcbiAgICBjb25zdCBtYXhYID0gdGhpcy5nZXRNYXhYKCk7XG4gICAgY29uc3QgbWFwcGVyID0gbmV3IENvb3JkTWFwcGVyKG1pblgsIG1heFgsIHdpZHRoLCBoZWlnaHQpO1xuXG4gICAgbGV0IHggPSAobWluWCArIG1heFgpIC8gMjtcbiAgICBsZXQgeSA9IDAuNTtcblxuICAgIGlmICh0aGlzLl9wcm9wLm1vZGUgPT09ICdnYXVzc2lhbicpIHtcbiAgICAgIHggPSB0aGlzLl9wcm9wLm1lYW4gPz8gKG1pblggKyBtYXhYKSAvIDI7XG4gICAgICB5ID0gMTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuX3Byb3AubW9kZSA9PT0gJ3NpZ21vaWQnKSB7XG4gICAgICB4ID0gdGhpcy5fcHJvcC54MCA/PyAobWluWCArIG1heFgpIC8gMjtcbiAgICAgIHkgPSAwLjU7XG4gICAgfVxuXG4gICAgY29uc3QgY29vcmRzID0gbWFwcGVyLnRvQ2FudmFzQ29vcmRzKFt4LCB5XSk7XG5cbiAgICBpZiAoIXRoaXMuc3BlY2lhbEhhbmRsZSkge1xuICAgICAgdGhpcy5zcGVjaWFsSGFuZGxlID0gbmV3IF9rb252YSEuQ2lyY2xlKHtcbiAgICAgICAgeDogY29vcmRzLngsXG4gICAgICAgIHk6IGNvb3Jkcy55LFxuICAgICAgICByYWRpdXM6IDcsXG4gICAgICAgIGZpbGw6IENPTE9SUy5oYW5kbGUsXG4gICAgICAgIGRyYWdnYWJsZTogdHJ1ZSxcbiAgICAgICAgaGl0U3Ryb2tlV2lkdGg6IDE1LFxuICAgICAgfSk7XG5cbiAgICAgIHRoaXMuc3BlY2lhbEhhbmRsZS5vbignZHJhZ21vdmUnLCAoZXZ0KSA9PiB7XG4gICAgICAgIGNvbnN0IHBvcyA9IGV2dC50YXJnZXQucG9zaXRpb24oKTtcbiAgICAgICAgY29uc3QgZGF0YSA9IG1hcHBlci50b0RhdGFDb29yZHMocG9zLngsIHBvcy55KTtcblxuICAgICAgICBpZiAodGhpcy5fcHJvcC5tb2RlID09PSAnZ2F1c3NpYW4nKSB7XG4gICAgICAgICAgdGhpcy5fcHJvcC5tZWFuID0gZGF0YS54O1xuICAgICAgICAgIHRoaXMuX3Byb3Auc2lnbWEgPSBNYXRoLm1heCgwLjAxLCBNYXRoLmFicyhkYXRhLnkgLSAxKSk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5fcHJvcC5tb2RlID09PSAnc2lnbW9pZCcpIHtcbiAgICAgICAgICB0aGlzLl9wcm9wLngwID0gZGF0YS54O1xuICAgICAgICAgIHRoaXMuX3Byb3AuayA9IGNsYW1wKE1hdGguYWJzKGRhdGEueSAtIDAuNSkgKiAzMCwgMC4xLCAzMCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9wcm9wLmxpbmUgPSB0aGlzLmNvbXB1dGVMaW5lKCk7XG4gICAgICAgIHRoaXMucmVkcmF3Rm4/LigpO1xuICAgICAgICB0aGlzLm9uUGFyYW1zQ2hhbmdlZD8uKHRoaXMuX3Byb3ApO1xuICAgICAgfSk7XG5cbiAgICAgIHRoaXMubGF5ZXIhLmFkZCh0aGlzLnNwZWNpYWxIYW5kbGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoIXRoaXMuc3BlY2lhbEhhbmRsZS5nZXRMYXllcigpKVxuICAgICAgICB0aGlzLmxheWVyIS5hZGQodGhpcy5zcGVjaWFsSGFuZGxlKTtcbiAgICAgIHRoaXMuc3BlY2lhbEhhbmRsZS5wb3NpdGlvbihjb29yZHMpO1xuICAgIH1cbiAgICB0aGlzLmxheWVyIS5iYXRjaERyYXcoKTtcbiAgfVxuXG4gIHByaXZhdGUgc2hvd1BvaW50RWRpdG9yKGRhdGFJbmRleDogbnVtYmVyLCBjbGllbnRYOiBudW1iZXIsIGNsaWVudFk6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IHBvaW50ID0gdGhpcy5fcHJvcC5saW5lW2RhdGFJbmRleF07XG4gICAgY29uc3QgeElucHV0ID0gdWkuaW5wdXQuZmxvYXQoJ1gnLCB7dmFsdWU6IHBvaW50WzBdLCBtaW46IHRoaXMuZ2V0TWluWCgpLCBtYXg6IHRoaXMuZ2V0TWF4WCgpLCBmb3JtYXQ6ICcjMC4wMCcsIHN0ZXA6IDAuMDF9KTtcbiAgICBjb25zdCB5SW5wdXQgPSB1aS5pbnB1dC5mbG9hdCgnWScsIHt2YWx1ZTogcG9pbnRbMV0sIG1pbjogMCwgbWF4OiAxLCBmb3JtYXQ6ICcjMC4wMCcsIHN0ZXA6IDAuMDF9KTtcblxuICAgIGNvbnN0IGNsb3NlID0gKCkgPT4ge1xuICAgICAgY29udGVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJywgb25LZXkpO1xuICAgICAgcG9wdXAucmVtb3ZlKCk7XG4gICAgfTtcblxuICAgIGNvbnN0IGFwcGx5ID0gKCkgPT4ge1xuICAgICAgY29uc3QgeCA9IHhJbnB1dC52YWx1ZTtcbiAgICAgIGNvbnN0IHkgPSB5SW5wdXQudmFsdWU7XG4gICAgICBpZiAoeCA9PSBudWxsIHx8IHkgPT0gbnVsbCB8fCBpc05hTih4KSB8fCBpc05hTih5KSlcbiAgICAgICAgcmV0dXJuO1xuICAgICAgdGhpcy5fcHJvcC5saW5lW2RhdGFJbmRleF0gPSBbeCwgeV07XG4gICAgICB0aGlzLnJlZHJhd0FsbCgpO1xuICAgIH07XG5cbiAgICBjb25zdCBvbktleSA9IChlOiBLZXlib2FyZEV2ZW50KSA9PiB7XG4gICAgICBpZiAoZS5rZXkgPT09ICdFbnRlcicpIHtcbiAgICAgICAgYXBwbHkoKTtcbiAgICAgICAgY2xvc2UoKTtcbiAgICAgIH1cbiAgICAgIGlmIChlLmtleSA9PT0gJ0VzY2FwZScpXG4gICAgICAgIGNsb3NlKCk7XG4gICAgfTtcblxuICAgIGNvbnN0IGNvbnRlbnQgPSB1aS5pbnB1dHMoW3hJbnB1dCwgeUlucHV0XSk7XG4gICAgY29udGVudC5zdHlsZS5vdmVyZmxvdyA9ICdoaWRkZW4nO1xuICAgIGNvbnRlbnQuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIG9uS2V5KTtcblxuICAgIGNvbnN0IHJvb3RSZWN0ID0gdGhpcy5yb290LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IHBvcHVwID0gdWkuc2hvd1BvcHVwKGNvbnRlbnQsIHRoaXMucm9vdCwge2R4OiBjbGllbnRYIC0gcm9vdFJlY3QubGVmdCwgZHk6IGNsaWVudFkgLSByb290UmVjdC5ib3R0b20sIHNtYXJ0OiBmYWxzZX0pO1xuICB9XG5cbiAgc2V0UmFuZ2UobWluOiBudW1iZXIsIG1heDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3Qgb2xkTWluID0gdGhpcy5nZXRNaW5YKCk7XG4gICAgY29uc3Qgb2xkTWF4ID0gdGhpcy5nZXRNYXhYKCk7XG4gICAgY29uc3Qgb2xkUmFuZ2UgPSBvbGRNYXggLSBvbGRNaW47XG4gICAgY29uc3QgbmV3UmFuZ2UgPSBtYXggLSBtaW47XG5cbiAgICBpZiAob2xkUmFuZ2UgIT09IDAgJiYgbmV3UmFuZ2UgIT09IDApIHtcbiAgICAgIGNvbnN0IHNjYWxlID0gbmV3UmFuZ2UgLyBvbGRSYW5nZTtcbiAgICAgIGNvbnN0IHJlbWFwID0gKHg6IG51bWJlcikgPT4gbWluICsgKHggLSBvbGRNaW4pICogc2NhbGU7XG5cbiAgICAgIGlmICh0aGlzLl9wcm9wLm1lYW4gIT0gbnVsbClcbiAgICAgICAgdGhpcy5fcHJvcC5tZWFuID0gcmVtYXAodGhpcy5fcHJvcC5tZWFuKTtcbiAgICAgIGlmICh0aGlzLl9wcm9wLnNpZ21hICE9IG51bGwpXG4gICAgICAgIHRoaXMuX3Byb3Auc2lnbWEgKj0gc2NhbGU7XG4gICAgICBpZiAodGhpcy5fcHJvcC54MCAhPSBudWxsKVxuICAgICAgICB0aGlzLl9wcm9wLngwID0gcmVtYXAodGhpcy5fcHJvcC54MCk7XG4gICAgICBpZiAodGhpcy5fcHJvcC5rICE9IG51bGwpXG4gICAgICAgIHRoaXMuX3Byb3AuayAvPSBzY2FsZTtcblxuICAgICAgZm9yIChjb25zdCBwIG9mIHRoaXMuX3Byb3AubGluZSlcbiAgICAgICAgcFswXSA9IHJlbWFwKHBbMF0pO1xuXG4gICAgICBpZiAodGhpcy5fcHJvcC5mcmVlZm9ybUxpbmUpIHtcbiAgICAgICAgZm9yIChjb25zdCBwIG9mIHRoaXMuX3Byb3AuZnJlZWZvcm1MaW5lKVxuICAgICAgICAgIHBbMF0gPSByZW1hcChwWzBdKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLl9wcm9wLm1pbiA9IG1pbjtcbiAgICB0aGlzLl9wcm9wLm1heCA9IG1heDtcbiAgICB0aGlzLnVwZGF0ZURyYWdTY2FsZXMoKTtcbiAgICB0aGlzLnJlZHJhd0FsbChmYWxzZSk7XG4gIH1cblxuICBzZXRDb2x1bW4oY29sOiBERy5Db2x1bW4gfCBudWxsKTogdm9pZCB7XG4gICAgaWYgKCFjb2wpXG4gICAgICByZXR1cm47XG5cbiAgICBjb25zdCB2YWx1ZXMgPSBjb2wudG9MaXN0KCk7XG4gICAgdGhpcy5kcmF3QmFycyh2YWx1ZXMpO1xuICB9XG59XG4iXX0=