@swimlane/ngx-datatable 17.0.0 → 20.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/README.md +0 -1
  2. package/assets/icons.css +39 -19
  3. package/bundles/swimlane-ngx-datatable.umd.js +1103 -1564
  4. package/bundles/swimlane-ngx-datatable.umd.js.map +1 -1
  5. package/esm2015/lib/components/body/body-cell.component.js +40 -86
  6. package/esm2015/lib/components/body/body-group-header-template.directive.js +8 -10
  7. package/esm2015/lib/components/body/body-group-header.directive.js +11 -19
  8. package/esm2015/lib/components/body/body-row-wrapper.component.js +32 -54
  9. package/esm2015/lib/components/body/body-row.component.js +38 -75
  10. package/esm2015/lib/components/body/body.component.js +61 -137
  11. package/esm2015/lib/components/body/progress-bar.component.js +10 -12
  12. package/esm2015/lib/components/body/scroller.component.js +21 -33
  13. package/esm2015/lib/components/body/selection.component.js +19 -35
  14. package/esm2015/lib/components/body/summary/summary-row.component.js +19 -29
  15. package/esm2015/lib/components/columns/column-cell.directive.js +6 -8
  16. package/esm2015/lib/components/columns/column-header.directive.js +6 -8
  17. package/esm2015/lib/components/columns/column.directive.js +36 -92
  18. package/esm2015/lib/components/columns/tree.directive.js +6 -8
  19. package/esm2015/lib/components/datatable.component.js +85 -214
  20. package/esm2015/lib/components/footer/footer-template.directive.js +6 -8
  21. package/esm2015/lib/components/footer/footer.component.js +28 -54
  22. package/esm2015/lib/components/footer/footer.directive.js +16 -34
  23. package/esm2015/lib/components/footer/pager.component.js +23 -39
  24. package/esm2015/lib/components/header/header-cell.component.js +45 -80
  25. package/esm2015/lib/components/header/header.component.js +43 -80
  26. package/esm2015/lib/components/row-detail/row-detail-template.directive.js +8 -10
  27. package/esm2015/lib/components/row-detail/row-detail.directive.js +11 -19
  28. package/esm2015/lib/directives/draggable.directive.js +16 -30
  29. package/esm2015/lib/directives/long-press.directive.js +16 -34
  30. package/esm2015/lib/directives/orderable.directive.js +12 -19
  31. package/esm2015/lib/directives/resizeable.directive.js +19 -29
  32. package/esm2015/lib/directives/visibility.directive.js +11 -15
  33. package/esm2015/lib/events.js +1 -1
  34. package/esm2015/lib/ngx-datatable.module.js +54 -57
  35. package/esm2015/lib/services/column-changes.service.js +6 -8
  36. package/esm2015/lib/services/dimensions-helper.service.js +6 -8
  37. package/esm2015/lib/services/scrollbar-helper.service.js +6 -9
  38. package/esm2015/lib/types/click.type.js +1 -1
  39. package/esm2015/lib/types/column-mode.type.js +1 -1
  40. package/esm2015/lib/types/contextmenu.type.js +1 -1
  41. package/esm2015/lib/types/selection.type.js +1 -1
  42. package/esm2015/lib/types/sort-direction.type.js +1 -1
  43. package/esm2015/lib/types/sort-prop-dir.type.js +2 -1
  44. package/esm2015/lib/types/sort.type.js +1 -1
  45. package/esm2015/lib/types/table-column.type.js +2 -1
  46. package/esm2015/lib/utils/camel-case.js +1 -1
  47. package/esm2015/lib/utils/column-helper.js +1 -1
  48. package/esm2015/lib/utils/column-prop-getters.js +1 -1
  49. package/esm2015/lib/utils/column.js +1 -1
  50. package/esm2015/lib/utils/elm-from-point.js +1 -1
  51. package/esm2015/lib/utils/id.js +1 -1
  52. package/esm2015/lib/utils/keys.js +1 -1
  53. package/esm2015/lib/utils/math.js +1 -1
  54. package/esm2015/lib/utils/prefixes.js +1 -1
  55. package/esm2015/lib/utils/row-height-cache.js +1 -1
  56. package/esm2015/lib/utils/selection.js +1 -1
  57. package/esm2015/lib/utils/sort.js +1 -1
  58. package/esm2015/lib/utils/throttle.js +1 -1
  59. package/esm2015/lib/utils/translate.js +1 -1
  60. package/esm2015/lib/utils/tree.js +1 -1
  61. package/esm2015/public-api.js +3 -1
  62. package/esm2015/swimlane-ngx-datatable.js +1 -1
  63. package/fesm2015/swimlane-ngx-datatable.js +682 -1248
  64. package/fesm2015/swimlane-ngx-datatable.js.map +1 -1
  65. package/lib/components/header/header-cell.component.d.ts +2 -0
  66. package/lib/components/header/header.component.d.ts +1 -0
  67. package/lib/utils/throttle.d.ts +1 -1
  68. package/package.json +10 -10
  69. package/swimlane-ngx-datatable.metadata.json +1 -1
  70. package/bundles/swimlane-ngx-datatable.umd.min.js +0 -16
  71. package/bundles/swimlane-ngx-datatable.umd.min.js.map +0 -1
  72. package/esm5/lib/components/body/body-cell.component.js +0 -438
  73. package/esm5/lib/components/body/body-group-header-template.directive.js +0 -18
  74. package/esm5/lib/components/body/body-group-header.directive.js +0 -67
  75. package/esm5/lib/components/body/body-row-wrapper.component.js +0 -114
  76. package/esm5/lib/components/body/body-row.component.js +0 -260
  77. package/esm5/lib/components/body/body.component.js +0 -775
  78. package/esm5/lib/components/body/progress-bar.component.js +0 -16
  79. package/esm5/lib/components/body/scroller.component.js +0 -97
  80. package/esm5/lib/components/body/selection.component.js +0 -159
  81. package/esm5/lib/components/body/summary/summary-row.component.js +0 -81
  82. package/esm5/lib/components/columns/column-cell.directive.js +0 -16
  83. package/esm5/lib/components/columns/column-header.directive.js +0 -16
  84. package/esm5/lib/components/columns/column.directive.js +0 -134
  85. package/esm5/lib/components/columns/tree.directive.js +0 -16
  86. package/esm5/lib/components/datatable.component.js +0 -1147
  87. package/esm5/lib/components/footer/footer-template.directive.js +0 -16
  88. package/esm5/lib/components/footer/footer.component.js +0 -74
  89. package/esm5/lib/components/footer/footer.directive.js +0 -47
  90. package/esm5/lib/components/footer/pager.component.js +0 -135
  91. package/esm5/lib/components/header/header-cell.component.js +0 -253
  92. package/esm5/lib/components/header/header.component.js +0 -317
  93. package/esm5/lib/components/row-detail/row-detail-template.directive.js +0 -18
  94. package/esm5/lib/components/row-detail/row-detail.directive.js +0 -68
  95. package/esm5/lib/directives/draggable.directive.js +0 -118
  96. package/esm5/lib/directives/long-press.directive.js +0 -132
  97. package/esm5/lib/directives/orderable.directive.js +0 -161
  98. package/esm5/lib/directives/resizeable.directive.js +0 -101
  99. package/esm5/lib/directives/visibility.directive.js +0 -69
  100. package/esm5/lib/events.js +0 -7
  101. package/esm5/lib/ngx-datatable.module.js +0 -103
  102. package/esm5/lib/services/column-changes.service.js +0 -28
  103. package/esm5/lib/services/dimensions-helper.service.js +0 -19
  104. package/esm5/lib/services/scrollbar-helper.service.js +0 -38
  105. package/esm5/lib/types/click.type.js +0 -6
  106. package/esm5/lib/types/column-mode.type.js +0 -7
  107. package/esm5/lib/types/contextmenu.type.js +0 -6
  108. package/esm5/lib/types/selection.type.js +0 -9
  109. package/esm5/lib/types/sort-direction.type.js +0 -6
  110. package/esm5/lib/types/sort-prop-dir.type.js +0 -1
  111. package/esm5/lib/types/sort.type.js +0 -6
  112. package/esm5/lib/types/table-column.type.js +0 -1
  113. package/esm5/lib/utils/camel-case.js +0 -28
  114. package/esm5/lib/utils/column-helper.js +0 -128
  115. package/esm5/lib/utils/column-prop-getters.js +0 -96
  116. package/esm5/lib/utils/column.js +0 -103
  117. package/esm5/lib/utils/elm-from-point.js +0 -38
  118. package/esm5/lib/utils/id.js +0 -8
  119. package/esm5/lib/utils/keys.js +0 -10
  120. package/esm5/lib/utils/math.js +0 -224
  121. package/esm5/lib/utils/prefixes.js +0 -40
  122. package/esm5/lib/utils/row-height-cache.js +0 -137
  123. package/esm5/lib/utils/selection.js +0 -40
  124. package/esm5/lib/utils/sort.js +0 -139
  125. package/esm5/lib/utils/throttle.js +0 -60
  126. package/esm5/lib/utils/translate.js +0 -25
  127. package/esm5/lib/utils/tree.js +0 -106
  128. package/esm5/public-api.js +0 -62
  129. package/esm5/swimlane-ngx-datatable.js +0 -5
  130. package/fesm5/swimlane-ngx-datatable.js +0 -6088
  131. package/fesm5/swimlane-ngx-datatable.js.map +0 -1
  132. package/lib/test/jasmine-matchers.d.ts +0 -12
@@ -1,775 +0,0 @@
1
- import { __decorate, __values } from "tslib";
2
- import { Component, Output, EventEmitter, Input, HostBinding, ChangeDetectorRef, ViewChild, OnInit, OnDestroy, ChangeDetectionStrategy } from '@angular/core';
3
- import { ScrollerComponent } from './scroller.component';
4
- import { columnsByPin, columnGroupWidths } from '../../utils/column';
5
- import { RowHeightCache } from '../../utils/row-height-cache';
6
- import { translateXY } from '../../utils/translate';
7
- var DataTableBodyComponent = /** @class */ (function () {
8
- /**
9
- * Creates an instance of DataTableBodyComponent.
10
- */
11
- function DataTableBodyComponent(cd) {
12
- var _this = this;
13
- this.cd = cd;
14
- this.selected = [];
15
- this.scroll = new EventEmitter();
16
- this.page = new EventEmitter();
17
- this.activate = new EventEmitter();
18
- this.select = new EventEmitter();
19
- this.detailToggle = new EventEmitter();
20
- this.rowContextmenu = new EventEmitter(false);
21
- this.treeAction = new EventEmitter();
22
- this.rowHeightsCache = new RowHeightCache();
23
- this.temp = [];
24
- this.offsetY = 0;
25
- this.indexes = {};
26
- this.rowIndexes = new WeakMap();
27
- this.rowExpansions = [];
28
- /**
29
- * Get the height of the detail row.
30
- */
31
- this.getDetailRowHeight = function (row, index) {
32
- if (!_this.rowDetail) {
33
- return 0;
34
- }
35
- var rowHeight = _this.rowDetail.rowHeight;
36
- return typeof rowHeight === 'function' ? rowHeight(row, index) : rowHeight;
37
- };
38
- // declare fn here so we can get access to the `this` property
39
- this.rowTrackingFn = function (index, row) {
40
- var idx = _this.getRowIndex(row);
41
- if (_this.trackByProp) {
42
- return row[_this.trackByProp];
43
- }
44
- else {
45
- return idx;
46
- }
47
- };
48
- }
49
- Object.defineProperty(DataTableBodyComponent.prototype, "pageSize", {
50
- get: function () {
51
- return this._pageSize;
52
- },
53
- set: function (val) {
54
- this._pageSize = val;
55
- this.recalcLayout();
56
- },
57
- enumerable: true,
58
- configurable: true
59
- });
60
- Object.defineProperty(DataTableBodyComponent.prototype, "rows", {
61
- get: function () {
62
- return this._rows;
63
- },
64
- set: function (val) {
65
- this._rows = val;
66
- this.recalcLayout();
67
- },
68
- enumerable: true,
69
- configurable: true
70
- });
71
- Object.defineProperty(DataTableBodyComponent.prototype, "columns", {
72
- get: function () {
73
- return this._columns;
74
- },
75
- set: function (val) {
76
- this._columns = val;
77
- var colsByPin = columnsByPin(val);
78
- this.columnGroupWidths = columnGroupWidths(colsByPin, val);
79
- },
80
- enumerable: true,
81
- configurable: true
82
- });
83
- Object.defineProperty(DataTableBodyComponent.prototype, "offset", {
84
- get: function () {
85
- return this._offset;
86
- },
87
- set: function (val) {
88
- this._offset = val;
89
- if (!this.scrollbarV || (this.scrollbarV && !this.virtualization))
90
- this.recalcLayout();
91
- },
92
- enumerable: true,
93
- configurable: true
94
- });
95
- Object.defineProperty(DataTableBodyComponent.prototype, "rowCount", {
96
- get: function () {
97
- return this._rowCount;
98
- },
99
- set: function (val) {
100
- this._rowCount = val;
101
- this.recalcLayout();
102
- },
103
- enumerable: true,
104
- configurable: true
105
- });
106
- Object.defineProperty(DataTableBodyComponent.prototype, "bodyWidth", {
107
- get: function () {
108
- if (this.scrollbarH) {
109
- return this.innerWidth + 'px';
110
- }
111
- else {
112
- return '100%';
113
- }
114
- },
115
- enumerable: true,
116
- configurable: true
117
- });
118
- Object.defineProperty(DataTableBodyComponent.prototype, "bodyHeight", {
119
- get: function () {
120
- return this._bodyHeight;
121
- },
122
- set: function (val) {
123
- if (this.scrollbarV) {
124
- this._bodyHeight = val + 'px';
125
- }
126
- else {
127
- this._bodyHeight = 'auto';
128
- }
129
- this.recalcLayout();
130
- },
131
- enumerable: true,
132
- configurable: true
133
- });
134
- Object.defineProperty(DataTableBodyComponent.prototype, "selectEnabled", {
135
- /**
136
- * Returns if selection is enabled.
137
- */
138
- get: function () {
139
- return !!this.selectionType;
140
- },
141
- enumerable: true,
142
- configurable: true
143
- });
144
- Object.defineProperty(DataTableBodyComponent.prototype, "scrollHeight", {
145
- /**
146
- * Property that would calculate the height of scroll bar
147
- * based on the row heights cache for virtual scroll and virtualization. Other scenarios
148
- * calculate scroll height automatically (as height will be undefined).
149
- */
150
- get: function () {
151
- if (this.scrollbarV && this.virtualization && this.rowCount) {
152
- return this.rowHeightsCache.query(this.rowCount - 1);
153
- }
154
- // avoid TS7030: Not all code paths return a value.
155
- return undefined;
156
- },
157
- enumerable: true,
158
- configurable: true
159
- });
160
- /**
161
- * Called after the constructor, initializing input properties
162
- */
163
- DataTableBodyComponent.prototype.ngOnInit = function () {
164
- var _this = this;
165
- if (this.rowDetail) {
166
- this.listener = this.rowDetail.toggle.subscribe(function (_a) {
167
- var type = _a.type, value = _a.value;
168
- if (type === 'row') {
169
- _this.toggleRowExpansion(value);
170
- }
171
- if (type === 'all') {
172
- _this.toggleAllRows(value);
173
- }
174
- // Refresh rows after toggle
175
- // Fixes #883
176
- _this.updateIndexes();
177
- _this.updateRows();
178
- _this.cd.markForCheck();
179
- });
180
- }
181
- if (this.groupHeader) {
182
- this.listener = this.groupHeader.toggle.subscribe(function (_a) {
183
- var type = _a.type, value = _a.value;
184
- if (type === 'group') {
185
- _this.toggleRowExpansion(value);
186
- }
187
- if (type === 'all') {
188
- _this.toggleAllRows(value);
189
- }
190
- // Refresh rows after toggle
191
- // Fixes #883
192
- _this.updateIndexes();
193
- _this.updateRows();
194
- _this.cd.markForCheck();
195
- });
196
- }
197
- };
198
- /**
199
- * Called once, before the instance is destroyed.
200
- */
201
- DataTableBodyComponent.prototype.ngOnDestroy = function () {
202
- if (this.rowDetail || this.groupHeader) {
203
- this.listener.unsubscribe();
204
- }
205
- };
206
- /**
207
- * Updates the Y offset given a new offset.
208
- */
209
- DataTableBodyComponent.prototype.updateOffsetY = function (offset) {
210
- // scroller is missing on empty table
211
- if (!this.scroller) {
212
- return;
213
- }
214
- if (this.scrollbarV && this.virtualization && offset) {
215
- // First get the row Index that we need to move to.
216
- var rowIndex = this.pageSize * offset;
217
- offset = this.rowHeightsCache.query(rowIndex - 1);
218
- }
219
- else if (this.scrollbarV && !this.virtualization) {
220
- offset = 0;
221
- }
222
- this.scroller.setOffset(offset || 0);
223
- };
224
- /**
225
- * Body was scrolled, this is mainly useful for
226
- * when a user is server-side pagination via virtual scroll.
227
- */
228
- DataTableBodyComponent.prototype.onBodyScroll = function (event) {
229
- var scrollYPos = event.scrollYPos;
230
- var scrollXPos = event.scrollXPos;
231
- // if scroll change, trigger update
232
- // this is mainly used for header cell positions
233
- if (this.offsetY !== scrollYPos || this.offsetX !== scrollXPos) {
234
- this.scroll.emit({
235
- offsetY: scrollYPos,
236
- offsetX: scrollXPos
237
- });
238
- }
239
- this.offsetY = scrollYPos;
240
- this.offsetX = scrollXPos;
241
- this.updateIndexes();
242
- this.updatePage(event.direction);
243
- this.updateRows();
244
- };
245
- /**
246
- * Updates the page given a direction.
247
- */
248
- DataTableBodyComponent.prototype.updatePage = function (direction) {
249
- var offset = this.indexes.first / this.pageSize;
250
- if (direction === 'up') {
251
- offset = Math.ceil(offset);
252
- }
253
- else if (direction === 'down') {
254
- offset = Math.floor(offset);
255
- }
256
- if (direction !== undefined && !isNaN(offset)) {
257
- this.page.emit({ offset: offset });
258
- }
259
- };
260
- /**
261
- * Updates the rows in the view port
262
- */
263
- DataTableBodyComponent.prototype.updateRows = function () {
264
- var _this = this;
265
- var _a = this.indexes, first = _a.first, last = _a.last;
266
- var rowIndex = first;
267
- var idx = 0;
268
- var temp = [];
269
- // if grouprowsby has been specified treat row paging
270
- // parameters as group paging parameters ie if limit 10 has been
271
- // specified treat it as 10 groups rather than 10 rows
272
- if (this.groupedRows) {
273
- var maxRowsPerGroup = 3;
274
- // if there is only one group set the maximum number of
275
- // rows per group the same as the total number of rows
276
- if (this.groupedRows.length === 1) {
277
- maxRowsPerGroup = this.groupedRows[0].value.length;
278
- }
279
- while (rowIndex < last && rowIndex < this.groupedRows.length) {
280
- // Add the groups into this page
281
- var group = this.groupedRows[rowIndex];
282
- this.rowIndexes.set(group, rowIndex);
283
- if (group.value) {
284
- // add indexes for each group item
285
- group.value.forEach(function (g, i) {
286
- var _idx = rowIndex + "-" + i;
287
- _this.rowIndexes.set(g, _idx);
288
- });
289
- }
290
- temp[idx] = group;
291
- idx++;
292
- // Group index in this context
293
- rowIndex++;
294
- }
295
- }
296
- else {
297
- while (rowIndex < last && rowIndex < this.rowCount) {
298
- var row = this.rows[rowIndex];
299
- if (row) {
300
- // add indexes for each row
301
- this.rowIndexes.set(row, rowIndex);
302
- temp[idx] = row;
303
- }
304
- idx++;
305
- rowIndex++;
306
- }
307
- }
308
- this.temp = temp;
309
- };
310
- /**
311
- * Get the row height
312
- */
313
- DataTableBodyComponent.prototype.getRowHeight = function (row) {
314
- // if its a function return it
315
- if (typeof this.rowHeight === 'function') {
316
- return this.rowHeight(row);
317
- }
318
- return this.rowHeight;
319
- };
320
- /**
321
- * @param group the group with all rows
322
- */
323
- DataTableBodyComponent.prototype.getGroupHeight = function (group) {
324
- var rowHeight = 0;
325
- if (group.value) {
326
- for (var index = 0; index < group.value.length; index++) {
327
- rowHeight += this.getRowAndDetailHeight(group.value[index]);
328
- }
329
- }
330
- return rowHeight;
331
- };
332
- /**
333
- * Calculate row height based on the expanded state of the row.
334
- */
335
- DataTableBodyComponent.prototype.getRowAndDetailHeight = function (row) {
336
- var rowHeight = this.getRowHeight(row);
337
- var expanded = this.getRowExpanded(row);
338
- // Adding detail row height if its expanded.
339
- if (expanded) {
340
- rowHeight += this.getDetailRowHeight(row);
341
- }
342
- return rowHeight;
343
- };
344
- /**
345
- * Calculates the styles for the row so that the rows can be moved in 2D space
346
- * during virtual scroll inside the DOM. In the below case the Y position is
347
- * manipulated. As an example, if the height of row 0 is 30 px and row 1 is
348
- * 100 px then following styles are generated:
349
- *
350
- * transform: translate3d(0px, 0px, 0px); -> row0
351
- * transform: translate3d(0px, 30px, 0px); -> row1
352
- * transform: translate3d(0px, 130px, 0px); -> row2
353
- *
354
- * Row heights have to be calculated based on the row heights cache as we wont
355
- * be able to determine which row is of what height before hand. In the above
356
- * case the positionY of the translate3d for row2 would be the sum of all the
357
- * heights of the rows before it (i.e. row0 and row1).
358
- *
359
- * @param rows the row that needs to be placed in the 2D space.
360
- * @returns the CSS3 style to be applied
361
- *
362
- * @memberOf DataTableBodyComponent
363
- */
364
- DataTableBodyComponent.prototype.getRowsStyles = function (rows) {
365
- var styles = {};
366
- // only add styles for the group if there is a group
367
- if (this.groupedRows) {
368
- styles.width = this.columnGroupWidths.total;
369
- }
370
- if (this.scrollbarV && this.virtualization) {
371
- var idx = 0;
372
- if (this.groupedRows) {
373
- // Get the latest row rowindex in a group
374
- var row = rows[rows.length - 1];
375
- idx = row ? this.getRowIndex(row) : 0;
376
- }
377
- else {
378
- idx = this.getRowIndex(rows);
379
- }
380
- // const pos = idx * rowHeight;
381
- // The position of this row would be the sum of all row heights
382
- // until the previous row position.
383
- var pos = this.rowHeightsCache.query(idx - 1);
384
- translateXY(styles, 0, pos);
385
- }
386
- return styles;
387
- };
388
- /**
389
- * Calculate bottom summary row offset for scrollbar mode.
390
- * For more information about cache and offset calculation
391
- * see description for `getRowsStyles` method
392
- *
393
- * @returns the CSS3 style to be applied
394
- *
395
- * @memberOf DataTableBodyComponent
396
- */
397
- DataTableBodyComponent.prototype.getBottomSummaryRowStyles = function () {
398
- if (!this.scrollbarV || !this.rows || !this.rows.length) {
399
- return null;
400
- }
401
- var styles = { position: 'absolute' };
402
- var pos = this.rowHeightsCache.query(this.rows.length - 1);
403
- translateXY(styles, 0, pos);
404
- return styles;
405
- };
406
- /**
407
- * Hides the loading indicator
408
- */
409
- DataTableBodyComponent.prototype.hideIndicator = function () {
410
- var _this = this;
411
- setTimeout(function () { return (_this.loadingIndicator = false); }, 500);
412
- };
413
- /**
414
- * Updates the index of the rows in the viewport
415
- */
416
- DataTableBodyComponent.prototype.updateIndexes = function () {
417
- var first = 0;
418
- var last = 0;
419
- if (this.scrollbarV) {
420
- if (this.virtualization) {
421
- // Calculation of the first and last indexes will be based on where the
422
- // scrollY position would be at. The last index would be the one
423
- // that shows up inside the view port the last.
424
- var height = parseInt(this.bodyHeight, 0);
425
- first = this.rowHeightsCache.getRowIndex(this.offsetY);
426
- last = this.rowHeightsCache.getRowIndex(height + this.offsetY) + 1;
427
- }
428
- else {
429
- // If virtual rows are not needed
430
- // We render all in one go
431
- first = 0;
432
- last = this.rowCount;
433
- }
434
- }
435
- else {
436
- // The server is handling paging and will pass an array that begins with the
437
- // element at a specified offset. first should always be 0 with external paging.
438
- if (!this.externalPaging) {
439
- first = Math.max(this.offset * this.pageSize, 0);
440
- }
441
- last = Math.min(first + this.pageSize, this.rowCount);
442
- }
443
- this.indexes = { first: first, last: last };
444
- };
445
- /**
446
- * Refreshes the full Row Height cache. Should be used
447
- * when the entire row array state has changed.
448
- */
449
- DataTableBodyComponent.prototype.refreshRowHeightCache = function () {
450
- var e_1, _a;
451
- if (!this.scrollbarV || (this.scrollbarV && !this.virtualization)) {
452
- return;
453
- }
454
- // clear the previous row height cache if already present.
455
- // this is useful during sorts, filters where the state of the
456
- // rows array is changed.
457
- this.rowHeightsCache.clearCache();
458
- // Initialize the tree only if there are rows inside the tree.
459
- if (this.rows && this.rows.length) {
460
- var rowExpansions = new Set();
461
- try {
462
- for (var _b = __values(this.rows), _c = _b.next(); !_c.done; _c = _b.next()) {
463
- var row = _c.value;
464
- if (this.getRowExpanded(row)) {
465
- rowExpansions.add(row);
466
- }
467
- }
468
- }
469
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
470
- finally {
471
- try {
472
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
473
- }
474
- finally { if (e_1) throw e_1.error; }
475
- }
476
- this.rowHeightsCache.initCache({
477
- rows: this.rows,
478
- rowHeight: this.rowHeight,
479
- detailRowHeight: this.getDetailRowHeight,
480
- externalVirtual: this.scrollbarV && this.externalPaging,
481
- rowCount: this.rowCount,
482
- rowIndexes: this.rowIndexes,
483
- rowExpansions: rowExpansions
484
- });
485
- }
486
- };
487
- /**
488
- * Gets the index for the view port
489
- */
490
- DataTableBodyComponent.prototype.getAdjustedViewPortIndex = function () {
491
- // Capture the row index of the first row that is visible on the viewport.
492
- // If the scroll bar is just below the row which is highlighted then make that as the
493
- // first index.
494
- var viewPortFirstRowIndex = this.indexes.first;
495
- if (this.scrollbarV && this.virtualization) {
496
- var offsetScroll = this.rowHeightsCache.query(viewPortFirstRowIndex - 1);
497
- return offsetScroll <= this.offsetY ? viewPortFirstRowIndex - 1 : viewPortFirstRowIndex;
498
- }
499
- return viewPortFirstRowIndex;
500
- };
501
- /**
502
- * Toggle the Expansion of the row i.e. if the row is expanded then it will
503
- * collapse and vice versa. Note that the expanded status is stored as
504
- * a part of the row object itself as we have to preserve the expanded row
505
- * status in case of sorting and filtering of the row set.
506
- */
507
- DataTableBodyComponent.prototype.toggleRowExpansion = function (row) {
508
- // Capture the row index of the first row that is visible on the viewport.
509
- var viewPortFirstRowIndex = this.getAdjustedViewPortIndex();
510
- var rowExpandedIdx = this.getRowExpandedIdx(row, this.rowExpansions);
511
- var expanded = rowExpandedIdx > -1;
512
- // If the detailRowHeight is auto --> only in case of non-virtualized scroll
513
- if (this.scrollbarV && this.virtualization) {
514
- var detailRowHeight = this.getDetailRowHeight(row) * (expanded ? -1 : 1);
515
- // const idx = this.rowIndexes.get(row) || 0;
516
- var idx = this.getRowIndex(row);
517
- this.rowHeightsCache.update(idx, detailRowHeight);
518
- }
519
- // Update the toggled row and update thive nevere heights in the cache.
520
- if (expanded) {
521
- this.rowExpansions.splice(rowExpandedIdx, 1);
522
- }
523
- else {
524
- this.rowExpansions.push(row);
525
- }
526
- this.detailToggle.emit({
527
- rows: [row],
528
- currentIndex: viewPortFirstRowIndex
529
- });
530
- };
531
- /**
532
- * Expand/Collapse all the rows no matter what their state is.
533
- */
534
- DataTableBodyComponent.prototype.toggleAllRows = function (expanded) {
535
- var e_2, _a;
536
- // clear prev expansions
537
- this.rowExpansions = [];
538
- // Capture the row index of the first row that is visible on the viewport.
539
- var viewPortFirstRowIndex = this.getAdjustedViewPortIndex();
540
- if (expanded) {
541
- try {
542
- for (var _b = __values(this.rows), _c = _b.next(); !_c.done; _c = _b.next()) {
543
- var row = _c.value;
544
- this.rowExpansions.push(row);
545
- }
546
- }
547
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
548
- finally {
549
- try {
550
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
551
- }
552
- finally { if (e_2) throw e_2.error; }
553
- }
554
- }
555
- if (this.scrollbarV) {
556
- // Refresh the full row heights cache since every row was affected.
557
- this.recalcLayout();
558
- }
559
- // Emit all rows that have been expanded.
560
- this.detailToggle.emit({
561
- rows: this.rows,
562
- currentIndex: viewPortFirstRowIndex
563
- });
564
- };
565
- /**
566
- * Recalculates the table
567
- */
568
- DataTableBodyComponent.prototype.recalcLayout = function () {
569
- this.refreshRowHeightCache();
570
- this.updateIndexes();
571
- this.updateRows();
572
- };
573
- /**
574
- * Tracks the column
575
- */
576
- DataTableBodyComponent.prototype.columnTrackingFn = function (index, column) {
577
- return column.$$id;
578
- };
579
- /**
580
- * Gets the row pinning group styles
581
- */
582
- DataTableBodyComponent.prototype.stylesByGroup = function (group) {
583
- var widths = this.columnGroupWidths;
584
- var offsetX = this.offsetX;
585
- var styles = {
586
- width: widths[group] + "px"
587
- };
588
- if (group === 'left') {
589
- translateXY(styles, offsetX, 0);
590
- }
591
- else if (group === 'right') {
592
- var bodyWidth = parseInt(this.innerWidth + '', 0);
593
- var totalDiff = widths.total - bodyWidth;
594
- var offsetDiff = totalDiff - offsetX;
595
- var offset = offsetDiff * -1;
596
- translateXY(styles, offset, 0);
597
- }
598
- return styles;
599
- };
600
- /**
601
- * Returns if the row was expanded and set default row expansion when row expansion is empty
602
- */
603
- DataTableBodyComponent.prototype.getRowExpanded = function (row) {
604
- var e_3, _a;
605
- if (this.rowExpansions.length === 0 && this.groupExpansionDefault) {
606
- try {
607
- for (var _b = __values(this.groupedRows), _c = _b.next(); !_c.done; _c = _b.next()) {
608
- var group = _c.value;
609
- this.rowExpansions.push(group);
610
- }
611
- }
612
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
613
- finally {
614
- try {
615
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
616
- }
617
- finally { if (e_3) throw e_3.error; }
618
- }
619
- }
620
- return this.getRowExpandedIdx(row, this.rowExpansions) > -1;
621
- };
622
- DataTableBodyComponent.prototype.getRowExpandedIdx = function (row, expanded) {
623
- var _this = this;
624
- if (!expanded || !expanded.length)
625
- return -1;
626
- var rowId = this.rowIdentity(row);
627
- return expanded.findIndex(function (r) {
628
- var id = _this.rowIdentity(r);
629
- return id === rowId;
630
- });
631
- };
632
- /**
633
- * Gets the row index given a row
634
- */
635
- DataTableBodyComponent.prototype.getRowIndex = function (row) {
636
- return this.rowIndexes.get(row) || 0;
637
- };
638
- DataTableBodyComponent.prototype.onTreeAction = function (row) {
639
- this.treeAction.emit({ row: row });
640
- };
641
- DataTableBodyComponent.ctorParameters = function () { return [
642
- { type: ChangeDetectorRef }
643
- ]; };
644
- __decorate([
645
- Input()
646
- ], DataTableBodyComponent.prototype, "scrollbarV", void 0);
647
- __decorate([
648
- Input()
649
- ], DataTableBodyComponent.prototype, "scrollbarH", void 0);
650
- __decorate([
651
- Input()
652
- ], DataTableBodyComponent.prototype, "loadingIndicator", void 0);
653
- __decorate([
654
- Input()
655
- ], DataTableBodyComponent.prototype, "externalPaging", void 0);
656
- __decorate([
657
- Input()
658
- ], DataTableBodyComponent.prototype, "rowHeight", void 0);
659
- __decorate([
660
- Input()
661
- ], DataTableBodyComponent.prototype, "offsetX", void 0);
662
- __decorate([
663
- Input()
664
- ], DataTableBodyComponent.prototype, "emptyMessage", void 0);
665
- __decorate([
666
- Input()
667
- ], DataTableBodyComponent.prototype, "selectionType", void 0);
668
- __decorate([
669
- Input()
670
- ], DataTableBodyComponent.prototype, "selected", void 0);
671
- __decorate([
672
- Input()
673
- ], DataTableBodyComponent.prototype, "rowIdentity", void 0);
674
- __decorate([
675
- Input()
676
- ], DataTableBodyComponent.prototype, "rowDetail", void 0);
677
- __decorate([
678
- Input()
679
- ], DataTableBodyComponent.prototype, "groupHeader", void 0);
680
- __decorate([
681
- Input()
682
- ], DataTableBodyComponent.prototype, "selectCheck", void 0);
683
- __decorate([
684
- Input()
685
- ], DataTableBodyComponent.prototype, "displayCheck", void 0);
686
- __decorate([
687
- Input()
688
- ], DataTableBodyComponent.prototype, "trackByProp", void 0);
689
- __decorate([
690
- Input()
691
- ], DataTableBodyComponent.prototype, "rowClass", void 0);
692
- __decorate([
693
- Input()
694
- ], DataTableBodyComponent.prototype, "groupedRows", void 0);
695
- __decorate([
696
- Input()
697
- ], DataTableBodyComponent.prototype, "groupExpansionDefault", void 0);
698
- __decorate([
699
- Input()
700
- ], DataTableBodyComponent.prototype, "innerWidth", void 0);
701
- __decorate([
702
- Input()
703
- ], DataTableBodyComponent.prototype, "groupRowsBy", void 0);
704
- __decorate([
705
- Input()
706
- ], DataTableBodyComponent.prototype, "virtualization", void 0);
707
- __decorate([
708
- Input()
709
- ], DataTableBodyComponent.prototype, "summaryRow", void 0);
710
- __decorate([
711
- Input()
712
- ], DataTableBodyComponent.prototype, "summaryPosition", void 0);
713
- __decorate([
714
- Input()
715
- ], DataTableBodyComponent.prototype, "summaryHeight", void 0);
716
- __decorate([
717
- Input()
718
- ], DataTableBodyComponent.prototype, "pageSize", null);
719
- __decorate([
720
- Input()
721
- ], DataTableBodyComponent.prototype, "rows", null);
722
- __decorate([
723
- Input()
724
- ], DataTableBodyComponent.prototype, "columns", null);
725
- __decorate([
726
- Input()
727
- ], DataTableBodyComponent.prototype, "offset", null);
728
- __decorate([
729
- Input()
730
- ], DataTableBodyComponent.prototype, "rowCount", null);
731
- __decorate([
732
- HostBinding('style.width')
733
- ], DataTableBodyComponent.prototype, "bodyWidth", null);
734
- __decorate([
735
- Input(),
736
- HostBinding('style.height')
737
- ], DataTableBodyComponent.prototype, "bodyHeight", null);
738
- __decorate([
739
- Output()
740
- ], DataTableBodyComponent.prototype, "scroll", void 0);
741
- __decorate([
742
- Output()
743
- ], DataTableBodyComponent.prototype, "page", void 0);
744
- __decorate([
745
- Output()
746
- ], DataTableBodyComponent.prototype, "activate", void 0);
747
- __decorate([
748
- Output()
749
- ], DataTableBodyComponent.prototype, "select", void 0);
750
- __decorate([
751
- Output()
752
- ], DataTableBodyComponent.prototype, "detailToggle", void 0);
753
- __decorate([
754
- Output()
755
- ], DataTableBodyComponent.prototype, "rowContextmenu", void 0);
756
- __decorate([
757
- Output()
758
- ], DataTableBodyComponent.prototype, "treeAction", void 0);
759
- __decorate([
760
- ViewChild(ScrollerComponent)
761
- ], DataTableBodyComponent.prototype, "scroller", void 0);
762
- DataTableBodyComponent = __decorate([
763
- Component({
764
- selector: 'datatable-body',
765
- template: "\n <datatable-progress *ngIf=\"loadingIndicator\"> </datatable-progress>\n <datatable-selection\n #selector\n [selected]=\"selected\"\n [rows]=\"rows\"\n [selectCheck]=\"selectCheck\"\n [selectEnabled]=\"selectEnabled\"\n [selectionType]=\"selectionType\"\n [rowIdentity]=\"rowIdentity\"\n (select)=\"select.emit($event)\"\n (activate)=\"activate.emit($event)\"\n >\n <datatable-scroller\n *ngIf=\"rows?.length\"\n [scrollbarV]=\"scrollbarV\"\n [scrollbarH]=\"scrollbarH\"\n [scrollHeight]=\"scrollHeight\"\n [scrollWidth]=\"columnGroupWidths?.total\"\n (scroll)=\"onBodyScroll($event)\"\n >\n <datatable-summary-row\n *ngIf=\"summaryRow && summaryPosition === 'top'\"\n [rowHeight]=\"summaryHeight\"\n [offsetX]=\"offsetX\"\n [innerWidth]=\"innerWidth\"\n [rows]=\"rows\"\n [columns]=\"columns\"\n >\n </datatable-summary-row>\n <datatable-row-wrapper\n [groupedRows]=\"groupedRows\"\n *ngFor=\"let group of temp; let i = index; trackBy: rowTrackingFn\"\n [innerWidth]=\"innerWidth\"\n [ngStyle]=\"getRowsStyles(group)\"\n [rowDetail]=\"rowDetail\"\n [groupHeader]=\"groupHeader\"\n [offsetX]=\"offsetX\"\n [detailRowHeight]=\"getDetailRowHeight(group && group[i], i)\"\n [row]=\"group\"\n [expanded]=\"getRowExpanded(group)\"\n [rowIndex]=\"getRowIndex(group && group[i])\"\n (rowContextmenu)=\"rowContextmenu.emit($event)\"\n >\n <datatable-body-row\n *ngIf=\"!groupedRows; else groupedRowsTemplate\"\n tabindex=\"-1\"\n [isSelected]=\"selector.getRowSelected(group)\"\n [innerWidth]=\"innerWidth\"\n [offsetX]=\"offsetX\"\n [columns]=\"columns\"\n [rowHeight]=\"getRowHeight(group)\"\n [row]=\"group\"\n [rowIndex]=\"getRowIndex(group)\"\n [expanded]=\"getRowExpanded(group)\"\n [rowClass]=\"rowClass\"\n [displayCheck]=\"displayCheck\"\n [treeStatus]=\"group && group.treeStatus\"\n (treeAction)=\"onTreeAction(group)\"\n (activate)=\"selector.onActivate($event, indexes.first + i)\"\n >\n </datatable-body-row>\n <ng-template #groupedRowsTemplate>\n <datatable-body-row\n *ngFor=\"let row of group.value; let i = index; trackBy: rowTrackingFn\"\n tabindex=\"-1\"\n [isSelected]=\"selector.getRowSelected(row)\"\n [innerWidth]=\"innerWidth\"\n [offsetX]=\"offsetX\"\n [columns]=\"columns\"\n [rowHeight]=\"getRowHeight(row)\"\n [row]=\"row\"\n [group]=\"group.value\"\n [rowIndex]=\"getRowIndex(row)\"\n [expanded]=\"getRowExpanded(row)\"\n [rowClass]=\"rowClass\"\n (activate)=\"selector.onActivate($event, i)\"\n >\n </datatable-body-row>\n </ng-template>\n </datatable-row-wrapper>\n <datatable-summary-row\n *ngIf=\"summaryRow && summaryPosition === 'bottom'\"\n [ngStyle]=\"getBottomSummaryRowStyles()\"\n [rowHeight]=\"summaryHeight\"\n [offsetX]=\"offsetX\"\n [innerWidth]=\"innerWidth\"\n [rows]=\"rows\"\n [columns]=\"columns\"\n >\n </datatable-summary-row>\n </datatable-scroller>\n <div class=\"empty-row\" *ngIf=\"!rows?.length && !loadingIndicator\" [innerHTML]=\"emptyMessage\"></div>\n </datatable-selection>\n ",
766
- changeDetection: ChangeDetectionStrategy.OnPush,
767
- host: {
768
- class: 'datatable-body'
769
- }
770
- })
771
- ], DataTableBodyComponent);
772
- return DataTableBodyComponent;
773
- }());
774
- export { DataTableBodyComponent };
775
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9keS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Ac3dpbWxhbmUvbmd4LWRhdGF0YWJsZS8iLCJzb3VyY2VzIjpbImxpYi9jb21wb25lbnRzL2JvZHkvYm9keS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsTUFBTSxFQUNOLFlBQVksRUFDWixLQUFLLEVBQ0wsV0FBVyxFQUNYLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsTUFBTSxFQUNOLFNBQVMsRUFDVCx1QkFBdUIsRUFDeEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFekQsT0FBTyxFQUFFLFlBQVksRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3JFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUF3R3BEO0lBaUpFOztPQUVHO0lBQ0gsZ0NBQW9CLEVBQXFCO1FBQXpDLGlCQVVDO1FBVm1CLE9BQUUsR0FBRixFQUFFLENBQW1CO1FBM0loQyxhQUFRLEdBQVUsRUFBRSxDQUFDO1FBd0ZwQixXQUFNLEdBQXNCLElBQUksWUFBWSxFQUFFLENBQUM7UUFDL0MsU0FBSSxHQUFzQixJQUFJLFlBQVksRUFBRSxDQUFDO1FBQzdDLGFBQVEsR0FBc0IsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUNqRCxXQUFNLEdBQXNCLElBQUksWUFBWSxFQUFFLENBQUM7UUFDL0MsaUJBQVksR0FBc0IsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUNyRCxtQkFBYyxHQUFHLElBQUksWUFBWSxDQUFrQyxLQUFLLENBQUMsQ0FBQztRQUMxRSxlQUFVLEdBQXNCLElBQUksWUFBWSxFQUFFLENBQUM7UUF3QjdELG9CQUFlLEdBQW1CLElBQUksY0FBYyxFQUFFLENBQUM7UUFD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QU0sRUFBRTt3REFBOEM7SUFDN0M7UUFBVCxNQUFNLEVBQUU7NERBQWtEO0lBQ2pEO1FBQVQsTUFBTSxFQUFFOzBEQUFnRDtJQUMvQztRQUFULE1BQU0sRUFBRTtnRUFBc0Q7SUFDckQ7UUFBVCxNQUFNLEVBQUU7a0VBQTJFO0lBQzFFO1FBQVQsTUFBTSxFQUFFOzhEQUFvRDtJQUUvQjtRQUE3QixTQUFTLENBQUMsaUJBQWlCLENBQUM7NERBQTZCO0lBekcvQyxzQkFBc0I7UUF0R2xDLFNBQVMsQ0FBQztZQUNULFFBQVEsRUFBRSxnQkFBZ0I7WUFDMUIsUUFBUSxFQUFFLDBxSEE4RlQ7WUFDRCxlQUFlLEVBQUUsdUJBQXVCLENBQUMsTUFBTTtZQUMvQyxJQUFJLEVBQUU7Z0JBQ0osS0FBSyxFQUFFLGdCQUFnQjthQUN4QjtTQUNGLENBQUM7T0FDVyxzQkFBc0IsQ0FxcUJsQztJQUFELDZCQUFDO0NBQUEsQUFycUJELElBcXFCQztTQXJxQlksc0JBQXNCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBPdXRwdXQsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIEhvc3RCaW5kaW5nLFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgVmlld0NoaWxkLFxuICBPbkluaXQsXG4gIE9uRGVzdHJveSxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3lcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBTY3JvbGxlckNvbXBvbmVudCB9IGZyb20gJy4vc2Nyb2xsZXIuY29tcG9uZW50JztcbmltcG9ydCB7IFNlbGVjdGlvblR5cGUgfSBmcm9tICcuLi8uLi90eXBlcy9zZWxlY3Rpb24udHlwZSc7XG5pbXBvcnQgeyBjb2x1bW5zQnlQaW4sIGNvbHVtbkdyb3VwV2lkdGhzIH0gZnJvbSAnLi4vLi4vdXRpbHMvY29sdW1uJztcbmltcG9ydCB7IFJvd0hlaWdodENhY2hlIH0gZnJvbSAnLi4vLi4vdXRpbHMvcm93LWhlaWdodC1jYWNoZSc7XG5pbXBvcnQgeyB0cmFuc2xhdGVYWSB9IGZyb20gJy4uLy4uL3V0aWxzL3RyYW5zbGF0ZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2RhdGF0YWJsZS1ib2R5JyxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGF0YXRhYmxlLXByb2dyZXNzICpuZ0lmPVwibG9hZGluZ0luZGljYXRvclwiPiA8L2RhdGF0YWJsZS1wcm9ncmVzcz5cbiAgICA8ZGF0YXRhYmxlLXNlbGVjdGlvblxuICAgICAgI3NlbGVjdG9yXG4gICAgICBbc2VsZWN0ZWRdPVwic2VsZWN0ZWRcIlxuICAgICAgW3Jvd3NdPVwicm93c1wiXG4gICAgICBbc2VsZWN0Q2hlY2tdPVwic2VsZWN0Q2hlY2tcIlxuICAgICAgW3NlbGVjdEVuYWJsZWRdPVwic2VsZWN0RW5hYmxlZFwiXG4gICAgICBbc2VsZWN0aW9uVHlwZV09XCJzZWxlY3Rpb25UeXBlXCJcbiAgICAgIFtyb3dJZGVudGl0eV09XCJyb3dJZGVudGl0eVwiXG4gICAgICAoc2VsZWN0KT1cInNlbGVjdC5lbWl0KCRldmVudClcIlxuICAgICAgKGFjdGl2YXRlKT1cImFjdGl2YXRlLmVtaXQoJGV2ZW50KVwiXG4gICAgPlxuICAgICAgPGRhdGF0YWJsZS1zY3JvbGxlclxuICAgICAgICAqbmdJZj1cInJvd3M/Lmxlbmd0aFwiXG4gICAgICAgIFtzY3JvbGxiYXJWXT1cInNjcm9sbGJhclZcIlxuICAgICAgICBbc2Nyb2xsYmFySF09XCJzY3JvbGxiYXJIXCJcbiAgICAgICAgW3Njcm9sbEhlaWdodF09XCJzY3JvbGxIZWlnaHRcIlxuICAgICAgICBbc2Nyb2xsV2lkdGhdPVwiY29sdW1uR3JvdXBXaWR0aHM/LnRvdGFsXCJcbiAgICAgICAgKHNjcm9sbCk9XCJvbkJvZHlTY3JvbGwoJGV2ZW50KVwiXG4gICAgICA+XG4gICAgICAgIDxkYXRhdGFibGUtc3VtbWFyeS1yb3dcbiAgICAgICAgICAqbmdJZj1cInN1bW1hcnlSb3cgJiYgc3VtbWFyeVBvc2l0aW9uID09PSAndG9wJ1wiXG4gICAgICAgICAgW3Jvd0hlaWdodF09XCJzdW1tYXJ5SGVpZ2h0XCJcbiAgICAgICAgICBbb2Zmc2V0WF09XCJvZmZzZXRYXCJcbiAgICAgICAgICBbaW5uZXJXaWR0aF09XCJpbm5lcldpZHRoXCJcbiAgICAgICAgICBbcm93c109XCJyb3dzXCJcbiAgICAgICAgICBbY29sdW1uc109XCJjb2x1bW5zXCJcbiAgICAgICAgPlxuICAgICAgICA8L2RhdGF0YWJsZS1zdW1tYXJ5LXJvdz5cbiAgICAgICAgPGRhdGF0YWJsZS1yb3ctd3JhcHBlclxuICAgICAgICAgIFtncm91cGVkUm93c109XCJncm91cGVkUm93c1wiXG4gICAgICAgICAgKm5nRm9yPVwibGV0IGdyb3VwIG9mIHRlbXA7IGxldCBpID0gaW5kZXg7IHRyYWNrQnk6IHJvd1RyYWNraW5nRm5cIlxuICAgICAgICAgIFtpbm5lcldpZHRoXT1cImlubmVyV2lkdGhcIlxuICAgICAgICAgIFtuZ1N0eWxlXT1cImdldFJvd3NTdHlsZXMoZ3JvdXApXCJcbiAgICAgICAgICBbcm93RGV0YWlsXT1cInJvd0RldGFpbFwiXG4gICAgICAgICAgW2dyb3VwSGVhZGVyXT1cImdyb3VwSGVhZGVyXCJcbiAgICAgICAgICBbb2Zmc2V0WF09XCJvZmZzZXRYXCJcbiAgICAgICAgICBbZGV0YWlsUm93SGVpZ2h0XT1cImdldERldGFpbFJvd0hlaWdodChncm91cCAmJiBncm91cFtpXSwgaSlcIlxuICAgICAgICAgIFtyb3ddPVwiZ3JvdXBcIlxuICAgICAgICAgIFtleHBhbmRlZF09XCJnZXRSb3dFeHBhbmRlZChncm91cClcIlxuICAgICAgICAgIFtyb3dJbmRleF09XCJnZXRSb3dJbmRleChncm91cCAmJiBncm91cFtpXSlcIlxuICAgICAgICAgIChyb3dDb250ZXh0bWVudSk9XCJyb3dDb250ZXh0bWVudS5lbWl0KCRldmVudClcIlxuICAgICAgICA+XG4gICAgICAgICAgPGRhdGF0YWJsZS1ib2R5LXJvd1xuICAgICAgICAgICAgKm5nSWY9XCIhZ3JvdXBlZFJvd3M7IGVsc2UgZ3JvdXBlZFJvd3NUZW1wbGF0ZVwiXG4gICAgICAgICAgICB0YWJpbmRleD1cIi0xXCJcbiAgICAgICAgICAgIFtpc1NlbGVjdGVkXT1cInNlbGVjdG9yLmdldFJvd1NlbGVjdGVkKGdyb3VwKVwiXG4gICAgICAgICAgICBbaW5uZXJXaWR0aF09XCJpbm5lcldpZHRoXCJcbiAgICAgICAgICAgIFtvZmZzZXRYXT1cIm9mZnNldFhcIlxuICAgICAgICAgICAgW2NvbHVtbnNdPVwiY29sdW1uc1wiXG4gICAgICAgICAgICBbcm93SGVpZ2h0XT1cImdldFJvd0hlaWdodChncm91cClcIlxuICAgICAgICAgICAgW3Jvd109XCJncm91cFwiXG4gICAgICAgICAgICBbcm93SW5kZXhdPVwiZ2V0Um93SW5kZXgoZ3JvdXApXCJcbiAgICAgICAgICAgIFtleHBhbmRlZF09XCJnZXRSb3dFeHBhbmRlZChncm91cClcIlxuICAgICAgICAgICAgW3Jvd0NsYXNzXT1cInJvd0NsYXNzXCJcbiAgICAgICAgICAgIFtkaXNwbGF5Q2hlY2tdPVwiZGlzcGxheUNoZWNrXCJcbiAgICAgICAgICAgIFt0cmVlU3RhdHVzXT1cImdyb3VwICYmIGdyb3VwLnRyZWVTdGF0dXNcIlxuICAgICAgICAgICAgKHRyZWVBY3Rpb24pPVwib25UcmVlQWN0aW9uKGdyb3VwKVwiXG4gICAgICAgICAgICAoYWN0aXZhdGUpPVwic2VsZWN0b3Iub25BY3RpdmF0ZSgkZXZlbnQsIGluZGV4ZXMuZmlyc3QgKyBpKVwiXG4gICAgICAgICAgPlxuICAgICAgICAgIDwvZGF0YXRhYmxlLWJvZHktcm93PlxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZ3JvdXBlZFJvd3NUZW1wbGF0ZT5cbiAgICAgICAgICAgIDxkYXRhdGFibGUtYm9keS1yb3dcbiAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IHJvdyBvZiBncm91cC52YWx1ZTsgbGV0IGkgPSBpbmRleDsgdHJhY2tCeTogcm93VHJhY2tpbmdGblwiXG4gICAgICAgICAgICAgIHRhYmluZGV4PVwiLTFcIlxuICAgICAgICAgICAgICBbaXNTZWxlY3RlZF09XCJzZWxlY3Rvci5nZXRSb3dTZWxlY3RlZChyb3cpXCJcbiAgICAgICAgICAgICAgW2lubmVyV2lkdGhdPVwiaW5uZXJXaWR0aFwiXG4gICAgICAgICAgICAgIFtvZmZzZXRYXT1cIm9mZnNldFhcIlxuICAgICAgICAgICAgICBbY29sdW1uc109XCJjb2x1bW5zXCJcbiAgICAgICAgICAgICAgW3Jvd0hlaWdodF09XCJnZXRSb3dIZWlnaHQocm93KVwiXG4gICAgICAgICAgICAgIFtyb3ddPVwicm93XCJcbiAgICAgICAgICAgICAgW2dyb3VwXT1cImdyb3VwLnZhbHVlXCJcbiAgICAgICAgICAgICAgW3Jvd0luZGV4XT1cImdldFJvd0luZGV4KHJvdylcIlxuICAgICAgICAgICAgICBbZXhwYW5kZWRdPVwiZ2V0Um93RXhwYW5kZWQocm93KVwiXG4gICAgICAgICAgICAgIFtyb3dDbGFzc109XCJyb3dDbGFzc1wiXG4gICAgICAgICAgICAgIChhY3RpdmF0ZSk9XCJzZWxlY3Rvci5vbkFjdGl2YXRlKCRldmVudCwgaSlcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgPC9kYXRhdGFibGUtYm9keS1yb3c+XG4gICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC9kYXRhdGFibGUtcm93LXdyYXBwZXI+XG4gICAgICAgIDxkYXRhdGFibGUtc3VtbWFyeS1yb3dcbiAgICAgICAgICAqbmdJZj1cInN1bW1hcnlSb3cgJiYgc3VtbWFyeVBvc2l0aW9uID09PSAnYm90dG9tJ1wiXG4gICAgICAgICAgW25nU3R5bGVdPVwiZ2V0Qm90dG9tU3VtbWFyeVJvd1N0eWxlcygpXCJcbiAgICAgICAgICBbcm93SGVpZ2h0XT1cInN1bW1hcnlIZWlnaHRcIlxuICAgICAgICAgIFtvZmZzZXRYXT1cIm9mZnNldFhcIlxuICAgICAgICAgIFtpbm5lcldpZHRoXT1cImlubmVyV2lkdGhcIlxuICAgICAgICAgIFtyb3dzXT1cInJvd3NcIlxuICAgICAgICAgIFtjb2x1bW5zXT1cImNvbHVtbnNcIlxuICAgICAgICA+XG4gICAgICAgIDwvZGF0YXRhYmxlLXN1bW1hcnktcm93PlxuICAgICAgPC9kYXRhdGFibGUtc2Nyb2xsZXI+XG4gICAgICA8ZGl2IGNsYXNzPVwiZW1wdHktcm93XCIgKm5nSWY9XCIhcm93cz8ubGVuZ3RoICYmICFsb2FkaW5nSW5kaWNhdG9yXCIgW2lubmVySFRNTF09XCJlbXB0eU1lc3NhZ2VcIj48L2Rpdj5cbiAgICA8L2RhdGF0YWJsZS1zZWxlY3Rpb24+XG4gIGAsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBob3N0OiB7XG4gICAgY2xhc3M6ICdkYXRhdGFibGUtYm9keSdcbiAgfVxufSlcbmV4cG9ydCBjbGFzcyBEYXRhVGFibGVCb2R5Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICBASW5wdXQoKSBzY3JvbGxiYXJWOiBib29sZWFuO1xuICBASW5wdXQoKSBzY3JvbGxiYXJIOiBib29sZWFuO1xuICBASW5wdXQoKSBsb2FkaW5nSW5kaWNhdG9yOiBib29sZWFuO1xuICBASW5wdXQoKSBleHRlcm5hbFBhZ2luZzogYm9vbGVhbjtcbiAgQElucHV0KCkgcm93SGVpZ2h0OiBudW1iZXIgfCAnYXV0bycgfCAoKHJvdz86IGFueSkgPT4gbnVtYmVyKTtcbiAgQElucHV0KCkgb2Zmc2V0WDogbnVtYmVyO1xuICBASW5wdXQoKSBlbXB0eU1lc3NhZ2U6IHN0cmluZztcbiAgQElucHV0KCkgc2VsZWN0aW9uVHlwZTogU2VsZWN0aW9uVHlwZTtcbiAgQElucHV0KCkgc2VsZWN0ZWQ6IGFueVtdID0gW107XG4gIEBJbnB1dCgpIHJvd0lkZW50aXR5OiBhbnk7XG4gIEBJbnB1dCgpIHJvd0RldGFpbDogYW55O1xuICBASW5wdXQoKSBncm91cEhlYWRlcjogYW55O1xuICBASW5wdXQoKSBzZWxlY3RDaGVjazogYW55O1xuICBASW5wdXQoKSBkaXNwbGF5Q2hlY2s6IGFueTtcbiAgQElucHV0KCkgdHJhY2tCeVByb3A6IHN0cmluZztcbiAgQElucHV0KCkgcm93Q2xhc3M6IGFueTtcbiAgQElucHV0KCkgZ3JvdXBlZFJvd3M6IGFueTtcbiAgQElucHV0KCkgZ3JvdXBFeHBhbnNpb25EZWZhdWx0OiBib29sZWFuO1xuICBASW5wdXQoKSBpbm5lcldpZHRoOiBudW1iZXI7XG4gIEBJbnB1dCgpIGdyb3VwUm93c0J5OiBzdHJpbmc7XG4gIEBJbnB1dCgpIHZpcnR1YWxpemF0aW9uOiBib29sZWFuO1xuICBASW5wdXQoKSBzdW1tYXJ5Um93OiBib29sZWFuO1xuICBASW5wdXQoKSBzdW1tYXJ5UG9zaXRpb246IHN0cmluZztcbiAgQElucHV0KCkgc3VtbWFyeUhlaWdodDogbnVtYmVyO1xuXG4gIEBJbnB1dCgpIHNldCBwYWdlU2l6ZSh2YWw6IG51bWJlcikge1xuICAgIHRoaXMuX3BhZ2VTaXplID0gdmFsO1xuICAgIHRoaXMucmVjYWxjTGF5b3V0KCk7XG4gIH1cblxuICBnZXQgcGFnZVNpemUoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fcGFnZVNpemU7XG4gIH1cblxuICBASW5wdXQoKSBzZXQgcm93cyh2YWw6IGFueVtdKSB7XG4gICAgdGhpcy5fcm93cyA9IHZhbDtcbiAgICB0aGlzLnJlY2FsY0xheW91dCgpO1xuICB9XG5cbiAgZ2V0IHJvd3MoKTogYW55W10ge1xuICAgIHJldHVybiB0aGlzLl9yb3dzO1xuICB9XG5cbiAgQElucHV0KCkgc2V0IGNvbHVtbnModmFsOiBhbnlbXSkge1xuICAgIHRoaXMuX2NvbHVtbnMgPSB2YWw7XG4gICAgY29uc3QgY29sc0J5UGluID0gY29sdW1uc0J5UGluKHZhbCk7XG4gICAgdGhpcy5jb2x1bW5Hcm91cFdpZHRocyA9IGNvbHVtbkdyb3VwV2lkdGhzKGNvbHNCeVBpbiwgdmFsKTtcbiAgfVxuXG4gIGdldCBjb2x1bW5zKCk6IGFueVtdIHtcbiAgICByZXR1cm4gdGhpcy5fY29sdW1ucztcbiAgfVxuXG4gIEBJbnB1dCgpIHNldCBvZmZzZXQodmFsOiBudW1iZXIpIHtcbiAgICB0aGlzLl9vZmZzZXQgPSB2YWw7XG4gICAgaWYgKCF0aGlzLnNjcm9sbGJhclYgfHwgKHRoaXMuc2Nyb2xsYmFyViAmJiAhdGhpcy52aXJ0dWFsaXphdGlvbikpIHRoaXMucmVjYWxjTGF5b3V0KCk7XG4gIH1cblxuICBnZXQgb2Zmc2V0KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuX29mZnNldDtcbiAgfVxuXG4gIEBJbnB1dCgpIHNldCByb3dDb3VudCh2YWw6IG51bWJlcikge1xuICAgIHRoaXMuX3Jvd0NvdW50ID0gdmFsO1xuICAgIHRoaXMucmVjYWxjTGF5b3V0KCk7XG4gIH1cblxuICBnZXQgcm93Q291bnQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fcm93Q291bnQ7XG4gIH1cblxuICBASG9zdEJpbmRpbmcoJ3N0eWxlLndpZHRoJylcbiAgZ2V0IGJvZHlXaWR0aCgpOiBzdHJpbmcge1xuICAgIGlmICh0aGlzLnNjcm9sbGJhckgpIHtcbiAgICAgIHJldHVybiB0aGlzLmlubmVyV2lkdGggKyAncHgnO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gJzEwMCUnO1xuICAgIH1cbiAgfVxuXG4gIEBJbnB1dCgpXG4gIEBIb3N0QmluZGluZygnc3R5bGUuaGVpZ2h0JylcbiAgc2V0IGJvZHlIZWlnaHQodmFsKSB7XG4gICAgaWYgKHRoaXMuc2Nyb2xsYmFyVikge1xuICAgICAgdGhpcy5fYm9keUhlaWdodCA9IHZhbCArICdweCc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX2JvZHlIZWlnaHQgPSAnYXV0byc7XG4gICAgfVxuXG4gICAgdGhpcy5yZWNhbGNMYXlvdXQoKTtcbiAgfVxuXG4gIGdldCBib2R5SGVpZ2h0KCkge1xuICAgIHJldHVybiB0aGlzLl9ib2R5SGVpZ2h0O1xuICB9XG5cbiAgQE91dHB1dCgpIHNjcm9sbDogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBwYWdlOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIGFjdGl2YXRlOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIHNlbGVjdDogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBkZXRhaWxUb2dnbGU6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgcm93Q29udGV4dG1lbnUgPSBuZXcgRXZlbnRFbWl0dGVyPHsgZXZlbnQ6IE1vdXNlRXZlbnQ7IHJvdzogYW55IH0+KGZhbHNlKTtcbiAgQE91dHB1dCgpIHRyZWVBY3Rpb246IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIEBWaWV3Q2hpbGQoU2Nyb2xsZXJDb21wb25lbnQpIHNjcm9sbGVyOiBTY3JvbGxlckNvbXBvbmVudDtcblxuICAvKipcbiAgICogUmV0dXJucyBpZiBzZWxlY3Rpb24gaXMgZW5hYmxlZC5cbiAgICovXG4gIGdldCBzZWxlY3RFbmFibGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIXRoaXMuc2VsZWN0aW9uVHlwZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9wZXJ0eSB0aGF0IHdvdWxkIGNhbGN1bGF0ZSB0aGUgaGVpZ2h0IG9mIHNjcm9sbCBiYXJcbiAgICogYmFzZWQgb24gdGhlIHJvdyBoZWlnaHRzIGNhY2hlIGZvciB2aXJ0dWFsIHNjcm9sbCBhbmQgdmlydHVhbGl6YXRpb24uIE90aGVyIHNjZW5hcmlvc1xuICAgKiBjYWxjdWxhdGUgc2Nyb2xsIGhlaWdodCBhdXRvbWF0aWNhbGx5IChhcyBoZWlnaHQgd2lsbCBiZSB1bmRlZmluZWQpLlxuICAgKi9cbiAgZ2V0IHNjcm9sbEhlaWdodCgpOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICAgIGlmICh0aGlzLnNjcm9sbGJhclYgJiYgdGhpcy52aXJ0dWFsaXphdGlvbiAmJiB0aGlzLnJvd0NvdW50KSB7XG4gICAgICByZXR1cm4gdGhpcy5yb3dIZWlnaHRzQ2FjaGUucXVlcnkodGhpcy5yb3dDb3VudCAtIDEpO1xuICAgIH1cbiAgICAvLyBhdm9pZCBUUzcwMzA6IE5vdCBhbGwgY29kZSBwYXRocyByZXR1cm4gYSB2YWx1ZS5cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgcm93SGVpZ2h0c0NhY2hlOiBSb3dIZWlnaHRDYWNoZSA9IG5ldyBSb3dIZWlnaHRDYWNoZSgpO1xuICB0ZW1wOiBhbnlbXSA9IFtdO1xuICBvZmZzZXRZID0gMDtcbiAgaW5kZXhlczogYW55ID0ge307XG4gIGNvbHVtbkdyb3VwV2lkdGhzOiBhbnk7XG4gIGNvbHVtbkdyb3VwV2lkdGhzV2l0aG91dEdyb3VwOiBhbnk7XG4gIHJvd1RyYWNraW5nRm46IGFueTtcbiAgbGlzdGVuZXI6IGFueTtcbiAgcm93SW5kZXhlczogYW55ID0gbmV3IFdlYWtNYXA8YW55LCBzdHJpbmc+KCk7XG4gIHJvd0V4cGFuc2lvbnM6IGFueVtdID0gW107XG5cbiAgX3Jvd3M6IGFueVtdO1xuICBfYm9keUhlaWdodDogYW55O1xuICBfY29sdW1uczogYW55W107XG4gIF9yb3dDb3VudDogbnVtYmVyO1xuICBfb2Zmc2V0OiBudW1iZXI7XG4gIF9wYWdlU2l6ZTogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIERhdGFUYWJsZUJvZHlDb21wb25lbnQuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNkOiBDaGFuZ2VEZXRlY3RvclJlZikge1xuICAgIC8vIGRlY2xhcmUgZm4gaGVyZSBzbyB3ZSBjYW4gZ2V0IGFjY2VzcyB0byB0aGUgYHRoaXNgIHByb3BlcnR5XG4gICAgdGhpcy5yb3dUcmFja2luZ0ZuID0gKGluZGV4OiBudW1iZXIsIHJvdzogYW55KTogYW55ID0+IHtcbiAgICAgIGNvbnN0IGlkeCA9IHRoaXMuZ2V0Um93SW5kZXgocm93KTtcbiAgICAgIGlmICh0aGlzLnRyYWNrQnlQcm9wKSB7XG4gICAgICAgIHJldHVybiByb3dbdGhpcy50cmFja0J5UHJvcF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gaWR4O1xuICAgICAgfVxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQ2FsbGVkIGFmdGVyIHRoZSBjb25zdHJ1Y3RvciwgaW5pdGlhbGl6aW5nIGlucHV0IHByb3BlcnRpZXNcbiAgICovXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnJvd0RldGFpbCkge1xuICAgICAgdGhpcy5saXN0ZW5lciA9IHRoaXMucm93RGV0YWlsLnRvZ2dsZS5zdWJzY3JpYmUoKHsgdHlwZSwgdmFsdWUgfTogeyB0eXBlOiBzdHJpbmc7IHZhbHVlOiBhbnkgfSkgPT4ge1xuICAgICAgICBpZiAodHlwZSA9PT0gJ3JvdycpIHtcbiAgICAgICAgICB0aGlzLnRvZ2dsZVJvd0V4cGFuc2lvbih2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhbGwnKSB7XG4gICAgICAgICAgdGhpcy50b2dnbGVBbGxSb3dzKHZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFJlZnJlc2ggcm93cyBhZnRlciB0b2dnbGVcbiAgICAgICAgLy8gRml4ZXMgIzg4M1xuICAgICAgICB0aGlzLnVwZGF0ZUluZGV4ZXMoKTtcbiAgICAgICAgdGhpcy51cGRhdGVSb3dzKCk7XG4gICAgICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5ncm91cEhlYWRlcikge1xuICAgICAgdGhpcy5saXN0ZW5lciA9IHRoaXMuZ3JvdXBIZWFkZXIudG9nZ2xlLnN1YnNjcmliZSgoeyB0eXBlLCB2YWx1ZSB9OiB7IHR5cGU6IHN0cmluZzsgdmFsdWU6IGFueSB9KSA9PiB7XG4gICAgICAgIGlmICh0eXBlID09PSAnZ3JvdXAnKSB7XG4gICAgICAgICAgdGhpcy50b2dnbGVSb3dFeHBhbnNpb24odmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnYWxsJykge1xuICAgICAgICAgIHRoaXMudG9nZ2xlQWxsUm93cyh2YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZWZyZXNoIHJvd3MgYWZ0ZXIgdG9nZ2xlXG4gICAgICAgIC8vIEZpeGVzICM4ODNcbiAgICAgICAgdGhpcy51cGRhdGVJbmRleGVzKCk7XG4gICAgICAgIHRoaXMudXBkYXRlUm93cygpO1xuICAgICAgICB0aGlzLmNkLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENhbGxlZCBvbmNlLCBiZWZvcmUgdGhlIGluc3RhbmNlIGlzIGRlc3Ryb3llZC5cbiAgICovXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnJvd0RldGFpbCB8fCB0aGlzLmdyb3VwSGVhZGVyKSB7XG4gICAgICB0aGlzLmxpc3RlbmVyLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgdGhlIFkgb2Zmc2V0IGdpdmVuIGEgbmV3IG9mZnNldC5cbiAgICovXG4gIHVwZGF0ZU9mZnNldFkob2Zmc2V0PzogbnVtYmVyKTogdm9pZCB7XG4gICAgLy8gc2Nyb2xsZXIgaXMgbWlzc2luZyBvbiBlbXB0eSB0YWJsZVxuICAgIGlmICghdGhpcy5zY3JvbGxlcikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnNjcm9sbGJhclYgJiYgdGhpcy52aXJ0dWFsaXphdGlvbiAmJiBvZmZzZXQpIHtcbiAgICAgIC8vIEZpcnN0IGdldCB0aGUgcm93IEluZGV4IHRoYXQgd2UgbmVlZCB0byBtb3ZlIHRvLlxuICAgICAgY29uc3Qgcm93SW5kZXggPSB0aGlzLnBhZ2VTaXplICogb2Zmc2V0O1xuICAgICAgb2Zmc2V0ID0gdGhpcy5yb3dIZWlnaHRzQ2FjaGUucXVlcnkocm93SW5kZXggLSAxKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuc2Nyb2xsYmFyViAmJiAhdGhpcy52aXJ0dWFsaXphdGlvbikge1xuICAgICAgb2Zmc2V0ID0gMDtcbiAgICB9XG5cbiAgICB0aGlzLnNjcm9sbGVyLnNldE9mZnNldChvZmZzZXQgfHwgMCk7XG4gIH1cblxuICAvKipcbiAgICogQm9keSB3YXMgc2Nyb2xsZWQsIHRoaXMgaXMgbWFpbmx5IHVzZWZ1bCBmb3JcbiAgICogd2hlbiBhIHVzZXIgaXMgc2VydmVyLXNpZGUgcGFnaW5hdGlvbiB2aWEgdmlydHVhbCBzY3JvbGwuXG4gICAqL1xuICBvbkJvZHlTY3JvbGwoZXZlbnQ6IGFueSk6IHZvaWQge1xuICAgIGNvbnN0IHNjcm9sbFlQb3M6IG51bWJlciA9IGV2ZW50LnNjcm9sbFlQb3M7XG4gICAgY29uc3Qgc2Nyb2xsWFBvczogbnVtYmVyID0gZXZlbnQuc2Nyb2xsWFBvcztcblxuICAgIC8vIGlmIHNjcm9sbCBjaGFuZ2UsIHRyaWdnZXIgdXBkYXRlXG4gICAgLy8gdGhpcyBpcyBtYWlubHkgdXNlZCBmb3IgaGVhZGVyIGNlbGwgcG9zaXRpb25zXG4gICAgaWYgKHRoaXMub2Zmc2V0WSAhPT0gc2Nyb2xsWVBvcyB8fCB0aGlzLm9mZnNldFggIT09IHNjcm9sbFhQb3MpIHtcbiAgICAgIHRoaXMuc2Nyb2xsLmVtaXQoe1xuICAgICAgICBvZmZzZXRZOiBzY3JvbGxZUG9zLFxuICAgICAgICBvZmZzZXRYOiBzY3JvbGxYUG9zXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLm9mZnNldFkgPSBzY3JvbGxZUG9zO1xuICAgIHRoaXMub2Zmc2V0WCA9IHNjcm9sbFhQb3M7XG5cbiAgICB0aGlzLnVwZGF0ZUluZGV4ZXMoKTtcbiAgICB0aGlzLnVwZGF0ZVBhZ2UoZXZlbnQuZGlyZWN0aW9uKTtcbiAgICB0aGlzLnVwZGF0ZVJvd3MoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGVzIHRoZSBwYWdlIGdpdmVuIGEgZGlyZWN0aW9uLlxuICAgKi9cbiAgdXBkYXRlUGFnZShkaXJlY3Rpb246IHN0cmluZyk6IHZvaWQge1xuICAgIGxldCBvZmZzZXQgPSB0aGlzLmluZGV4ZXMuZmlyc3QgLyB0aGlzLnBhZ2VTaXplO1xuXG4gICAgaWYgKGRpcmVjdGlvbiA9PT0gJ3VwJykge1xuICAgICAgb2Zmc2V0ID0gTWF0aC5jZWlsKG9mZnNldCk7XG4gICAgfSBlbHNlIGlmIChkaXJlY3Rpb24gPT09ICdkb3duJykge1xuICAgICAgb2Zmc2V0ID0gTWF0aC5mbG9vcihvZmZzZXQpO1xuICAgIH1cblxuICAgIGlmIChkaXJlY3Rpb24gIT09IHVuZGVmaW5lZCAmJiAhaXNOYU4ob2Zmc2V0KSkge1xuICAgICAgdGhpcy5wYWdlLmVtaXQoeyBvZmZzZXQgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgdGhlIHJvd3MgaW4gdGhlIHZpZXcgcG9ydFxuICAgKi9cbiAgdXBkYXRlUm93cygpOiB2b2lkIHtcbiAgICBjb25zdCB7IGZpcnN0LCBsYXN0IH0gPSB0aGlzLmluZGV4ZXM7XG4gICAgbGV0IHJvd0luZGV4ID0gZmlyc3Q7XG4gICAgbGV0IGlkeCA9IDA7XG4gICAgY29uc3QgdGVtcDogYW55W10gPSBbXTtcblxuICAgIC8vIGlmIGdyb3Vwcm93c2J5IGhhcyBiZWVuIHNwZWNpZmllZCB0cmVhdCByb3cgcGFnaW5nXG4gICAgLy8gcGFyYW1ldGVycyBhcyBncm91cCBwYWdpbmcgcGFyYW1ldGVycyBpZSBpZiBsaW1pdCAxMCBoYXMgYmVlblxuICAgIC8vIHNwZWNpZmllZCB0cmVhdCBpdCBhcyAxMCBncm91cHMgcmF0aGVyIHRoYW4gMTAgcm93c1xuICAgIGlmICh0aGlzLmdyb3VwZWRSb3dzKSB7XG4gICAgICBsZXQgbWF4Um93c1Blckdyb3VwID0gMztcbiAgICAgIC8vIGlmIHRoZXJlIGlzIG9ubHkgb25lIGdyb3VwIHNldCB0aGUgbWF4aW11bSBudW1iZXIgb2ZcbiAgICAgIC8vIHJvd3MgcGVyIGdyb3VwIHRoZSBzYW1lIGFzIHRoZSB0b3RhbCBudW1iZXIgb2Ygcm93c1xuICAgICAgaWYgKHRoaXMuZ3JvdXBlZFJvd3MubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIG1heFJvd3NQZXJHcm91cCA9IHRoaXMuZ3JvdXBlZFJvd3NbMF0udmFsdWUubGVuZ3RoO1xuICAgICAgfVxuXG4gICAgICB3aGlsZSAocm93SW5kZXggPCBsYXN0ICYmIHJvd0luZGV4IDwgdGhpcy5ncm91cGVkUm93cy5sZW5ndGgpIHtcbiAgICAgICAgLy8gQWRkIHRoZSBncm91cHMgaW50byB0aGlzIHBhZ2VcbiAgICAgICAgY29uc3QgZ3JvdXAgPSB0aGlzLmdyb3VwZWRSb3dzW3Jvd0luZGV4XTtcbiAgICAgICAgdGhpcy5yb3dJbmRleGVzLnNldChncm91cCwgcm93SW5kZXgpO1xuXG4gICAgICAgIGlmIChncm91cC52YWx1ZSkge1xuICAgICAgICAgIC8vIGFkZCBpbmRleGVzIGZvciBlYWNoIGdyb3VwIGl0ZW1cbiAgICAgICAgICBncm91cC52YWx1ZS5mb3JFYWNoKChnOiBhbnksIGk6IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgY29uc3QgX2lkeCA9IGAke3Jvd0luZGV4fS0ke2l9YDtcbiAgICAgICAgICAgIHRoaXMucm93SW5kZXhlcy5zZXQoZywgX2lkeCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdGVtcFtpZHhdID0gZ3JvdXA7XG4gICAgICAgIGlkeCsrO1xuXG4gICAgICAgIC8vIEdyb3VwIGluZGV4IGluIHRoaXMgY29udGV4dFxuICAgICAgICByb3dJbmRleCsrO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB3aGlsZSAocm93SW5kZXggPCBsYXN0ICYmIHJvd0luZGV4IDwgdGhpcy5yb3dDb3VudCkge1xuICAgICAgICBjb25zdCByb3cgPSB0aGlzLnJvd3Nbcm93SW5kZXhdO1xuXG4gICAgICAgIGlmIChyb3cpIHtcbiAgICAgICAgICAvLyBhZGQgaW5kZXhlcyBmb3IgZWFjaCByb3dcbiAgICAgICAgICB0aGlzLnJvd0luZGV4ZXMuc2V0KHJvdywgcm93SW5kZXgpO1xuICAgICAgICAgIHRlbXBbaWR4XSA9IHJvdztcbiAgICAgICAgfVxuXG4gICAgICAgIGlkeCsrO1xuICAgICAgICByb3dJbmRleCsrO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMudGVtcCA9IHRlbXA7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSByb3cgaGVpZ2h0XG4gICAqL1xuICBnZXRSb3dIZWlnaHQocm93OiBhbnkpOiBudW1iZXIge1xuICAgIC8vIGlmIGl0cyBhIGZ1bmN0aW9uIHJldHVybiBpdFxuICAgIGlmICh0eXBlb2YgdGhpcy5yb3dIZWlnaHQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiB0aGlzLnJvd0hlaWdodChyb3cpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnJvd0hlaWdodCBhcyBudW1iZXI7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIGdyb3VwIHRoZSBncm91cCB3aXRoIGFsbCByb3dzXG4gICAqL1xuICBnZXRHcm91cEhlaWdodChncm91cDogYW55KTogbnVtYmVyIHtcbiAgICBsZXQgcm93SGVpZ2h0ID0gMDtcblxuICAgIGlmIChncm91cC52YWx1ZSkge1xuICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGdyb3VwLnZhbHVlLmxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICByb3dIZWlnaHQgKz0gdGhpcy5nZXRSb3dBbmREZXRhaWxIZWlnaHQoZ3JvdXAudmFsdWVbaW5kZXhdKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcm93SGVpZ2h0O1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZSByb3cgaGVpZ2h0IGJhc2VkIG9uIHRoZSBleHBhbmRlZCBzdGF0ZSBvZiB0aGUgcm93LlxuICAgKi9cbiAgZ2V0Um93QW5kRGV0YWlsSGVpZ2h0KHJvdzogYW55KTogbnVtYmVyIHtcbiAgICBsZXQgcm93SGVpZ2h0ID0gdGhpcy5nZXRSb3dIZWlnaHQocm93KTtcbiAgICBjb25zdCBleHBhbmRlZCA9IHRoaXMuZ2V0Um93RXhwYW5kZWQocm93KTtcblxuICAgIC8vIEFkZGluZyBkZXRhaWwgcm93IGhlaWdodCBpZiBpdHMgZXhwYW5kZWQuXG4gICAgaWYgKGV4cGFuZGVkKSB7XG4gICAgICByb3dIZWlnaHQgKz0gdGhpcy5nZXREZXRhaWxSb3dIZWlnaHQocm93KTtcbiAgICB9XG5cbiAgICByZXR1cm4gcm93SGVpZ2h0O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgaGVpZ2h0IG9mIHRoZSBkZXRhaWwgcm93LlxuICAgKi9cbiAgZ2V0RGV0YWlsUm93SGVpZ2h0ID0gKHJvdz86IGFueSwgaW5kZXg/OiBhbnkpOiBudW1iZXIgPT4ge1xuICAgIGlmICghdGhpcy5yb3dEZXRhaWwpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICBjb25zdCByb3dIZWlnaHQgPSB0aGlzLnJvd0RldGFpbC5yb3dIZWlnaHQ7XG4gICAgcmV0dXJuIHR5cGVvZiByb3dIZWlnaHQgPT09ICdmdW5jdGlvbicgPyByb3dIZWlnaHQocm93LCBpbmRleCkgOiAocm93SGVpZ2h0IGFzIG51bWJlcik7XG4gIH07XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZXMgdGhlIHN0eWxlcyBmb3IgdGhlIHJvdyBzbyB0aGF0IHRoZSByb3dzIGNhbiBiZSBtb3ZlZCBpbiAyRCBzcGFjZVxuICAgKiBkdXJpbmcgdmlydHVhbCBzY3JvbGwgaW5zaWRlIHRoZSBET00uICAgSW4gdGhlIGJlbG93IGNhc2UgdGhlIFkgcG9zaXRpb24gaXNcbiAgICogbWFuaXB1bGF0ZWQuICAgQXMgYW4gZXhhbXBsZSwgaWYgdGhlIGhlaWdodCBvZiByb3cgMCBpcyAzMCBweCBhbmQgcm93IDEgaXNcbiAgICogMTAwIHB4IHRoZW4gZm9sbG93aW5nIHN0eWxlcyBhcmUgZ2VuZXJhdGVkOlxuICAgKlxuICAgKiB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKDBweCwgMHB4LCAwcHgpOyAgICAtPiAgcm93MFxuICAgKiB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKDBweCwgMzBweCwgMHB4KTsgICAtPiAgcm93MVxuICAgKiB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKDBweCwgMTMwcHgsIDBweCk7ICAtPiAgcm93MlxuICAgKlxuICAgKiBSb3cgaGVpZ2h0cyBoYXZlIHRvIGJlIGNhbGN1bGF0ZWQgYmFzZWQgb24gdGhlIHJvdyBoZWlnaHRzIGNhY2hlIGFzIHdlIHdvbnRcbiAgICogYmUgYWJsZSB0byBkZXRlcm1pbmUgd2hpY2ggcm93IGlzIG9mIHdoYXQgaGVpZ2h0IGJlZm9yZSBoYW5kLiAgSW4gdGhlIGFib3ZlXG4gICAqIGNhc2UgdGhlIHBvc2l0aW9uWSBvZiB0aGUgdHJhbnNsYXRlM2QgZm9yIHJvdzIgd291bGQgYmUgdGhlIHN1bSBvZiBhbGwgdGhlXG4gICAqIGhlaWdodHMgb2YgdGhlIHJvd3MgYmVmb3JlIGl0IChpLmUuIHJvdzAgYW5kIHJvdzEpLlxuICAgKlxuICAgKiBAcGFyYW0gcm93cyB0aGUgcm93IHRoYXQgbmVlZHMgdG8gYmUgcGxhY2VkIGluIHRoZSAyRCBzcGFjZS5cbiAgICogQHJldHVybnMgdGhlIENTUzMgc3R5bGUgdG8gYmUgYXBwbGllZFxuICAgKlxuICAgKiBAbWVtYmVyT2YgRGF0YVRhYmxlQm9keUNvbXBvbmVudFxuICAgKi9cbiAgZ2V0Um93c1N0eWxlcyhyb3dzOiBhbnkpOiBhbnkge1xuICAgIGNvbnN0IHN0eWxlczogYW55ID0ge307XG5cbiAgICAvLyBvbmx5IGFkZCBzdHlsZXMgZm9yIHRoZSBncm91cCBpZiB0aGVyZSBpcyBhIGdyb3VwXG4gICAgaWYgKHRoaXMuZ3JvdXBlZFJvd3MpIHtcbiAgICAgIHN0eWxlcy53aWR0aCA9IHRoaXMuY29sdW1uR3JvdXBXaWR0aHMudG90YWw7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc2Nyb2xsYmFyViAmJiB0aGlzLnZpcnR1YWxpemF0aW9uKSB7XG4gICAgICBsZXQgaWR4ID0gMDtcblxuICAgICAgaWYgKHRoaXMuZ3JvdXBlZFJvd3MpIHtcbiAgICAgICAgLy8gR2V0IHRoZSBsYXRlc3Qgcm93IHJvd2luZGV4IGluIGEgZ3JvdXBcbiAgICAgICAgY29uc3Qgcm93ID0gcm93c1tyb3dzLmxlbmd0aCAtIDFdO1xuICAgICAgICBpZHggPSByb3cgPyB0aGlzLmdldFJvd0luZGV4KHJvdykgOiAwO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWR4ID0gdGhpcy5nZXRSb3dJbmRleChyb3dzKTtcbiAgICAgIH1cblxuICAgICAgLy8gY29uc3QgcG9zID0gaWR4ICogcm93SGVpZ2h0O1xuICAgICAgLy8gVGhlIHBvc2l0aW9uIG9mIHRoaXMgcm93IHdvdWxkIGJlIHRoZSBzdW0gb2YgYWxsIHJvdyBoZWlnaHRzXG4gICAgICAvLyB1bnRpbCB0aGUgcHJldmlvdXMgcm93IHBvc2l0aW9uLlxuICAgICAgY29uc3QgcG9zID0gdGhpcy5yb3dIZWlnaHRzQ2FjaGUucXVlcnkoaWR4IC0gMSk7XG5cbiAgICAgIHRyYW5zbGF0ZVhZKHN0eWxlcywgMCwgcG9zKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc3R5bGVzO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZSBib3R0b20gc3VtbWFyeSByb3cgb2Zmc2V0IGZvciBzY3JvbGxiYXIgbW9kZS5cbiAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgY2FjaGUgYW5kIG9mZnNldCBjYWxjdWxhdGlvblxuICAgKiBzZWUgZGVzY3JpcHRpb24gZm9yIGBnZXRSb3dzU3R5bGVzYCBtZXRob2RcbiAgICpcbiAgICogQHJldHVybnMgdGhlIENTUzMgc3R5bGUgdG8gYmUgYXBwbGllZFxuICAgKlxuICAgKiBAbWVtYmVyT2YgRGF0YVRhYmxlQm9keUNvbXBvbmVudFxuICAgKi9cbiAgZ2V0Qm90dG9tU3VtbWFyeVJvd1N0eWxlcygpOiBhbnkge1xuICAgIGlmICghdGhpcy5zY3JvbGxiYXJWIHx8ICF0aGlzLnJvd3MgfHwgIXRoaXMucm93cy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IHN0eWxlcyA9IHsgcG9zaXRpb246ICdhYnNvbHV0ZScgfTtcbiAgICBjb25zdCBwb3MgPSB0aGlzLnJvd0hlaWdodHNDYWNoZS5xdWVyeSh0aGlzLnJvd3MubGVuZ3RoIC0gMSk7XG5cbiAgICB0cmFuc2xhdGVYWShzdHlsZXMsIDAsIHBvcyk7XG5cbiAgICByZXR1cm4gc3R5bGVzO1xuICB9XG5cbiAgLyoqXG4gICAqIEhpZGVzIHRoZSBsb2FkaW5nIGluZGljYXRvclxuICAgKi9cbiAgaGlkZUluZGljYXRvcigpOiB2b2lkIHtcbiAgICBzZXRUaW1lb3V0KCgpID0+ICh0aGlzLmxvYWRpbmdJbmRpY2F0b3IgPSBmYWxzZSksIDUwMCk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlcyB0aGUgaW5kZXggb2YgdGhlIHJvd3MgaW4gdGhlIHZpZXdwb3J0XG4gICAqL1xuICB1cGRhdGVJbmRleGVzKCk6IHZvaWQge1xuICAgIGxldCBmaXJzdCA9IDA7XG4gICAgbGV0IGxhc3QgPSAwO1xuXG4gICAgaWYgKHRoaXMuc2Nyb2xsYmFyVikge1xuICAgICAgaWYgKHRoaXMudmlydHVhbGl6YXRpb24pIHtcbiAgICAgICAgLy8gQ2FsY3VsYXRpb24gb2YgdGhlIGZpcnN0IGFuZCBsYXN0IGluZGV4ZXMgd2lsbCBiZSBiYXNlZCBvbiB3aGVyZSB0aGVcbiAgICAgICAgLy8gc2Nyb2xsWSBwb3NpdGlvbiB3b3VsZCBiZSBhdC4gIFRoZSBsYXN0IGluZGV4IHdvdWxkIGJlIHRoZSBvbmVcbiAgICAgICAgLy8gdGhhdCBzaG93cyB1cCBpbnNpZGUgdGhlIHZpZXcgcG9ydCB0aGUgbGFzdC5cbiAgICAgICAgY29uc3QgaGVpZ2h0ID0gcGFyc2VJbnQodGhpcy5ib2R5SGVpZ2h0LCAwKTtcbiAgICAgICAgZmlyc3QgPSB0aGlzLnJvd0hlaWdodHNDYWNoZS5nZXRSb3dJbmRleCh0aGlzLm9mZnNldFkpO1xuICAgICAgICBsYXN0ID0gdGhpcy5yb3dIZWlnaHRzQ2FjaGUuZ2V0Um93SW5kZXgoaGVpZ2h0ICsgdGhpcy5vZmZzZXRZKSArIDE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBJZiB2aXJ0dWFsIHJvd3MgYXJlIG5vdCBuZWVkZWRcbiAgICAgICAgLy8gV2UgcmVuZGVyIGFsbCBpbiBvbmUgZ29cbiAgICAgICAgZmlyc3QgPSAwO1xuICAgICAgICBsYXN0ID0gdGhpcy5yb3dDb3VudDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVGhlIHNlcnZlciBpcyBoYW5kbGluZyBwYWdpbmcgYW5kIHdpbGwgcGFzcyBhbiBhcnJheSB0aGF0IGJlZ2lucyB3aXRoIHRoZVxuICAgICAgLy8gZWxlbWVudCBhdCBhIHNwZWNpZmllZCBvZmZzZXQuICBmaXJzdCBzaG91bGQgYWx3YXlzIGJlIDAgd2l0aCBleHRlcm5hbCBwYWdpbmcuXG4gICAgICBpZiAoIXRoaXMuZXh0ZXJuYWxQYWdpbmcpIHtcbiAgICAgICAgZmlyc3QgPSBNYXRoLm1heCh0aGlzLm9mZnNldCAqIHRoaXMucGFnZVNpemUsIDApO1xuICAgICAgfVxuICAgICAgbGFzdCA9IE1hdGgubWluKGZpcnN0ICsgdGhpcy5wYWdlU2l6ZSwgdGhpcy5yb3dDb3VudCk7XG4gICAgfVxuXG4gICAgdGhpcy5pbmRleGVzID0geyBmaXJzdCwgbGFzdCB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZnJlc2hlcyB0aGUgZnVsbCBSb3cgSGVpZ2h0IGNhY2hlLiAgU2hvdWxkIGJlIHVzZWRcbiAgICogd2hlbiB0aGUgZW50aXJlIHJvdyBhcnJheSBzdGF0ZSBoYXMgY2hhbmdlZC5cbiAgICovXG4gIHJlZnJlc2hSb3dIZWlnaHRDYWNoZSgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuc2Nyb2xsYmFyViB8fCAodGhpcy5zY3JvbGxiYXJWICYmICF0aGlzLnZpcnR1YWxpemF0aW9uKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGNsZWFyIHRoZSBwcmV2aW91cyByb3cgaGVpZ2h0IGNhY2hlIGlmIGFscmVhZHkgcHJlc2VudC5cbiAgICAvLyB0aGlzIGlzIHVzZWZ1bCBkdXJpbmcgc29ydHMsIGZpbHRlcnMgd2hlcmUgdGhlIHN0YXRlIG9mIHRoZVxuICAgIC8vIHJvd3MgYXJyYXkgaXMgY2hhbmdlZC5cbiAgICB0aGlzLnJvd0hlaWdodHNDYWNoZS5jbGVhckNhY2hlKCk7XG5cbiAgICAvLyBJbml0aWFsaXplIHRoZSB0cmVlIG9ubHkgaWYgdGhlcmUgYXJlIHJvd3MgaW5zaWRlIHRoZSB0cmVlLlxuICAgIGlmICh0aGlzLnJvd3MgJiYgdGhpcy5yb3dzLmxlbmd0aCkge1xuICAgICAgY29uc3Qgcm93RXhwYW5zaW9ucyA9IG5ldyBTZXQoKTtcbiAgICAgIGZvciAoY29uc3Qgcm93IG9mIHRoaXMucm93cykge1xuICAgICAgICBpZiAodGhpcy5nZXRSb3dFeHBhbmRlZChyb3cpKSB7XG4gICAgICAgICAgcm93RXhwYW5zaW9ucy5hZGQocm93KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0aGlzLnJvd0hlaWdodHNDYWNoZS5pbml0Q2FjaGUoe1xuICAgICAgICByb3dzOiB0aGlzLnJvd3MsXG4gICAgICAgIHJvd0hlaWdodDogdGhpcy5yb3dIZWlnaHQsXG4gICAgICAgIGRldGFpbFJvd0hlaWdodDogdGhpcy5nZXREZXRhaWxSb3dIZWlnaHQsXG4gICAgICAgIGV4dGVybmFsVmlydHVhbDogdGhpcy5zY3JvbGxiYXJWICYmIHRoaXMuZXh0ZXJuYWxQYWdpbmcsXG4gICAgICAgIHJvd0NvdW50OiB0aGlzLnJvd0NvdW50LFxuICAgICAgICByb3dJbmRleGVzOiB0aGlzLnJvd0luZGV4ZXMsXG4gICAgICAgIHJvd0V4cGFuc2lvbnNcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBpbmRleCBmb3IgdGhlIHZpZXcgcG9ydFxuICAgKi9cbiAgZ2V0QWRqdXN0ZWRWaWV3UG9ydEluZGV4KCk6IG51bWJlciB7XG4gICAgLy8gQ2FwdHVyZSB0aGUgcm93IGluZGV4IG9mIHRoZSBmaXJzdCByb3cgdGhhdCBpcyB2aXNpYmxlIG9uIHRoZSB2aWV3cG9ydC5cbiAgICAvLyBJZiB0aGUgc2Nyb2xsIGJhciBpcyBqdXN0IGJlbG93IHRoZSByb3cgd2hpY2ggaXMgaGlnaGxpZ2h0ZWQgdGhlbiBtYWtlIHRoYXQgYXMgdGhlXG4gICAgLy8gZmlyc3QgaW5kZXguXG4gICAgY29uc3Qgdmlld1BvcnRGaXJzdFJvd0luZGV4ID0gdGhpcy5pbmRleGVzLmZpcnN0O1xuXG4gICAgaWYgKHRoaXMuc2Nyb2xsYmFyViAmJiB0aGlzLnZpcnR1YWxpemF0aW9uKSB7XG4gICAgICBjb25zdCBvZmZzZXRTY3JvbGwgPSB0aGlzLnJvd0hlaWdodHNDYWNoZS5xdWVyeSh2aWV3UG9ydEZpcnN0Um93SW5kZXggLSAxKTtcbiAgICAgIHJldHVybiBvZmZzZXRTY3JvbGwgPD0gdGhpcy5vZmZzZXRZID8gdmlld1BvcnRGaXJzdFJvd0luZGV4IC0gMSA6IHZpZXdQb3J0Rmlyc3RSb3dJbmRleDtcbiAgICB9XG5cbiAgICByZXR1cm4gdmlld1BvcnRGaXJzdFJvd0luZGV4O1xuICB9XG5cbiAgLyoqXG4gICAqIFRvZ2dsZSB0aGUgRXhwYW5zaW9uIG9mIHRoZSByb3cgaS5lLiBpZiB0aGUgcm93IGlzIGV4cGFuZGVkIHRoZW4gaXQgd2lsbFxuICAgKiBjb2xsYXBzZSBhbmQgdmljZSB2ZXJzYS4gICBOb3RlIHRoYXQgdGhlIGV4cGFuZGVkIHN0YXR1cyBpcyBzdG9yZWQgYXNcbiAgICogYSBwYXJ0IG9mIHRoZSByb3cgb2JqZWN0IGl0c2VsZiBhcyB3ZSBoYXZlIHRvIHByZXNlcnZlIHRoZSBleHBhbmRlZCByb3dcbiAgICogc3RhdHVzIGluIGNhc2Ugb2Ygc29ydGluZyBhbmQgZmlsdGVyaW5nIG9mIHRoZSByb3cgc2V0LlxuICAgKi9cbiAgdG9nZ2xlUm93RXhwYW5zaW9uKHJvdzogYW55KTogdm9pZCB7XG4gICAgLy8gQ2FwdHVyZSB0aGUgcm93IGluZGV4IG9mIHRoZSBmaXJzdCByb3cgdGhhdCBpcyB2aXNpYmxlIG9uIHRoZSB2aWV3cG9ydC5cbiAgICBjb25zdCB2aWV3UG9ydEZpcnN0Um93SW5kZXggPSB0aGlzLmdldEFkanVzdGVkVmlld1BvcnRJbmRleCgpO1xuICAgIGNvbnN0IHJvd0V4cGFuZGVkSWR4ID0gdGhpcy5nZXRSb3dFeHBhbmRlZElkeChyb3csIHRoaXMucm93RXhwYW5zaW9ucyk7XG4gICAgY29uc3QgZXhwYW5kZWQgPSByb3dFeHBhbmRlZElkeCA+IC0xO1xuXG4gICAgLy8gSWYgdGhlIGRldGFpbFJvd0hlaWdodCBpcyBhdXRvIC0tPiBvbmx5IGluIGNhc2Ugb2Ygbm9uLXZpcnR1YWxpemVkIHNjcm9sbFxuICAgIGlmICh0aGlzLnNjcm9sbGJhclYgJiYgdGhpcy52aXJ0dWFsaXphdGlvbikge1xuICAgICAgY29uc3QgZGV0YWlsUm93SGVpZ2h0ID0gdGhpcy5nZXREZXRhaWxSb3dIZWlnaHQocm93KSAqIChleHBhbmRlZCA/IC0xIDogMSk7XG4gICAgICAvLyBjb25zdCBpZHggPSB0aGlzLnJvd0luZGV4ZXMuZ2V0KHJvdykgfHwgMDtcbiAgICAgIGNvbnN0IGlkeCA9IHRoaXMuZ2V0Um93SW5kZXgocm93KTtcbiAgICAgIHRoaXMucm93SGVpZ2h0c0NhY2hlLnVwZGF0ZShpZHgsIGRldGFpbFJvd0hlaWdodCk7XG4gICAgfVxuXG4gICAgLy8gVXBkYXRlIHRoZSB0b2dnbGVkIHJvdyBhbmQgdXBkYXRlIHRoaXZlIG5ldmVyZSBoZWlnaHRzIGluIHRoZSBjYWNoZS5cbiAgICBpZiAoZXhwYW5kZWQpIHtcbiAgICAgIHRoaXMucm93RXhwYW5zaW9ucy5zcGxpY2Uocm93RXhwYW5kZWRJZHgsIDEpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJvd0V4cGFuc2lvbnMucHVzaChyb3cpO1xuICAgIH1cblxuICAgIHRoaXMuZGV0YWlsVG9nZ2xlLmVtaXQoe1xuICAgICAgcm93czogW3Jvd10sXG4gICAgICBjdXJyZW50SW5kZXg6IHZpZXdQb3J0Rmlyc3RSb3dJbmRleFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4cGFuZC9Db2xsYXBzZSBhbGwgdGhlIHJvd3Mgbm8gbWF0dGVyIHdoYXQgdGhlaXIgc3RhdGUgaXMuXG4gICAqL1xuICB0b2dnbGVBbGxSb3dzKGV4cGFuZGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgLy8gY2xlYXIgcHJldiBleHBhbnNpb25zXG4gICAgdGhpcy5yb3dFeHBhbnNpb25zID0gW107XG5cbiAgICAvLyBDYXB0dXJlIHRoZSByb3cgaW5kZXggb2YgdGhlIGZpcnN0IHJvdyB0aGF0IGlzIHZpc2libGUgb24gdGhlIHZpZXdwb3J0LlxuICAgIGNvbnN0IHZpZXdQb3J0Rmlyc3RSb3dJbmRleCA9IHRoaXMuZ2V0QWRqdXN0ZWRWaWV3UG9ydEluZGV4KCk7XG5cbiAgICBpZiAoZXhwYW5kZWQpIHtcbiAgICAgIGZvciAoY29uc3Qgcm93IG9mIHRoaXMucm93cykge1xuICAgICAgICB0aGlzLnJvd0V4cGFuc2lvbnMucHVzaChyb3cpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLnNjcm9sbGJhclYpIHtcbiAgICAgIC8vIFJlZnJlc2ggdGhlIGZ1bGwgcm93IGhlaWdodHMgY2FjaGUgc2luY2UgZXZlcnkgcm93IHdhcyBhZmZlY3RlZC5cbiAgICAgIHRoaXMucmVjYWxjTGF5b3V0KCk7XG4gICAgfVxuXG4gICAgLy8gRW1pdCBhbGwgcm93cyB0aGF0IGhhdmUgYmVlbiBleHBhbmRlZC5cbiAgICB0aGlzLmRldGFpbFRvZ2dsZS5lbWl0KHtcbiAgICAgIHJvd3M6IHRoaXMucm93cyxcbiAgICAgIGN1cnJlbnRJbmRleDogdmlld1BvcnRGaXJzdFJvd0luZGV4XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmVjYWxjdWxhdGVzIHRoZSB0YWJsZVxuICAgKi9cbiAgcmVjYWxjTGF5b3V0KCk6IHZvaWQge1xuICAgIHRoaXMucmVmcmVzaFJvd0hlaWdodENhY2hlKCk7XG4gICAgdGhpcy51cGRhdGVJbmRleGVzKCk7XG4gICAgdGhpcy51cGRhdGVSb3dzKCk7XG4gIH1cblxuICAvKipcbiAgICogVHJhY2tzIHRoZSBjb2x1bW5cbiAgICovXG4gIGNvbHVtblRyYWNraW5nRm4oaW5kZXg6IG51bWJlciwgY29sdW1uOiBhbnkpOiBhbnkge1xuICAgIHJldHVybiBjb2x1bW4uJCRpZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSByb3cgcGlubmluZyBncm91cCBzdHlsZXNcbiAgICovXG4gIHN0eWxlc0J5R3JvdXAoZ3JvdXA6IHN0cmluZykge1xuICAgIGNvbnN0IHdpZHRocyA9IHRoaXMuY29sdW1uR3JvdXBXaWR0aHM7XG4gICAgY29uc3Qgb2Zmc2V0WCA9IHRoaXMub2Zmc2V0WDtcblxuICAgIGNvbnN0IHN0eWxlcyA9IHtcbiAgICAgIHdpZHRoOiBgJHt3aWR0aHNbZ3JvdXBdfXB4YFxuICAgIH07XG5cbiAgICBpZiAoZ3JvdXAgPT09ICdsZWZ0Jykge1xuICAgICAgdHJhbnNsYXRlWFkoc3R5bGVzLCBvZmZzZXRYLCAwKTtcbiAgICB9IGVsc2UgaWYgKGdyb3VwID09PSAncmlnaHQnKSB7XG4gICAgICBjb25zdCBib2R5V2lkdGggPSBwYXJzZUludCh0aGlzLmlubmVyV2lkdGggKyAnJywgMCk7XG4gICAgICBjb25zdCB0b3RhbERpZmYgPSB3aWR0aHMudG90YWwgLSBib2R5V2lkdGg7XG4gICAgICBjb25zdCBvZmZzZXREaWZmID0gdG90YWxEaWZmIC0gb2Zmc2V0WDtcbiAgICAgIGNvbnN0IG9mZnNldCA9IG9mZnNldERpZmYgKiAtMTtcbiAgICAgIHRyYW5zbGF0ZVhZKHN0eWxlcywgb2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc3R5bGVzO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgaWYgdGhlIHJvdyB3YXMgZXhwYW5kZWQgYW5kIHNldCBkZWZhdWx0IHJvdyBleHBhbnNpb24gd2hlbiByb3cgZXhwYW5zaW9uIGlzIGVtcHR5XG4gICAqL1xuICBnZXRSb3dFeHBhbmRlZChyb3c6IGFueSk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLnJvd0V4cGFuc2lvbnMubGVuZ3RoID09PSAwICYmIHRoaXMuZ3JvdXBFeHBhbnNpb25EZWZhdWx0KSB7XG4gICAgICBmb3IgKGNvbnN0IGdyb3VwIG9mIHRoaXMuZ3JvdXBlZFJvd3MpIHtcbiAgICAgICAgdGhpcy5yb3dFeHBhbnNpb25zLnB1c2goZ3JvdXApO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmdldFJvd0V4cGFuZGVkSWR4KHJvdywgdGhpcy5yb3dFeHBhbnNpb25zKSA+IC0xO1xuICB9XG5cbiAgZ2V0Um93RXhwYW5kZWRJZHgocm93OiBhbnksIGV4cGFuZGVkOiBhbnlbXSk6IG51bWJlciB7XG4gICAgaWYgKCFleHBhbmRlZCB8fCAhZXhwYW5kZWQubGVuZ3RoKSByZXR1cm4gLTE7XG5cbiAgICBjb25zdCByb3dJZCA9IHRoaXMucm93SWRlbnRpdHkocm93KTtcbiAgICByZXR1cm4gZXhwYW5kZWQuZmluZEluZGV4KHIgPT4ge1xuICAgICAgY29uc3QgaWQgPSB0aGlzLnJvd0lkZW50aXR5KHIpO1xuICAgICAgcmV0dXJuIGlkID09PSByb3dJZDtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSByb3cgaW5kZXggZ2l2ZW4gYSByb3dcbiAgICovXG4gIGdldFJvd0luZGV4KHJvdzogYW55KTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5yb3dJbmRleGVzLmdldChyb3cpIHx8IDA7XG4gIH1cblxuICBvblRyZWVBY3Rpb24ocm93OiBhbnkpIHtcbiAgICB0aGlzLnRyZWVBY3Rpb24uZW1pdCh7IHJvdyB9KTtcbiAgfVxufVxuIl19