@ogidor/dashboard 1.0.2 → 1.0.4
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/README.md +283 -48
- package/app/app.module.d.ts +7 -9
- package/app/custom-grid.component.d.ts +93 -0
- package/app/dashboard-state.service.d.ts +54 -33
- package/app/dashboard.component.d.ts +27 -59
- package/app/models.d.ts +18 -38
- package/app/widget-renderer.component.d.ts +5 -32
- package/esm2020/app/app.module.mjs +21 -29
- package/esm2020/app/custom-grid.component.mjs +509 -0
- package/esm2020/app/dashboard-state.service.mjs +228 -158
- package/esm2020/app/dashboard.component.mjs +198 -602
- package/esm2020/app/models.mjs +1 -1
- package/esm2020/app/widget-renderer.component.mjs +41 -121
- package/esm2020/public-api.mjs +5 -4
- package/fesm2015/ogidor-dashboard.mjs +988 -909
- package/fesm2015/ogidor-dashboard.mjs.map +1 -1
- package/fesm2020/ogidor-dashboard.mjs +982 -898
- package/fesm2020/ogidor-dashboard.mjs.map +1 -1
- package/package.json +8 -12
- package/public-api.d.ts +3 -2
|
@@ -0,0 +1,509 @@
|
|
|
1
|
+
import { Component, Input, Output, EventEmitter, ViewChild, ContentChild, TemplateRef, Directive, ChangeDetectionStrategy } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
import * as i1 from "@angular/common";
|
|
4
|
+
/**
|
|
5
|
+
* Directive applied to the template that should be stamped inside each grid cell.
|
|
6
|
+
* Usage:
|
|
7
|
+
* <app-grid [widgets]="...">
|
|
8
|
+
* <ng-template gridCell let-widget="widget">
|
|
9
|
+
* <app-widget-renderer [widget]="widget" ...></app-widget-renderer>
|
|
10
|
+
* </ng-template>
|
|
11
|
+
* </app-grid>
|
|
12
|
+
*/
|
|
13
|
+
export class GridCellDirective {
|
|
14
|
+
constructor(templateRef) {
|
|
15
|
+
this.templateRef = templateRef;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
GridCellDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: GridCellDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
19
|
+
GridCellDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.10", type: GridCellDirective, selector: "[gridCell]", ngImport: i0 });
|
|
20
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: GridCellDirective, decorators: [{
|
|
21
|
+
type: Directive,
|
|
22
|
+
args: [{ selector: '[gridCell]' }]
|
|
23
|
+
}], ctorParameters: function () { return [{ type: i0.TemplateRef }]; } });
|
|
24
|
+
class GridEngine {
|
|
25
|
+
/**
|
|
26
|
+
* Check if two rects overlap.
|
|
27
|
+
*/
|
|
28
|
+
static collides(a, b) {
|
|
29
|
+
return !(a.x + a.cols <= b.x ||
|
|
30
|
+
b.x + b.cols <= a.x ||
|
|
31
|
+
a.y + a.rows <= b.y ||
|
|
32
|
+
b.y + b.rows <= a.y);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Get ALL widgets that collide with `rect`.
|
|
36
|
+
*/
|
|
37
|
+
static getAllCollisions(widgets, rect) {
|
|
38
|
+
return widgets.filter(w => w.id !== rect.id && GridEngine.collides(w, rect));
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Sort widgets top-to-bottom, left-to-right.
|
|
42
|
+
*/
|
|
43
|
+
static sortByPosition(widgets) {
|
|
44
|
+
return [...widgets].sort((a, b) => a.y - b.y || a.x - b.x);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Move a widget to (x, y) and push any colliding widgets downward.
|
|
48
|
+
* Returns the full list with resolved positions.
|
|
49
|
+
*/
|
|
50
|
+
static moveWidget(allWidgets, widget, newX, newY, columns) {
|
|
51
|
+
const widgets = allWidgets.map(w => ({ ...w }));
|
|
52
|
+
const moving = widgets.find(w => w.id === widget.id);
|
|
53
|
+
if (!moving)
|
|
54
|
+
return widgets;
|
|
55
|
+
moving.x = Math.max(0, Math.min(newX, columns - moving.cols));
|
|
56
|
+
moving.y = Math.max(0, newY);
|
|
57
|
+
const sorted = GridEngine.sortByPosition(widgets);
|
|
58
|
+
GridEngine.resolveCollisions(sorted, moving);
|
|
59
|
+
return GridEngine.compact(sorted, columns);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Resize a widget and push colliding widgets down.
|
|
63
|
+
*/
|
|
64
|
+
static resizeWidget(allWidgets, widget, newCols, newRows, columns) {
|
|
65
|
+
const widgets = allWidgets.map(w => ({ ...w }));
|
|
66
|
+
const resizing = widgets.find(w => w.id === widget.id);
|
|
67
|
+
if (!resizing)
|
|
68
|
+
return widgets;
|
|
69
|
+
resizing.cols = Math.max(1, Math.min(newCols, columns - resizing.x));
|
|
70
|
+
resizing.rows = Math.max(1, newRows);
|
|
71
|
+
const sorted = GridEngine.sortByPosition(widgets);
|
|
72
|
+
GridEngine.resolveCollisions(sorted, resizing);
|
|
73
|
+
return GridEngine.compact(sorted, columns);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Push all widgets that collide with `movedWidget` downward, recursively.
|
|
77
|
+
*/
|
|
78
|
+
static resolveCollisions(widgets, movedWidget) {
|
|
79
|
+
const collisions = GridEngine.getAllCollisions(widgets, movedWidget);
|
|
80
|
+
for (const collider of collisions) {
|
|
81
|
+
collider.y = movedWidget.y + movedWidget.rows;
|
|
82
|
+
GridEngine.resolveCollisions(widgets, collider);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Compact the grid: move every widget as far up as possible without overlapping.
|
|
87
|
+
*/
|
|
88
|
+
static compact(widgets, _columns) {
|
|
89
|
+
const sorted = GridEngine.sortByPosition(widgets);
|
|
90
|
+
const placed = [];
|
|
91
|
+
for (const widget of sorted) {
|
|
92
|
+
widget.y = GridEngine.findCompactY(placed, widget);
|
|
93
|
+
placed.push(widget);
|
|
94
|
+
}
|
|
95
|
+
return placed;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Find the highest Y position a widget can occupy without overlapping any already-placed widget.
|
|
99
|
+
*/
|
|
100
|
+
static findCompactY(placed, widget) {
|
|
101
|
+
let y = 0;
|
|
102
|
+
while (true) {
|
|
103
|
+
const test = { ...widget, y };
|
|
104
|
+
const collision = placed.find(p => GridEngine.collides(p, test));
|
|
105
|
+
if (!collision)
|
|
106
|
+
return y;
|
|
107
|
+
y = collision.y + collision.rows;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Compute the total number of rows the grid needs.
|
|
112
|
+
*/
|
|
113
|
+
static getGridHeight(widgets) {
|
|
114
|
+
if (widgets.length === 0)
|
|
115
|
+
return 0;
|
|
116
|
+
return Math.max(...widgets.map(w => w.y + w.rows));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/* ═══════════════════════════════════════════════════════════════════════
|
|
120
|
+
CUSTOM GRID COMPONENT
|
|
121
|
+
═══════════════════════════════════════════════════════════════════════ */
|
|
122
|
+
export class CustomGridComponent {
|
|
123
|
+
constructor(zone, cdr) {
|
|
124
|
+
this.zone = zone;
|
|
125
|
+
this.cdr = cdr;
|
|
126
|
+
this.widgets = [];
|
|
127
|
+
this.columns = 12;
|
|
128
|
+
this.gap = 16;
|
|
129
|
+
this.rowHeight = 80;
|
|
130
|
+
this.minItemCols = 1;
|
|
131
|
+
this.minItemRows = 1;
|
|
132
|
+
this.itemChanged = new EventEmitter();
|
|
133
|
+
this.layoutChanged = new EventEmitter();
|
|
134
|
+
this.placeholder = null;
|
|
135
|
+
this.containerHeight = 400;
|
|
136
|
+
this.dragging = null;
|
|
137
|
+
this.resizing = null;
|
|
138
|
+
this.previewWidgets = [];
|
|
139
|
+
this.boundMouseMove = this.onMouseMove.bind(this);
|
|
140
|
+
this.boundMouseUp = this.onMouseUp.bind(this);
|
|
141
|
+
}
|
|
142
|
+
ngOnInit() {
|
|
143
|
+
this.compactAndApply();
|
|
144
|
+
this.updateContainerHeight();
|
|
145
|
+
this.zone.runOutsideAngular(() => {
|
|
146
|
+
window.addEventListener('mousemove', this.boundMouseMove);
|
|
147
|
+
window.addEventListener('mouseup', this.boundMouseUp);
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
ngOnChanges(_changes) {
|
|
151
|
+
this.updateContainerHeight();
|
|
152
|
+
}
|
|
153
|
+
ngOnDestroy() {
|
|
154
|
+
window.removeEventListener('mousemove', this.boundMouseMove);
|
|
155
|
+
window.removeEventListener('mouseup', this.boundMouseUp);
|
|
156
|
+
}
|
|
157
|
+
trackByFn(_index, item) { return item.id; }
|
|
158
|
+
// ── Geometry ──
|
|
159
|
+
get cellWidth() {
|
|
160
|
+
const containerW = this.gridContainer?.nativeElement?.clientWidth ?? 800;
|
|
161
|
+
return (containerW - (this.columns - 1) * this.gap) / this.columns;
|
|
162
|
+
}
|
|
163
|
+
colToPixel(col) {
|
|
164
|
+
return col * (this.cellWidth + this.gap);
|
|
165
|
+
}
|
|
166
|
+
rowToPixel(row) {
|
|
167
|
+
return row * (this.rowHeight + this.gap);
|
|
168
|
+
}
|
|
169
|
+
pixelToCol(px) {
|
|
170
|
+
return Math.round(px / (this.cellWidth + this.gap));
|
|
171
|
+
}
|
|
172
|
+
pixelToRow(px) {
|
|
173
|
+
return Math.round(px / (this.rowHeight + this.gap));
|
|
174
|
+
}
|
|
175
|
+
colsToPixelWidth(cols) {
|
|
176
|
+
return cols * this.cellWidth + (cols - 1) * this.gap;
|
|
177
|
+
}
|
|
178
|
+
rowsToPixelHeight(rows) {
|
|
179
|
+
return rows * this.rowHeight + (rows - 1) * this.gap;
|
|
180
|
+
}
|
|
181
|
+
getItemLeft(w) {
|
|
182
|
+
return this.dragging?.id === w.id ? this.dragging.currentPixelX : this.colToPixel(w.x);
|
|
183
|
+
}
|
|
184
|
+
getItemTop(w) {
|
|
185
|
+
return this.dragging?.id === w.id ? this.dragging.currentPixelY : this.rowToPixel(w.y);
|
|
186
|
+
}
|
|
187
|
+
getItemWidth(w) {
|
|
188
|
+
return this.resizing?.id === w.id ? this.resizing.currentPixelW : this.colsToPixelWidth(w.cols);
|
|
189
|
+
}
|
|
190
|
+
getItemHeight(w) {
|
|
191
|
+
return this.resizing?.id === w.id ? this.resizing.currentPixelH : this.rowsToPixelHeight(w.rows);
|
|
192
|
+
}
|
|
193
|
+
// ── Drag ──
|
|
194
|
+
onDragStart(event, widget) {
|
|
195
|
+
const target = event.target;
|
|
196
|
+
if (target.closest('button, input, select, textarea, a, .resize-handle'))
|
|
197
|
+
return;
|
|
198
|
+
event.preventDefault();
|
|
199
|
+
event.stopPropagation();
|
|
200
|
+
const rect = this.gridContainer.nativeElement.getBoundingClientRect();
|
|
201
|
+
const itemLeft = this.colToPixel(widget.x);
|
|
202
|
+
const itemTop = this.rowToPixel(widget.y);
|
|
203
|
+
this.dragging = {
|
|
204
|
+
id: widget.id,
|
|
205
|
+
offsetX: event.clientX - rect.left - itemLeft,
|
|
206
|
+
offsetY: event.clientY - rect.top - itemTop,
|
|
207
|
+
currentPixelX: itemLeft,
|
|
208
|
+
currentPixelY: itemTop,
|
|
209
|
+
};
|
|
210
|
+
this.previewWidgets = this.widgets.map(w => ({ id: w.id, x: w.x, y: w.y, cols: w.cols, rows: w.rows }));
|
|
211
|
+
this.placeholder = {
|
|
212
|
+
left: itemLeft, top: itemTop,
|
|
213
|
+
width: this.colsToPixelWidth(widget.cols),
|
|
214
|
+
height: this.rowsToPixelHeight(widget.rows),
|
|
215
|
+
};
|
|
216
|
+
this.cdr.markForCheck();
|
|
217
|
+
}
|
|
218
|
+
onResizeStart(event, widget) {
|
|
219
|
+
event.preventDefault();
|
|
220
|
+
event.stopPropagation();
|
|
221
|
+
this.resizing = {
|
|
222
|
+
id: widget.id,
|
|
223
|
+
startMouseX: event.clientX,
|
|
224
|
+
startMouseY: event.clientY,
|
|
225
|
+
startCols: widget.cols,
|
|
226
|
+
startRows: widget.rows,
|
|
227
|
+
currentPixelW: this.colsToPixelWidth(widget.cols),
|
|
228
|
+
currentPixelH: this.rowsToPixelHeight(widget.rows),
|
|
229
|
+
};
|
|
230
|
+
this.previewWidgets = this.widgets.map(w => ({ id: w.id, x: w.x, y: w.y, cols: w.cols, rows: w.rows }));
|
|
231
|
+
this.placeholder = {
|
|
232
|
+
left: this.colToPixel(widget.x), top: this.rowToPixel(widget.y),
|
|
233
|
+
width: this.colsToPixelWidth(widget.cols),
|
|
234
|
+
height: this.rowsToPixelHeight(widget.rows),
|
|
235
|
+
};
|
|
236
|
+
this.cdr.markForCheck();
|
|
237
|
+
}
|
|
238
|
+
onMouseMove(event) {
|
|
239
|
+
if (this.dragging)
|
|
240
|
+
this.handleDragMove(event);
|
|
241
|
+
else if (this.resizing)
|
|
242
|
+
this.handleResizeMove(event);
|
|
243
|
+
}
|
|
244
|
+
onMouseUp(_event) {
|
|
245
|
+
if (this.dragging)
|
|
246
|
+
this.zone.run(() => this.finalizeDrag());
|
|
247
|
+
else if (this.resizing)
|
|
248
|
+
this.zone.run(() => this.finalizeResize());
|
|
249
|
+
}
|
|
250
|
+
handleDragMove(event) {
|
|
251
|
+
if (!this.dragging)
|
|
252
|
+
return;
|
|
253
|
+
const rect = this.gridContainer.nativeElement.getBoundingClientRect();
|
|
254
|
+
const widget = this.widgets.find(w => w.id === this.dragging.id);
|
|
255
|
+
if (!widget)
|
|
256
|
+
return;
|
|
257
|
+
let px = event.clientX - rect.left - this.dragging.offsetX;
|
|
258
|
+
let py = event.clientY - rect.top - this.dragging.offsetY;
|
|
259
|
+
px = Math.max(0, Math.min(px, rect.width - this.colsToPixelWidth(widget.cols)));
|
|
260
|
+
py = Math.max(0, py);
|
|
261
|
+
this.dragging.currentPixelX = px;
|
|
262
|
+
this.dragging.currentPixelY = py;
|
|
263
|
+
const targetCol = Math.max(0, Math.min(this.pixelToCol(px), this.columns - widget.cols));
|
|
264
|
+
const targetRow = Math.max(0, this.pixelToRow(py));
|
|
265
|
+
const resolved = GridEngine.moveWidget(this.previewWidgets, { id: widget.id, x: widget.x, y: widget.y, cols: widget.cols, rows: widget.rows }, targetCol, targetRow, this.columns);
|
|
266
|
+
this.placeholder = {
|
|
267
|
+
left: this.colToPixel(targetCol), top: this.rowToPixel(targetRow),
|
|
268
|
+
width: this.colsToPixelWidth(widget.cols),
|
|
269
|
+
height: this.rowsToPixelHeight(widget.rows),
|
|
270
|
+
};
|
|
271
|
+
this.zone.run(() => {
|
|
272
|
+
for (const rw of resolved) {
|
|
273
|
+
if (rw.id === widget.id)
|
|
274
|
+
continue;
|
|
275
|
+
const w = this.widgets.find(ww => ww.id === rw.id);
|
|
276
|
+
if (w) {
|
|
277
|
+
w.x = rw.x;
|
|
278
|
+
w.y = rw.y;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
this.updateContainerHeight();
|
|
282
|
+
this.cdr.markForCheck();
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
finalizeDrag() {
|
|
286
|
+
if (!this.dragging)
|
|
287
|
+
return;
|
|
288
|
+
const widget = this.widgets.find(w => w.id === this.dragging.id);
|
|
289
|
+
const targetCol = Math.max(0, Math.min(this.pixelToCol(this.dragging.currentPixelX), this.columns - widget.cols));
|
|
290
|
+
const targetRow = Math.max(0, this.pixelToRow(this.dragging.currentPixelY));
|
|
291
|
+
const resolved = GridEngine.moveWidget(this.widgets.map(w => ({ id: w.id, x: w.x, y: w.y, cols: w.cols, rows: w.rows })), { id: widget.id, x: widget.x, y: widget.y, cols: widget.cols, rows: widget.rows }, targetCol, targetRow, this.columns);
|
|
292
|
+
for (const rw of resolved) {
|
|
293
|
+
const w = this.widgets.find(ww => ww.id === rw.id);
|
|
294
|
+
if (w) {
|
|
295
|
+
w.x = rw.x;
|
|
296
|
+
w.y = rw.y;
|
|
297
|
+
w.cols = rw.cols;
|
|
298
|
+
w.rows = rw.rows;
|
|
299
|
+
this.itemChanged.emit(w);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
this.dragging = null;
|
|
303
|
+
this.placeholder = null;
|
|
304
|
+
this.previewWidgets = [];
|
|
305
|
+
this.updateContainerHeight();
|
|
306
|
+
this.layoutChanged.emit(this.widgets);
|
|
307
|
+
this.cdr.markForCheck();
|
|
308
|
+
}
|
|
309
|
+
handleResizeMove(event) {
|
|
310
|
+
if (!this.resizing)
|
|
311
|
+
return;
|
|
312
|
+
const widget = this.widgets.find(w => w.id === this.resizing.id);
|
|
313
|
+
if (!widget)
|
|
314
|
+
return;
|
|
315
|
+
const dx = event.clientX - this.resizing.startMouseX;
|
|
316
|
+
const dy = event.clientY - this.resizing.startMouseY;
|
|
317
|
+
let newCols = Math.max(this.minItemCols, Math.round((this.colsToPixelWidth(this.resizing.startCols) + dx) / (this.cellWidth + this.gap)));
|
|
318
|
+
let newRows = Math.max(this.minItemRows, Math.round((this.rowsToPixelHeight(this.resizing.startRows) + dy) / (this.rowHeight + this.gap)));
|
|
319
|
+
newCols = Math.min(newCols, this.columns - widget.x);
|
|
320
|
+
this.resizing.currentPixelW = this.colsToPixelWidth(newCols);
|
|
321
|
+
this.resizing.currentPixelH = this.rowsToPixelHeight(newRows);
|
|
322
|
+
const resolved = GridEngine.resizeWidget(this.previewWidgets, { id: widget.id, x: widget.x, y: widget.y, cols: widget.cols, rows: widget.rows }, newCols, newRows, this.columns);
|
|
323
|
+
this.placeholder = {
|
|
324
|
+
left: this.colToPixel(widget.x), top: this.rowToPixel(widget.y),
|
|
325
|
+
width: this.colsToPixelWidth(newCols),
|
|
326
|
+
height: this.rowsToPixelHeight(newRows),
|
|
327
|
+
};
|
|
328
|
+
this.zone.run(() => {
|
|
329
|
+
for (const rw of resolved) {
|
|
330
|
+
if (rw.id === widget.id)
|
|
331
|
+
continue;
|
|
332
|
+
const w = this.widgets.find(ww => ww.id === rw.id);
|
|
333
|
+
if (w) {
|
|
334
|
+
w.x = rw.x;
|
|
335
|
+
w.y = rw.y;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
this.updateContainerHeight();
|
|
339
|
+
this.cdr.markForCheck();
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
finalizeResize() {
|
|
343
|
+
if (!this.resizing)
|
|
344
|
+
return;
|
|
345
|
+
const widget = this.widgets.find(w => w.id === this.resizing.id);
|
|
346
|
+
let newCols = Math.max(this.minItemCols, Math.round(this.resizing.currentPixelW / (this.cellWidth + this.gap)));
|
|
347
|
+
let newRows = Math.max(this.minItemRows, Math.round(this.resizing.currentPixelH / (this.rowHeight + this.gap)));
|
|
348
|
+
newCols = Math.min(newCols, this.columns - widget.x);
|
|
349
|
+
const resolved = GridEngine.resizeWidget(this.widgets.map(w => ({ id: w.id, x: w.x, y: w.y, cols: w.cols, rows: w.rows })), { id: widget.id, x: widget.x, y: widget.y, cols: widget.cols, rows: widget.rows }, newCols, newRows, this.columns);
|
|
350
|
+
for (const rw of resolved) {
|
|
351
|
+
const w = this.widgets.find(ww => ww.id === rw.id);
|
|
352
|
+
if (w) {
|
|
353
|
+
w.x = rw.x;
|
|
354
|
+
w.y = rw.y;
|
|
355
|
+
w.cols = rw.cols;
|
|
356
|
+
w.rows = rw.rows;
|
|
357
|
+
this.itemChanged.emit(w);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
this.resizing = null;
|
|
361
|
+
this.placeholder = null;
|
|
362
|
+
this.previewWidgets = [];
|
|
363
|
+
this.updateContainerHeight();
|
|
364
|
+
this.layoutChanged.emit(this.widgets);
|
|
365
|
+
this.cdr.markForCheck();
|
|
366
|
+
}
|
|
367
|
+
// ── Utilities ──
|
|
368
|
+
compactAndApply() {
|
|
369
|
+
if (!this.widgets?.length)
|
|
370
|
+
return;
|
|
371
|
+
const compacted = GridEngine.compact(this.widgets.map(w => ({ id: w.id, x: w.x, y: w.y, cols: w.cols, rows: w.rows })), this.columns);
|
|
372
|
+
for (const rw of compacted) {
|
|
373
|
+
const w = this.widgets.find(ww => ww.id === rw.id);
|
|
374
|
+
if (w) {
|
|
375
|
+
w.x = rw.x;
|
|
376
|
+
w.y = rw.y;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
updateContainerHeight() {
|
|
381
|
+
if (!this.widgets?.length) {
|
|
382
|
+
this.containerHeight = 400;
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
const maxRow = GridEngine.getGridHeight(this.widgets.map(w => ({ id: w.id, x: w.x, y: w.y, cols: w.cols, rows: w.rows })));
|
|
386
|
+
this.containerHeight = this.rowToPixel(maxRow) + this.rowHeight + this.gap;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
CustomGridComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CustomGridComponent, deps: [{ token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
390
|
+
CustomGridComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: CustomGridComponent, selector: "app-grid", inputs: { widgets: "widgets", columns: "columns", gap: "gap", rowHeight: "rowHeight", minItemCols: "minItemCols", minItemRows: "minItemRows" }, outputs: { itemChanged: "itemChanged", layoutChanged: "layoutChanged" }, queries: [{ propertyName: "cellTemplate", first: true, predicate: GridCellDirective, descendants: true, read: TemplateRef }], viewQueries: [{ propertyName: "gridContainer", first: true, predicate: ["gridContainer"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: `
|
|
391
|
+
<div
|
|
392
|
+
#gridContainer
|
|
393
|
+
class="grid-container"
|
|
394
|
+
[style.height.px]="containerHeight"
|
|
395
|
+
>
|
|
396
|
+
<!-- Placeholder preview -->
|
|
397
|
+
<div
|
|
398
|
+
class="grid-placeholder"
|
|
399
|
+
*ngIf="placeholder"
|
|
400
|
+
[style.left.px]="placeholder.left"
|
|
401
|
+
[style.top.px]="placeholder.top"
|
|
402
|
+
[style.width.px]="placeholder.width"
|
|
403
|
+
[style.height.px]="placeholder.height"
|
|
404
|
+
></div>
|
|
405
|
+
|
|
406
|
+
<!-- Widget items -->
|
|
407
|
+
<div
|
|
408
|
+
*ngFor="let widget of widgets; trackBy: trackByFn"
|
|
409
|
+
class="grid-item"
|
|
410
|
+
[class.is-dragging]="dragging?.id === widget.id"
|
|
411
|
+
[class.is-resizing]="resizing?.id === widget.id"
|
|
412
|
+
[style.left.px]="getItemLeft(widget)"
|
|
413
|
+
[style.top.px]="getItemTop(widget)"
|
|
414
|
+
[style.width.px]="getItemWidth(widget)"
|
|
415
|
+
[style.height.px]="getItemHeight(widget)"
|
|
416
|
+
[style.z-index]="(dragging?.id === widget.id || resizing?.id === widget.id) ? 100 : 1"
|
|
417
|
+
(mousedown)="onDragStart($event, widget)"
|
|
418
|
+
>
|
|
419
|
+
<!-- Content stamped from parent template, context carries the widget -->
|
|
420
|
+
<ng-container
|
|
421
|
+
*ngIf="cellTemplate"
|
|
422
|
+
[ngTemplateOutlet]="cellTemplate"
|
|
423
|
+
[ngTemplateOutletContext]="{ widget: widget }"
|
|
424
|
+
></ng-container>
|
|
425
|
+
|
|
426
|
+
<!-- Resize handle -->
|
|
427
|
+
<div class="resize-handle" (mousedown)="onResizeStart($event, widget)">
|
|
428
|
+
<svg width="12" height="12" viewBox="0 0 12 12">
|
|
429
|
+
<path d="M11 1v10H1" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
|
|
430
|
+
<path d="M11 5v6H5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
|
|
431
|
+
<path d="M11 9v2H9" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
|
|
432
|
+
</svg>
|
|
433
|
+
</div>
|
|
434
|
+
</div>
|
|
435
|
+
</div>
|
|
436
|
+
`, isInline: true, styles: [":host{display:block;width:100%;height:100%}.grid-container{position:relative;width:100%;min-height:100%;transition:height .25s ease}.grid-placeholder{position:absolute;background:var(--dash-accent-color, #0a84ff);opacity:.12;border-radius:24px;border:2px dashed var(--dash-accent-color, #0a84ff);transition:left .15s ease,top .15s ease,width .15s ease,height .15s ease;pointer-events:none;z-index:0}.grid-item{position:absolute;display:flex;flex-direction:column;transition:left .25s ease,top .25s ease,width .25s ease,height .25s ease;border-radius:24px;overflow:hidden}.grid-item.is-dragging,.grid-item.is-resizing{transition:none!important;opacity:.88;overflow:visible;filter:drop-shadow(0 20px 40px rgba(0,0,0,.45))}.resize-handle{position:absolute;right:4px;bottom:4px;width:22px;height:22px;cursor:nwse-resize;display:flex;align-items:center;justify-content:center;color:#ffffff40;border-radius:6px;transition:color .2s,background .2s;z-index:20}.resize-handle:hover{color:var(--dash-accent-color, #0a84ff);background:rgba(255,255,255,.06)}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
437
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CustomGridComponent, decorators: [{
|
|
438
|
+
type: Component,
|
|
439
|
+
args: [{ selector: 'app-grid', template: `
|
|
440
|
+
<div
|
|
441
|
+
#gridContainer
|
|
442
|
+
class="grid-container"
|
|
443
|
+
[style.height.px]="containerHeight"
|
|
444
|
+
>
|
|
445
|
+
<!-- Placeholder preview -->
|
|
446
|
+
<div
|
|
447
|
+
class="grid-placeholder"
|
|
448
|
+
*ngIf="placeholder"
|
|
449
|
+
[style.left.px]="placeholder.left"
|
|
450
|
+
[style.top.px]="placeholder.top"
|
|
451
|
+
[style.width.px]="placeholder.width"
|
|
452
|
+
[style.height.px]="placeholder.height"
|
|
453
|
+
></div>
|
|
454
|
+
|
|
455
|
+
<!-- Widget items -->
|
|
456
|
+
<div
|
|
457
|
+
*ngFor="let widget of widgets; trackBy: trackByFn"
|
|
458
|
+
class="grid-item"
|
|
459
|
+
[class.is-dragging]="dragging?.id === widget.id"
|
|
460
|
+
[class.is-resizing]="resizing?.id === widget.id"
|
|
461
|
+
[style.left.px]="getItemLeft(widget)"
|
|
462
|
+
[style.top.px]="getItemTop(widget)"
|
|
463
|
+
[style.width.px]="getItemWidth(widget)"
|
|
464
|
+
[style.height.px]="getItemHeight(widget)"
|
|
465
|
+
[style.z-index]="(dragging?.id === widget.id || resizing?.id === widget.id) ? 100 : 1"
|
|
466
|
+
(mousedown)="onDragStart($event, widget)"
|
|
467
|
+
>
|
|
468
|
+
<!-- Content stamped from parent template, context carries the widget -->
|
|
469
|
+
<ng-container
|
|
470
|
+
*ngIf="cellTemplate"
|
|
471
|
+
[ngTemplateOutlet]="cellTemplate"
|
|
472
|
+
[ngTemplateOutletContext]="{ widget: widget }"
|
|
473
|
+
></ng-container>
|
|
474
|
+
|
|
475
|
+
<!-- Resize handle -->
|
|
476
|
+
<div class="resize-handle" (mousedown)="onResizeStart($event, widget)">
|
|
477
|
+
<svg width="12" height="12" viewBox="0 0 12 12">
|
|
478
|
+
<path d="M11 1v10H1" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
|
|
479
|
+
<path d="M11 5v6H5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
|
|
480
|
+
<path d="M11 9v2H9" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
|
|
481
|
+
</svg>
|
|
482
|
+
</div>
|
|
483
|
+
</div>
|
|
484
|
+
</div>
|
|
485
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;width:100%;height:100%}.grid-container{position:relative;width:100%;min-height:100%;transition:height .25s ease}.grid-placeholder{position:absolute;background:var(--dash-accent-color, #0a84ff);opacity:.12;border-radius:24px;border:2px dashed var(--dash-accent-color, #0a84ff);transition:left .15s ease,top .15s ease,width .15s ease,height .15s ease;pointer-events:none;z-index:0}.grid-item{position:absolute;display:flex;flex-direction:column;transition:left .25s ease,top .25s ease,width .25s ease,height .25s ease;border-radius:24px;overflow:hidden}.grid-item.is-dragging,.grid-item.is-resizing{transition:none!important;opacity:.88;overflow:visible;filter:drop-shadow(0 20px 40px rgba(0,0,0,.45))}.resize-handle{position:absolute;right:4px;bottom:4px;width:22px;height:22px;cursor:nwse-resize;display:flex;align-items:center;justify-content:center;color:#ffffff40;border-radius:6px;transition:color .2s,background .2s;z-index:20}.resize-handle:hover{color:var(--dash-accent-color, #0a84ff);background:rgba(255,255,255,.06)}\n"] }]
|
|
486
|
+
}], ctorParameters: function () { return [{ type: i0.NgZone }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { widgets: [{
|
|
487
|
+
type: Input
|
|
488
|
+
}], columns: [{
|
|
489
|
+
type: Input
|
|
490
|
+
}], gap: [{
|
|
491
|
+
type: Input
|
|
492
|
+
}], rowHeight: [{
|
|
493
|
+
type: Input
|
|
494
|
+
}], minItemCols: [{
|
|
495
|
+
type: Input
|
|
496
|
+
}], minItemRows: [{
|
|
497
|
+
type: Input
|
|
498
|
+
}], itemChanged: [{
|
|
499
|
+
type: Output
|
|
500
|
+
}], layoutChanged: [{
|
|
501
|
+
type: Output
|
|
502
|
+
}], gridContainer: [{
|
|
503
|
+
type: ViewChild,
|
|
504
|
+
args: ['gridContainer', { static: true }]
|
|
505
|
+
}], cellTemplate: [{
|
|
506
|
+
type: ContentChild,
|
|
507
|
+
args: [GridCellDirective, { read: TemplateRef }]
|
|
508
|
+
}] } });
|
|
509
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9tLWdyaWQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwcC9jdXN0b20tZ3JpZC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFDdEMsU0FBUyxFQUNULFlBQVksRUFBRSxXQUFXLEVBQ3pCLFNBQVMsRUFBRSx1QkFBdUIsRUFDbkMsTUFBTSxlQUFlLENBQUM7OztBQUd2Qjs7Ozs7Ozs7R0FRRztBQUVILE1BQU0sT0FBTyxpQkFBaUI7SUFDNUIsWUFBbUIsV0FBNEM7UUFBNUMsZ0JBQVcsR0FBWCxXQUFXLENBQWlDO0lBQUcsQ0FBQzs7K0dBRHhELGlCQUFpQjttR0FBakIsaUJBQWlCOzRGQUFqQixpQkFBaUI7a0JBRDdCLFNBQVM7bUJBQUMsRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFOztBQW1CckMsTUFBTSxVQUFVO0lBRWQ7O09BRUc7SUFDSCxNQUFNLENBQUMsUUFBUSxDQUFDLENBQVcsRUFBRSxDQUFXO1FBQ3RDLE9BQU8sQ0FBQyxDQUNOLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQztZQUNuQixDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUM7WUFDbkIsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ25CLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUNwQixDQUFDO0lBQ0osQ0FBQztJQUVEOztPQUVHO0lBQ0gsTUFBTSxDQUFDLGdCQUFnQixDQUFDLE9BQW1CLEVBQUUsSUFBYztRQUN6RCxPQUFPLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUs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OztHQThDVCxtQkE0RGdCLHVCQUF1QixDQUFDLE1BQU07NkhBR3RDLE9BQU87c0JBQWYsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csR0FBRztzQkFBWCxLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUVJLFdBQVc7c0JBQXBCLE1BQU07Z0JBQ0csYUFBYTtzQkFBdEIsTUFBTTtnQkFFdUMsYUFBYTtzQkFBMUQsU0FBUzt1QkFBQyxlQUFlLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQUdZLFlBQVk7c0JBQW5FLFlBQVk7dUJBQUMsaUJBQWlCLEVBQUUsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LCBJbnB1dCwgT3V0cHV0LCBFdmVudEVtaXR0ZXIsIEVsZW1lbnRSZWYsXG4gIFZpZXdDaGlsZCwgT25EZXN0cm95LCBPbkluaXQsIE5nWm9uZSwgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbnRlbnRDaGlsZCwgVGVtcGxhdGVSZWYsXG4gIERpcmVjdGl2ZSwgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIE9uQ2hhbmdlcywgU2ltcGxlQ2hhbmdlc1xufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFdpZGdldCB9IGZyb20gJy4vbW9kZWxzJztcblxuLyoqXG4gKiBEaXJlY3RpdmUgYXBwbGllZCB0byB0aGUgdGVtcGxhdGUgdGhhdCBzaG91bGQgYmUgc3RhbXBlZCBpbnNpZGUgZWFjaCBncmlkIGNlbGwuXG4gKiBVc2FnZTpcbiAqICAgPGFwcC1ncmlkIFt3aWRnZXRzXT1cIi4uLlwiPlxuICogICAgIDxuZy10ZW1wbGF0ZSBncmlkQ2VsbCBsZXQtd2lkZ2V0PVwid2lkZ2V0XCI+XG4gKiAgICAgICA8YXBwLXdpZGdldC1yZW5kZXJlciBbd2lkZ2V0XT1cIndpZGdldFwiIC4uLj48L2FwcC13aWRnZXQtcmVuZGVyZXI+XG4gKiAgICAgPC9uZy10ZW1wbGF0ZT5cbiAqICAgPC9hcHAtZ3JpZD5cbiAqL1xuQERpcmVjdGl2ZSh7IHNlbGVjdG9yOiAnW2dyaWRDZWxsXScgfSlcbmV4cG9ydCBjbGFzcyBHcmlkQ2VsbERpcmVjdGl2ZSB7XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyB0ZW1wbGF0ZVJlZjogVGVtcGxhdGVSZWY8eyB3aWRnZXQ6IFdpZGdldCB9Pikge31cbn1cblxuLyog4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQXG4gICBHUklEIEVOR0lORSDigJQgcHVyZSBkYXRhLCB6ZXJvIERPTVxuICAgSGFuZGxlcyBjb2xsaXNpb24gZGV0ZWN0aW9uLCByZXNvbHV0aW9uLCBhbmQgY29tcGFjdGlvbi5cbiAgIEluc3BpcmVkIGJ5IHJlYWN0LWdyaWQtbGF5b3V0IC8gZ3JpZHN0ZXIgYWxnb3JpdGhtcy5cbiAgIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkCAqL1xuXG5pbnRlcmZhY2UgR3JpZFJlY3Qge1xuICBpZDogc3RyaW5nO1xuICB4OiBudW1iZXI7XG4gIHk6IG51bWJlcjtcbiAgY29sczogbnVtYmVyO1xuICByb3dzOiBudW1iZXI7XG59XG5cbmNsYXNzIEdyaWRFbmdpbmUge1xuXG4gIC8qKlxuICAgKiBDaGVjayBpZiB0d28gcmVjdHMgb3ZlcmxhcC5cbiAgICovXG4gIHN0YXRpYyBjb2xsaWRlcyhhOiBHcmlkUmVjdCwgYjogR3JpZFJlY3QpOiBib29sZWFuIHtcbiAgICByZXR1cm4gIShcbiAgICAgIGEueCArIGEuY29scyA8PSBiLnggfHxcbiAgICAgIGIueCArIGIuY29scyA8PSBhLnggfHxcbiAgICAgIGEueSArIGEucm93cyA8PSBiLnkgfHxcbiAgICAgIGIueSArIGIucm93cyA8PSBhLnlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBBTEwgd2lkZ2V0cyB0aGF0IGNvbGxpZGUgd2l0aCBgcmVjdGAuXG4gICAqL1xuICBzdGF0aWMgZ2V0QWxsQ29sbGlzaW9ucyh3aWRnZXRzOiBHcmlkUmVjdFtdLCByZWN0OiBHcmlkUmVjdCk6IEdyaWRSZWN0W10ge1xuICAgIHJldHVybiB3aWRnZXRzLmZpbHRlcih3ID0+IHcuaWQgIT09IHJlY3QuaWQgJiYgR3JpZEVuZ2luZS5jb2xsaWRlcyh3LCByZWN0KSk7XG4gIH1cblxuICAvKipcbiAgICogU29ydCB3aWRnZXRzIHRvcC10by1ib3R0b20sIGxlZnQtdG8tcmlnaHQuXG4gICAqL1xuICBzdGF0aWMgc29ydEJ5UG9zaXRpb24od2lkZ2V0czogR3JpZFJlY3RbXSk6IEdyaWRSZWN0W10ge1xuICAgIHJldHVybiBbLi4ud2lkZ2V0c10uc29ydCgoYSwgYikgPT4gYS55IC0gYi55IHx8IGEueCAtIGIueCk7XG4gIH1cblxuICAvKipcbiAgICogTW92ZSBhIHdpZGdldCB0byAoeCwgeSkgYW5kIHB1c2ggYW55IGNvbGxpZGluZyB3aWRnZXRzIGRvd253YXJkLlxuICAgKiBSZXR1cm5zIHRoZSBmdWxsIGxpc3Qgd2l0aCByZXNvbHZlZCBwb3NpdGlvbnMuXG4gICAqL1xuICBzdGF0aWMgbW92ZVdpZGdldChcbiAgICBhbGxXaWRnZXRzOiBHcmlkUmVjdFtdLFxuICAgIHdpZGdldDogR3JpZFJlY3QsXG4gICAgbmV3WDogbnVtYmVyLFxuICAgIG5ld1k6IG51bWJlcixcbiAgICBjb2x1bW5zOiBudW1iZXJcbiAgKTogR3JpZFJlY3RbXSB7XG4gICAgY29uc3Qgd2lkZ2V0cyA9IGFsbFdpZGdldHMubWFwKHcgPT4gKHsgLi4udyB9KSk7XG4gICAgY29uc3QgbW92aW5nID0gd2lkZ2V0cy5maW5kKHcgPT4gdy5pZCA9PT0gd2lkZ2V0LmlkKTtcbiAgICBpZiAoIW1vdmluZykgcmV0dXJuIHdpZGdldHM7XG5cbiAgICBtb3ZpbmcueCA9IE1hdGgubWF4KDAsIE1hdGgubWluKG5ld1gsIGNvbHVtbnMgLSBtb3ZpbmcuY29scykpO1xuICAgIG1vdmluZy55ID0gTWF0aC5tYXgoMCwgbmV3WSk7XG5cbiAgICBjb25zdCBzb3J0ZWQgPSBHcmlkRW5naW5lLnNvcnRCeVBvc2l0aW9uKHdpZGdldHMpO1xuICAgIEdyaWRFbmdpbmUucmVzb2x2ZUNvbGxpc2lvbnMoc29ydGVkLCBtb3ZpbmcpO1xuICAgIHJldHVybiBHcmlkRW5naW5lLmNvbXBhY3Qoc29ydGVkLCBjb2x1bW5zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNpemUgYSB3aWRnZXQgYW5kIHB1c2ggY29sbGlkaW5nIHdpZGdldHMgZG93bi5cbiAgICovXG4gIHN0YXRpYyByZXNpemVXaWRnZXQoXG4gICAgYWxsV2lkZ2V0czogR3JpZFJlY3RbXSxcbiAgICB3aWRnZXQ6IEdyaWRSZWN0LFxuICAgIG5ld0NvbHM6IG51bWJlcixcbiAgICBuZXdSb3dzOiBudW1iZXIsXG4gICAgY29sdW1uczogbnVtYmVyXG4gICk6IEdyaWRSZWN0W10ge1xuICAgIGNvbnN0IHdpZGdldHMgPSBhbGxXaWRnZXRzLm1hcCh3ID0+ICh7IC4uLncgfSkpO1xuICAgIGNvbnN0IHJlc2l6aW5nID0gd2lkZ2V0cy5maW5kKHcgPT4gdy5pZCA9PT0gd2lkZ2V0LmlkKTtcbiAgICBpZiAoIXJlc2l6aW5nKSByZXR1cm4gd2lkZ2V0cztcblxuICAgIHJlc2l6aW5nLmNvbHMgPSBNYXRoLm1heCgxLCBNYXRoLm1pbihuZXdDb2xzLCBjb2x1bW5zIC0gcmVzaXppbmcueCkpO1xuICAgIHJlc2l6aW5nLnJvd3MgPSBNYXRoLm1heCgxLCBuZXdSb3dzKTtcblxuICAgIGNvbnN0IHNvcnRlZCA9IEdyaWRFbmdpbmUuc29ydEJ5UG9zaXRpb24od2lkZ2V0cyk7XG4gICAgR3JpZEVuZ2luZS5yZXNvbHZlQ29sbGlzaW9ucyhzb3J0ZWQsIHJlc2l6aW5nKTtcbiAgICByZXR1cm4gR3JpZEVuZ2luZS5jb21wYWN0KHNvcnRlZCwgY29sdW1ucyk7XG4gIH1cblxuICAvKipcbiAgICogUHVzaCBhbGwgd2lkZ2V0cyB0aGF0IGNvbGxpZGUgd2l0aCBgbW92ZWRXaWRnZXRgIGRvd253YXJkLCByZWN1cnNpdmVseS5cbiAgICovXG4gIHByaXZhdGUgc3RhdGljIHJlc29sdmVDb2xsaXNpb25zKHdpZGdldHM6IEdyaWRSZWN0W10sIG1vdmVkV2lkZ2V0OiBHcmlkUmVjdCk6IHZvaWQge1xuICAgIGNvbnN0IGNvbGxpc2lvbnMgPSBHcmlkRW5naW5lLmdldEFsbENvbGxpc2lvbnMod2lkZ2V0cywgbW92ZWRXaWRnZXQpO1xuICAgIGZvciAoY29uc3QgY29sbGlkZXIgb2YgY29sbGlzaW9ucykge1xuICAgICAgY29sbGlkZXIueSA9IG1vdmVkV2lkZ2V0LnkgKyBtb3ZlZFdpZGdldC5yb3dzO1xuICAgICAgR3JpZEVuZ2luZS5yZXNvbHZlQ29sbGlzaW9ucyh3aWRnZXRzLCBjb2xsaWRlcik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENvbXBhY3QgdGhlIGdyaWQ6IG1vdmUgZXZlcnkgd2lkZ2V0IGFzIGZhciB1cCBhcyBwb3NzaWJsZSB3aXRob3V0IG92ZXJsYXBwaW5nLlxuICAgKi9cbiAgc3RhdGljIGNvbXBhY3Qod2lkZ2V0czogR3JpZFJlY3RbXSwgX2NvbHVtbnM6IG51bWJlcik6IEdyaWRSZWN0W10ge1xuICAgIGNvbnN0IHNvcnRlZCA9IEdyaWRFbmdpbmUuc29ydEJ5UG9zaXRpb24od2lkZ2V0cyk7XG4gICAgY29uc3QgcGxhY2VkOiBHcmlkUmVjdFtdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IHdpZGdldCBvZiBzb3J0ZWQpIHtcbiAgICAgIHdpZGdldC55ID0gR3JpZEVuZ2luZS5maW5kQ29tcGFjdFkocGxhY2VkLCB3aWRnZXQpO1xuICAgICAgcGxhY2VkLnB1c2god2lkZ2V0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gcGxhY2VkO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbmQgdGhlIGhpZ2hlc3QgWSBwb3NpdGlvbiBhIHdpZGdldCBjYW4gb2NjdXB5IHdpdGhvdXQgb3ZlcmxhcHBpbmcgYW55IGFscmVhZHktcGxhY2VkIHdpZGdldC5cbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGZpbmRDb21wYWN0WShwbGFjZWQ6IEdyaWRSZWN0W10sIHdpZGdldDogR3JpZFJlY3QpOiBudW1iZXIge1xuICAgIGxldCB5ID0gMDtcbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgY29uc3QgdGVzdDogR3JpZFJlY3QgPSB7IC4uLndpZGdldCwgeSB9O1xuICAgICAgY29uc3QgY29sbGlzaW9uID0gcGxhY2VkLmZpbmQocCA9PiBHcmlkRW5naW5lLmNvbGxpZGVzKHAsIHRlc3QpKTtcbiAgICAgIGlmICghY29sbGlzaW9uKSByZXR1cm4geTtcbiAgICAgIHkgPSBjb2xsaXNpb24ueSArIGNvbGxpc2lvbi5yb3dzO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb21wdXRlIHRoZSB0b3RhbCBudW1iZXIgb2Ygcm93cyB0aGUgZ3JpZCBuZWVkcy5cbiAgICovXG4gIHN0YXRpYyBnZXRHcmlkSGVpZ2h0KHdpZGdldHM6IEdyaWRSZWN0W10pOiBudW1iZXIge1xuICAgIGlmICh3aWRnZXRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIDA7XG4gICAgcmV0dXJuIE1hdGgubWF4KC4uLndpZGdldHMubWFwKHcgPT4gdy55ICsgdy5yb3dzKSk7XG4gIH1cbn1cblxuLyog4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQXG4gICBDVVNUT00gR1JJRCBDT01QT05FTlRcbiAgIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkCAqL1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcHAtZ3JpZCcsXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdlxuICAgICAgI2dyaWRDb250YWluZXJcbiAgICAgIGNsYXNzPVwiZ3JpZC1jb250YWluZXJcIlxuICAgICAgW3N0eWxlLmhlaWdodC5weF09XCJjb250YWluZXJIZWlnaHRcIlxuICAgID5cbiAgICAgIDwhLS0gUGxhY2Vob2xkZXIgcHJldmlldyAtLT5cbiAgICAgIDxkaXZcbiAgICAgICAgY2xhc3M9XCJncmlkLXBsYWNlaG9sZGVyXCJcbiAgICAgICAgKm5nSWY9XCJwbGFjZWhvbGRlclwiXG4gICAgICAgIFtzdHlsZS5sZWZ0LnB4XT1cInBsYWNlaG9sZGVyLmxlZnRcIlxuICAgICAgICBbc3R5bGUudG9wLnB4XT1cInBsYWNlaG9sZGVyLnRvcFwiXG4gICAgICAgIFtzdHlsZS53aWR0aC5weF09XCJwbGFjZWhvbGRlci53aWR0aFwiXG4gICAgICAgIFtzdHlsZS5oZWlnaHQucHhdPVwicGxhY2Vob2xkZXIuaGVpZ2h0XCJcbiAgICAgID48L2Rpdj5cblxuICAgICAgPCEtLSBXaWRnZXQgaXRlbXMgLS0+XG4gICAgICA8ZGl2XG4gICAgICAgICpuZ0Zvcj1cImxldCB3aWRnZXQgb2Ygd2lkZ2V0czsgdHJhY2tCeTogdHJhY2tCeUZuXCJcbiAgICAgICAgY2xhc3M9XCJncmlkLWl0ZW1cIlxuICAgICAgICBbY2xhc3MuaXMtZHJhZ2dpbmddPVwiZHJhZ2dpbmc/LmlkID09PSB3aWRnZXQuaWRcIlxuICAgICAgICBbY2xhc3MuaXMtcmVzaXppbmddPVwicmVzaXppbmc/LmlkID09PSB3aWRnZXQuaWRcIlxuICAgICAgICBbc3R5bGUubGVmdC5weF09XCJnZXRJdGVtTGVmdCh3aWRnZXQpXCJcbiAgICAgICAgW3N0eWxlLnRvcC5weF09XCJnZXRJdGVtVG9wKHdpZGdldClcIlxuICAgICAgICBbc3R5bGUud2lkdGgucHhdPVwiZ2V0SXRlbVdpZHRoKHdpZGdldClcIlxuICAgICAgICBbc3R5bGUuaGVpZ2h0LnB4XT1cImdldEl0ZW1IZWlnaHQod2lkZ2V0KVwiXG4gICAgICAgIFtzdHlsZS56LWluZGV4XT1cIihkcmFnZ2luZz8uaWQgPT09IHdpZGdldC5pZCB8fCByZXNpemluZz8uaWQgPT09IHdpZGdldC5pZCkgPyAxMDAgOiAxXCJcbiAgICAgICAgKG1vdXNlZG93bik9XCJvbkRyYWdTdGFydCgkZXZlbnQsIHdpZGdldClcIlxuICAgICAgPlxuICAgICAgICA8IS0tIENvbnRlbnQgc3RhbXBlZCBmcm9tIHBhcmVudCB0ZW1wbGF0ZSwgY29udGV4dCBjYXJyaWVzIHRoZSB3aWRnZXQgLS0+XG4gICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAqbmdJZj1cImNlbGxUZW1wbGF0ZVwiXG4gICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwiY2VsbFRlbXBsYXRlXCJcbiAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyB3aWRnZXQ6IHdpZGdldCB9XCJcbiAgICAgICAgPjwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDwhLS0gUmVzaXplIGhhbmRsZSAtLT5cbiAgICAgICAgPGRpdiBjbGFzcz1cInJlc2l6ZS1oYW5kbGVcIiAobW91c2Vkb3duKT1cIm9uUmVzaXplU3RhcnQoJGV2ZW50LCB3aWRnZXQpXCI+XG4gICAgICAgICAgPHN2ZyB3aWR0aD1cIjEyXCIgaGVpZ2h0PVwiMTJcIiB2aWV3Qm94PVwiMCAwIDEyIDEyXCI+XG4gICAgICAgICAgICA8cGF0aCBkPVwiTTExIDF2MTBIMVwiIGZpbGw9XCJub25lXCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMS41XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiLz5cbiAgICAgICAgICAgIDxwYXRoIGQ9XCJNMTEgNXY2SDVcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjEuNVwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIi8+XG4gICAgICAgICAgICA8cGF0aCBkPVwiTTExIDl2Mkg5XCIgZmlsbD1cIm5vbmVcIiBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBzdHJva2Utd2lkdGg9XCIxLjVcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIvPlxuICAgICAgICAgIDwvc3ZnPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICBgLFxuICBzdHlsZXM6IFtgXG4gICAgOmhvc3QgeyBkaXNwbGF5OiBibG9jazsgd2lkdGg6IDEwMCU7IGhlaWdodDogMTAwJTsgfVxuXG4gICAgLmdyaWQtY29udGFpbmVyIHtcbiAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgbWluLWhlaWdodDogMTAwJTtcbiAgICAgIHRyYW5zaXRpb246IGhlaWdodCAwLjI1cyBlYXNlO1xuICAgIH1cblxuICAgIC5ncmlkLXBsYWNlaG9sZGVyIHtcbiAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgIGJhY2tncm91bmQ6IHZhcigtLWRhc2gtYWNjZW50LWNvbG9yLCAjMGE4NGZmKTtcbiAgICAgIG9wYWNpdHk6IDAuMTI7XG4gICAgICBib3JkZXItcmFkaXVzOiAyNHB4O1xuICAgICAgYm9yZGVyOiAycHggZGFzaGVkIHZhcigtLWRhc2gtYWNjZW50LWNvbG9yLCAjMGE4NGZmKTtcbiAgICAgIHRyYW5zaXRpb246IGxlZnQgMC4xNXMgZWFzZSwgdG9wIDAuMTVzIGVhc2UsIHdpZHRoIDAuMTVzIGVhc2UsIGhlaWdodCAwLjE1cyBlYXNlO1xuICAgICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG4gICAgICB6LWluZGV4OiAwO1xuICAgIH1cblxuICAgIC5ncmlkLWl0ZW0ge1xuICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICB0cmFuc2l0aW9uOiBsZWZ0IDAuMjVzIGVhc2UsIHRvcCAwLjI1cyBlYXNlLCB3aWR0aCAwLjI1cyBlYXNlLCBoZWlnaHQgMC4yNXMgZWFzZTtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDI0cHg7XG4gICAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgIH1cblxuICAgIC5ncmlkLWl0ZW0uaXMtZHJhZ2dpbmcsXG4gICAgLmdyaWQtaXRlbS5pcy1yZXNpemluZyB7XG4gICAgICB0cmFuc2l0aW9uOiBub25lICFpbXBvcnRhbnQ7XG4gICAgICBvcGFjaXR5OiAwLjg4O1xuICAgICAgb3ZlcmZsb3c6IHZpc2libGU7XG4gICAgICBmaWx0ZXI6IGRyb3Atc2hhZG93KDAgMjBweCA0MHB4IHJnYmEoMCwwLDAsMC40NSkpO1xuICAgIH1cblxuICAgIC8qIFJlc2l6ZSBIYW5kbGUgKi9cbiAgICAucmVzaXplLWhhbmRsZSB7XG4gICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICByaWdodDogNHB4O1xuICAgICAgYm90dG9tOiA0cHg7XG4gICAgICB3aWR0aDogMjJweDtcbiAgICAgIGhlaWdodDogMjJweDtcbiAgICAgIGN1cnNvcjogbndzZS1yZXNpemU7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgICAgY29sb3I6IHJnYmEoMjU1LDI1NSwyNTUsMC4yNSk7XG4gICAgICBib3JkZXItcmFkaXVzOiA2cHg7XG4gICAgICB0cmFuc2l0aW9uOiBjb2xvciAwLjJzLCBiYWNrZ3JvdW5kIDAuMnM7XG4gICAgICB6LWluZGV4OiAyMDtcbiAgICB9XG4gICAgLnJlc2l6ZS1oYW5kbGU6aG92ZXIge1xuICAgICAgY29sb3I6IHZhcigtLWRhc2gtYWNjZW50LWNvbG9yLCAjMGE4NGZmKTtcbiAgICAgIGJhY2tncm91bmQ6IHJnYmEoMjU1LDI1NSwyNTUsMC4wNik7XG4gICAgfVxuICBgXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2hcbn0pXG5leHBvcnQgY2xhc3MgQ3VzdG9tR3JpZENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95LCBPbkNoYW5nZXMge1xuICBASW5wdXQoKSB3aWRnZXRzOiBXaWRnZXRbXSA9IFtdO1xuICBASW5wdXQoKSBjb2x1bW5zOiBudW1iZXIgPSAxMjtcbiAgQElucHV0KCkgZ2FwOiBudW1iZXIgPSAxNjtcbiAgQElucHV0KCkgcm93SGVpZ2h0OiBudW1iZXIgPSA4MDtcbiAgQElucHV0KCkgbWluSXRlbUNvbHM6IG51bWJlciA9IDE7XG4gIEBJbnB1dCgpIG1pbkl0ZW1Sb3dzOiBudW1iZXIgPSAxO1xuXG4gIEBPdXRwdXQoKSBpdGVtQ2hhbmdlZCA9IG5ldyBFdmVudEVtaXR0ZXI8V2lkZ2V0PigpO1xuICBAT3V0cHV0KCkgbGF5b3V0Q2hhbmdlZCA9IG5ldyBFdmVudEVtaXR0ZXI8V2lkZ2V0W10+KCk7XG5cbiAgQFZpZXdDaGlsZCgnZ3JpZENvbnRhaW5lcicsIHsgc3RhdGljOiB0cnVlIH0pIGdyaWRDb250YWluZXIhOiBFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50PjtcblxuICAvKiogVGhlIG5nLXRlbXBsYXRlIGRlY29yYXRlZCB3aXRoIGdyaWRDZWxsIGZyb20gdGhlIHBhcmVudCAqL1xuICBAQ29udGVudENoaWxkKEdyaWRDZWxsRGlyZWN0aXZlLCB7IHJlYWQ6IFRlbXBsYXRlUmVmIH0pIGNlbGxUZW1wbGF0ZSE6IFRlbXBsYXRlUmVmPHsgd2lkZ2V0OiBXaWRnZXQgfT47XG5cbiAgcGxhY2Vob2xkZXI6IHsgbGVmdDogbnVtYmVyOyB0b3A6IG51bWJlcjsgd2lkdGg6IG51bWJlcjsgaGVpZ2h0OiBudW1iZXIgfSB8IG51bGwgPSBudWxsO1xuICBjb250YWluZXJIZWlnaHQgPSA0MDA7XG5cbiAgZHJhZ2dpbmc6IHtcbiAgICBpZDogc3RyaW5nO1xuICAgIG9mZnNldFg6IG51bWJlcjtcbiAgICBvZmZzZXRZOiBudW1iZXI7XG4gICAgY3VycmVudFBpeGVsWDogbnVtYmVyO1xuICAgIGN1cnJlbnRQaXhlbFk6IG51bWJlcjtcbiAgfSB8IG51bGwgPSBudWxsO1xuXG4gIHJlc2l6aW5nOiB7XG4gICAgaWQ6IHN0cmluZztcbiAgICBzdGFydE1vdXNlWDogbnVtYmVyO1xuICAgIHN0YXJ0TW91c2VZOiBudW1iZXI7XG4gICAgc3RhcnRDb2xzOiBudW1iZXI7XG4gICAgc3RhcnRSb3dzOiBudW1iZXI7XG4gICAgY3VycmVudFBpeGVsVzogbnVtYmVyO1xuICAgIGN1cnJlbnRQaXhlbEg6IG51bWJlcjtcbiAgfSB8IG51bGwgPSBudWxsO1xuXG4gIHByaXZhdGUgcHJldmlld1dpZGdldHM6IEdyaWRSZWN0W10gPSBbXTtcbiAgcHJpdmF0ZSBib3VuZE1vdXNlTW92ZSA9IHRoaXMub25Nb3VzZU1vdmUuYmluZCh0aGlzKTtcbiAgcHJpdmF0ZSBib3VuZE1vdXNlVXAgPSB0aGlzLm9uTW91c2VVcC5iaW5kKHRoaXMpO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgem9uZTogTmdab25lLCBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYpIHt9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5jb21wYWN0QW5kQXBwbHkoKTtcbiAgICB0aGlzLnVwZGF0ZUNvbnRhaW5lckhlaWdodCgpO1xuICAgIHRoaXMuem9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdGhpcy5ib3VuZE1vdXNlTW92ZSk7XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHRoaXMuYm91bmRNb3VzZVVwKTtcbiAgICB9KTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKF9jaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgdGhpcy51cGRhdGVDb250YWluZXJIZWlnaHQoKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCB0aGlzLmJvdW5kTW91c2VNb3ZlKTtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHRoaXMuYm91bmRNb3VzZVVwKTtcbiAgfVxuXG4gIHRyYWNrQnlGbihfaW5kZXg6IG51bWJlciwgaXRlbTogV2lkZ2V0KSB7IHJldHVybiBpdGVtLmlkOyB9XG5cbiAgLy8g4pSA4pSAIEdlb21ldHJ5IOKUgOKUgFxuXG4gIHByaXZhdGUgZ2V0IGNlbGxXaWR0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IGNvbnRhaW5lclcgPSB0aGlzLmdyaWRDb250YWluZXI/Lm5hdGl2ZUVsZW1lbnQ/LmNsaWVudFdpZHRoID8/IDgwMDtcbiAgICByZXR1cm4gKGNvbnRhaW5lclcgLSAodGhpcy5jb2x1bW5zIC0gMSkgKiB0aGlzLmdhcCkgLyB0aGlzLmNvbHVtbnM7XG4gIH1cblxuICBwcml2YXRlIGNvbFRvUGl4ZWwoY29sOiBudW1iZXIpOiBudW1iZXIge1xuICAgIHJldHVybiBjb2wgKiAodGhpcy5jZWxsV2lkdGggKyB0aGlzLmdhcCk7XG4gIH1cblxuICBwcml2YXRlIHJvd1RvUGl4ZWwocm93OiBudW1iZXIpOiBudW1iZXIge1xuICAgIHJldHVybiByb3cgKiAodGhpcy5yb3dIZWlnaHQgKyB0aGlzLmdhcCk7XG4gIH1cblxuICBwcml2YXRlIHBpeGVsVG9Db2wocHg6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIE1hdGgucm91bmQocHggLyAodGhpcy5jZWxsV2lkdGggKyB0aGlzLmdhcCkpO1xuICB9XG5cbiAgcHJpdmF0ZSBwaXhlbFRvUm93KHB4OiBudW1iZXIpOiBudW1iZXIge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKHB4IC8gKHRoaXMucm93SGVpZ2h0ICsgdGhpcy5nYXApKTtcbiAgfVxuXG4gIHByaXZhdGUgY29sc1RvUGl4ZWxXaWR0aChjb2xzOiBudW1iZXIpOiBudW1iZXIge1xuICAgIHJldHVybiBjb2xzICogdGhpcy5jZWxsV2lkdGggKyAoY29scyAtIDEpICogdGhpcy5nYXA7XG4gIH1cblxuICBwcml2YXRlIHJvd3NUb1BpeGVsSGVpZ2h0KHJvd3M6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIHJvd3MgKiB0aGlzLnJvd0hlaWdodCArIChyb3dzIC0gMSkgKiB0aGlzLmdhcDtcbiAgfVxuXG4gIGdldEl0ZW1MZWZ0KHc6IFdpZGdldCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuZHJhZ2dpbmc/LmlkID09PSB3LmlkID8gdGhpcy5kcmFnZ2luZy5jdXJyZW50UGl4ZWxYIDogdGhpcy5jb2xUb1BpeGVsKHcueCk7XG4gIH1cblxuICBnZXRJdGVtVG9wKHc6IFdpZGdldCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuZHJhZ2dpbmc/LmlkID09PSB3LmlkID8gdGhpcy5kcmFnZ2luZy5jdXJyZW50UGl4ZWxZIDogdGhpcy5yb3dUb1BpeGVsKHcueSk7XG4gIH1cblxuICBnZXRJdGVtV2lkdGgodzogV2lkZ2V0KTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5yZXNpemluZz8uaWQgPT09IHcuaWQgPyB0aGlzLnJlc2l6aW5nLmN1cnJlbnRQaXhlbFcgOiB0aGlzLmNvbHNUb1BpeGVsV2lkdGgody5jb2xzKTtcbiAgfVxuXG4gIGdldEl0ZW1IZWlnaHQodzogV2lkZ2V0KTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5yZXNpemluZz8uaWQgPT09IHcuaWQgPyB0aGlzLnJlc2l6aW5nLmN1cnJlbnRQaXhlbEggOiB0aGlzLnJvd3NUb1BpeGVsSGVpZ2h0KHcucm93cyk7XG4gIH1cblxuICAvLyDilIDilIAgRHJhZyDilIDilIBcblxuICBvbkRyYWdTdGFydChldmVudDogTW91c2VFdmVudCwgd2lkZ2V0OiBXaWRnZXQpIHtcbiAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgaWYgKHRhcmdldC5jbG9zZXN0KCdidXR0b24sIGlucHV0LCBzZWxlY3QsIHRleHRhcmVhLCBhLCAucmVzaXplLWhhbmRsZScpKSByZXR1cm47XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgIGNvbnN0IHJlY3QgPSB0aGlzLmdyaWRDb250YWluZXIubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBjb25zdCBpdGVtTGVmdCA9IHRoaXMuY29sVG9QaXhlbCh3aWRnZXQueCk7XG4gICAgY29uc3QgaXRlbVRvcCA9IHRoaXMucm93VG9QaXhlbCh3aWRnZXQueSk7XG5cbiAgICB0aGlzLmRyYWdnaW5nID0ge1xuICAgICAgaWQ6IHdpZGdldC5pZCxcbiAgICAgIG9mZnNldFg6IGV2ZW50LmNsaWVudFggLSByZWN0LmxlZnQgLSBpdGVtTGVmdCxcbiAgICAgIG9mZnNldFk6IGV2ZW50LmNsaWVudFkgLSByZWN0LnRvcCAtIGl0ZW1Ub3AsXG4gICAgICBjdXJyZW50UGl4ZWxYOiBpdGVtTGVmdCxcbiAgICAgIGN1cnJlbnRQaXhlbFk6IGl0ZW1Ub3AsXG4gICAgfTtcbiAgICB0aGlzLnByZXZpZXdXaWRnZXRzID0gdGhpcy53aWRnZXRzLm1hcCh3ID0+ICh7IGlkOiB3LmlkLCB4OiB3LngsIHk6IHcueSwgY29sczogdy5jb2xzLCByb3dzOiB3LnJvd3MgfSkpO1xuICAgIHRoaXMucGxhY2Vob2xkZXIgPSB7XG4gICAgICBsZWZ0OiBpdGVtTGVmdCwgdG9wOiBpdGVtVG9wLFxuICAgICAgd2lkdGg6IHRoaXMuY29sc1RvUGl4ZWxXaWR0aCh3aWRnZXQuY29scyksXG4gICAgICBoZWlnaHQ6IHRoaXMucm93c1RvUGl4ZWxIZWlnaHQod2lkZ2V0LnJvd3MpLFxuICAgIH07XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBvblJlc2l6ZVN0YXJ0KGV2ZW50OiBNb3VzZUV2ZW50LCB3aWRnZXQ6IFdpZGdldCkge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgdGhpcy5yZXNpemluZyA9IHtcbiAgICAgIGlkOiB3aWRnZXQuaWQsXG4gICAgICBzdGFydE1vdXNlWDogZXZlbnQuY2xpZW50WCxcbiAgICAgIHN0YXJ0TW91c2VZOiBldmVudC5jbGllbnRZLFxuICAgICAgc3RhcnRDb2xzOiB3aWRnZXQuY29scyxcbiAgICAgIHN0YXJ0Um93czogd2lkZ2V0LnJvd3MsXG4gICAgICBjdXJyZW50UGl4ZWxXOiB0aGlzLmNvbHNUb1BpeGVsV2lkdGgod2lkZ2V0LmNvbHMpLFxuICAgICAgY3VycmVudFBpeGVsSDogdGhpcy5yb3dzVG9QaXhlbEhlaWdodCh3aWRnZXQucm93cyksXG4gICAgfTtcbiAgICB0aGlzLnByZXZpZXdXaWRnZXRzID0gdGhpcy53aWRnZXRzLm1hcCh3ID0+ICh7IGlkOiB3LmlkLCB4OiB3LngsIHk6IHcueSwgY29sczogdy5jb2xzLCByb3dzOiB3LnJvd3MgfSkpO1xuICAgIHRoaXMucGxhY2Vob2xkZXIgPSB7XG4gICAgICBsZWZ0OiB0aGlzLmNvbFRvUGl4ZWwod2lkZ2V0LngpLCB0b3A6IHRoaXMucm93VG9QaXhlbCh3aWRnZXQueSksXG4gICAgICB3aWR0aDogdGhpcy5jb2xzVG9QaXhlbFdpZHRoKHdpZGdldC5jb2xzKSxcbiAgICAgIGhlaWdodDogdGhpcy5yb3dzVG9QaXhlbEhlaWdodCh3aWRnZXQucm93cyksXG4gICAgfTtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIHByaXZhdGUgb25Nb3VzZU1vdmUoZXZlbnQ6IE1vdXNlRXZlbnQpIHtcbiAgICBpZiAodGhpcy5kcmFnZ2luZykgdGhpcy5oYW5kbGVEcmFnTW92ZShldmVudCk7XG4gICAgZWxzZSBpZiAodGhpcy5yZXNpemluZykgdGhpcy5oYW5kbGVSZXNpemVNb3ZlKGV2ZW50KTtcbiAgfVxuXG4gIHByaXZhdGUgb25Nb3VzZVVwKF9ldmVudDogTW91c2VFdmVudCkge1xuICAgIGlmICh0aGlzLmRyYWdnaW5nKSB0aGlzLnpvbmUucnVuKCgpID0+IHRoaXMuZmluYWxpemVEcmFnKCkpO1xuICAgIGVsc2UgaWYgKHRoaXMucmVzaXppbmcpIHRoaXMuem9uZS5ydW4oKCkgPT4gdGhpcy5maW5hbGl6ZVJlc2l6ZSgpKTtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlRHJhZ01vdmUoZXZlbnQ6IE1vdXNlRXZlbnQpIHtcbiAgICBpZiAoIXRoaXMuZHJhZ2dpbmcpIHJldHVybjtcbiAgICBjb25zdCByZWN0ID0gdGhpcy5ncmlkQ29udGFpbmVyLm5hdGl2ZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgY29uc3Qgd2lkZ2V0ID0gdGhpcy53aWRnZXRzLmZpbmQodyA9PiB3LmlkID09PSB0aGlzLmRyYWdnaW5nIS5pZCkhO1xuICAgIGlmICghd2lkZ2V0KSByZXR1cm47XG5cbiAgICBsZXQgcHggPSBldmVudC5jbGllbnRYIC0gcmVjdC5sZWZ0IC0gdGhpcy5kcmFnZ2luZy5vZmZzZXRYO1xuICAgIGxldCBweSA9IGV2ZW50LmNsaWVudFkgLSByZWN0LnRvcCAtIHRoaXMuZHJhZ2dpbmcub2Zmc2V0WTtcbiAgICBweCA9IE1hdGgubWF4KDAsIE1hdGgubWluKHB4LCByZWN0LndpZHRoIC0gdGhpcy5jb2xzVG9QaXhlbFdpZHRoKHdpZGdldC5jb2xzKSkpO1xuICAgIHB5ID0gTWF0aC5tYXgoMCwgcHkpO1xuXG4gICAgdGhpcy5kcmFnZ2luZy5jdXJyZW50UGl4ZWxYID0gcHg7XG4gICAgdGhpcy5kcmFnZ2luZy5jdXJyZW50UGl4ZWxZID0gcHk7XG5cbiAgICBjb25zdCB0YXJnZXRDb2wgPSBNYXRoLm1heCgwLCBNYXRoLm1pbih0aGlzLnBpeGVsVG9Db2wocHgpLCB0aGlzLmNvbHVtbnMgLSB3aWRnZXQuY29scykpO1xuICAgIGNvbnN0IHRhcmdldFJvdyA9IE1hdGgubWF4KDAsIHRoaXMucGl4ZWxUb1JvdyhweSkpO1xuXG4gICAgY29uc3QgcmVzb2x2ZWQgPSBHcmlkRW5naW5lLm1vdmVXaWRnZXQoXG4gICAgICB0aGlzLnByZXZpZXdXaWRnZXRzLFxuICAgICAgeyBpZDogd2lkZ2V0LmlkLCB4OiB3aWRnZXQueCwgeTogd2lkZ2V0LnksIGNvbHM6IHdpZGdldC5jb2xzLCByb3dzOiB3aWRnZXQucm93cyB9LFxuICAgICAgdGFyZ2V0Q29sLCB0YXJnZXRSb3csIHRoaXMuY29sdW1uc1xuICAgICk7XG5cbiAgICB0aGlzLnBsYWNlaG9sZGVyID0ge1xuICAgICAgbGVmdDogdGhpcy5jb2xUb1BpeGVsKHRhcmdldENvbCksIHRvcDogdGhpcy5yb3dUb1BpeGVsKHRhcmdldFJvdyksXG4gICAgICB3aWR0aDogdGhpcy5jb2xzVG9QaXhlbFdpZHRoKHdpZGdldC5jb2xzKSxcbiAgICAgIGhlaWdodDogdGhpcy5yb3dzVG9QaXhlbEhlaWdodCh3aWRnZXQucm93cyksXG4gICAgfTtcblxuICAgIHRoaXMuem9uZS5ydW4oKCkgPT4ge1xuICAgICAgZm9yIChjb25zdCBydyBvZiByZXNvbHZlZCkge1xuICAgICAgICBpZiAocncuaWQgPT09IHdpZGdldC5pZCkgY29udGludWU7XG4gICAgICAgIGNvbnN0IHcgPSB0aGlzLndpZGdldHMuZmluZCh3dyA9PiB3dy5pZCA9PT0gcncuaWQpO1xuICAgICAgICBpZiAodykgeyB3LnggPSBydy54OyB3LnkgPSBydy55OyB9XG4gICAgICB9XG4gICAgICB0aGlzLnVwZGF0ZUNvbnRhaW5lckhlaWdodCgpO1xuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGZpbmFsaXplRHJhZygpIHtcbiAgICBpZiAoIXRoaXMuZHJhZ2dpbmcpIHJldHVybjtcbiAgICBjb25zdCB3aWRnZXQgPSB0aGlzLndpZGdldHMuZmluZCh3ID0+IHcuaWQgPT09IHRoaXMuZHJhZ2dpbmchLmlkKSE7XG4gICAgY29uc3QgdGFyZ2V0Q29sID0gTWF0aC5tYXgoMCwgTWF0aC5taW4odGhpcy5waXhlbFRvQ29sKHRoaXMuZHJhZ2dpbmcuY3VycmVudFBpeGVsWCksIHRoaXMuY29sdW1ucyAtIHdpZGdldC5jb2xzKSk7XG4gICAgY29uc3QgdGFyZ2V0Um93ID0gTWF0aC5tYXgoMCwgdGhpcy5waXhlbFRvUm93KHRoaXMuZHJhZ2dpbmcuY3VycmVudFBpeGVsWSkpO1xuXG4gICAgY29uc3QgcmVzb2x2ZWQgPSBHcmlkRW5naW5lLm1vdmVXaWRnZXQoXG4gICAgICB0aGlzLndpZGdldHMubWFwKHcgPT4gKHsgaWQ6IHcuaWQsIHg6IHcueCwgeTogdy55LCBjb2xzOiB3LmNvbHMsIHJvd3M6IHcucm93cyB9KSksXG4gICAgICB7IGlkOiB3aWRnZXQuaWQsIHg6IHdpZGdldC54LCB5OiB3aWRnZXQueSwgY29sczogd2lkZ2V0LmNvbHMsIHJvd3M6IHdpZGdldC5yb3dzIH0sXG4gICAgICB0YXJnZXRDb2wsIHRhcmdldFJvdywgdGhpcy5jb2x1bW5zXG4gICAgKTtcbiAgICBmb3IgKGNvbnN0IHJ3IG9mIHJlc29sdmVkKSB7XG4gICAgICBjb25zdCB3ID0gdGhpcy53aWRnZXRzLmZpbmQod3cgPT4gd3cuaWQgPT09IHJ3LmlkKTtcbiAgICAgIGlmICh3KSB7IHcueCA9IHJ3Lng7IHcueSA9IHJ3Lnk7IHcuY29scyA9IHJ3LmNvbHM7IHcucm93cyA9IHJ3LnJvd3M7IHRoaXMuaXRlbUNoYW5nZWQuZW1pdCh3KTsgfVxuICAgIH1cbiAgICB0aGlzLmRyYWdnaW5nID0gbnVsbDtcbiAgICB0aGlzLnBsYWNlaG9sZGVyID0gbnVsbDtcbiAgICB0aGlzLnByZXZpZXdXaWRnZXRzID0gW107XG4gICAgdGhpcy51cGRhdGVDb250YWluZXJIZWlnaHQoKTtcbiAgICB0aGlzLmxheW91dENoYW5nZWQuZW1pdCh0aGlzLndpZGdldHMpO1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVSZXNpemVNb3ZlKGV2ZW50OiBNb3VzZUV2ZW50KSB7XG4gICAgaWYgKCF0aGlzLnJlc2l6aW5nKSByZXR1cm47XG4gICAgY29uc3Qgd2lkZ2V0ID0gdGhpcy53aWRnZXRzLmZpbmQodyA9PiB3LmlkID09PSB0aGlzLnJlc2l6aW5nIS5pZCkhO1xuICAgIGlmICghd2lkZ2V0KSByZXR1cm47XG5cbiAgICBjb25zdCBkeCA9IGV2ZW50LmNsaWVudFggLSB0aGlzLnJlc2l6aW5nLnN0YXJ0TW91c2VYO1xuICAgIGNvbnN0IGR5ID0gZXZlbnQuY2xpZW50WSAtIHRoaXMucmVzaXppbmcuc3RhcnRNb3VzZVk7XG5cbiAgICBsZXQgbmV3Q29scyA9IE1hdGgubWF4KHRoaXMubWluSXRlbUNvbHMsIE1hdGgucm91bmQoKHRoaXMuY29sc1RvUGl4ZWxXaWR0aCh0aGlzLnJlc2l6aW5nLnN0YXJ0Q29scykgKyBkeCkgLyAodGhpcy5jZWxsV2lkdGggKyB0aGlzLmdhcCkpKTtcbiAgICBsZXQgbmV3Um93cyA9IE1hdGgubWF4KHRoaXMubWluSXRlbVJvd3MsIE1hdGgucm91bmQoKHRoaXMucm93c1RvUGl4ZWxIZWlnaHQodGhpcy5yZXNpemluZy5zdGFydFJvd3MpICsgZHkpIC8gKHRoaXMucm93SGVpZ2h0ICsgdGhpcy5nYXApKSk7XG4gICAgbmV3Q29scyA9IE1hdGgubWluKG5ld0NvbHMsIHRoaXMuY29sdW1ucyAtIHdpZGdldC54KTtcblxuICAgIHRoaXMucmVzaXppbmcuY3VycmVudFBpeGVsVyA9IHRoaXMuY29sc1RvUGl4ZWxXaWR0aChuZXdDb2xzKTtcbiAgICB0aGlzLnJlc2l6aW5nLmN1cnJlbnRQaXhlbEggPSB0aGlzLnJvd3NUb1BpeGVsSGVpZ2h0KG5ld1Jvd3MpO1xuXG4gICAgY29uc3QgcmVzb2x2ZWQgPSBHcmlkRW5naW5lLnJlc2l6ZVdpZGdldChcbiAgICAgIHRoaXMucHJldmlld1dpZGdldHMsXG4gICAgICB7IGlkOiB3aWRnZXQuaWQsIHg6IHdpZGdldC54LCB5OiB3aWRnZXQueSwgY29sczogd2lkZ2V0LmNvbHMsIHJvd3M6IHdpZGdldC5yb3dzIH0sXG4gICAgICBuZXdDb2xzLCBuZXdSb3dzLCB0aGlzLmNvbHVtbnNcbiAgICApO1xuXG4gICAgdGhpcy5wbGFjZWhvbGRlciA9IHtcbiAgICAgIGxlZnQ6IHRoaXMuY29sVG9QaXhlbCh3aWRnZXQueCksIHRvcDogdGhpcy5yb3dUb1BpeGVsKHdpZGdldC55KSxcbiAgICAgIHdpZHRoOiB0aGlzLmNvbHNUb1BpeGVsV2lkdGgobmV3Q29scyksXG4gICAgICBoZWlnaHQ6IHRoaXMucm93c1RvUGl4ZWxIZWlnaHQobmV3Um93cyksXG4gICAgfTtcblxuICAgIHRoaXMuem9uZS5ydW4oKCkgPT4ge1xuICAgICAgZm9yIChjb25zdCBydyBvZiByZXNvbHZlZCkge1xuICAgICAgICBpZiAocncuaWQgPT09IHdpZGdldC5pZCkgY29udGludWU7XG4gICAgICAgIGNvbnN0IHcgPSB0aGlzLndpZGdldHMuZmluZCh3dyA9PiB3dy5pZCA9PT0gcncuaWQpO1xuICAgICAgICBpZiAodykgeyB3LnggPSBydy54OyB3LnkgPSBydy55OyB9XG4gICAgICB9XG4gICAgICB0aGlzLnVwZGF0ZUNvbnRhaW5lckhlaWdodCgpO1xuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGZpbmFsaXplUmVzaXplKCkge1xuICAgIGlmICghdGhpcy5yZXNpemluZykgcmV0dXJuO1xuICAgIGNvbnN0IHdpZGdldCA9IHRoaXMud2lkZ2V0cy5maW5kKHcgPT4gdy5pZCA9PT0gdGhpcy5yZXNpemluZyEuaWQpITtcblxuICAgIGxldCBuZXdDb2xzID0gTWF0aC5tYXgodGhpcy5taW5JdGVtQ29scywgTWF0aC5yb3VuZCh0aGlzLnJlc2l6aW5nLmN1cnJlbnRQaXhlbFcgLyAodGhpcy5jZWxsV2lkdGggKyB0aGlzLmdhcCkpKTtcbiAgICBsZXQgbmV3Um93cyA9IE1hdGgubWF4KHRoaXMubWluSXRlbVJvd3MsIE1hdGgucm91bmQodGhpcy5yZXNpemluZy5jdXJyZW50UGl4ZWxIIC8gKHRoaXMucm93SGVpZ2h0ICsgdGhpcy5nYXApKSk7XG4gICAgbmV3Q29scyA9IE1hdGgubWluKG5ld0NvbHMsIHRoaXMuY29sdW1ucyAtIHdpZGdldC54KTtcblxuICAgIGNvbnN0IHJlc29sdmVkID0gR3JpZEVuZ2luZS5yZXNpemVXaWRnZXQoXG4gICAgICB0aGlzLndpZGdldHMubWFwKHcgPT4gKHsgaWQ6IHcuaWQsIHg6IHcueCwgeTogdy55LCBjb2xzOiB3LmNvbHMsIHJvd3M6IHcucm93cyB9KSksXG4gICAgICB7IGlkOiB3aWRnZXQuaWQsIHg6IHdpZGdldC54LCB5OiB3aWRnZXQueSwgY29sczogd2lkZ2V0LmNvbHMsIHJvd3M6IHdpZGdldC5yb3dzIH0sXG4gICAgICBuZXdDb2xzLCBuZXdSb3dzLCB0aGlzLmNvbHVtbnNcbiAgICApO1xuICAgIGZvciAoY29uc3Qgcncgb2YgcmVzb2x2ZWQpIHtcbiAgICAgIGNvbnN0IHcgPSB0aGlzLndpZGdldHMuZmluZCh3dyA9PiB3dy5pZCA9PT0gcncuaWQpO1xuICAgICAgaWYgKHcpIHsgdy54ID0gcncueDsgdy55ID0gcncueTsgdy5jb2xzID0gcncuY29sczsgdy5yb3dzID0gcncucm93czsgdGhpcy5pdGVtQ2hhbmdlZC5lbWl0KHcpOyB9XG4gICAgfVxuICAgIHRoaXMucmVzaXppbmcgPSBudWxsO1xuICAgIHRoaXMucGxhY2Vob2xkZXIgPSBudWxsO1xuICAgIHRoaXMucHJldmlld1dpZGdldHMgPSBbXTtcbiAgICB0aGlzLnVwZGF0ZUNvbnRhaW5lckhlaWdodCgpO1xuICAgIHRoaXMubGF5b3V0Q2hhbmdlZC5lbWl0KHRoaXMud2lkZ2V0cyk7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICAvLyDilIDilIAgVXRpbGl0aWVzIOKUgOKUgFxuXG4gIHByaXZhdGUgY29tcGFjdEFuZEFwcGx5KCkge1xuICAgIGlmICghdGhpcy53aWRnZXRzPy5sZW5ndGgpIHJldHVybjtcbiAgICBjb25zdCBjb21wYWN0ZWQgPSBHcmlkRW5naW5lLmNvbXBhY3QoXG4gICAgICB0aGlzLndpZGdldHMubWFwKHcgPT4gKHsgaWQ6IHcuaWQsIHg6IHcueCwgeTogdy55LCBjb2xzOiB3LmNvbHMsIHJvd3M6IHcucm93cyB9KSksXG4gICAgICB0aGlzLmNvbHVtbnNcbiAgICApO1xuICAgIGZvciAoY29uc3Qgcncgb2YgY29tcGFjdGVkKSB7XG4gICAgICBjb25zdCB3ID0gdGhpcy53aWRnZXRzLmZpbmQod3cgPT4gd3cuaWQgPT09IHJ3LmlkKTtcbiAgICAgIGlmICh3KSB7IHcueCA9IHJ3Lng7IHcueSA9IHJ3Lnk7IH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZUNvbnRhaW5lckhlaWdodCgpIHtcbiAgICBpZiAoIXRoaXMud2lkZ2V0cz8ubGVuZ3RoKSB7IHRoaXMuY29udGFpbmVySGVpZ2h0ID0gNDAwOyByZXR1cm47IH1cbiAgICBjb25zdCBtYXhSb3cgPSBHcmlkRW5naW5lLmdldEdyaWRIZWlnaHQoXG4gICAgICB0aGlzLndpZGdldHMubWFwKHcgPT4gKHsgaWQ6IHcuaWQsIHg6IHcueCwgeTogdy55LCBjb2xzOiB3LmNvbHMsIHJvd3M6IHcucm93cyB9KSlcbiAgICApO1xuICAgIHRoaXMuY29udGFpbmVySGVpZ2h0ID0gdGhpcy5yb3dUb1BpeGVsKG1heFJvdykgKyB0aGlzLnJvd0hlaWdodCArIHRoaXMuZ2FwO1xuICB9XG59XG4iXX0=
|