ms-data-grid 0.0.149 → 0.0.151
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/esm2022/lib/data-grid/data-grid.component.mjs +138 -1108
- package/esm2022/lib/services/cell-selection.service.mjs +544 -0
- package/esm2022/lib/services/common.service.mjs +75 -1
- package/esm2022/lib/services/copy-service.service.mjs +42 -11
- package/fesm2022/ms-data-grid.mjs +805 -1129
- package/fesm2022/ms-data-grid.mjs.map +1 -1
- package/lib/data-grid/data-grid.component.d.ts +18 -59
- package/lib/services/cell-selection.service.d.ts +66 -0
- package/lib/services/common.service.d.ts +4 -0
- package/lib/services/copy-service.service.d.ts +2 -0
- package/package.json +1 -1
|
@@ -0,0 +1,544 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
export class CellSelectionService {
|
|
4
|
+
constructor() {
|
|
5
|
+
this.selectedCells = [];
|
|
6
|
+
this.selectedKeys = new Set();
|
|
7
|
+
this.selectionStart = null;
|
|
8
|
+
this.isSelecting = false;
|
|
9
|
+
this.activeCell = null;
|
|
10
|
+
this.cellSelectionAutoScrollInterval = null;
|
|
11
|
+
this.scrollSpeed = 150;
|
|
12
|
+
this.scrollMargin = 30;
|
|
13
|
+
this.columns = [];
|
|
14
|
+
this.getColumnByIndex = () => null;
|
|
15
|
+
this.verticalContainer = null;
|
|
16
|
+
this.horizontalContainer = null;
|
|
17
|
+
this.selectionBounds = { top: 0, bottom: 0, left: null, right: null };
|
|
18
|
+
this.ctrlKeyPressed = false;
|
|
19
|
+
this.rowHeight = 44;
|
|
20
|
+
}
|
|
21
|
+
startSelection(row, column, subColIndex, event) {
|
|
22
|
+
this.isSelecting = true;
|
|
23
|
+
this.activeCell = null;
|
|
24
|
+
const rIndex = row.__virtualIndex;
|
|
25
|
+
const cIndex = column.index;
|
|
26
|
+
const sIndex = subColIndex ?? 0;
|
|
27
|
+
const key = `${rIndex}-${cIndex}-${sIndex}`;
|
|
28
|
+
this.selectionStart = { rowIndex: rIndex, colIndex: cIndex, subColIndex: sIndex, field: column.field, key };
|
|
29
|
+
this.selectedCells = [this.selectionStart];
|
|
30
|
+
this.selectedKeys.clear();
|
|
31
|
+
this.selectedKeys.add(key);
|
|
32
|
+
const mouseUpHandler = () => {
|
|
33
|
+
this.endSelection();
|
|
34
|
+
document.removeEventListener('mouseup', mouseUpHandler);
|
|
35
|
+
};
|
|
36
|
+
document.addEventListener('mouseup', mouseUpHandler);
|
|
37
|
+
this.updateSelectionBoundaries();
|
|
38
|
+
}
|
|
39
|
+
extendSelection(row, column, subColIndex, event) {
|
|
40
|
+
if (!this.isSelecting || !this.selectionStart)
|
|
41
|
+
return;
|
|
42
|
+
const start = this.selectionStart;
|
|
43
|
+
const rStart = start.rowIndex;
|
|
44
|
+
const rEnd = row.__virtualIndex;
|
|
45
|
+
const cStart = start.colIndex;
|
|
46
|
+
const cEnd = column.index;
|
|
47
|
+
const sStart = start.subColIndex ?? 0;
|
|
48
|
+
const sEnd = subColIndex ?? 0;
|
|
49
|
+
const minRow = Math.min(rStart, rEnd);
|
|
50
|
+
const maxRow = Math.max(rStart, rEnd);
|
|
51
|
+
const minCol = Math.min(cStart, cEnd);
|
|
52
|
+
const maxCol = Math.max(cStart, cEnd);
|
|
53
|
+
const newKeys = new Set();
|
|
54
|
+
const newCells = [];
|
|
55
|
+
for (let r = minRow; r <= maxRow; r++) {
|
|
56
|
+
for (let c = minCol; c <= maxCol; c++) {
|
|
57
|
+
const colObj = this.getColumnByIndex(c);
|
|
58
|
+
const subCount = colObj?.children?.length ?? 1;
|
|
59
|
+
const startSub = (c === cStart) ? sStart : 0;
|
|
60
|
+
const endSub = (c === cEnd) ? sEnd : subCount - 1;
|
|
61
|
+
for (let s = startSub; s <= endSub; s++) {
|
|
62
|
+
const key = `${r}-${c}-${s}`;
|
|
63
|
+
newKeys.add(key);
|
|
64
|
+
newCells.push({ rowIndex: r, colIndex: c, subColIndex: s, field: colObj?.field || '', key });
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
this.selectedKeys = newKeys;
|
|
69
|
+
this.selectedCells = newCells;
|
|
70
|
+
this.updateSelectionBoundaries();
|
|
71
|
+
// Auto-scroll
|
|
72
|
+
this.handleCellAutoScroll(event);
|
|
73
|
+
}
|
|
74
|
+
// ------------------- END SELECTION -------------------
|
|
75
|
+
endSelection() {
|
|
76
|
+
this.isSelecting = false;
|
|
77
|
+
this.stopAutoScroll();
|
|
78
|
+
this.updateSelectionBoundaries();
|
|
79
|
+
}
|
|
80
|
+
// ------------------- AUTO-SCROLL -------------------
|
|
81
|
+
handleCellAutoScroll(event) {
|
|
82
|
+
if (this.cellSelectionAutoScrollInterval) {
|
|
83
|
+
clearInterval(this.cellSelectionAutoScrollInterval);
|
|
84
|
+
this.cellSelectionAutoScrollInterval = null;
|
|
85
|
+
}
|
|
86
|
+
if (!this.horizontalContainer || !this.verticalContainer)
|
|
87
|
+
return;
|
|
88
|
+
const horRect = this.horizontalContainer.getBoundingClientRect();
|
|
89
|
+
const vertRect = this.verticalContainer.getBoundingClientRect();
|
|
90
|
+
const mouseX = event.clientX;
|
|
91
|
+
const mouseY = event.clientY;
|
|
92
|
+
let scrollX = 0;
|
|
93
|
+
let scrollY = 0;
|
|
94
|
+
if (mouseX - horRect.left < this.scrollMargin)
|
|
95
|
+
scrollX = -this.scrollSpeed;
|
|
96
|
+
else if (horRect.right - mouseX < this.scrollMargin)
|
|
97
|
+
scrollX = this.scrollSpeed;
|
|
98
|
+
if (mouseY - vertRect.top < this.scrollMargin)
|
|
99
|
+
scrollY = -this.scrollSpeed;
|
|
100
|
+
else if (vertRect.bottom - mouseY < this.scrollMargin)
|
|
101
|
+
scrollY = this.scrollSpeed;
|
|
102
|
+
if (scrollX !== 0 || scrollY !== 0) {
|
|
103
|
+
this.cellSelectionAutoScrollInterval = setInterval(() => {
|
|
104
|
+
if (scrollX !== 0)
|
|
105
|
+
this.horizontalContainer.scrollBy(scrollX, 0);
|
|
106
|
+
if (scrollY !== 0)
|
|
107
|
+
this.verticalContainer.scrollBy(0, scrollY);
|
|
108
|
+
}, 8);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
stopAutoScroll() {
|
|
112
|
+
if (this.cellSelectionAutoScrollInterval) {
|
|
113
|
+
clearInterval(this.cellSelectionAutoScrollInterval);
|
|
114
|
+
this.cellSelectionAutoScrollInterval = null;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// ------------------- HELPERS -------------------
|
|
118
|
+
isSelected(rowIndex, colIndex, subColIndex) {
|
|
119
|
+
const sIndex = subColIndex ?? 0;
|
|
120
|
+
const key = `${rowIndex}-${colIndex}-${sIndex}`;
|
|
121
|
+
return this.selectedKeys.has(key);
|
|
122
|
+
}
|
|
123
|
+
updateSelectionBoundaries() {
|
|
124
|
+
if (this.selectedCells.length === 0) {
|
|
125
|
+
this.selectionBounds = { top: 0, bottom: 0, left: null, right: null };
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const rowIndices = this.selectedCells.map(c => c.rowIndex);
|
|
129
|
+
this.selectionBounds.top = Math.min(...rowIndices);
|
|
130
|
+
this.selectionBounds.bottom = Math.max(...rowIndices);
|
|
131
|
+
const leftCol = Math.min(...this.selectedCells.map(c => c.colIndex));
|
|
132
|
+
const leftCells = this.selectedCells.filter(c => c.colIndex === leftCol);
|
|
133
|
+
const minSub = Math.min(...leftCells.map(c => c.subColIndex ?? 0));
|
|
134
|
+
this.selectionBounds.left = { colIndex: leftCol, subColIndex: minSub };
|
|
135
|
+
const rightCol = Math.max(...this.selectedCells.map(c => c.colIndex));
|
|
136
|
+
const rightCells = this.selectedCells.filter(c => c.colIndex === rightCol);
|
|
137
|
+
const maxSub = Math.max(...rightCells.map(c => c.subColIndex ?? 0));
|
|
138
|
+
this.selectionBounds.right = { colIndex: rightCol, subColIndex: maxSub };
|
|
139
|
+
}
|
|
140
|
+
// ------------------- BORDER CHECKS -------------------
|
|
141
|
+
isTopBorder(rowIndex, colIndex, subColIndex) {
|
|
142
|
+
return this.isSelected(rowIndex, colIndex, subColIndex) && rowIndex === this.selectionBounds.top;
|
|
143
|
+
}
|
|
144
|
+
isBottomBorder(rowIndex, colIndex, subColIndex) {
|
|
145
|
+
return this.isSelected(rowIndex, colIndex, subColIndex) && rowIndex === this.selectionBounds.bottom;
|
|
146
|
+
}
|
|
147
|
+
isLeftBorder(rowIndex, colIndex, subColIndex) {
|
|
148
|
+
if (!this.selectionBounds.left)
|
|
149
|
+
return false;
|
|
150
|
+
const sIndex = subColIndex ?? 0;
|
|
151
|
+
return this.isSelected(rowIndex, colIndex, subColIndex) &&
|
|
152
|
+
colIndex === this.selectionBounds.left.colIndex &&
|
|
153
|
+
sIndex === this.selectionBounds.left.subColIndex;
|
|
154
|
+
}
|
|
155
|
+
isRightBorder(rowIndex, colIndex, subColIndex) {
|
|
156
|
+
if (!this.selectionBounds.right)
|
|
157
|
+
return false;
|
|
158
|
+
const sIndex = subColIndex ?? 0;
|
|
159
|
+
return this.isSelected(rowIndex, colIndex, subColIndex) &&
|
|
160
|
+
colIndex === this.selectionBounds.right.colIndex &&
|
|
161
|
+
sIndex === this.selectionBounds.right.subColIndex;
|
|
162
|
+
}
|
|
163
|
+
isTopLeftCorner(rowIndex, colIndex, subColIndex) {
|
|
164
|
+
return this.isTopBorder(rowIndex, colIndex, subColIndex) && this.isLeftBorder(rowIndex, colIndex, subColIndex);
|
|
165
|
+
}
|
|
166
|
+
isTopRightCorner(rowIndex, colIndex, subColIndex) {
|
|
167
|
+
return this.isTopBorder(rowIndex, colIndex, subColIndex) && this.isRightBorder(rowIndex, colIndex, subColIndex);
|
|
168
|
+
}
|
|
169
|
+
isBottomLeftCorner(rowIndex, colIndex, subColIndex) {
|
|
170
|
+
return this.isBottomBorder(rowIndex, colIndex, subColIndex) && this.isLeftBorder(rowIndex, colIndex, subColIndex);
|
|
171
|
+
}
|
|
172
|
+
isBottomRightCorner(rowIndex, colIndex, subColIndex) {
|
|
173
|
+
return this.isBottomBorder(rowIndex, colIndex, subColIndex) && this.isRightBorder(rowIndex, colIndex, subColIndex);
|
|
174
|
+
}
|
|
175
|
+
setActiveCell(rowIndex, colIndex, subColIndex) {
|
|
176
|
+
const sIndex = subColIndex ?? 0;
|
|
177
|
+
this.activeCell = { rowIndex, colIndex, subColIndex: sIndex, key: `${rowIndex}-${colIndex}-${sIndex}`, field: '' };
|
|
178
|
+
}
|
|
179
|
+
isActiveCell(rowIndex, colIndex, subColIndex) {
|
|
180
|
+
if (!this.activeCell)
|
|
181
|
+
return false;
|
|
182
|
+
const sIndex = subColIndex ?? 0;
|
|
183
|
+
return this.activeCell.rowIndex === rowIndex && this.activeCell.colIndex === colIndex && this.activeCell.subColIndex === sIndex;
|
|
184
|
+
}
|
|
185
|
+
selectAllCells(dataSet, columns) {
|
|
186
|
+
if (!dataSet?.length || !columns?.length)
|
|
187
|
+
return;
|
|
188
|
+
this.selectedCells = [];
|
|
189
|
+
this.selectedKeys.clear();
|
|
190
|
+
this.selectionStart = null;
|
|
191
|
+
this.isSelecting = true;
|
|
192
|
+
for (const row of dataSet) {
|
|
193
|
+
const rIndex = row.__virtualIndex;
|
|
194
|
+
for (let c = 0; c < columns.length; c++) {
|
|
195
|
+
const col = columns[c];
|
|
196
|
+
if (col.is_visible === false)
|
|
197
|
+
continue;
|
|
198
|
+
const field = col.field || col.name;
|
|
199
|
+
if (Array.isArray(col.children) && col.children.length) {
|
|
200
|
+
col.children.forEach((subCol, s) => {
|
|
201
|
+
if (subCol.is_visible === false)
|
|
202
|
+
return;
|
|
203
|
+
const key = `${rIndex}-${c}-${s}`;
|
|
204
|
+
this.selectedKeys.add(key);
|
|
205
|
+
this.selectedCells.push({
|
|
206
|
+
rowIndex: rIndex,
|
|
207
|
+
colIndex: c,
|
|
208
|
+
subColIndex: s,
|
|
209
|
+
field,
|
|
210
|
+
key
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
const key = `${rIndex}-${c}-0`;
|
|
216
|
+
this.selectedKeys.add(key);
|
|
217
|
+
this.selectedCells.push({
|
|
218
|
+
rowIndex: rIndex,
|
|
219
|
+
colIndex: c,
|
|
220
|
+
subColIndex: 0,
|
|
221
|
+
field,
|
|
222
|
+
key
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
this.isSelecting = false;
|
|
228
|
+
this.selectionStart = this.selectedCells[0] ?? null;
|
|
229
|
+
this.updateSelectionBoundaries();
|
|
230
|
+
}
|
|
231
|
+
moveActiveCell(direction, shiftKey, dataSet, columns) {
|
|
232
|
+
if (!this.activeCell)
|
|
233
|
+
return;
|
|
234
|
+
let { rowIndex, colIndex, subColIndex = 0 } = this.activeCell;
|
|
235
|
+
const col = this.getColumnByIndex(colIndex);
|
|
236
|
+
// ---------------------------
|
|
237
|
+
// Adjust for 1-based virtual index
|
|
238
|
+
const minRow = 1; // first row __virtualIndex
|
|
239
|
+
const maxRow = dataSet.length; // last row __virtualIndex
|
|
240
|
+
const maxCol = columns.length - 1;
|
|
241
|
+
// Compute new indices
|
|
242
|
+
switch (direction) {
|
|
243
|
+
case 'up':
|
|
244
|
+
rowIndex = Math.max(minRow, rowIndex - 1);
|
|
245
|
+
break;
|
|
246
|
+
case 'down':
|
|
247
|
+
rowIndex = Math.min(maxRow, rowIndex + 1);
|
|
248
|
+
break;
|
|
249
|
+
case 'left': {
|
|
250
|
+
// 1️⃣ Move inside sub-columns
|
|
251
|
+
if (subColIndex > 0) {
|
|
252
|
+
subColIndex -= 1;
|
|
253
|
+
break;
|
|
254
|
+
}
|
|
255
|
+
// 2️⃣ Find previous visible column
|
|
256
|
+
const prevCol = this.findPrevVisibleCol(colIndex);
|
|
257
|
+
if (prevCol !== null) {
|
|
258
|
+
colIndex = prevCol;
|
|
259
|
+
const pCol = this.getColumnByIndex(colIndex);
|
|
260
|
+
subColIndex = pCol?.children?.length
|
|
261
|
+
? pCol.children.length - 1
|
|
262
|
+
: 0;
|
|
263
|
+
break;
|
|
264
|
+
}
|
|
265
|
+
// 3️⃣ Start of row → previous row last visible column
|
|
266
|
+
if (rowIndex > minRow) {
|
|
267
|
+
rowIndex -= 1;
|
|
268
|
+
const lastVisible = this.findPrevVisibleCol(maxCol + 1);
|
|
269
|
+
if (lastVisible !== null) {
|
|
270
|
+
colIndex = lastVisible;
|
|
271
|
+
const lCol = this.getColumnByIndex(colIndex);
|
|
272
|
+
subColIndex = lCol?.children?.length
|
|
273
|
+
? lCol.children.length - 1
|
|
274
|
+
: 0;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
break;
|
|
278
|
+
}
|
|
279
|
+
case 'right': {
|
|
280
|
+
const maxSub = col?.children?.length ? col.children.length - 1 : 0;
|
|
281
|
+
// 1️⃣ Move inside sub-columns
|
|
282
|
+
if (subColIndex < maxSub) {
|
|
283
|
+
subColIndex += 1;
|
|
284
|
+
break;
|
|
285
|
+
}
|
|
286
|
+
// 2️⃣ Find next visible column
|
|
287
|
+
const nextCol = this.findNextVisibleCol(colIndex, maxCol);
|
|
288
|
+
if (nextCol !== null) {
|
|
289
|
+
colIndex = nextCol;
|
|
290
|
+
subColIndex = 0;
|
|
291
|
+
break;
|
|
292
|
+
}
|
|
293
|
+
// 3️⃣ End of row → next row first visible column
|
|
294
|
+
if (rowIndex < maxRow) {
|
|
295
|
+
rowIndex += 1;
|
|
296
|
+
const firstVisible = this.findNextVisibleCol(-1, maxCol);
|
|
297
|
+
if (firstVisible !== null) {
|
|
298
|
+
colIndex = firstVisible;
|
|
299
|
+
subColIndex = 0;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
break;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
subColIndex = subColIndex ?? 0;
|
|
306
|
+
// Set active cell
|
|
307
|
+
const active = {
|
|
308
|
+
rowIndex,
|
|
309
|
+
colIndex,
|
|
310
|
+
subColIndex,
|
|
311
|
+
key: `${rowIndex}-${colIndex}-${subColIndex}`,
|
|
312
|
+
field: columns[colIndex]?.field || ''
|
|
313
|
+
};
|
|
314
|
+
this.setActiveCell(rowIndex, colIndex, subColIndex);
|
|
315
|
+
// ---------------------------
|
|
316
|
+
// Always copy active cell into selection if Shift not pressed
|
|
317
|
+
if (!shiftKey) {
|
|
318
|
+
this.selectedCells = [active];
|
|
319
|
+
this.selectedKeys = new Set([active.key]);
|
|
320
|
+
this.selectionStart = { ...active };
|
|
321
|
+
this.updateSelectionBoundaries();
|
|
322
|
+
}
|
|
323
|
+
// Extend selection if Shift pressed
|
|
324
|
+
if (shiftKey) {
|
|
325
|
+
if (!this.selectionStart) {
|
|
326
|
+
this.selectionStart = { ...this.activeCell };
|
|
327
|
+
}
|
|
328
|
+
// 🔥 CTRL + SHIFT → extend to edge
|
|
329
|
+
if (this.ctrlKeyPressed) {
|
|
330
|
+
const edgeCell = this.getEdgeCell(direction, dataSet, columns, this.activeCell);
|
|
331
|
+
this.setActiveCell(edgeCell.rowIndex, edgeCell.colIndex, edgeCell.subColIndex);
|
|
332
|
+
this.extendSelectionByKeyboard(edgeCell);
|
|
333
|
+
this.scrollCellIntoViewImmediate(edgeCell.rowIndex, edgeCell.colIndex);
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
// Normal Shift + Arrow
|
|
337
|
+
this.extendSelectionByKeyboard(active);
|
|
338
|
+
}
|
|
339
|
+
// ---------------------------
|
|
340
|
+
// Scroll to keep active cell in view
|
|
341
|
+
const cell = this.verticalContainer?.querySelector(`[location='${rowIndex}-${colIndex}']`);
|
|
342
|
+
if (!cell || !this.verticalContainer || !this.horizontalContainer)
|
|
343
|
+
return;
|
|
344
|
+
const vertRect = this.verticalContainer.getBoundingClientRect();
|
|
345
|
+
const horRect = this.horizontalContainer.getBoundingClientRect();
|
|
346
|
+
const cellRect = cell.getBoundingClientRect();
|
|
347
|
+
const scrollMargin = 5;
|
|
348
|
+
// Vertical scroll
|
|
349
|
+
if (cellRect.bottom > vertRect.bottom) {
|
|
350
|
+
this.verticalContainer.scrollBy({ top: cellRect.bottom - vertRect.bottom + scrollMargin, behavior: 'auto' });
|
|
351
|
+
}
|
|
352
|
+
else if (cellRect.top < vertRect.top) {
|
|
353
|
+
this.verticalContainer.scrollBy({ top: cellRect.top - vertRect.top - scrollMargin, behavior: 'auto' });
|
|
354
|
+
}
|
|
355
|
+
// Horizontal scroll
|
|
356
|
+
if (cellRect.right > horRect.right) {
|
|
357
|
+
this.horizontalContainer.scrollBy({ left: cellRect.right - horRect.right + scrollMargin, behavior: 'auto' });
|
|
358
|
+
}
|
|
359
|
+
else if (cellRect.left < horRect.left) {
|
|
360
|
+
this.horizontalContainer.scrollBy({ left: cellRect.left - horRect.left - scrollMargin, behavior: 'auto' });
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
isColumnVisible(colIndex) {
|
|
364
|
+
const col = this.getColumnByIndex(colIndex);
|
|
365
|
+
if (!col)
|
|
366
|
+
return false;
|
|
367
|
+
// Parent visible OR any child visible
|
|
368
|
+
if (Array.isArray(col.children)) {
|
|
369
|
+
return col.children.some((c) => c.is_visible !== false);
|
|
370
|
+
}
|
|
371
|
+
return col.is_visible !== false;
|
|
372
|
+
}
|
|
373
|
+
findNextVisibleCol(start, maxCol) {
|
|
374
|
+
for (let i = start + 1; i <= maxCol; i++) {
|
|
375
|
+
if (this.isColumnVisible(i))
|
|
376
|
+
return i;
|
|
377
|
+
}
|
|
378
|
+
return null;
|
|
379
|
+
}
|
|
380
|
+
findPrevVisibleCol(start) {
|
|
381
|
+
for (let i = start - 1; i >= 0; i--) {
|
|
382
|
+
if (this.isColumnVisible(i))
|
|
383
|
+
return i;
|
|
384
|
+
}
|
|
385
|
+
return null;
|
|
386
|
+
}
|
|
387
|
+
scrollActiveCellIntoView(rowIndex, colIndex) {
|
|
388
|
+
if (!this.verticalContainer || !this.horizontalContainer)
|
|
389
|
+
return;
|
|
390
|
+
const rowEl = this.verticalContainer.querySelector(`[location='${rowIndex}-${colIndex}']`);
|
|
391
|
+
if (!rowEl)
|
|
392
|
+
return;
|
|
393
|
+
const rowRect = rowEl.getBoundingClientRect();
|
|
394
|
+
const vertRect = this.verticalContainer.getBoundingClientRect();
|
|
395
|
+
const horRect = this.horizontalContainer.getBoundingClientRect();
|
|
396
|
+
// Vertical scroll
|
|
397
|
+
if (rowRect.bottom > vertRect.bottom) {
|
|
398
|
+
this.verticalContainer.scrollBy({ top: rowRect.bottom - vertRect.bottom + 5, behavior: 'smooth' });
|
|
399
|
+
}
|
|
400
|
+
else if (rowRect.top < vertRect.top) {
|
|
401
|
+
this.verticalContainer.scrollBy({ top: rowRect.top - vertRect.top - 5, behavior: 'smooth' });
|
|
402
|
+
}
|
|
403
|
+
// Horizontal scroll
|
|
404
|
+
if (rowRect.right > horRect.right) {
|
|
405
|
+
this.horizontalContainer.scrollBy({ left: rowRect.right - horRect.right + 5, behavior: 'smooth' });
|
|
406
|
+
}
|
|
407
|
+
else if (rowRect.left < horRect.left) {
|
|
408
|
+
this.horizontalContainer.scrollBy({ left: rowRect.left - horRect.left - 5, behavior: 'smooth' });
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
extendSelectionByKeyboard(target) {
|
|
412
|
+
if (!this.selectionStart) {
|
|
413
|
+
this.selectionStart = { ...target };
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
const start = this.selectionStart;
|
|
417
|
+
const minRow = Math.min(start.rowIndex, target.rowIndex);
|
|
418
|
+
const maxRow = Math.max(start.rowIndex, target.rowIndex);
|
|
419
|
+
const minCol = Math.min(start.colIndex, target.colIndex);
|
|
420
|
+
const maxCol = Math.max(start.colIndex, target.colIndex);
|
|
421
|
+
const newKeys = new Set();
|
|
422
|
+
const newCells = [];
|
|
423
|
+
for (let r = minRow; r <= maxRow; r++) {
|
|
424
|
+
for (let c = minCol; c <= maxCol; c++) {
|
|
425
|
+
const colObj = this.getColumnByIndex(c);
|
|
426
|
+
if (!colObj)
|
|
427
|
+
continue;
|
|
428
|
+
const subCount = colObj.children?.length ?? 1;
|
|
429
|
+
const startSub = c === start.colIndex ? start.subColIndex : 0;
|
|
430
|
+
const endSub = c === target.colIndex ? target.subColIndex : subCount - 1;
|
|
431
|
+
for (let s = startSub; s <= endSub; s++) {
|
|
432
|
+
const key = `${r}-${c}-${s}`;
|
|
433
|
+
newKeys.add(key);
|
|
434
|
+
newCells.push({
|
|
435
|
+
rowIndex: r,
|
|
436
|
+
colIndex: c,
|
|
437
|
+
subColIndex: s,
|
|
438
|
+
field: colObj.field || '',
|
|
439
|
+
key
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
this.selectedKeys = newKeys;
|
|
445
|
+
this.selectedCells = newCells;
|
|
446
|
+
this.updateSelectionBoundaries();
|
|
447
|
+
}
|
|
448
|
+
getEdgeCell(direction, dataSet, columns, from) {
|
|
449
|
+
const minRow = 1;
|
|
450
|
+
const maxRow = dataSet.length;
|
|
451
|
+
const maxCol = columns.length - 1;
|
|
452
|
+
let { rowIndex, colIndex, subColIndex } = from;
|
|
453
|
+
switch (direction) {
|
|
454
|
+
case 'up':
|
|
455
|
+
rowIndex = minRow;
|
|
456
|
+
break;
|
|
457
|
+
case 'down':
|
|
458
|
+
rowIndex = maxRow;
|
|
459
|
+
break;
|
|
460
|
+
case 'left': {
|
|
461
|
+
const firstVisible = this.findNextVisibleCol(-1, maxCol);
|
|
462
|
+
if (firstVisible !== null) {
|
|
463
|
+
colIndex = firstVisible;
|
|
464
|
+
const col = this.getColumnByIndex(colIndex);
|
|
465
|
+
subColIndex = 0;
|
|
466
|
+
}
|
|
467
|
+
break;
|
|
468
|
+
}
|
|
469
|
+
case 'right': {
|
|
470
|
+
const lastVisible = this.findPrevVisibleCol(maxCol + 1);
|
|
471
|
+
if (lastVisible !== null) {
|
|
472
|
+
colIndex = lastVisible;
|
|
473
|
+
const col = this.getColumnByIndex(colIndex);
|
|
474
|
+
subColIndex = col?.children?.length
|
|
475
|
+
? col.children.length - 1
|
|
476
|
+
: 0;
|
|
477
|
+
}
|
|
478
|
+
break;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
return {
|
|
482
|
+
rowIndex,
|
|
483
|
+
colIndex,
|
|
484
|
+
subColIndex,
|
|
485
|
+
key: `${rowIndex}-${colIndex}-${subColIndex}`,
|
|
486
|
+
field: columns[colIndex]?.field || ''
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
scrollCellIntoViewImmediate(rowIndex, colIndex) {
|
|
490
|
+
if (!this.verticalContainer || !this.horizontalContainer)
|
|
491
|
+
return;
|
|
492
|
+
const margin = 6;
|
|
493
|
+
// ---------------------------
|
|
494
|
+
// Vertical scroll
|
|
495
|
+
// ---------------------------
|
|
496
|
+
const targetScrollTop = (rowIndex - 1) * this.rowHeight;
|
|
497
|
+
const maxScrollTop = this.verticalContainer.scrollHeight - this.verticalContainer.clientHeight;
|
|
498
|
+
this.verticalContainer.scrollTop = Math.max(0, Math.min(targetScrollTop, maxScrollTop));
|
|
499
|
+
// ---------------------------
|
|
500
|
+
// Horizontal scroll
|
|
501
|
+
// ---------------------------
|
|
502
|
+
const activeCell = this.verticalContainer.querySelector(`[location='${rowIndex}-${colIndex}']`);
|
|
503
|
+
if (!activeCell)
|
|
504
|
+
return;
|
|
505
|
+
const container = this.horizontalContainer;
|
|
506
|
+
// cell's offset relative to container
|
|
507
|
+
const cellLeft = activeCell.offsetLeft;
|
|
508
|
+
const cellRight = cellLeft + activeCell.offsetWidth;
|
|
509
|
+
const scrollLeft = container.scrollLeft;
|
|
510
|
+
const containerWidth = container.clientWidth;
|
|
511
|
+
if (cellLeft < scrollLeft) {
|
|
512
|
+
container.scrollLeft = cellLeft - margin;
|
|
513
|
+
}
|
|
514
|
+
else if (cellRight > scrollLeft + containerWidth) {
|
|
515
|
+
container.scrollLeft = cellRight - containerWidth + margin;
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
isLastRow(rowIndex) {
|
|
519
|
+
if (!this.verticalContainer)
|
|
520
|
+
return false;
|
|
521
|
+
return (rowIndex ===
|
|
522
|
+
Math.round(this.verticalContainer.scrollHeight /
|
|
523
|
+
(this.verticalContainer.scrollHeight /
|
|
524
|
+
this.verticalContainer.children.length)) || false);
|
|
525
|
+
}
|
|
526
|
+
get selectedColumnIndices() {
|
|
527
|
+
if (!this.selectionBounds.left || !this.selectionBounds.right)
|
|
528
|
+
return [];
|
|
529
|
+
const indices = [];
|
|
530
|
+
for (let i = this.selectionBounds.left.colIndex; i <= this.selectionBounds.right.colIndex; i++) {
|
|
531
|
+
// Only include visible columns
|
|
532
|
+
if (this.isColumnVisible(i))
|
|
533
|
+
indices.push(i);
|
|
534
|
+
}
|
|
535
|
+
return indices;
|
|
536
|
+
}
|
|
537
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CellSelectionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
538
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CellSelectionService, providedIn: 'root' }); }
|
|
539
|
+
}
|
|
540
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CellSelectionService, decorators: [{
|
|
541
|
+
type: Injectable,
|
|
542
|
+
args: [{ providedIn: 'root' }]
|
|
543
|
+
}] });
|
|
544
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VsbC1zZWxlY3Rpb24uc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2RhdGEtZ3JpZC9zcmMvbGliL3NlcnZpY2VzL2NlbGwtc2VsZWN0aW9uLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQzs7QUFZM0MsTUFBTSxPQUFPLG9CQUFvQjtJQURqQztRQUdFLGtCQUFhLEdBQWMsRUFBRSxDQUFDO1FBQzlCLGlCQUFZLEdBQWdCLElBQUksR0FBRyxFQUFFLENBQUM7UUFDdEMsbUJBQWMsR0FBbUIsSUFBSSxDQUFDO1FBQ3RDLGdCQUFXLEdBQUcsS0FBSyxDQUFDO1FBQ3BCLGVBQVUsR0FBbUIsSUFBSSxDQUFDO1FBRzFCLG9DQUErQixHQUFRLElBQUksQ0FBQztRQUM1QyxnQkFBVyxHQUFHLEdBQUcsQ0FBQztRQUNsQixpQkFBWSxHQUFHLEVBQUUsQ0FBQztRQUUxQixZQUFPLEdBQVUsRUFBRSxDQUFDO1FBQ3BCLHFCQUFnQixHQUEyQixHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUM7UUFFdEQsc0JBQWlCLEdBQXVCLElBQUksQ0FBQztRQUM3Qyx3QkFBbUIsR0FBdUIsSUFBSSxDQUFDO1FBRXhDLG9CQUFlLEdBS2xCLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDO1FBMFpuRCxtQkFBYyxHQUFHLEtBQUssQ0FBQztRQTZKdkIsY0FBUyxHQUFHLEVBQUUsQ0FBQztLQThEaEI7SUFubkJDLGNBQWMsQ0FBQyxHQUFRLEVBQUUsTUFBVyxFQUFFLFdBQTBCLEVBQUUsS0FBaUI7UUFDakYsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7UUFDeEIsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7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QUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxVQUFVLENBQUMsQ0FBQztRQUV0RCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztRQUNyRSxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLEtBQUssT0FBTyxDQUFDLENBQUM7UUFDekUsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsV0FBVyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbkUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLEdBQUcsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUUsQ0FBQztRQUV2RSxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztRQUN0RSxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLEtBQUssUUFBUSxDQUFDLENBQUM7UUFDM0UsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsV0FBVyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDcEUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLEdBQUcsRUFBRSxRQUFRLEVBQUUsUUFB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QUUsQ0FBQyxFQUFFLEVBQUU7WUFDOUYsK0JBQStCO1lBQy9CLElBQUksSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUM7Z0JBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUM5QztRQUNELE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7K0dBem9CWSxvQkFBb0I7bUhBQXBCLG9CQUFvQixjQURQLE1BQU07OzRGQUNuQixvQkFBb0I7a0JBRGhDLFVBQVU7bUJBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2VsbFBvcyB7XG4gIHJvd0luZGV4OiBudW1iZXI7XG4gIGNvbEluZGV4OiBudW1iZXI7XG4gIHN1YkNvbEluZGV4OiBudW1iZXI7XG4gIGZpZWxkOiBzdHJpbmc7XG4gIGtleTogc3RyaW5nO1xufVxuXG5ASW5qZWN0YWJsZSh7IHByb3ZpZGVkSW46ICdyb290JyB9KVxuZXhwb3J0IGNsYXNzIENlbGxTZWxlY3Rpb25TZXJ2aWNlIHtcblxuICBzZWxlY3RlZENlbGxzOiBDZWxsUG9zW10gPSBbXTtcbiAgc2VsZWN0ZWRLZXlzOiBTZXQ8c3RyaW5nPiA9IG5ldyBTZXQoKTtcbiAgc2VsZWN0aW9uU3RhcnQ6IENlbGxQb3MgfCBudWxsID0gbnVsbDtcbiAgaXNTZWxlY3RpbmcgPSBmYWxzZTtcbiAgYWN0aXZlQ2VsbDogQ2VsbFBvcyB8IG51bGwgPSBudWxsO1xuXG5cbiAgcHJpdmF0ZSBjZWxsU2VsZWN0aW9uQXV0b1Njcm9sbEludGVydmFsOiBhbnkgPSBudWxsO1xuICBwcml2YXRlIHNjcm9sbFNwZWVkID0gMTUwO1xuICBwcml2YXRlIHNjcm9sbE1hcmdpbiA9IDMwO1xuXG4gIGNvbHVtbnM6IGFueVtdID0gW107XG4gIGdldENvbHVtbkJ5SW5kZXg6IChpbmRleDogbnVtYmVyKSA9PiBhbnkgPSAoKSA9PiBudWxsO1xuXG4gIHZlcnRpY2FsQ29udGFpbmVyOiBIVE1MRWxlbWVudCB8IG51bGwgPSBudWxsO1xuICBob3Jpem9udGFsQ29udGFpbmVyOiBIVE1MRWxlbWVudCB8IG51bGwgPSBudWxsO1xuXG4gIHB1YmxpYyBzZWxlY3Rpb25Cb3VuZHM6IHtcbiAgICB0b3A6IG51bWJlcjtcbiAgICBib3R0b206IG51bWJlcjtcbiAgICBsZWZ0OiB7IGNvbEluZGV4OiBudW1iZXI7IHN1YkNvbEluZGV4OiBudW1iZXIgfSB8IG51bGw7XG4gICAgcmlnaHQ6IHsgY29sSW5kZXg6IG51bWJlcjsgc3ViQ29sSW5kZXg6IG51bWJlciB9IHwgbnVsbDtcbiAgfSA9IHsgdG9wOiAwLCBib3R0b206IDAsIGxlZnQ6IG51bGwsIHJpZ2h0OiBudWxsIH07XG5cbiAgc3RhcnRTZWxlY3Rpb24ocm93OiBhbnksIGNvbHVtbjogYW55LCBzdWJDb2xJbmRleDogbnVtYmVyIHwgbnVsbCwgZXZlbnQ6IE1vdXNlRXZlbnQpIHtcbiAgICB0aGlzLmlzU2VsZWN0aW5nID0gdHJ1ZTtcbiAgICB0aGlzLmFjdGl2ZUNlbGwgPSBudWxsO1xuXG4gICAgY29uc3QgckluZGV4ID0gcm93Ll9fdmlydHVhbEluZGV4O1xuICAgIGNvbnN0IGNJbmRleCA9IGNvbHVtbi5pbmRleDtcbiAgICBjb25zdCBzSW5kZXggPSBzdWJDb2xJbmRleCA/PyAwO1xuICAgIGNvbnN0IGtleSA9IGAke3JJbmRleH0tJHtjSW5kZXh9LSR7c0luZGV4fWA7XG5cbiAgICB0aGlzLnNlbGVjdGlvblN0YXJ0ID0geyByb3dJbmRleDogckluZGV4LCBjb2xJbmRleDogY0luZGV4LCBzdWJDb2xJbmRleDogc0luZGV4LCBmaWVsZDogY29sdW1uLmZpZWxkLCBrZXkgfTtcbiAgICB0aGlzLnNlbGVjdGVkQ2VsbHMgPSBbdGhpcy5zZWxlY3Rpb25TdGFydF07XG4gICAgdGhpcy5zZWxlY3RlZEtleXMuY2xlYXIoKTtcbiAgICB0aGlzLnNlbGVjdGVkS2V5cy5hZGQoa2V5KTtcblxuICAgIGNvbnN0IG1vdXNlVXBIYW5kbGVyID0gKCkgPT4ge1xuICAgICAgdGhpcy5lbmRTZWxlY3Rpb24oKTtcbiAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCBtb3VzZVVwSGFuZGxlcik7XG4gICAgfTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgbW91c2VVcEhhbmRsZXIpO1xuXG4gICAgdGhpcy51cGRhdGVTZWxlY3Rpb25Cb3VuZGFyaWVzKCk7XG4gIH1cblxuICBleHRlbmRTZWxlY3Rpb24ocm93OiBhbnksIGNvbHVtbjogYW55LCBzdWJDb2xJbmRleDogbnVtYmVyIHwgbnVsbCwgZXZlbnQ6IE1vdXNlRXZlbnQpIHtcbiAgICBpZiAoIXRoaXMuaXNTZWxlY3RpbmcgfHwgIXRoaXMuc2VsZWN0aW9uU3RhcnQpIHJldHVybjtcblxuICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5zZWxlY3Rpb25TdGFydCE7XG4gICAgY29uc3QgclN0YXJ0ID0gc3RhcnQucm93SW5kZXg7XG4gICAgY29uc3QgckVuZCA9IHJvdy5fX3ZpcnR1YWxJbmRleDtcbiAgICBjb25zdCBjU3RhcnQgPSBzdGFydC5jb2xJbmRleDtcbiAgICBjb25zdCBjRW5kID0gY29sdW1uLmluZGV4O1xuICAgIGNvbnN0IHNTdGFydCA9IHN0YXJ0LnN1YkNvbEluZGV4ID8/IDA7XG4gICAgY29uc3Qgc0VuZCA9IHN1YkNvbEluZGV4ID8/IDA7XG5cbiAgICBjb25zdCBtaW5Sb3cgPSBNYXRoLm1pbihyU3RhcnQsIHJFbmQpO1xuICAgIGNvbnN0IG1heFJvdyA9IE1hdGgubWF4KHJTdGFydCwgckVuZCk7XG4gICAgY29uc3QgbWluQ29sID0gTWF0aC5taW4oY1N0YXJ0LCBjRW5kKTtcbiAgICBjb25zdCBtYXhDb2wgPSBNYXRoLm1heChjU3RhcnQsIGNFbmQpO1xuXG4gICAgY29uc3QgbmV3S2V5czogU2V0PHN0cmluZz4gPSBuZXcgU2V0KCk7XG4gICAgY29uc3QgbmV3Q2VsbHM6IENlbGxQb3NbXSA9IFtdO1xuXG4gICAgZm9yIChsZXQgciA9IG1pblJvdzsgciA8PSBtYXhSb3c7IHIrKykge1xuICAgICAgZm9yIChsZXQgYyA9IG1pbkNvbDsgYyA8PSBtYXhDb2w7IGMrKykge1xuICAgICAgICBjb25zdCBjb2xPYmogPSB0aGlzLmdldENvbHVtbkJ5SW5kZXgoYyk7XG4gICAgICAgIGNvbnN0IHN1YkNvdW50ID0gY29sT2JqPy5jaGlsZHJlbj8ubGVuZ3RoID8/IDE7XG4gICAgICAgIGNvbnN0IHN0YXJ0U3ViID0gKGMgPT09IGNTdGFydCkgPyBzU3RhcnQgOiAwO1xuICAgICAgICBjb25zdCBlbmRTdWIgPSAoYyA9PT0gY0VuZCkgPyBzRW5kIDogc3ViQ291bnQgLSAxO1xuXG4gICAgICAgIGZvciAobGV0IHMgPSBzdGFydFN1YjsgcyA8PSBlbmRTdWI7IHMrKykge1xuICAgICAgICAgIGNvbnN0IGtleSA9IGAke3J9LSR7Y30tJHtzfWA7XG4gICAgICAgICAgbmV3S2V5cy5hZGQoa2V5KTtcbiAgICAgICAgICBuZXdDZWxscy5wdXNoKHsgcm93SW5kZXg6IHIsIGNvbEluZGV4OiBjLCBzdWJDb2xJbmRleDogcywgZmllbGQ6IGNvbE9iaj8uZmllbGQgfHwgJycsIGtleSB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuc2VsZWN0ZWRLZXlzID0gbmV3S2V5cztcbiAgICB0aGlzLnNlbGVjdGVkQ2VsbHMgPSBuZXdDZWxscztcbiAgICB0aGlzLnVwZGF0ZVNlbGVjdGlvbkJvdW5kYXJpZXMoKTtcblxuICAgIC8vIEF1dG8tc2Nyb2xsXG4gICAgdGhpcy5oYW5kbGVDZWxsQXV0b1Njcm9sbChldmVudCk7XG4gIH1cblxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tIEVORCBTRUxFQ1RJT04gLS0tLS0tLS0tLS0tLS0tLS0tLVxuICBlbmRTZWxlY3Rpb24oKSB7XG4gICAgdGhpcy5pc1NlbGVjdGluZyA9IGZhbHNlO1xuICAgIHRoaXMuc3RvcEF1dG9TY3JvbGwoKTtcbiAgICB0aGlzLnVwZGF0ZVNlbGVjdGlvbkJvdW5kYXJpZXMoKTtcbiAgfVxuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0gQVVUTy1TQ1JPTEwgLS0tLS0tLS0tLS0tLS0tLS0tLVxuICBoYW5kbGVDZWxsQXV0b1Njcm9sbChldmVudDogTW91c2VFdmVudCkge1xuICAgIGlmICh0aGlzLmNlbGxTZWxlY3Rpb25BdXRvU2Nyb2xsSW50ZXJ2YWwpIHtcbiAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5jZWxsU2VsZWN0aW9uQXV0b1Njcm9sbEludGVydmFsKTtcbiAgICAgIHRoaXMuY2VsbFNlbGVjdGlvbkF1dG9TY3JvbGxJbnRlcnZhbCA9IG51bGw7XG4gICAgfVxuICAgIGlmICghdGhpcy5ob3Jpem9udGFsQ29udGFpbmVyIHx8ICF0aGlzLnZlcnRpY2FsQ29udGFpbmVyKSByZXR1cm47XG5cbiAgICBjb25zdCBob3JSZWN0ID0gdGhpcy5ob3Jpem9udGFsQ29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IHZlcnRSZWN0ID0gdGhpcy52ZXJ0aWNhbENvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBjb25zdCBtb3VzZVggPSBldmVudC5jbGllbnRYO1xuICAgIGNvbnN0IG1vdXNlWSA9IGV2ZW50LmNsaWVudFk7XG5cbiAgICBsZXQgc2Nyb2xsWCA9IDA7XG4gICAgbGV0IHNjcm9sbFkgPSAwO1xuXG4gICAgaWYgKG1vdXNlWCAtIGhvclJlY3QubGVmdCA8IHRoaXMuc2Nyb2xsTWFyZ2luKSBzY3JvbGxYID0gLXRoaXMuc2Nyb2xsU3BlZWQ7XG4gICAgZWxzZSBpZiAoaG9yUmVjdC5yaWdodCAtIG1vdXNlWCA8IHRoaXMuc2Nyb2xsTWFyZ2luKSBzY3JvbGxYID0gdGhpcy5zY3JvbGxTcGVlZDtcblxuICAgIGlmIChtb3VzZVkgLSB2ZXJ0UmVjdC50b3AgPCB0aGlzLnNjcm9sbE1hcmdpbikgc2Nyb2xsWSA9IC10aGlzLnNjcm9sbFNwZWVkO1xuICAgIGVsc2UgaWYgKHZlcnRSZWN0LmJvdHRvbSAtIG1vdXNlWSA8IHRoaXMuc2Nyb2xsTWFyZ2luKSBzY3JvbGxZID0gdGhpcy5zY3JvbGxTcGVlZDtcblxuICAgIGlmIChzY3JvbGxYICE9PSAwIHx8IHNjcm9sbFkgIT09IDApIHtcbiAgICAgIHRoaXMuY2VsbFNlbGVjdGlvbkF1dG9TY3JvbGxJbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgaWYgKHNjcm9sbFggIT09IDApIHRoaXMuaG9yaXpvbnRhbENvbnRhaW5lciEuc2Nyb2xsQnkoc2Nyb2xsWCwgMCk7XG4gICAgICAgIGlmIChzY3JvbGxZICE9PSAwKSB0aGlzLnZlcnRpY2FsQ29udGFpbmVyIS5zY3JvbGxCeSgwLCBzY3JvbGxZKTtcbiAgICAgIH0sIDgpO1xuICAgIH1cbiAgfVxuXG4gIHN0b3BBdXRvU2Nyb2xsKCkge1xuICAgIGlmICh0aGlzLmNlbGxTZWxlY3Rpb25BdXRvU2Nyb2xsSW50ZXJ2YWwpIHtcbiAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5jZWxsU2VsZWN0aW9uQXV0b1Njcm9sbEludGVydmFsKTtcbiAgICAgIHRoaXMuY2VsbFNlbGVjdGlvbkF1dG9TY3JvbGxJbnRlcnZhbCA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLSBIRUxQRVJTIC0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgaXNTZWxlY3RlZChyb3dJbmRleDogbnVtYmVyLCBjb2xJbmRleDogbnVtYmVyLCBzdWJDb2xJbmRleD86IG51bWJlciB8IG51bGwpIHtcbiAgICBjb25zdCBzSW5kZXggPSBzdWJDb2xJbmRleCA/PyAwO1xuICAgIGNvbnN0IGtleSA9IGAke3Jvd0luZGV4fS0ke2NvbEluZGV4fS0ke3NJbmRleH1gO1xuICAgIHJldHVybiB0aGlzLnNlbGVjdGVkS2V5cy5oYXMoa2V5KTtcbiAgfVxuXG4gIHVwZGF0ZVNlbGVjdGlvbkJvdW5kYXJpZXMoKSB7XG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRDZWxscy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRoaXMuc2VsZWN0aW9uQm91bmRzID0geyB0b3A6IDAsIGJvdHRvbTogMCwgbGVmdDogbnVsbCwgcmlnaHQ6IG51bGwgfTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCByb3dJbmRpY2VzID0gdGhpcy5zZWxlY3RlZENlbGxzLm1hcChjID0+IGMucm93SW5kZXgpO1xuICAgIHRoaXMuc2VsZWN0aW9uQm91bmRzLnRvcCA9IE1hdGgubWluKC4uLnJvd0luZGljZXMpO1xuICAgIHRoaXMuc2VsZWN0aW9uQm91bmRzLmJvdHRvbSA9IE1hdGgubWF4KC4uLnJvd0luZGljZXMpO1xuXG4gICAgY29uc3QgbGVmdENvbCA9IE1hdGgubWluKC4uLnRoaXMuc2VsZWN0ZWRDZWxscy5tYXAoYyA9PiBjLmNvbEluZGV4KSk7XG4gICAgY29uc3QgbGVmdENlbGxzID0gdGhpcy5zZWxlY3RlZENlbGxzLmZpbHRlcihjID0+IGMuY29sSW5kZXggPT09IGxlZnRDb2wpO1xuICAgIGNvbnN0IG1pblN1YiA9IE1hdGgubWluKC4uLmxlZnRDZWxscy5tYXAoYyA9PiBjLnN1YkNvbEluZGV4ID8/IDApKTtcbiAgICB0aGlzLnNlbGVjdGlvbkJvdW5kcy5sZWZ0ID0geyBjb2xJbmRleDogbGVmdENvbCwgc3ViQ29sSW5kZXg6IG1pblN1YiB9O1xuXG4gICAgY29uc3QgcmlnaHRDb2wgPSBNYXRoLm1heCguLi50aGlzLnNlbGVjdGVkQ2VsbHMubWFwKGMgPT4gYy5jb2xJbmRleCkpO1xuICAgIGNvbnN0IHJpZ2h0Q2VsbHMgPSB0aGlzLnNlbGVjdGVkQ2VsbHMuZmlsdGVyKGMgPT4gYy5jb2xJbmRleCA9PT0gcmlnaHRDb2wpO1xuICAgIGNvbnN0IG1heFN1YiA9IE1hdGgubWF4KC4uLnJpZ2h0Q2VsbHMubWFwKGMgPT4gYy5zdWJDb2xJbmRleCA/PyAwKSk7XG4gICAgdGhpcy5zZWxlY3Rpb25Cb3VuZHMucmlnaHQgPSB7IGNvbEluZGV4OiByaWdodENvbCwgc3ViQ29sSW5kZXg6IG1heFN1YiB9O1xuICB9XG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLSBCT1JERVIgQ0hFQ0tTIC0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgaXNUb3BCb3JkZXIocm93SW5kZXg6IG51bWJlciwgY29sSW5kZXg6IG51bWJlciwgc3ViQ29sSW5kZXg/OiBudW1iZXIpIHtcbiAgICByZXR1cm4gdGhpcy5pc1NlbGVjdGVkKHJvd0luZGV4LCBjb2xJbmRleCwgc3ViQ29sSW5kZXgpICYmIHJvd0luZGV4ID09PSB0aGlzLnNlbGVjdGlvbkJvdW5kcy50b3A7XG4gIH1cbiAgaXNCb3R0b21Cb3JkZXIocm93SW5kZXg6IG51bWJlciwgY29sSW5kZXg6IG51bWJlciwgc3ViQ29sSW5kZXg/OiBudW1iZXIpIHtcbiAgICByZXR1cm4gdGhpcy5pc1NlbGVjdGVkKHJvd0luZGV4LCBjb2xJbmRleCwgc3ViQ29sSW5kZXgpICYmIHJvd0luZGV4ID09PSB0aGlzLnNlbGVjdGlvbkJvdW5kcy5ib3R0b207XG4gIH1cbiAgaXNMZWZ0Qm9yZGVyKHJvd0luZGV4OiBudW1iZXIsIGNvbEluZGV4OiBudW1iZXIsIHN1YkNvbEluZGV4PzogbnVtYmVyKSB7XG4gICAgaWYgKCF0aGlzLnNlbGVjdGlvbkJvdW5kcy5sZWZ0KSByZXR1cm4gZmFsc2U7XG4gICAgY29uc3Qgc0luZGV4ID0gc3ViQ29sSW5kZXggPz8gMDtcbiAgICByZXR1cm4gdGhpcy5pc1NlbGVjdGVkKHJvd0luZGV4LCBjb2xJbmRleCwgc3ViQ29sSW5kZXgpICYmXG4gICAgICBjb2xJbmRleCA9PT0gdGhpcy5zZWxlY3Rpb25Cb3VuZHMubGVmdC5jb2xJbmRleCAmJlxuICAgICAgc0luZGV4ID09PSB0aGlzLnNlbGVjdGlvbkJvdW5kcy5sZWZ0LnN1YkNvbEluZGV4O1xuICB9XG4gIGlzUmlnaHRCb3JkZXIocm93SW5kZXg6IG51bWJlciwgY29sSW5kZXg6IG51bWJlciwgc3ViQ29sSW5kZXg/OiBudW1iZXIpIHtcbiAgICBpZiAoIXRoaXMuc2VsZWN0aW9uQm91bmRzLnJpZ2h0KSByZXR1cm4gZmFsc2U7XG4gICAgY29uc3Qgc0luZGV4ID0gc3ViQ29sSW5kZXggPz8gMDtcbiAgICByZXR1cm4gdGhpcy5pc1NlbGVjdGVkKHJvd0luZGV4LCBjb2xJbmRleCwgc3ViQ29sSW5kZXgpICYmXG4gICAgICBjb2xJbmRleCA9PT0gdGhpcy5zZWxlY3Rpb25Cb3VuZHMucmlnaHQuY29sSW5kZXggJiZcbiAgICAgIHNJbmRleCA9PT0gdGhpcy5zZWxlY3Rpb25Cb3VuZHMucmlnaHQuc3ViQ29sSW5kZXg7XG4gIH1cbiAgaXNUb3BMZWZ0Q29ybmVyKHJvd0luZGV4OiBudW1iZXIsIGNvbEluZGV4OiBudW1iZXIsIHN1YkNvbEluZGV4PzogbnVtYmVyKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNUb3BCb3JkZXIocm93SW5kZXgsIGNvbEluZGV4LCBzdWJDb2xJbmRleCkgJiYgdGhpcy5pc0xlZnRCb3JkZXIocm93SW5kZXgsIGNvbEluZGV4LCBzdWJDb2xJbmRleCk7XG4gIH1cbiAgaXNUb3BSaWdodENvcm5lcihyb3dJbmRleDogbnVtYmVyLCBjb2xJbmRleDogbnVtYmVyLCBzdWJDb2xJbmRleD86IG51bWJlcikge1xuICAgIHJldHVybiB0aGlzLmlzVG9wQm9yZGVyKHJvd0luZGV4LCBjb2xJbmRleCwgc3ViQ29sSW5kZXgpICYmIHRoaXMuaXNSaWdodEJvcmRlcihyb3dJbmRleCwgY29sSW5kZXgsIHN1YkNvbEluZGV4KTtcbiAgfVxuICBpc0JvdHRvbUxlZnRDb3JuZXIocm93SW5kZXg6IG51bWJlciwgY29sSW5kZXg6IG51bWJlciwgc3ViQ29sSW5kZXg/OiBudW1iZXIpIHtcbiAgICByZXR1cm4gdGhpcy5pc0JvdHRvbUJvcmRlcihyb3dJbmRleCwgY29sSW5kZXgsIHN1YkNvbEluZGV4KSAmJiB0aGlzLmlzTGVmdEJvcmRlcihyb3dJbmRleCwgY29sSW5kZXgsIHN1YkNvbEluZGV4KTtcbiAgfVxuICBpc0JvdHRvbVJpZ2h0Q29ybmVyKHJvd0luZGV4OiBudW1iZXIsIGNvbEluZGV4OiBudW1iZXIsIHN1YkNvbEluZGV4PzogbnVtYmVyKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNCb3R0b21Cb3JkZXIocm93SW5kZXgsIGNvbEluZGV4LCBzdWJDb2xJbmRleCkgJiYgdGhpcy5pc1JpZ2h0Qm9yZGVyKHJvd0luZGV4LCBjb2xJbmRleCwgc3ViQ29sSW5kZXgpO1xuICB9XG5cblxuICBzZXRBY3RpdmVDZWxsKHJvd0luZGV4OiBudW1iZXIsIGNvbEluZGV4OiBudW1iZXIsIHN1YkNvbEluZGV4PzogbnVtYmVyKSB7XG4gICAgY29uc3Qgc0luZGV4ID0gc3ViQ29sSW5kZXggPz8gMDtcbiAgICB0aGlzLmFjdGl2ZUNlbGwgPSB7IHJvd0luZGV4LCBjb2xJbmRleCwgc3ViQ29sSW5kZXg6IHNJbmRleCwga2V5OiBgJHtyb3dJbmRleH0tJHtjb2xJbmRleH0tJHtzSW5kZXh9YCwgZmllbGQ6ICcnIH07XG4gIH1cblxuICBpc0FjdGl2ZUNlbGwocm93SW5kZXg6IG51bWJlciwgY29sSW5kZXg6IG51bWJlciwgc3ViQ29sSW5kZXg/OiBudW1iZXIpIHtcbiAgICBpZiAoIXRoaXMuYWN0aXZlQ2VsbCkgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IHNJbmRleCA9IHN1YkNvbEluZGV4ID8/IDA7XG4gICAgcmV0dXJuIHRoaXMuYWN0aXZlQ2VsbC5yb3dJbmRleCA9PT0gcm93SW5kZXggJiYgdGhpcy5hY3RpdmVDZWxsLmNvbEluZGV4ID09PSBjb2xJbmRleCAmJiB0aGlzLmFjdGl2ZUNlbGwuc3ViQ29sSW5kZXggPT09IHNJbmRleDtcbiAgfVxuXG4gIHNlbGVjdEFsbENlbGxzKGRhdGFTZXQ6IGFueVtdLCBjb2x1bW5zOiBhbnlbXSkge1xuICAgIGlmICghZGF0YVNldD8ubGVuZ3RoIHx8ICFjb2x1bW5zPy5sZW5ndGgpIHJldHVybjtcblxuICAgIHRoaXMuc2VsZWN0ZWRDZWxscyA9IFtdO1xuICAgIHRoaXMuc2VsZWN0ZWRLZXlzLmNsZWFyKCk7XG4gICAgdGhpcy5zZWxlY3Rpb25TdGFydCA9IG51bGw7XG4gICAgdGhpcy5pc1NlbGVjdGluZyA9IHRydWU7XG5cbiAgICBmb3IgKGNvbnN0IHJvdyBvZiBkYXRhU2V0KSB7XG4gICAgICBjb25zdCBySW5kZXggPSByb3cuX192aXJ0dWFsSW5kZXg7XG4gICAgICBmb3IgKGxldCBjID0gMDsgYyA8IGNvbHVtbnMubGVuZ3RoOyBjKyspIHtcbiAgICAgICAgY29uc3QgY29sID0gY29sdW1uc1tjXTtcbiAgICAgICAgaWYgKGNvbC5pc192aXNpYmxlID09PSBmYWxzZSkgY29udGludWU7XG5cbiAgICAgICAgY29uc3QgZmllbGQgPSBjb2wuZmllbGQgfHwgY29sLm5hbWU7XG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoY29sLmNoaWxkcmVuKSAmJiBjb2wuY2hpbGRyZW4ubGVuZ3RoKSB7XG4gICAgICAgICAgY29sLmNoaWxkcmVuLmZvckVhY2goKHN1YkNvbDogYW55LCBzOiBudW1iZXIpID0+IHtcbiAgICAgICAgICAgIGlmIChzdWJDb2wuaXNfdmlzaWJsZSA9PT0gZmFsc2UpIHJldHVybjtcblxuICAgICAgICAgICAgY29uc3Qga2V5ID0gYCR7ckluZGV4fS0ke2N9LSR7c31gO1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZEtleXMuYWRkKGtleSk7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkQ2VsbHMucHVzaCh7XG4gICAgICAgICAgICAgIHJvd0luZGV4OiBySW5kZXgsXG4gICAgICAgICAgICAgIGNvbEluZGV4OiBjLFxuICAgICAgICAgICAgICBzdWJDb2xJbmRleDogcyxcbiAgICAgICAgICAgICAgZmllbGQsXG4gICAgICAgICAgICAgIGtleVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3Qga2V5ID0gYCR7ckluZGV4fS0ke2N9LTBgO1xuICAgICAgICAgIHRoaXMuc2VsZWN0ZWRLZXlzLmFkZChrZXkpO1xuICAgICAgICAgIHRoaXMuc2VsZWN0ZWRDZWxscy5wdXNoKHtcbiAgICAgICAgICAgIHJvd0luZGV4OiBySW5kZXgsXG4gICAgICAgICAgICBjb2xJbmRleDogYyxcbiAgICAgICAgICAgIHN1YkNvbEluZGV4OiAwLFxuICAgICAgICAgICAgZmllbGQsXG4gICAgICAgICAgICBrZXlcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuaXNTZWxlY3RpbmcgPSBmYWxzZTtcbiAgICB0aGlzLnNlbGVjdGlvblN0YXJ0ID0gdGhpcy5zZWxlY3RlZENlbGxzWzBdID8/IG51bGw7XG4gICAgdGhpcy51cGRhdGVTZWxlY3Rpb25Cb3VuZGFyaWVzKCk7XG4gIH1cblxuXG5cbiAgbW92ZUFjdGl2ZUNlbGwoXG4gICAgZGlyZWN0aW9uOiAndXAnIHwgJ2Rvd24nIHwgJ2xlZnQnIHwgJ3JpZ2h0JyxcbiAgICBzaGlmdEtleTogYm9vbGVhbixcbiAgICBkYXRhU2V0OiBhbnlbXSxcbiAgICBjb2x1bW5zOiBhbnlbXVxuICApIHtcbiAgICBpZiAoIXRoaXMuYWN0aXZlQ2VsbCkgcmV0dXJuO1xuXG4gICAgbGV0IHsgcm93SW5kZXgsIGNvbEluZGV4LCBzdWJDb2xJbmRleCA9IDAgfSA9IHRoaXMuYWN0aXZlQ2VsbDtcbiAgICBjb25zdCBjb2wgPSB0aGlzLmdldENvbHVtbkJ5SW5kZXgoY29sSW5kZXgpO1xuXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gQWRqdXN0IGZvciAxLWJhc2VkIHZpcnR1YWwgaW5kZXhcbiAgICBjb25zdCBtaW5Sb3cgPSAxOyAgICAgICAgICAgICAgIC8vIGZpcnN0IHJvdyBfX3ZpcnR1YWxJbmRleFxuICAgIGNvbnN0IG1heFJvdyA9IGRhdGFTZXQubGVuZ3RoOyAgLy8gbGFzdCByb3cgX192aXJ0dWFsSW5kZXhcbiAgICBjb25zdCBtYXhDb2wgPSBjb2x1bW5zLmxlbmd0aCAtIDE7XG5cbiAgICAvLyBDb21wdXRlIG5ldyBpbmRpY2VzXG4gICAgc3dpdGNoIChkaXJlY3Rpb24pIHtcbiAgICAgIGNhc2UgJ3VwJzpcbiAgICAgICAgcm93SW5kZXggPSBNYXRoLm1heChtaW5Sb3csIHJvd0luZGV4IC0gMSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnZG93bic6XG4gICAgICAgIHJvd0luZGV4ID0gTWF0aC5taW4obWF4Um93LCByb3dJbmRleCArIDEpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2xlZnQnOiB7XG4gICAgICAgIC8vIDHvuI/ig6MgTW92ZSBpbnNpZGUgc3ViLWNvbHVtbnNcbiAgICAgICAgaWYgKHN1YkNvbEluZGV4ID4gMCkge1xuICAgICAgICAgIHN1YkNvbEluZGV4IC09IDE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICAvLyAy77iP4oOjIEZpbmQgcHJldmlvdXMgdmlzaWJsZSBjb2x1bW5cbiAgICAgICAgY29uc3QgcHJldkNvbCA9IHRoaXMuZmluZFByZXZWaXNpYmxlQ29sKGNvbEluZGV4KTtcbiAgICAgICAgaWYgKHByZXZDb2wgIT09IG51bGwpIHtcbiAgICAgICAgICBjb2xJbmRleCA9IHByZXZDb2w7XG4gICAgICAgICAgY29uc3QgcENvbCA9IHRoaXMuZ2V0Q29sdW1uQnlJbmRleChjb2xJbmRleCk7XG4gICAgICAgICAgc3ViQ29sSW5kZXggPSBwQ29sPy5jaGlsZHJlbj8ubGVuZ3RoXG4gICAgICAgICAgICA/IHBDb2wuY2hpbGRyZW4ubGVuZ3RoIC0gMVxuICAgICAgICAgICAgOiAwO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gM++4j+KDoyBTdGFydCBvZiByb3cg4oaSIHByZXZpb3VzIHJvdyBsYXN0IHZpc2libGUgY29sdW1uXG4gICAgICAgIGlmIChyb3dJbmRleCA+IG1pblJvdykge1xuICAgICAgICAgIHJvd0luZGV4IC09IDE7XG4gICAgICAgICAgY29uc3QgbGFzdFZpc2libGUgPSB0aGlzLmZpbmRQcmV2VmlzaWJsZUNvbChtYXhDb2wgKyAxKTtcbiAgICAgICAgICBpZiAobGFzdFZpc2libGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbEluZGV4ID0gbGFzdFZpc2libGU7XG4gICAgICAgICAgICBjb25zdCBsQ29sID0gdGhpcy5nZXRDb2x1bW5CeUluZGV4KGNvbEluZGV4KTtcbiAgICAgICAgICAgIHN1YkNvbEluZGV4ID0gbENvbD8uY2hpbGRyZW4/Lmxlbmd0aFxuICAgICAgICAgICAgICA/IGxDb2wuY2hpbGRyZW4ubGVuZ3RoIC0gMVxuICAgICAgICAgICAgICA6IDA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cblxuICAgICAgY2FzZSAncmlnaHQnOiB7XG4gICAgICAgIGNvbnN0IG1heFN1YiA9IGNvbD8uY2hpbGRyZW4/Lmxlbmd0aCA/IGNvbC5jaGlsZHJlbi5sZW5ndGggLSAxIDogMDtcblxuICAgICAgICAvLyAx77iP4oOjIE1vdmUgaW5zaWRlIHN1Yi1jb2x1bW5zXG4gICAgICAgIGlmIChzdWJDb2xJbmRleCA8IG1heFN1Yikge1xuICAgICAgICAgIHN1YkNvbEluZGV4ICs9IDE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICAvLyAy77iP4oOjIEZpbmQgbmV4dCB2aXNpYmxlIGNvbHVtblxuICAgICAgICBjb25zdCBuZXh0Q29sID0gdGhpcy5maW5kTmV4dFZpc2libGVDb2woY29sSW5kZXgsIG1heENvbCk7XG4gICAgICAgIGlmIChuZXh0Q29sICE9PSBudWxsKSB7XG4gICAgICAgICAgY29sSW5kZXggPSBuZXh0Q29sO1xuICAgICAgICAgIHN1YkNvbEluZGV4ID0gMDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIDPvuI/ig6MgRW5kIG9mIHJvdyDihpIgbmV4dCByb3cgZmlyc3QgdmlzaWJsZSBjb2x1bW5cbiAgICAgICAgaWYgKHJvd0luZGV4IDwgbWF4Um93KSB7XG4gICAgICAgICAgcm93SW5kZXggKz0gMTtcbiAgICAgICAgICBjb25zdCBmaXJzdFZpc2libGUgPSB0aGlzLmZpbmROZXh0VmlzaWJsZUNvbCgtMSwgbWF4Q29sKTtcbiAgICAgICAgICBpZiAoZmlyc3RWaXNpYmxlICE9PSBudWxsKSB7XG4gICAgICAgICAgICBjb2xJbmRleCA9IGZpcnN0VmlzaWJsZTtcbiAgICAgICAgICAgIHN1YkNvbEluZGV4ID0gMDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBzdWJDb2xJbmRleCA9IHN1YkNvbEluZGV4ID8/IDA7XG5cbiAgICAvLyBTZXQgYWN0aXZlIGNlbGxcbiAgICBjb25zdCBhY3RpdmU6IENlbGxQb3MgPSB7XG4gICAgICByb3dJbmRleCxcbiAgICAgIGNvbEluZGV4LFxuICAgICAgc3ViQ29sSW5kZXgsXG4gICAgICBrZXk6IGAke3Jvd0luZGV4fS0ke2NvbEluZGV4fS0ke3N1YkNvbEluZGV4fWAsXG4gICAgICBmaWVsZDogY29sdW1uc1tjb2xJbmRleF0/LmZpZWxkIHx8ICcnXG4gICAgfTtcbiAgICB0aGlzLnNldEFjdGl2ZUNlbGwocm93SW5kZXgsIGNvbEluZGV4LCBzdWJDb2xJbmRleCk7XG5cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBBbHdheXMgY29weSBhY3RpdmUgY2VsbCBpbnRvIHNlbGVjdGlvbiBpZiBTaGlmdCBub3QgcHJlc3NlZFxuICAgIGlmICghc2hpZnRLZXkpIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRDZWxscyA9IFthY3RpdmVdO1xuICAgICAgdGhpcy5zZWxlY3RlZEtleXMgPSBuZXcgU2V0KFthY3RpdmUua2V5XSk7XG4gICAgICB0aGlzLnNlbGVjdGlvblN0YXJ0ID0geyAuLi5hY3RpdmUgfTtcbiAgICAgIHRoaXMudXBkYXRlU2VsZWN0aW9uQm91bmRhcmllcygpO1xuICAgIH1cblxuICAgIC8vIEV4dGVuZCBzZWxlY3Rpb24gaWYgU2hpZnQgcHJlc3NlZFxuICAgIGlmIChzaGlmdEtleSkge1xuICAgICAgaWYgKCF0aGlzLnNlbGVjdGlvblN0YXJ0KSB7XG4gICAgICAgIHRoaXMuc2VsZWN0aW9uU3RhcnQgPSB7IC4uLnRoaXMuYWN0aXZlQ2VsbCEgfTtcbiAgICAgIH1cblxuICAgICAgLy8g8J+UpSBDVFJMICsgU0hJRlQg4oaSIGV4dGVuZCB0byBlZGdlXG4gICAgICBpZiAodGhpcy5jdHJsS2V5UHJlc3NlZCkge1xuICAgICAgICBjb25zdCBlZGdlQ2VsbCA9IHRoaXMuZ2V0RWRnZUNlbGwoXG4gICAgICAgICAgZGlyZWN0aW9uLFxuICAgICAgICAgIGRhdGFTZXQsXG4gICAgICAgICAgY29sdW1ucyxcbiAgICAgICAgICB0aGlzLmFjdGl2ZUNlbGwhXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5zZXRBY3RpdmVDZWxsKFxuICAgICAgICAgIGVkZ2VDZWxsLnJvd0luZGV4LFxuICAgICAgICAgIGVkZ2VDZWxsLmNvbEluZGV4LFxuICAgICAgICAgIGVkZ2VDZWxsLnN1YkNvbEluZGV4XG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5leHRlbmRTZWxlY3Rpb25CeUtleWJvYXJkKGVkZ2VDZWxsKTtcblxuICAgICAgICB0aGlzLnNjcm9sbENlbGxJbnRvVmlld0ltbWVkaWF0ZShcbiAgICAgICAgICBlZGdlQ2VsbC5yb3dJbmRleCxcbiAgICAgICAgICBlZGdlQ2VsbC5jb2xJbmRleFxuICAgICAgICApO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gTm9ybWFsIFNoaWZ0ICsgQXJyb3dcbiAgICAgIHRoaXMuZXh0ZW5kU2VsZWN0aW9uQnlLZXlib2FyZChhY3RpdmUpO1xuICAgIH1cblxuXG5cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBTY3JvbGwgdG8ga2VlcCBhY3RpdmUgY2VsbCBpbiB2aWV3XG4gICAgY29uc3QgY2VsbCA9IHRoaXMudmVydGljYWxDb250YWluZXI/LnF1ZXJ5U2VsZWN0b3IoYFtsb2NhdGlvbj0nJHtyb3dJbmRleH0tJHtjb2xJbmRleH0nXWApIGFzIEhUTUxFbGVtZW50O1xuICAgIGlmICghY2VsbCB8fCAhdGhpcy52ZXJ0aWNhbENvbnRhaW5lciB8fCAhdGhpcy5ob3Jpem9udGFsQ29udGFpbmVyKSByZXR1cm47XG5cbiAgICBjb25zdCB2ZXJ0UmVjdCA9IHRoaXMudmVydGljYWxDb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgY29uc3QgaG9yUmVjdCA9IHRoaXMuaG9yaXpvbnRhbENvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBjb25zdCBjZWxsUmVjdCA9IGNlbGwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgY29uc3Qgc2Nyb2xsTWFyZ2luID0gNTtcblxuICAgIC8vIFZlcnRpY2FsIHNjcm9sbFxuICAgIGlmIChjZWxsUmVjdC5ib3R0b20gPiB2ZXJ0UmVjdC5ib3R0b20pIHtcbiAgICAgIHRoaXMudmVydGljYWxDb250YWluZXIuc2Nyb2xsQnkoeyB0b3A6IGNlbGxSZWN0LmJvdHRvbSAtIHZlcnRSZWN0LmJvdHRvbSArIHNjcm9sbE1hcmdpbiwgYmVoYXZpb3I6ICdhdXRvJyB9KTtcbiAgICB9IGVsc2UgaWYgKGNlbGxSZWN0LnRvcCA8IHZlcnRSZWN0LnRvcCkge1xuICAgICAgdGhpcy52ZXJ0aWNhbENvbnRhaW5lci5zY3JvbGxCeSh7IHRvcDogY2VsbFJlY3QudG9wIC0gdmVydFJlY3QudG9wIC0gc2Nyb2xsTWFyZ2luLCBiZWhhdmlvcjogJ2F1dG8nIH0pO1xuICAgIH1cblxuICAgIC8vIEhvcml6b250YWwgc2Nyb2xsXG4gICAgaWYgKGNlbGxSZWN0LnJpZ2h0ID4gaG9yUmVjdC5yaWdodCkge1xuICAgICAgdGhpcy5ob3Jpem9udGFsQ29udGFpbmVyLnNjcm9sbEJ5KHsgbGVmdDogY2VsbFJlY3QucmlnaHQgLSBob3JSZWN0LnJpZ2h0ICsgc2Nyb2xsTWFyZ2luLCBiZWhhdmlvcjogJ2F1dG8nIH0pO1xuICAgIH0gZWxzZSBpZiAoY2VsbFJlY3QubGVmdCA8IGhvclJlY3QubGVmdCkge1xuICAgICAgdGhpcy5ob3Jpem9udGFsQ29udGFpbmVyLnNjcm9sbEJ5KHsgbGVmdDogY2VsbFJlY3QubGVmdCAtIGhvclJlY3QubGVmdCAtIHNjcm9sbE1hcmdpbiwgYmVoYXZpb3I6ICdhdXRvJyB9KTtcbiAgICB9XG4gIH1cblxuICBjdHJsS2V5UHJlc3NlZCA9IGZhbHNlO1xuXG4gIHByaXZhdGUgaXNDb2x1bW5WaXNpYmxlKGNvbEluZGV4OiBudW1iZXIpOiBib29sZWFuIHtcbiAgICBjb25zdCBjb2wgPSB0aGlzLmdldENvbHVtbkJ5SW5kZXgoY29sSW5kZXgpO1xuICAgIGlmICghY29sKSByZXR1cm4gZmFsc2U7XG5cbiAgICAvLyBQYXJlbnQgdmlzaWJsZSBPUiBhbnkgY2hpbGQgdmlzaWJsZVxuICAgIGlmIChBcnJheS5pc0FycmF5KGNvbC5jaGlsZHJlbikpIHtcbiAgICAgIHJldHVybiBjb2wuY2hpbGRyZW4uc29tZSgoYzogYW55KSA9PiBjLmlzX3Zpc2libGUgIT09IGZhbHNlKTtcbiAgICB9XG4gICAgcmV0dXJuIGNvbC5pc192aXNpYmxlICE9PSBmYWxzZTtcbiAgfVxuXG4gIHByaXZhdGUgZmluZE5leHRWaXNpYmxlQ29sKHN0YXJ0OiBudW1iZXIsIG1heENvbDogbnVtYmVyKTogbnVtYmVyIHwgbnVsbCB7XG4gICAgZm9yIChsZXQgaSA9IHN0YXJ0ICsgMTsgaSA8PSBtYXhDb2w7IGkrKykge1xuICAgICAgaWYgKHRoaXMuaXNDb2x1bW5WaXNpYmxlKGkpKSByZXR1cm4gaTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBwcml2YXRlIGZpbmRQcmV2VmlzaWJsZUNvbChzdGFydDogbnVtYmVyKTogbnVtYmVyIHwgbnVsbCB7XG4gICAgZm9yIChsZXQgaSA9IHN0YXJ0IC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGlmICh0aGlzLmlzQ29sdW1uVmlzaWJsZShpKSkgcmV0dXJuIGk7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cblxuXG5cbiAgc2Nyb2xsQWN0aXZlQ2VsbEludG9WaWV3KHJvd0luZGV4OiBudW1iZXIsIGNvbEluZGV4OiBudW1iZXIpIHtcbiAgICBpZiAoIXRoaXMudmVydGljYWxDb250YWluZXIgfHwgIXRoaXMuaG9yaXpvbnRhbENvbnRhaW5lcikgcmV0dXJuO1xuXG4gICAgY29uc3Qgcm93RWwgPSB0aGlzLnZlcnRpY2FsQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoYFtsb2NhdGlvbj0nJHtyb3dJbmRleH0tJHtjb2xJbmRleH0nXWApIGFzIEhUTUxFbGVtZW50O1xuICAgIGlmICghcm93RWwpIHJldHVybjtcblxuICAgIGNvbnN0IHJvd1JlY3QgPSByb3dFbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBjb25zdCB2ZXJ0UmVjdCA9IHRoaXMudmVydGljYWxDb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgY29uc3QgaG9yUmVjdCA9IHRoaXMuaG9yaXpvbnRhbENvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgIC8vIFZlcnRpY2FsIHNjcm9sbFxuICAgIGlmIChyb3dSZWN0LmJvdHRvbSA+IHZlcnRSZWN0LmJvdHRvbSkge1xuICAgICAgdGhpcy52ZXJ0aWNhbENvbnRhaW5lci5zY3JvbGxCeSh7IHRvcDogcm93UmVjdC5ib3R0b20gLSB2ZXJ0UmVjdC5ib3R0b20gKyA1LCBiZWhhdmlvcjogJ3Ntb290aCcgfSk7XG4gICAgfSBlbHNlIGlmIChyb3dSZWN0LnRvcCA8IHZlcnRSZWN0LnRvcCkge1xuICAgICAgdGhpcy52ZXJ0aWNhbENvbnRhaW5lci5zY3JvbGxCeSh7IHRvcDogcm93UmVjdC50b3AgLSB2ZXJ0UmVjdC50b3AgLSA1LCBiZWhhdmlvcjogJ3Ntb290aCcgfSk7XG4gICAgfVxuXG4gICAgLy8gSG9yaXpvbnRhbCBzY3JvbGxcbiAgICBpZiAocm93UmVjdC5yaWdodCA+IGhvclJlY3QucmlnaHQpIHtcbiAgICAgIHRoaXMuaG9yaXpvbnRhbENvbnRhaW5lci5zY3JvbGxCeSh7IGxlZnQ6IHJvd1JlY3QucmlnaHQgLSBob3JSZWN0LnJpZ2h0ICsgNSwgYmVoYXZpb3I6ICdzbW9vdGgnIH0pO1xuICAgIH0gZWxzZSBpZiAocm93UmVjdC5sZWZ0IDwgaG9yUmVjdC5sZWZ0KSB7XG4gICAgICB0aGlzLmhvcml6b250YWxDb250YWluZXIuc2Nyb2xsQnkoeyBsZWZ0OiByb3dSZWN0LmxlZnQgLSBob3JSZWN0LmxlZnQgLSA1LCBiZWhhdmlvcjogJ3Ntb290aCcgfSk7XG4gICAgfVxuICB9XG5cblxuICBleHRlbmRTZWxlY3Rpb25CeUtleWJvYXJkKHRhcmdldDogQ2VsbFBvcykge1xuICAgIGlmICghdGhpcy5zZWxlY3Rpb25TdGFydCkge1xuICAgICAgdGhpcy5zZWxlY3Rpb25TdGFydCA9IHsgLi4udGFyZ2V0IH07XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgc3RhcnQgPSB0aGlzLnNlbGVjdGlvblN0YXJ0O1xuXG4gICAgY29uc3QgbWluUm93ID0gTWF0aC5taW4oc3RhcnQucm93SW5kZXgsIHRhcmdldC5yb3dJbmRleCk7XG4gICAgY29uc3QgbWF4Um93ID0gTWF0aC5tYXgoc3RhcnQucm93SW5kZXgsIHRhcmdldC5yb3dJbmRleCk7XG5cbiAgICBjb25zdCBtaW5Db2wgPSBNYXRoLm1pbihzdGFydC5jb2xJbmRleCwgdGFyZ2V0LmNvbEluZGV4KTtcbiAgICBjb25zdCBtYXhDb2wgPSBNYXRoLm1heChzdGFydC5jb2xJbmRleCwgdGFyZ2V0LmNvbEluZGV4KTtcblxuICAgIGNvbnN0IG5ld0tleXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBjb25zdCBuZXdDZWxsczogQ2VsbFBvc1tdID0gW107XG5cbiAgICBmb3IgKGxldCByID0gbWluUm93OyByIDw9IG1heFJvdzsgcisrKSB7XG4gICAgICBmb3IgKGxldCBjID0gbWluQ29sOyBjIDw9IG1heENvbDsgYysrKSB7XG4gICAgICAgIGNvbnN0IGNvbE9iaiA9IHRoaXMuZ2V0Q29sdW1uQnlJbmRleChjKTtcbiAgICAgICAgaWYgKCFjb2xPYmopIGNvbnRpbnVlO1xuXG4gICAgICAgIGNvbnN0IHN1YkNvdW50ID0gY29sT2JqLmNoaWxkcmVuPy5sZW5ndGggPz8gMTtcblxuICAgICAgICBjb25zdCBzdGFydFN1YiA9XG4gICAgICAgICAgYyA9PT0gc3RhcnQuY29sSW5kZXggPyBzdGFydC5zdWJDb2xJbmRleCA6IDA7XG4gICAgICAgIGNvbnN0IGVuZFN1YiA9XG4gICAgICAgICAgYyA9PT0gdGFyZ2V0LmNvbEluZGV4ID8gdGFyZ2V0LnN1YkNvbEluZGV4IDogc3ViQ291bnQgLSAxO1xuXG4gICAgICAgIGZvciAobGV0IHMgPSBzdGFydFN1YjsgcyA8PSBlbmRTdWI7IHMrKykge1xuICAgICAgICAgIGNvbnN0IGtleSA9IGAke3J9LSR7Y30tJHtzfWA7XG4gICAgICAgICAgbmV3S2V5cy5hZGQoa2V5KTtcbiAgICAgICAgICBuZXdDZWxscy5wdXNoKHtcbiAgICAgICAgICAgIHJvd0luZGV4OiByLFxuICAgICAgICAgICAgY29sSW5kZXg6IGMsXG4gICAgICAgICAgICBzdWJDb2xJbmRleDogcyxcbiAgICAgICAgICAgIGZpZWxkOiBjb2xPYmouZmllbGQgfHwgJycsXG4gICAgICAgICAgICBrZXlcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuc2VsZWN0ZWRLZXlzID0gbmV3S2V5cztcbiAgICB0aGlzLnNlbGVjdGVkQ2VsbHMgPSBuZXdDZWxscztcbiAgICB0aGlzLnVwZGF0ZVNlbGVjdGlvbkJvdW5kYXJpZXMoKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0RWRnZUNlbGwoXG4gICAgZGlyZWN0aW9uOiAndXAnIHwgJ2Rvd24nIHwgJ2xlZnQnIHwgJ3JpZ2h0JyxcbiAgICBkYXRhU2V0OiBhbnlbXSxcbiAgICBjb2x1bW5zOiBhbnlbXSxcbiAgICBmcm9tOiBDZWxsUG9zXG4gICk6IENlbGxQb3Mge1xuICAgIGNvbnN0IG1pblJvdyA9IDE7XG4gICAgY29uc3QgbWF4Um93ID0gZGF0YVNldC5sZW5ndGg7XG4gICAgY29uc3QgbWF4Q29sID0gY29sdW1ucy5sZW5ndGggLSAxO1xuXG4gICAgbGV0IHsgcm93SW5kZXgsIGNvbEluZGV4LCBzdWJDb2xJbmRleCB9ID0gZnJvbTtcblxuICAgIHN3aXRjaCAoZGlyZWN0aW9uKSB7XG4gICAgICBjYXNlICd1cCc6XG4gICAgICAgIHJvd0luZGV4ID0gbWluUm93O1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnZG93bic6XG4gICAgICAgIHJvd0luZGV4ID0gbWF4Um93O1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnbGVmdCc6IHtcbiAgICAgICAgY29uc3QgZmlyc3RWaXNpYmxlID0gdGhpcy5maW5kTmV4dFZpc2libGVDb2woLTEsIG1heENvbCk7XG4gICAgICAgIGlmIChmaXJzdFZpc2libGUgIT09IG51bGwpIHtcbiAgICAgICAgICBjb2xJbmRleCA9IGZpcnN0VmlzaWJsZTtcbiAgICAgICAgICBjb25zdCBjb2wgPSB0aGlzLmdldENvbHVtbkJ5SW5kZXgoY29sSW5kZXgpO1xuICAgICAgICAgIHN1YkNvbEluZGV4ID0gMDtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgY2FzZSAncmlnaHQnOiB7XG4gICAgICAgIGNvbnN0IGxhc3RWaXNpYmxlID0gdGhpcy5maW5kUHJldlZpc2libGVDb2wobWF4Q29sICsgMSk7XG4gICAgICAgIGlmIChsYXN0VmlzaWJsZSAhPT0gbnVsbCkge1xuICAgICAgICAgIGNvbEluZGV4ID0gbGFzdFZpc2libGU7XG4gICAgICAgICAgY29uc3QgY29sID0gdGhpcy5nZXRDb2x1bW5CeUluZGV4KGNvbEluZGV4KTtcbiAgICAgICAgICBzdWJDb2xJbmRleCA9IGNvbD8uY2hpbGRyZW4/Lmxlbmd0aFxuICAgICAgICAgICAgPyBjb2wuY2hpbGRyZW4ubGVuZ3RoIC0gMVxuICAgICAgICAgICAgOiAwO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICByb3dJbmRleCxcbiAgICAgIGNvbEluZGV4LFxuICAgICAgc3ViQ29sSW5kZXgsXG4gICAgICBrZXk6IGAke3Jvd0luZGV4fS0ke2NvbEluZGV4fS0ke3N1YkNvbEluZGV4fWAsXG4gICAgICBmaWVsZDogY29sdW1uc1tjb2xJbmRleF0/LmZpZWxkIHx8ICcnXG4gICAgfTtcbiAgfVxuXG4gIHJvd0hlaWdodCA9IDQ0O1xuICBwcml2YXRlIHNjcm9sbENlbGxJbnRvVmlld0ltbWVkaWF0ZShyb3dJbmRleDogbnVtYmVyLCBjb2xJbmRleDogbnVtYmVyKSB7XG4gICAgaWYgKCF0aGlzLnZlcnRpY2FsQ29udGFpbmVyIHx8ICF0aGlzLmhvcml6b250YWxDb250YWluZXIpIHJldHVybjtcblxuICAgIGNvbnN0IG1hcmdpbiA9IDY7XG5cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBWZXJ0aWNhbCBzY3JvbGxcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBjb25zdCB0YXJnZXRTY3JvbGxUb3AgPSAocm93SW5kZXggLSAxKSAqIHRoaXMucm93SGVpZ2h0O1xuICAgIGNvbnN0IG1heFNjcm9sbFRvcCA9IHRoaXMudmVydGljYWxDb250YWluZXIuc2Nyb2xsSGVpZ2h0IC0gdGhpcy52ZXJ0aWNhbENvbnRhaW5lci5jbGllbnRIZWlnaHQ7XG4gICAgdGhpcy52ZXJ0aWNhbENvbnRhaW5lci5zY3JvbGxUb3AgPSBNYXRoLm1heCgwLCBNYXRoLm1pbih0YXJnZXRTY3JvbGxUb3AsIG1heFNjcm9sbFRvcCkpO1xuXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gSG9yaXpvbnRhbCBzY3JvbGxcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBjb25zdCBhY3RpdmVDZWxsID0gdGhpcy52ZXJ0aWNhbENvbnRhaW5lci5xdWVyeVNlbGVjdG9yKFxuICAgICAgYFtsb2NhdGlvbj0nJHtyb3dJbmRleH0tJHtjb2xJbmRleH0nXWBcbiAgICApIGFzIEhUTUxFbGVtZW50O1xuICAgIGlmICghYWN0aXZlQ2VsbCkgcmV0dXJuO1xuXG4gICAgY29uc3QgY29udGFpbmVyID0gdGhpcy5ob3Jpem9udGFsQ29udGFpbmVyO1xuXG4gICAgLy8gY2VsbCdzIG9mZnNldCByZWxhdGl2ZSB0byBjb250YWluZXJcbiAgICBjb25zdCBjZWxsTGVmdCA9IGFjdGl2ZUNlbGwub2Zmc2V0TGVmdDtcbiAgICBjb25zdCBjZWxsUmlnaHQgPSBjZWxsTGVmdCArIGFjdGl2ZUNlbGwub2Zmc2V0V2lkdGg7XG5cbiAgICBjb25zdCBzY3JvbGxMZWZ0ID0gY29udGFpbmVyLnNjcm9sbExlZnQ7XG4gICAgY29uc3QgY29udGFpbmVyV2lkdGggPSBjb250YWluZXIuY2xpZW50V2lkdGg7XG5cbiAgICBpZiAoY2VsbExlZnQgPCBzY3JvbGxMZWZ0KSB7XG4gICAgICBjb250YWluZXIuc2Nyb2xsTGVmdCA9IGNlbGxMZWZ0IC0gbWFyZ2luO1xuICAgIH0gZWxzZSBpZiAoY2VsbFJpZ2h0ID4gc2Nyb2xsTGVmdCArIGNvbnRhaW5lcldpZHRoKSB7XG4gICAgICBjb250YWluZXIuc2Nyb2xsTGVmdCA9IGNlbGxSaWdodCAtIGNvbnRhaW5lcldpZHRoICsgbWFyZ2luO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaXNMYXN0Um93KHJvd0luZGV4OiBudW1iZXIpOiBib29sZWFuIHtcbiAgICBpZiAoIXRoaXMudmVydGljYWxDb250YWluZXIpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gKFxuICAgICAgcm93SW5kZXggPT09XG4gICAgICBNYXRoLnJvdW5kKFxuICAgICAgICB0aGlzLnZlcnRpY2FsQ29udGFpbmVyLnNjcm9sbEhlaWdodCAvXG4gICAgICAgICh0aGlzLnZlcnRpY2FsQ29udGFpbmVyLnNjcm9sbEhlaWdodCAvXG4gICAgICAgICAgdGhpcy52ZXJ0aWNhbENvbnRhaW5lci5jaGlsZHJlbi5sZW5ndGgpXG4gICAgICApIHx8IGZhbHNlXG4gICAgKTtcbiAgfVxuXG5nZXQgc2VsZWN0ZWRDb2x1bW5JbmRpY2VzKCk6IG51bWJlcltdIHtcbiAgaWYgKCF0aGlzLnNlbGVjdGlvbkJvdW5kcy5sZWZ0IHx8ICF0aGlzLnNlbGVjdGlvbkJvdW5kcy5yaWdodCkgcmV0dXJuIFtdO1xuXG4gIGNvbnN0IGluZGljZXM6IG51bWJlcltdID0gW107XG4gIGZvciAobGV0IGkgPSB0aGlzLnNlbGVjdGlvbkJvdW5kcy5sZWZ0LmNvbEluZGV4OyBpIDw9IHRoaXMuc2VsZWN0aW9uQm91bmRzLnJpZ2h0LmNvbEluZGV4OyBpKyspIHtcbiAgICAvLyBPbmx5IGluY2x1ZGUgdmlzaWJsZSBjb2x1bW5zXG4gICAgaWYgKHRoaXMuaXNDb2x1bW5WaXNpYmxlKGkpKSBpbmRpY2VzLnB1c2goaSk7XG4gIH1cbiAgcmV0dXJuIGluZGljZXM7XG59XG5cblxuXG59XG4iXX0=
|