@schneideress/dashboardframework 13.0.0 → 17.0.2

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.
Files changed (94) hide show
  1. package/README.md +7 -7
  2. package/esm2022/gridster/index.mjs +12 -0
  3. package/esm2022/gridster/lib/gridster.component.mjs +627 -0
  4. package/esm2022/gridster/lib/gridster.interface.mjs +3 -0
  5. package/esm2022/gridster/lib/gridster.module.mjs +17 -0
  6. package/esm2022/gridster/lib/gridsterCompact.service.mjs +126 -0
  7. package/esm2022/gridster/lib/gridsterConfig.constant.mjs +118 -0
  8. package/esm2022/gridster/lib/gridsterConfig.interface.mjs +37 -0
  9. package/esm2022/gridster/lib/gridsterConfigS.interface.mjs +2 -0
  10. package/esm2022/gridster/lib/gridsterDraggable.service.mjs +405 -0
  11. package/esm2022/gridster/lib/gridsterEmptyCell.service.mjs +255 -0
  12. package/esm2022/gridster/lib/gridsterItem.component.mjs +228 -0
  13. package/esm2022/gridster/lib/gridsterItem.interface.mjs +3 -0
  14. package/esm2022/gridster/lib/gridsterPreview.component.mjs +36 -0
  15. package/esm2022/gridster/lib/gridsterPush.service.mjs +316 -0
  16. package/esm2022/gridster/lib/gridsterPushResize.service.mjs +225 -0
  17. package/esm2022/gridster/lib/gridsterRenderer.interface.mjs +2 -0
  18. package/esm2022/gridster/lib/gridsterRenderer.service.mjs +274 -0
  19. package/esm2022/gridster/lib/gridsterResizable.service.mjs +470 -0
  20. package/esm2022/gridster/lib/gridsterResizeEventType.interface.mjs +2 -0
  21. package/esm2022/gridster/lib/gridsterScroll.service.mjs +134 -0
  22. package/esm2022/gridster/lib/gridsterSwap.service.mjs +87 -0
  23. package/esm2022/gridster/lib/gridsterUtils.service.mjs +92 -0
  24. package/esm2022/lib/custom.notifier.options.mjs +41 -0
  25. package/esm2022/lib/ra-dashboard-area/ra.dashboard.area.mjs +460 -0
  26. package/esm2022/lib/ra-widget-container/lock-tooltip/lock.tooltip.component.mjs +43 -0
  27. package/esm2022/lib/ra-widget-container/ra.widget.container.component.mjs +767 -0
  28. package/esm2022/lib/ra.base.dashboard.filter.mjs +41 -0
  29. package/esm2022/lib/ra.base.dashboard.template.mjs +33 -0
  30. package/esm2022/lib/ra.dashbard.event.bus.mjs +46 -0
  31. package/esm2022/lib/ra.dashboard.module.mjs +55 -0
  32. package/esm2022/lib/ra.dashboard.responsive.service.mjs +139 -0
  33. package/esm2022/lib/ra.dashboard.service.mjs +77 -0
  34. package/esm2022/lib/ra.event.enum.mjs +60 -0
  35. package/esm2022/lib/ra.gridster.config.mjs +56 -0
  36. package/esm2022/public-api.mjs +13 -0
  37. package/esm2022/schneideress-dashboardframework.mjs +5 -0
  38. package/fesm2022/schneideress-dashboardframework.mjs +5198 -0
  39. package/fesm2022/schneideress-dashboardframework.mjs.map +1 -0
  40. package/gridster/index.d.ts +9 -0
  41. package/gridster/lib/gridster.component.d.ts +79 -0
  42. package/gridster/lib/gridster.interface.d.ts +49 -0
  43. package/gridster/lib/gridster.module.d.ts +8 -0
  44. package/gridster/lib/gridsterCompact.service.d.ts +11 -0
  45. package/gridster/lib/gridsterConfig.constant.d.ts +2 -0
  46. package/gridster/lib/gridsterConfig.interface.d.ts +155 -0
  47. package/gridster/lib/gridsterConfigS.interface.d.ts +107 -0
  48. package/gridster/lib/gridsterDraggable.service.d.ts +68 -0
  49. package/gridster/lib/gridsterEmptyCell.service.d.ts +31 -0
  50. package/gridster/lib/gridsterItem.component.d.ts +61 -0
  51. package/gridster/lib/gridsterItem.interface.d.ts +67 -0
  52. package/gridster/lib/gridsterPreview.component.d.ts +17 -0
  53. package/gridster/lib/gridsterPush.service.d.ts +34 -0
  54. package/gridster/lib/gridsterPushResize.service.d.ts +26 -0
  55. package/gridster/lib/gridsterRenderer.interface.d.ts +14 -0
  56. package/gridster/lib/gridsterRenderer.service.d.ts +37 -0
  57. package/gridster/lib/gridsterResizable.service.d.ts +86 -0
  58. package/gridster/lib/gridsterResizeEventType.interface.d.ts +6 -0
  59. package/gridster/lib/gridsterScroll.service.d.ts +7 -0
  60. package/gridster/lib/gridsterSwap.service.d.ts +13 -0
  61. package/gridster/lib/gridsterUtils.service.d.ts +16 -0
  62. package/{schneideress-dashboardframework.d.ts → index.d.ts} +5 -5
  63. package/lib/custom.notifier.options.d.ts +2 -2
  64. package/lib/ra-dashboard-area/ra.dashboard.area.d.ts +88 -88
  65. package/lib/ra-widget-container/lock-tooltip/lock.tooltip.component.d.ts +20 -20
  66. package/lib/ra-widget-container/ra.widget.container.component.d.ts +142 -142
  67. package/lib/ra.base.dashboard.filter.d.ts +17 -17
  68. package/lib/ra.base.dashboard.template.d.ts +18 -18
  69. package/lib/ra.dashbard.event.bus.d.ts +23 -23
  70. package/lib/ra.dashboard.module.d.ts +16 -17
  71. package/lib/ra.dashboard.responsive.service.d.ts +24 -24
  72. package/lib/ra.dashboard.service.d.ts +25 -25
  73. package/lib/ra.event.enum.d.ts +57 -57
  74. package/lib/ra.gridster.config.d.ts +2 -2
  75. package/package.json +11 -17
  76. package/public-api.d.ts +9 -9
  77. package/esm2020/lib/custom.notifier.options.mjs +0 -41
  78. package/esm2020/lib/ra-dashboard-area/ra.dashboard.area.mjs +0 -445
  79. package/esm2020/lib/ra-widget-container/lock-tooltip/lock.tooltip.component.mjs +0 -43
  80. package/esm2020/lib/ra-widget-container/ra.widget.container.component.mjs +0 -767
  81. package/esm2020/lib/ra.base.dashboard.filter.mjs +0 -44
  82. package/esm2020/lib/ra.base.dashboard.template.mjs +0 -36
  83. package/esm2020/lib/ra.dashbard.event.bus.mjs +0 -46
  84. package/esm2020/lib/ra.dashboard.module.mjs +0 -64
  85. package/esm2020/lib/ra.dashboard.responsive.service.mjs +0 -136
  86. package/esm2020/lib/ra.dashboard.service.mjs +0 -77
  87. package/esm2020/lib/ra.event.enum.mjs +0 -60
  88. package/esm2020/lib/ra.gridster.config.mjs +0 -56
  89. package/esm2020/public-api.mjs +0 -15
  90. package/esm2020/schneideress-dashboardframework.mjs +0 -5
  91. package/fesm2015/schneideress-dashboardframework.mjs +0 -1800
  92. package/fesm2015/schneideress-dashboardframework.mjs.map +0 -1
  93. package/fesm2020/schneideress-dashboardframework.mjs +0 -1790
  94. package/fesm2020/schneideress-dashboardframework.mjs.map +0 -1
@@ -0,0 +1,627 @@
1
+ import { NgForOf, NgStyle } from '@angular/common';
2
+ import { ChangeDetectorRef, Component, ElementRef, EventEmitter, Inject, Input, NgZone, Renderer2, ViewEncapsulation } from '@angular/core';
3
+ import { debounceTime, Subject, switchMap, takeUntil, timer } from 'rxjs';
4
+ import { GridsterCompact } from './gridsterCompact.service';
5
+ import { GridsterConfigService } from './gridsterConfig.constant';
6
+ import { GridType } from './gridsterConfig.interface';
7
+ import { GridsterEmptyCell } from './gridsterEmptyCell.service';
8
+ import { GridsterPreviewComponent } from './gridsterPreview.component';
9
+ import { GridsterRenderer } from './gridsterRenderer.service';
10
+ import { GridsterUtils } from './gridsterUtils.service';
11
+ import * as i0 from "@angular/core";
12
+ export class GridsterComponent {
13
+ constructor(el, renderer, cdRef, zone) {
14
+ this.renderer = renderer;
15
+ this.cdRef = cdRef;
16
+ this.zone = zone;
17
+ this.columns = 0;
18
+ this.rows = 0;
19
+ this.gridColumns = [];
20
+ this.gridRows = [];
21
+ this.previewStyle$ = new EventEmitter();
22
+ this.calculateLayout$ = new Subject();
23
+ this.resize$ = new Subject();
24
+ this.destroy$ = new Subject();
25
+ this.optionsChanged = () => {
26
+ this.setOptions();
27
+ let widgetsIndex = this.grid.length - 1;
28
+ let widget;
29
+ for (; widgetsIndex >= 0; widgetsIndex--) {
30
+ widget = this.grid[widgetsIndex];
31
+ widget.updateOptions();
32
+ }
33
+ this.calculateLayout();
34
+ };
35
+ this.onResize = () => {
36
+ if (this.el.clientWidth) {
37
+ if (this.options.setGridSize) {
38
+ // reset width/height so the size is recalculated afterwards
39
+ this.renderer.setStyle(this.el, 'width', '');
40
+ this.renderer.setStyle(this.el, 'height', '');
41
+ }
42
+ this.setGridSize();
43
+ this.calculateLayout();
44
+ }
45
+ };
46
+ this.getNextPossiblePosition = (newItem, startingFrom = {}) => {
47
+ if (newItem.cols === -1) {
48
+ newItem.cols = this.$options.defaultItemCols;
49
+ }
50
+ if (newItem.rows === -1) {
51
+ newItem.rows = this.$options.defaultItemRows;
52
+ }
53
+ this.setGridDimensions();
54
+ let rowsIndex = startingFrom.y || 0;
55
+ let colsIndex;
56
+ for (; rowsIndex < this.rows; rowsIndex++) {
57
+ newItem.y = rowsIndex;
58
+ colsIndex = startingFrom.x || 0;
59
+ for (; colsIndex < this.columns; colsIndex++) {
60
+ newItem.x = colsIndex;
61
+ if (!this.checkCollision(newItem)) {
62
+ return true;
63
+ }
64
+ }
65
+ }
66
+ const canAddToRows = this.$options.maxRows >= this.rows + newItem.rows;
67
+ const canAddToColumns = this.$options.maxCols >= this.columns + newItem.cols;
68
+ const addToRows = this.rows <= this.columns && canAddToRows;
69
+ if (!addToRows && canAddToColumns) {
70
+ newItem.x = this.columns;
71
+ newItem.y = 0;
72
+ return true;
73
+ }
74
+ else if (canAddToRows) {
75
+ newItem.y = this.rows;
76
+ newItem.x = 0;
77
+ return true;
78
+ }
79
+ return false;
80
+ };
81
+ this.getFirstPossiblePosition = (item) => {
82
+ const tmpItem = Object.assign({}, item);
83
+ this.getNextPossiblePosition(tmpItem);
84
+ return tmpItem;
85
+ };
86
+ this.getLastPossiblePosition = (item) => {
87
+ let farthestItem = { y: 0, x: 0 };
88
+ farthestItem = this.grid.reduce((prev, curr) => {
89
+ const currCoords = {
90
+ y: curr.$item.y + curr.$item.rows - 1,
91
+ x: curr.$item.x + curr.$item.cols - 1
92
+ };
93
+ if (GridsterUtils.compareItems(prev, currCoords) === 1) {
94
+ return currCoords;
95
+ }
96
+ else {
97
+ return prev;
98
+ }
99
+ }, farthestItem);
100
+ const tmpItem = Object.assign({}, item);
101
+ this.getNextPossiblePosition(tmpItem, farthestItem);
102
+ return tmpItem;
103
+ };
104
+ this.el = el.nativeElement;
105
+ this.$options = JSON.parse(JSON.stringify(GridsterConfigService));
106
+ this.mobile = false;
107
+ this.curWidth = 0;
108
+ this.curHeight = 0;
109
+ this.grid = [];
110
+ this.curColWidth = 0;
111
+ this.curRowHeight = 0;
112
+ this.dragInProgress = false;
113
+ this.emptyCell = new GridsterEmptyCell(this);
114
+ this.compact = new GridsterCompact(this);
115
+ this.gridRenderer = new GridsterRenderer(this);
116
+ }
117
+ // ------ Function for swapWhileDragging option
118
+ // identical to checkCollision() except that here we add boundaries.
119
+ static checkCollisionTwoItemsForSwaping(item, item2) {
120
+ // if the cols or rows of the items are 1 , doesnt make any sense to set a boundary. Only if the item is bigger we set a boundary
121
+ const horizontalBoundaryItem1 = item.cols === 1 ? 0 : 1;
122
+ const horizontalBoundaryItem2 = item2.cols === 1 ? 0 : 1;
123
+ const verticalBoundaryItem1 = item.rows === 1 ? 0 : 1;
124
+ const verticalBoundaryItem2 = item2.rows === 1 ? 0 : 1;
125
+ return (item.x + horizontalBoundaryItem1 < item2.x + item2.cols &&
126
+ item.x + item.cols > item2.x + horizontalBoundaryItem2 &&
127
+ item.y + verticalBoundaryItem1 < item2.y + item2.rows &&
128
+ item.y + item.rows > item2.y + verticalBoundaryItem2);
129
+ }
130
+ checkCollisionTwoItems(item, item2) {
131
+ const collision = item.x < item2.x + item2.cols &&
132
+ item.x + item.cols > item2.x &&
133
+ item.y < item2.y + item2.rows &&
134
+ item.y + item.rows > item2.y;
135
+ if (!collision) {
136
+ return false;
137
+ }
138
+ if (!this.$options.allowMultiLayer) {
139
+ return true;
140
+ }
141
+ const defaultLayerIndex = this.$options.defaultLayerIndex;
142
+ const layerIndex = item.layerIndex === undefined ? defaultLayerIndex : item.layerIndex;
143
+ const layerIndex2 = item2.layerIndex === undefined ? defaultLayerIndex : item2.layerIndex;
144
+ return layerIndex === layerIndex2;
145
+ }
146
+ ngOnInit() {
147
+ if (this.options.initCallback) {
148
+ this.options.initCallback(this);
149
+ }
150
+ this.calculateLayout$
151
+ .pipe(debounceTime(0), takeUntil(this.destroy$))
152
+ .subscribe(() => this.calculateLayout());
153
+ this.resize$
154
+ .pipe(
155
+ // Cancel previously scheduled DOM timer if `calculateLayout()` has been called
156
+ // within this time range.
157
+ switchMap(() => timer(100)), takeUntil(this.destroy$))
158
+ .subscribe(() => this.resize());
159
+ }
160
+ ngOnChanges(changes) {
161
+ if (changes.options) {
162
+ this.setOptions();
163
+ this.options.api = {
164
+ optionsChanged: this.optionsChanged.bind(this),
165
+ resize: this.onResize.bind(this),
166
+ getNextPossiblePosition: this.getNextPossiblePosition.bind(this),
167
+ getFirstPossiblePosition: this.getFirstPossiblePosition.bind(this),
168
+ getLastPossiblePosition: this.getLastPossiblePosition.bind(this),
169
+ getItemComponent: (item) => this.getItemComponent(item),
170
+ getCurrentRowHeight: this.getCurrentRowHeight.bind(this)
171
+ };
172
+ this.columns = this.$options.minCols;
173
+ this.rows = this.$options.minRows + this.$options.addEmptyRowsCount;
174
+ this.setGridSize();
175
+ this.calculateLayout();
176
+ }
177
+ }
178
+ getCurrentRowHeight() {
179
+ return this.curRowHeight;
180
+ }
181
+ resize() {
182
+ let height;
183
+ let width;
184
+ if (this.$options.gridType === 'fit' && !this.mobile) {
185
+ width = this.el.offsetWidth;
186
+ height = this.el.offsetHeight;
187
+ }
188
+ else {
189
+ width = this.el.clientWidth;
190
+ height = this.el.clientHeight;
191
+ }
192
+ if ((width !== this.curWidth || height !== this.curHeight) &&
193
+ this.checkIfToResize()) {
194
+ this.onResize();
195
+ }
196
+ }
197
+ setOptions() {
198
+ this.$options = GridsterUtils.merge(this.$options, this.options, this.$options);
199
+ if (!this.$options.disableWindowResize && !this.windowResize) {
200
+ this.windowResize = this.renderer.listen('window', 'resize', this.onResize);
201
+ }
202
+ else if (this.$options.disableWindowResize && this.windowResize) {
203
+ this.windowResize();
204
+ this.windowResize = null;
205
+ }
206
+ this.emptyCell.updateOptions();
207
+ }
208
+ ngOnDestroy() {
209
+ this.destroy$.next();
210
+ this.previewStyle$.complete();
211
+ if (this.windowResize) {
212
+ this.windowResize();
213
+ }
214
+ if (this.options && this.options.destroyCallback) {
215
+ this.options.destroyCallback(this);
216
+ }
217
+ if (this.options && this.options.api) {
218
+ this.options.api.resize = undefined;
219
+ this.options.api.optionsChanged = undefined;
220
+ this.options.api.getNextPossiblePosition = undefined;
221
+ this.options.api = undefined;
222
+ }
223
+ this.emptyCell.destroy();
224
+ this.emptyCell = null;
225
+ this.compact.destroy();
226
+ this.compact = null;
227
+ }
228
+ checkIfToResize() {
229
+ const clientWidth = this.el.clientWidth;
230
+ const offsetWidth = this.el.offsetWidth;
231
+ const scrollWidth = this.el.scrollWidth;
232
+ const clientHeight = this.el.clientHeight;
233
+ const offsetHeight = this.el.offsetHeight;
234
+ const scrollHeight = this.el.scrollHeight;
235
+ const verticalScrollPresent = clientWidth < offsetWidth &&
236
+ scrollHeight > offsetHeight &&
237
+ scrollHeight - offsetHeight < offsetWidth - clientWidth;
238
+ const horizontalScrollPresent = clientHeight < offsetHeight &&
239
+ scrollWidth > offsetWidth &&
240
+ scrollWidth - offsetWidth < offsetHeight - clientHeight;
241
+ if (verticalScrollPresent) {
242
+ return false;
243
+ }
244
+ return !horizontalScrollPresent;
245
+ }
246
+ checkIfMobile() {
247
+ if (this.$options.useBodyForBreakpoint) {
248
+ return this.$options.mobileBreakpoint > document.body.clientWidth;
249
+ }
250
+ else {
251
+ return this.$options.mobileBreakpoint > this.curWidth;
252
+ }
253
+ }
254
+ setGridSize() {
255
+ const el = this.el;
256
+ let width;
257
+ let height;
258
+ if (this.$options.setGridSize ||
259
+ (this.$options.gridType === GridType.Fit && !this.mobile)) {
260
+ width = el.offsetWidth;
261
+ height = el.offsetHeight;
262
+ }
263
+ else {
264
+ width = el.clientWidth;
265
+ height = el.clientHeight;
266
+ }
267
+ this.curWidth = width;
268
+ this.curHeight = height;
269
+ }
270
+ setGridDimensions() {
271
+ this.setGridSize();
272
+ if (!this.mobile && this.checkIfMobile()) {
273
+ this.mobile = !this.mobile;
274
+ this.renderer.addClass(this.el, 'mobile');
275
+ }
276
+ else if (this.mobile && !this.checkIfMobile()) {
277
+ this.mobile = !this.mobile;
278
+ this.renderer.removeClass(this.el, 'mobile');
279
+ }
280
+ let rows = this.$options.minRows;
281
+ let columns = this.$options.minCols;
282
+ let widgetsIndex = this.grid.length - 1;
283
+ let widget;
284
+ for (; widgetsIndex >= 0; widgetsIndex--) {
285
+ widget = this.grid[widgetsIndex];
286
+ if (!widget.notPlaced) {
287
+ rows = Math.max(rows, widget.$item.y + widget.$item.rows);
288
+ columns = Math.max(columns, widget.$item.x + widget.$item.cols);
289
+ }
290
+ }
291
+ rows += this.$options.addEmptyRowsCount;
292
+ if (this.columns !== columns || this.rows !== rows) {
293
+ this.columns = columns;
294
+ this.rows = rows;
295
+ if (this.options.gridSizeChangedCallback) {
296
+ this.options.gridSizeChangedCallback(this);
297
+ }
298
+ }
299
+ }
300
+ calculateLayout() {
301
+ if (this.compact) {
302
+ this.compact.checkCompact();
303
+ }
304
+ this.setGridDimensions();
305
+ if (this.$options.outerMargin) {
306
+ let marginWidth = -this.$options.margin;
307
+ if (this.$options.outerMarginLeft !== null) {
308
+ marginWidth += this.$options.outerMarginLeft;
309
+ this.renderer.setStyle(this.el, 'padding-left', this.$options.outerMarginLeft + 'px');
310
+ }
311
+ else {
312
+ marginWidth += this.$options.margin;
313
+ this.renderer.setStyle(this.el, 'padding-left', this.$options.margin + 'px');
314
+ }
315
+ if (this.$options.outerMarginRight !== null) {
316
+ marginWidth += this.$options.outerMarginRight;
317
+ this.renderer.setStyle(this.el, 'padding-right', this.$options.outerMarginRight + 'px');
318
+ }
319
+ else {
320
+ marginWidth += this.$options.margin;
321
+ this.renderer.setStyle(this.el, 'padding-right', this.$options.margin + 'px');
322
+ }
323
+ this.curColWidth = (this.curWidth - marginWidth) / this.columns;
324
+ let marginHeight = -this.$options.margin;
325
+ if (this.$options.outerMarginTop !== null) {
326
+ marginHeight += this.$options.outerMarginTop;
327
+ this.renderer.setStyle(this.el, 'padding-top', this.$options.outerMarginTop + 'px');
328
+ }
329
+ else {
330
+ marginHeight += this.$options.margin;
331
+ this.renderer.setStyle(this.el, 'padding-top', this.$options.margin + 'px');
332
+ }
333
+ if (this.$options.outerMarginBottom !== null) {
334
+ marginHeight += this.$options.outerMarginBottom;
335
+ this.renderer.setStyle(this.el, 'padding-bottom', this.$options.outerMarginBottom + 'px');
336
+ }
337
+ else {
338
+ marginHeight += this.$options.margin;
339
+ this.renderer.setStyle(this.el, 'padding-bottom', this.$options.margin + 'px');
340
+ }
341
+ this.curRowHeight =
342
+ ((this.curHeight - marginHeight) / this.rows) *
343
+ this.$options.rowHeightRatio;
344
+ }
345
+ else {
346
+ this.curColWidth = (this.curWidth + this.$options.margin) / this.columns;
347
+ this.curRowHeight =
348
+ ((this.curHeight + this.$options.margin) / this.rows) *
349
+ this.$options.rowHeightRatio;
350
+ this.renderer.setStyle(this.el, 'padding-left', 0 + 'px');
351
+ this.renderer.setStyle(this.el, 'padding-right', 0 + 'px');
352
+ this.renderer.setStyle(this.el, 'padding-top', 0 + 'px');
353
+ this.renderer.setStyle(this.el, 'padding-bottom', 0 + 'px');
354
+ }
355
+ this.gridRenderer.updateGridster();
356
+ if (this.$options.setGridSize) {
357
+ this.renderer.addClass(this.el, 'gridSize');
358
+ if (!this.mobile) {
359
+ this.renderer.setStyle(this.el, 'width', this.columns * this.curColWidth + this.$options.margin + 'px');
360
+ this.renderer.setStyle(this.el, 'height', this.rows * this.curRowHeight + this.$options.margin + 'px');
361
+ }
362
+ }
363
+ else {
364
+ this.renderer.removeClass(this.el, 'gridSize');
365
+ this.renderer.setStyle(this.el, 'width', '');
366
+ this.renderer.setStyle(this.el, 'height', '');
367
+ }
368
+ this.updateGrid();
369
+ let widgetsIndex = this.grid.length - 1;
370
+ let widget;
371
+ for (; widgetsIndex >= 0; widgetsIndex--) {
372
+ widget = this.grid[widgetsIndex];
373
+ widget.setSize();
374
+ widget.drag.toggle();
375
+ widget.resize.toggle();
376
+ }
377
+ this.resize$.next();
378
+ }
379
+ updateGrid() {
380
+ if (this.$options.displayGrid === 'always' && !this.mobile) {
381
+ this.renderer.addClass(this.el, 'display-grid');
382
+ }
383
+ else if (this.$options.displayGrid === 'onDrag&Resize' &&
384
+ this.dragInProgress) {
385
+ this.renderer.addClass(this.el, 'display-grid');
386
+ }
387
+ else if (this.$options.displayGrid === 'none' ||
388
+ !this.dragInProgress ||
389
+ this.mobile) {
390
+ this.renderer.removeClass(this.el, 'display-grid');
391
+ }
392
+ this.setGridDimensions();
393
+ this.gridColumns.length = GridsterComponent.getNewArrayLength(this.columns, this.curWidth, this.curColWidth);
394
+ this.gridRows.length = GridsterComponent.getNewArrayLength(this.rows, this.curHeight, this.curRowHeight);
395
+ this.cdRef.markForCheck();
396
+ }
397
+ addItem(itemComponent) {
398
+ if (itemComponent.$item.cols === undefined) {
399
+ itemComponent.$item.cols = this.$options.defaultItemCols;
400
+ itemComponent.item.cols = itemComponent.$item.cols;
401
+ itemComponent.itemChanged();
402
+ }
403
+ if (itemComponent.$item.rows === undefined) {
404
+ itemComponent.$item.rows = this.$options.defaultItemRows;
405
+ itemComponent.item.rows = itemComponent.$item.rows;
406
+ itemComponent.itemChanged();
407
+ }
408
+ if (itemComponent.$item.x === -1 || itemComponent.$item.y === -1) {
409
+ this.autoPositionItem(itemComponent);
410
+ }
411
+ else if (this.checkCollision(itemComponent.$item)) {
412
+ if (!this.$options.disableWarnings) {
413
+ itemComponent.notPlaced = true;
414
+ console.warn("Can't be placed in the bounds of the dashboard, trying to auto position!/n" +
415
+ JSON.stringify(itemComponent.item, ['cols', 'rows', 'x', 'y']));
416
+ }
417
+ if (!this.$options.disableAutoPositionOnConflict) {
418
+ this.autoPositionItem(itemComponent);
419
+ }
420
+ else {
421
+ itemComponent.notPlaced = true;
422
+ }
423
+ }
424
+ this.grid.push(itemComponent);
425
+ this.calculateLayout$.next();
426
+ }
427
+ removeItem(itemComponent) {
428
+ this.grid.splice(this.grid.indexOf(itemComponent), 1);
429
+ this.calculateLayout$.next();
430
+ if (this.options.itemRemovedCallback) {
431
+ this.options.itemRemovedCallback(itemComponent.item, itemComponent);
432
+ }
433
+ }
434
+ checkCollision(item) {
435
+ let collision = false;
436
+ if (this.options.itemValidateCallback) {
437
+ collision = !this.options.itemValidateCallback(item);
438
+ }
439
+ if (!collision && this.checkGridCollision(item)) {
440
+ collision = true;
441
+ }
442
+ if (!collision) {
443
+ const c = this.findItemWithItem(item);
444
+ if (c) {
445
+ collision = c;
446
+ }
447
+ }
448
+ return collision;
449
+ }
450
+ checkGridCollision(item) {
451
+ const noNegativePosition = item.y > -1 && item.x > -1;
452
+ const maxGridCols = item.cols + item.x <= this.$options.maxCols;
453
+ const maxGridRows = item.rows + item.y <= this.$options.maxRows;
454
+ const maxItemCols = item.maxItemCols === undefined
455
+ ? this.$options.maxItemCols
456
+ : item.maxItemCols;
457
+ const minItemCols = item.minItemCols === undefined
458
+ ? this.$options.minItemCols
459
+ : item.minItemCols;
460
+ const maxItemRows = item.maxItemRows === undefined
461
+ ? this.$options.maxItemRows
462
+ : item.maxItemRows;
463
+ const minItemRows = item.minItemRows === undefined
464
+ ? this.$options.minItemRows
465
+ : item.minItemRows;
466
+ const inColsLimits = item.cols <= maxItemCols && item.cols >= minItemCols;
467
+ const inRowsLimits = item.rows <= maxItemRows && item.rows >= minItemRows;
468
+ const minAreaLimit = item.minItemArea === undefined
469
+ ? this.$options.minItemArea
470
+ : item.minItemArea;
471
+ const maxAreaLimit = item.maxItemArea === undefined
472
+ ? this.$options.maxItemArea
473
+ : item.maxItemArea;
474
+ const area = item.cols * item.rows;
475
+ const inMinArea = minAreaLimit <= area;
476
+ const inMaxArea = maxAreaLimit >= area;
477
+ return !(noNegativePosition &&
478
+ maxGridCols &&
479
+ maxGridRows &&
480
+ inColsLimits &&
481
+ inRowsLimits &&
482
+ inMinArea &&
483
+ inMaxArea);
484
+ }
485
+ findItemWithItem(item) {
486
+ let widgetsIndex = 0;
487
+ let widget;
488
+ for (; widgetsIndex < this.grid.length; widgetsIndex++) {
489
+ widget = this.grid[widgetsIndex];
490
+ if (widget.$item !== item &&
491
+ this.checkCollisionTwoItems(widget.$item, item)) {
492
+ return widget;
493
+ }
494
+ }
495
+ return false;
496
+ }
497
+ findItemsWithItem(item) {
498
+ const a = [];
499
+ let widgetsIndex = 0;
500
+ let widget;
501
+ for (; widgetsIndex < this.grid.length; widgetsIndex++) {
502
+ widget = this.grid[widgetsIndex];
503
+ if (widget.$item !== item &&
504
+ this.checkCollisionTwoItems(widget.$item, item)) {
505
+ a.push(widget);
506
+ }
507
+ }
508
+ return a;
509
+ }
510
+ autoPositionItem(itemComponent) {
511
+ if (this.getNextPossiblePosition(itemComponent.$item)) {
512
+ itemComponent.notPlaced = false;
513
+ itemComponent.item.x = itemComponent.$item.x;
514
+ itemComponent.item.y = itemComponent.$item.y;
515
+ itemComponent.itemChanged();
516
+ }
517
+ else {
518
+ itemComponent.notPlaced = true;
519
+ if (!this.$options.disableWarnings) {
520
+ console.warn("Can't be placed in the bounds of the dashboard!/n" +
521
+ JSON.stringify(itemComponent.item, ['cols', 'rows', 'x', 'y']));
522
+ }
523
+ }
524
+ }
525
+ pixelsToPositionX(x, roundingMethod, noLimit) {
526
+ const position = roundingMethod(x / this.curColWidth);
527
+ if (noLimit) {
528
+ return position;
529
+ }
530
+ else {
531
+ return Math.max(position, 0);
532
+ }
533
+ }
534
+ pixelsToPositionY(y, roundingMethod, noLimit) {
535
+ const position = roundingMethod(y / this.curRowHeight);
536
+ if (noLimit) {
537
+ return position;
538
+ }
539
+ else {
540
+ return Math.max(position, 0);
541
+ }
542
+ }
543
+ positionXToPixels(x) {
544
+ return x * this.curColWidth;
545
+ }
546
+ positionYToPixels(y) {
547
+ return y * this.curRowHeight;
548
+ }
549
+ getItemComponent(item) {
550
+ return this.grid.find(c => c.item === item);
551
+ }
552
+ // ------ Functions for swapWhileDragging option
553
+ // identical to checkCollision() except that this function calls findItemWithItemForSwaping() instead of findItemWithItem()
554
+ checkCollisionForSwaping(item) {
555
+ let collision = false;
556
+ if (this.options.itemValidateCallback) {
557
+ collision = !this.options.itemValidateCallback(item);
558
+ }
559
+ if (!collision && this.checkGridCollision(item)) {
560
+ collision = true;
561
+ }
562
+ if (!collision) {
563
+ const c = this.findItemWithItemForSwapping(item);
564
+ if (c) {
565
+ collision = c;
566
+ }
567
+ }
568
+ return collision;
569
+ }
570
+ // identical to findItemWithItem() except that this function calls checkCollisionTwoItemsForSwaping() instead of checkCollisionTwoItems()
571
+ findItemWithItemForSwapping(item) {
572
+ let widgetsIndex = this.grid.length - 1;
573
+ let widget;
574
+ for (; widgetsIndex > -1; widgetsIndex--) {
575
+ widget = this.grid[widgetsIndex];
576
+ if (widget.$item !== item &&
577
+ GridsterComponent.checkCollisionTwoItemsForSwaping(widget.$item, item)) {
578
+ return widget;
579
+ }
580
+ }
581
+ return false;
582
+ }
583
+ previewStyle(drag = false) {
584
+ if (this.movingItem) {
585
+ if (this.compact && drag) {
586
+ this.compact.checkCompactItem(this.movingItem);
587
+ }
588
+ this.previewStyle$.next(this.movingItem);
589
+ }
590
+ else {
591
+ this.previewStyle$.next(null);
592
+ }
593
+ }
594
+ // ------ End of functions for swapWhileDragging option
595
+ // eslint-disable-next-line @typescript-eslint/member-ordering
596
+ static getNewArrayLength(length, overallSize, size) {
597
+ const newLength = Math.max(length, Math.floor(overallSize / size));
598
+ if (newLength < 0) {
599
+ return 0;
600
+ }
601
+ if (Number.isFinite(newLength)) {
602
+ return Math.floor(newLength);
603
+ }
604
+ return 0;
605
+ }
606
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.1", ngImport: i0, type: GridsterComponent, deps: [{ token: ElementRef }, { token: Renderer2 }, { token: ChangeDetectorRef }, { token: NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
607
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.1", type: GridsterComponent, isStandalone: true, selector: "gridster", inputs: { options: "options" }, usesOnChanges: true, ngImport: i0, template: "<div\r\n class=\"gridster-column\"\r\n *ngFor=\"let column of gridColumns; let i = index;\"\r\n [ngStyle]=\"gridRenderer.getGridColumnStyle(i)\"\r\n></div>\r\n<div\r\n class=\"gridster-row\"\r\n *ngFor=\"let row of gridRows; let i = index;\"\r\n [ngStyle]=\"gridRenderer.getGridRowStyle(i)\"\r\n></div>\r\n<ng-content></ng-content>\r\n<gridster-preview\r\n [gridRenderer]=\"gridRenderer\"\r\n [previewStyle$]=\"previewStyle$\"\r\n class=\"gridster-preview\"\r\n></gridster-preview>\r\n", styles: ["gridster{position:relative;box-sizing:border-box;background:gray;width:100%;height:100%;-webkit-user-select:none;user-select:none;display:block}gridster.fit{overflow-x:hidden;overflow-y:hidden}gridster.scrollVertical{overflow-x:hidden;overflow-y:auto}gridster.scrollHorizontal{overflow-x:auto;overflow-y:hidden}gridster.fixed{overflow:auto}gridster.mobile{overflow-x:hidden;overflow-y:auto}gridster.mobile gridster-item{position:relative}gridster.gridSize{height:initial;width:initial}gridster.gridSize.fit{height:100%;width:100%}gridster .gridster-column,gridster .gridster-row{position:absolute;display:none;transition:.3s;box-sizing:border-box}gridster.display-grid .gridster-column,gridster.display-grid .gridster-row{display:block}gridster .gridster-column{border-left:1px solid white;border-right:1px solid white}gridster .gridster-row{border-top:1px solid white;border-bottom:1px solid white}\n"], dependencies: [{ kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: GridsterPreviewComponent, selector: "gridster-preview", inputs: ["previewStyle$", "gridRenderer"] }], encapsulation: i0.ViewEncapsulation.None }); }
608
+ }
609
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.1", ngImport: i0, type: GridsterComponent, decorators: [{
610
+ type: Component,
611
+ args: [{ selector: 'gridster', encapsulation: ViewEncapsulation.None, standalone: true, imports: [NgForOf, NgStyle, GridsterPreviewComponent], template: "<div\r\n class=\"gridster-column\"\r\n *ngFor=\"let column of gridColumns; let i = index;\"\r\n [ngStyle]=\"gridRenderer.getGridColumnStyle(i)\"\r\n></div>\r\n<div\r\n class=\"gridster-row\"\r\n *ngFor=\"let row of gridRows; let i = index;\"\r\n [ngStyle]=\"gridRenderer.getGridRowStyle(i)\"\r\n></div>\r\n<ng-content></ng-content>\r\n<gridster-preview\r\n [gridRenderer]=\"gridRenderer\"\r\n [previewStyle$]=\"previewStyle$\"\r\n class=\"gridster-preview\"\r\n></gridster-preview>\r\n", styles: ["gridster{position:relative;box-sizing:border-box;background:gray;width:100%;height:100%;-webkit-user-select:none;user-select:none;display:block}gridster.fit{overflow-x:hidden;overflow-y:hidden}gridster.scrollVertical{overflow-x:hidden;overflow-y:auto}gridster.scrollHorizontal{overflow-x:auto;overflow-y:hidden}gridster.fixed{overflow:auto}gridster.mobile{overflow-x:hidden;overflow-y:auto}gridster.mobile gridster-item{position:relative}gridster.gridSize{height:initial;width:initial}gridster.gridSize.fit{height:100%;width:100%}gridster .gridster-column,gridster .gridster-row{position:absolute;display:none;transition:.3s;box-sizing:border-box}gridster.display-grid .gridster-column,gridster.display-grid .gridster-row{display:block}gridster .gridster-column{border-left:1px solid white;border-right:1px solid white}gridster .gridster-row{border-top:1px solid white;border-bottom:1px solid white}\n"] }]
612
+ }], ctorParameters: () => [{ type: i0.ElementRef, decorators: [{
613
+ type: Inject,
614
+ args: [ElementRef]
615
+ }] }, { type: i0.Renderer2, decorators: [{
616
+ type: Inject,
617
+ args: [Renderer2]
618
+ }] }, { type: i0.ChangeDetectorRef, decorators: [{
619
+ type: Inject,
620
+ args: [ChangeDetectorRef]
621
+ }] }, { type: i0.NgZone, decorators: [{
622
+ type: Inject,
623
+ args: [NgZone]
624
+ }] }], propDecorators: { options: [{
625
+ type: Input
626
+ }] } });
627
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JpZHN0ZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvcmEtZGFzaGJvYXJkLWZyYW1ld29yay9zcmMvZ3JpZHN0ZXIvbGliL2dyaWRzdGVyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3JhLWRhc2hib2FyZC1mcmFtZXdvcmsvc3JjL2dyaWRzdGVyL2xpYi9ncmlkc3Rlci5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDbkQsT0FBTyxFQUNMLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixNQUFNLEVBQ04sS0FBSyxFQUNMLE1BQU0sRUFJTixTQUFTLEVBRVQsaUJBQWlCLEVBQ2xCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRTFFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUU1RCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNsRSxPQUFPLEVBQWtCLFFBQVEsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRXRFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBS2hFLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzlELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQzs7QUFXeEQsTUFBTSxPQUFPLGlCQUFpQjtJQTZCNUIsWUFDc0IsRUFBYyxFQUNSLFFBQW1CLEVBQ1gsS0FBd0IsRUFD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QVM7K0JBRUUsVUFBVSxpQkFHTCxpQkFBaUIsQ0FBQyxJQUFJLGNBQ3pCLElBQUksV0FDUCxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsd0JBQXdCLENBQUM7OzBCQWdDbEQsTUFBTTsyQkFBQyxVQUFVOzswQkFDakIsTUFBTTsyQkFBQyxTQUFTOzswQkFDaEIsTUFBTTsyQkFBQyxpQkFBaUI7OzBCQUN4QixNQUFNOzJCQUFDLE1BQU07eUNBL0JQLE9BQU87c0JBQWYsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE5nRm9yT2YsIE5nU3R5bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQge1xyXG4gIENoYW5nZURldGVjdG9yUmVmLFxyXG4gIENvbXBvbmVudCxcclxuICBFbGVtZW50UmVmLFxyXG4gIEV2ZW50RW1pdHRlcixcclxuICBJbmplY3QsXHJcbiAgSW5wdXQsXHJcbiAgTmdab25lLFxyXG4gIE9uQ2hhbmdlcyxcclxuICBPbkRlc3Ryb3ksXHJcbiAgT25Jbml0LFxyXG4gIFJlbmRlcmVyMixcclxuICBTaW1wbGVDaGFuZ2VzLFxyXG4gIFZpZXdFbmNhcHN1bGF0aW9uXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IGRlYm91bmNlVGltZSwgU3ViamVjdCwgc3dpdGNoTWFwLCB0YWtlVW50aWwsIHRpbWVyIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IEdyaWRzdGVyQ29tcG9uZW50SW50ZXJmYWNlIH0gZnJvbSAnLi9ncmlkc3Rlci5pbnRlcmZhY2UnO1xyXG5pbXBvcnQgeyBHcmlkc3RlckNvbXBhY3QgfSBmcm9tICcuL2dyaWRzdGVyQ29tcGFjdC5zZXJ2aWNlJztcclxuXHJcbmltcG9ydCB7IEdyaWRzdGVyQ29uZmlnU2VydmljZSB9IGZyb20gJy4vZ3JpZHN0ZXJDb25maWcuY29uc3RhbnQnO1xyXG5pbXBvcnQgeyBHcmlkc3RlckNvbmZpZywgR3JpZFR5cGUgfSBmcm9tICcuL2dyaWRzdGVyQ29uZmlnLmludGVyZmFjZSc7XHJcbmltcG9ydCB7IEdyaWRzdGVyQ29uZmlnUyB9IGZyb20gJy4vZ3JpZHN0ZXJDb25maWdTLmludGVyZmFjZSc7XHJcbmltcG9ydCB7IEdyaWRzdGVyRW1wdHlDZWxsIH0gZnJvbSAnLi9ncmlkc3RlckVtcHR5Q2VsbC5zZXJ2aWNlJztcclxuaW1wb3J0IHtcclxuICBHcmlkc3Rlckl0ZW0sXHJcbiAgR3JpZHN0ZXJJdGVtQ29tcG9uZW50SW50ZXJmYWNlXHJcbn0gZnJvbSAnLi9ncmlkc3Rlckl0ZW0uaW50ZXJmYWNlJztcclxuaW1wb3J0IHsgR3JpZHN0ZXJQcmV2aWV3Q29tcG9uZW50IH0gZnJvbSAnLi9ncmlkc3RlclByZXZpZXcuY29tcG9uZW50JztcclxuaW1wb3J0IHsgR3JpZHN0ZXJSZW5kZXJlciB9IGZyb20gJy4vZ3JpZHN0ZXJSZW5kZXJlci5zZXJ2aWNlJztcclxuaW1wb3J0IHsgR3JpZHN0ZXJVdGlscyB9IGZyb20gJy4vZ3JpZHN0ZXJVdGlscy5zZXJ2aWNlJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAYW5ndWxhci1lc2xpbnQvY29tcG9uZW50LXNlbGVjdG9yXHJcbiAgc2VsZWN0b3I6ICdncmlkc3RlcicsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL2dyaWRzdGVyLmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL2dyaWRzdGVyLmNzcyddLFxyXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXHJcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcclxuICBpbXBvcnRzOiBbTmdGb3JPZiwgTmdTdHlsZSwgR3JpZHN0ZXJQcmV2aWV3Q29tcG9uZW50XVxyXG59KVxyXG5leHBvcnQgY2xhc3MgR3JpZHN0ZXJDb21wb25lbnRcclxuICBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3ksIEdyaWRzdGVyQ29tcG9uZW50SW50ZXJmYWNlIHtcclxuICBASW5wdXQoKSBvcHRpb25zITogR3JpZHN0ZXJDb25maWc7XHJcbiAgbW92aW5nSXRlbSE6IEdyaWRzdGVySXRlbSB8IG51bGw7XHJcbiAgZWw6IEhUTUxFbGVtZW50O1xyXG4gICRvcHRpb25zOiBHcmlkc3RlckNvbmZpZ1M7XHJcbiAgbW9iaWxlOiBib29sZWFuO1xyXG4gIGN1cldpZHRoOiBudW1iZXI7XHJcbiAgY3VySGVpZ2h0OiBudW1iZXI7XHJcbiAgZ3JpZDogR3JpZHN0ZXJJdGVtQ29tcG9uZW50SW50ZXJmYWNlW107XHJcbiAgY29sdW1ucyA9IDA7XHJcbiAgcm93cyA9IDA7XHJcbiAgY3VyQ29sV2lkdGg6IG51bWJlcjtcclxuICBjdXJSb3dIZWlnaHQ6IG51bWJlcjtcclxuICBncmlkQ29sdW1ucyA9IFtdO1xyXG4gIGdyaWRSb3dzID0gW107XHJcbiAgd2luZG93UmVzaXplITogKCgpID0+IHZvaWQpIHwgbnVsbDtcclxuICBkcmFnSW5Qcm9ncmVzczogYm9vbGVhbjtcclxuICBlbXB0eUNlbGw6IEdyaWRzdGVyRW1wdHlDZWxsO1xyXG4gIGNvbXBhY3Q6IEdyaWRzdGVyQ29tcGFjdDtcclxuICBncmlkUmVuZGVyZXI6IEdyaWRzdGVyUmVuZGVyZXI7XHJcbiAgcHJldmlld1N0eWxlJDogRXZlbnRFbWl0dGVyPEdyaWRzdGVySXRlbSB8IG51bGw+ID1cclxuICAgIG5ldyBFdmVudEVtaXR0ZXI8R3JpZHN0ZXJJdGVtIHwgbnVsbD4oKTtcclxuXHJcbiAgY2FsY3VsYXRlTGF5b3V0JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XHJcblxyXG4gIHByaXZhdGUgcmVzaXplJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XHJcbiAgcHJpdmF0ZSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgQEluamVjdChFbGVtZW50UmVmKSBlbDogRWxlbWVudFJlZixcclxuICAgIEBJbmplY3QoUmVuZGVyZXIyKSBwdWJsaWMgcmVuZGVyZXI6IFJlbmRlcmVyMixcclxuICAgIEBJbmplY3QoQ2hhbmdlRGV0ZWN0b3JSZWYpIHB1YmxpYyBjZFJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgICBASW5qZWN0KE5nWm9uZSkgcHVibGljIHpvbmU6IE5nWm9uZVxyXG4gICkge1xyXG4gICAgdGhpcy5lbCA9IGVsLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICB0aGlzLiRvcHRpb25zID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShHcmlkc3RlckNvbmZpZ1NlcnZpY2UpKTtcclxuICAgIHRoaXMubW9iaWxlID0gZmFsc2U7XHJcbiAgICB0aGlzLmN1cldpZHRoID0gMDtcclxuICAgIHRoaXMuY3VySGVpZ2h0ID0gMDtcclxuICAgIHRoaXMuZ3JpZCA9IFtdO1xyXG4gICAgdGhpcy5jdXJDb2xXaWR0aCA9IDA7XHJcbiAgICB0aGlzLmN1clJvd0hlaWdodCA9IDA7XHJcbiAgICB0aGlzLmRyYWdJblByb2dyZXNzID0gZmFsc2U7XHJcbiAgICB0aGlzLmVtcHR5Q2VsbCA9IG5ldyBHcmlkc3RlckVtcHR5Q2VsbCh0aGlzKTtcclxuICAgIHRoaXMuY29tcGFjdCA9IG5ldyBHcmlkc3RlckNvbXBhY3QodGhpcyk7XHJcbiAgICB0aGlzLmdyaWRSZW5kZXJlciA9IG5ldyBHcmlkc3RlclJlbmRlcmVyKHRoaXMpO1xyXG4gIH1cclxuXHJcbiAgLy8gLS0tLS0tIEZ1bmN0aW9uIGZvciBzd2FwV2hpbGVEcmFnZ2luZyBvcHRpb25cclxuXHJcbiAgLy8gaWRlbnRpY2FsIHRvIGNoZWNrQ29sbGlzaW9uKCkgZXhjZXB0IHRoYXQgaGVyZSB3ZSBhZGQgYm91bmRhcmllcy5cclxuICBzdGF0aWMgY2hlY2tDb2xsaXNpb25Ud29JdGVtc0ZvclN3YXBpbmcoXHJcbiAgICBpdGVtOiBHcmlkc3Rlckl0ZW0sXHJcbiAgICBpdGVtMjogR3JpZHN0ZXJJdGVtXHJcbiAgKTogYm9vbGVhbiB7XHJcbiAgICAvLyBpZiB0aGUgY29scyBvciByb3dzIG9mIHRoZSBpdGVtcyBhcmUgMSAsIGRvZXNudCBtYWtlIGFueSBzZW5zZSB0byBzZXQgYSBib3VuZGFyeS4gT25seSBpZiB0aGUgaXRlbSBpcyBiaWdnZXIgd2Ugc2V0IGEgYm91bmRhcnlcclxuICAgIGNvbnN0IGhvcml6b250YWxCb3VuZGFyeUl0ZW0xID0gaXRlbS5jb2xzID09PSAxID8gMCA6IDE7XHJcbiAgICBjb25zdCBob3Jpem9udGFsQm91bmRhcnlJdGVtMiA9IGl0ZW0yLmNvbHMgPT09IDEgPyAwIDogMTtcclxuICAgIGNvbnN0IHZlcnRpY2FsQm91bmRhcnlJdGVtMSA9IGl0ZW0ucm93cyA9PT0gMSA/IDAgOiAxO1xyXG4gICAgY29uc3QgdmVydGljYWxCb3VuZGFyeUl0ZW0yID0gaXRlbTIucm93cyA9PT0gMSA/IDAgOiAxO1xyXG4gICAgcmV0dXJuIChcclxuICAgICAgaXRlbS54ICsgaG9yaXpvbnRhbEJvdW5kYXJ5SXRlbTEgPCBpdGVtMi54ICsgaXRlbTIuY29scyAmJlxyXG4gICAgICBpdGVtLnggKyBpdGVtLmNvbHMgPiBpdGVtMi54ICsgaG9yaXpvbnRhbEJvdW5kYXJ5SXRlbTIgJiZcclxuICAgICAgaXRlbS55ICsgdmVydGljYWxCb3VuZGFyeUl0ZW0xIDwgaXRlbTIueSArIGl0ZW0yLnJvd3MgJiZcclxuICAgICAgaXRlbS55ICsgaXRlbS5yb3dzID4gaXRlbTIueSArIHZlcnRpY2FsQm91bmRhcnlJdGVtMlxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIGNoZWNrQ29sbGlzaW9uVHdvSXRlbXMoaXRlbTogR3JpZHN0ZXJJdGVtLCBpdGVtMjogR3JpZHN0ZXJJdGVtKTogYm9vbGVhbiB7XHJcbiAgICBjb25zdCBjb2xsaXNpb24gPVxyXG4gICAgICBpdGVtLnggPCBpdGVtMi54ICsgaXRlbTIuY29scyAmJlxyXG4gICAgICBpdGVtLnggKyBpdGVtLmNvbHMgPiBpdGVtMi54ICYmXHJcbiAgICAgIGl0ZW0ueSA8IGl0ZW0yLnkgKyBpdGVtMi5yb3dzICYmXHJcbiAgICAgIGl0ZW0ueSArIGl0ZW0ucm93cyA+IGl0ZW0yLnk7XHJcbiAgICBpZiAoIWNvbGxpc2lvbikge1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICBpZiAoIXRoaXMuJG9wdGlvbnMuYWxsb3dNdWx0aUxheWVyKSB7XHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG4gICAgY29uc3QgZGVmYXVsdExheWVySW5kZXggPSB0aGlzLiRvcHRpb25zLmRlZmF1bHRMYXllckluZGV4O1xyXG4gICAgY29uc3QgbGF5ZXJJbmRleCA9XHJcbiAgICAgIGl0ZW0ubGF5ZXJJbmRleCA9PT0gdW5kZWZpbmVkID8gZGVmYXVsdExheWVySW5kZXggOiBpdGVtLmxheWVySW5kZXg7XHJcbiAgICBjb25zdCBsYXllckluZGV4MiA9XHJcbiAgICAgIGl0ZW0yLmxheWVySW5kZXggPT09IHVuZGVmaW5lZCA/IGRlZmF1bHRMYXllckluZGV4IDogaXRlbTIubGF5ZXJJbmRleDtcclxuICAgIHJldHVybiBsYXllckluZGV4ID09PSBsYXllckluZGV4MjtcclxuICB9XHJcblxyXG4gIG5nT25Jbml0KCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5pbml0Q2FsbGJhY2spIHtcclxuICAgICAgdGhpcy5vcHRpb25zLmluaXRDYWxsYmFjayh0aGlzKTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmNhbGN1bGF0ZUxheW91dCRcclxuICAgICAgLnBpcGUoZGVib3VuY2VUaW1lKDApLCB0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXHJcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5jYWxjdWxhdGVMYXlvdXQoKSk7XHJcblxyXG4gICAgdGhpcy5yZXNpemUkXHJcbiAgICAgIC5waXBlKFxyXG4gICAgICAgIC8vIENhbmNlbCBwcmV2aW91c2x5IHNjaGVkdWxlZCBET00gdGltZXIgaWYgYGNhbGN1bGF0ZUxheW91dCgpYCBoYXMgYmVlbiBjYWxsZWRcclxuICAgICAgICAvLyB3aXRoaW4gdGhpcyB0aW1lIHJhbmdlLlxyXG4gICAgICAgIHN3aXRjaE1hcCgoKSA9PiB0aW1lcigxMDApKSxcclxuICAgICAgICB0YWtlVW50aWwodGhpcy5kZXN0cm95JClcclxuICAgICAgKVxyXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHRoaXMucmVzaXplKCkpO1xyXG4gIH1cclxuXHJcbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xyXG4gICAgaWYgKGNoYW5nZXMub3B0aW9ucykge1xyXG4gICAgICB0aGlzLnNldE9wdGlvbnMoKTtcclxuICAgICAgdGhpcy5vcHRpb25zLmFwaSA9IHtcclxuICAgICAgICBvcHRpb25zQ2hhbmdlZDogdGhpcy5vcHRpb25zQ2hhbmdlZC5iaW5kKHRoaXMpLFxyXG4gICAgICAgIHJlc2l6ZTogdGhpcy5vblJlc2l6ZS5iaW5kKHRoaXMpLFxyXG4gICAgICAgIGdldE5leHRQb3NzaWJsZVBvc2l0aW9uOiB0aGlzLmdldE5leHRQb3NzaWJsZVBvc2l0aW9uLmJpbmQodGhpcyksXHJcbiAgICAgICAgZ2V0Rmlyc3RQb3NzaWJsZVBvc2l0aW9uOiB0aGlzLmdldEZpcnN0UG9zc2libGVQb3NpdGlvbi5iaW5kKHRoaXMpLFxyXG4gICAgICAgIGdldExhc3RQb3NzaWJsZVBvc2l0aW9uOiB0aGlzLmdldExhc3RQb3NzaWJsZVBvc2l0aW9uLmJpbmQodGhpcyksXHJcbiAgICAgICAgZ2V0SXRlbUNvbXBvbmVudDogKGl0ZW06IEdyaWRzdGVySXRlbSkgPT4gdGhpcy5nZXRJdGVtQ29tcG9uZW50KGl0ZW0pLFxyXG4gICAgICAgIGdldEN1cnJlbnRSb3dIZWlnaHQ6IHRoaXMuZ2V0Q3VycmVudFJvd0hlaWdodC5iaW5kKHRoaXMpXHJcbiAgICAgIH07XHJcbiAgICAgIHRoaXMuY29sdW1ucyA9IHRoaXMuJG9wdGlvbnMubWluQ29scztcclxuICAgICAgdGhpcy5yb3dzID0gdGhpcy4kb3B0aW9ucy5taW5Sb3dzICsgdGhpcy4kb3B0aW9ucy5hZGRFbXB0eVJvd3NDb3VudDtcclxuICAgICAgdGhpcy5zZXRHcmlkU2l6ZSgpO1xyXG4gICAgICB0aGlzLmNhbGN1bGF0ZUxheW91dCgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZ2V0Q3VycmVudFJvd0hlaWdodCgpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMuY3VyUm93SGVpZ2h0O1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSByZXNpemUoKTogdm9pZCB7XHJcbiAgICBsZXQgaGVpZ2h0O1xyXG4gICAgbGV0IHdpZHRoO1xyXG4gICAgaWYgKHRoaXMuJG9wdGlvbnMuZ3JpZFR5cGUgPT09ICdmaXQnICYmICF0aGlzLm1vYmlsZSkge1xyXG4gICAgICB3aWR0aCA9IHRoaXMuZWwub2Zmc2V0V2lkdGg7XHJcbiAgICAgIGhlaWdodCA9IHRoaXMuZWwub2Zmc2V0SGVpZ2h0O1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgd2lkdGggPSB0aGlzLmVsLmNsaWVudFdpZHRoO1xyXG4gICAgICBoZWlnaHQgPSB0aGlzLmVsLmNsaWVudEhlaWdodDtcclxuICAgIH1cclxuICAgIGlmIChcclxuICAgICAgKHdpZHRoICE9PSB0aGlzLmN1cldpZHRoIHx8IGhlaWdodCAhPT0gdGhpcy5jdXJIZWlnaHQpICYmXHJcbiAgICAgIHRoaXMuY2hlY2tJZlRvUmVzaXplKClcclxuICAgICkge1xyXG4gICAgICB0aGlzLm9uUmVzaXplKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBzZXRPcHRpb25zKCk6IHZvaWQge1xyXG4gICAgdGhpcy4kb3B0aW9ucyA9IEdyaWRzdGVyVXRpbHMubWVyZ2UoXHJcbiAgICAgIHRoaXMuJG9wdGlvbnMsXHJcbiAgICAgIHRoaXMub3B0aW9ucyxcclxuICAgICAgdGhpcy4kb3B0aW9uc1xyXG4gICAgKTtcclxuICAgIGlmICghdGhpcy4kb3B0aW9ucy5kaXNhYmxlV2luZG93UmVzaXplICYmICF0aGlzLndpbmRvd1Jlc2l6ZSkge1xyXG4gICAgICB0aGlzLndpbmRvd1Jlc2l6ZSA9IHRoaXMucmVuZGVyZXIubGlzdGVuKFxyXG4gICAgICAgICd3aW5kb3cnLFxyXG4gICAgICAgICdyZXNpemUnLFxyXG4gICAgICAgIHRoaXMub25SZXNpemVcclxuICAgICAgKTtcclxuICAgIH0gZWxzZSBpZiAodGhpcy4kb3B0aW9ucy5kaXNhYmxlV2luZG93UmVzaXplICYmIHRoaXMud2luZG93UmVzaXplKSB7XHJcbiAgICAgIHRoaXMud2luZG93UmVzaXplKCk7XHJcbiAgICAgIHRoaXMud2luZG93UmVzaXplID0gbnVsbDtcclxuICAgIH1cclxuICAgIHRoaXMuZW1wdHlDZWxsLnVwZGF0ZU9wdGlvbnMoKTtcclxuICB9XHJcblxyXG4gIG9wdGlvbnNDaGFuZ2VkID0gKCk6IHZvaWQgPT4ge1xyXG4gICAgdGhpcy5zZXRPcHRpb25zKCk7XHJcbiAgICBsZXQgd2lkZ2V0c0luZGV4OiBudW1iZXIgPSB0aGlzLmdyaWQubGVuZ3RoIC0gMTtcclxuICAgIGxldCB3aWRnZXQ6IEdyaWRzdGVySXRlbUNvbXBvbmVudEludGVyZmFjZTtcclxuICAgIGZvciAoOyB3aWRnZXRzSW5kZXggPj0gMDsgd2lkZ2V0c0luZGV4LS0pIHtcclxuICAgICAgd2lkZ2V0ID0gdGhpcy5ncmlkW3dpZGdldHNJbmRleF07XHJcbiAgICAgIHdpZGdldC51cGRhdGVPcHRpb25zKCk7XHJcbiAgICB9XHJcbiAgICB0aGlzLmNhbGN1bGF0ZUxheW91dCgpO1xyXG4gIH07XHJcblxyXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xyXG4gICAgdGhpcy5kZXN0cm95JC5uZXh0KCk7XHJcbiAgICB0aGlzLnByZXZpZXdTdHlsZSQuY29tcGxldGUoKTtcclxuICAgIGlmICh0aGlzLndpbmRvd1Jlc2l6ZSkge1xyXG4gICAgICB0aGlzLndpbmRvd1Jlc2l6ZSgpO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMub3B0aW9ucyAmJiB0aGlzLm9wdGlvbnMuZGVzdHJveUNhbGxiYWNrKSB7XHJcbiAgICAgIHRoaXMub3B0aW9ucy5kZXN0cm95Q2FsbGJhY2sodGhpcyk7XHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy5vcHRpb25zICYmIHRoaXMub3B0aW9ucy5hcGkpIHtcclxuICAgICAgdGhpcy5vcHRpb25zLmFwaS5yZXNpemUgPSB1bmRlZmluZWQ7XHJcbiAgICAgIHRoaXMub3B0aW9ucy5hcGkub3B0aW9uc0NoYW5nZWQgPSB1bmRlZmluZWQ7XHJcbiAgICAgIHRoaXMub3B0aW9ucy5hcGkuZ2V0TmV4dFBvc3NpYmxlUG9zaXRpb24gPSB1bmRlZmluZWQ7XHJcbiAgICAgIHRoaXMub3B0aW9ucy5hcGkgPSB1bmRlZmluZWQ7XHJcbiAgICB9XHJcbiAgICB0aGlzLmVtcHR5Q2VsbC5kZXN0cm95KCk7XHJcbiAgICB0aGlzLmVtcHR5Q2VsbCA9IG51bGwhO1xyXG4gICAgdGhpcy5jb21wYWN0LmRlc3Ryb3koKTtcclxuICAgIHRoaXMuY29tcGFjdCA9IG51bGwhO1xyXG4gIH1cclxuXHJcbiAgb25SZXNpemUgPSAoKTogdm9pZCA9PiB7XHJcbiAgICBpZiAodGhpcy5lbC5jbGllbnRXaWR0aCkge1xyXG4gICAgICBpZiAodGhpcy5vcHRpb25zLnNldEdyaWRTaXplKSB7XHJcbiAgICAgICAgLy8gcmVzZXQgd2lkdGgvaGVpZ2h0IHNvIHRoZSBzaXplIGlzIHJlY2FsY3VsYXRlZCBhZnRlcndhcmRzXHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLmVsLCAnd2lkdGgnLCAnJyk7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLmVsLCAnaGVpZ2h0JywgJycpO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuc2V0R3JpZFNpemUoKTtcclxuICAgICAgdGhpcy5jYWxjdWxhdGVMYXlvdXQoKTtcclxuICAgIH1cclxuICB9O1xyXG5cclxuICBjaGVja0lmVG9SZXNpemUoKTogYm9vbGVhbiB7XHJcbiAgICBjb25zdCBjbGllbnRXaWR0aCA9IHRoaXMuZWwuY2xpZW50V2lkdGg7XHJcbiAgICBjb25zdCBvZmZzZXRXaWR0aCA9IHRoaXMuZWwub2Zmc2V0V2lkdGg7XHJcbiAgICBjb25zdCBzY3JvbGxXaWR0aCA9IHRoaXMuZWwuc2Nyb2xsV2lkdGg7XHJcbiAgICBjb25zdCBjbGllbnRIZWlnaHQgPSB0aGlzLmVsLmNsaWVudEhlaWdodDtcclxuICAgIGNvbnN0IG9mZnNldEhlaWdodCA9IHRoaXMuZWwub2Zmc2V0SGVpZ2h0O1xyXG4gICAgY29uc3Qgc2Nyb2xsSGVpZ2h0ID0gdGhpcy5lbC5zY3JvbGxIZWlnaHQ7XHJcbiAgICBjb25zdCB2ZXJ0aWNhbFNjcm9sbFByZXNlbnQgPVxyXG4gICAgICBjbGllbnRXaWR0aCA8IG9mZnNldFdpZHRoICYmXHJcbiAgICAgIHNjcm9sbEhlaWdodCA+IG9mZnNldEhlaWdodCAmJlxyXG4gICAgICBzY3JvbGxIZWlnaHQgLSBvZmZzZXRIZWlnaHQgPCBvZmZzZXRXaWR0aCAtIGNsaWVudFdpZHRoO1xyXG4gICAgY29uc3QgaG9yaXpvbnRhbFNjcm9sbFByZXNlbnQgPVxyXG4gICAgICBjbGllbnRIZWlnaHQgPCBvZmZzZXRIZWlnaHQgJiZcclxuICAgICAgc2Nyb2xsV2lkdGggPiBvZmZzZXRXaWR0aCAmJlxyXG4gICAgICBzY3JvbGxXaWR0aCAtIG9mZnNldFdpZHRoIDwgb2Zmc2V0SGVpZ2h0IC0gY2xpZW50SGVpZ2h0O1xyXG4gICAgaWYgKHZlcnRpY2FsU2Nyb2xsUHJlc2VudCkge1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gIWhvcml6b250YWxTY3JvbGxQcmVzZW50O1xyXG4gIH1cclxuXHJcbiAgY2hlY2tJZk1vYmlsZSgpOiBib29sZWFuIHtcclxuICAgIGlmICh0aGlzLiRvcHRpb25zLnVzZUJvZHlGb3JCcmVha3BvaW50KSB7XHJcbiAgICAgIHJldHVybiB0aGlzLiRvcHRpb25zLm1vYmlsZUJyZWFrcG9pbnQgPiBkb2N1bWVudC5ib2R5LmNsaWVudFdpZHRoO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0dXJuIHRoaXMuJG9wdGlvbnMubW9iaWxlQnJlYWtwb2ludCA+IHRoaXMuY3VyV2lkdGg7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBzZXRHcmlkU2l6ZSgpOiB2b2lkIHtcclxuICAgIGNvbnN0IGVsID0gdGhpcy5lbDtcclxuICAgIGxldCB3aWR0aDtcclxuICAgIGxldCBoZWlnaHQ7XHJcbiAgICBpZiAoXHJcbiAgICAgIHRoaXMuJG9wdGlvbnMuc2V0R3JpZFNpemUgfHxcclxuICAgICAgKHRoaXMuJG9wdGlvbnMuZ3JpZFR5cGUgPT09IEdyaWRUeXBlLkZpdCAmJiAhdGhpcy5tb2JpbGUpXHJcbiAgICApIHtcclxuICAgICAgd2lkdGggPSBlbC5vZmZzZXRXaWR0aDtcclxuICAgICAgaGVpZ2h0ID0gZWwub2Zmc2V0SGVpZ2h0O1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgd2lkdGggPSBlbC5jbGllbnRXaWR0aDtcclxuICAgICAgaGVpZ2h0ID0gZWwuY2xpZW50SGVpZ2h0O1xyXG4gICAgfVxyXG4gICAgdGhpcy5jdXJXaWR0aCA9IHdpZHRoO1xyXG4gICAgdGhpcy5jdXJIZWlnaHQgPSBoZWlnaHQ7XHJcbiAgfVxyXG5cclxuICBzZXRHcmlkRGltZW5zaW9ucygpOiB2b2lkIHtcclxuICAgIHRoaXMuc2V0R3JpZFNpemUoKTtcclxuICAgIGlmICghdGhpcy5tb2JpbGUgJiYgdGhpcy5jaGVja0lmTW9iaWxlKCkpIHtcclxuICAgICAgdGhpcy5tb2JpbGUgPSAhdGhpcy5tb2JpbGU7XHJcbiAgICAgIHRoaXMucmVuZGVyZXIuYWRkQ2xhc3ModGhpcy5lbCwgJ21vYmlsZScpO1xyXG4gICAgfSBlbHNlIGlmICh0aGlzLm1vYmlsZSAmJiAhdGhpcy5jaGVja0lmTW9iaWxlKCkpIHtcclxuICAgICAgdGhpcy5tb2JpbGUgPSAhdGhpcy5tb2JpbGU7XHJcbiAgICAgIHRoaXMucmVuZGVyZXIucmVtb3ZlQ2xhc3ModGhpcy5lbCwgJ21vYmlsZScpO1xyXG4gICAgfVxyXG4gICAgbGV0IHJvd3MgPSB0aGlzLiRvcHRpb25zLm1pblJvd3M7XHJcbiAgICBsZXQgY29sdW1ucyA9IHRoaXMuJG9wdGlvbnMubWluQ29scztcclxuXHJcbiAgICBsZXQgd2lkZ2V0c0luZGV4ID0gdGhpcy5ncmlkLmxlbmd0aCAtIDE7XHJcbiAgICBsZXQgd2lkZ2V0O1xyXG4gICAgZm9yICg7IHdpZGdldHNJbmRleCA+PSAwOyB3aWRnZXRzSW5kZXgtLSkge1xyXG4gICAgICB3aWRnZXQgPSB0aGlzLmdyaWRbd2lkZ2V0c0luZGV4XTtcclxuICAgICAgaWYgKCF3aWRnZXQubm90UGxhY2VkKSB7XHJcbiAgICAgICAgcm93cyA9IE1hdGgubWF4KHJvd3MsIHdpZGdldC4kaXRlbS55ICsgd2lkZ2V0LiRpdGVtLnJvd3MpO1xyXG4gICAgICAgIGNvbHVtbnMgPSBNYXRoLm1heChjb2x1bW5zLCB3aWRnZXQuJGl0ZW0ueCArIHdpZGdldC4kaXRlbS5jb2xzKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcm93cyArPSB0aGlzLiRvcHRpb25zLmFkZEVtcHR5Um93c0NvdW50O1xyXG4gICAgaWYgKHRoaXMuY29sdW1ucyAhPT0gY29sdW1ucyB8fCB0aGlzLnJvd3MgIT09IHJvd3MpIHtcclxuICAgICAgdGhpcy5jb2x1bW5zID0gY29sdW1ucztcclxuICAgICAgdGhpcy5yb3dzID0gcm93cztcclxuICAgICAgaWYgKHRoaXMub3B0aW9ucy5ncmlkU2l6ZUNoYW5nZWRDYWxsYmFjaykge1xyXG4gICAgICAgIHRoaXMub3B0aW9ucy5ncmlkU2l6ZUNoYW5nZWRDYWxsYmFjayh0aGlzKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjYWxjdWxhdGVMYXlvdXQoKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5jb21wYWN0KSB7XHJcbiAgICAgIHRoaXMuY29tcGFjdC5jaGVja0NvbXBhY3QoKTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLnNldEdyaWREaW1lbnNpb25zKCk7XHJcbiAgICBpZiAodGhpcy4kb3B0aW9ucy5vdXRlck1hcmdpbikge1xyXG4gICAgICBsZXQgbWFyZ2luV2lkdGggPSAtdGhpcy4kb3B0aW9ucy5tYXJnaW47XHJcbiAgICAgIGlmICh0aGlzLiRvcHRpb25zLm91dGVyTWFyZ2luTGVmdCAhPT0gbnVsbCkge1xyXG4gICAgICAgIG1hcmdpbldpZHRoICs9IHRoaXMuJG9wdGlvbnMub3V0ZXJNYXJnaW5MZWZ0O1xyXG4gICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUoXHJcbiAgICAgICAgICB0aGlzLmVsLFxyXG4gICAgICAgICAgJ3BhZGRpbmctbGVmdCcsXHJcbiAgICAgICAgICB0aGlzLiRvcHRpb25zLm91dGVyTWFyZ2luTGVmdCArICdweCdcclxuICAgICAgICApO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIG1hcmdpbldpZHRoICs9IHRoaXMuJG9wdGlvbnMubWFyZ2luO1xyXG4gICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUoXHJcbiAgICAgICAgICB0aGlzLmVsLFxyXG4gICAgICAgICAgJ3BhZGRpbmctbGVmdCcsXHJcbiAgICAgICAgICB0aGlzLiRvcHRpb25zLm1hcmdpbiArICdweCdcclxuICAgICAgICApO1xyXG4gICAgICB9XHJcbiAgICAgIGlmICh0aGlzLiRvcHRpb25zLm91dGVyTWFyZ2luUmlnaHQgIT09IG51bGwpIHtcclxuICAgICAgICBtYXJnaW5XaWR0aCArPSB0aGlzLiRvcHRpb25zLm91dGVyTWFyZ2luUmlnaHQ7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZShcclxuICAgICAgICAgIHRoaXMuZWwsXHJcbiAgICAgICAgICAncGFkZGluZy1yaWdodCcsXHJcbiAgICAgICAgICB0aGlzLiRvcHRpb25zLm91dGVyTWFyZ2luUmlnaHQgKyAncHgnXHJcbiAgICAgICAgKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBtYXJnaW5XaWR0aCArPSB0aGlzLiRvcHRpb25zLm1hcmdpbjtcclxuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKFxyXG4gICAgICAgICAgdGhpcy5lbCxcclxuICAgICAgICAgICdwYWRkaW5nLXJpZ2h0JyxcclxuICAgICAgICAgIHRoaXMuJG9wdGlvbnMubWFyZ2luICsgJ3B4J1xyXG4gICAgICAgICk7XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5jdXJDb2xXaWR0aCA9ICh0aGlzLmN1cldpZHRoIC0gbWFyZ2luV2lkdGgpIC8gdGhpcy5jb2x1bW5zO1xyXG4gICAgICBsZXQgbWFyZ2luSGVpZ2h0ID0gLXRoaXMuJG9wdGlvbnMubWFyZ2luO1xyXG4gICAgICBpZiAodGhpcy4kb3B0aW9ucy5vdXRlck1hcmdpblRvcCAhPT0gbnVsbCkge1xyXG4gICAgICAgIG1hcmdpbkhlaWdodCArPSB0aGlzLiRvcHRpb25zLm91dGVyTWFyZ2luVG9wO1xyXG4gICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUoXHJcbiAgICAgICAgICB0aGlzLmVsLFxyXG4gICAgICAgICAgJ3BhZGRpbmctdG9wJyxcclxuICAgICAgICAgIHRoaXMuJG9wdGlvbnMub3V0ZXJNYXJnaW5Ub3AgKyAncHgnXHJcbiAgICAgICAgKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBtYXJnaW5IZWlnaHQgKz0gdGhpcy4kb3B0aW9ucy5tYXJnaW47XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZShcclxuICAgICAgICAgIHRoaXMuZWwsXHJcbiAgICAgICAgICAncGFkZGluZy10b3AnLFxyXG4gICAgICAgICAgdGhpcy4kb3B0aW9ucy5tYXJnaW4gKyAncHgnXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG4gICAgICBpZiAodGhpcy4kb3B0aW9ucy5vdXRlck1hcmdpbkJvdHRvbSAhPT0gbnVsbCkge1xyXG4gICAgICAgIG1hcmdpbkhlaWdodCArPSB0aGlzLiRvcHRpb25zLm91dGVyTWFyZ2luQm90dG9tO1xyXG4gICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUoXHJcbiAgICAgICAgICB0aGlzLmVsLFxyXG4gICAgICAgICAgJ3BhZGRpbmctYm90dG9tJyxcclxuICAgICAgICAgIHRoaXMuJG9wdGlvbnMub3V0ZXJNYXJnaW5Cb3R0b20gKyAncHgnXHJcbiAgICAgICAgKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBtYXJnaW5IZWlnaHQgKz0gdGhpcy4kb3B0aW9ucy5tYXJnaW47XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZShcclxuICAgICAgICAgIHRoaXMuZWwsXHJcbiAgICAgICAgICAncGFkZGluZy1ib3R0b20nLFxyXG4gICAgICAgICAgdGhpcy4kb3B0aW9ucy5tYXJnaW4gKyAncHgnXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLmN1clJvd0hlaWdodCA9XHJcbiAgICAgICAgKCh0aGlzLmN1ckhlaWdodCAtIG1hcmdpbkhlaWdodCkgLyB0aGlzLnJvd3MpICpcclxuICAgICAgICB0aGlzLiRvcHRpb25zLnJvd0hlaWdodFJhdGlvO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5jdXJDb2xXaWR0aCA9ICh0aGlzLmN1cldpZHRoICsgdGhpcy4kb3B0aW9ucy5tYXJnaW4pIC8gdGhpcy5jb2x1bW5zO1xyXG4gICAgICB0aGlzLmN1clJvd0hlaWdodCA9XHJcbiAgICAgICAgKCh0aGlzLmN1ckhlaWdodCArIHRoaXMuJG9wdGlvbnMubWFyZ2luKSAvIHRoaXMucm93cykgKlxyXG4gICAgICAgIHRoaXMuJG9wdGlvbnMucm93SGVpZ2h0UmF0aW87XHJcbiAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5lbCwgJ3BhZGRpbmctbGVmdCcsIDAgKyAncHgnKTtcclxuICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLmVsLCAncGFkZGluZy1yaWdodCcsIDAgKyAncHgnKTtcclxuICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLmVsLCAncGFkZGluZy10b3AnLCAwICsgJ3B4Jyk7XHJcbiAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5lbCwgJ3BhZGRpbmctYm90dG9tJywgMCArICdweCcpO1xyXG4gICAgfVxyXG4gICAgdGhpcy5ncmlkUmVuZGVyZXIudXBkYXRlR3JpZHN0ZXIoKTtcclxuXHJcbiAgICBpZiAodGhpcy4kb3B0aW9ucy5zZXRHcmlkU2l6ZSkge1xyXG4gICAgICB0aGlzLnJlbmRlcmVyLmFkZENsYXNzKHRoaXMuZWwsICdncmlkU2l6ZScpO1xyXG4gICAgICBpZiAoIXRoaXMubW9iaWxlKSB7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZShcclxuICAgICAgICAgIHRoaXMuZWwsXHJcbiAgICAgICAgICAnd2lkdGgnLFxyXG4gICAgICAgICAgdGhpcy5jb2x1bW5zICogdGhpcy5jdXJDb2xXaWR0aCArIHRoaXMuJG9wdGlvbnMubWFyZ2luICsgJ3B4J1xyXG4gICAgICAgICk7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZShcclxuICAgICAgICAgIHRoaXMuZWwsXHJcbiAgICAgICAgICAnaGVpZ2h0JyxcclxuICAgICAgICAgIHRoaXMucm93cyAqIHRoaXMuY3VyUm93SGVpZ2h0ICsgdGhpcy4kb3B0aW9ucy5tYXJnaW4gKyAncHgnXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5yZW5kZXJlci5yZW1vdmVDbGFzcyh0aGlzLmVsLCAnZ3JpZFNpemUnKTtcclxuICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLmVsLCAnd2lkdGgnLCAnJyk7XHJcbiAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5lbCwgJ2hlaWdodCcsICcnKTtcclxuICAgIH1cclxuICAgIHRoaXMudXBkYXRlR3JpZCgpO1xyXG5cclxuICAgIGxldCB3aWRnZXRzSW5kZXg6IG51bWJlciA9IHRoaXMuZ3JpZC5sZW5ndGggLSAxO1xyXG4gICAgbGV0IHdpZGdldDogR3JpZHN0ZXJJdGVtQ29tcG9uZW50SW50ZXJmYWNlO1xyXG4gICAgZm9yICg7IHdpZGdldHNJbmRleCA+PSAwOyB3aWRnZXRzSW5kZXgtLSkge1xyXG4gICAgICB3aWRnZXQgPSB0aGlzLmdyaWRbd2lkZ2V0c0luZGV4XTtcclxuICAgICAgd2lkZ2V0LnNldFNpemUoKTtcclxuICAgICAgd2lkZ2V0LmRyYWcudG9nZ2xlKCk7XHJcbiAgICAgIHdpZGdldC5yZXNpemUudG9nZ2xlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5yZXNpemUkLm5leHQoKTtcclxuICB9XHJcblxyXG4gIHVwZGF0ZUdyaWQoKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy4kb3B0aW9ucy5kaXNwbGF5R3JpZCA9PT0gJ2Fsd2F5cycgJiYgIXRoaXMubW9iaWxlKSB7XHJcbiAgICAgIHRoaXMucmVuZGVyZXIuYWRkQ2xhc3ModGhpcy5lbCwgJ2Rpc3BsYXktZ3JpZCcpO1xyXG4gICAgfSBlbHNlIGlmIChcclxuICAgICAgdGhpcy4kb3B0aW9ucy5kaXNwbGF5R3JpZCA9PT0gJ29uRHJhZyZSZXNpemUnICYmXHJcbiAgICAgIHRoaXMuZHJhZ0luUHJvZ3Jlc3NcclxuICAgICkge1xyXG4gICAgICB0aGlzLnJlbmRlcmVyLmFkZENsYXNzKHRoaXMuZWwsICdkaXNwbGF5LWdyaWQnKTtcclxuICAgIH0gZWxzZSBpZiAoXHJcbiAgICAgIHRoaXMuJG9wdGlvbnMuZGlzcGxheUdyaWQgPT09ICdub25lJyB8fFxyXG4gICAgICAhdGhpcy5kcmFnSW5Qcm9ncmVzcyB8fFxyXG4gICAgICB0aGlzLm1vYmlsZVxyXG4gICAgKSB7XHJcbiAgICAgIHRoaXMucmVuZGVyZXIucmVtb3ZlQ2xhc3ModGhpcy5lbCwgJ2Rpc3BsYXktZ3JpZCcpO1xyXG4gICAgfVxyXG4gICAgdGhpcy5zZXRHcmlkRGltZW5zaW9ucygpO1xyXG4gICAgdGhpcy5ncmlkQ29sdW1ucy5sZW5ndGggPSBHcmlkc3RlckNvbXBvbmVudC5nZXROZXdBcnJheUxlbmd0aChcclxuICAgICAgdGhpcy5jb2x1bW5zLFxyXG4gICAgICB0aGlzLmN1cldpZHRoLFxyXG4gICAgICB0aGlzLmN1ckNvbFdpZHRoXHJcbiAgICApO1xyXG4gICAgdGhpcy5ncmlkUm93cy5sZW5ndGggPSBHcmlkc3RlckNvbXBvbmVudC5nZXROZXdBcnJheUxlbmd0aChcclxuICAgICAgdGhpcy5yb3dzLFxyXG4gICAgICB0aGlzLmN1ckhlaWdodCxcclxuICAgICAgdGhpcy5jdXJSb3dIZWlnaHRcclxuICAgICk7XHJcbiAgICB0aGlzLmNkUmVmLm1hcmtGb3JDaGVjaygpO1xyXG4gIH1cclxuXHJcbiAgYWRkSXRlbShpdGVtQ29tcG9uZW50OiBHcmlkc3Rlckl0ZW1Db21wb25lbnRJbnRlcmZhY2UpOiB2b2lkIHtcclxuICAgIGlmIChpdGVtQ29tcG9uZW50LiRpdGVtLmNvbHMgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICBpdGVtQ29tcG9uZW50LiRpdGVtLmNvbHMgPSB0aGlzLiRvcHRpb25zLmRlZmF1bHRJdGVtQ29scztcclxuICAgICAgaXRlbUNvbXBvbmVudC5pdGVtLmNvbHMgPSBpdGVtQ29tcG9uZW50LiRpdGVtLmNvbHM7XHJcbiAgICAgIGl0ZW1Db21wb25lbnQuaXRlbUNoYW5nZWQoKTtcclxuICAgIH1cclxuICAgIGlmIChpdGVtQ29tcG9uZW50LiRpdGVtLnJvd3MgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICBpdGVtQ29tcG9uZW50LiRpdGVtLnJvd3MgPSB0aGlzLiRvcHRpb25zLmRlZmF1bHRJdGVtUm93cztcclxuICAgICAgaXRlbUNvbXBvbmVudC5pdGVtLnJvd3MgPSBpdGVtQ29tcG9uZW50LiRpdGVtLnJvd3M7XHJcbiAgICAgIGl0ZW1Db21wb25lbnQuaXRlbUNoYW5nZWQoKTtcclxuICAgIH1cclxuICAgIGlmIChpdGVtQ29tcG9uZW50LiRpdGVtLnggPT09IC0xIHx8IGl0ZW1Db21wb25lbnQuJGl0ZW0ueSA9PT0gLTEpIHtcclxuICAgICAgdGhpcy5hdXRvUG9zaXRpb25JdGVtKGl0ZW1Db21wb25lbnQpO1xyXG4gICAgfSBlbHNlIGlmICh0aGlzLmNoZWNrQ29sbGlzaW9uKGl0ZW1Db21wb25lbnQuJGl0ZW0pKSB7XHJcbiAgICAgIGlmICghdGhpcy4kb3B0aW9ucy5kaXNhYmxlV2FybmluZ3MpIHtcclxuICAgICAgICBpdGVtQ29tcG9uZW50Lm5vdFBsYWNlZCA9IHRydWU7XHJcbiAgICAgICAgY29uc29sZS53YXJuKFxyXG4gICAgICAgICAgXCJDYW4ndCBiZSBwbGFjZWQgaW4gdGhlIGJvdW5kcyBvZiB0aGUgZGFzaGJvYXJkLCB0cnlpbmcgdG8gYXV0byBwb3NpdGlvbiEvblwiICtcclxuICAgICAgICAgIEpTT04uc3RyaW5naWZ5KGl0ZW1Db21wb25lbnQuaXRlbSwgWydjb2xzJywgJ3Jvd3MnLCAneCcsICd5J10pXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG4gICAgICBpZiAoIXRoaXMuJG9wdGlvbnMuZGlzYWJsZUF1dG9Qb3NpdGlvbk9uQ29uZmxpY3QpIHtcclxuICAgICAgICB0aGlzLmF1dG9Qb3NpdGlvbkl0ZW0oaXRlbUNvbXBvbmVudCk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgaXRlbUNvbXBvbmVudC5ub3RQbGFjZWQgPSB0cnVlO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICB0aGlzLmdyaWQucHVzaChpdGVtQ29tcG9uZW50KTtcclxuICAgIHRoaXMuY2FsY3VsYXRlTGF5b3V0JC5uZXh0KCk7XHJcbiAgfVxyXG5cclxuICByZW1vdmVJdGVtKGl0ZW1Db21wb25lbnQ6IEdyaWRzdGVySXRlbUNvbXBvbmVudEludGVyZmFjZSk6IHZvaWQge1xyXG4gICAgdGhpcy5ncmlkLnNwbGljZSh0aGlzLmdyaWQuaW5kZXhPZihpdGVtQ29tcG9uZW50KSwgMSk7XHJcbiAgICB0aGlzLmNhbGN1bGF0ZUxheW91dCQubmV4dCgpO1xyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5pdGVtUmVtb3ZlZENhbGxiYWNrKSB7XHJcbiAgICAgIHRoaXMub3B0aW9ucy5pdGVtUmVtb3ZlZENhbGxiYWNrKGl0ZW1Db21wb25lbnQuaXRlbSwgaXRlbUNvbXBvbmVudCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBjaGVja0NvbGxpc2lvbihpdGVtOiBHcmlkc3Rlckl0ZW0pOiBHcmlkc3Rlckl0ZW1Db21wb25lbnRJbnRlcmZhY2UgfCBib29sZWFuIHtcclxuICAgIGxldCBjb2xsaXNpb246IEdyaWRzdGVySXRlbUNvbXBvbmVudEludGVyZmFjZSB8IGJvb2xlYW4gPSBmYWxzZTtcclxuICAgIGlmICh0aGlzLm9wdGlvbnMuaXRlbVZhbGlkYXRlQ2FsbGJhY2spIHtcclxuICAgICAgY29sbGlzaW9uID0gIXRoaXMub3B0aW9ucy5pdGVtVmFsaWRhdGVDYWxsYmFjayhpdGVtKTtcclxuICAgIH1cclxuICAgIGlmICghY29sbGlzaW9uICYmIHRoaXMuY2hlY2tHcmlkQ29sbGlzaW9uKGl0ZW0pKSB7XHJcbiAgICAgIGNvbGxpc2lvbiA9IHRydWU7XHJcbiAgICB9XHJcbiAgICBpZiAoIWNvbGxpc2lvbikge1xyXG4gICAgICBjb25zdCBjID0gdGhpcy5maW5kSXRlbVdpdGhJdGVtKGl0ZW0pO1xyXG4gICAgICBpZiAoYykge1xyXG4gICAgICAgIGNvbGxpc2lvbiA9IGM7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBjb2xsaXNpb247XHJcbiAgfVxyXG5cclxuICBjaGVja0dyaWRDb2xsaXNpb24oaXRlbTogR3JpZHN0ZXJJdGVtKTogYm9vbGVhbiB7XHJcbiAgICBjb25zdCBub05lZ2F0aXZlUG9zaXRpb24gPSBpdGVtLnkgPiAtMSAmJiBpdGVtLnggPiAtMTtcclxuICAgIGNvbnN0IG1heEdyaWRDb2xzID0gaXRlbS5jb2xzICsgaXRlbS54IDw9IHRoaXMuJG9wdGlvbnMubWF4Q29scztcclxuICAgIGNvbnN0IG1heEdyaWRSb3dzID0gaXRlbS5yb3dzICsgaXRlbS55IDw9IHRoaXMuJG9wdGlvbnMubWF4Um93cztcclxuICAgIGNvbnN0IG1heEl0ZW1Db2xzID1cclxuICAgICAgaXRlbS5tYXhJdGVtQ29scyA9PT0gdW5kZWZpbmVkXHJcbiAgICAgICAgPyB0aGlzLiRvcHRpb25zLm1heEl0ZW1Db2xzXHJcbiAgICAgICAgOiBpdGVtLm1heEl0ZW1Db2xzO1xyXG4gICAgY29uc3QgbWluSXRlbUNvbHMgPVxyXG4gICAgICBpdGVtLm1pbkl0ZW1Db2xzID09PSB1bmRlZmluZWRcclxuICAgICAgICA/IHRoaXMuJG9wdGlvbnMubWluSXRlbUNvbHNcclxuICAgICAgICA6IGl0ZW0ubWluSXRlbUNvbHM7XHJcbiAgICBjb25zdCBtYXhJdGVtUm93cyA9XHJcbiAgICAgIGl0ZW0ubWF4SXRlbVJvd3MgPT09IHVuZGVmaW5lZFxyXG4gICAgICAgID8gdGhpcy4kb3B0aW9ucy5tYXhJdGVtUm93c1xyXG4gICAgICAgIDogaXRlbS5tYXhJdGVtUm93cztcclxuICAgIGNvbnN0IG1pbkl0ZW1Sb3dzID1cclxuICAgICAgaXRlbS5taW5JdGVtUm93cyA9PT0gdW5kZWZpbmVkXHJcbiAgICAgICAgPyB0aGlzLiRvcHRpb25zLm1pbkl0ZW1Sb3dzXHJcbiAgICAgICAgOiBpdGVtLm1pbkl0ZW1Sb3dzO1xyXG4gICAgY29uc3QgaW5Db2xzTGltaXRzID0gaXRlbS5jb2xzIDw9IG1heEl0ZW1Db2xzICYmIGl0ZW0uY29scyA+PSBtaW5JdGVtQ29scztcclxuICAgIGNvbnN0IGluUm93c0xpbWl0cyA9IGl0ZW0ucm93cyA8PSBtYXhJdGVtUm93cyAmJiBpdGVtLnJvd3MgPj0gbWluSXRlbVJvd3M7XHJcbiAgICBjb25zdCBtaW5BcmVhTGltaXQgPVxyXG4gICAgICBpdGVtLm1pbkl0ZW1BcmVhID09PSB1bmRlZmluZWRcclxuICAgICAgICA/IHRoaXMuJG9wdGlvbnMubWluSXRlbUFyZWFcclxuICAgICAgICA6IGl0ZW0ubWluSXRlbUFyZWE7XHJcbiAgICBjb25zdCBtYXhBcmVhTGltaXQgPVxyXG4gICAgICBpdGVtLm1heEl0ZW1BcmVhID09PSB1bmRlZmluZWRcclxuICAgICAgICA/IHRoaXMuJG9wdGlvbnMubWF4SXRlbUFyZWFcclxuICAgICAgICA6IGl0ZW0ubWF4SXRlbUFyZWE7XHJcbiAgICBjb25zdCBhcmVhID0gaXRlbS5jb2xzICogaXRlbS5yb3dzO1xyXG4gICAgY29uc3QgaW5NaW5BcmVhID0gbWluQXJlYUxpbWl0IDw9IGFyZWE7XHJcbiAgICBjb25zdCBpbk1heEFyZWEgPSBtYXhBcmVhTGltaXQgPj0gYXJlYTtcclxuICAgIHJldHVybiAhKFxyXG4gICAgICBub05lZ2F0aXZlUG9zaXRpb24gJiZcclxuICAgICAgbWF4R3JpZENvbHMgJiZcclxuICAgICAgbWF4R3JpZFJvd3MgJiZcclxuICAgICAgaW5Db2xzTGltaXRzICYmXHJcbiAgICAgIGluUm93c0xpbWl0cyAmJlxyXG4gICAgICBpbk1pbkFyZWEgJiZcclxuICAgICAgaW5NYXhBcmVhXHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgZmluZEl0ZW1XaXRoSXRlbShcclxuICAgIGl0ZW06IEdyaWRzdGVySXRlbVxyXG4gICk6IEdyaWRzdGVySXRlbUNvbXBvbmVudEludGVyZmFjZSB8IGJvb2xlYW4ge1xyXG4gICAgbGV0IHdpZGdldHNJbmRleCA9IDA7XHJcbiAgICBsZXQgd2lkZ2V0OiBHcmlkc3Rlckl0ZW1Db21wb25lbnRJbnRlcmZhY2U7XHJcbiAgICBmb3IgKDsgd2lkZ2V0c0luZGV4IDwgdGhpcy5ncmlkLmxlbmd0aDsgd2lkZ2V0c0luZGV4KyspIHtcclxuICAgICAgd2lkZ2V0ID0gdGhpcy5ncmlkW3dpZGdldHNJbmRleF07XHJcbiAgICAgIGlmIChcclxuICAgICAgICB3aWRnZXQuJGl0ZW0gIT09IGl0ZW0gJiZcclxuICAgICAgICB0aGlzLmNoZWNrQ29sbGlzaW9uVHdvSXRlbXMod2lkZ2V0LiRpdGVtLCBpdGVtKVxyXG4gICAgICApIHtcclxuICAgICAgICByZXR1cm4gd2lkZ2V0O1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbiAgfVxyXG5cclxuICBmaW5kSXRlbXNXaXRoSXRlbShpdGVtOiBHcmlkc3Rlckl0ZW0pOiBBcnJheTxHcmlkc3Rlckl0ZW1Db21wb25lbnRJbnRlcmZhY2U+IHtcclxuICAgIGNvbnN0IGE6IEFycmF5PEdyaWRzdGVySXRlbUNvbXBvbmVudEludGVyZmFjZT4gPSBbXTtcclxuICAgIGxldCB3aWRnZXRzSW5kZXggPSAwO1xyXG4gICAgbGV0IHdpZGdldDogR3JpZHN0ZXJJdGVtQ29tcG9uZW50SW50ZXJmYWNlO1xyXG4gICAgZm9yICg7IHdpZGdldHNJbmRleCA8IHRoaXMuZ3JpZC5sZW5ndGg7IHdpZGdldHNJbmRleCsrKSB7XHJcbiAgICAgIHdpZGdldCA9IHRoaXMuZ3JpZFt3aWRnZXRzSW5kZXhdO1xyXG4gICAgICBpZiAoXHJcbiAgICAgICAgd2lkZ2V0LiRpdGVtICE9PSBpdGVtICYmXHJcbiAgICAgICAgdGhpcy5jaGVja0NvbGxpc2lvblR3b0l0ZW1zKHdpZGdldC4kaXRlbSwgaXRlbSlcclxuICAgICAgKSB7XHJcbiAgICAgICAgYS5wdXNoKHdpZGdldCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBhO1xyXG4gIH1cclxuXHJcbiAgYXV0b1Bvc2l0aW9uSXRlbShpdGVtQ29tcG9uZW50OiBHcmlkc3Rlckl0ZW1Db21wb25lbnRJbnRlcmZhY2UpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLmdldE5leHRQb3NzaWJsZVBvc2l0aW9uKGl0ZW1Db21wb25lbnQuJGl0ZW0pKSB7XHJcbiAgICAgIGl0ZW1Db21wb25lbnQubm90UGxhY2VkID0gZmFsc2U7XHJcbiAgICAgIGl0ZW1Db21wb25lbnQuaXRlbS54ID0gaXRlbUNvbXBvbmVudC4kaXRlbS54O1xyXG4gICAgICBpdGVtQ29tcG9uZW50Lml0ZW0ueSA9IGl0ZW1Db21wb25lbnQuJGl0ZW0ueTtcclxuICAgICAgaXRlbUNvbXBvbmVudC5pdGVtQ2hhbmdlZCgpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaXRlbUNvbXBvbmVudC5ub3RQbGFjZWQgPSB0cnVlO1xyXG4gICAgICBpZiAoIXRoaXMuJG9wdGlvbnMuZGlzYWJsZVdhcm5pbmdzKSB7XHJcbiAgICAgICAgY29uc29sZS53YXJuKFxyXG4gICAgICAgICAgXCJDYW4ndCBiZSBwbGFjZWQgaW4gdGhlIGJvdW5kcyBvZiB0aGUgZGFzaGJvYXJkIS9uXCIgK1xyXG4gICAgICAgICAgSlNPTi5zdHJpbmdpZnkoaXRlbUNvbXBvbmVudC5pdGVtLCBbJ2NvbHMnLCAncm93cycsICd4JywgJ3knXSlcclxuICAgICAgICApO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnZXROZXh0UG9zc2libGVQb3NpdGlvbiA9IChcclxuICAgIG5ld0l0ZW06IEdyaWRzdGVySXRlbSxcclxuICAgIHN0YXJ0aW5nRnJvbTogeyB5PzogbnVtYmVyOyB4PzogbnVtYmVyIH0gPSB7fVxyXG4gICk6IGJvb2xlYW4gPT4ge1xyXG4gICAgaWYgKG5ld0l0ZW0uY29scyA9PT0gLTEpIHtcclxuICAgICAgbmV3SXRlbS5jb2xzID0gdGhpcy4kb3B0aW9ucy5kZWZhdWx0SXRlbUNvbHM7XHJcbiAgICB9XHJcbiAgICBpZiAobmV3SXRlbS5yb3dzID09PSAtMSkge1xyXG4gICAgICBuZXdJdGVtLnJvd3MgPSB0aGlzLiRvcHRpb25zLmRlZmF1bHRJdGVtUm93cztcclxuICAgIH1cclxuICAgIHRoaXMuc2V0R3JpZERpbWVuc2lvbnMoKTtcclxuICAgIGxldCByb3dzSW5kZXggPSBzdGFydGluZ0Zyb20ueSB8fCAwO1xyXG4gICAgbGV0IGNvbHNJbmRleDtcclxuICAgIGZvciAoOyByb3dzSW5kZXggPCB0aGlzLnJvd3M7IHJvd3NJbmRleCsrKSB7XHJcbiAgICAgIG5ld0l0ZW0ueSA9IHJvd3NJbmRleDtcclxuICAgICAgY29sc0luZGV4ID0gc3RhcnRpbmdGcm9tLnggfHwgMDtcclxuICAgICAgZm9yICg7IGNvbHNJbmRleCA8IHRoaXMuY29sdW1uczsgY29sc0luZGV4KyspIHtcclxuICAgICAgICBuZXdJdGVtLnggPSBjb2xzSW5kZXg7XHJcbiAgICAgICAgaWYgKCF0aGlzLmNoZWNrQ29sbGlzaW9uKG5ld0l0ZW0pKSB7XHJcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGNvbnN0IGNhbkFkZFRvUm93cyA9IHRoaXMuJG9wdGlvbnMubWF4Um93cyA+PSB0aGlzLnJvd3MgKyBuZXdJdGVtLnJvd3M7XHJcbiAgICBjb25zdCBjYW5BZGRUb0NvbHVtbnMgPVxyXG4gICAgICB0aGlzLiRvcHRpb25zLm1heENvbHMgPj0gdGhpcy5jb2x1bW5zICsgbmV3SXRlbS5jb2xzO1xyXG4gICAgY29uc3QgYWRkVG9Sb3dzID0gdGhpcy5yb3dzIDw9IHRoaXMuY29sdW1ucyAmJiBjYW5BZGRUb1Jvd3M7XHJcbiAgICBpZiAoIWFkZFRvUm93cyAmJiBjYW5BZGRUb0NvbHVtbnMpIHtcclxuICAgICAgbmV3SXRlbS54ID0gdGhpcy5jb2x1bW5zO1xyXG4gICAgICBuZXdJdGVtLnkgPSAwO1xyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH0gZWxzZSBpZiAoY2FuQWRkVG9Sb3dzKSB7XHJcbiAgICAgIG5ld0l0ZW0ueSA9IHRoaXMucm93cztcclxuICAgICAgbmV3SXRlbS54ID0gMDtcclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbiAgfTtcclxuXHJcbiAgZ2V0Rmlyc3RQb3NzaWJsZVBvc2l0aW9uID0gKGl0ZW06IEdyaWRzdGVySXRlbSk6IEdyaWRzdGVySXRlbSA9PiB7XHJcbiAgICBjb25zdCB0bXBJdGVtID0gT2JqZWN0LmFzc2lnbih7fSwgaXRlbSk7XHJcbiAgICB0aGlzLmdldE5leHRQb3NzaWJsZVBvc2l0aW9uKHRtcEl0ZW0pO1xyXG4gICAgcmV0dXJuIHRtcEl0ZW07XHJcbiAgfTtcclxuXHJcbiAgZ2V0TGFzdFBvc3NpYmxlUG9zaXRpb24gPSAoaXRlbTogR3JpZHN0ZXJJdGVtKTogR3JpZHN0ZXJJdGVtID0+IHtcclxuICAgIGxldCBmYXJ0aGVzdEl0ZW06IHsgeTogbnVtYmVyOyB4OiBudW1iZXIgfSA9IHsgeTogMCwgeDogMCB9O1xyXG4gICAgZmFydGhlc3RJdGVtID0gdGhpcy5ncmlkLnJlZHVjZShcclxuICAgICAgKFxyXG4gICAgICAgIHByZXY6IHsgeTogbnVtYmVyOyB4OiBudW1iZXIgfSxcclxuICAgICAgICBjdXJyOiBHcmlkc3Rlckl0ZW1Db21wb25lbnRJbnRlcmZhY2VcclxuICAgICAgKSA9PiB7XHJcbiAgICAgICAgY29uc3QgY3VyckNvb3JkcyA9IHtcclxuICAgICAgICAgIHk6IGN1cnIuJGl0ZW0ueSArIGN1cnIuJGl0ZW0ucm93cyAtIDEsXHJcbiAgICAgICAgICB4OiBjdXJyLiRpdGVtLnggKyBjdXJyLiRpdGVtLmNvbHMgLSAxXHJcbiAgICAgICAgfTtcclxuICAgICAgICBpZiAoR3JpZHN0ZXJVdGlscy5jb21wYXJlSXRlbXMocHJldiwgY3VyckNvb3JkcykgPT09IDEpIHtcclxuICAgICAgICAgIHJldHVybiBjdXJyQ29vcmRzO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICByZXR1cm4gcHJldjtcclxuICAgICAgICB9XHJcbiAgICAgIH0sXHJcbiAgICAgIGZhcnRoZXN0SXRlbVxyXG4gICAgKTtcclxuXHJcbiAgICBjb25zdCB0bXBJdGVtID0gT2JqZWN0LmFzc2lnbih7fSwgaXRlbSk7XHJcbiAgICB0aGlzLmdldE5leHRQb3NzaWJsZVBvc2l0aW9uKHRtcEl0ZW0sIGZhcnRoZXN0SXRlbSk7XHJcbiAgICByZXR1cm4gdG1wSXRlbTtcclxuICB9O1xyXG5cclxuICBwaXhlbHNUb1Bvc2l0aW9uWChcclxuICAgIHg6IG51bWJlcixcclxuICAgIHJvdW5kaW5nTWV0aG9kOiAoeDogbnVtYmVyKSA9PiBudW1iZXIsXHJcbiAgICBub0xpbWl0PzogYm9vbGVhblxyXG4gICk6IG51bWJlciB7XHJcbiAgICBjb25zdCBwb3NpdGlvbiA9IHJvdW5kaW5nTWV0aG9kKHggLyB0aGlzLmN1ckNvbFdpZHRoKTtcclxuICAgIGlmIChub0xpbWl0KSB7XHJcbiAgICAgIHJldHVybiBwb3NpdGlvbjtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiBNYXRoLm1heChwb3NpdGlvbiwgMCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwaXhlbHNUb1Bvc2l0aW9uWShcclxuICAgIHk6IG51bWJlcixcclxuICAgIHJvdW5kaW5nTWV0aG9kOiAoeDogbnVtYmVyKSA9PiBudW1iZXIsXHJcbiAgICBub0xpbWl0PzogYm9vbGVhblxyXG4gICk6IG51bWJlciB7XHJcbiAgICBjb25zdCBwb3NpdGlvbiA9IHJvdW5kaW5nTWV0aG9kKHkgLyB0aGlzLmN1clJvd0hlaWdodCk7XHJcbiAgICBpZiAobm9MaW1pdCkge1xyXG4gICAgICByZXR1cm4gcG9zaXRpb247XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXR1cm4gTWF0aC5tYXgocG9zaXRpb24sIDApO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcG9zaXRpb25YVG9QaXhlbHMoeDogbnVtYmVyKTogbnVtYmVyIHtcclxuICAgIHJldHVybiB4ICogdGhpcy5jdXJDb2xXaWR0aDtcclxuICB9XHJcblxyXG4gIHBvc2l0aW9uWVRvUGl4ZWxzKHk6IG51bWJlcik6IG51bWJlciB7XHJcbiAgICByZXR1cm4geSAqIHRoaXMuY3VyUm93SGVpZ2h0O1xyXG4gIH1cclxuXHJcbiAgZ2V0SXRlbUNvbXBvbmVudChcclxuICAgIGl0ZW06IEdyaWRzdGVySXRlbVxyXG4gICk6IEdyaWRzdGVySXRlbUNvbXBvbmVudEludGVyZmFjZSB8IHVuZGVmaW5lZCB7XHJcbiAgICByZXR1cm4gdGhpcy5ncmlkLmZpbmQoYyA9PiBjLml0ZW0gPT09IGl0ZW0pO1xyXG4gIH1cclxuXHJcbiAgLy8gLS0tLS0tIEZ1bmN0aW9ucyBmb3Igc3dhcFdoaWxlRHJhZ2dpbmcgb3B0aW9uXHJcblxyXG4gIC8vIGlkZW50aWNhbCB0byBjaGVja0NvbGxpc2lvbigpIGV4Y2VwdCB0aGF0IHRoaXMgZnVuY3Rpb24gY2FsbHMgZmluZEl0ZW1XaXRoSXRlbUZvclN3YXBpbmcoKSBpbnN0ZWFkIG9mIGZpbmRJdGVtV2l0aEl0ZW0oKVxyXG4gIGNoZWNrQ29sbGlzaW9uRm9yU3dhcGluZyhcclxuICAgIGl0ZW06IEdyaWRzdGVySXRlbVxyXG4gICk6IEdyaWRzdGVySXRlbUNvbXBvbmVudEludGVyZmFjZSB8IGJvb2xlYW4ge1xyXG4gICAgbGV0IGNvbGxpc2lvbjogR3JpZHN0ZXJJdGVtQ29tcG9uZW50SW50ZXJmYWNlIHwgYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5pdGVtVmFsaWRhdGVDYWxsYmFjaykge1xyXG4gICAgICBjb2xsaXNpb24gPSAhdGhpcy5vcHRpb25zLml0ZW1WYWxpZGF0ZUNhbGxiYWNrKGl0ZW0pO1xyXG4gICAgfVxyXG4gICAgaWYgKCFjb2xsaXNpb24gJiYgdGhpcy5jaGVja0dyaWRDb2xsaXNpb24oaXRlbSkpIHtcclxuICAgICAgY29sbGlzaW9uID0gdHJ1ZTtcclxuICAgIH1cclxuICAgIGlmICghY29sbGlzaW9uKSB7XHJcbiAgICAgIGNvbnN0IGMgPSB0aGlzLmZpbmRJdGVtV2l0aEl0ZW1Gb3JTd2FwcGluZyhpdGVtKTtcclxuICAgICAgaWYgKGMpIHtcclxuICAgICAgICBjb2xsaXNpb24gPSBjO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gY29sbGlzaW9uO1xyXG4gIH1cclxuXHJcbiAgLy8gaWRlbnRpY2FsIHRvIGZpbmRJdGVtV2l0aEl0ZW0oKSBleGNlcHQgdGhhdCB0aGlzIGZ1bmN0aW9uIGNhbGxzIGNoZWNrQ29sbGlzaW9uVHdvSXRlbXNGb3JTd2FwaW5nKCkgaW5zdGVhZCBvZiBjaGVja0NvbGxpc2lvblR3b0l0ZW1zKClcclxuICBmaW5kSXRlbVdpdGhJdGVtRm9yU3dhcHBpbmcoXHJcbiAgICBpdGVtOiBHcmlkc3Rlckl0ZW1cclxuICApOiBHcmlkc3Rlckl0ZW1Db21wb25lbnRJbnRlcmZhY2UgfCBib29sZWFuIHtcclxuICAgIGxldCB3aWRnZXRzSW5kZXg6IG51bWJlciA9IHRoaXMuZ3JpZC5sZW5ndGggLSAxO1xyXG4gICAgbGV0IHdpZGdldDogR3JpZHN0ZXJJdGVtQ29tcG9uZW50SW50ZXJmYWNlO1xyXG4gICAgZm9yICg7IHdpZGdldHNJbmRleCA+IC0xOyB3aWRnZXRzSW5kZXgtLSkge1xyXG4gICAgICB3aWRnZXQgPSB0aGlzLmdyaWRbd2lkZ2V0c0luZGV4XTtcclxuICAgICAgaWYgKFxyXG4gICAgICAgIHdpZGdldC4kaXRlbSAhPT0gaXRlbSAmJlxyXG4gICAgICAgIEdyaWRzdGVyQ29tcG9uZW50LmNoZWNrQ29sbGlzaW9uVHdvSXRlbXNGb3JTd2FwaW5nKHdpZGdldC4kaXRlbSwgaXRlbSlcclxuICAgICAgKSB7XHJcbiAgICAgICAgcmV0dXJuIHdpZGdldDtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG4gIH1cclxuXHJcbiAgcHJldmlld1N0eWxlKGRyYWcgPSBmYWxzZSk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMubW92aW5nSXRlbSkge1xyXG4gICAgICBpZiAodGhpcy5jb21wYWN0ICYmIGRyYWcpIHtcclxuICAgICAgICB0aGlzLmNvbXBhY3QuY2hlY2tDb21wYWN0SXRlbSh0aGlzLm1vdmluZ0l0ZW0pO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMucHJldmlld1N0eWxlJC5uZXh0KHRoaXMubW92aW5nSXRlbSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLnByZXZpZXdTdHlsZSQubmV4dChudWxsKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIC0tLS0tLSBFbmQgb2YgZnVuY3Rpb25zIGZvciBzd2FwV2hpbGVEcmFnZ2luZyBvcHRpb25cclxuXHJcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9tZW1iZXItb3JkZXJpbmdcclxuICBwcml2YXRlIHN0YXRpYyBnZXROZXdBcnJheUxlbmd0aChcclxuICAgIGxlbmd0aDogbnVtYmVyLFxyXG4gICAgb3ZlcmFsbFNpemU6IG51bWJlcixcclxuICAgIHNpemU6IG51bWJlclxyXG4gICk6IG51bWJlciB7XHJcbiAgICBjb25zdCBuZXdMZW5ndGggPSBNYXRoLm1heChsZW5ndGgsIE1hdGguZmxvb3Iob3ZlcmFsbFNpemUgLyBzaXplKSk7XHJcblxyXG4gICAgaWYgKG5ld0xlbmd0aCA8IDApIHtcclxuICAgICAgcmV0dXJuIDA7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKE51bWJlci5pc0Zpbml0ZShuZXdMZW5ndGgpKSB7XHJcbiAgICAgIHJldHVybiBNYXRoLmZsb29yKG5ld0xlbmd0aCk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIDA7XHJcbiAgfVxyXG59XHJcbiIsIjxkaXZcclxuICBjbGFzcz1cImdyaWRzdGVyLWNvbHVtblwiXHJcbiAgKm5nRm9yPVwibGV0IGNvbHVtbiBvZiBncmlkQ29sdW1uczsgbGV0IGkgPSBpbmRleDtcIlxyXG4gIFtuZ1N0eWxlXT1cImdyaWRSZW5kZXJlci5nZXRHcmlkQ29sdW1uU3R5bGUoaSlcIlxyXG4+PC9kaXY+XHJcbjxkaXZcclxuICBjbGFzcz1cImdyaWRzdGVyLXJvd1wiXHJcbiAgKm5nRm9yPVwibGV0IHJvdyBvZiBncmlkUm93czsgbGV0IGkgPSBpbmRleDtcIlxyXG4gIFtuZ1N0eWxlXT1cImdyaWRSZW5kZXJlci5nZXRHcmlkUm93U3R5bGUoaSlcIlxyXG4+PC9kaXY+XHJcbjxuZy1jb250ZW50PjwvbmctY29udGVudD5cclxuPGdyaWRzdGVyLXByZXZpZXdcclxuICBbZ3JpZFJlbmRlcmVyXT1cImdyaWRSZW5kZXJlclwiXHJcbiAgW3ByZXZpZXdTdHlsZSRdPVwicHJldmlld1N0eWxlJFwiXHJcbiAgY2xhc3M9XCJncmlkc3Rlci1wcmV2aWV3XCJcclxuPjwvZ3JpZHN0ZXItcHJldmlldz5cclxuIl19