@datagrok-libraries/statistics 1.10.0 → 1.12.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.
- package/CHANGELOG.md +5 -0
- package/css/styles.css +234 -0
- package/package.json +3 -2
- package/src/mpo/dialogs/desirability-mode-dialog.d.ts +14 -0
- package/src/mpo/dialogs/desirability-mode-dialog.d.ts.map +1 -0
- package/src/mpo/dialogs/desirability-mode-dialog.js +198 -0
- package/src/mpo/editors/desirability-editor-factory.d.ts +16 -0
- package/src/mpo/editors/desirability-editor-factory.d.ts.map +1 -0
- package/src/mpo/editors/desirability-editor-factory.js +11 -0
- package/src/mpo/editors/mpo-categorical-editor.d.ts +24 -0
- package/src/mpo/editors/mpo-categorical-editor.d.ts.map +1 -0
- package/src/mpo/editors/mpo-categorical-editor.js +113 -0
- package/src/mpo/editors/mpo-line-editor.d.ts +47 -0
- package/src/mpo/editors/mpo-line-editor.d.ts.map +1 -0
- package/src/mpo/editors/mpo-line-editor.js +600 -0
- package/src/mpo/mpo-profile-editor.d.ts +42 -6
- package/src/mpo/mpo-profile-editor.d.ts.map +1 -1
- package/src/mpo/mpo-profile-editor.js +369 -59
- package/src/mpo/mpo.d.ts +53 -3
- package/src/mpo/mpo.d.ts.map +1 -1
- package/src/mpo/mpo.js +92 -16
- package/src/mpo/utils.d.ts +6 -0
- package/src/mpo/utils.d.ts.map +1 -0
- package/src/mpo/utils.js +17 -0
- package/src/mpo/mpo-line-editor.d.ts +0 -10
- package/src/mpo/mpo-line-editor.d.ts.map +0 -1
- package/src/mpo/mpo-line-editor.js +0 -258
|
@@ -0,0 +1,600 @@
|
|
|
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([], 'statistics-mpo-line-editor');
|
|
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, this._width, this._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 = this._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(this._width, this._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, this._width, this._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();
|
|
272
|
+
this.updateDragScales();
|
|
273
|
+
ui.onSizeChanged(this.root).subscribe((_) => {
|
|
274
|
+
const { clientWidth: w, clientHeight: h } = this.root;
|
|
275
|
+
if (w > 0 && h > 0)
|
|
276
|
+
this.resize(w, h);
|
|
277
|
+
});
|
|
278
|
+
// Initial draw
|
|
279
|
+
if (this.pendingBarValues) {
|
|
280
|
+
this.drawBars(this.pendingBarValues);
|
|
281
|
+
this.pendingBarValues = undefined;
|
|
282
|
+
}
|
|
283
|
+
(_a = this.redrawFn) === null || _a === void 0 ? void 0 : _a.call(this, false);
|
|
284
|
+
}
|
|
285
|
+
get line() {
|
|
286
|
+
return this._prop.line;
|
|
287
|
+
}
|
|
288
|
+
computeLine() {
|
|
289
|
+
var _a, _b, _c, _d;
|
|
290
|
+
var _e, _f, _g, _h;
|
|
291
|
+
if (this._prop.mode === 'freeform')
|
|
292
|
+
return this._prop.line;
|
|
293
|
+
const minX = this.getMinX();
|
|
294
|
+
const maxX = this.getMaxX();
|
|
295
|
+
const n = 60;
|
|
296
|
+
const line = [];
|
|
297
|
+
for (let i = 0; i <= n; i++) {
|
|
298
|
+
const x = minX + (maxX - minX) * (i / n);
|
|
299
|
+
let y = 0;
|
|
300
|
+
if (this._prop.mode === 'gaussian') {
|
|
301
|
+
(_a = (_e = this._prop).mean) !== null && _a !== void 0 ? _a : (_e.mean = (minX + maxX) / 2);
|
|
302
|
+
(_b = (_f = this._prop).sigma) !== null && _b !== void 0 ? _b : (_f.sigma = (maxX - minX) / 6);
|
|
303
|
+
const mean = this._prop.mean;
|
|
304
|
+
const sigma = this._prop.sigma;
|
|
305
|
+
const z = (x - mean) / sigma;
|
|
306
|
+
y = Math.exp(-0.5 * z * z);
|
|
307
|
+
}
|
|
308
|
+
if (this._prop.mode === 'sigmoid') {
|
|
309
|
+
(_c = (_g = this._prop).x0) !== null && _c !== void 0 ? _c : (_g.x0 = (minX + maxX) / 2);
|
|
310
|
+
(_d = (_h = this._prop).k) !== null && _d !== void 0 ? _d : (_h.k = 10);
|
|
311
|
+
const x0 = this._prop.x0;
|
|
312
|
+
const k = this._prop.k;
|
|
313
|
+
y = 1 / (1 + Math.exp(-k * (x - x0)));
|
|
314
|
+
}
|
|
315
|
+
line.push([x, y]);
|
|
316
|
+
}
|
|
317
|
+
return line;
|
|
318
|
+
}
|
|
319
|
+
drawAxes(minX, maxX, width, height) {
|
|
320
|
+
const axisColor = getComputedStyle(document.documentElement).getPropertyValue('--grey-2').trim() || '#DBDCDF';
|
|
321
|
+
this.layer.add(new _konva.Line({
|
|
322
|
+
points: [EDITOR_PADDING.left, height - EDITOR_PADDING.bottom, width - EDITOR_PADDING.right, height - EDITOR_PADDING.bottom],
|
|
323
|
+
stroke: axisColor,
|
|
324
|
+
strokeWidth: 1,
|
|
325
|
+
}), new _konva.Line({
|
|
326
|
+
points: [EDITOR_PADDING.left, EDITOR_PADDING.top, EDITOR_PADDING.left, height - EDITOR_PADDING.bottom],
|
|
327
|
+
stroke: axisColor,
|
|
328
|
+
strokeWidth: 1,
|
|
329
|
+
}), 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' }));
|
|
330
|
+
}
|
|
331
|
+
getMinX() {
|
|
332
|
+
var _a, _b;
|
|
333
|
+
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;
|
|
334
|
+
}
|
|
335
|
+
getMaxX() {
|
|
336
|
+
var _a, _b;
|
|
337
|
+
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;
|
|
338
|
+
}
|
|
339
|
+
getDefaultMean() {
|
|
340
|
+
return (this.getMinX() + this.getMaxX()) / 2;
|
|
341
|
+
}
|
|
342
|
+
getDefaultSigma() {
|
|
343
|
+
return Math.max(0.01, (this.getMaxX() - this.getMinX()) / 6);
|
|
344
|
+
}
|
|
345
|
+
getDefaultX0() {
|
|
346
|
+
return (this.getMinX() + this.getMaxX()) / 2;
|
|
347
|
+
}
|
|
348
|
+
getDefaultK() {
|
|
349
|
+
return 10;
|
|
350
|
+
}
|
|
351
|
+
redrawAll(notify = true) {
|
|
352
|
+
if (!this.stage || !this.layer || !this.redrawFn)
|
|
353
|
+
return;
|
|
354
|
+
const width = this.stage.width();
|
|
355
|
+
const height = this.stage.height();
|
|
356
|
+
const minX = this.getMinX();
|
|
357
|
+
const maxX = this.getMaxX();
|
|
358
|
+
this.layer.destroyChildren();
|
|
359
|
+
this.drawAxes(minX, maxX, width, height);
|
|
360
|
+
this.layer.add(this.konvaLine, this.pointsGroup);
|
|
361
|
+
this.redrawFn(notify);
|
|
362
|
+
if (this.barValues)
|
|
363
|
+
this.drawBars();
|
|
364
|
+
}
|
|
365
|
+
resize(width, height) {
|
|
366
|
+
if (width === this._width && height === this._height)
|
|
367
|
+
return;
|
|
368
|
+
this._width = width;
|
|
369
|
+
this._height = height;
|
|
370
|
+
if (this.stage) {
|
|
371
|
+
this.stage.width(width);
|
|
372
|
+
this.stage.height(height);
|
|
373
|
+
this.updateDragScales();
|
|
374
|
+
this.redrawAll(false);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
drawBars(values) {
|
|
378
|
+
var _a;
|
|
379
|
+
if (values)
|
|
380
|
+
this.barValues = values;
|
|
381
|
+
if (!this.barsLayer) {
|
|
382
|
+
this.pendingBarValues = values;
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
this.barsLayer.destroyChildren();
|
|
386
|
+
if (!this.barValues || this.barValues.length === 0)
|
|
387
|
+
return;
|
|
388
|
+
const stage = this.barsLayer.getStage();
|
|
389
|
+
if (!stage) {
|
|
390
|
+
this.pendingBarValues = values;
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
const width = stage.width();
|
|
394
|
+
const height = stage.height();
|
|
395
|
+
const minX = this.getMinX();
|
|
396
|
+
const maxX = this.getMaxX();
|
|
397
|
+
if (maxX === minX)
|
|
398
|
+
return;
|
|
399
|
+
const numBins = 20;
|
|
400
|
+
const plotWidth = width - EDITOR_PADDING.left - EDITOR_PADDING.right;
|
|
401
|
+
const plotHeight = height - EDITOR_PADDING.top - EDITOR_PADDING.bottom;
|
|
402
|
+
const binWidth = Math.max(1e-9, (maxX - minX) / numBins);
|
|
403
|
+
const bins = new Array(numBins).fill(0);
|
|
404
|
+
((_a = this.barValues) !== null && _a !== void 0 ? _a : []).forEach((v) => {
|
|
405
|
+
const idx = Math.min(Math.floor((v - minX) / binWidth), numBins - 1);
|
|
406
|
+
bins[idx]++;
|
|
407
|
+
});
|
|
408
|
+
const maxCount = Math.max(...bins) || 1;
|
|
409
|
+
bins.forEach((count, i) => {
|
|
410
|
+
const barX = EDITOR_PADDING.left + (i * binWidth / (maxX - minX)) * plotWidth;
|
|
411
|
+
const barW = (binWidth / (maxX - minX)) * plotWidth - 1;
|
|
412
|
+
const barH = (count / maxCount) * plotHeight;
|
|
413
|
+
const rect = new _konva.Rect({
|
|
414
|
+
x: barX,
|
|
415
|
+
y: EDITOR_PADDING.top + plotHeight - barH,
|
|
416
|
+
width: barW,
|
|
417
|
+
height: barH,
|
|
418
|
+
fill: COLORS.barFill,
|
|
419
|
+
opacity: 0.25,
|
|
420
|
+
stroke: COLORS.barStroke,
|
|
421
|
+
strokeWidth: 0.5,
|
|
422
|
+
});
|
|
423
|
+
this.barsLayer.add(rect);
|
|
424
|
+
});
|
|
425
|
+
this.barsLayer.batchDraw();
|
|
426
|
+
}
|
|
427
|
+
enableCurveDrag() {
|
|
428
|
+
if (!this.stage)
|
|
429
|
+
return;
|
|
430
|
+
let dragging = false;
|
|
431
|
+
let startPointer = null;
|
|
432
|
+
let startMean = 0;
|
|
433
|
+
let startSigma = 0;
|
|
434
|
+
let startX0 = 0;
|
|
435
|
+
let startK = 0;
|
|
436
|
+
this.stage.on('mousedown touchstart', (evt) => {
|
|
437
|
+
var _a, _b, _c, _d;
|
|
438
|
+
if (this._prop.mode === 'freeform')
|
|
439
|
+
return;
|
|
440
|
+
if (!evt.evt)
|
|
441
|
+
return;
|
|
442
|
+
const pos = this.stage.getPointerPosition();
|
|
443
|
+
if (!pos)
|
|
444
|
+
return;
|
|
445
|
+
if (!this.isInPlotArea(pos, this._width, this._height))
|
|
446
|
+
return;
|
|
447
|
+
dragging = true;
|
|
448
|
+
startPointer = pos;
|
|
449
|
+
startMean = (_a = this._prop.mean) !== null && _a !== void 0 ? _a : (this.getMinX() + this.getMaxX()) / 2;
|
|
450
|
+
startSigma = (_b = this._prop.sigma) !== null && _b !== void 0 ? _b : (this.getMaxX() - this.getMinX()) / 6;
|
|
451
|
+
startX0 = (_c = this._prop.x0) !== null && _c !== void 0 ? _c : (this.getMinX() + this.getMaxX()) / 2;
|
|
452
|
+
startK = (_d = this._prop.k) !== null && _d !== void 0 ? _d : 10;
|
|
453
|
+
this.stage.container().style.cursor = 'grabbing';
|
|
454
|
+
});
|
|
455
|
+
this.stage.on('mousemove touchmove', (evt) => {
|
|
456
|
+
var _a, _b;
|
|
457
|
+
if (!dragging || !startPointer)
|
|
458
|
+
return;
|
|
459
|
+
const pos = this.stage.getPointerPosition();
|
|
460
|
+
if (!pos)
|
|
461
|
+
return;
|
|
462
|
+
const dx = pos.x - startPointer.x;
|
|
463
|
+
const dy = pos.y - startPointer.y;
|
|
464
|
+
if (this._prop.mode === 'gaussian') {
|
|
465
|
+
this._prop.mean = startMean + dx * this.dragScaleX;
|
|
466
|
+
this._prop.sigma = Math.max(0.01, startSigma + (-dy) * this.dragScaleY * (this.getMaxX() - this.getMinX()));
|
|
467
|
+
}
|
|
468
|
+
if (this._prop.mode === 'sigmoid') {
|
|
469
|
+
this._prop.x0 = startX0 + dx * this.dragScaleX;
|
|
470
|
+
this._prop.k = Math.max(0.1, startK + (-dy) * this.dragScaleY * 50);
|
|
471
|
+
}
|
|
472
|
+
this._prop.line = this.computeLine();
|
|
473
|
+
(_a = this.redrawFn) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
474
|
+
(_b = this.onParamsChanged) === null || _b === void 0 ? void 0 : _b.call(this, this._prop);
|
|
475
|
+
});
|
|
476
|
+
this.stage.on('mouseup touchend', () => {
|
|
477
|
+
dragging = false;
|
|
478
|
+
startPointer = null;
|
|
479
|
+
this.stage.container().style.cursor = 'default';
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
addSpecialHandle(width, height) {
|
|
483
|
+
var _a, _b;
|
|
484
|
+
const clamp = (v, min, max) => Math.max(min, Math.min(max, v));
|
|
485
|
+
if (this._prop.mode === 'freeform')
|
|
486
|
+
return;
|
|
487
|
+
const minX = this.getMinX();
|
|
488
|
+
const maxX = this.getMaxX();
|
|
489
|
+
const mapper = new CoordMapper(minX, maxX, width, height);
|
|
490
|
+
let x = (minX + maxX) / 2;
|
|
491
|
+
let y = 0.5;
|
|
492
|
+
if (this._prop.mode === 'gaussian') {
|
|
493
|
+
x = (_a = this._prop.mean) !== null && _a !== void 0 ? _a : (minX + maxX) / 2;
|
|
494
|
+
y = 1;
|
|
495
|
+
}
|
|
496
|
+
else if (this._prop.mode === 'sigmoid') {
|
|
497
|
+
x = (_b = this._prop.x0) !== null && _b !== void 0 ? _b : (minX + maxX) / 2;
|
|
498
|
+
y = 0.5;
|
|
499
|
+
}
|
|
500
|
+
const coords = mapper.toCanvasCoords([x, y]);
|
|
501
|
+
if (!this.specialHandle) {
|
|
502
|
+
this.specialHandle = new _konva.Circle({
|
|
503
|
+
x: coords.x,
|
|
504
|
+
y: coords.y,
|
|
505
|
+
radius: 7,
|
|
506
|
+
fill: COLORS.handle,
|
|
507
|
+
draggable: true,
|
|
508
|
+
hitStrokeWidth: 15,
|
|
509
|
+
});
|
|
510
|
+
this.specialHandle.on('dragmove', (evt) => {
|
|
511
|
+
var _a, _b;
|
|
512
|
+
const pos = evt.target.position();
|
|
513
|
+
const data = mapper.toDataCoords(pos.x, pos.y);
|
|
514
|
+
if (this._prop.mode === 'gaussian') {
|
|
515
|
+
this._prop.mean = data.x;
|
|
516
|
+
this._prop.sigma = Math.max(0.01, Math.abs(data.y - 1));
|
|
517
|
+
}
|
|
518
|
+
else if (this._prop.mode === 'sigmoid') {
|
|
519
|
+
this._prop.x0 = data.x;
|
|
520
|
+
this._prop.k = clamp(Math.abs(data.y - 0.5) * 30, 0.1, 30);
|
|
521
|
+
}
|
|
522
|
+
this._prop.line = this.computeLine();
|
|
523
|
+
(_a = this.redrawFn) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
524
|
+
(_b = this.onParamsChanged) === null || _b === void 0 ? void 0 : _b.call(this, this._prop);
|
|
525
|
+
});
|
|
526
|
+
this.layer.add(this.specialHandle);
|
|
527
|
+
}
|
|
528
|
+
else {
|
|
529
|
+
if (!this.specialHandle.getLayer())
|
|
530
|
+
this.layer.add(this.specialHandle);
|
|
531
|
+
this.specialHandle.position(coords);
|
|
532
|
+
}
|
|
533
|
+
this.layer.batchDraw();
|
|
534
|
+
}
|
|
535
|
+
showPointEditor(dataIndex, clientX, clientY) {
|
|
536
|
+
const point = this._prop.line[dataIndex];
|
|
537
|
+
const xInput = ui.input.float('X', { value: point[0], min: this.getMinX(), max: this.getMaxX(), format: '#0.00', step: 0.01 });
|
|
538
|
+
const yInput = ui.input.float('Y', { value: point[1], min: 0, max: 1, format: '#0.00', step: 0.01 });
|
|
539
|
+
const close = () => {
|
|
540
|
+
content.removeEventListener('keydown', onKey);
|
|
541
|
+
popup.remove();
|
|
542
|
+
};
|
|
543
|
+
const apply = () => {
|
|
544
|
+
const x = xInput.value;
|
|
545
|
+
const y = yInput.value;
|
|
546
|
+
if (x == null || y == null || isNaN(x) || isNaN(y))
|
|
547
|
+
return;
|
|
548
|
+
this._prop.line[dataIndex] = [x, y];
|
|
549
|
+
this.redrawAll();
|
|
550
|
+
};
|
|
551
|
+
const onKey = (e) => {
|
|
552
|
+
if (e.key === 'Enter') {
|
|
553
|
+
apply();
|
|
554
|
+
close();
|
|
555
|
+
}
|
|
556
|
+
if (e.key === 'Escape')
|
|
557
|
+
close();
|
|
558
|
+
};
|
|
559
|
+
const content = ui.inputs([xInput, yInput]);
|
|
560
|
+
content.style.overflow = 'hidden';
|
|
561
|
+
content.addEventListener('keydown', onKey);
|
|
562
|
+
const rootRect = this.root.getBoundingClientRect();
|
|
563
|
+
const popup = ui.showPopup(content, this.root, { dx: clientX - rootRect.left, dy: clientY - rootRect.bottom, smart: false });
|
|
564
|
+
}
|
|
565
|
+
setRange(min, max) {
|
|
566
|
+
const oldMin = this.getMinX();
|
|
567
|
+
const oldMax = this.getMaxX();
|
|
568
|
+
const oldRange = oldMax - oldMin;
|
|
569
|
+
const newRange = max - min;
|
|
570
|
+
if (oldRange !== 0 && newRange !== 0) {
|
|
571
|
+
const scale = newRange / oldRange;
|
|
572
|
+
const remap = (x) => min + (x - oldMin) * scale;
|
|
573
|
+
if (this._prop.mean != null)
|
|
574
|
+
this._prop.mean = remap(this._prop.mean);
|
|
575
|
+
if (this._prop.sigma != null)
|
|
576
|
+
this._prop.sigma *= scale;
|
|
577
|
+
if (this._prop.x0 != null)
|
|
578
|
+
this._prop.x0 = remap(this._prop.x0);
|
|
579
|
+
if (this._prop.k != null)
|
|
580
|
+
this._prop.k /= scale;
|
|
581
|
+
for (const p of this._prop.line)
|
|
582
|
+
p[0] = remap(p[0]);
|
|
583
|
+
if (this._prop.freeformLine) {
|
|
584
|
+
for (const p of this._prop.freeformLine)
|
|
585
|
+
p[0] = remap(p[0]);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
this._prop.min = min;
|
|
589
|
+
this._prop.max = max;
|
|
590
|
+
this.updateDragScales();
|
|
591
|
+
this.redrawAll(false);
|
|
592
|
+
}
|
|
593
|
+
setColumn(col) {
|
|
594
|
+
if (!col)
|
|
595
|
+
return;
|
|
596
|
+
const values = col.toList();
|
|
597
|
+
this.drawBars(values);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXBvLWxpbmUtZWRpdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsibXBvLWxpbmUtZWRpdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDRCQUE0QjtBQUM1QixPQUFPLEtBQUssSUFBSSxNQUFNLG1CQUFtQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDdEMsT0FBTyxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUl0QyxPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBRTdCLElBQUksTUFBZ0MsQ0FBQztBQUVyQyxLQUFLLFVBQVUsUUFBUTtJQUNyQixJQUFJLENBQUMsTUFBTTtRQUNULE1BQU0sR0FBRyxDQUFDLE1BQU0sTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO0lBQzNDLE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFJRCxrQ0FBa0M7QUFDbEMsTUFBTSxjQUFjLEdBQUcsRUFBQyxHQUFHLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFDLENBQUM7QUFDbEUsTUFBTSxZQUFZLEdBQUcsQ0FBQyxDQUFDO0FBRXZCLE1BQU0sTUFBTSxHQUFHO0lBQ2IsSUFBSSxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDO0lBQzVDLE1BQU0sRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQztJQUM5QyxPQUFPLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUM7SUFDL0MsU0FBUyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxL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RUQsU0FBUyxDQUFDLEdBQXFCO1FBQzdCLElBQUksQ0FBQyxHQUFHO1lBQ04sT0FBTztRQUVULE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUM1QixJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3hCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIG1heC1sZW4gKi9cbmltcG9ydCAqIGFzIGdyb2sgZnJvbSAnZGF0YWdyb2stYXBpL2dyb2snO1xuaW1wb3J0ICogYXMgdWkgZnJvbSAnZGF0YWdyb2stYXBpL3VpJztcbmltcG9ydCAqIGFzIERHIGZyb20gJ2RhdGFncm9rLWFwaS9kZyc7XG5cbmltcG9ydCB0eXBlIEtvbnZhIGZyb20gJ2tvbnZhJztcbmltcG9ydCB7RGVzaXJhYmlsaXR5TGluZSwgTnVtZXJpY2FsRGVzaXJhYmlsaXR5fSBmcm9tICcuLi9tcG8nO1xuaW1wb3J0IHtTdWJqZWN0fSBmcm9tICdyeGpzJztcblxubGV0IF9rb252YTogdHlwZW9mIEtvbnZhIHwgdW5kZWZpbmVkO1xuXG5hc3luYyBmdW5jdGlvbiBnZXRLb252YSgpOiBQcm9taXNlPHR5cGVvZiBLb252YT4ge1xuICBpZiAoIV9rb252YSlcbiAgICBfa29udmEgPSAoYXdhaXQgaW1wb3J0KCdrb252YScpKS5kZWZhdWx0O1xuICByZXR1cm4gX2tvbnZhO1xufVxuXG50eXBlIFBvaW50ID0gW251bWJlciwgbnVtYmVyXTtcblxuLy8gQ29uc3RhbnRzIGZvciB0aGUgZWRpdG9yIGxheW91dFxuY29uc3QgRURJVE9SX1BBRERJTkcgPSB7dG9wOiAxMCwgcmlnaHQ6IDEwLCBib3R0b206IDIwLCBsZWZ0OiAzMH07XG5jb25zdCBQT0lOVF9SQURJVVMgPSAzO1xuXG5jb25zdCBDT0xPUlMgPSB7XG4gIGxpbmU6IERHLkNvbG9yLnRvSHRtbChERy5Db2xvci5maWx0ZXJlZFJvd3MpLFxuICBoYW5kbGU6IERHLkNvbG9yLnRvSHRtbChERy5Db2xvci5zZWxlY3RlZFJvd3MpLFxuICBiYXJGaWxsOiBERy5Db2xvci50b0h0bWwoREcuQ29sb3IuaGlzdG9ncmFtQmFyKSxcbiAgYmFyU3Ryb2tlOiBERy5Db2xvci50b0h0bWwoREcuQ29sb3IubGlnaHRHcmF5KSxcbn07XG5cbmNsYXNzIENvb3JkTWFwcGVyIHtcbiAgcHJpdmF0ZSBwbG90V2lkdGg6IG51bWJlcjtcbiAgcHJpdmF0ZSBwbG90SGVpZ2h0OiBudW1iZXI7XG4gIHByaXZhdGUgc2NhbGVYOiBudW1iZXI7XG4gIHByaXZhdGUgc2NhbGVZOiBudW1iZXI7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBtaW5YOiBudW1iZXIsXG4gICAgcHJpdmF0ZSBtYXhYOiBudW1iZXIsXG4gICAgcHJpdmF0ZSB3aWR0aDogbnVtYmVyLFxuICAgIHByaXZhdGUgaGVpZ2h0OiBudW1iZXIsXG4gICkge1xuICAgIHRoaXMucGxvdFdpZHRoID0gd2lkdGggLSBFRElUT1JfUEFERElORy5sZWZ0IC0gRURJVE9SX1BBRERJTkcucmlnaHQ7XG4gICAgdGhpcy5wbG90SGVpZ2h0ID0gaGVpZ2h0IC0gRURJVE9SX1BBRERJTkcudG9wIC0gRURJVE9SX1BBRERJTkcuYm90dG9tO1xuICAgIHRoaXMuc2NhbGVYID0gKHRoaXMubWF4WCAtIHRoaXMubWluWCA9PT0gMCkgPyAxIDogdGhpcy5wbG90V2lkdGggLyAodGhpcy5tYXhYIC0gdGhpcy5taW5YKTtcbiAgICB0aGlzLnNjYWxlWSA9IHRoaXMucGxvdEhlaWdodDtcbiAgfVxuXG4gIHRvQ2FudmFzQ29vcmRzKHA6IFBvaW50KToge3g6IG51bWJlciwgeTogbnVtYmVyfSB7XG4gICAgY29uc3QgY2FudmFzWCA9IEVESVRPUl9QQURESU5HLmxlZnQgKyAocFswXSAtIHRoaXMubWluWCkgKiB0aGlzLnNjYWxlWDtcbiAgICBjb25zdCBjYW52YXNZID0gRURJVE9SX1BBRERJTkcudG9wICsgdGhpcy5wbG90SGVpZ2h0IC0gKHBbMV0gKiB0aGlzLnNjYWxlWSk7XG5cbiAgICByZXR1cm4ge3g6IGNhbnZhc1gsIHk6IGNhbnZhc1l9O1xuICB9XG5cbiAgdG9EYXRhQ29vcmRzKGNhbnZhc1g6IG51bWJlciwgY2FudmFzWTogbnVtYmVyKToge3g6IG51bWJlciwgeTogbnVtYmVyfSB7XG4gICAgbGV0IGRhdGFYID0gdGhpcy5taW5YICsgKGNhbnZhc1ggLSBFRElUT1JfUEFERElORy5sZWZ0KSAvIHRoaXMuc2NhbGVYO1xuICAgIGxldCBkYXRhWSA9IChFRElUT1JfUEFERElORy50b3AgKyB0aGlzLnBsb3RIZWlnaHQgLSBjYW52YXNZKSAvIHRoaXMuc2NhbGVZO1xuXG4gICAgZGF0YVggPSBNYXRoLm1heCh0aGlzLm1pblgsIE1hdGgubWluKHRoaXMubWF4WCwgZGF0YVgpKTtcbiAgICBkYXRhWSA9IE1hdGgubWF4KDAsIE1hdGgubWluKDEsIGRhdGFZKSk7XG5cbiAgICByZXR1cm4ge3g6IGRhdGFYLCB5OiBkYXRhWX07XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIE1wb0Rlc2lyYWJpbGl0eUxpbmVFZGl0b3Ige1xuICByb290ID0gdWkuZGl2KFtdLCAnc3RhdGlzdGljcy1tcG8tbGluZS1lZGl0b3InKTtcbiAgb25DaGFuZ2VkID0gbmV3IFN1YmplY3Q8RGVzaXJhYmlsaXR5TGluZT4oKTtcbiAgc3VwcG9ydHNNb2RlRGlhbG9nOiBib29sZWFuID0gdHJ1ZTtcblxuICBwcml2YXRlIF9wcm9wOiBOdW1lcmljYWxEZXNpcmFiaWxpdHk7XG4gIHByaXZhdGUgYmFyc0xheWVyPzogS29udmEuTGF5ZXI7XG4gIHByaXZhdGUgcGVuZGluZ0JhclZhbHVlcz86IG51bWJlcltdO1xuXG4gIHByaXZhdGUgc3RhZ2U/OiBLb252YS5TdGFnZTtcbiAgcHJpdmF0ZSBsYXllcj86IEtvbnZhLkxheWVyO1xuXG4gIHByaXZhdGUga29udmFMaW5lPzogS29udmEuTGluZTtcbiAgcHJpdmF0ZSBwb2ludHNHcm91cD86IEtvbnZhLkdyb3VwO1xuICBwcml2YXRlIGJhclZhbHVlcz86IG51bWJlcltdO1xuXG4gIHByaXZhdGUgcmVkcmF3Rm4hOiAobm90aWZ5PzogYm9vbGVhbikgPT4gdm9pZDtcblxuICBwcml2YXRlIHNwZWNpYWxIYW5kbGU/OiBLb252YS5DaXJjbGU7XG4gIG9uUGFyYW1zQ2hhbmdlZD86IChwcm9wOiBOdW1lcmljYWxEZXNpcmFiaWxpdHkpID0+IHZvaWQ7XG5cbiAgLy8gRmxhZyB0byBwcmV2ZW50IHRvdWNocGFkIHJpZ2h0LWNsaWNrIGZyb20gYWRkaW5nIGEgbmV3IHBvaW50XG4gIHByaXZhdGUgaWdub3JlTmV4dENsaWNrID0gZmFsc2U7XG4gIHByaXZhdGUgZHJhZ1NjYWxlWCA9IDA7XG4gIHByaXZhdGUgZHJhZ1NjYWxlWSA9IDA7XG4gIHByaXZhdGUgX3dpZHRoOiBudW1iZXI7XG4gIHByaXZhdGUgX2hlaWdodDogbnVtYmVyO1xuXG4gIGNvbnN0cnVjdG9yKHByb3A6IE51bWVyaWNhbERlc2lyYWJpbGl0eSwgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICB0aGlzLl9wcm9wID0gcHJvcDtcbiAgICB0aGlzLl93aWR0aCA9IHdpZHRoO1xuICAgIHRoaXMuX2hlaWdodCA9IGhlaWdodDtcbiAgICB0aGlzLmVuc3VyZURlZmF1bHRMaW5lKCk7XG4gICAgdGhpcy5yb290LnN0eWxlLndpZHRoID0gYCR7d2lkdGh9cHhgO1xuICAgIHRoaXMucm9vdC5zdHlsZS5oZWlnaHQgPSBgJHtoZWlnaHR9cHhgO1xuICAgIHRoaXMucm9vdC5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XG5cbiAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4gdGhpcy5pbml0S29udmEod2lkdGgsIGhlaWdodCkpO1xuICB9XG5cbiAgcHJpdmF0ZSBlbnN1cmVEZWZhdWx0TGluZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fcHJvcC5saW5lLmxlbmd0aCA+IDApXG4gICAgICByZXR1cm47XG5cbiAgICBjb25zdCBtaW4gPSB0aGlzLl9wcm9wLm1pbiA/PyAwO1xuICAgIGNvbnN0IG1heCA9IHRoaXMuX3Byb3AubWF4ID8/IDE7XG4gICAgdGhpcy5fcHJvcC5saW5lID0gW1ttaW4sIDAuNV0sIFttYXgsIDAuNV1dO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVEcmFnU2NhbGVzKCk6IHZvaWQge1xuICAgIGNvbnN0IHBsb3RXaWR0aCA9IHRoaXMuX3dpZHRoIC0gRURJVE9SX1BBRERJTkcubGVmdCAtIEVESVRPUl9QQURESU5HLnJpZ2h0O1xuICAgIGNvbnN0IHBsb3RIZWlnaHQgPSB0aGlzLl9oZWlnaHQgLSBFRElUT1JfUEFERElORy50b3AgLSBFRElUT1JfUEFERElORy5ib3R0b207XG4gICAgdGhpcy5kcmFnU2NhbGVYID0gKHRoaXMuZ2V0TWF4WCgpIC0gdGhpcy5nZXRNaW5YKCkpIC8gcGxvdFdpZHRoO1xuICAgIHRoaXMuZHJhZ1NjYWxlWSA9IDEgLyBwbG90SGVpZ2h0O1xuICB9XG5cbiAgcHJpdmF0ZSBpc0luUGxvdEFyZWEocG9zOiB7eDogbnVtYmVyLCB5OiBudW1iZXJ9LCB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiAoXG4gICAgICBwb3MueCA+PSBFRElUT1JfUEFERElORy5sZWZ0ICYmXG4gICAgICBwb3MueCA8PSB3aWR0aCAtIEVESVRPUl9QQURESU5HLnJpZ2h0ICYmXG4gICAgICBwb3MueSA+PSBFRElUT1JfUEFERElORy50b3AgJiZcbiAgICAgIHBvcy55IDw9IGhlaWdodCAtIEVESVRPUl9QQURESU5HLmJvdHRvbVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGluaXRLb252YSh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIGlmICghdGhpcy5yb290LnBhcmVudEVsZW1lbnQpIHtcbiAgICAgIGNvbnNvbGUud2FybignS29udmEgY29udGFpbmVyIG5vdCBhdHRhY2hlZCB0byBET00geWV0LicpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IEtvbnZhID0gYXdhaXQgZ2V0S29udmEoKTtcbiAgICB0aGlzLmJhcnNMYXllciA9IG5ldyBLb252YS5MYXllcigpO1xuXG4gICAgdGhpcy5zdGFnZSA9IG5ldyBLb252YS5TdGFnZSh7XG4gICAgICBjb250YWluZXI6IHRoaXMucm9vdCxcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgIH0pO1xuXG4gICAgdGhpcy5zdGFnZS5hZGQodGhpcy5iYXJzTGF5ZXIpO1xuICAgIHRoaXMubGF5ZXIgPSBuZXcgS29udmEuTGF5ZXIoKTtcbiAgICB0aGlzLnN0YWdlLmFkZCh0aGlzLmxheWVyKTtcblxuICAgIGNvbnN0IG1pblggPSB0aGlzLmdldE1pblgoKTtcbiAgICBjb25zdCBtYXhYID0gdGhpcy5nZXRNYXhYKCk7XG5cbiAgICAvLyAtLS0gRHJhdyBBeGVzIC0tLVxuICAgIHRoaXMuZHJhd0F4ZXMobWluWCwgbWF4WCwgd2lkdGgsIGhlaWdodCk7XG5cbiAgICAvLyAtLS0gRHJhdyBMaW5lIGFuZCBQb2ludHMgLS0tXG4gICAgdGhpcy5rb252YUxpbmUgPSBuZXcgS29udmEuTGluZSh7XG4gICAgICBwb2ludHM6IFtdLFxuICAgICAgc3Ryb2tlOiBDT0xPUlMubGluZSxcbiAgICAgIHN0cm9rZVdpZHRoOiAyLFxuICAgICAgbGluZUNhcDogJ3JvdW5kJyxcbiAgICAgIGxpbmVKb2luOiAncm91bmQnLFxuICAgIH0pO1xuICAgIHRoaXMubGF5ZXIuYWRkKHRoaXMua29udmFMaW5lKTtcblxuICAgIHRoaXMucG9pbnRzR3JvdXAgPSBuZXcgS29udmEuR3JvdXAoKTtcbiAgICB0aGlzLmxheWVyLmFkZCh0aGlzLnBvaW50c0dyb3VwKTtcblxuICAgIC8vIC0tLSBSZWRyYXcgRnVuY3Rpb24gLS0tXG4gICAgdGhpcy5yZWRyYXdGbiA9IChub3RpZnk6IGJvb2xlYW4gPSB0cnVlKSA9PiB7XG4gICAgICBjb25zdCBtaW5YID0gdGhpcy5nZXRNaW5YKCk7XG4gICAgICBjb25zdCBtYXhYID0gdGhpcy5nZXRNYXhYKCk7XG5cbiAgICAgIGlmICh0aGlzLl9wcm9wLm1vZGUgPT09ICdmcmVlZm9ybScgJiYgdGhpcy5fcHJvcC5mcmVlZm9ybUxpbmUpXG4gICAgICAgIHRoaXMuX3Byb3AubGluZSA9IHRoaXMuX3Byb3AuZnJlZWZvcm1MaW5lO1xuXG4gICAgICBpZiAodGhpcy5fcHJvcC5tb2RlICE9PSAnZnJlZWZvcm0nKSB7XG4gICAgICAgIGlmICghdGhpcy5fcHJvcC5mcmVlZm9ybUxpbmUpXG4gICAgICAgICAgdGhpcy5fcHJvcC5mcmVlZm9ybUxpbmUgPSBbLi4udGhpcy5fcHJvcC5saW5lXTtcbiAgICAgICAgdGhpcy5fcHJvcC5saW5lID0gdGhpcy5jb21wdXRlTGluZSgpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnBvaW50c0dyb3VwIS5kZXN0cm95Q2hpbGRyZW4oKTtcbiAgICAgIGNvbnN0IGtvbnZhUG9pbnRzOiBudW1iZXJbXSA9IFtdO1xuXG4gICAgICBjb25zdCBtYXBwZXIgPSBuZXcgQ29vcmRNYXBwZXIobWluWCwgbWF4WCwgdGhpcy5fd2lkdGgsIHRoaXMuX2hlaWdodCk7XG4gICAgICBjb25zdCBzb3J0ZWRJbmRpY2VzID0gWy4uLnRoaXMuX3Byb3AubGluZS5rZXlzKCldXG4gICAgICAgIC5zb3J0KChhLCBiKSA9PiB0aGlzLl9wcm9wLmxpbmVbYV1bMF0gLSB0aGlzLl9wcm9wLmxpbmVbYl1bMF0pO1xuICAgICAgY29uc3Qgc29ydGVkTGluZSA9IHNvcnRlZEluZGljZXMubWFwKChpZHgpID0+IHRoaXMuX3Byb3AubGluZVtpZHhdKTtcblxuICAgICAgc29ydGVkTGluZS5mb3JFYWNoKChwLCBpbmRleCkgPT4ge1xuICAgICAgICBjb25zdCBjb29yZHMgPSBtYXBwZXIudG9DYW52YXNDb29yZHMoW3BbMF0sIHBbMV1dKTtcbiAgICAgICAga29udmFQb2ludHMucHVzaChjb29yZHMueCwgY29vcmRzLnkpO1xuXG4gICAgICAgIGlmICh0aGlzLl9wcm9wLm1vZGUgIT09ICdmcmVlZm9ybScpXG4gICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IHBvaW50Q2lyY2xlID0gbmV3IEtvbnZhLkNpcmNsZSh7XG4gICAgICAgICAgeDogY29vcmRzLngsXG4gICAgICAgICAgeTogY29vcmRzLnksXG4gICAgICAgICAgcmFkaXVzOiBQT0lOVF9SQURJVVMsXG4gICAgICAgICAgZmlsbDogJ3doaXRlJyxcbiAgICAgICAgICBzdHJva2U6IENPTE9SUy5saW5lLFxuICAgICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgICAgIGRyYWdnYWJsZTogdHJ1ZSxcbiAgICAgICAgICBoaXRTdHJva2VXaWR0aDogNSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU3RvcmUgaW5kZXggZGlyZWN0bHkgb24gdGhlIG5vZGUgZm9yIGVhc3kgYWNjZXNzXG4gICAgICAgIHBvaW50Q2lyY2xlLnNldEF0dHIoJ19kYXRhSW5kZXgnLCBzb3J0ZWRJbmRpY2VzW2luZGV4XSk7XG5cbiAgICAgICAgcG9pbnRDaXJjbGUub24oJ2RyYWdtb3ZlJywgKGV2dCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGNpcmNsZSA9IGV2dC50YXJnZXQgYXMgS29udmEuQ2lyY2xlO1xuICAgICAgICAgIGNvbnN0IHBvcyA9IGNpcmNsZS5wb3NpdGlvbigpO1xuICAgICAgICAgIGNvbnN0IGRhdGFJbmRleCA9IGNpcmNsZS5nZXRBdHRyKCdfZGF0YUluZGV4Jyk7XG4gICAgICAgICAgY29uc3Qgc29ydGVkUG9zID0gc29ydGVkSW5kaWNlcy5pbmRleE9mKGRhdGFJbmRleCk7XG5cbiAgICAgICAgICAvLyBDb25zdHJhaW4gZHJhZ2dpbmcgaG9yaXpvbnRhbGx5IGJldHdlZW4gbmVpZ2hib3JzIChvciBib3VuZHMpXG4gICAgICAgICAgY29uc3QgcHJldlggPSBzb3J0ZWRQb3MgPiAwID8gdGhpcy5fcHJvcC5saW5lW3NvcnRlZEluZGljZXNbc29ydGVkUG9zIC0gMV1dWzBdIDogbWluWDtcbiAgICAgICAgICBjb25zdCBuZXh0WCA9IHNvcnRlZFBvcyA8IHNvcnRlZEluZGljZXMubGVuZ3RoIC0gMSA/XG4gICAgICAgICAgICB0aGlzLl9wcm9wLmxpbmVbc29ydGVkSW5kaWNlc1tzb3J0ZWRQb3MgKyAxXV1bMF0gOlxuICAgICAgICAgICAgbWF4WDtcblxuICAgICAgICAgIC8vIEFkZCBhIHNtYWxsIGJ1ZmZlciB0byBhdm9pZCBwb2ludHMgb3ZlcmxhcHBpbmcgZXhhY3RseVxuICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IChtYXhYIC0gbWluWCA9PT0gMCkgPyAwIDogMC4wMDEgKiAobWF4WCAtIG1pblgpOyAvLyBBdm9pZCBOYU4gaWYgbWluWCA9PT0gbWF4WFxuICAgICAgICAgIGNvbnN0IG1pbkNhbnZhc1ggPSBtYXBwZXIudG9DYW52YXNDb29yZHMoW3ByZXZYICsgKHNvcnRlZFBvcyA+IDAgPyBidWZmZXIgOiAwKSwgMF0pLng7XG4gICAgICAgICAgY29uc3QgbWF4Q2FudmFzWCA9IG1hcHBlci50b0NhbnZhc0Nvb3JkcyhbbmV4dFggLSAoc29ydGVkUG9zIDwgc29ydGVkSW5kaWNlcy5sZW5ndGggLSAxID8gYnVmZmVyIDogMCksIDBdKS54O1xuXG4gICAgICAgICAgcG9zLnggPSBNYXRoLm1heChtaW5DYW52YXNYLCBNYXRoLm1pbihtYXhDYW52YXNYLCBwb3MueCkpO1xuXG4gICAgICAgICAgY29uc3QgcGxvdFRvcCA9IEVESVRPUl9QQURESU5HLnRvcDtcbiAgICAgICAgICBjb25zdCBwbG90Qm90dG9tID0gdGhpcy5faGVpZ2h0IC0gRURJVE9SX1BBRERJTkcuYm90dG9tO1xuICAgICAgICAgIHBvcy55ID0gTWF0aC5tYXgocGxvdFRvcCwgTWF0aC5taW4ocGxvdEJvdHRvbSwgcG9zLnkpKTtcblxuICAgICAgICAgIGNpcmNsZS5wb3NpdGlvbihwb3MpO1xuXG4gICAgICAgICAgY29uc3QgZGF0YUNvb3JkcyA9IG1hcHBlci50b0RhdGFDb29yZHMocG9zLngsIHBvcy55KTtcbiAgICAgICAgICB0aGlzLl9wcm9wLmxpbmVbZGF0YUluZGV4XVswXSA9IGRhdGFDb29yZHMueDtcbiAgICAgICAgICB0aGlzLl9wcm9wLmxpbmVbZGF0YUluZGV4XVsxXSA9IGRhdGFDb29yZHMueTtcblxuICAgICAgICAgIGNvbnN0IGN1cnJlbnRLb252YVBvaW50cyA9IHRoaXMuX3Byb3AubGluZS5tYXAoKHBEYXRhLCBpZHgpID0+IHtcbiAgICAgICAgICAgIC8vIFVzZSBkcmFnZ2VkIGNpcmNsZSBwb3NpdGlvbiBkaXJlY3RseSBmb3IgdGhlIHBvaW50IGJlaW5nIGRyYWdnZWRcbiAgICAgICAgICAgIGlmIChpZHggPT09IGRhdGFJbmRleClcbiAgICAgICAgICAgICAgcmV0dXJuIFtwb3MueCwgcG9zLnldO1xuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgIGNvbnN0IGMgPSBtYXBwZXIudG9DYW52YXNDb29yZHMoW3BEYXRhWzBdLCBwRGF0YVsxXV0pO1xuICAgICAgICAgICAgICByZXR1cm4gW2MueCwgYy55XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KS5mbGF0KCk7XG5cbiAgICAgICAgICB0aGlzLmtvbnZhTGluZSEucG9pbnRzKGN1cnJlbnRLb252YVBvaW50cyk7XG4gICAgICAgICAgdGhpcy5sYXllciEuYmF0Y2hEcmF3KCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHBvaW50Q2lyY2xlLm9uKCdkcmFnZW5kJywgKCkgPT4ge1xuICAgICAgICAgIHRoaXMuX3Byb3AubGluZS5zb3J0KChhLCBiKSA9PiBhWzBdIC0gYlswXSk7XG4gICAgICAgICAgdGhpcy5yZWRyYXdGbj8uKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHBvaW50Q2lyY2xlLm9uKCdjb250ZXh0bWVudScsIChldnQpID0+IHtcbiAgICAgICAgICBldnQuZXZ0LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgaWYgKHRoaXMuX3Byb3AubGluZS5sZW5ndGggPD0gMikge1xuICAgICAgICAgICAgZ3Jvay5zaGVsbC53YXJuaW5nKCdDYW5ub3QgcmVtb3ZlIHBvaW50cywgbWluaW11bSBvZiAyIHJlcXVpcmVkLicpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMuaWdub3JlTmV4dENsaWNrID0gdHJ1ZTtcbiAgICAgICAgICBjb25zdCBjaXJjbGUgPSBldnQudGFyZ2V0IGFzIEtvbnZhLkNpcmNsZTtcbiAgICAgICAgICBjb25zdCBkYXRhSW5kZXggPSBjaXJjbGUuZ2V0QXR0cignX2RhdGFJbmRleCcpIGFzIG51bWJlcjtcblxuICAgICAgICAgIGlmIChkYXRhSW5kZXggPj0gMCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX3Byb3AubWluID09IG51bGwpXG4gICAgICAgICAgICAgIHRoaXMuX3Byb3AubWluID0gdGhpcy5nZXRNaW5YKCk7XG4gICAgICAgICAgICBpZiAodGhpcy5fcHJvcC5tYXggPT0gbnVsbClcbiAgICAgICAgICAgICAgdGhpcy5fcHJvcC5tYXggPSB0aGlzLmdldE1heFgoKTtcbiAgICAgICAgICAgIHRoaXMuX3Byb3AubGluZS5zcGxpY2UoZGF0YUluZGV4LCAxKTtcbiAgICAgICAgICAgIHRoaXMucmVkcmF3Rm4/LigpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgcG9pbnRDaXJjbGUub24oJ21vdXNlZW50ZXInLCAoZXZ0KSA9PiB7XG4gICAgICAgICAgdGhpcy5zdGFnZSEuY29udGFpbmVyKCkuc3R5bGUuY3Vyc29yID0gJ3BvaW50ZXInO1xuICAgICAgICAgIGNvbnN0IGNpcmNsZSA9IGV2dC50YXJnZXQgYXMgS29udmEuQ2lyY2xlO1xuICAgICAgICAgIGNvbnN0IHBvcyA9IGNpcmNsZS5wb3NpdGlvbigpO1xuICAgICAgICAgIGNvbnN0IGRhdGFDb29yZHMgPSBtYXBwZXIudG9EYXRhQ29vcmRzKHBvcy54LCBwb3MueSk7XG4gICAgICAgICAgY29uc3QgdG9vbHRpcFRleHQgPSBgWDogJHtkYXRhQ29vcmRzLngudG9GaXhlZCgyKX0sIFk6ICR7ZGF0YUNvb3Jkcy55LnRvRml4ZWQoMil9PGJyPjxicj5EcmFnIHRvIG1vdmUsIGRvdWJsZS1jbGljayB0byBlZGl0LCByaWdodC1jbGljayB0byBkZWxldGVgO1xuICAgICAgICAgIHVpLnRvb2x0aXAuc2hvdyh0b29sdGlwVGV4dCwgZXZ0LmV2dC5jbGllbnRYLCBldnQuZXZ0LmNsaWVudFkpO1xuICAgICAgICB9KTtcblxuICAgICAgICBwb2ludENpcmNsZS5vbignbW91c2VsZWF2ZScsICgpID0+IHtcbiAgICAgICAgICB0aGlzLnN0YWdlIS5jb250YWluZXIoKS5zdHlsZS5jdXJzb3IgPSAnZGVmYXVsdCc7XG4gICAgICAgICAgdWkudG9vbHRpcC5oaWRlKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHBvaW50Q2lyY2xlLm9uKCdkYmxjbGljayBkYmx0YXAnLCAoZXZ0KSA9PiB7XG4gICAgICAgICAgdGhpcy5pZ25vcmVOZXh0Q2xpY2sgPSB0cnVlO1xuICAgICAgICAgIHVpLnRvb2x0aXAuaGlkZSgpO1xuICAgICAgICAgIGNvbnN0IGRhdGFJbmRleCA9IChldnQudGFyZ2V0IGFzIEtvbnZhLkNpcmNsZSkuZ2V0QXR0cignX2RhdGFJbmRleCcpIGFzIG51bWJlcjtcbiAgICAgICAgICB0aGlzLnNob3dQb2ludEVkaXRvcihkYXRhSW5kZXgsIGV2dC5ldnQuY2xpZW50WCwgZXZ0LmV2dC5jbGllbnRZKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5wb2ludHNHcm91cCEuYWRkKHBvaW50Q2lyY2xlKTtcbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLmtvbnZhTGluZSEucG9pbnRzKGtvbnZhUG9pbnRzKTtcbiAgICAgIHRoaXMubGF5ZXIhLmJhdGNoRHJhdygpO1xuXG4gICAgICAvLyAtLS0gQWRkIHNwZWNpYWwgaGFuZGxlIChHYXVzc2lhbiBwZWFrIC8gU2lnbW9pZCBpbmZsZWN0aW9uKSAtLS1cbiAgICAgIHRoaXMuYWRkU3BlY2lhbEhhbmRsZSh0aGlzLl93aWR0aCwgdGhpcy5faGVpZ2h0KTtcblxuICAgICAgaWYgKG5vdGlmeSlcbiAgICAgICAgdGhpcy5vbkNoYW5nZWQubmV4dCh0aGlzLl9wcm9wLmxpbmUpO1xuICAgIH07XG5cbiAgICAvLyAtLS0gTGVmdC1jbGljayB0byBBZGQgUG9pbnQgLS0tXG4gICAgdGhpcy5zdGFnZS5vbignY2xpY2sgdGFwJywgKGV2dCkgPT4ge1xuICAgICAgaWYgKHRoaXMuaWdub3JlTmV4dENsaWNrKSB7XG4gICAgICAgIHRoaXMuaWdub3JlTmV4dENsaWNrID0gZmFsc2U7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGV2dC50YXJnZXQgaW5zdGFuY2VvZiBLb252YS5DaXJjbGUgfHwgZXZ0LmV2dC5idXR0b24gIT09IDApXG4gICAgICAgIHJldHVybjtcblxuICAgICAgY29uc3QgcG9zID0gdGhpcy5zdGFnZT8uZ2V0UG9pbnRlclBvc2l0aW9uKCk7XG4gICAgICBpZiAoIXBvcylcbiAgICAgICAgcmV0dXJuO1xuXG4gICAgICBjb25zdCBtaW5YID0gdGhpcy5nZXRNaW5YKCk7XG4gICAgICBjb25zdCBtYXhYID0gdGhpcy5nZXRNYXhYKCk7XG5cbiAgICAgIGlmICghdGhpcy5pc0luUGxvdEFyZWEocG9zLCB0aGlzLnN0YWdlIS53aWR0aCgpLCB0aGlzLnN0YWdlIS5oZWlnaHQoKSkpXG4gICAgICAgIHJldHVybjtcblxuICAgICAgY29uc3QgbWFwcGVyID0gbmV3IENvb3JkTWFwcGVyKG1pblgsIG1heFgsIHRoaXMuc3RhZ2UhLndpZHRoKCksIHRoaXMuc3RhZ2UhLmhlaWdodCgpKTtcbiAgICAgIGNvbnN0IGRhdGFDb29yZHMgPSBtYXBwZXIudG9EYXRhQ29vcmRzKHBvcy54LCBwb3MueSk7XG5cbiAgICAgIHRoaXMuX3Byb3AubGluZS5wdXNoKFtkYXRhQ29vcmRzLngsIGRhdGFDb29yZHMueV0pO1xuICAgICAgdGhpcy5fcHJvcC5saW5lLnNvcnQoKGEsIGIpID0+IGFbMF0gLSBiWzBdKTtcbiAgICAgIHRoaXMucmVkcmF3Rm4/LigpO1xuICAgIH0pO1xuXG4gICAgLy8gQ3Vyc29yIGNoYW5nZVxuICAgIHRoaXMuc3RhZ2Uub24oJ21vdXNlbW92ZScsIChldnQpID0+IHtcbiAgICAgIGlmICghdGhpcy5zdGFnZSlcbiAgICAgICAgcmV0dXJuO1xuICAgICAgY29uc3QgcG9zID0gdGhpcy5zdGFnZS5nZXRQb2ludGVyUG9zaXRpb24oKTtcbiAgICAgIGlmICghcG9zKVxuICAgICAgICByZXR1cm47XG5cbiAgICAgIGlmICh0aGlzLl9wcm9wLm1vZGUgIT09ICdmcmVlZm9ybScpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNJblBsb3RBcmVhKHBvcywgdGhpcy5fd2lkdGgsIHRoaXMuX2hlaWdodCkpXG4gICAgICAgICAgdGhpcy5zdGFnZS5jb250YWluZXIoKS5zdHlsZS5jdXJzb3IgPSAnZ3JhYic7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICB0aGlzLnN0YWdlLmNvbnRhaW5lcigpLnN0eWxlLmN1cnNvciA9ICdkZWZhdWx0JztcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMuc3RhZ2Uub24oJ21vdXNlb3V0JywgKCkgPT4gdWkudG9vbHRpcC5oaWRlKCkpO1xuXG4gICAgLy8gRW5hYmxlIGN1cnZlIGRyYWcgKHNtb290aClcbiAgICB0aGlzLmVuYWJsZUN1cnZlRHJhZygpO1xuICAgIHRoaXMudXBkYXRlRHJhZ1NjYWxlcygpO1xuXG4gICAgdWkub25TaXplQ2hhbmdlZCh0aGlzLnJvb3QpLnN1YnNjcmliZSgoXykgPT4ge1xuICAgICAgY29uc3Qge2NsaWVudFdpZHRoOiB3LCBjbGllbnRIZWlnaHQ6IGh9ID0gdGhpcy5yb290O1xuICAgICAgaWYgKHcgPiAwICYmIGggPiAwKVxuICAgICAgICB0aGlzLnJlc2l6ZSh3LCBoKTtcbiAgICB9KTtcblxuICAgIC8vIEluaXRpYWwgZHJhd1xuICAgIGlmICh0aGlzLnBlbmRpbmdCYXJWYWx1ZXMpIHtcbiAgICAgIHRoaXMuZHJhd0JhcnModGhpcy5wZW5kaW5nQmFyVmFsdWVzKTtcbiAgICAgIHRoaXMucGVuZGluZ0JhclZhbHVlcyA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgdGhpcy5yZWRyYXdGbj8uKGZhbHNlKTtcbiAgfVxuXG4gIGdldCBsaW5lKCk6IERlc2lyYWJpbGl0eUxpbmUge1xuICAgIHJldHVybiB0aGlzLl9wcm9wLmxpbmU7XG4gIH1cblxuICBwcml2YXRlIGNvbXB1dGVMaW5lKCk6IERlc2lyYWJpbGl0eUxpbmUge1xuICAgIGlmICh0aGlzLl9wcm9wLm1vZGUgPT09ICdmcmVlZm9ybScpXG4gICAgICByZXR1cm4gdGhpcy5fcHJvcC5saW5lO1xuXG4gICAgY29uc3QgbWluWCA9IHRoaXMuZ2V0TWluWCgpO1xuICAgIGNvbnN0IG1heFggPSB0aGlzLmdldE1heFgoKTtcbiAgICBjb25zdCBuID0gNjA7XG4gICAgY29uc3QgbGluZTogRGVzaXJhYmlsaXR5TGluZSA9IFtdO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPD0gbjsgaSsrKSB7XG4gICAgICBjb25zdCB4ID0gbWluWCArIChtYXhYIC0gbWluWCkgKiAoaSAvIG4pO1xuICAgICAgbGV0IHkgPSAwO1xuXG4gICAgICBpZiAodGhpcy5fcHJvcC5tb2RlID09PSAnZ2F1c3NpYW4nKSB7XG4gICAgICAgIHRoaXMuX3Byb3AubWVhbiA/Pz0gKG1pblggKyBtYXhYKSAvIDI7XG4gICAgICAgIHRoaXMuX3Byb3Auc2lnbWEgPz89IChtYXhYIC0gbWluWCkgLyA2O1xuICAgICAgICBjb25zdCBtZWFuID0gdGhpcy5fcHJvcC5tZWFuO1xuICAgICAgICBjb25zdCBzaWdtYSA9IHRoaXMuX3Byb3Auc2lnbWE7XG4gICAgICAgIGNvbnN0IHogPSAoeCAtIG1lYW4pIC8gc2lnbWE7XG4gICAgICAgIHkgPSBNYXRoLmV4cCgtMC41ICogeiAqIHopO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5fcHJvcC5tb2RlID09PSAnc2lnbW9pZCcpIHtcbiAgICAgICAgdGhpcy5fcHJvcC54MCA/Pz0gKG1pblggKyBtYXhYKSAvIDI7XG4gICAgICAgIHRoaXMuX3Byb3AuayA/Pz0gMTA7XG4gICAgICAgIGNvbnN0IHgwID0gdGhpcy5fcHJvcC54MDtcbiAgICAgICAgY29uc3QgayA9IHRoaXMuX3Byb3AuaztcbiAgICAgICAgeSA9IDEgLyAoMSArIE1hdGguZXhwKC1rICogKHggLSB4MCkpKTtcbiAgICAgIH1cblxuICAgICAgbGluZS5wdXNoKFt4LCB5XSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGxpbmU7XG4gIH1cblxuICBwcml2YXRlIGRyYXdBeGVzKG1pblg6IG51bWJlciwgbWF4WDogbnVtYmVyLCB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIGNvbnN0IGF4aXNDb2xvciA9IGdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KS5nZXRQcm9wZXJ0eVZhbHVlKCctLWdyZXktMicpLnRyaW0oKSB8fCAnI0RCRENERic7XG4gICAgdGhpcy5sYXllciEuYWRkKFxuICAgICAgbmV3IF9rb252YSEuTGluZSh7XG4gICAgICAgIHBvaW50czogW0VESVRPUl9QQURESU5HLmxlZnQsIGhlaWdodCAtIEVESVRPUl9QQURESU5HLmJvdHRvbSwgd2lkdGggLSBFRElUT1JfUEFERElORy5yaWdodCwgaGVpZ2h0IC0gRURJVE9SX1BBRERJTkcuYm90dG9tXSxcbiAgICAgICAgc3Ryb2tlOiBheGlzQ29sb3IsXG4gICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgfSksXG4gICAgICBuZXcgX2tvbnZhIS5MaW5lKHtcbiAgICAgICAgcG9pbnRzOiBbRURJVE9SX1BBRERJTkcubGVmdCwgRURJVE9SX1BBRERJTkcudG9wLCBFRElUT1JfUEFERElORy5sZWZ0LCBoZWlnaHQgLSBFRElUT1JfUEFERElORy5ib3R0b21dLFxuICAgICAgICBzdHJva2U6IGF4aXNDb2xvcixcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICB9KSxcbiAgICAgIG5ldyBfa29udmEhLlRleHQoe3g6IEVESVRPUl9QQURESU5HLmxlZnQsIHk6IGhlaWdodCAtIEVESVRPUl9QQURESU5HLmJvdHRvbSArIDMsIHRleHQ6IG1pblgudG9GaXhlZCgxKSwgZm9udFNpemU6IDksIGZpbGw6ICdncmV5J30pLFxuICAgICAgbmV3IF9rb252YSEuVGV4dCh7eDogd2lkdGggLSBFRElUT1JfUEFERElORy5yaWdodCAtIDE1LCB5OiBoZWlnaHQgLSBFRElUT1JfUEFERElORy5ib3R0b20gKyAzLCB0ZXh0OiBtYXhYLnRvRml4ZWQoMSksIGZvbnRTaXplOiA5LCBmaWxsOiAnZ3JleSd9KSxcbiAgICApO1xuICB9XG5cbiAgZ2V0TWluWCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLl9wcm9wLm1pbiA/PyBNYXRoLm1pbiguLi50aGlzLl9wcm9wLmxpbmUubWFwKChwKSA9PiBwWzBdKSkgPz8gMDtcbiAgfVxuXG4gIGdldE1heFgoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fcHJvcC5tYXggPz8gTWF0aC5tYXgoLi4udGhpcy5fcHJvcC5saW5lLm1hcCgocCkgPT4gcFswXSkpID8/IDE7XG4gIH1cblxuICBnZXREZWZhdWx0TWVhbigpOiBudW1iZXIge1xuICAgIHJldHVybiAodGhpcy5nZXRNaW5YKCkgKyB0aGlzLmdldE1heFgoKSkgLyAyO1xuICB9XG5cbiAgZ2V0RGVmYXVsdFNpZ21hKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIE1hdGgubWF4KDAuMDEsICh0aGlzLmdldE1heFgoKSAtIHRoaXMuZ2V0TWluWCgpKSAvIDYpO1xuICB9XG5cbiAgZ2V0RGVmYXVsdFgwKCk6IG51bWJlciB7XG4gICAgcmV0dXJuICh0aGlzLmdldE1pblgoKSArIHRoaXMuZ2V0TWF4WCgpKSAvIDI7XG4gIH1cblxuICBnZXREZWZhdWx0SygpOiBudW1iZXIge1xuICAgIHJldHVybiAxMDtcbiAgfVxuXG4gIHJlZHJhd0FsbChub3RpZnk6IGJvb2xlYW4gPSB0cnVlKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnN0YWdlIHx8ICF0aGlzLmxheWVyIHx8ICF0aGlzLnJlZHJhd0ZuKVxuICAgICAgcmV0dXJuO1xuXG4gICAgY29uc3Qgd2lkdGggPSB0aGlzLnN0YWdlLndpZHRoKCk7XG4gICAgY29uc3QgaGVpZ2h0ID0gdGhpcy5zdGFnZS5oZWlnaHQoKTtcbiAgICBjb25zdCBtaW5YID0gdGhpcy5nZXRNaW5YKCk7XG4gICAgY29uc3QgbWF4WCA9IHRoaXMuZ2V0TWF4WCgpO1xuXG4gICAgdGhpcy5sYXllci5kZXN0cm95Q2hpbGRyZW4oKTtcblxuICAgIHRoaXMuZHJhd0F4ZXMobWluWCwgbWF4WCwgd2lkdGgsIGhlaWdodCk7XG5cbiAgICB0aGlzLmxheWVyLmFkZCh0aGlzLmtvbnZhTGluZSEsIHRoaXMucG9pbnRzR3JvdXAhKTtcblxuICAgIHRoaXMucmVkcmF3Rm4obm90aWZ5KTtcblxuICAgIGlmICh0aGlzLmJhclZhbHVlcylcbiAgICAgIHRoaXMuZHJhd0JhcnMoKTtcbiAgfVxuXG4gIHJlc2l6ZSh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcik6IHZvaWQge1xuICAgIGlmICh3aWR0aCA9PT0gdGhpcy5fd2lkdGggJiYgaGVpZ2h0ID09PSB0aGlzLl9oZWlnaHQpXG4gICAgICByZXR1cm47XG5cbiAgICB0aGlzLl93aWR0aCA9IHdpZHRoO1xuICAgIHRoaXMuX2hlaWdodCA9IGhlaWdodDtcblxuICAgIGlmICh0aGlzLnN0YWdlKSB7XG4gICAgICB0aGlzLnN0YWdlLndpZHRoKHdpZHRoKTtcbiAgICAgIHRoaXMuc3RhZ2UuaGVpZ2h0KGhlaWdodCk7XG4gICAgICB0aGlzLnVwZGF0ZURyYWdTY2FsZXMoKTtcbiAgICAgIHRoaXMucmVkcmF3QWxsKGZhbHNlKTtcbiAgICB9XG4gIH1cblxuICBkcmF3QmFycyh2YWx1ZXM/OiBudW1iZXJbXSkge1xuICAgIGlmICh2YWx1ZXMpXG4gICAgICB0aGlzLmJhclZhbHVlcyA9IHZhbHVlcztcblxuICAgIGlmICghdGhpcy5iYXJzTGF5ZXIpIHtcbiAgICAgIHRoaXMucGVuZGluZ0JhclZhbHVlcyA9IHZhbHVlcztcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5iYXJzTGF5ZXIuZGVzdHJveUNoaWxkcmVuKCk7XG5cbiAgICBpZiAoIXRoaXMuYmFyVmFsdWVzIHx8IHRoaXMuYmFyVmFsdWVzLmxlbmd0aCA9PT0gMClcbiAgICAgIHJldHVybjtcblxuICAgIGNvbnN0IHN0YWdlID0gdGhpcy5iYXJzTGF5ZXIuZ2V0U3RhZ2UoKTtcbiAgICBpZiAoIXN0YWdlKSB7XG4gICAgICB0aGlzLnBlbmRpbmdCYXJWYWx1ZXMgPSB2YWx1ZXM7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgd2lkdGggPSBzdGFnZS53aWR0aCgpO1xuICAgIGNvbnN0IGhlaWdodCA9IHN0YWdlLmhlaWdodCgpO1xuXG4gICAgY29uc3QgbWluWCA9IHRoaXMuZ2V0TWluWCgpO1xuICAgIGNvbnN0IG1heFggPSB0aGlzLmdldE1heFgoKTtcblxuICAgIGlmIChtYXhYID09PSBtaW5YKVxuICAgICAgcmV0dXJuO1xuXG4gICAgY29uc3QgbnVtQmlucyA9IDIwO1xuICAgIGNvbnN0IHBsb3RXaWR0aCA9IHdpZHRoIC0gRURJVE9SX1BBRERJTkcubGVmdCAtIEVESVRPUl9QQURESU5HLnJpZ2h0O1xuICAgIGNvbnN0IHBsb3RIZWlnaHQgPSBoZWlnaHQgLSBFRElUT1JfUEFERElORy50b3AgLSBFRElUT1JfUEFERElORy5ib3R0b207XG5cbiAgICBjb25zdCBiaW5XaWR0aCA9IE1hdGgubWF4KDFlLTksIChtYXhYIC0gbWluWCkgLyBudW1CaW5zKTtcbiAgICBjb25zdCBiaW5zID0gbmV3IEFycmF5KG51bUJpbnMpLmZpbGwoMCk7XG5cbiAgICAodGhpcy5iYXJWYWx1ZXMgPz8gW10pLmZvckVhY2goKHYpID0+IHtcbiAgICAgIGNvbnN0IGlkeCA9IE1hdGgubWluKE1hdGguZmxvb3IoKHYgLSBtaW5YKSAvIGJpbldpZHRoKSwgbnVtQmlucyAtIDEpO1xuICAgICAgYmluc1tpZHhdKys7XG4gICAgfSk7XG5cbiAgICBjb25zdCBtYXhDb3VudCA9IE1hdGgubWF4KC4uLmJpbnMpIHx8IDE7XG5cbiAgICBiaW5zLmZvckVhY2goKGNvdW50LCBpKSA9PiB7XG4gICAgICBjb25zdCBiYXJYID0gRURJVE9SX1BBRERJTkcubGVmdCArIChpICogYmluV2lkdGggLyAobWF4WCAtIG1pblgpKSAqIHBsb3RXaWR0aDtcbiAgICAgIGNvbnN0IGJhclcgPSAoYmluV2lkdGggLyAobWF4WCAtIG1pblgpKSAqIHBsb3RXaWR0aCAtIDE7XG4gICAgICBjb25zdCBiYXJIID0gKGNvdW50IC8gbWF4Q291bnQpICogcGxvdEhlaWdodDtcblxuICAgICAgY29uc3QgcmVjdCA9IG5ldyBfa29udmEhLlJlY3Qoe1xuICAgICAgICB4OiBiYXJYLFxuICAgICAgICB5OiBFRElUT1JfUEFERElORy50b3AgKyBwbG90SGVpZ2h0IC0gYmFySCxcbiAgICAgICAgd2lkdGg6IGJhclcsXG4gICAgICAgIGhlaWdodDogYmFySCxcbiAgICAgICAgZmlsbDogQ09MT1JTLmJhckZpbGwsXG4gICAgICAgIG9wYWNpdHk6IDAuMjUsXG4gICAgICAgIHN0cm9rZTogQ09MT1JTLmJhclN0cm9rZSxcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDAuNSxcbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLmJhcnNMYXllciEuYWRkKHJlY3QpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5iYXJzTGF5ZXIhLmJhdGNoRHJhdygpO1xuICB9XG5cbiAgcHJpdmF0ZSBlbmFibGVDdXJ2ZURyYWcoKSB7XG4gICAgaWYgKCF0aGlzLnN0YWdlKVxuICAgICAgcmV0dXJuO1xuXG4gICAgbGV0IGRyYWdnaW5nID0gZmFsc2U7XG4gICAgbGV0IHN0YXJ0UG9pbnRlcjoge3g6IG51bWJlciwgeTogbnVtYmVyfSB8IG51bGwgPSBudWxsO1xuICAgIGxldCBzdGFydE1lYW4gPSAwO1xuICAgIGxldCBzdGFydFNpZ21hID0gMDtcbiAgICBsZXQgc3RhcnRYMCA9IDA7XG4gICAgbGV0IHN0YXJ0SyA9IDA7XG5cbiAgICB0aGlzLnN0YWdlLm9uKCdtb3VzZWRvd24gdG91Y2hzdGFydCcsIChldnQpID0+IHtcbiAgICAgIGlmICh0aGlzLl9wcm9wLm1vZGUgPT09ICdmcmVlZm9ybScpXG4gICAgICAgIHJldHVybjtcbiAgICAgIGlmICghZXZ0LmV2dClcbiAgICAgICAgcmV0dXJuO1xuXG4gICAgICBjb25zdCBwb3MgPSB0aGlzLnN0YWdlIS5nZXRQb2ludGVyUG9zaXRpb24oKTtcbiAgICAgIGlmICghcG9zKVxuICAgICAgICByZXR1cm47XG5cbiAgICAgIGlmICghdGhpcy5pc0luUGxvdEFyZWEocG9zLCB0aGlzLl93aWR0aCwgdGhpcy5faGVpZ2h0KSlcbiAgICAgICAgcmV0dXJuO1xuXG4gICAgICBkcmFnZ2luZyA9IHRydWU7XG4gICAgICBzdGFydFBvaW50ZXIgPSBwb3M7XG5cbiAgICAgIHN0YXJ0TWVhbiA9IHRoaXMuX3Byb3AubWVhbiA/PyAodGhpcy5nZXRNaW5YKCkgKyB0aGlzLmdldE1heFgoKSkgLyAyO1xuICAgICAgc3RhcnRTaWdtYSA9IHRoaXMuX3Byb3Auc2lnbWEgPz8gKHRoaXMuZ2V0TWF4WCgpIC0gdGhpcy5nZXRNaW5YKCkpIC8gNjtcbiAgICAgIHN0YXJ0WDAgPSB0aGlzLl9wcm9wLngwID8/ICh0aGlzLmdldE1pblgoKSArIHRoaXMuZ2V0TWF4WCgpKSAvIDI7XG4gICAgICBzdGFydEsgPSB0aGlzLl9wcm9wLmsgPz8gMTA7XG5cbiAgICAgIHRoaXMuc3RhZ2UhLmNvbnRhaW5lcigpLnN0eWxlLmN1cnNvciA9ICdncmFiYmluZyc7XG4gICAgfSk7XG5cbiAgICB0aGlzLnN0YWdlLm9uKCdtb3VzZW1vdmUgdG91Y2htb3ZlJywgKGV2dCkgPT4ge1xuICAgICAgaWYgKCFkcmFnZ2luZyB8fCAhc3RhcnRQb2ludGVyKVxuICAgICAgICByZXR1cm47XG5cbiAgICAgIGNvbnN0IHBvcyA9IHRoaXMuc3RhZ2UhLmdldFBvaW50ZXJQb3NpdGlvbigpO1xuICAgICAgaWYgKCFwb3MpXG4gICAgICAgIHJldHVybjtcblxuICAgICAgY29uc3QgZHggPSBwb3MueCAtIHN0YXJ0UG9pbnRlci54O1xuICAgICAgY29uc3QgZHkgPSBwb3MueSAtIHN0YXJ0UG9pbnRlci55O1xuXG4gICAgICBpZiAodGhpcy5fcHJvcC5tb2RlID09PSAnZ2F1c3NpYW4nKSB7XG4gICAgICAgIHRoaXMuX3Byb3AubWVhbiA9IHN0YXJ0TWVhbiArIGR4ICogdGhpcy5kcmFnU2NhbGVYO1xuICAgICAgICB0aGlzLl9wcm9wLnNpZ21hID0gTWF0aC5tYXgoMC4wMSwgc3RhcnRTaWdtYSArICgtZHkpICogdGhpcy5kcmFnU2NhbGVZICogKHRoaXMuZ2V0TWF4WCgpIC0gdGhpcy5nZXRNaW5YKCkpKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuX3Byb3AubW9kZSA9PT0gJ3NpZ21vaWQnKSB7XG4gICAgICAgIHRoaXMuX3Byb3AueDAgPSBzdGFydFgwICsgZHggKiB0aGlzLmRyYWdTY2FsZVg7XG4gICAgICAgIHRoaXMuX3Byb3AuayA9IE1hdGgubWF4KDAuMSwgc3RhcnRLICsgKC1keSkgKiB0aGlzLmRyYWdTY2FsZVkgKiA1MCk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX3Byb3AubGluZSA9IHRoaXMuY29tcHV0ZUxpbmUoKTtcbiAgICAgIHRoaXMucmVkcmF3Rm4/LigpO1xuICAgICAgdGhpcy5vblBhcmFtc0NoYW5nZWQ/Lih0aGlzLl9wcm9wKTtcbiAgICB9KTtcblxuICAgIHRoaXMuc3RhZ2Uub24oJ21vdXNldXAgdG91Y2hlbmQnLCAoKSA9PiB7XG4gICAgICBkcmFnZ2luZyA9IGZhbHNlO1xuICAgICAgc3RhcnRQb2ludGVyID0gbnVsbDtcbiAgICAgIHRoaXMuc3RhZ2UhLmNvbnRhaW5lcigpLnN0eWxlLmN1cnNvciA9ICdkZWZhdWx0JztcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkU3BlY2lhbEhhbmRsZSh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIGNvbnN0IGNsYW1wID0gKHY6IG51bWJlciwgbWluOiBudW1iZXIsIG1heDogbnVtYmVyKSA9PiBNYXRoLm1heChtaW4sIE1hdGgubWluKG1heCwgdikpO1xuXG4gICAgaWYgKHRoaXMuX3Byb3AubW9kZSA9PT0gJ2ZyZWVmb3JtJylcbiAgICAgIHJldHVybjtcblxuICAgIGNvbnN0IG1pblggPSB0aGlzLmdldE1pblgoKTtcbiAgICBjb25zdCBtYXhYID0gdGhpcy5nZXRNYXhYKCk7XG4gICAgY29uc3QgbWFwcGVyID0gbmV3IENvb3JkTWFwcGVyKG1pblgsIG1heFgsIHdpZHRoLCBoZWlnaHQpO1xuXG4gICAgbGV0IHggPSAobWluWCArIG1heFgpIC8gMjtcbiAgICBsZXQgeSA9IDAuNTtcblxuICAgIGlmICh0aGlzLl9wcm9wLm1vZGUgPT09ICdnYXVzc2lhbicpIHtcbiAgICAgIHggPSB0aGlzLl9wcm9wLm1lYW4gPz8gKG1pblggKyBtYXhYKSAvIDI7XG4gICAgICB5ID0gMTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuX3Byb3AubW9kZSA9PT0gJ3NpZ21vaWQnKSB7XG4gICAgICB4ID0gdGhpcy5fcHJvcC54MCA/PyAobWluWCArIG1heFgpIC8gMjtcbiAgICAgIHkgPSAwLjU7XG4gICAgfVxuXG4gICAgY29uc3QgY29vcmRzID0gbWFwcGVyLnRvQ2FudmFzQ29vcmRzKFt4LCB5XSk7XG5cbiAgICBpZiAoIXRoaXMuc3BlY2lhbEhhbmRsZSkge1xuICAgICAgdGhpcy5zcGVjaWFsSGFuZGxlID0gbmV3IF9rb252YSEuQ2lyY2xlKHtcbiAgICAgICAgeDogY29vcmRzLngsXG4gICAgICAgIHk6IGNvb3Jkcy55LFxuICAgICAgICByYWRpdXM6IDcsXG4gICAgICAgIGZpbGw6IENPTE9SUy5oYW5kbGUsXG4gICAgICAgIGRyYWdnYWJsZTogdHJ1ZSxcbiAgICAgICAgaGl0U3Ryb2tlV2lkdGg6IDE1LFxuICAgICAgfSk7XG5cbiAgICAgIHRoaXMuc3BlY2lhbEhhbmRsZS5vbignZHJhZ21vdmUnLCAoZXZ0KSA9PiB7XG4gICAgICAgIGNvbnN0IHBvcyA9IGV2dC50YXJnZXQucG9zaXRpb24oKTtcbiAgICAgICAgY29uc3QgZGF0YSA9IG1hcHBlci50b0RhdGFDb29yZHMocG9zLngsIHBvcy55KTtcblxuICAgICAgICBpZiAodGhpcy5fcHJvcC5tb2RlID09PSAnZ2F1c3NpYW4nKSB7XG4gICAgICAgICAgdGhpcy5fcHJvcC5tZWFuID0gZGF0YS54O1xuICAgICAgICAgIHRoaXMuX3Byb3Auc2lnbWEgPSBNYXRoLm1heCgwLjAxLCBNYXRoLmFicyhkYXRhLnkgLSAxKSk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5fcHJvcC5tb2RlID09PSAnc2lnbW9pZCcpIHtcbiAgICAgICAgICB0aGlzLl9wcm9wLngwID0gZGF0YS54O1xuICAgICAgICAgIHRoaXMuX3Byb3AuayA9IGNsYW1wKE1hdGguYWJzKGRhdGEueSAtIDAuNSkgKiAzMCwgMC4xLCAzMCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9wcm9wLmxpbmUgPSB0aGlzLmNvbXB1dGVMaW5lKCk7XG4gICAgICAgIHRoaXMucmVkcmF3Rm4/LigpO1xuICAgICAgICB0aGlzLm9uUGFyYW1zQ2hhbmdlZD8uKHRoaXMuX3Byb3ApO1xuICAgICAgfSk7XG5cbiAgICAgIHRoaXMubGF5ZXIhLmFkZCh0aGlzLnNwZWNpYWxIYW5kbGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoIXRoaXMuc3BlY2lhbEhhbmRsZS5nZXRMYXllcigpKVxuICAgICAgICB0aGlzLmxheWVyIS5hZGQodGhpcy5zcGVjaWFsSGFuZGxlKTtcbiAgICAgIHRoaXMuc3BlY2lhbEhhbmRsZS5wb3NpdGlvbihjb29yZHMpO1xuICAgIH1cbiAgICB0aGlzLmxheWVyIS5iYXRjaERyYXcoKTtcbiAgfVxuXG4gIHByaXZhdGUgc2hvd1BvaW50RWRpdG9yKGRhdGFJbmRleDogbnVtYmVyLCBjbGllbnRYOiBudW1iZXIsIGNsaWVudFk6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IHBvaW50ID0gdGhpcy5fcHJvcC5saW5lW2RhdGFJbmRleF07XG4gICAgY29uc3QgeElucHV0ID0gdWkuaW5wdXQuZmxvYXQoJ1gnLCB7dmFsdWU6IHBvaW50WzBdLCBtaW46IHRoaXMuZ2V0TWluWCgpLCBtYXg6IHRoaXMuZ2V0TWF4WCgpLCBmb3JtYXQ6ICcjMC4wMCcsIHN0ZXA6IDAuMDF9KTtcbiAgICBjb25zdCB5SW5wdXQgPSB1aS5pbnB1dC5mbG9hdCgnWScsIHt2YWx1ZTogcG9pbnRbMV0sIG1pbjogMCwgbWF4OiAxLCBmb3JtYXQ6ICcjMC4wMCcsIHN0ZXA6IDAuMDF9KTtcblxuICAgIGNvbnN0IGNsb3NlID0gKCkgPT4ge1xuICAgICAgY29udGVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJywgb25LZXkpO1xuICAgICAgcG9wdXAucmVtb3ZlKCk7XG4gICAgfTtcblxuICAgIGNvbnN0IGFwcGx5ID0gKCkgPT4ge1xuICAgICAgY29uc3QgeCA9IHhJbnB1dC52YWx1ZTtcbiAgICAgIGNvbnN0IHkgPSB5SW5wdXQudmFsdWU7XG4gICAgICBpZiAoeCA9PSBudWxsIHx8IHkgPT0gbnVsbCB8fCBpc05hTih4KSB8fCBpc05hTih5KSlcbiAgICAgICAgcmV0dXJuO1xuICAgICAgdGhpcy5fcHJvcC5saW5lW2RhdGFJbmRleF0gPSBbeCwgeV07XG4gICAgICB0aGlzLnJlZHJhd0FsbCgpO1xuICAgIH07XG5cbiAgICBjb25zdCBvbktleSA9IChlOiBLZXlib2FyZEV2ZW50KSA9PiB7XG4gICAgICBpZiAoZS5rZXkgPT09ICdFbnRlcicpIHtcbiAgICAgICAgYXBwbHkoKTtcbiAgICAgICAgY2xvc2UoKTtcbiAgICAgIH1cbiAgICAgIGlmIChlLmtleSA9PT0gJ0VzY2FwZScpXG4gICAgICAgIGNsb3NlKCk7XG4gICAgfTtcblxuICAgIGNvbnN0IGNvbnRlbnQgPSB1aS5pbnB1dHMoW3hJbnB1dCwgeUlucHV0XSk7XG4gICAgY29udGVudC5zdHlsZS5vdmVyZmxvdyA9ICdoaWRkZW4nO1xuICAgIGNvbnRlbnQuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIG9uS2V5KTtcblxuICAgIGNvbnN0IHJvb3RSZWN0ID0gdGhpcy5yb290LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IHBvcHVwID0gdWkuc2hvd1BvcHVwKGNvbnRlbnQsIHRoaXMucm9vdCwge2R4OiBjbGllbnRYIC0gcm9vdFJlY3QubGVmdCwgZHk6IGNsaWVudFkgLSByb290UmVjdC5ib3R0b20sIHNtYXJ0OiBmYWxzZX0pO1xuICB9XG5cbiAgc2V0UmFuZ2UobWluOiBudW1iZXIsIG1heDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3Qgb2xkTWluID0gdGhpcy5nZXRNaW5YKCk7XG4gICAgY29uc3Qgb2xkTWF4ID0gdGhpcy5nZXRNYXhYKCk7XG4gICAgY29uc3Qgb2xkUmFuZ2UgPSBvbGRNYXggLSBvbGRNaW47XG4gICAgY29uc3QgbmV3UmFuZ2UgPSBtYXggLSBtaW47XG5cbiAgICBpZiAob2xkUmFuZ2UgIT09IDAgJiYgbmV3UmFuZ2UgIT09IDApIHtcbiAgICAgIGNvbnN0IHNjYWxlID0gbmV3UmFuZ2UgLyBvbGRSYW5nZTtcbiAgICAgIGNvbnN0IHJlbWFwID0gKHg6IG51bWJlcikgPT4gbWluICsgKHggLSBvbGRNaW4pICogc2NhbGU7XG5cbiAgICAgIGlmICh0aGlzLl9wcm9wLm1lYW4gIT0gbnVsbClcbiAgICAgICAgdGhpcy5fcHJvcC5tZWFuID0gcmVtYXAodGhpcy5fcHJvcC5tZWFuKTtcbiAgICAgIGlmICh0aGlzLl9wcm9wLnNpZ21hICE9IG51bGwpXG4gICAgICAgIHRoaXMuX3Byb3Auc2lnbWEgKj0gc2NhbGU7XG4gICAgICBpZiAodGhpcy5fcHJvcC54MCAhPSBudWxsKVxuICAgICAgICB0aGlzLl9wcm9wLngwID0gcmVtYXAodGhpcy5fcHJvcC54MCk7XG4gICAgICBpZiAodGhpcy5fcHJvcC5rICE9IG51bGwpXG4gICAgICAgIHRoaXMuX3Byb3AuayAvPSBzY2FsZTtcblxuICAgICAgZm9yIChjb25zdCBwIG9mIHRoaXMuX3Byb3AubGluZSlcbiAgICAgICAgcFswXSA9IHJlbWFwKHBbMF0pO1xuXG4gICAgICBpZiAodGhpcy5fcHJvcC5mcmVlZm9ybUxpbmUpIHtcbiAgICAgICAgZm9yIChjb25zdCBwIG9mIHRoaXMuX3Byb3AuZnJlZWZvcm1MaW5lKVxuICAgICAgICAgIHBbMF0gPSByZW1hcChwWzBdKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLl9wcm9wLm1pbiA9IG1pbjtcbiAgICB0aGlzLl9wcm9wLm1heCA9IG1heDtcbiAgICB0aGlzLnVwZGF0ZURyYWdTY2FsZXMoKTtcbiAgICB0aGlzLnJlZHJhd0FsbChmYWxzZSk7XG4gIH1cblxuICBzZXRDb2x1bW4oY29sOiBERy5Db2x1bW4gfCBudWxsKTogdm9pZCB7XG4gICAgaWYgKCFjb2wpXG4gICAgICByZXR1cm47XG5cbiAgICBjb25zdCB2YWx1ZXMgPSBjb2wudG9MaXN0KCk7XG4gICAgdGhpcy5kcmF3QmFycyh2YWx1ZXMpO1xuICB9XG59XG4iXX0=
|