@skyux/grids 5.9.4 → 6.0.0-beta.10

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 (97) hide show
  1. package/documentation.json +387 -295
  2. package/esm2020/index.mjs +20 -0
  3. package/esm2020/lib/modules/grid/grid-adapter.service.mjs +88 -0
  4. package/esm2020/lib/modules/grid/grid-cell.component.mjs +42 -0
  5. package/esm2020/lib/modules/grid/grid-column.component.mjs +115 -0
  6. package/esm2020/lib/modules/grid/grid-column.model.mjs +26 -0
  7. package/esm2020/lib/modules/grid/grid.component.mjs +1034 -0
  8. package/esm2020/lib/modules/grid/grid.module.mjs +74 -0
  9. package/esm2020/lib/modules/grid/types/grid-column-alignment.mjs +2 -0
  10. package/esm2020/lib/modules/grid/types/grid-column-description-model-change.mjs +2 -0
  11. package/esm2020/lib/modules/grid/types/grid-column-heading-model-change.mjs +2 -0
  12. package/esm2020/lib/modules/grid/types/grid-column-inline-help-popover-model-change.mjs +2 -0
  13. package/esm2020/lib/modules/grid/types/grid-column-width-model-change.mjs +2 -0
  14. package/esm2020/lib/modules/grid/types/grid-message-type.mjs +23 -0
  15. package/esm2020/lib/modules/grid/types/grid-message.mjs +2 -0
  16. package/esm2020/lib/modules/grid/types/grid-row-delete-cancel-args.mjs +2 -0
  17. package/esm2020/lib/modules/grid/types/grid-row-delete-config.mjs +2 -0
  18. package/esm2020/lib/modules/grid/types/grid-row-delete-confirm-args.mjs +2 -0
  19. package/esm2020/lib/modules/grid/types/grid-row-delete-contents.mjs +2 -0
  20. package/esm2020/lib/modules/grid/types/grid-selected-rows-model-change.mjs +2 -0
  21. package/esm2020/lib/modules/grid/types/grid-selected-rows-source.mjs +13 -0
  22. package/esm2020/lib/modules/grid/types/grid-ui-config.mjs +2 -0
  23. package/esm2020/lib/modules/shared/sky-grids-resources.module.mjs +45 -0
  24. package/esm2020/skyux-grids.mjs +5 -0
  25. package/fesm2015/{skyux-grids.js → skyux-grids.mjs} +56 -47
  26. package/fesm2015/skyux-grids.mjs.map +1 -0
  27. package/fesm2020/skyux-grids.mjs +1443 -0
  28. package/fesm2020/skyux-grids.mjs.map +1 -0
  29. package/lib/modules/grid/grid-adapter.service.d.ts +1 -1
  30. package/lib/modules/grid/grid-cell.component.d.ts +1 -0
  31. package/lib/modules/grid/grid-column.component.d.ts +1 -0
  32. package/lib/modules/grid/grid-column.model.d.ts +1 -0
  33. package/lib/modules/grid/grid.component.d.ts +6 -2
  34. package/lib/modules/grid/grid.module.d.ts +3 -0
  35. package/lib/modules/grid/types/grid-column-alignment.d.ts +1 -0
  36. package/lib/modules/grid/types/grid-column-description-model-change.d.ts +1 -0
  37. package/lib/modules/grid/types/grid-column-heading-model-change.d.ts +1 -0
  38. package/lib/modules/grid/types/grid-column-inline-help-popover-model-change.d.ts +1 -0
  39. package/lib/modules/grid/types/grid-column-width-model-change.d.ts +3 -0
  40. package/lib/modules/grid/types/grid-message-type.d.ts +3 -0
  41. package/lib/modules/grid/types/grid-message.d.ts +3 -0
  42. package/lib/modules/grid/types/grid-row-delete-cancel-args.d.ts +1 -0
  43. package/lib/modules/grid/types/grid-row-delete-config.d.ts +1 -0
  44. package/lib/modules/grid/types/grid-row-delete-confirm-args.d.ts +1 -0
  45. package/lib/modules/grid/types/grid-row-delete-contents.d.ts +1 -0
  46. package/lib/modules/grid/types/grid-selected-rows-model-change.d.ts +3 -0
  47. package/lib/modules/grid/types/grid-selected-rows-source.d.ts +1 -0
  48. package/lib/modules/grid/types/grid-ui-config.d.ts +1 -0
  49. package/package.json +33 -17
  50. package/bundles/skyux-grids.umd.js +0 -1853
  51. package/esm2015/index.js +0 -20
  52. package/esm2015/index.js.map +0 -1
  53. package/esm2015/lib/modules/grid/grid-adapter.service.js +0 -84
  54. package/esm2015/lib/modules/grid/grid-adapter.service.js.map +0 -1
  55. package/esm2015/lib/modules/grid/grid-cell.component.js +0 -46
  56. package/esm2015/lib/modules/grid/grid-cell.component.js.map +0 -1
  57. package/esm2015/lib/modules/grid/grid-column.component.js +0 -116
  58. package/esm2015/lib/modules/grid/grid-column.component.js.map +0 -1
  59. package/esm2015/lib/modules/grid/grid-column.model.js +0 -25
  60. package/esm2015/lib/modules/grid/grid-column.model.js.map +0 -1
  61. package/esm2015/lib/modules/grid/grid.component.js +0 -1032
  62. package/esm2015/lib/modules/grid/grid.component.js.map +0 -1
  63. package/esm2015/lib/modules/grid/grid.module.js +0 -71
  64. package/esm2015/lib/modules/grid/grid.module.js.map +0 -1
  65. package/esm2015/lib/modules/grid/types/grid-column-alignment.js +0 -2
  66. package/esm2015/lib/modules/grid/types/grid-column-alignment.js.map +0 -1
  67. package/esm2015/lib/modules/grid/types/grid-column-description-model-change.js +0 -2
  68. package/esm2015/lib/modules/grid/types/grid-column-description-model-change.js.map +0 -1
  69. package/esm2015/lib/modules/grid/types/grid-column-heading-model-change.js +0 -2
  70. package/esm2015/lib/modules/grid/types/grid-column-heading-model-change.js.map +0 -1
  71. package/esm2015/lib/modules/grid/types/grid-column-inline-help-popover-model-change.js +0 -2
  72. package/esm2015/lib/modules/grid/types/grid-column-inline-help-popover-model-change.js.map +0 -1
  73. package/esm2015/lib/modules/grid/types/grid-column-width-model-change.js +0 -2
  74. package/esm2015/lib/modules/grid/types/grid-column-width-model-change.js.map +0 -1
  75. package/esm2015/lib/modules/grid/types/grid-message-type.js +0 -20
  76. package/esm2015/lib/modules/grid/types/grid-message-type.js.map +0 -1
  77. package/esm2015/lib/modules/grid/types/grid-message.js +0 -2
  78. package/esm2015/lib/modules/grid/types/grid-message.js.map +0 -1
  79. package/esm2015/lib/modules/grid/types/grid-row-delete-cancel-args.js +0 -2
  80. package/esm2015/lib/modules/grid/types/grid-row-delete-cancel-args.js.map +0 -1
  81. package/esm2015/lib/modules/grid/types/grid-row-delete-config.js +0 -2
  82. package/esm2015/lib/modules/grid/types/grid-row-delete-config.js.map +0 -1
  83. package/esm2015/lib/modules/grid/types/grid-row-delete-confirm-args.js +0 -2
  84. package/esm2015/lib/modules/grid/types/grid-row-delete-confirm-args.js.map +0 -1
  85. package/esm2015/lib/modules/grid/types/grid-row-delete-contents.js +0 -2
  86. package/esm2015/lib/modules/grid/types/grid-row-delete-contents.js.map +0 -1
  87. package/esm2015/lib/modules/grid/types/grid-selected-rows-model-change.js +0 -2
  88. package/esm2015/lib/modules/grid/types/grid-selected-rows-model-change.js.map +0 -1
  89. package/esm2015/lib/modules/grid/types/grid-selected-rows-source.js +0 -12
  90. package/esm2015/lib/modules/grid/types/grid-selected-rows-source.js.map +0 -1
  91. package/esm2015/lib/modules/grid/types/grid-ui-config.js +0 -2
  92. package/esm2015/lib/modules/grid/types/grid-ui-config.js.map +0 -1
  93. package/esm2015/lib/modules/shared/sky-grids-resources.module.js +0 -45
  94. package/esm2015/lib/modules/shared/sky-grids-resources.module.js.map +0 -1
  95. package/esm2015/skyux-grids.js +0 -5
  96. package/esm2015/skyux-grids.js.map +0 -1
  97. package/fesm2015/skyux-grids.js.map +0 -1
@@ -0,0 +1,1034 @@
1
+ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChildren, ElementRef, EventEmitter, HostListener, Input, Output, QueryList, TemplateRef, ViewChild, ViewChildren, } from '@angular/core';
2
+ import { SkyAffixAutoFitContext, SkyAffixService, SkyAppWindowRef, SkyLogService, SkyOverlayService, SkyUIConfigService, } from '@skyux/core';
3
+ import { ListItemModel, ListSortFieldSelectorModel, } from '@skyux/list-builder-common';
4
+ import { DragulaService } from 'ng2-dragula';
5
+ import { BehaviorSubject, Subject, fromEvent, merge, } from 'rxjs';
6
+ import { distinctUntilChanged, map, take, takeUntil, takeWhile, } from 'rxjs/operators';
7
+ import { SkyGridAdapterService } from './grid-adapter.service';
8
+ import { SkyGridColumnComponent } from './grid-column.component';
9
+ import { SkyGridColumnModel } from './grid-column.model';
10
+ import { SkyGridMessageType } from './types/grid-message-type';
11
+ import { SkyGridSelectedRowsSource } from './types/grid-selected-rows-source';
12
+ import * as i0 from "@angular/core";
13
+ import * as i1 from "@skyux/core";
14
+ import * as i2 from "ng2-dragula";
15
+ import * as i3 from "./grid-adapter.service";
16
+ import * as i4 from "@skyux/indicators";
17
+ import * as i5 from "@skyux/forms";
18
+ import * as i6 from "./grid-cell.component";
19
+ import * as i7 from "@skyux/layout";
20
+ import * as i8 from "@angular/common";
21
+ import * as i9 from "@skyux/popovers";
22
+ import * as i10 from "@angular/forms";
23
+ import * as i11 from "@skyux/i18n";
24
+ let nextId = 0;
25
+ /**
26
+ * @deprecated `SkyGridComponent` and its features are deprecated. We recommend using the data grid instead. For more information, see https://developer.blackbaud.com/skyux/components/data-grid
27
+ */
28
+ export class SkyGridComponent {
29
+ constructor(affixService, changeDetector, dragulaService, gridAdapter, overlayService, skyWindow, uiConfigService, logger) {
30
+ this.affixService = affixService;
31
+ this.changeDetector = changeDetector;
32
+ this.dragulaService = dragulaService;
33
+ this.gridAdapter = gridAdapter;
34
+ this.overlayService = overlayService;
35
+ this.skyWindow = skyWindow;
36
+ this.uiConfigService = uiConfigService;
37
+ /**
38
+ * Indicates whether to enable the multiselect feature to display a column of
39
+ * checkboxes on the left side of the grid. You can specify a unique ID with
40
+ * the `multiselectRowId` property, but multiselect defaults to the `id` property on
41
+ * the `data` object.
42
+ * @default false
43
+ */
44
+ this.enableMultiselect = false;
45
+ /**
46
+ * Specifies how the grid fits to its parent. The valid options are `width`,
47
+ * which fits the grid to the parent's full width, and `scroll`, which allows the grid
48
+ * to exceed the parent's width. If the grid does not have enough columns to fill
49
+ * the parent's width, it always stretches to the parent's full width.
50
+ * @default "width"
51
+ */
52
+ this.fit = 'width';
53
+ /**
54
+ * Indicates whether to display a toolbar with the grid.
55
+ */
56
+ this.hasToolbar = false;
57
+ /**
58
+ * Provides an observable to send commands to the grid.
59
+ */
60
+ this.messageStream = new Subject();
61
+ /**
62
+ * Fires when the width of a column changes.
63
+ */
64
+ this.columnWidthChange = new EventEmitter();
65
+ /**
66
+ * Fires when the selection of multiselect checkboxes changes.
67
+ * Emits an array of IDs for the selected rows based on the `multiselectRowId` property
68
+ * that the consumer provides.
69
+ */
70
+ this.multiselectSelectionChange = new EventEmitter();
71
+ /**
72
+ * @internal
73
+ */
74
+ this.rowDeleteCancel = new EventEmitter();
75
+ /**
76
+ * @internal
77
+ */
78
+ this.rowDeleteConfirm = new EventEmitter();
79
+ /**
80
+ * Fires when the columns to display in the grid change or when the order of the columns changes.
81
+ * The event emits an array of IDs for the displayed columns that reflects the column order.
82
+ */
83
+ this.selectedColumnIdsChange = new EventEmitter();
84
+ /**
85
+ * Fires when the active sort field changes.
86
+ */
87
+ this.sortFieldChange = new EventEmitter();
88
+ this.columnResizeStep = 10;
89
+ this.gridId = ++nextId;
90
+ this.rowDeleteConfigs = [];
91
+ this.maxColWidth = 9999; // This is an arbitrary number, as the input range picker won't work without a value.
92
+ this.minColWidth = 50;
93
+ this.showResizeBar = false;
94
+ this.showTopScroll = false;
95
+ this.isDraggingResizeHandle = false;
96
+ this.isResized = false;
97
+ this.ngUnsubscribe = new Subject();
98
+ this.rowDeleteContents = {};
99
+ this.subscriptions = [];
100
+ this.scrollTriggered = false;
101
+ this.selectedColumnIdsSet = false;
102
+ logger.deprecated('SkyGridComponent', {
103
+ deprecationMajorVersion: 6,
104
+ moreInfoUrl: 'https://developer.blackbaud.com/skyux/components/data-grid',
105
+ replacementRecommendation: 'Use data grid instead.',
106
+ });
107
+ this.displayedColumns = new Array();
108
+ this.items = new Array();
109
+ this.currentSortField = new BehaviorSubject({
110
+ fieldSelector: '',
111
+ descending: false,
112
+ });
113
+ this.dragulaGroupName = `sky-grids-group-${this.gridId}`;
114
+ }
115
+ /**
116
+ * Specifies columns and column properties for the grid.
117
+ */
118
+ set columns(newColumns) {
119
+ const oldColumns = this.columns;
120
+ this._columns = newColumns;
121
+ if (oldColumns) {
122
+ this.transferColumnWidths(oldColumns, this.columns);
123
+ this.isResized = false;
124
+ this.setDisplayedColumns(true);
125
+ }
126
+ this.changeDetector.markForCheck();
127
+ }
128
+ get columns() {
129
+ return this._columns;
130
+ }
131
+ /**
132
+ * Specifies the columns to display in the grid based on the `id` or `field` properties
133
+ * of the columns. If no columns are specified, then the grid displays all columns.
134
+ */
135
+ set selectedColumnIds(value) {
136
+ const currentIds = this._selectedColumnIds;
137
+ this._selectedColumnIds = value;
138
+ if (this.columns) {
139
+ this.setDisplayedColumns();
140
+ }
141
+ // Ensure that the ids have changed.
142
+ if (!currentIds || !value || !this.arraysEqual(value, currentIds)) {
143
+ // This variable ensures that we do not set user config options or fire the change event
144
+ // on the first time that the columns are set up
145
+ if (this.selectedColumnIdsSet) {
146
+ this.setUserConfig({
147
+ selectedColumnIds: value,
148
+ });
149
+ this.selectedColumnIdsChange.emit(this._selectedColumnIds);
150
+ if (this.isResized) {
151
+ this.resetTableWidth();
152
+ }
153
+ }
154
+ }
155
+ this.selectedColumnIdsSet = true;
156
+ }
157
+ get selectedColumnIds() {
158
+ return this._selectedColumnIds;
159
+ }
160
+ /**
161
+ * Specifies a set of IDs for the rows to select in a multiselect grid.
162
+ * The IDs match the `id` properties of the `data` objects.
163
+ * Rows with IDs that are not included are de-selected in the grid.
164
+ */
165
+ set selectedRowIds(value) {
166
+ if (value) {
167
+ this._selectedRowIds = value;
168
+ this.applySelectedRows();
169
+ this.emitSelectedRows(SkyGridSelectedRowsSource.SelectedRowIdsChange);
170
+ }
171
+ }
172
+ get selectedRowIds() {
173
+ return this._selectedRowIds;
174
+ }
175
+ get tableWidth() {
176
+ return this.tableElementRef.nativeElement.offsetWidth;
177
+ }
178
+ ngOnInit() {
179
+ this.messageStream
180
+ .pipe(takeUntil(this.ngUnsubscribe))
181
+ .subscribe((message) => {
182
+ this.handleIncomingMessages(message);
183
+ });
184
+ }
185
+ ngAfterContentInit() {
186
+ if (this.settingsKey) {
187
+ this.applyUserConfig().then(() => {
188
+ this.initColumns();
189
+ });
190
+ }
191
+ else {
192
+ this.initColumns();
193
+ }
194
+ // Setup column drag-and-drop.
195
+ this.gridAdapter.initializeDragAndDrop(this.dragulaGroupName, this.dragulaService, (selectedColumnIds) => {
196
+ this.onHeaderDrop(selectedColumnIds);
197
+ });
198
+ this.applySelectedRows();
199
+ }
200
+ ngAfterViewInit() {
201
+ this.checkUserColumnWidthsForScroll();
202
+ }
203
+ ngOnChanges(changes) {
204
+ if (changes.columns && this.columns) {
205
+ if (this.selectedColumnIds) {
206
+ this.selectedColumnIds = this.selectedColumnIds.filter((columnId) => {
207
+ return this.columns.find((column) => column.id === columnId);
208
+ });
209
+ }
210
+ this.setDisplayedColumns(true);
211
+ }
212
+ if (changes.data && this.data) {
213
+ this.transformData();
214
+ // This set timeout is necessary to ensure the data has rendered in the grid
215
+ setTimeout(() => {
216
+ // This cleans up any lingering row deletes for items that have been removed.
217
+ Object.keys(this.rowDeleteContents).forEach((id) => {
218
+ if (!this.data.find((item) => item.id === id)) {
219
+ this.destroyRowDelete(id);
220
+ }
221
+ else {
222
+ // The rows re-render thus messing up the affixers. We must reaffix them so that things
223
+ // continue to render correctly.
224
+ const rowElement = this.tableElementRef.nativeElement.querySelector('[sky-cmp-id="' + id + '"]');
225
+ this.rowDeleteContents[id].affixer.affixTo(rowElement, {
226
+ autoFitContext: SkyAffixAutoFitContext.Viewport,
227
+ isSticky: true,
228
+ placement: 'above',
229
+ verticalAlignment: 'top',
230
+ horizontalAlignment: 'left',
231
+ enableAutoFit: false,
232
+ });
233
+ }
234
+ });
235
+ this.checkUserColumnWidthsForScroll();
236
+ });
237
+ }
238
+ if (changes.sortField) {
239
+ this.setSortHeaders();
240
+ }
241
+ }
242
+ ngOnDestroy() {
243
+ this.subscriptions.forEach((subscription) => {
244
+ subscription.unsubscribe();
245
+ });
246
+ this.multiselectSelectionChange.complete();
247
+ this.ngUnsubscribe.next();
248
+ this.ngUnsubscribe.complete();
249
+ Object.keys(this.rowDeleteContents).forEach((id) => {
250
+ this.destroyRowDelete(id);
251
+ });
252
+ this.dragulaService.destroy(this.dragulaGroupName);
253
+ }
254
+ onWindowResize() {
255
+ this.checkUserColumnWidthsForScroll();
256
+ }
257
+ getTopScrollWidth() {
258
+ return this.tableElementRef.nativeElement.scrollWidth;
259
+ }
260
+ getTableClassNames() {
261
+ const classNames = [];
262
+ if (this.fit !== 'scroll') {
263
+ classNames.push('sky-grid-fit');
264
+ }
265
+ if (this.hasToolbar) {
266
+ classNames.push('sky-grid-has-toolbar');
267
+ }
268
+ return this.addDelimeter(classNames, ' ');
269
+ }
270
+ getTableHeaderClassNames(column) {
271
+ const classNames = [];
272
+ if (column && column.locked) {
273
+ classNames.push('sky-grid-header-locked');
274
+ }
275
+ return this.addDelimeter(classNames, ' ');
276
+ }
277
+ getCaretIconNames(column) {
278
+ const iconNames = [];
279
+ this.getSortDirection(column.field).subscribe((sortDir) => {
280
+ if (sortDir === 'asc') {
281
+ iconNames.push('caret-up');
282
+ }
283
+ if (sortDir === 'desc') {
284
+ iconNames.push('caret-down');
285
+ }
286
+ });
287
+ return this.addDelimeter(iconNames, ' ');
288
+ }
289
+ onKeydown(event, column) {
290
+ const key = event.key.toLowerCase();
291
+ if (key === 'enter' || key === ' ') {
292
+ this.sortByColumn(column);
293
+ }
294
+ }
295
+ sortByColumn(column) {
296
+ if (!this.isDraggingResizeHandle && column.isSortable) {
297
+ this.currentSortField
298
+ .pipe(take(1), map((field) => {
299
+ let selector = {
300
+ fieldSelector: column.field,
301
+ descending: true,
302
+ };
303
+ if (field &&
304
+ field.fieldSelector === column.field &&
305
+ field.descending) {
306
+ selector = {
307
+ fieldSelector: column.field,
308
+ descending: false,
309
+ };
310
+ }
311
+ this.sortFieldChange.emit(selector);
312
+ this.currentSortField.next(selector);
313
+ }))
314
+ .subscribe();
315
+ }
316
+ }
317
+ getSortDirection(columnField) {
318
+ return this.currentSortField.pipe(distinctUntilChanged(), map((field) => {
319
+ return field.fieldSelector === columnField
320
+ ? field.descending
321
+ ? 'desc'
322
+ : 'asc'
323
+ : undefined;
324
+ }));
325
+ }
326
+ getAriaSortDirection(column) {
327
+ return this.currentSortField.pipe(distinctUntilChanged(), map((field) => {
328
+ return field.fieldSelector === column.field
329
+ ? field.descending
330
+ ? 'descending'
331
+ : 'ascending'
332
+ : column.isSortable
333
+ ? 'none'
334
+ : undefined;
335
+ }));
336
+ }
337
+ getCaretVisibility(columnField) {
338
+ return this.currentSortField.pipe(distinctUntilChanged(), map((field) => {
339
+ return field.fieldSelector === columnField ? 'visible' : 'hidden';
340
+ }));
341
+ }
342
+ getHelpInlineClass(columnField) {
343
+ return this.getCaretVisibility(columnField).pipe(map((visibility) => {
344
+ return visibility === 'hidden';
345
+ }));
346
+ }
347
+ onMultiselectCheckboxChange() {
348
+ this.emitSelectedRows(SkyGridSelectedRowsSource.CheckboxChange);
349
+ }
350
+ updateColumnHeading(change) {
351
+ const foundColumnModel = this.columns.find((column) => {
352
+ return ((change.id !== undefined && change.id === column.id) ||
353
+ (change.field !== undefined && change.field === column.field));
354
+ });
355
+ /* istanbul ignore else */
356
+ if (foundColumnModel) {
357
+ foundColumnModel.heading = change.value;
358
+ this.changeDetector.markForCheck();
359
+ }
360
+ }
361
+ updateInlineHelpPopover(change) {
362
+ const foundColumnModel = this.columns.find((column) => {
363
+ return ((change.id !== undefined && change.id === column.id) ||
364
+ (change.field !== undefined && change.field === column.field));
365
+ });
366
+ /* istanbul ignore else */
367
+ if (foundColumnModel) {
368
+ foundColumnModel.inlineHelpPopover = change.value;
369
+ this.changeDetector.markForCheck();
370
+ }
371
+ }
372
+ updateColumnDescription(change) {
373
+ const foundColumnModel = this.columns.find((column) => {
374
+ return ((change.id !== undefined && change.id === column.id) ||
375
+ (change.field !== undefined && change.field === column.field));
376
+ });
377
+ /* istanbul ignore else */
378
+ if (foundColumnModel) {
379
+ foundColumnModel.description = change.value;
380
+ this.changeDetector.markForCheck();
381
+ }
382
+ }
383
+ onResizeColumnStart(event) {
384
+ // If this table hasn't been resized, initialize all the resize widths.
385
+ if (!this.isResized) {
386
+ this.initColumnWidths();
387
+ this.isResized = true;
388
+ }
389
+ this.initializeResizeColumn(event);
390
+ this.isDraggingResizeHandle = true;
391
+ this.xPosStart = event.pageX;
392
+ this.showResizeBar = true;
393
+ // Show visual indicator of where mouse is dragging (resizeBar).
394
+ this.changeDetector.detectChanges();
395
+ this.setResizeBarPosition(event.pageX);
396
+ event.preventDefault();
397
+ event.stopPropagation();
398
+ const mouseMoveEvent = fromEvent(document, 'mousemove');
399
+ const touchMoveEvent = fromEvent(document, 'touchmove');
400
+ merge(mouseMoveEvent, touchMoveEvent)
401
+ .pipe(takeWhile(() => {
402
+ return this.isDraggingResizeHandle;
403
+ }))
404
+ .subscribe((moveEvent) => {
405
+ this.onResizeHandleMove(moveEvent);
406
+ });
407
+ const mouseUpEvent = fromEvent(document, 'mouseup');
408
+ const touchEndEvent = fromEvent(document, 'touchend');
409
+ merge(mouseUpEvent, touchEndEvent)
410
+ .pipe(takeWhile(() => {
411
+ return this.isDraggingResizeHandle;
412
+ }))
413
+ .subscribe((endEvent) => {
414
+ this.onResizeHandleRelease(endEvent);
415
+ });
416
+ }
417
+ onKeydownResizeCol(event) {
418
+ // If this table hasn't been resized, initialize all the resize widths.
419
+ if (!this.isResized) {
420
+ this.initColumnWidths();
421
+ this.isResized = true;
422
+ }
423
+ this.initializeResizeColumn(event);
424
+ }
425
+ onInputChangeResizeCol(event) {
426
+ const input = event.target;
427
+ const newValue = Number(input.value);
428
+ const deltaX = newValue - this.startColumnWidth;
429
+ this.resizeColumnByIndex(this.activeResizeColumnIndex, newValue, deltaX);
430
+ const left = input.getBoundingClientRect().left;
431
+ this.setResizeBarPosition(left);
432
+ }
433
+ onResizeHandleMove(event) {
434
+ const deltaX = event.pageX - this.xPosStart;
435
+ const newColWidth = this.startColumnWidth + deltaX;
436
+ if (newColWidth <= this.minColWidth) {
437
+ event.stopPropagation();
438
+ return;
439
+ }
440
+ const max = this.getMaxRangeByIndex(this.activeResizeColumnIndex);
441
+ if (this.fit === 'width' && newColWidth > max) {
442
+ event.stopPropagation();
443
+ return;
444
+ }
445
+ this.setResizeBarPosition(event.pageX);
446
+ }
447
+ onResizeHandleBlur(event) {
448
+ this.showResizeBar = false;
449
+ }
450
+ onResizeHandleFocus(event) {
451
+ this.showResizeBar = true;
452
+ this.changeDetector.detectChanges();
453
+ const target = event.target;
454
+ const left = target.getBoundingClientRect().left;
455
+ this.setResizeBarPosition(left);
456
+ }
457
+ onResizeHandleRelease(event) {
458
+ this.showResizeBar = false;
459
+ const deltaX = event.pageX - this.xPosStart;
460
+ const newColWidth = this.startColumnWidth + deltaX;
461
+ this.resizeColumnByIndex(this.activeResizeColumnIndex, newColWidth, deltaX);
462
+ this.isDraggingResizeHandle = false;
463
+ this.activeResizeColumnIndex = undefined;
464
+ event.stopPropagation();
465
+ this.changeDetector.markForCheck();
466
+ }
467
+ onRowClick(event, selectedItem) {
468
+ /* istanbul ignore else */
469
+ if (this.enableMultiselect) {
470
+ if (event.target === event.currentTarget ||
471
+ !this.isInteractiveElement(event)) {
472
+ selectedItem.isSelected = !selectedItem.isSelected;
473
+ this.changeDetector.markForCheck();
474
+ this.emitSelectedRows(SkyGridSelectedRowsSource.RowClick);
475
+ }
476
+ }
477
+ }
478
+ isRowHighlighted(id) {
479
+ if (this.rowHighlightedId) {
480
+ return id === this.rowHighlightedId;
481
+ }
482
+ return false;
483
+ }
484
+ getRowHeight(index) {
485
+ return this.gridAdapter.getRowHeight(this.tableElementRef, index);
486
+ }
487
+ cancelRowDelete(id) {
488
+ this.rowDeleteConfigs = this.rowDeleteConfigs.filter((config) => config.id !== id);
489
+ this.rowDeleteCancel.emit({ id: id });
490
+ this.destroyRowDelete(id);
491
+ }
492
+ confirmRowDelete(id) {
493
+ this.rowDeleteConfigs.find((config) => config.id === id).pending = true;
494
+ this.rowDeleteConfirm.emit({ id: id });
495
+ }
496
+ getRowDeleteItem(id) {
497
+ return this.rowDeleteConfigs.find((rowDelete) => rowDelete.id === id);
498
+ }
499
+ // Prevent touch devices from inadvertently scrolling grid while dragging columns.
500
+ onTouchMove(event) {
501
+ event.preventDefault();
502
+ }
503
+ onTopScroll(event) {
504
+ /* sanity check */
505
+ /* istanbul ignore else */
506
+ if (this.tableContainerElementRef) {
507
+ if (this.scrollTriggered) {
508
+ this.scrollTriggered = false;
509
+ this.tableContainerElementRef.nativeElement.scrollLeft =
510
+ this.topScrollContainerElementRef.nativeElement.scrollLeft;
511
+ }
512
+ else {
513
+ this.scrollTriggered = true;
514
+ }
515
+ }
516
+ }
517
+ onGridScroll(event) {
518
+ /* sanity check */
519
+ /* istanbul ignore else */
520
+ if (this.topScrollContainerElementRef) {
521
+ if (this.scrollTriggered) {
522
+ this.scrollTriggered = false;
523
+ this.topScrollContainerElementRef.nativeElement.scrollLeft =
524
+ this.tableContainerElementRef.nativeElement.scrollLeft;
525
+ }
526
+ else {
527
+ this.scrollTriggered = true;
528
+ }
529
+ }
530
+ }
531
+ checkUserColumnWidthsForScroll() {
532
+ if (!this.showTopScroll &&
533
+ this.columnElementRefs &&
534
+ this.columnElementRefs.length > 0) {
535
+ let columnsWidthTotal = 0;
536
+ const windowSize = this.skyWindow.nativeWindow.innerWidth;
537
+ this.columnElementRefs.forEach((col) => {
538
+ if (!this.showTopScroll) {
539
+ const computedWidth = parseFloat(window.getComputedStyle(col.nativeElement).width);
540
+ const offsetWidth = col.nativeElement.offsetWidth;
541
+ const width = Math.max(computedWidth || offsetWidth, this.minColWidth);
542
+ columnsWidthTotal = columnsWidthTotal + width;
543
+ if (columnsWidthTotal > windowSize) {
544
+ this.showTopScroll = true;
545
+ setTimeout(() => {
546
+ this.changeDetector.markForCheck();
547
+ });
548
+ }
549
+ }
550
+ });
551
+ }
552
+ }
553
+ multiselectSelectAll() {
554
+ for (let i = 0; i < this.items.length; i++) {
555
+ this.items[i].isSelected = true;
556
+ }
557
+ this.changeDetector.markForCheck();
558
+ this.emitSelectedRows(SkyGridSelectedRowsSource.SelectAll);
559
+ }
560
+ multiselectClearAll() {
561
+ for (let i = 0; i < this.items.length; i++) {
562
+ this.items[i].isSelected = false;
563
+ }
564
+ this.changeDetector.markForCheck();
565
+ this.emitSelectedRows(SkyGridSelectedRowsSource.ClearAll);
566
+ }
567
+ handleIncomingMessages(message) {
568
+ switch (message.type) {
569
+ case SkyGridMessageType.SelectAll:
570
+ this.multiselectSelectAll();
571
+ break;
572
+ case SkyGridMessageType.ClearAll:
573
+ this.multiselectClearAll();
574
+ break;
575
+ case SkyGridMessageType.PromptDeleteRow:
576
+ /* sanity check */
577
+ /* istanbul ignore else */
578
+ if (message.data && message.data.promptDeleteRow) {
579
+ const existingConfig = this.rowDeleteConfigs.find((config) => config.id === message.data.promptDeleteRow.id);
580
+ if (existingConfig) {
581
+ existingConfig.pending = false;
582
+ }
583
+ else {
584
+ this.rowDeleteConfigs.push({
585
+ id: message.data.promptDeleteRow.id,
586
+ pending: false,
587
+ });
588
+ const overlay = this.overlayService.create({
589
+ enableScroll: true,
590
+ showBackdrop: false,
591
+ closeOnNavigation: true,
592
+ enableClose: false,
593
+ enablePointerEvents: true,
594
+ });
595
+ overlay.attachTemplate(this.inlineDeleteTemplateRef, {
596
+ $implicit: this.data.find((item) => item.id === message.data.promptDeleteRow.id),
597
+ });
598
+ /**
599
+ * We are manually setting the z-index here because overlays will always be on top of
600
+ * the omnibar. This manual setting is 1 less than the omnibar's z-index of 1000. We
601
+ * discussed changing the overlay service to allow for this but decided against that
602
+ * change at this time due to its niche nature.
603
+ */
604
+ overlay.componentRef.instance.zIndex = '999';
605
+ setTimeout(() => {
606
+ const inlineDeleteRef = this.inlineDeleteRefs
607
+ .toArray()
608
+ .find((elRef) => {
609
+ return (elRef.nativeElement.id ===
610
+ 'row-delete-ref-' + message.data.promptDeleteRow.id);
611
+ });
612
+ const affixer = this.affixService.createAffixer(inlineDeleteRef);
613
+ const rowElement = this.tableElementRef.nativeElement.querySelector('[sky-cmp-id="' + message.data.promptDeleteRow.id + '"]');
614
+ affixer.affixTo(rowElement, {
615
+ autoFitContext: SkyAffixAutoFitContext.Viewport,
616
+ isSticky: true,
617
+ placement: 'above',
618
+ verticalAlignment: 'top',
619
+ horizontalAlignment: 'left',
620
+ enableAutoFit: false,
621
+ });
622
+ this.rowDeleteContents[message.data.promptDeleteRow.id] = {
623
+ affixer: affixer,
624
+ overlay: overlay,
625
+ };
626
+ });
627
+ }
628
+ }
629
+ break;
630
+ case SkyGridMessageType.AbortDeleteRow:
631
+ /* sanity check */
632
+ /* istanbul ignore else */
633
+ if (message.data && message.data.abortDeleteRow) {
634
+ this.rowDeleteConfigs = this.rowDeleteConfigs.filter((config) => config.id !== message.data.abortDeleteRow.id);
635
+ this.destroyRowDelete(message.data.abortDeleteRow.id);
636
+ }
637
+ break;
638
+ }
639
+ this.changeDetector.markForCheck();
640
+ }
641
+ onHeaderDrop(newColumnIds) {
642
+ // update selected columnIds
643
+ this.selectedColumnIdsSet = true;
644
+ this.selectedColumnIds = newColumnIds;
645
+ // mark for check because we are using ChangeDetectionStrategy.onPush
646
+ this.changeDetector.markForCheck();
647
+ }
648
+ setDisplayedColumns(respectHidden = false) {
649
+ /* sanity check */
650
+ /* istanbul ignore else */
651
+ if (this.columns) {
652
+ if (this.selectedColumnIds !== undefined) {
653
+ // setup displayed columns
654
+ this.displayedColumns = this.selectedColumnIds
655
+ .filter((columnId) => {
656
+ return this.columns.find((column) => column.id === columnId);
657
+ })
658
+ .map((columnId) => {
659
+ return this.columns.filter((column) => column.id === columnId)[0];
660
+ });
661
+ }
662
+ else if (respectHidden) {
663
+ this.displayedColumns = this.columns.filter((column) => {
664
+ return !column.hidden;
665
+ });
666
+ }
667
+ else {
668
+ this.displayedColumns = this.columns;
669
+ }
670
+ }
671
+ }
672
+ transformData() {
673
+ // Transform data into object with id and data properties
674
+ if (this.data &&
675
+ this.data.length > 0 &&
676
+ this.data[0].id &&
677
+ !this.data[0].data) {
678
+ if (this.multiselectRowId) {
679
+ this.items = this.getGridDataWithSelectedRows();
680
+ }
681
+ else {
682
+ this.items = this.data.map((item) => new ListItemModel(item.id, item));
683
+ }
684
+ }
685
+ else {
686
+ this.items = this.data;
687
+ }
688
+ }
689
+ getGridDataWithSelectedRows() {
690
+ const selectedRows = this.getSelectedRows();
691
+ return this.data.map((item) => {
692
+ let checked;
693
+ if (Object.prototype.hasOwnProperty.call(item, this.multiselectRowId)) {
694
+ checked = selectedRows.indexOf(item[this.multiselectRowId]) > -1;
695
+ }
696
+ else {
697
+ checked = selectedRows.indexOf(item.id) > -1;
698
+ }
699
+ return new ListItemModel(item.id, item, checked);
700
+ });
701
+ }
702
+ applySelectedRows() {
703
+ if (this.items && this.items.length > 0 && this.selectedRowIds) {
704
+ for (let i = 0; i < this.items.length; i++) {
705
+ this.items[i].isSelected =
706
+ this.selectedRowIds.indexOf(this.items[i].id) > -1;
707
+ }
708
+ this.changeDetector.markForCheck();
709
+ }
710
+ }
711
+ setSortHeaders() {
712
+ this.currentSortField.next(this.sortField || { fieldSelector: '', descending: false });
713
+ }
714
+ getColumnsFromComponent() {
715
+ this.columns = this.columnComponents.map((columnComponent) => {
716
+ return new SkyGridColumnModel(columnComponent.template, columnComponent);
717
+ });
718
+ }
719
+ updateColumns() {
720
+ this.getColumnsFromComponent();
721
+ // This set timeout is necessary to ensure the columns have rendered in the grid
722
+ setTimeout(() => {
723
+ this.checkUserColumnWidthsForScroll();
724
+ });
725
+ }
726
+ resizeColumnByIndex(columnIndex, newColWidth, deltaX) {
727
+ const column = this.getColumnModelByIndex(columnIndex);
728
+ // Prevent accidental shrinkage below minimum width.
729
+ if (newColWidth <= this.minColWidth) {
730
+ deltaX = deltaX + this.minColWidth - newColWidth;
731
+ newColWidth = this.minColWidth;
732
+ }
733
+ // fit=width adds/removes width from the last column
734
+ // fit=scroll adds/removes width from the table
735
+ if (this.fit === 'width') {
736
+ const lastColumn = this.getLastDisplayedColumn();
737
+ // Prevent accidental growth that would bump last column off screen.
738
+ const max = this.getMaxRangeByIndex(columnIndex);
739
+ if (newColWidth > max) {
740
+ newColWidth = max;
741
+ deltaX = max - this.startColumnWidth;
742
+ }
743
+ column.width = newColWidth;
744
+ lastColumn.width = lastColumn.width - deltaX;
745
+ this.updateMaxRange();
746
+ }
747
+ else {
748
+ this.gridAdapter.setStyle(this.tableElementRef, 'width', `${this.tableWidth + deltaX}px`);
749
+ column.width = newColWidth;
750
+ }
751
+ this.changeDetector.detectChanges();
752
+ this.columnWidthChange.emit(this.getColumnWidthModelChange());
753
+ }
754
+ initColumnWidths() {
755
+ // Establish table width.
756
+ this.showTopScroll = true;
757
+ // Set column widths based on the width initially given by the browser.
758
+ // computedWidth prevents accidental overflow for browsers with sub-pixel widths.
759
+ this.columnElementRefs.forEach((col, index) => {
760
+ const computedWidth = parseFloat(window.getComputedStyle(col.nativeElement).width);
761
+ const offsetWidth = col.nativeElement.offsetWidth;
762
+ /* istanbul ignore next */
763
+ this.getColumnModelByIndex(index).width = Math.max(computedWidth || offsetWidth, this.minColWidth);
764
+ });
765
+ // 'scroll' tables should be allowed to expand outside of their constraints.
766
+ if (this.fit === 'scroll') {
767
+ this.gridAdapter.setStyle(this.tableElementRef, 'min-width', 'auto');
768
+ }
769
+ // Update max limits for input ranges.
770
+ if (this.fit === 'width') {
771
+ this.updateMaxRange();
772
+ }
773
+ this.changeDetector.detectChanges();
774
+ }
775
+ transferColumnWidths(oldColumns, newColumns) {
776
+ /* sanity check */
777
+ /* istanbul ignore else */
778
+ if (oldColumns && newColumns) {
779
+ for (const oldColumn of oldColumns) {
780
+ if (oldColumn.width) {
781
+ const matchingColumn = newColumns.find((newColumn) => oldColumn.id === newColumn.id);
782
+ if (matchingColumn && !matchingColumn.width) {
783
+ matchingColumn.width = oldColumn.width;
784
+ }
785
+ }
786
+ }
787
+ }
788
+ this.changeDetector.markForCheck();
789
+ }
790
+ getColumnWidthModelChange() {
791
+ const columnWidthModelChange = new Array();
792
+ this.columns.forEach((column) => {
793
+ columnWidthModelChange.push({
794
+ id: column.id,
795
+ field: column.field,
796
+ width: column.width,
797
+ });
798
+ });
799
+ return columnWidthModelChange;
800
+ }
801
+ updateMaxRange() {
802
+ const leftoverWidth = this.getLastDisplayedColumn().width - this.minColWidth;
803
+ this.displayedColumns.forEach((column, index) => {
804
+ const newMaxRange = column.width + leftoverWidth;
805
+ const rangeInput = this.getRangeInputByIndex(index);
806
+ rangeInput.nativeElement.max = newMaxRange;
807
+ rangeInput.nativeElement.setAttribute('aria-valuemax', newMaxRange);
808
+ });
809
+ }
810
+ initializeResizeColumn(event) {
811
+ const clickTarget = event.target;
812
+ this.activeResizeColumnIndex = clickTarget.getAttribute('sky-cmp-index');
813
+ const column = this.getColumnModelByIndex(this.activeResizeColumnIndex);
814
+ this.startColumnWidth = column.width;
815
+ }
816
+ resetTableWidth() {
817
+ this.skyWindow.nativeWindow.setTimeout(() => {
818
+ this.gridAdapter.setStyle(this.tableElementRef, 'width', `auto`);
819
+ this.changeDetector.detectChanges();
820
+ this.gridAdapter.setStyle(this.tableElementRef, 'width', `${this.tableWidth}px`);
821
+ this.changeDetector.detectChanges();
822
+ });
823
+ }
824
+ getRangeInputByIndex(index) {
825
+ return this.columnRangeInputElementRefs.find((input) => input.nativeElement.getAttribute('sky-cmp-index') === index.toString());
826
+ }
827
+ getColumnModelByIndex(index) {
828
+ return this.displayedColumns[Number(index)];
829
+ }
830
+ getMaxRangeByIndex(index) {
831
+ const columnElementRef = this.columnElementRefs.find((th) => th.nativeElement.getAttribute('sky-cmp-index') === index);
832
+ const rangeInput = columnElementRef.nativeElement.querySelector('.sky-grid-column-input-aria-only');
833
+ return Number(rangeInput.max);
834
+ }
835
+ getLastDisplayedColumn() {
836
+ return this.getColumnModelByIndex(this.displayedColumns.length - 1);
837
+ }
838
+ addDelimeter(text, delimiter) {
839
+ return text.filter((val) => val).join(delimiter);
840
+ }
841
+ destroyRowDelete(id) {
842
+ const rowDeleteContents = this.rowDeleteContents[id];
843
+ /* istanbul ignore else */
844
+ if (rowDeleteContents) {
845
+ rowDeleteContents.affixer.destroy();
846
+ this.overlayService.close(rowDeleteContents.overlay);
847
+ delete this.rowDeleteContents[id];
848
+ }
849
+ }
850
+ emitSelectedRows(source) {
851
+ const selectedRows = {
852
+ selectedRowIds: this.getSelectedRows(),
853
+ source: source,
854
+ };
855
+ this.multiselectSelectionChange.emit(selectedRows);
856
+ }
857
+ getSelectedRows() {
858
+ return this.items
859
+ .filter((item) => {
860
+ return item.isSelected;
861
+ })
862
+ .map((item) => {
863
+ if (Object.prototype.hasOwnProperty.call(item.data, this.multiselectRowId)) {
864
+ return item.data[this.multiselectRowId];
865
+ }
866
+ return item.id;
867
+ });
868
+ }
869
+ isInteractiveElement(event) {
870
+ const interactiveElSelectors = `
871
+ a,
872
+ button,
873
+ input,
874
+ label,
875
+ option,
876
+ select,
877
+ textarea,
878
+ details,
879
+ dialog,
880
+ menu,
881
+ menuitem,
882
+ summary`;
883
+ return event.target.closest(interactiveElSelectors);
884
+ }
885
+ setResizeBarPosition(xPosition) {
886
+ const parentScroll = this.tableContainerElementRef.nativeElement.scrollLeft;
887
+ const resizeBarX = xPosition -
888
+ this.tableElementRef.nativeElement.getBoundingClientRect().left -
889
+ parentScroll;
890
+ this.gridAdapter.setStyle(this.resizeBar, 'left', resizeBarX + 'px');
891
+ }
892
+ applyUserConfig() {
893
+ return new Promise((resolve) => {
894
+ this.uiConfigService
895
+ .getConfig(this.settingsKey)
896
+ .pipe(take(1))
897
+ .subscribe((config) => {
898
+ /* istanbul ignore else */
899
+ if (config && config.selectedColumnIds) {
900
+ // Remove any columnIds that don't exist in the current data set.
901
+ this.selectedColumnIds = config.selectedColumnIds.filter((id) => this.columns.find((column) => column.id === id));
902
+ this.changeDetector.markForCheck();
903
+ }
904
+ resolve();
905
+ }, () => {
906
+ resolve();
907
+ });
908
+ });
909
+ }
910
+ setUserConfig(config) {
911
+ if (!this.settingsKey) {
912
+ return;
913
+ }
914
+ this.uiConfigService
915
+ .setConfig(this.settingsKey, config)
916
+ .pipe(takeUntil(this.ngUnsubscribe))
917
+ .subscribe(
918
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
919
+ () => { }, (err) => {
920
+ console.warn('Could not save grid settings.');
921
+ console.warn(err);
922
+ });
923
+ }
924
+ initColumns() {
925
+ /* istanbul ignore else */
926
+ if (this.columnComponents.length !== 0 || this.columns !== undefined) {
927
+ /* istanbul ignore else */
928
+ /* sanity check */
929
+ if (this.columnComponents.length > 0) {
930
+ this.getColumnsFromComponent();
931
+ }
932
+ this.transformData();
933
+ this.setDisplayedColumns(true);
934
+ this.changeDetector.markForCheck();
935
+ }
936
+ // Watch for added/removed columns:
937
+ this.subscriptions.push(this.columnComponents.changes.subscribe(() => this.updateColumns()));
938
+ // Watch for column heading changes:
939
+ this.columnComponents.forEach((comp) => {
940
+ this.subscriptions.push(comp.headingModelChanges.subscribe((change) => {
941
+ this.updateColumnHeading(change);
942
+ }));
943
+ this.subscriptions.push(comp.descriptionModelChanges.subscribe((change) => {
944
+ this.updateColumnDescription(change);
945
+ }));
946
+ this.subscriptions.push(comp.inlineHelpPopoverModelChanges.subscribe((change) => {
947
+ this.updateInlineHelpPopover(change);
948
+ }));
949
+ });
950
+ }
951
+ arraysEqual(arrayA, arrayB) {
952
+ return (arrayA.length === arrayB.length &&
953
+ arrayA.every((value, index) => value === arrayB[index]));
954
+ }
955
+ }
956
+ SkyGridComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyGridComponent, deps: [{ token: i1.SkyAffixService }, { token: i0.ChangeDetectorRef }, { token: i2.DragulaService }, { token: i3.SkyGridAdapterService }, { token: i1.SkyOverlayService }, { token: i1.SkyAppWindowRef }, { token: i1.SkyUIConfigService }, { token: i1.SkyLogService }], target: i0.ɵɵFactoryTarget.Component });
957
+ SkyGridComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.2", type: SkyGridComponent, selector: "sky-grid", inputs: { columns: "columns", data: "data", enableMultiselect: "enableMultiselect", fit: "fit", hasToolbar: "hasToolbar", height: "height", highlightText: "highlightText", messageStream: "messageStream", multiselectRowId: "multiselectRowId", rowHighlightedId: "rowHighlightedId", selectedColumnIds: "selectedColumnIds", selectedRowIds: "selectedRowIds", settingsKey: "settingsKey", sortField: "sortField", width: "width" }, outputs: { columnWidthChange: "columnWidthChange", multiselectSelectionChange: "multiselectSelectionChange", rowDeleteCancel: "rowDeleteCancel", rowDeleteConfirm: "rowDeleteConfirm", selectedColumnIdsChange: "selectedColumnIdsChange", sortFieldChange: "sortFieldChange" }, host: { listeners: { "window:resize": "onWindowResize()" } }, providers: [SkyGridAdapterService], queries: [{ propertyName: "columnComponents", predicate: SkyGridColumnComponent }], viewQueries: [{ propertyName: "inlineDeleteTemplateRef", first: true, predicate: ["inlineDeleteTemplateRef"], descendants: true, read: TemplateRef }, { propertyName: "tableContainerElementRef", first: true, predicate: ["gridContainer"], descendants: true }, { propertyName: "tableElementRef", first: true, predicate: ["gridTable"], descendants: true }, { propertyName: "topScrollContainerElementRef", first: true, predicate: ["topScrollContainer"], descendants: true }, { propertyName: "resizeBar", first: true, predicate: ["resizeBar"], descendants: true }, { propertyName: "columnElementRefs", predicate: ["gridCol"], descendants: true }, { propertyName: "columnRangeInputElementRefs", predicate: ["colSizeRange"], descendants: true }, { propertyName: "inlineDeleteRefs", predicate: ["inlineDeleteRef"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"sky-grid\">\n <div\n *ngIf=\"showTopScroll\"\n class=\"sky-grid-top-scroll-container\"\n (scroll)=\"onTopScroll($event)\"\n #topScrollContainer\n >\n <div\n class=\"sky-grid-top-scroll\"\n [style.width.px]=\"getTopScrollWidth()\"\n ></div>\n </div>\n <div\n class=\"sky-grid-table-container\"\n [style.height.px]=\"height\"\n [style.width.px]=\"width\"\n (scroll)=\"onGridScroll($event)\"\n #gridContainer\n >\n <table class=\"sky-grid-table\" [ngClass]=\"getTableClassNames()\" #gridTable>\n <thead>\n <tr [dragula]=\"dragulaGroupName\">\n <th\n *ngIf=\"enableMultiselect\"\n class=\"sky-grid-heading sky-grid-multiselect-cell sky-grid-header-locked\"\n scope=\"col\"\n [style.max-width.px]=\"minColWidth\"\n [style.width.px]=\"minColWidth\"\n >\n <span class=\"screen-reader-only\">\n {{ 'skyux_grid_multiselect_select_row' | skyLibResources }}\n </span>\n </th>\n <th\n *ngFor=\"\n let column of displayedColumns;\n let last = last;\n let i = index\n \"\n class=\"sky-grid-heading sky-field-label\"\n scope=\"col\"\n [attr.sky-cmp-index]=\"i\"\n [attr.sky-cmp-id]=\"column.id || column.field\"\n [attr.aria-sort]=\"getAriaSortDirection(column) | async\"\n [id]=\"'sky-grid-' + gridId + '-column-' + i\"\n [ngClass]=\"'sky-grid-column-alignment-' + column.alignment\"\n [style.max-width.px]=\"column.width\"\n [style.width.px]=\"column.width\"\n [tabIndex]=\"column.isSortable ? 0 : -1\"\n (mouseup)=\"sortByColumn(column)\"\n (keydown)=\"onKeydown($event, column)\"\n (touchmove)=\"onTouchMove($event)\"\n #gridCol\n >\n <div\n class=\"overflow\"\n [ngClass]=\"getTableHeaderClassNames(column)\"\n [style.max-width.px]=\"column.width - 1\"\n [style.width.px]=\"column.width - 1\"\n >\n <span\n *ngIf=\"(getCaretVisibility(column.field) | async) === 'hidden'\"\n class=\"sky-grid-header-caret-hidden-spacing\"\n ></span>\n <!-- The no spacing here is intentional to avoid extra spaces due to these being inline elements -->\n <span class=\"sky-grid-header-text\">{{\n column.heading?.trim()\n }}</span>\n <sky-icon\n class=\"sky-grid-heading-sort\"\n [ngClass]=\"\n 'sky-grid-heading-sort-' +\n (getCaretVisibility(column.field) | async)\n \"\n [icon]=\"getCaretIconNames(column)\"\n >\n </sky-icon>\n <sky-help-inline\n *ngIf=\"column.inlineHelpPopover\"\n [ngClass]=\"{\n 'sky-grid-help-inline-sort-hidden':\n getHelpInlineClass(column.field) | async\n }\"\n [skyPopover]=\"column.inlineHelpPopover\"\n (keydown.enter)=\"$event.stopPropagation()\"\n (keydown.space)=\"$event.stopPropagation()\"\n (mousedown)=\"$event.stopPropagation()\"\n (mouseup)=\"$event.stopPropagation()\"\n >\n </sky-help-inline>\n </div>\n <span\n *ngIf=\"(fit === 'width' && !last) || fit === 'scroll'\"\n aria-hidden=\"true\"\n class=\"sky-grid-resize-handle\"\n tabindex=\"-1\"\n [attr.sky-cmp-index]=\"i\"\n (mousedown)=\"onResizeColumnStart($event)\"\n (touchstart)=\"onResizeColumnStart($event)\"\n >\n </span>\n <input\n aria-label=\"Width of column\"\n class=\"sky-grid-column-input-aria-only\"\n role=\"slider\"\n type=\"range\"\n [attr.aria-controls]=\"'sky-grid-' + gridId + '-column-' + i\"\n [attr.aria-valuemin]=\"minColWidth\"\n [attr.aria-valuemax]=\"maxColWidth\"\n [attr.aria-valuenow]=\"column.width\"\n [attr.sky-cmp-index]=\"i\"\n [min]=\"minColWidth\"\n [max]=\"maxColWidth\"\n [step]=\"columnResizeStep\"\n [(ngModel)]=\"column.width\"\n (blur)=\"onResizeHandleBlur($event)\"\n (focus)=\"onResizeHandleFocus($event)\"\n (keydown)=\"onKeydownResizeCol($event)\"\n (change)=\"onInputChangeResizeCol($event)\"\n #colSizeRange\n />\n </th>\n </tr>\n </thead>\n <tbody class=\"sky-grid-tbody\">\n <tr\n class=\"sky-grid-row\"\n *ngFor=\"let item of items; let i = index\"\n [attr.aria-current]=\"isRowHighlighted(item.id) ? true : null\"\n [attr.sky-cmp-id]=\"item.id\"\n [ngClass]=\"{\n 'sky-grid-multiselect-selected-row': item.isSelected,\n 'sky-grid-multiselect-row': enableMultiselect,\n 'sky-grid-row-highlight': isRowHighlighted(item.id)\n }\"\n (click)=\"onRowClick($event, item)\"\n >\n <td\n *ngIf=\"enableMultiselect\"\n class=\"sky-grid-multiselect-cell sky-grid-header-locked\"\n >\n <div\n [style.max-width.px]=\"minColWidth\"\n [style.width.px]=\"minColWidth\"\n >\n <sky-checkbox\n [label]=\"'skyux_grid_multiselect_select_row' | skyLibResources\"\n (change)=\"onMultiselectCheckboxChange()\"\n [(ngModel)]=\"item.isSelected\"\n >\n </sky-checkbox>\n </div>\n </td>\n <td\n *ngFor=\"\n let column of displayedColumns;\n let last = last;\n let i = index\n \"\n class=\"sky-grid-cell\"\n [ngClass]=\"'sky-grid-column-alignment-' + column.alignment\"\n [style.max-width.px]=\"column.width\"\n [style.width.px]=\"column.width\"\n >\n <sky-grid-cell\n [skyHighlight]=\"\n !column.excludeFromHighlighting ? highlightText : undefined\n \"\n [template]=\"column.template || defaultCellTemplate\"\n [fieldSelector]=\"column.field\"\n [item]=\"item\"\n [columnId]=\"column.id\"\n [attr.sky-cmp-id]=\"column.id || column.field\"\n >\n </sky-grid-cell>\n </td>\n </tr>\n </tbody>\n </table>\n <div\n *ngIf=\"showResizeBar\"\n aria-hidden=\"true\"\n id=\"sky-grid-resize-bar\"\n tabindex=\"-1\"\n #resizeBar\n ></div>\n </div>\n</div>\n\n<ng-template #defaultCellTemplate let-row=\"row\" let-value=\"value\">{{\n value\n}}</ng-template>\n\n<ng-template let-item #inlineDeleteTemplateRef>\n <div\n [id]=\"'row-delete-ref-' + item.id\"\n [ngStyle]=\"{\n height: getRowHeight(0),\n position: 'fixed',\n width: tableWidth + 'px'\n }\"\n #inlineDeleteRef\n >\n <sky-inline-delete\n [pending]=\"getRowDeleteItem(item.id).pending\"\n (cancelTriggered)=\"cancelRowDelete(item.id)\"\n (deleteTriggered)=\"confirmRowDelete(item.id)\"\n ></sky-inline-delete>\n </div>\n</ng-template>\n", styles: [".sky-grid{position:relative;display:block}.sky-grid-table-container{overflow:auto}.sky-grid-table{position:relative;table-layout:fixed;border-collapse:collapse;margin:0;font-size:15px;min-width:100%}.sky-grid-table.sky-grid-fit{max-width:100%;width:100%}.sky-grid-tbody{background-color:#fff}.sky-grid-row{border-bottom:1px dotted #cdcfd2}.sky-grid-row:nth-child(odd){background-color:#fbfbfb}.sky-grid-row.sky-grid-row-highlight{border-top:1px solid #0974a1;box-shadow:0 0 0 3px inset #0974a1}.sky-grid-row .sky-grid-cell{padding:0;min-width:10px}.sky-grid-heading{position:relative;border-top:1px solid #cdcfd2;border-bottom:1px solid #cdcfd2;border-left:1px solid #cdcfd2;border-right:1px solid #cdcfd2;border-right-width:0px;padding:0;cursor:pointer;background-color:#fff;overflow:visible;background-clip:padding-box;-webkit-user-select:none;-webkit-tap-highlight-color:transparent;user-select:none}.sky-grid-heading:first-child{border-left:1px solid transparent}.sky-grid-heading.sky-grid-header-dragging{background-color:#eeeeef}.sky-grid-heading.sky-grid-column-alignment-left .sky-grid-heading-sort,.sky-grid-heading.sky-grid-column-alignment-center .sky-grid-heading-sort{width:14px}.sky-grid-heading.sky-grid-column-alignment-left .sky-grid-help-inline-sort-hidden,.sky-grid-heading.sky-grid-column-alignment-center .sky-grid-help-inline-sort-hidden{margin-left:-14px;margin-right:14px}.sky-grid-heading.sky-grid-column-alignment-right .sky-grid-header-caret-hidden-spacing{padding-left:14px}.sky-grid-heading.sky-grid-column-alignment-right .sky-grid-heading-sort-visible{width:14px}.sky-grid-heading div{padding:8px}.sky-grid-heading .overflow{text-overflow:ellipsis;white-space:nowrap;position:relative;z-index:1;overflow:hidden;min-width:100%}.sky-grid-heading .sky-grid-column-input-aria-only{-webkit-appearance:none;-moz-appearance:none;height:100%;width:5px;position:absolute;display:block;top:0;bottom:0;right:0}.sky-grid-heading .sky-grid-column-input-aria-only::-moz-range-track{background:transparent}.sky-grid-heading .sky-grid-column-input-aria-only::-moz-range-thumb{-webkit-appearance:none;-moz-appearance:none;width:0;height:0;border-radius:0;border:0 none;background:none;display:none}.sky-grid-heading .sky-grid-column-input-aria-only::-ms-thumb{-webkit-appearance:none;-moz-appearance:none;width:0;height:0;border-radius:0;border:0 none;background:none;display:none}.sky-grid-heading .sky-grid-column-input-aria-only::-webkit-slider-thumb{-webkit-appearance:none;-moz-appearance:none;width:0;height:0;border-radius:0;border:0 none;background:none;display:none}.sky-grid-heading .sky-grid-column-input-aria-only:focus{background-color:#00b4f1}.sky-grid-column-alignment-left{text-align:left}.sky-grid-column-alignment-center{text-align:center}.sky-grid-column-alignment-right{text-align:right}.sky-grid-multiselect-cell{padding:0;text-align:center}.sky-grid-multiselect-cell ::ng-deep .sky-switch-control{margin:0 auto}th.sky-grid-multiselect-cell{cursor:default}th.sky-grid-multiselect-cell .screen-reader-only{width:0;height:0;padding:0;opacity:0;position:absolute;margin:-1px;border:0;overflow:hidden;clip:rect(0,0,0,0);outline:none;white-space:nowrap}@-moz-document url-prefix(){.sky-grid-multiselect-row td{border-left:0px solid transparent;border-right:0px solid transparent}}.sky-grid-multiselect-row:hover{background-color:#e9e4f1}.sky-grid-multiselect-row:hover:nth-child(odd){background:#e9e4f1}.sky-grid-multiselect-selected-row{background:#f1eef6;border-top:1px solid #dadbf6;border-bottom:1px solid #dadbf6}.sky-grid-multiselect-selected-row:nth-child(odd){background:#f1eef6}.sky-grid-has-toolbar .sky-grid-heading{border-top-width:0px}.sky-grid-heading-sort.sky-grid-heading-sort-hidden{visibility:hidden}.sky-grid-heading-sort.sky-grid-heading-sort-visible{visibility:visible;padding-left:5px}.sky-grid-resize-handle{position:absolute;right:0;top:0;bottom:0;width:30px;z-index:2;min-height:20px;height:100%!important;vertical-align:middle;cursor:col-resize}.sky-grid-resize-handle:hover:after{background-color:#00b4f1}.sky-grid-resize-handle:after{position:absolute;right:0;top:0;bottom:0;width:5px;height:100%;content:\"\"}#sky-grid-resize-bar{position:absolute;top:0;left:0;z-index:99;height:100%;width:5px;background:#00b4f1;opacity:.6}tr{position:relative}.sky-grid-top-scroll-container{overflow:auto}.sky-grid-top-scroll{height:1px}\n"], components: [{ type: i4.λ4, selector: "sky-icon", inputs: ["icon", "iconType", "size", "fixedWidth", "variant"] }, { type: i4.λ3, selector: "sky-help-inline", outputs: ["actionClick"] }, { type: i5.λ3, selector: "sky-checkbox", inputs: ["label", "labelledBy", "id", "disabled", "tabindex", "name", "icon", "checkboxType", "checked", "required"], outputs: ["change", "checkedChange", "disabledChange"] }, { type: i6.SkyGridCellComponent, selector: "sky-grid-cell", inputs: ["item", "columnId", "template", "fieldSelector"] }, { type: i7.λ8, selector: "sky-inline-delete", inputs: ["pending"], outputs: ["cancelTriggered", "deleteTriggered"] }], directives: [{ type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i8.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i2.DragulaDirective, selector: "[dragula]", inputs: ["dragula", "dragulaModel"], outputs: ["dragulaModelChange"] }, { type: i8.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i9.λ7, selector: "[skyPopover]", inputs: ["skyPopover", "skyPopoverAlignment", "skyPopoverMessageStream", "skyPopoverPlacement", "skyPopoverTrigger"] }, { type: i10.RangeValueAccessor, selector: "input[type=range][formControlName],input[type=range][formControl],input[type=range][ngModel]" }, { type: i10.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i10.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i10.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i4.λ11, selector: "[skyHighlight]", inputs: ["skyHighlight"] }, { type: i8.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], pipes: { "skyLibResources": i11.SkyLibResourcesPipe, "async": i8.AsyncPipe }, viewProviders: [DragulaService], changeDetection: i0.ChangeDetectionStrategy.OnPush });
958
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyGridComponent, decorators: [{
959
+ type: Component,
960
+ args: [{ selector: 'sky-grid', viewProviders: [DragulaService], providers: [SkyGridAdapterService], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"sky-grid\">\n <div\n *ngIf=\"showTopScroll\"\n class=\"sky-grid-top-scroll-container\"\n (scroll)=\"onTopScroll($event)\"\n #topScrollContainer\n >\n <div\n class=\"sky-grid-top-scroll\"\n [style.width.px]=\"getTopScrollWidth()\"\n ></div>\n </div>\n <div\n class=\"sky-grid-table-container\"\n [style.height.px]=\"height\"\n [style.width.px]=\"width\"\n (scroll)=\"onGridScroll($event)\"\n #gridContainer\n >\n <table class=\"sky-grid-table\" [ngClass]=\"getTableClassNames()\" #gridTable>\n <thead>\n <tr [dragula]=\"dragulaGroupName\">\n <th\n *ngIf=\"enableMultiselect\"\n class=\"sky-grid-heading sky-grid-multiselect-cell sky-grid-header-locked\"\n scope=\"col\"\n [style.max-width.px]=\"minColWidth\"\n [style.width.px]=\"minColWidth\"\n >\n <span class=\"screen-reader-only\">\n {{ 'skyux_grid_multiselect_select_row' | skyLibResources }}\n </span>\n </th>\n <th\n *ngFor=\"\n let column of displayedColumns;\n let last = last;\n let i = index\n \"\n class=\"sky-grid-heading sky-field-label\"\n scope=\"col\"\n [attr.sky-cmp-index]=\"i\"\n [attr.sky-cmp-id]=\"column.id || column.field\"\n [attr.aria-sort]=\"getAriaSortDirection(column) | async\"\n [id]=\"'sky-grid-' + gridId + '-column-' + i\"\n [ngClass]=\"'sky-grid-column-alignment-' + column.alignment\"\n [style.max-width.px]=\"column.width\"\n [style.width.px]=\"column.width\"\n [tabIndex]=\"column.isSortable ? 0 : -1\"\n (mouseup)=\"sortByColumn(column)\"\n (keydown)=\"onKeydown($event, column)\"\n (touchmove)=\"onTouchMove($event)\"\n #gridCol\n >\n <div\n class=\"overflow\"\n [ngClass]=\"getTableHeaderClassNames(column)\"\n [style.max-width.px]=\"column.width - 1\"\n [style.width.px]=\"column.width - 1\"\n >\n <span\n *ngIf=\"(getCaretVisibility(column.field) | async) === 'hidden'\"\n class=\"sky-grid-header-caret-hidden-spacing\"\n ></span>\n <!-- The no spacing here is intentional to avoid extra spaces due to these being inline elements -->\n <span class=\"sky-grid-header-text\">{{\n column.heading?.trim()\n }}</span>\n <sky-icon\n class=\"sky-grid-heading-sort\"\n [ngClass]=\"\n 'sky-grid-heading-sort-' +\n (getCaretVisibility(column.field) | async)\n \"\n [icon]=\"getCaretIconNames(column)\"\n >\n </sky-icon>\n <sky-help-inline\n *ngIf=\"column.inlineHelpPopover\"\n [ngClass]=\"{\n 'sky-grid-help-inline-sort-hidden':\n getHelpInlineClass(column.field) | async\n }\"\n [skyPopover]=\"column.inlineHelpPopover\"\n (keydown.enter)=\"$event.stopPropagation()\"\n (keydown.space)=\"$event.stopPropagation()\"\n (mousedown)=\"$event.stopPropagation()\"\n (mouseup)=\"$event.stopPropagation()\"\n >\n </sky-help-inline>\n </div>\n <span\n *ngIf=\"(fit === 'width' && !last) || fit === 'scroll'\"\n aria-hidden=\"true\"\n class=\"sky-grid-resize-handle\"\n tabindex=\"-1\"\n [attr.sky-cmp-index]=\"i\"\n (mousedown)=\"onResizeColumnStart($event)\"\n (touchstart)=\"onResizeColumnStart($event)\"\n >\n </span>\n <input\n aria-label=\"Width of column\"\n class=\"sky-grid-column-input-aria-only\"\n role=\"slider\"\n type=\"range\"\n [attr.aria-controls]=\"'sky-grid-' + gridId + '-column-' + i\"\n [attr.aria-valuemin]=\"minColWidth\"\n [attr.aria-valuemax]=\"maxColWidth\"\n [attr.aria-valuenow]=\"column.width\"\n [attr.sky-cmp-index]=\"i\"\n [min]=\"minColWidth\"\n [max]=\"maxColWidth\"\n [step]=\"columnResizeStep\"\n [(ngModel)]=\"column.width\"\n (blur)=\"onResizeHandleBlur($event)\"\n (focus)=\"onResizeHandleFocus($event)\"\n (keydown)=\"onKeydownResizeCol($event)\"\n (change)=\"onInputChangeResizeCol($event)\"\n #colSizeRange\n />\n </th>\n </tr>\n </thead>\n <tbody class=\"sky-grid-tbody\">\n <tr\n class=\"sky-grid-row\"\n *ngFor=\"let item of items; let i = index\"\n [attr.aria-current]=\"isRowHighlighted(item.id) ? true : null\"\n [attr.sky-cmp-id]=\"item.id\"\n [ngClass]=\"{\n 'sky-grid-multiselect-selected-row': item.isSelected,\n 'sky-grid-multiselect-row': enableMultiselect,\n 'sky-grid-row-highlight': isRowHighlighted(item.id)\n }\"\n (click)=\"onRowClick($event, item)\"\n >\n <td\n *ngIf=\"enableMultiselect\"\n class=\"sky-grid-multiselect-cell sky-grid-header-locked\"\n >\n <div\n [style.max-width.px]=\"minColWidth\"\n [style.width.px]=\"minColWidth\"\n >\n <sky-checkbox\n [label]=\"'skyux_grid_multiselect_select_row' | skyLibResources\"\n (change)=\"onMultiselectCheckboxChange()\"\n [(ngModel)]=\"item.isSelected\"\n >\n </sky-checkbox>\n </div>\n </td>\n <td\n *ngFor=\"\n let column of displayedColumns;\n let last = last;\n let i = index\n \"\n class=\"sky-grid-cell\"\n [ngClass]=\"'sky-grid-column-alignment-' + column.alignment\"\n [style.max-width.px]=\"column.width\"\n [style.width.px]=\"column.width\"\n >\n <sky-grid-cell\n [skyHighlight]=\"\n !column.excludeFromHighlighting ? highlightText : undefined\n \"\n [template]=\"column.template || defaultCellTemplate\"\n [fieldSelector]=\"column.field\"\n [item]=\"item\"\n [columnId]=\"column.id\"\n [attr.sky-cmp-id]=\"column.id || column.field\"\n >\n </sky-grid-cell>\n </td>\n </tr>\n </tbody>\n </table>\n <div\n *ngIf=\"showResizeBar\"\n aria-hidden=\"true\"\n id=\"sky-grid-resize-bar\"\n tabindex=\"-1\"\n #resizeBar\n ></div>\n </div>\n</div>\n\n<ng-template #defaultCellTemplate let-row=\"row\" let-value=\"value\">{{\n value\n}}</ng-template>\n\n<ng-template let-item #inlineDeleteTemplateRef>\n <div\n [id]=\"'row-delete-ref-' + item.id\"\n [ngStyle]=\"{\n height: getRowHeight(0),\n position: 'fixed',\n width: tableWidth + 'px'\n }\"\n #inlineDeleteRef\n >\n <sky-inline-delete\n [pending]=\"getRowDeleteItem(item.id).pending\"\n (cancelTriggered)=\"cancelRowDelete(item.id)\"\n (deleteTriggered)=\"confirmRowDelete(item.id)\"\n ></sky-inline-delete>\n </div>\n</ng-template>\n", styles: [".sky-grid{position:relative;display:block}.sky-grid-table-container{overflow:auto}.sky-grid-table{position:relative;table-layout:fixed;border-collapse:collapse;margin:0;font-size:15px;min-width:100%}.sky-grid-table.sky-grid-fit{max-width:100%;width:100%}.sky-grid-tbody{background-color:#fff}.sky-grid-row{border-bottom:1px dotted #cdcfd2}.sky-grid-row:nth-child(odd){background-color:#fbfbfb}.sky-grid-row.sky-grid-row-highlight{border-top:1px solid #0974a1;box-shadow:0 0 0 3px inset #0974a1}.sky-grid-row .sky-grid-cell{padding:0;min-width:10px}.sky-grid-heading{position:relative;border-top:1px solid #cdcfd2;border-bottom:1px solid #cdcfd2;border-left:1px solid #cdcfd2;border-right:1px solid #cdcfd2;border-right-width:0px;padding:0;cursor:pointer;background-color:#fff;overflow:visible;background-clip:padding-box;-webkit-user-select:none;-webkit-tap-highlight-color:transparent;user-select:none}.sky-grid-heading:first-child{border-left:1px solid transparent}.sky-grid-heading.sky-grid-header-dragging{background-color:#eeeeef}.sky-grid-heading.sky-grid-column-alignment-left .sky-grid-heading-sort,.sky-grid-heading.sky-grid-column-alignment-center .sky-grid-heading-sort{width:14px}.sky-grid-heading.sky-grid-column-alignment-left .sky-grid-help-inline-sort-hidden,.sky-grid-heading.sky-grid-column-alignment-center .sky-grid-help-inline-sort-hidden{margin-left:-14px;margin-right:14px}.sky-grid-heading.sky-grid-column-alignment-right .sky-grid-header-caret-hidden-spacing{padding-left:14px}.sky-grid-heading.sky-grid-column-alignment-right .sky-grid-heading-sort-visible{width:14px}.sky-grid-heading div{padding:8px}.sky-grid-heading .overflow{text-overflow:ellipsis;white-space:nowrap;position:relative;z-index:1;overflow:hidden;min-width:100%}.sky-grid-heading .sky-grid-column-input-aria-only{-webkit-appearance:none;-moz-appearance:none;height:100%;width:5px;position:absolute;display:block;top:0;bottom:0;right:0}.sky-grid-heading .sky-grid-column-input-aria-only::-moz-range-track{background:transparent}.sky-grid-heading .sky-grid-column-input-aria-only::-moz-range-thumb{-webkit-appearance:none;-moz-appearance:none;width:0;height:0;border-radius:0;border:0 none;background:none;display:none}.sky-grid-heading .sky-grid-column-input-aria-only::-ms-thumb{-webkit-appearance:none;-moz-appearance:none;width:0;height:0;border-radius:0;border:0 none;background:none;display:none}.sky-grid-heading .sky-grid-column-input-aria-only::-webkit-slider-thumb{-webkit-appearance:none;-moz-appearance:none;width:0;height:0;border-radius:0;border:0 none;background:none;display:none}.sky-grid-heading .sky-grid-column-input-aria-only:focus{background-color:#00b4f1}.sky-grid-column-alignment-left{text-align:left}.sky-grid-column-alignment-center{text-align:center}.sky-grid-column-alignment-right{text-align:right}.sky-grid-multiselect-cell{padding:0;text-align:center}.sky-grid-multiselect-cell ::ng-deep .sky-switch-control{margin:0 auto}th.sky-grid-multiselect-cell{cursor:default}th.sky-grid-multiselect-cell .screen-reader-only{width:0;height:0;padding:0;opacity:0;position:absolute;margin:-1px;border:0;overflow:hidden;clip:rect(0,0,0,0);outline:none;white-space:nowrap}@-moz-document url-prefix(){.sky-grid-multiselect-row td{border-left:0px solid transparent;border-right:0px solid transparent}}.sky-grid-multiselect-row:hover{background-color:#e9e4f1}.sky-grid-multiselect-row:hover:nth-child(odd){background:#e9e4f1}.sky-grid-multiselect-selected-row{background:#f1eef6;border-top:1px solid #dadbf6;border-bottom:1px solid #dadbf6}.sky-grid-multiselect-selected-row:nth-child(odd){background:#f1eef6}.sky-grid-has-toolbar .sky-grid-heading{border-top-width:0px}.sky-grid-heading-sort.sky-grid-heading-sort-hidden{visibility:hidden}.sky-grid-heading-sort.sky-grid-heading-sort-visible{visibility:visible;padding-left:5px}.sky-grid-resize-handle{position:absolute;right:0;top:0;bottom:0;width:30px;z-index:2;min-height:20px;height:100%!important;vertical-align:middle;cursor:col-resize}.sky-grid-resize-handle:hover:after{background-color:#00b4f1}.sky-grid-resize-handle:after{position:absolute;right:0;top:0;bottom:0;width:5px;height:100%;content:\"\"}#sky-grid-resize-bar{position:absolute;top:0;left:0;z-index:99;height:100%;width:5px;background:#00b4f1;opacity:.6}tr{position:relative}.sky-grid-top-scroll-container{overflow:auto}.sky-grid-top-scroll{height:1px}\n"] }]
961
+ }], ctorParameters: function () { return [{ type: i1.SkyAffixService }, { type: i0.ChangeDetectorRef }, { type: i2.DragulaService }, { type: i3.SkyGridAdapterService }, { type: i1.SkyOverlayService }, { type: i1.SkyAppWindowRef }, { type: i1.SkyUIConfigService }, { type: i1.SkyLogService }]; }, propDecorators: { columns: [{
962
+ type: Input
963
+ }], data: [{
964
+ type: Input
965
+ }], enableMultiselect: [{
966
+ type: Input
967
+ }], fit: [{
968
+ type: Input
969
+ }], hasToolbar: [{
970
+ type: Input
971
+ }], height: [{
972
+ type: Input
973
+ }], highlightText: [{
974
+ type: Input
975
+ }], messageStream: [{
976
+ type: Input
977
+ }], multiselectRowId: [{
978
+ type: Input
979
+ }], rowHighlightedId: [{
980
+ type: Input
981
+ }], selectedColumnIds: [{
982
+ type: Input
983
+ }], selectedRowIds: [{
984
+ type: Input
985
+ }], settingsKey: [{
986
+ type: Input
987
+ }], sortField: [{
988
+ type: Input
989
+ }], width: [{
990
+ type: Input
991
+ }], columnWidthChange: [{
992
+ type: Output
993
+ }], multiselectSelectionChange: [{
994
+ type: Output
995
+ }], rowDeleteCancel: [{
996
+ type: Output
997
+ }], rowDeleteConfirm: [{
998
+ type: Output
999
+ }], selectedColumnIdsChange: [{
1000
+ type: Output
1001
+ }], sortFieldChange: [{
1002
+ type: Output
1003
+ }], columnComponents: [{
1004
+ type: ContentChildren,
1005
+ args: [SkyGridColumnComponent]
1006
+ }], columnElementRefs: [{
1007
+ type: ViewChildren,
1008
+ args: ['gridCol']
1009
+ }], columnRangeInputElementRefs: [{
1010
+ type: ViewChildren,
1011
+ args: ['colSizeRange']
1012
+ }], inlineDeleteRefs: [{
1013
+ type: ViewChildren,
1014
+ args: ['inlineDeleteRef']
1015
+ }], inlineDeleteTemplateRef: [{
1016
+ type: ViewChild,
1017
+ args: ['inlineDeleteTemplateRef', { read: TemplateRef }]
1018
+ }], tableContainerElementRef: [{
1019
+ type: ViewChild,
1020
+ args: ['gridContainer']
1021
+ }], tableElementRef: [{
1022
+ type: ViewChild,
1023
+ args: ['gridTable']
1024
+ }], topScrollContainerElementRef: [{
1025
+ type: ViewChild,
1026
+ args: ['topScrollContainer']
1027
+ }], resizeBar: [{
1028
+ type: ViewChild,
1029
+ args: ['resizeBar']
1030
+ }], onWindowResize: [{
1031
+ type: HostListener,
1032
+ args: ['window:resize']
1033
+ }] } });
1034
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JpZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL2NvbXBvbmVudHMvZ3JpZHMvc3JjL2xpYi9tb2R1bGVzL2dyaWQvZ3JpZC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL2NvbXBvbmVudHMvZ3JpZHMvc3JjL2xpYi9tb2R1bGVzL2dyaWQvZ3JpZC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBR0wsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsZUFBZSxFQUNmLFVBQVUsRUFDVixZQUFZLEVBQ1osWUFBWSxFQUNaLEtBQUssRUFJTCxNQUFNLEVBQ04sU0FBUyxFQUVULFdBQVcsRUFDWCxTQUFTLEVBQ1QsWUFBWSxHQUNiLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFDTCxzQkFBc0IsRUFDdEIsZUFBZSxFQUNmLGVBQWUsRUFDZixhQUFhLEVBQ2IsaUJBQWlCLEVBQ2pCLGtCQUFrQixHQUNuQixNQUFNLGFBQWEsQ0FBQztBQUNyQixPQUFPLEVBQ0wsYUFBYSxFQUNiLDBCQUEwQixHQUMzQixNQUFNLDRCQUE0QixDQUFDO0FBRXBDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDN0MsT0FBTyxFQUNMLGVBQWUsRUFFZixPQUFPLEVBRVAsU0FBUyxFQUNULEtBQUssR0FDTixNQUFNLE1BQU0sQ0FBQztBQUNkLE9BQU8sRUFDTCxvQkFBb0IsRUFDcEIsR0FBRyxFQUNILElBQUksRUFDSixTQUFTLEVBQ1QsU0FBUyxHQUNWLE1BQU0sZ0JBQWdCLENBQUM7QUFFeEIsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDL0QsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDakUsT0FBTyxFQUFFLGtCQUFrQixF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QUFZO3VCQUFDLFNBQVM7Z0JBR2YsMkJBQTJCO3NCQURsQyxZQUFZO3VCQUFDLGNBQWM7Z0JBR3BCLGdCQUFnQjtzQkFEdkIsWUFBWTt1QkFBQyxpQkFBaUI7Z0JBR3ZCLHVCQUF1QjtzQkFEOUIsU0FBUzt1QkFBQyx5QkFBeUIsRUFBRSxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUU7Z0JBR25ELHdCQUF3QjtzQkFEL0IsU0FBUzt1QkFBQyxlQUFlO2dCQUdsQixlQUFlO3NCQUR0QixTQUFTO3VCQUFDLFdBQVc7Z0JBR2QsNEJBQTRCO3NCQURuQyxTQUFTO3VCQUFDLG9CQUFvQjtnQkFHdkIsU0FBUztzQkFEaEIsU0FBUzt1QkFBQyxXQUFXO2dCQTRJZixjQUFjO3NCQURwQixZQUFZO3VCQUFDLGVBQWUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBBZnRlckNvbnRlbnRJbml0LFxuICBBZnRlclZpZXdJbml0LFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgQ29udGVudENoaWxkcmVuLFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEhvc3RMaXN0ZW5lcixcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgUXVlcnlMaXN0LFxuICBTaW1wbGVDaGFuZ2VzLFxuICBUZW1wbGF0ZVJlZixcbiAgVmlld0NoaWxkLFxuICBWaWV3Q2hpbGRyZW4sXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgU2t5QWZmaXhBdXRvRml0Q29udGV4dCxcbiAgU2t5QWZmaXhTZXJ2aWNlLFxuICBTa3lBcHBXaW5kb3dSZWYsXG4gIFNreUxvZ1NlcnZpY2UsXG4gIFNreU92ZXJsYXlTZXJ2aWNlLFxuICBTa3lVSUNvbmZpZ1NlcnZpY2UsXG59IGZyb20gJ0Bza3l1eC9jb3JlJztcbmltcG9ydCB7XG4gIExpc3RJdGVtTW9kZWwsXG4gIExpc3RTb3J0RmllbGRTZWxlY3Rvck1vZGVsLFxufSBmcm9tICdAc2t5dXgvbGlzdC1idWlsZGVyLWNvbW1vbic7XG5cbmltcG9ydCB7IERyYWd1bGFTZXJ2aWNlIH0gZnJvbSAnbmcyLWRyYWd1bGEnO1xuaW1wb3J0IHtcbiAgQmVoYXZpb3JTdWJqZWN0LFxuICBPYnNlcnZhYmxlLFxuICBTdWJqZWN0LFxuICBTdWJzY3JpcHRpb24sXG4gIGZyb21FdmVudCxcbiAgbWVyZ2UsXG59IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtcbiAgZGlzdGluY3RVbnRpbENoYW5nZWQsXG4gIG1hcCxcbiAgdGFrZSxcbiAgdGFrZVVudGlsLFxuICB0YWtlV2hpbGUsXG59IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgU2t5R3JpZEFkYXB0ZXJTZXJ2aWNlIH0gZnJvbSAnLi9ncmlkLWFkYXB0ZXIuc2VydmljZSc7XG5pbXBvcnQgeyBTa3lHcmlkQ29sdW1uQ29tcG9uZW50IH0gZnJvbSAnLi9ncmlkLWNvbHVtbi5jb21wb25lbnQnO1xuaW1wb3J0IHsgU2t5R3JpZENvbHVtbk1vZGVsIH0gZnJvbSAnLi9ncmlkLWNvbHVtbi5tb2RlbCc7XG5pbXBvcnQgeyBTa3lHcmlkQ29sdW1uRGVzY3JpcHRpb25Nb2RlbENoYW5nZSB9IGZyb20gJy4vdHlwZXMvZ3JpZC1jb2x1bW4tZGVzY3JpcHRpb24tbW9kZWwtY2hhbmdlJztcbmltcG9ydCB7IFNreUdyaWRDb2x1bW5IZWFkaW5nTW9kZWxDaGFuZ2UgfSBmcm9tICcuL3R5cGVzL2dyaWQtY29sdW1uLWhlYWRpbmctbW9kZWwtY2hhbmdlJztcbmltcG9ydCB7IFNreUdyaWRDb2x1bW5JbmxpbmVIZWxwUG9wb3Zlck1vZGVsQ2hhbmdlIH0gZnJvbSAnLi90eXBlcy9ncmlkLWNvbHVtbi1pbmxpbmUtaGVscC1wb3BvdmVyLW1vZGVsLWNoYW5nZSc7XG5pbXBvcnQgeyBTa3lHcmlkQ29sdW1uV2lkdGhNb2RlbENoYW5nZSB9IGZyb20gJy4vdHlwZXMvZ3JpZC1jb2x1bW4td2lkdGgtbW9kZWwtY2hhbmdlJztcbmltcG9ydCB7IFNreUdyaWRNZXNzYWdlIH0gZnJvbSAnLi90eXBlcy9ncmlkLW1lc3NhZ2UnO1xuaW1wb3J0IHsgU2t5R3JpZE1lc3NhZ2VUeXBlIH0gZnJvbSAnLi90eXBlcy9ncmlkLW1lc3NhZ2UtdHlwZSc7XG5pbXBvcnQgeyBTa3lHcmlkUm93RGVsZXRlQ2FuY2VsQXJncyB9IGZyb20gJy4vdHlwZXMvZ3JpZC1yb3ctZGVsZXRlLWNhbmNlbC1hcmdzJztcbmltcG9ydCB7IFNreUdyaWRSb3dEZWxldGVDb25maWcgfSBmcm9tICcuL3R5cGVzL2dyaWQtcm93LWRlbGV0ZS1jb25maWcnO1xuaW1wb3J0IHsgU2t5R3JpZFJvd0RlbGV0ZUNvbmZpcm1BcmdzIH0gZnJvbSAnLi90eXBlcy9ncmlkLXJvdy1kZWxldGUtY29uZmlybS1hcmdzJztcbmltcG9ydCB7IFNreUdyaWRSb3dEZWxldGVDb250ZW50cyB9IGZyb20gJy4vdHlwZXMvZ3JpZC1yb3ctZGVsZXRlLWNvbnRlbnRzJztcbmltcG9ydCB7IFNreUdyaWRTZWxlY3RlZFJvd3NNb2RlbENoYW5nZSB9IGZyb20gJy4vdHlwZXMvZ3JpZC1zZWxlY3RlZC1yb3dzLW1vZGVsLWNoYW5nZSc7XG5pbXBvcnQgeyBTa3lHcmlkU2VsZWN0ZWRSb3dzU291cmNlIH0gZnJvbSAnLi90eXBlcy9ncmlkLXNlbGVjdGVkLXJvd3Mtc291cmNlJztcbmltcG9ydCB7IFNreUdyaWRVSUNvbmZpZyB9IGZyb20gJy4vdHlwZXMvZ3JpZC11aS1jb25maWcnO1xuXG5sZXQgbmV4dElkID0gMDtcblxuLyoqXG4gKiBAZGVwcmVjYXRlZCBgU2t5R3JpZENvbXBvbmVudGAgYW5kIGl0cyBmZWF0dXJlcyBhcmUgZGVwcmVjYXRlZC4gV2UgcmVjb21tZW5kIHVzaW5nIHRoZSBkYXRhIGdyaWQgaW5zdGVhZC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBodHRwczovL2RldmVsb3Blci5ibGFja2JhdWQuY29tL3NreXV4L2NvbXBvbmVudHMvZGF0YS1ncmlkXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3NreS1ncmlkJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2dyaWQuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9ncmlkLmNvbXBvbmVudC5zY3NzJ10sXG4gIHZpZXdQcm92aWRlcnM6IFtEcmFndWxhU2VydmljZV0sXG4gIHByb3ZpZGVyczogW1NreUdyaWRBZGFwdGVyU2VydmljZV0sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBTa3lHcmlkQ29tcG9uZW50XG4gIGltcGxlbWVudHMgT25Jbml0LCBBZnRlckNvbnRlbnRJbml0LCBBZnRlclZpZXdJbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveVxue1xuICAvKipcbiAgICogU3BlY2lmaWVzIGNvbHVtbnMgYW5kIGNvbHVtbiBwcm9wZXJ0aWVzIGZvciB0aGUgZ3JpZC5cbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBzZXQgY29sdW1ucyhuZXdDb2x1bW5zOiBBcnJheTxTa3lHcmlkQ29sdW1uTW9kZWw+KSB7XG4gICAgY29uc3Qgb2xkQ29sdW1ucyA9IHRoaXMuY29sdW1ucztcbiAgICB0aGlzLl9jb2x1bW5zID0gbmV3Q29sdW1ucztcbiAgICBpZiAob2xkQ29sdW1ucykge1xuICAgICAgdGhpcy50cmFuc2ZlckNvbHVtbldpZHRocyhvbGRDb2x1bW5zLCB0aGlzLmNvbHVtbnMpO1xuICAgICAgdGhpcy5pc1Jlc2l6ZWQgPSBmYWxzZTtcbiAgICAgIHRoaXMuc2V0RGlzcGxheWVkQ29sdW1ucyh0cnVlKTtcbiAgICB9XG4gICAgdGhpcy5jaGFuZ2VEZXRlY3Rvci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgY29sdW1ucygpOiBBcnJheTxTa3lHcmlkQ29sdW1uTW9kZWw+IHtcbiAgICByZXR1cm4gdGhpcy5fY29sdW1ucztcbiAgfVxuXG4gIC8qKlxuICAgKiBTcGVjaWZpZXMgdGhlIGRhdGEgZm9yIHRoZSBncmlkLiBFYWNoIGl0ZW0gcmVxdWlyZXMgYW4gYGlkYCBhbmQgYSBwcm9wZXJ0eSB0aGF0IG1hcHNcbiAgICogdG8gdGhlIGBmaWVsZGAgb3IgYGlkYCBwcm9wZXJ0eSBvZiBlYWNoIGNvbHVtbiBpbiB0aGUgZ3JpZC5cbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBkYXRhOiBBcnJheTxhbnk+O1xuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0byBlbmFibGUgdGhlIG11bHRpc2VsZWN0IGZlYXR1cmUgdG8gZGlzcGxheSBhIGNvbHVtbiBvZlxuICAgKiBjaGVja2JveGVzIG9uIHRoZSBsZWZ0IHNpZGUgb2YgdGhlIGdyaWQuIFlvdSBjYW4gc3BlY2lmeSBhIHVuaXF1ZSBJRCB3aXRoXG4gICAqIHRoZSBgbXVsdGlzZWxlY3RSb3dJZGAgcHJvcGVydHksIGJ1dCBtdWx0aXNlbGVjdCBkZWZhdWx0cyB0byB0aGUgYGlkYCBwcm9wZXJ0eSBvblxuICAgKiB0aGUgYGRhdGFgIG9iamVjdC5cbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBlbmFibGVNdWx0aXNlbGVjdCA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBTcGVjaWZpZXMgaG93IHRoZSBncmlkIGZpdHMgdG8gaXRzIHBhcmVudC4gVGhlIHZhbGlkIG9wdGlvbnMgYXJlIGB3aWR0aGAsXG4gICAqIHdoaWNoIGZpdHMgdGhlIGdyaWQgdG8gdGhlIHBhcmVudCdzIGZ1bGwgd2lkdGgsIGFuZCBgc2Nyb2xsYCwgd2hpY2ggYWxsb3dzIHRoZSBncmlkXG4gICAqIHRvIGV4Y2VlZCB0aGUgcGFyZW50J3Mgd2lkdGguIElmIHRoZSBncmlkIGRvZXMgbm90IGhhdmUgZW5vdWdoIGNvbHVtbnMgdG8gZmlsbFxuICAgKiB0aGUgcGFyZW50J3Mgd2lkdGgsIGl0IGFsd2F5cyBzdHJldGNoZXMgdG8gdGhlIHBhcmVudCdzIGZ1bGwgd2lkdGguXG4gICAqIEBkZWZhdWx0IFwid2lkdGhcIlxuICAgKi9cbiAgQElucHV0KClcbiAgcHVibGljIGZpdCA9ICd3aWR0aCc7XG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyB3aGV0aGVyIHRvIGRpc3BsYXkgYSB0b29sYmFyIHdpdGggdGhlIGdyaWQuXG4gICAqL1xuICBASW5wdXQoKVxuICBwdWJsaWMgaGFzVG9vbGJhciA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBTcGVjaWZpZXMgdGhlIGhlaWdodCBvZiB0aGUgZ3JpZC5cbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBoZWlnaHQ6IG51bWJlcjtcblxuICAvKipcbiAgICogU3BlY2lmaWVzIHRleHQgdG8gaGlnaGxpZ2h0IHdpdGhpbiB0aGUgZ3JpZC5cbiAgICogVHlwaWNhbGx5LCB0aGlzIHByb3BlcnR5IGlzIHVzZWQgaW4gY29uanVuY3Rpb24gd2l0aCBzZWFyY2guXG4gICAqL1xuICBASW5wdXQoKVxuICBwdWJsaWMgaGlnaGxpZ2h0VGV4dDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBQcm92aWRlcyBhbiBvYnNlcnZhYmxlIHRvIHNlbmQgY29tbWFuZHMgdG8gdGhlIGdyaWQuXG4gICAqL1xuICBASW5wdXQoKVxuICBwdWJsaWMgbWVzc2FnZVN0cmVhbSA9IG5ldyBTdWJqZWN0PFNreUdyaWRNZXNzYWdlPigpO1xuXG4gIC8qKlxuICAgKiBTcGVjaWZpZXMgYSB1bmlxdWUgSUQgdGhhdCBtYXRjaGVzIGEgcHJvcGVydHkgb24gdGhlIGBkYXRhYCBvYmplY3QuXG4gICAqIEJ5IGRlZmF1bHQsIHRoaXMgcHJvcGVydHkgdXNlcyB0aGUgYGlkYCBwcm9wZXJ0eS5cbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBtdWx0aXNlbGVjdFJvd0lkOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFNwZWNpZmllcyB0aGUgSUQgb2YgdGhlIHJvdyB0byBoaWdobGlnaHQuIFRoZSBJRCBtYXRjaGVzIHRoZSBgaWRgIHByb3BlcnR5XG4gICAqIG9mIHRoZSBgZGF0YWAgb2JqZWN0LiBUeXBpY2FsbHksIHRoaXMgcHJvcGVydHkgaXMgdXNlZCBpbiBjb25qdW5jdGlvbiB3aXRoXG4gICAqIHRoZSBmbHlvdXQgY29tcG9uZW50IHRvIGluZGljYXRlIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgcm93LlxuICAgKi9cbiAgQElucHV0KClcbiAgcHVibGljIHJvd0hpZ2hsaWdodGVkSWQ6IHN0cmluZztcblxuICAvKipcbiAgICogU3BlY2lmaWVzIHRoZSBjb2x1bW5zIHRvIGRpc3BsYXkgaW4gdGhlIGdyaWQgYmFzZWQgb24gdGhlIGBpZGAgb3IgYGZpZWxkYCBwcm9wZXJ0aWVzXG4gICAqIG9mIHRoZSBjb2x1bW5zLiBJZiBubyBjb2x1bW5zIGFyZSBzcGVjaWZpZWQsIHRoZW4gdGhlIGdyaWQgZGlzcGxheXMgYWxsIGNvbHVtbnMuXG4gICAqL1xuICBASW5wdXQoKVxuICBwdWJsaWMgc2V0IHNlbGVjdGVkQ29sdW1uSWRzKHZhbHVlOiBBcnJheTxzdHJpbmc+KSB7XG4gICAgY29uc3QgY3VycmVudElkcyA9IHRoaXMuX3NlbGVjdGVkQ29sdW1uSWRzO1xuICAgIHRoaXMuX3NlbGVjdGVkQ29sdW1uSWRzID0gdmFsdWU7XG5cbiAgICBpZiAodGhpcy5jb2x1bW5zKSB7XG4gICAgICB0aGlzLnNldERpc3BsYXllZENvbHVtbnMoKTtcbiAgICB9XG5cbiAgICAvLyBFbnN1cmUgdGhhdCB0aGUgaWRzIGhhdmUgY2hhbmdlZC5cbiAgICBpZiAoIWN1cnJlbnRJZHMgfHwgIXZhbHVlIHx8ICF0aGlzLmFycmF5c0VxdWFsKHZhbHVlLCBjdXJyZW50SWRzKSkge1xuICAgICAgLy8gVGhpcyB2YXJpYWJsZSBlbnN1cmVzIHRoYXQgd2UgZG8gbm90IHNldCB1c2VyIGNvbmZpZyBvcHRpb25zIG9yIGZpcmUgdGhlIGNoYW5nZSBldmVudFxuICAgICAgLy8gb24gdGhlIGZpcnN0IHRpbWUgdGhhdCB0aGUgY29sdW1ucyBhcmUgc2V0IHVwXG4gICAgICBpZiAodGhpcy5zZWxlY3RlZENvbHVtbklkc1NldCkge1xuICAgICAgICB0aGlzLnNldFVzZXJDb25maWcoe1xuICAgICAgICAgIHNlbGVjdGVkQ29sdW1uSWRzOiB2YWx1ZSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5zZWxlY3RlZENvbHVtbklkc0NoYW5nZS5lbWl0KHRoaXMuX3NlbGVjdGVkQ29sdW1uSWRzKTtcblxuICAgICAgICBpZiAodGhpcy5pc1Jlc2l6ZWQpIHtcbiAgICAgICAgICB0aGlzLnJlc2V0VGFibGVXaWR0aCgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5zZWxlY3RlZENvbHVtbklkc1NldCA9IHRydWU7XG4gIH1cblxuICBwdWJsaWMgZ2V0IHNlbGVjdGVkQ29sdW1uSWRzKCk6IEFycmF5PHN0cmluZz4ge1xuICAgIHJldHVybiB0aGlzLl9zZWxlY3RlZENvbHVtbklkcztcbiAgfVxuXG4gIC8qKlxuICAgKiBTcGVjaWZpZXMgYSBzZXQgb2YgSURzIGZvciB0aGUgcm93cyB0byBzZWxlY3QgaW4gYSBtdWx0aXNlbGVjdCBncmlkLlxuICAgKiBUaGUgSURzIG1hdGNoIHRoZSBgaWRgIHByb3BlcnRpZXMgb2YgdGhlIGBkYXRhYCBvYmplY3RzLlxuICAgKiBSb3dzIHdpdGggSURzIHRoYXQgYXJlIG5vdCBpbmNsdWRlZCBhcmUgZGUtc2VsZWN0ZWQgaW4gdGhlIGdyaWQuXG4gICAqL1xuICBASW5wdXQoKVxuICBwdWJsaWMgc2V0IHNlbGVjdGVkUm93SWRzKHZhbHVlOiBBcnJheTxzdHJpbmc+KSB7XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICB0aGlzLl9zZWxlY3RlZFJvd0lkcyA9IHZhbHVlO1xuICAgICAgdGhpcy5hcHBseVNlbGVjdGVkUm93cygpO1xuICAgICAgdGhpcy5lbWl0U2VsZWN0ZWRSb3dzKFNreUdyaWRTZWxlY3RlZFJvd3NTb3VyY2UuU2VsZWN0ZWRSb3dJZHNDaGFuZ2UpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBnZXQgc2VsZWN0ZWRSb3dJZHMoKTogQXJyYXk8c3RyaW5nPiB7XG4gICAgcmV0dXJuIHRoaXMuX3NlbGVjdGVkUm93SWRzO1xuICB9XG5cbiAgLyoqXG4gICAqIFNwZWNpZmllcyBhIHVuaXF1ZSBrZXkgZm9yIHRoZSBVSSBDb25maWcgU2VydmljZSB0byByZXRyaWV2ZSBzdG9yZWQgc2V0dGluZ3MgZnJvbSBhIGRhdGFiYXNlLlxuICAgKiBUaGUgVUkgQ29uZmlnIFNlcnZpY2Ugc2F2ZXMgY29uZmlndXJhdGlvbiBzZXR0aW5ncyBmb3IgdXNlcnMgYW5kIHJldHVybnNcbiAgICogYHNlbGVjdGVkQ29sdW1uSWRzYCB0byBwcmVzZXJ2ZSB0aGUgY29sdW1ucyB0byBkaXNwbGF5IGFuZCB0aGUgcHJlZmVycmVkIGNvbHVtbiBvcmRlci4gWW91ICBtdXN0IHByb3ZpZGUgYGlkYCB2YWx1ZXMgZm9yIHlvdXIgYHNreS1ncmlkLWNvbHVtbmAgZWxlbWVudHMgYmVjYXVzZSB0aGUgVUkgQ29uZmlnIFNlcnZpY2UgZGVwZW5kcyBvbiB0aG9zZSB2YWx1ZXMgdG8gb3JnYW5pemUgY29sdW1ucyBiYXNlZCBvbiB1c2VyIHNldHRpbmdzLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgVUkgQ29uZmlnIFNlcnZpY2UsIHNlZSBbdGhlIHN0aWNreSBzZXR0aW5ncyBkb2N1bWVudGF0aW9uXShodHRwczovL2RldmVsb3Blci5ibGFja2JhdWQuY29tL3NreXV4L2xlYXJuL2dldC1zdGFydGVkL3N0aWNreS1zZXR0aW5ncykuXG4gICAqL1xuICBASW5wdXQoKVxuICBwdWJsaWMgc2V0dGluZ3NLZXk6IHN0cmluZztcblxuICAvKipcbiAgICogRGlzcGxheXMgYSBjYXJldCBpbiB0aGUgY29sdW1uIHRoYXQgd2FzIHVzZWQgdG8gc29ydCB0aGUgZ3JpZC4gVGhpcyBpcyBwYXJ0aWN1bGFybHkgdXNlZnVsXG4gICAqIHdoZW4geW91IHByb2dyYW1tYXRpY2FsbHkgc29ydCBkYXRhIGFuZCB3YW50IHRvIHZpc3VhbGx5IGluZGljYXRlIGhvdyB0aGUgZ3JpZCB3YXMgc29ydGVkLlxuICAgKiBUaGlzIHByb3BlcnR5IGFjY2VwdHMgYSBgTGlzdFNvcnRGaWVsZFNlbGVjdG9yTW9kZWxgIHZhbHVlIHdpdGggdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOlxuICAgKiAtIGBmaWVsZFNlbGVjdG9yYCBSZXByZXNlbnRzIHRoZSBjdXJyZW50IHNvcnQgZmllbGQuIFRoaXMgcHJvcGVydHkgYWNjZXB0cyBgc3RyaW5nYCB2YWx1ZXMuXG4gICAqIC0gYGRlc2NlbmRpbmdgIEluZGljYXRlcyB3aGV0aGVyIHRvIHNvcnQgaW4gZGVzY2VuZGluZyBvcmRlci4gVGhlIGNhcmV0IHRoYXQgdmlzdWFsbHlcbiAgICogaW5kaWNhdGVzIHRoZSBzb3J0IG9yZGVyIHBvaW50cyBkb3duIGZvciBkZXNjZW5kaW5nIG9yZGVyIGFuZCB1cCBmb3IgYXNjZW5kaW5nIG9yZGVyLlxuICAgKiBUaGlzIHByb3BlcnR5IGFjY2VwdHMgYGJvb2xlYW5gIHZhbHVlcy4gRGVmYXVsdCBpcyBgZmFsc2VgLlxuICAgKi9cbiAgQElucHV0KClcbiAgcHVibGljIHNvcnRGaWVsZDogTGlzdFNvcnRGaWVsZFNlbGVjdG9yTW9kZWw7XG5cbiAgLyoqXG4gICAqIFNwZWNpZmllcyB0aGUgd2lkdGggb2YgdGhlIGdyaWQgaW4gcGl4ZWxzLlxuICAgKi9cbiAgQElucHV0KClcbiAgcHVibGljIHdpZHRoOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIEZpcmVzIHdoZW4gdGhlIHdpZHRoIG9mIGEgY29sdW1uIGNoYW5nZXMuXG4gICAqL1xuICBAT3V0cHV0KClcbiAgcHVibGljIGNvbHVtbldpZHRoQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxcbiAgICBBcnJheTxTa3lHcmlkQ29sdW1uV2lkdGhNb2RlbENoYW5nZT5cbiAgPigpO1xuXG4gIC8qKlxuICAgKiBGaXJlcyB3aGVuIHRoZSBzZWxlY3Rpb24gb2YgbXVsdGlzZWxlY3QgY2hlY2tib3hlcyBjaGFuZ2VzLlxuICAgKiBFbWl0cyBhbiBhcnJheSBvZiBJRHMgZm9yIHRoZSBzZWxlY3RlZCByb3dzIGJhc2VkIG9uIHRoZSBgbXVsdGlzZWxlY3RSb3dJZGAgcHJvcGVydHlcbiAgICogdGhhdCB0aGUgY29uc3VtZXIgcHJvdmlkZXMuXG4gICAqL1xuICBAT3V0cHV0KClcbiAgcHVibGljIG11bHRpc2VsZWN0U2VsZWN0aW9uQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxTa3lHcmlkU2VsZWN0ZWRSb3dzTW9kZWxDaGFuZ2U+KCk7XG5cbiAgLyoqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgQE91dHB1dCgpXG4gIHB1YmxpYyByb3dEZWxldGVDYW5jZWwgPSBuZXcgRXZlbnRFbWl0dGVyPFNreUdyaWRSb3dEZWxldGVDYW5jZWxBcmdzPigpO1xuXG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIEBPdXRwdXQoKVxuICBwdWJsaWMgcm93RGVsZXRlQ29uZmlybSA9IG5ldyBFdmVudEVtaXR0ZXI8U2t5R3JpZFJvd0RlbGV0ZUNvbmZpcm1BcmdzPigpO1xuXG4gIC8qKlxuICAgKiBGaXJlcyB3aGVuIHRoZSBjb2x1bW5zIHRvIGRpc3BsYXkgaW4gdGhlIGdyaWQgY2hhbmdlIG9yIHdoZW4gdGhlIG9yZGVyIG9mIHRoZSBjb2x1bW5zIGNoYW5nZXMuXG4gICAqIFRoZSBldmVudCBlbWl0cyBhbiBhcnJheSBvZiBJRHMgZm9yIHRoZSBkaXNwbGF5ZWQgY29sdW1ucyB0aGF0IHJlZmxlY3RzIHRoZSBjb2x1bW4gb3JkZXIuXG4gICAqL1xuICBAT3V0cHV0KClcbiAgcHVibGljIHNlbGVjdGVkQ29sdW1uSWRzQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxBcnJheTxzdHJpbmc+PigpO1xuXG4gIC8qKlxuICAgKiBGaXJlcyB3aGVuIHRoZSBhY3RpdmUgc29ydCBmaWVsZCBjaGFuZ2VzLlxuICAgKi9cbiAgQE91dHB1dCgpXG4gIHB1YmxpYyBzb3J0RmllbGRDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPExpc3RTb3J0RmllbGRTZWxlY3Rvck1vZGVsPigpO1xuXG4gIHB1YmxpYyBjb2x1bW5SZXNpemVTdGVwID0gMTA7XG4gIHB1YmxpYyBjdXJyZW50U29ydEZpZWxkOiBCZWhhdmlvclN1YmplY3Q8TGlzdFNvcnRGaWVsZFNlbGVjdG9yTW9kZWw+O1xuICBwdWJsaWMgZGlzcGxheWVkQ29sdW1uczogQXJyYXk8U2t5R3JpZENvbHVtbk1vZGVsPjtcbiAgcHVibGljIGRyYWd1bGFHcm91cE5hbWU6IHN0cmluZztcbiAgcHVibGljIGdyaWRJZDogbnVtYmVyID0gKytuZXh0SWQ7XG4gIHB1YmxpYyByb3dEZWxldGVDb25maWdzOiBTa3lHcmlkUm93RGVsZXRlQ29uZmlnW10gPSBbXTtcbiAgcHVibGljIGl0ZW1zOiBBcnJheTxhbnk+O1xuICBwdWJsaWMgbWF4Q29sV2lkdGggPSA5OTk5OyAvLyBUaGlzIGlzIGFuIGFyYml0cmFyeSBudW1iZXIsIGFzIHRoZSBpbnB1dCByYW5nZSBwaWNrZXIgd29uJ3Qgd29yayB3aXRob3V0IGEgdmFsdWUuXG4gIHB1YmxpYyBtaW5Db2xXaWR0aCA9IDUwO1xuICBwdWJsaWMgc2hvd1Jlc2l6ZUJhciA9IGZhbHNlO1xuICBwdWJsaWMgc2hvd1RvcFNjcm9sbCA9IGZhbHNlO1xuXG4gIHB1YmxpYyBnZXQgdGFibGVXaWR0aCgpIHtcbiAgICByZXR1cm4gdGhpcy50YWJsZUVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5vZmZzZXRXaWR0aDtcbiAgfVxuXG4gIEBDb250ZW50Q2hpbGRyZW4oU2t5R3JpZENvbHVtbkNvbXBvbmVudClcbiAgcHJpdmF0ZSBjb2x1bW5Db21wb25lbnRzOiBRdWVyeUxpc3Q8U2t5R3JpZENvbHVtbkNvbXBvbmVudD47XG5cbiAgQFZpZXdDaGlsZHJlbignZ3JpZENvbCcpXG4gIHByaXZhdGUgY29sdW1uRWxlbWVudFJlZnM6IFF1ZXJ5TGlzdDxFbGVtZW50UmVmPjtcbiAgQFZpZXdDaGlsZHJlbignY29sU2l6ZVJhbmdlJylcbiAgcHJpdmF0ZSBjb2x1bW5SYW5nZUlucHV0RWxlbWVudFJlZnM6IFF1ZXJ5TGlzdDxFbGVtZW50UmVmPjtcbiAgQFZpZXdDaGlsZHJlbignaW5saW5lRGVsZXRlUmVmJylcbiAgcHJpdmF0ZSBpbmxpbmVEZWxldGVSZWZzOiBRdWVyeUxpc3Q8RWxlbWVudFJlZj47XG4gIEBWaWV3Q2hpbGQoJ2lubGluZURlbGV0ZVRlbXBsYXRlUmVmJywgeyByZWFkOiBUZW1wbGF0ZVJlZiB9KVxuICBwcml2YXRlIGlubGluZURlbGV0ZVRlbXBsYXRlUmVmOiBUZW1wbGF0ZVJlZjx1bmtub3duPjtcbiAgQFZpZXdDaGlsZCgnZ3JpZENvbnRhaW5lcicpXG4gIHByaXZhdGUgdGFibGVDb250YWluZXJFbGVtZW50UmVmOiBFbGVtZW50UmVmO1xuICBAVmlld0NoaWxkKCdncmlkVGFibGUnKVxuICBwcml2YXRlIHRhYmxlRWxlbWVudFJlZjogRWxlbWVudFJlZjtcbiAgQFZpZXdDaGlsZCgndG9wU2Nyb2xsQ29udGFpbmVyJylcbiAgcHJpdmF0ZSB0b3BTY3JvbGxDb250YWluZXJFbGVtZW50UmVmOiBFbGVtZW50UmVmO1xuICBAVmlld0NoaWxkKCdyZXNpemVCYXInKVxuICBwcml2YXRlIHJlc2l6ZUJhcjogRWxlbWVudFJlZjtcblxuICBwcml2YXRlIGFjdGl2ZVJlc2l6ZUNvbHVtbkluZGV4OiBzdHJpbmc7XG4gIHByaXZhdGUgaXNEcmFnZ2luZ1Jlc2l6ZUhhbmRsZSA9IGZhbHNlO1xuICBwcml2YXRlIGlzUmVzaXplZCA9IGZhbHNlO1xuICBwcml2YXRlIG5nVW5zdWJzY3JpYmUgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICBwcml2YXRlIHJvd0RlbGV0ZUNvbnRlbnRzOiB7IFtpZDogc3RyaW5nXTogU2t5R3JpZFJvd0RlbGV0ZUNvbnRlbnRzIH0gPSB7fTtcbiAgcHJpdmF0ZSBzdGFydENvbHVtbldpZHRoOiBudW1iZXI7XG4gIHByaXZhdGUgc3Vic2NyaXB0aW9uczogU3Vic2NyaXB0aW9uW10gPSBbXTtcbiAgcHJpdmF0ZSBzY3JvbGxUcmlnZ2VyZWQgPSBmYWxzZTtcbiAgcHJpdmF0ZSBzZWxlY3RlZENvbHVtbklkc1NldCA9IGZhbHNlO1xuICBwcml2YXRlIHhQb3NTdGFydDogbnVtYmVyO1xuXG4gIHByaXZhdGUgX2NvbHVtbnM6IEFycmF5PFNreUdyaWRDb2x1bW5Nb2RlbD47XG4gIHByaXZhdGUgX3NlbGVjdGVkQ29sdW1uSWRzOiBBcnJheTxzdHJpbmc+O1xuICBwcml2YXRlIF9zZWxlY3RlZFJvd0lkczogQXJyYXk8c3RyaW5nPjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGFmZml4U2VydmljZTogU2t5QWZmaXhTZXJ2aWNlLFxuICAgIHByaXZhdGUgY2hhbmdlRGV0ZWN0b3I6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIHByaXZhdGUgZHJhZ3VsYVNlcnZpY2U6IERyYWd1bGFTZXJ2aWNlLFxuICAgIHByaXZhdGUgZ3JpZEFkYXB0ZXI6IFNreUdyaWRBZGFwdGVyU2VydmljZSxcbiAgICBwcml2YXRlIG92ZXJsYXlTZXJ2aWNlOiBTa3lPdmVybGF5U2VydmljZSxcbiAgICBwcml2YXRlIHNreVdpbmRvdzogU2t5QXBwV2luZG93UmVmLFxuICAgIHByaXZhdGUgdWlDb25maWdTZXJ2aWNlOiBTa3lVSUNvbmZpZ1NlcnZpY2UsXG4gICAgbG9nZ2VyOiBTa3lMb2dTZXJ2aWNlXG4gICkge1xuICAgIGxvZ2dlci5kZXByZWNhdGVkKCdTa3lHcmlkQ29tcG9uZW50Jywge1xuICAgICAgZGVwcmVjYXRpb25NYWpvclZlcnNpb246IDYsXG4gICAgICBtb3JlSW5mb1VybDogJ2h0dHBzOi8vZGV2ZWxvcGVyLmJsYWNrYmF1ZC5jb20vc2t5dXgvY29tcG9uZW50cy9kYXRhLWdyaWQnLFxuICAgICAgcmVwbGFjZW1lbnRSZWNvbW1lbmRhdGlvbjogJ1VzZSBkYXRhIGdyaWQgaW5zdGVhZC4nLFxuICAgIH0pO1xuXG4gICAgdGhpcy5kaXNwbGF5ZWRDb2x1bW5zID0gbmV3IEFycmF5PFNreUdyaWRDb2x1bW5Nb2RlbD4oKTtcbiAgICB0aGlzLml0ZW1zID0gbmV3IEFycmF5PGFueT4oKTtcbiAgICB0aGlzLmN1cnJlbnRTb3J0RmllbGQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PExpc3RTb3J0RmllbGRTZWxlY3Rvck1vZGVsPih7XG4gICAgICBmaWVsZFNlbGVjdG9yOiAnJyxcbiAgICAgIGRlc2NlbmRpbmc6IGZhbHNlLFxuICAgIH0pO1xuICAgIHRoaXMuZHJhZ3VsYUdyb3VwTmFtZSA9IGBza3ktZ3JpZHMtZ3JvdXAtJHt0aGlzLmdyaWRJZH1gO1xuICB9XG5cbiAgcHVibGljIG5nT25Jbml0KCkge1xuICAgIHRoaXMubWVzc2FnZVN0cmVhbVxuICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMubmdVbnN1YnNjcmliZSkpXG4gICAgICAuc3Vic2NyaWJlKChtZXNzYWdlOiBTa3lHcmlkTWVzc2FnZSkgPT4ge1xuICAgICAgICB0aGlzLmhhbmRsZUluY29taW5nTWVzc2FnZXMobWVzc2FnZSk7XG4gICAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBuZ0FmdGVyQ29udGVudEluaXQoKSB7XG4gICAgaWYgKHRoaXMuc2V0dGluZ3NLZXkpIHtcbiAgICAgIHRoaXMuYXBwbHlVc2VyQ29uZmlnKCkudGhlbigoKSA9PiB7XG4gICAgICAgIHRoaXMuaW5pdENvbHVtbnMoKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmluaXRDb2x1bW5zKCk7XG4gICAgfVxuXG4gICAgLy8gU2V0dXAgY29sdW1uIGRyYWctYW5kLWRyb3AuXG4gICAgdGhpcy5ncmlkQWRhcHRlci5pbml0aWFsaXplRHJhZ0FuZERyb3AoXG4gICAgICB0aGlzLmRyYWd1bGFHcm91cE5hbWUsXG4gICAgICB0aGlzLmRyYWd1bGFTZXJ2aWNlLFxuICAgICAgKHNlbGVjdGVkQ29sdW1uSWRzOiBBcnJheTxzdHJpbmc+KSA9PiB7XG4gICAgICAgIHRoaXMub25IZWFkZXJEcm9wKHNlbGVjdGVkQ29sdW1uSWRzKTtcbiAgICAgIH1cbiAgICApO1xuXG4gICAgdGhpcy5hcHBseVNlbGVjdGVkUm93cygpO1xuICB9XG5cbiAgcHVibGljIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICB0aGlzLmNoZWNrVXNlckNvbHVtbldpZHRoc0ZvclNjcm9sbCgpO1xuICB9XG5cbiAgcHVibGljIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcbiAgICBpZiAoY2hhbmdlcy5jb2x1bW5zICYmIHRoaXMuY29sdW1ucykge1xuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRDb2x1bW5JZHMpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZENvbHVtbklkcyA9IHRoaXMuc2VsZWN0ZWRDb2x1bW5JZHMuZmlsdGVyKChjb2x1bW5JZCkgPT4ge1xuICAgICAgICAgIHJldHVybiB0aGlzLmNvbHVtbnMuZmluZCgoY29sdW1uKSA9PiBjb2x1bW4uaWQgPT09IGNvbHVtbklkKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICB0aGlzLnNldERpc3BsYXllZENvbHVtbnModHJ1ZSk7XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZXMuZGF0YSAmJiB0aGlzLmRhdGEpIHtcbiAgICAgIHRoaXMudHJhbnNmb3JtRGF0YSgpO1xuXG4gICAgICAvLyBUaGlzIHNldCB0aW1lb3V0IGlzIG5lY2Vzc2FyeSB0byBlbnN1cmUgdGhlIGRhdGEgaGFzIHJlbmRlcmVkIGluIHRoZSBncmlkXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgLy8gVGhpcyBjbGVhbnMgdXAgYW55IGxpbmdlcmluZyByb3cgZGVsZXRlcyBmb3IgaXRlbXMgdGhhdCBoYXZlIGJlZW4gcmVtb3ZlZC5cbiAgICAgICAgT2JqZWN0LmtleXModGhpcy5yb3dEZWxldGVDb250ZW50cykuZm9yRWFjaCgoaWQpID0+IHtcbiAgICAgICAgICBpZiAoIXRoaXMuZGF0YS5maW5kKChpdGVtKSA9PiBpdGVtLmlkID09PSBpZCkpIHtcbiAgICAgICAgICAgIHRoaXMuZGVzdHJveVJvd0RlbGV0ZShpZCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFRoZSByb3dzIHJlLXJlbmRlciB0aHVzIG1lc3NpbmcgdXAgdGhlIGFmZml4ZXJzLiBXZSBtdXN0IHJlYWZmaXggdGhlbSBzbyB0aGF0IHRoaW5nc1xuICAgICAgICAgICAgLy8gY29udGludWUgdG8gcmVuZGVyIGNvcnJlY3RseS5cbiAgICAgICAgICAgIGNvbnN0IHJvd0VsZW1lbnQ6IEhUTUxFbGVtZW50ID1cbiAgICAgICAgICAgICAgdGhpcy50YWJsZUVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKFxuICAgICAgICAgICAgICAgICdbc2t5LWNtcC1pZD1cIicgKyBpZCArICdcIl0nXG4gICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIHRoaXMucm93RGVsZXRlQ29udGVudHNbaWRdLmFmZml4ZXIuYWZmaXhUbyhyb3dFbGVtZW50LCB7XG4gICAgICAgICAgICAgIGF1dG9GaXRDb250ZXh0OiBTa3lBZmZpeEF1dG9GaXRDb250ZXh0LlZpZXdwb3J0LFxuICAgICAgICAgICAgICBpc1N0aWNreTogdHJ1ZSxcbiAgICAgICAgICAgICAgcGxhY2VtZW50OiAnYWJvdmUnLFxuICAgICAgICAgICAgICB2ZXJ0aWNhbEFsaWdubWVudDogJ3RvcCcsXG4gICAgICAgICAgICAgIGhvcml6b250YWxBbGlnbm1lbnQ6ICdsZWZ0JyxcbiAgICAgICAgICAgICAgZW5hYmxlQXV0b0ZpdDogZmFsc2UsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuY2hlY2tVc2VyQ29sdW1uV2lkdGhzRm9yU2Nyb2xsKCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoY2hhbmdlcy5zb3J0RmllbGQpIHtcbiAgICAgIHRoaXMuc2V0U29ydEhlYWRlcnMoKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmZvckVhY2goKHN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uKSA9PiB7XG4gICAgICBzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB9KTtcbiAgICB0aGlzLm11bHRpc2VsZWN0U2VsZWN0aW9uQ2hhbmdlLmNvbXBsZXRlKCk7XG5cbiAgICB0aGlzLm5nVW5zdWJzY3JpYmUubmV4dCgpO1xuICAgIHRoaXMubmdVbnN1YnNjcmliZS5jb21wbGV0ZSgpO1xuXG4gICAgT2JqZWN0LmtleXModGhpcy5yb3dEZWxldGVDb250ZW50cykuZm9yRWFjaCgoaWQpID0+IHtcbiAgICAgIHRoaXMuZGVzdHJveVJvd0RlbGV0ZShpZCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmRyYWd1bGFTZXJ2aWNlLmRlc3Ryb3kodGhpcy5kcmFndWxhR3JvdXBOYW1lKTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzpyZXNpemUnKVxuICBwdWJsaWMgb25XaW5kb3dSZXNpemUoKTogdm9pZCB7XG4gICAgdGhpcy5jaGVja1VzZXJDb2x1bW5XaWR0aHNGb3JTY3JvbGwoKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRUb3BTY3JvbGxXaWR0aCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnRhYmxlRWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnNjcm9sbFdpZHRoO1xuICB9XG5cbiAgcHVibGljIGdldFRhYmxlQ2xhc3NOYW1lcygpIHtcbiAgICBjb25zdCBjbGFzc05hbWVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgaWYgKHRoaXMuZml0ICE9PSAnc2Nyb2xsJykge1xuICAgICAgY2xhc3NOYW1lcy5wdXNoKCdza3ktZ3JpZC1maXQnKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5oYXNUb29sYmFyKSB7XG4gICAgICBjbGFzc05hbWVzLnB1c2goJ3NreS1ncmlkLWhhcy10b29sYmFyJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuYWRkRGVsaW1ldGVyKGNsYXNzTmFtZXMsICcgJyk7XG4gIH1cblxuICBwdWJsaWMgZ2V0VGFibGVIZWFkZXJDbGFzc05hbWVzKGNvbHVtbjogU2t5R3JpZENvbHVtbk1vZGVsKSB7XG4gICAgY29uc3QgY2xhc3NOYW1lczogc3RyaW5nW10gPSBbXTtcblxuICAgIGlmIChjb2x1bW4gJiYgY29sdW1uLmxvY2tlZCkge1xuICAgICAgY2xhc3NOYW1lcy5wdXNoKCdza3ktZ3JpZC1oZWFkZXItbG9ja2VkJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuYWRkRGVsaW1ldGVyKGNsYXNzTmFtZXMsICcgJyk7XG4gIH1cblxuICBwdWJsaWMgZ2V0Q2FyZXRJY29uTmFtZXMoY29sdW1uOiBTa3lHcmlkQ29sdW1uTW9kZWwpIHtcbiAgICBjb25zdCBpY29uTmFtZXM6IHN0cmluZ1tdID0gW107XG5cbiAgICB0aGlzLmdldFNvcnREaXJlY3Rpb24oY29sdW1uLmZpZWxkKS5zdWJzY3JpYmUoKHNvcnREaXIpID0+IHtcbiAgICAgIGlmIChzb3J0RGlyID09PSAnYXNjJykge1xuICAgICAgICBpY29uTmFtZXMucHVzaCgnY2FyZXQtdXAnKTtcbiAgICAgIH1cbiAgICAgIGlmIChzb3J0RGlyID09PSAnZGVzYycpIHtcbiAgICAgICAgaWNvbk5hbWVzLnB1c2goJ2NhcmV0LWRvd24nKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiB0aGlzLmFkZERlbGltZXRlcihpY29uTmFtZXMsICcgJyk7XG4gIH1cblxuICBwdWJsaWMgb25LZXlkb3duKGV2ZW50OiBLZXlib2FyZEV2ZW50LCBjb2x1bW46IFNreUdyaWRDb2x1bW5Nb2RlbCkge1xuICAgIGNvbnN0IGtleSA9IGV2ZW50LmtleS50b0xvd2VyQ2FzZSgpO1xuICAgIGlmIChrZXkgPT09ICdlbnRlcicgfHwga2V5ID09PSAnICcpIHtcbiAgICAgIHRoaXMuc29ydEJ5Q29sdW1uKGNvbHVtbik7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHNvcnRCeUNvbHVtbihjb2x1bW46IFNreUdyaWRDb2x1bW5Nb2RlbCkge1xuICAgIGlmICghdGhpcy5pc0RyYWdnaW5nUmVzaXplSGFuZGxlICYmIGNvbHVtbi5pc1NvcnRhYmxlKSB7XG4gICAgICB0aGlzLmN1cnJlbnRTb3J0RmllbGRcbiAgICAgICAgLnBpcGUoXG4gICAgICAgICAgdGFrZSgxKSxcbiAgICAgICAgICBtYXAoKGZpZWxkKSA9PiB7XG4gICAgICAgICAgICBsZXQgc2VsZWN0b3IgPSB7XG4gICAgICAgICAgICAgIGZpZWxkU2VsZWN0b3I6IGNvbHVtbi5maWVsZCxcbiAgICAgICAgICAgICAgZGVzY2VuZGluZzogdHJ1ZSxcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgZmllbGQgJiZcbiAgICAgICAgICAgICAgZmllbGQuZmllbGRTZWxlY3RvciA9PT0gY29sdW1uLmZpZWxkICYmXG4gICAgICAgICAgICAgIGZpZWxkLmRlc2NlbmRpbmdcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICBzZWxlY3RvciA9IHtcbiAgICAgICAgICAgICAgICBmaWVsZFNlbGVjdG9yOiBjb2x1bW4uZmllbGQsXG4gICAgICAgICAgICAgICAgZGVzY2VuZGluZzogZmFsc2UsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNvcnRGaWVsZENoYW5nZS5lbWl0KHNlbGVjdG9yKTtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudFNvcnRGaWVsZC5uZXh0KHNlbGVjdG9yKTtcbiAgICAgICAgICB9KVxuICAgICAgICApXG4gICAgICAgIC5zdWJzY3JpYmUoKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZ2V0U29ydERpcmVjdGlvbihjb2x1bW5GaWVsZDogc3RyaW5nKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHtcbiAgICByZXR1cm4gdGhpcy5jdXJyZW50U29ydEZpZWxkLnBpcGUoXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxuICAgICAgbWFwKChmaWVsZCkgPT4ge1xuICAgICAgICByZXR1cm4gZmllbGQuZmllbGRTZWxlY3RvciA9PT0gY29sdW1uRmllbGRcbiAgICAgICAgICA/IGZpZWxkLmRlc2NlbmRpbmdcbiAgICAgICAgICAgID8gJ2Rlc2MnXG4gICAgICAgICAgICA6ICdhc2MnXG4gICAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgZ2V0QXJpYVNvcnREaXJlY3Rpb24oY29sdW1uOiBTa3lHcmlkQ29sdW1uTW9kZWwpOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuICAgIHJldHVybiB0aGlzLmN1cnJlbnRTb3J0RmllbGQucGlwZShcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG4gICAgICBtYXAoKGZpZWxkKSA9PiB7XG4gICAgICAgIHJldHVybiBmaWVsZC5maWVsZFNlbGVjdG9yID09PSBjb2x1bW4uZmllbGRcbiAgICAgICAgICA/IGZpZWxkLmRlc2NlbmRpbmdcbiAgICAgICAgICAgID8gJ2Rlc2NlbmRpbmcnXG4gICAgICAgICAgICA6ICdhc2NlbmRpbmcnXG4gICAgICAgICAgOiBjb2x1bW4uaXNTb3J0YWJsZVxuICAgICAgICAgID8gJ25vbmUnXG4gICAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgZ2V0Q2FyZXRWaXNpYmlsaXR5KGNvbHVtbkZpZWxkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuICAgIHJldHVybiB0aGlzLmN1cnJlbnRTb3J0RmllbGQucGlwZShcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG4gICAgICBtYXAoKGZpZWxkKSA9PiB7XG4gICAgICAgIHJldHVybiBmaWVsZC5maWVsZFNlbGVjdG9yID09PSBjb2x1bW5GaWVsZCA/ICd2aXNpYmxlJyA6ICdoaWRkZW4nO1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgcHVibGljIGdldEhlbHBJbmxpbmVDbGFzcyhjb2x1bW5GaWVsZDogc3RyaW5nKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0Q2FyZXRWaXNpYmlsaXR5KGNvbHVtbkZpZWxkKS5waXBlKFxuICAgICAgbWFwKCh2aXNpYmlsaXR5OiBzdHJpbmcpID0+IHtcbiAgICAgICAgcmV0dXJuIHZpc2liaWxpdHkgPT09ICdoaWRkZW4nO1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgcHVibGljIG9uTXVsdGlzZWxlY3RDaGVja2JveENoYW5nZSgpIHtcbiAgICB0aGlzLmVtaXRTZWxlY3RlZFJvd3MoU2t5R3JpZFNlbGVjdGVkUm93c1NvdXJjZS5DaGVja2JveENoYW5nZSk7XG4gIH1cblxuICBwdWJsaWMgdXBkYXRlQ29sdW1uSGVhZGluZyhjaGFuZ2U6IFNreUdyaWRDb2x1bW5IZWFkaW5nTW9kZWxDaGFuZ2UpIHtcbiAgICBjb25zdCBmb3VuZENvbHVtbk1vZGVsID0gdGhpcy5jb2x1bW5zLmZpbmQoKGNvbHVtbjogU2t5R3JpZENvbHVtbk1vZGVsKSA9PiB7XG4gICAgICByZXR1cm4gKFxuICAgICAgICAoY2hhbmdlLmlkICE9PSB1bmRlZmluZWQgJiYgY2hhbmdlLmlkID09PSBjb2x1bW4uaWQpIHx8XG4gICAgICAgIChjaGFuZ2UuZmllbGQgIT09IHVuZGVmaW5lZCAmJiBjaGFuZ2UuZmllbGQgPT09IGNvbHVtbi5maWVsZClcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgIGlmIChmb3VuZENvbHVtbk1vZGVsKSB7XG4gICAgICBmb3VuZENvbHVtbk1vZGVsLmhlYWRpbmcgPSBjaGFuZ2UudmFsdWU7XG4gICAgICB0aGlzLmNoYW5nZURldGVjdG9yLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyB1cGRhdGVJbmxpbmVIZWxwUG9wb3ZlcihcbiAgICBjaGFuZ2U6IFNreUdyaWRDb2x1bW5JbmxpbmVIZWxwUG9wb3Zlck1vZGVsQ2hhbmdlXG4gICkge1xuICAgIGNvbnN0IGZvdW5kQ29sdW1uTW9kZWwgPSB0aGlzLmNvbHVtbnMuZmluZCgoY29sdW1uOiBTa3lHcmlkQ29sdW1uTW9kZWwpID0+IHtcbiAgICAgIHJldHVybiAoXG4gICAgICAgIChjaGFuZ2UuaWQgIT09IHVuZGVmaW5lZCAmJiBjaGFuZ2UuaWQgPT09IGNvbHVtbi5pZCkgfHxcbiAgICAgICAgKGNoYW5nZS5maWVsZCAhPT0gdW5kZWZpbmVkICYmIGNoYW5nZS5maWVsZCA9PT0gY29sdW1uLmZpZWxkKVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgaWYgKGZvdW5kQ29sdW1uTW9kZWwpIHtcbiAgICAgIGZvdW5kQ29sdW1uTW9kZWwuaW5saW5lSGVscFBvcG92ZXIgPSBjaGFuZ2UudmFsdWU7XG4gICAgICB0aGlzLmNoYW5nZURldGVjdG9yLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyB1cGRhdGVDb2x1bW5EZXNjcmlwdGlvbihjaGFuZ2U6IFNreUdyaWRDb2x1bW5EZXNjcmlwdGlvbk1vZGVsQ2hhbmdlKSB7XG4gICAgY29uc3QgZm91bmRDb2x1bW5Nb2RlbCA9IHRoaXMuY29sdW1ucy5maW5kKChjb2x1bW46IFNreUdyaWRDb2x1bW5Nb2RlbCkgPT4ge1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgKGNoYW5nZS5pZCAhPT0gdW5kZWZpbmVkICYmIGNoYW5nZS5pZCA9PT0gY29sdW1uLmlkKSB8fFxuICAgICAgICAoY2hhbmdlLmZpZWxkICE9PSB1bmRlZmluZWQgJiYgY2hhbmdlLmZpZWxkID09PSBjb2x1bW4uZmllbGQpXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICBpZiAoZm91bmRDb2x1bW5Nb2RlbCkge1xuICAgICAgZm91bmRDb2x1bW5Nb2RlbC5kZXNjcmlwdGlvbiA9IGNoYW5nZS52YWx1ZTtcbiAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3IubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIG9uUmVzaXplQ29sdW1uU3RhcnQoZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICAvLyBJZiB0aGlzIHRhYmxlIGhhc24ndCBiZWVuIHJlc2l6ZWQsIGluaXRpYWxpemUgYWxsIHRoZSByZXNpemUgd2lkdGhzLlxuICAgIGlmICghdGhpcy5pc1Jlc2l6ZWQpIHtcbiAgICAgIHRoaXMuaW5pdENvbHVtbldpZHRocygpO1xuICAgICAgdGhpcy5pc1Jlc2l6ZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIHRoaXMuaW5pdGlhbGl6ZVJlc2l6ZUNvbHVtbihldmVudCk7XG5cbiAgICB0aGlzLmlzRHJhZ2dpbmdSZXNpemVIYW5kbGUgPSB0cnVlO1xuICAgIHRoaXMueFBvc1N0YXJ0ID0gZXZlbnQucGFnZVg7XG4gICAgdGhpcy5zaG93UmVzaXplQmFyID0gdHJ1ZTtcblxuICAgIC8vIFNob3cgdmlzdWFsIGluZGljYXRvciBvZiB3aGVyZSBtb3VzZSBpcyBkcmFnZ2luZyAocmVzaXplQmFyKS5cbiAgICB0aGlzLmNoYW5nZURldGVjdG9yLmRldGVjdENoYW5nZXMoKTtcbiAgICB0aGlzLnNldFJlc2l6ZUJhclBvc2l0aW9uKGV2ZW50LnBhZ2VYKTtcblxuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICBjb25zdCBtb3VzZU1vdmVFdmVudCA9IGZyb21FdmVudChkb2N1bWVudCwgJ21vdXNlbW92ZScpO1xuICAgIGNvbnN0IHRvdWNoTW92ZUV2ZW50ID0gZnJvbUV2ZW50KGRvY3VtZW50LCAndG91Y2htb3ZlJyk7XG5cbiAgICBtZXJnZShtb3VzZU1vdmVFdmVudCwgdG91Y2hNb3ZlRXZlbnQpXG4gICAgICAucGlwZShcbiAgICAgICAgdGFrZVdoaWxlKCgpID0+IHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5pc0RyYWdnaW5nUmVzaXplSGFuZGxlO1xuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgobW92ZUV2ZW50OiBhbnkpID0+IHtcbiAgICAgICAgdGhpcy5vblJlc2l6ZUhhbmRsZU1vdmUobW92ZUV2ZW50KTtcbiAgICAgIH0pO1xuXG4gICAgY29uc3QgbW91c2VVcEV2ZW50ID0gZnJvbUV2ZW50KGRvY3VtZW50LCAnbW91c2V1cCcpO1xuICAgIGNvbnN0IHRvdWNoRW5kRXZlbnQgPSBmcm9tRXZlbnQoZG9jdW1lbnQsICd0b3VjaGVuZCcpO1xuXG4gICAgbWVyZ2UobW91c2VVcEV2ZW50LCB0b3VjaEVuZEV2ZW50KVxuICAgICAgLnBpcGUoXG4gICAgICAgIHRha2VXaGlsZSgoKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuaXNEcmFnZ2luZ1Jlc2l6ZUhhbmRsZTtcbiAgICAgICAgfSlcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKGVuZEV2ZW50OiBhbnkpID0+IHtcbiAgICAgICAgdGhpcy5vblJlc2l6ZUhhbmRsZVJlbGVhc2UoZW5kRXZlbnQpO1xuICAgICAgfSk7XG4gIH1cblxuICBwdWJsaWMgb25LZXlkb3duUmVzaXplQ29sKGV2ZW50OiBLZXlib2FyZEV2ZW50KSB7XG4gICAgLy8gSWYgdGhpcyB0YWJsZSBoYXNuJ3QgYmVlbiByZXNpemVkLCBpbml0aWFsaXplIGFsbCB0aGUgcmVzaXplIHdpZHRocy5cbiAgICBpZiAoIXRoaXMuaXNSZXNpemVkKSB7XG4gICAgICB0aGlzLmluaXRDb2x1bW5XaWR0aHMoKTtcbiAgICAgIHRoaXMuaXNSZXNpemVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICB0aGlzLmluaXRpYWxpemVSZXNpemVDb2x1bW4oZXZlbnQpO1xuICB9XG5cbiAgcHVibGljIG9uSW5wdXRDaGFuZ2VSZXNpemVDb2woZXZlbnQ6IEV2ZW50KSB7XG4gICAgY29uc3QgaW5wdXQgPSBldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudDtcbiAgICBjb25zdCBuZXdWYWx1ZSA9IE51bWJlcihpbnB1dC52YWx1ZSk7XG4gICAgY29uc3QgZGVsdGFYID0gbmV3VmFsdWUgLSB0aGlzLnN0YXJ0Q29sdW1uV2lkdGg7XG4gICAgdGhpcy5yZXNpemVDb2x1bW5CeUluZGV4KHRoaXMuYWN0aXZlUmVzaXplQ29sdW1uSW5kZXgsIG5ld1ZhbHVlLCBkZWx0YVgpO1xuICAgIGNvbnN0IGxlZnQgPSBpbnB1dC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5sZWZ0O1xuICAgIHRoaXMuc2V0UmVzaXplQmFyUG9zaXRpb24obGVmdCk7XG4gIH1cblxuICBwdWJsaWMgb25SZXNpemVIYW5kbGVNb3ZlKGV2ZW50OiBNb3VzZUV2ZW50KSB7XG4gICAgY29uc3QgZGVsdGFYID0gZXZlbnQucGFnZVggLSB0aGlzLnhQb3NTdGFydDtcbiAgICBjb25zdCBuZXdDb2xXaWR0aCA9IHRoaXMuc3RhcnRDb2x1bW5XaWR0aCArIGRlbHRhWDtcblxuICAgIGlmIChuZXdDb2xXaWR0aCA8PSB0aGlzLm1pbkNvbFdpZHRoKSB7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBtYXggPSB0aGlzLmdldE1heFJhbmdlQnlJbmRleCh0aGlzLmFjdGl2ZVJlc2l6ZUNvbHVtbkluZGV4KTtcbiAgICBpZiAodGhpcy5maXQgPT09ICd3aWR0aCcgJiYgbmV3Q29sV2lkdGggPiBtYXgpIHtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuc2V0UmVzaXplQmFyUG9zaXRpb24oZXZlbnQucGFnZVgpO1xuICB9XG5cbiAgcHVibGljIG9uUmVzaXplSGFuZGxlQmx1cihldmVudDogRXZlbnQpIHtcbiAgICB0aGlzLnNob3dSZXNpemVCYXIgPSBmYWxzZTtcbiAgfVxuXG4gIHB1YmxpYyBvblJlc2l6ZUhhbmRsZUZvY3VzKGV2ZW50OiBLZXlib2FyZEV2ZW50KSB7XG4gICAgdGhpcy5zaG93UmVzaXplQmFyID0gdHJ1ZTtcbiAgICB0aGlzLmNoYW5nZURldGVjdG9yLmRldGVjdENoYW5nZXMoKTtcblxuICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudDtcbiAgICBjb25zdCBsZWZ0ID0gdGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmxlZnQ7XG4gICAgdGhpcy5zZXRSZXNpemVCYXJQb3NpdGlvbihsZWZ0KTtcbiAgfVxuXG4gIHB1YmxpYyBvblJlc2l6ZUhhbmRsZVJlbGVhc2UoZXZlbnQ6IE1vdXNlRXZlbnQpIHtcbiAgICB0aGlzLnNob3dSZXNpemVCYXIgPSBmYWxzZTtcbiAgICBjb25zdCBkZWx0YVggPSBldmVudC5wYWdlWCAtIHRoaXMueFBvc1N0YXJ0O1xuICAgIGNvbnN0IG5ld0NvbFdpZHRoID0gdGhpcy5zdGFydENvbHVtbldpZHRoICsgZGVsdGFYO1xuICAgIHRoaXMucmVzaXplQ29sdW1uQnlJbmRleCh0aGlzLmFjdGl2ZVJlc2l6ZUNvbHVtbkluZGV4LCBuZXdDb2xXaWR0aCwgZGVsdGFYKTtcbiAgICB0aGlzLmlzRHJhZ2dpbmdSZXNpemVIYW5kbGUgPSBmYWxzZTtcbiAgICB0aGlzLmFjdGl2ZVJlc2l6ZUNvbHVtbkluZGV4ID0gdW5kZWZpbmVkO1xuXG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgdGhpcy5jaGFuZ2VEZXRlY3Rvci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIHB1YmxpYyBvblJvd0NsaWNrKGV2ZW50OiBhbnksIHNlbGVjdGVkSXRlbTogTGlzdEl0ZW1Nb2RlbCkge1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgaWYgKHRoaXMuZW5hYmxlTXVsdGlzZWxlY3QpIHtcbiAgICAgIGlmIChcbiAgICAgICAgZXZlbnQudGFyZ2V0ID09PSBldmVudC5jdXJyZW50VGFyZ2V0IHx8XG4gICAgICAgICF0aGlzLmlzSW50ZXJhY3RpdmVFbGVtZW50KGV2ZW50KVxuICAgICAgKSB7XG4gICAgICAgIHNlbGVjdGVkSXRlbS5pc1NlbGVjdGVkID0gIXNlbGVjdGVkSXRlbS5pc1NlbGVjdGVkO1xuICAgICAgICB0aGlzLmNoYW5nZURldGVjdG9yLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICB0aGlzLmVtaXRTZWxlY3RlZFJvd3MoU2t5R3JpZFNlbGVjdGVkUm93c1NvdXJjZS5Sb3dDbGljayk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGlzUm93SGlnaGxpZ2h0ZWQoaWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLnJvd0hpZ2hsaWdodGVkSWQpIHtcbiAgICAgIHJldHVybiBpZCA9PT0gdGhpcy5yb3dIaWdobGlnaHRlZElkO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBwdWJsaWMgZ2V0Um93SGVpZ2h0KGluZGV4OiBudW1iZXIpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmdyaWRBZGFwdGVyLmdldFJvd0hlaWdodCh0aGlzLnRhYmxlRWxlbWVudFJlZiwgaW5kZXgpO1xuICB9XG5cbiAgcHVibGljIGNhbmNlbFJvd0RlbGV0ZShpZDogc3RyaW5nKSB7XG4gICAgdGhpcy5yb3dEZWxldGVDb25maWdzID0gdGhpcy5yb3dEZWxldGVDb25maWdzLmZpbHRlcihcbiAgICAgIChjb25maWcpID0+IGNvbmZpZy5pZCAhPT0gaWRcbiAgICApO1xuICAgIHRoaXMucm93RGVsZXRlQ2FuY2VsLmVtaXQoeyBpZDogaWQgfSk7XG5cbiAgICB0aGlzLmRlc3Ryb3lSb3dEZWxldGUoaWQpO1xuICB9XG5cbiAgcHVibGljIGNvbmZpcm1Sb3dEZWxldGUoaWQ6IHN0cmluZykge1xuICAgIHRoaXMucm93RGVsZXRlQ29uZmlncy5maW5kKChjb25maWcpID0+IGNvbmZpZy5pZCA9PT0gaWQpLnBlbmRpbmcgPSB0cnVlO1xuICAgIHRoaXMucm93RGVsZXRlQ29uZmlybS5lbWl0KHsgaWQ6IGlkIH0pO1xuICB9XG5cbiAgcHVibGljIGdldFJvd0RlbGV0ZUl0ZW0oaWQ6IHN0cmluZyk6IFNreUdyaWRSb3dEZWxldGVDb25maWcge1xuICAgIHJldHVybiB0aGlzLnJvd0RlbGV0ZUNvbmZpZ3MuZmluZCgocm93RGVsZXRlKSA9PiByb3dEZWxldGUuaWQgPT09IGlkKTtcbiAgfVxuXG4gIC8vIFByZXZlbnQgdG91Y2ggZGV2aWNlcyBmcm9tIGluYWR2ZXJ0ZW50bHkgc2Nyb2xsaW5nIGdyaWQgd2hpbGUgZHJhZ2dpbmcgY29sdW1ucy5cbiAgcHVibGljIG9uVG91Y2hNb3ZlKGV2ZW50OiBhbnkpOiB2b2lkIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICB9XG5cbiAgcHVibGljIG9uVG9wU2Nyb2xsKGV2ZW50OiBhbnkpOiB2b2lkIHtcbiAgICAvKiBzYW5pdHkgY2hlY2sgKi9cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgIGlmICh0aGlzLnRhYmxlQ29udGFpbmVyRWxlbWVudFJlZikge1xuICAgICAgaWYgKHRoaXMuc2Nyb2xsVHJpZ2dlcmVkKSB7XG4gICAgICAgIHRoaXMuc2Nyb2xsVHJpZ2dlcmVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMudGFibGVDb250YWluZXJFbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuc2Nyb2xsTGVmdCA9XG4gICAgICAgICAgdGhpcy50b3BTY3JvbGxDb250YWluZXJFbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuc2Nyb2xsTGVmdDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2Nyb2xsVHJpZ2dlcmVkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwdWJsaWMgb25HcmlkU2Nyb2xsKGV2ZW50OiBhbnkpOiB2b2lkIHtcbiAgICAvKiBzYW5pdHkgY2hlY2sgKi9cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgIGlmICh0aGlzLnRvcFNjcm9sbENvbnRhaW5lckVsZW1lbnRSZWYpIHtcbiAgICAgIGlmICh0aGlzLnNjcm9sbFRyaWdnZXJlZCkge1xuICAgICAgICB0aGlzLnNjcm9sbFRyaWdnZXJlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnRvcFNjcm9sbENvbnRhaW5lckVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5zY3JvbGxMZWZ0ID1cbiAgICAgICAgICB0aGlzLnRhYmxlQ29udGFpbmVyRWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnNjcm9sbExlZnQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnNjcm9sbFRyaWdnZXJlZCA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjaGVja1VzZXJDb2x1bW5XaWR0aHNGb3JTY3JvbGwoKTogdm9pZCB7XG4gICAgaWYgKFxuICAgICAgIXRoaXMuc2hvd1RvcFNjcm9sbCAmJlxuICAgICAgdGhpcy5jb2x1bW5FbGVtZW50UmVmcyAmJlxuICAgICAgdGhpcy5jb2x1bW5FbGVtZW50UmVmcy5sZW5ndGggPiAwXG4gICAgKSB7XG4gICAgICBsZXQgY29sdW1uc1dpZHRoVG90YWwgPSAwO1xuICAgICAgY29uc3Qgd2luZG93U2l6ZSA9IHRoaXMuc2t5V2luZG93Lm5hdGl2ZVdpbmRvdy5pbm5lcldpZHRoO1xuICAgICAgdGhpcy5jb2x1bW5FbGVtZW50UmVmcy5mb3JFYWNoKChjb2wpID0+IHtcbiAgICAgICAgaWYgKCF0aGlzLnNob3dUb3BTY3JvbGwpIHtcbiAgICAgICAgICBjb25zdCBjb21wdXRlZFdpZHRoID0gcGFyc2VGbG9hdChcbiAgICAgICAgICAgIHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGNvbC5uYXRpdmVFbGVtZW50KS53aWR0aFxuICAgICAgICAgICk7XG4gICAgICAgICAgY29uc3Qgb2Zmc2V0V2lkdGggPSBjb2wubmF0aXZlRWxlbWVudC5vZmZzZXRXaWR0aDtcbiAgICAgICAgICBjb25zdCB3aWR0aCA9IE1hdGgubWF4KFxuICAgICAgICAgICAgY29tcHV0ZWRXaWR0aCB8fCBvZmZzZXRXaWR0aCxcbiAgICAgICAgICAgIHRoaXMubWluQ29sV2lkdGhcbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbHVtbnNXaWR0aFRvdGFsID0gY29sdW1uc1dpZHRoVG90YWwgKyB3aWR0aDtcbiAgICAgICAgICBpZiAoY29sdW1uc1dpZHRoVG90YWwgPiB3aW5kb3dTaXplKSB7XG4gICAgICAgICAgICB0aGlzLnNob3dUb3BTY3JvbGwgPSB0cnVlO1xuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3IubWFya0ZvckNoZWNrKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbXVsdGlzZWxlY3RTZWxlY3RBbGwoKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLml0ZW1zLmxlbmd0aDsgaSsrKSB7XG4gICAgICB0aGlzLml0ZW1zW2ldLmlzU2VsZWN0ZWQgPSB0cnVlO1xuICAgIH1cbiAgICB0aGlzLmNoYW5nZURldGVjdG9yLm1hcmtGb3JDaGVjaygpO1xuICAgIHRoaXMuZW1pdFNlbGVjdGVkUm93cyhTa3lHcmlkU2VsZWN0ZWRSb3dzU291cmNlLlNlbGVjdEFsbCk7XG4gIH1cblxuICBwcml2YXRlIG11bHRpc2VsZWN0Q2xlYXJBbGwoKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLml0ZW1zLmxlbmd0aDsgaSsrKSB7XG4gICAgICB0aGlzLml0ZW1zW2ldLmlzU2VsZWN0ZWQgPSBmYWxzZTtcbiAgICB9XG4gICAgdGhpcy5jaGFuZ2VEZXRlY3Rvci5tYXJrRm9yQ2hlY2soKTtcbiAgICB0aGlzLmVtaXRTZWxlY3RlZFJvd3MoU2t5R3JpZFNlbGVjdGVkUm93c1NvdXJjZS5DbGVhckFsbCk7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZUluY29taW5nTWVzc2FnZXMobWVzc2FnZTogU2t5R3JpZE1lc3NhZ2UpIHtcbiAgICBzd2l0Y2ggKG1lc3NhZ2UudHlwZSkge1xuICAgICAgY2FzZSBTa3lHcmlkTWVzc2FnZVR5cGUuU2VsZWN0QWxsOlxuICAgICAgICB0aGlzLm11bHRpc2VsZWN0U2VsZWN0QWxsKCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIFNreUdyaWRNZXNzYWdlVHlwZS5DbGVhckFsbDpcbiAgICAgICAgdGhpcy5tdWx0aXNlbGVjdENsZWFyQWxsKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBTa3lHcmlkTWVzc2FnZVR5cGUuUHJvbXB0RGVsZXRlUm93OlxuICAgICAgICAvKiBzYW5pdHkgY2hlY2sgKi9cbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICAgICAgaWYgKG1lc3NhZ2UuZGF0YSAmJiBtZXNzYWdlLmRhdGEucHJvbXB0RGVsZXRlUm93KSB7XG4gICAgICAgICAgY29uc3QgZXhpc3RpbmdDb25maWcgPSB0aGlzLnJvd0RlbGV0ZUNvbmZpZ3MuZmluZChcbiAgICAgICAgICAgIChjb25maWcpID0+IGNvbmZpZy5pZCA9PT0gbWVzc2FnZS5kYXRhLnByb21wdERlbGV0ZVJvdy5pZFxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKGV4aXN0aW5nQ29uZmlnKSB7XG4gICAgICAgICAgICBleGlzdGluZ0NvbmZpZy5wZW5kaW5nID0gZmFsc2U7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMucm93RGVsZXRlQ29uZmlncy5wdXNoKHtcbiAgICAgICAgICAgICAgaWQ6IG1lc3NhZ2UuZGF0YS5wcm9tcHREZWxldGVSb3cuaWQsXG4gICAgICAgICAgICAgIHBlbmRpbmc6IGZhbHNlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBjb25zdCBvdmVybGF5ID0gdGhpcy5vdmVybGF5U2VydmljZS5jcmVhdGUoe1xuICAgICAgICAgICAgICBlbmFibGVTY3JvbGw6IHRydWUsXG4gICAgICAgICAgICAgIHNob3dCYWNrZHJvcDogZmFsc2UsXG4gICAgICAgICAgICAgIGNsb3NlT25OYXZpZ2F0aW9uOiB0cnVlLFxuICAgICAgICAgICAgICBlbmFibGVDbG9zZTogZmFsc2UsXG4gICAgICAgICAgICAgIGVuYWJsZVBvaW50ZXJFdmVudHM6IHRydWUsXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgb3ZlcmxheS5hdHRhY2hUZW1wbGF0ZSh0aGlzLmlubGluZURlbGV0ZVRlbXBsYXRlUmVmLCB7XG4gICAgICAgICAgICAgICRpbXBsaWNpdDogdGhpcy5kYXRhLmZpbmQoXG4gICAgICAgICAgICAgICAgKGl0ZW0pID0+IGl0ZW0uaWQgPT09IG1lc3NhZ2UuZGF0YS5wcm9tcHREZWxldGVSb3cuaWRcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIFdlIGFyZSBtYW51YWxseSBzZXR0aW5nIHRoZSB6LWluZGV4IGhlcmUgYmVjYXVzZSBvdmVybGF5cyB3aWxsIGFsd2F5cyBiZSBvbiB0b3Agb2ZcbiAgICAgICAgICAgICAqIHRoZSBvbW5pYmFyLiBUaGlzIG1hbnVhbCBzZXR0aW5nIGlzIDEgbGVzcyB0aGFuIHRoZSBvbW5pYmFyJ3Mgei1pbmRleCBvZiAxMDAwLiBXZVxuICAgICAgICAgICAgICogZGlzY3Vzc2VkIGNoYW5naW5nIHRoZSBvdmVybGF5IHNlcnZpY2UgdG8gYWxsb3cgZm9yIHRoaXMgYnV0IGRlY2lkZWQgYWdhaW5zdCB0aGF0XG4gICAgICAgICAgICAgKiBjaGFuZ2UgYXQgdGhpcyB0aW1lIGR1ZSB0byBpdHMgbmljaGUgbmF0dXJlLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBvdmVybGF5LmNvbXBvbmVudFJlZi5pbnN0YW5jZS56SW5kZXggPSAnOTk5JztcblxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IGlubGluZURlbGV0ZVJlZiA9IHRoaXMuaW5saW5lRGVsZXRlUmVmc1xuICAgICAgICAgICAgICAgIC50b0FycmF5KClcbiAgICAgICAgICAgICAgICAuZmluZCgoZWxSZWYpID0+IHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgICAgIGVsUmVmLm5hdGl2ZUVsZW1lbnQuaWQgPT09XG4gICAgICAgICAgICAgICAgICAgICdyb3ctZGVsZXRlLXJlZi0nICsgbWVzc2FnZS5kYXRhLnByb21wdERlbGV0ZVJvdy5pZFxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgY29uc3QgYWZmaXhlciA9IHRoaXMuYWZmaXhTZXJ2aWNlLmNyZWF0ZUFmZml4ZXIoaW5saW5lRGVsZXRlUmVmKTtcblxuICAgICAgICAgICAgICBjb25zdCByb3dFbGVtZW50OiBIVE1MRWxlbWVudCA9XG4gICAgICAgICAgICAgICAgdGhpcy50YWJsZUVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKFxuICAgICAgICAgICAgICAgICAgJ1tza3ktY21wLWlkPVwiJyArIG1lc3NhZ2UuZGF0YS5wcm9tcHREZWxldGVSb3cuaWQgKyAnXCJdJ1xuICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgYWZmaXhlci5hZmZpeFRvKHJvd0VsZW1lbnQsIHtcbiAgICAgICAgICAgICAgICBhdXRvRml0Q29udGV4dDogU2t5QWZmaXhBdXRvRml0Q29udGV4dC5WaWV3cG9ydCxcbiAgICAgICAgICAgICAgICBpc1N0aWNreTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBwbGFjZW1lbnQ6ICdhYm92ZScsXG4gICAgICAgICAgICAgICAgdmVydGljYWxBbGlnbm1lbnQ6ICd0b3AnLFxuICAgICAgICAgICAgICAgIGhvcml6b250YWxBbGlnbm1lbnQ6ICdsZWZ0JyxcbiAgICAgICAgICAgICAgICBlbmFibGVBdXRvRml0OiBmYWxzZSxcbiAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgdGhpcy5yb3dEZWxldGVDb250ZW50c1ttZXNzYWdlLmRhdGEucHJvbXB0RGVsZXRlUm93LmlkXSA9IHtcbiAgICAgICAgICAgICAgICBhZmZpeGVyOiBhZmZpeGVyLFxuICAgICAgICAgICAgICAgIG92ZXJsYXk6IG92ZXJsYXksXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFNreUdyaWRNZXNzYWdlVHlwZS5BYm9ydERlbGV0ZVJvdzpcbiAgICAgICAgLyogc2FuaXR5IGNoZWNrICovXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgICAgIGlmIChtZXNzYWdlLmRhdGEgJiYgbWVzc2FnZS5kYXRhLmFib3J0RGVsZXRlUm93KSB7XG4gICAgICAgICAgdGhpcy5yb3dEZWxldGVDb25maWdzID0gdGhpcy5yb3dEZWxldGVDb25maWdzLmZpbHRlcihcbiAgICAgICAgICAgIChjb25maWcpID0+IGNvbmZpZy5pZCAhPT0gbWVzc2FnZS5kYXRhLmFib3J0RGVsZXRlUm93LmlkXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIHRoaXMuZGVzdHJveVJvd0RlbGV0ZShtZXNzYWdlLmRhdGEuYWJvcnREZWxldGVSb3cuaWQpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICB0aGlzLmNoYW5nZURldGVjdG9yLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgcHJpdmF0ZSBvbkhlYWRlckRyb3AobmV3Q29sdW1uSWRzOiBBcnJheTxzdHJpbmc+KSB7XG4gICAgLy8gdXBkYXRlIHNlbGVjdGVkIGNvbHVtbklkc1xuICAgIHRoaXMuc2VsZWN0ZWRDb2x1bW5JZHNTZXQgPSB0cnVlO1xuICAgIHRoaXMuc2VsZWN0ZWRDb2x1bW5JZHMgPSBuZXdDb2x1bW5JZHM7XG5cbiAgICAvLyBtYXJrIGZvciBjaGVjayBiZWNhdXNlIHdlIGFyZSB1c2luZyBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5vblB1c2hcbiAgICB0aGlzLmNoYW5nZURldGVjdG9yLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXREaXNwbGF5ZWRDb2x1bW5zKHJlc3BlY3RIaWRkZW46IGJvb2xlYW4gPSBmYWxzZSkge1xuICAgIC8qIHNhbml0eSBjaGVjayAqL1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgaWYgKHRoaXMuY29sdW1ucykge1xuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRDb2x1bW5JZHMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAvLyBzZXR1cCBkaXNwbGF5ZWQgY29sdW1uc1xuICAgICAgICB0aGlzLmRpc3BsYXllZENvbHVtbnMgPSB0aGlzLnNlbGVjdGVkQ29sdW1uSWRzXG4gICAgICAgICAgLmZpbHRlcigoY29sdW1uSWQpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbHVtbnMuZmluZCgoY29sdW1uKSA9PiBjb2x1bW4uaWQgPT09IGNvbHVtbklkKTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5tYXAoKGNvbHVtbklkKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb2x1bW5zLmZpbHRlcigoY29sdW1uKSA9PiBjb2x1bW4uaWQgPT09IGNvbHVtbklkKVswXTtcbiAgICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAocmVzcGVjdEhpZGRlbikge1xuICAgICAgICB0aGlzLmRpc3BsYXllZENvbHVtbnMgPSB0aGlzLmNvbHVtbnMuZmlsdGVyKChjb2x1bW4pID0+IHtcbiAgICAgICAgICByZXR1cm4gIWNvbHVtbi5oaWRkZW47XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5kaXNwbGF5ZWRDb2x1bW5zID0gdGhpcy5jb2x1bW5zO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdHJhbnNmb3JtRGF0YSgpIHtcbiAgICAvLyBUcmFuc2Zvcm0gZGF0YSBpbnRvIG9iamVjdCB3aXRoIGlkIGFuZCBkYXRhIHByb3BlcnRpZXNcbiAgICBpZiAoXG4gICAgICB0aGlzLmRhdGEgJiZcbiAgICAgIHRoaXMuZGF0YS5sZW5ndGggPiAwICYmXG4gICAgICB0aGlzLmRhdGFbMF0uaWQgJiZcbiAgICAgICF0aGlzLmRhdGFbMF0uZGF0YVxuICAgICkge1xuICAgICAgaWYgKHRoaXMubXVsdGlzZWxlY3RSb3dJZCkge1xuICAgICAgICB0aGlzLml0ZW1zID0gdGhpcy5nZXRHcmlkRGF0YVdpdGhTZWxlY3RlZFJvd3MoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuaXRlbXMgPSB0aGlzLmRhdGEubWFwKChpdGVtKSA9PiBuZXcgTGlzdEl0ZW1Nb2RlbChpdGVtLmlkLCBpdGVtKSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaXRlbXMgPSB0aGlzLmRhdGE7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRHcmlkRGF0YVdpdGhTZWxlY3RlZFJvd3MoKSB7XG4gICAgY29uc3Qgc2VsZWN0ZWRSb3dzID0gdGhpcy5nZXRTZWxlY3RlZFJvd3MoKTtcbiAgICByZXR1cm4gdGhpcy5kYXRhLm1hcCgoaXRlbSkgPT4ge1xuICAgICAgbGV0IGNoZWNrZWQ7XG4gICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGl0ZW0sIHRoaXMubXVsdGlzZWxlY3RSb3dJZCkpIHtcbiAgICAgICAgY2hlY2tlZCA9IHNlbGVjdGVkUm93cy5pbmRleE9mKGl0ZW1bdGhpcy5tdWx0aXNlbGVjdFJvd0lkXSkgPiAtMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNoZWNrZWQgPSBzZWxlY3RlZFJvd3MuaW5kZXhPZihpdGVtLmlkKSA+IC0xO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBMaXN0SXRlbU1vZGVsKGl0ZW0uaWQsIGl0ZW0sIGNoZWNrZWQpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhcHBseVNlbGVjdGVkUm93cygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pdGVtcyAmJiB0aGlzLml0ZW1zLmxlbmd0aCA+IDAgJiYgdGhpcy5zZWxlY3RlZFJvd0lkcykge1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLml0ZW1zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRoaXMuaXRlbXNbaV0uaXNTZWxlY3RlZCA9XG4gICAgICAgICAgdGhpcy5zZWxlY3RlZFJvd0lkcy5pbmRleE9mKHRoaXMuaXRlbXNbaV0uaWQpID4gLTE7XG4gICAgICB9XG4gICAgICB0aGlzLmNoYW5nZURldGVjdG9yLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2V0U29ydEhlYWRlcnMoKSB7XG4gICAgdGhpcy5jdXJyZW50U29ydEZpZWxkLm5leHQoXG4gICAgICB0aGlzLnNvcnRGaWVsZCB8fCB7IGZpZWxkU2VsZWN0b3I6ICcnLCBkZXNjZW5kaW5nOiBmYWxzZSB9XG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q29sdW1uc0Zyb21Db21wb25lbnQoKSB7XG4gICAgdGhpcy5jb2x1bW5zID0gdGhpcy5jb2x1bW5Db21wb25lbnRzLm1hcCgoY29sdW1uQ29tcG9uZW50KSA9PiB7XG4gICAgICByZXR1cm4gbmV3IFNreUdyaWRDb2x1bW5Nb2RlbChjb2x1bW5Db21wb25lbnQudGVtcGxhdGUsIGNvbHVtbkNvbXBvbmVudCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZUNvbHVtbnMoKSB7XG4gICAgdGhpcy5nZXRDb2x1bW5zRnJvbUNvbXBvbmVudCgpO1xuXG4gICAgLy8gVGhpcyBzZXQgdGltZW91dCBpcyBuZWNlc3NhcnkgdG8gZW5zdXJlIHRoZSBjb2x1bW5zIGhhdmUgcmVuZGVyZWQgaW4gdGhlIGdyaWRcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuY2hlY2tVc2VyQ29sdW1uV2lkdGhzRm9yU2Nyb2xsKCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHJlc2l6ZUNvbHVtbkJ5SW5kZXgoXG4gICAgY29sdW1uSW5kZXg6IHN0cmluZyxcbiAgICBuZXdDb2xXaWR0aDogbnVtYmVyLFxuICAgIGRlbHRhWDogbnVtYmVyXG4gICkge1xuICAgIGNvbnN0IGNvbHVtbiA9IHRoaXMuZ2V0Q29sdW1uTW9kZWxCeUluZGV4KGNvbHVtbkluZGV4KTtcblxuICAgIC8vIFByZXZlbnQgYWNjaWRlbnRhbCBzaHJpbmthZ2UgYmVsb3cgbWluaW11bSB3aWR0aC5cbiAgICBpZiAobmV3Q29sV2lkdGggPD0gdGhpcy5taW5Db2xXaWR0aCkge1xuICAgICAgZGVsdGFYID0gZGVsdGFYICsgdGhpcy5taW5Db2xXaWR0aCAtIG5ld0NvbFdpZHRoO1xuICAgICAgbmV3Q29sV2lkdGggPSB0aGlzLm1pbkNvbFdpZHRoO1xuICAgIH1cblxuICAgIC8vIGZpdD13aWR0aCBhZGRzL3JlbW92ZXMgd2lkdGggZnJvbSB0aGUgbGFzdCBjb2x1bW5cbiAgICAvLyBmaXQ9c2Nyb2xsIGFkZHMvcmVtb3ZlcyB3aWR0aCBmcm9tIHRoZSB0YWJsZVxuICAgIGlmICh0aGlzLmZpdCA9PT0gJ3dpZHRoJykge1xuICAgICAgY29uc3QgbGFzdENvbHVtbiA9IHRoaXMuZ2V0TGFzdERpc3BsYXllZENvbHVtbigpO1xuXG4gICAgICAvLyBQcmV2ZW50IGFjY2lkZW50YWwgZ3Jvd3RoIHRoYXQgd291bGQgYnVtcCBsYXN0IGNvbHVtbiBvZmYgc2NyZWVuLlxuICAgICAgY29uc3QgbWF4ID0gdGhpcy5nZXRNYXhSYW5nZUJ5SW5kZXgoY29sdW1uSW5kZXgpO1xuICAgICAgaWYgKG5ld0NvbFdpZHRoID4gbWF4KSB7XG4gICAgICAgIG5ld0NvbFdpZHRoID0gbWF4O1xuICAgICAgICBkZWx0YVggPSBtYXggLSB0aGlzLnN0YXJ0Q29sdW1uV2lkdGg7XG4gICAgICB9XG4gICAgICBjb2x1bW4ud2lkdGggPSBuZXdDb2xXaWR0aDtcbiAgICAgIGxhc3RDb2x1bW4ud2lkdGggPSBsYXN0Q29sdW1uLndpZHRoIC0gZGVsdGFYO1xuICAgICAgdGhpcy51cGRhdGVNYXhSYW5nZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmdyaWRBZGFwdGVyLnNldFN0eWxlKFxuICAgICAgICB0aGlzLnRhYmxlRWxlbWVudFJlZixcbiAgICAgICAgJ3dpZHRoJyxcbiAgICAgICAgYCR7dGhpcy50YWJsZVdpZHRoICsgZGVsdGFYfXB4YFxuICAgICAgKTtcbiAgICAgIGNvbHVtbi53aWR0aCA9IG5ld0NvbFdpZHRoO1xuICAgIH1cblxuICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3IuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIHRoaXMuY29sdW1uV2lkdGhDaGFuZ2UuZW1pdCh0aGlzLmdldENvbHVtbldpZHRoTW9kZWxDaGFuZ2UoKSk7XG4gIH1cblxuICBwcml2YXRlIGluaXRDb2x1bW5XaWR0aHMoKSB7XG4gICAgLy8gRXN0YWJsaXNoIHRhYmxlIHdpZHRoLlxuICAgIHRoaXMuc2hvd1RvcFNjcm9sbCA9IHRydWU7XG5cbiAgICAvLyBTZXQgY29sdW1uIHdpZHRocyBiYXNlZCBvbiB0aGUgd2lkdGggaW5pdGlhbGx5IGdpdmVuIGJ5IHRoZSBicm93c2VyLlxuICAgIC8vIGNvbXB1dGVkV2lkdGggcHJldmVudHMgYWNjaWRlbnRhbCBvdmVyZmxvdyBmb3IgYnJvd3NlcnMgd2l0aCBzdWItcGl4ZWwgd2lkdGhzLlxuICAgIHRoaXMuY29sdW1uRWxlbWVudFJlZnMuZm9yRWFjaCgoY29sLCBpbmRleCkgPT4ge1xuICAgICAgY29uc3QgY29tcHV0ZWRXaWR0aCA9IHBhcnNlRmxvYXQoXG4gICAgICAgIHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGNvbC5uYXRpdmVFbGVtZW50KS53aWR0aFxuICAgICAgKTtcbiAgICAgIGNvbnN0IG9mZnNldFdpZHRoID0gY29sLm5hdGl2ZUVsZW1lbnQub2Zmc2V0V2lkdGg7XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgdGhpcy5nZXRDb2x1bW5Nb2RlbEJ5SW5kZXgoaW5kZXgpLndpZHRoID0gTWF0aC5tYXgoXG4gICAgICAgIGNvbXB1dGVkV2lkdGggfHwgb2Zmc2V0V2lkdGgsXG4gICAgICAgIHRoaXMubWluQ29sV2lkdGhcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICAvLyAnc2Nyb2xsJyB0YWJsZXMgc2hvdWxkIGJlIGFsbG93ZWQgdG8gZXhwYW5kIG91dHNpZGUgb2YgdGhlaXIgY29uc3RyYWludHMuXG4gICAgaWYgKHRoaXMuZml0ID09PSAnc2Nyb2xsJykge1xuICAgICAgdGhpcy5ncmlkQWRhcHRlci5zZXRTdHlsZSh0aGlzLnRhYmxlRWxlbWVudFJlZiwgJ21pbi13aWR0aCcsICdhdXRvJyk7XG4gICAgfVxuXG4gICAgLy8gVXBkYXRlIG1heCBsaW1pdHMgZm9yIGlucHV0IHJhbmdlcy5cbiAgICBpZiAodGhpcy5maXQgPT09ICd3aWR0aCcpIHtcbiAgICAgIHRoaXMudXBkYXRlTWF4UmFuZ2UoKTtcbiAgICB9XG5cbiAgICB0aGlzLmNoYW5nZURldGVjdG9yLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIHByaXZhdGUgdHJhbnNmZXJDb2x1bW5XaWR0aHMoXG4gICAgb2xkQ29sdW1uczogU2t5R3JpZENvbHVtbk1vZGVsW10sXG4gICAgbmV3Q29sdW1uczogU2t5R3JpZENvbHVtbk1vZGVsW11cbiAgKSB7XG4gICAgLyogc2FuaXR5IGNoZWNrICovXG4gICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICBpZiAob2xkQ29sdW1ucyAmJiBuZXdDb2x1bW5zKSB7XG4gICAgICBmb3IgKGNvbnN0IG9sZENvbHVtbiBvZiBvbGRDb2x1bW5zKSB7XG4gICAgICAgIGlmIChvbGRDb2x1bW4ud2lkdGgpIHtcbiAgICAgICAgICBjb25zdCBtYXRjaGluZ0NvbHVtbiA9IG5ld0NvbHVtbnMuZmluZChcbiAgICAgICAgICAgIChuZXdDb2x1bW4pID0+IG9sZENvbHVtbi5pZCA9PT0gbmV3Q29sdW1uLmlkXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAobWF0Y2hpbmdDb2x1bW4gJiYgIW1hdGNoaW5nQ29sdW1uLndpZHRoKSB7XG4gICAgICAgICAgICBtYXRjaGluZ0NvbHVtbi53aWR0aCA9IG9sZENvbHVtbi53aWR0aDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5jaGFuZ2VEZXRlY3Rvci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q29sdW1uV2lkdGhNb2RlbENoYW5nZSgpIHtcbiAgICBjb25zdCBjb2x1bW5XaWR0aE1vZGVsQ2hhbmdlID0gbmV3IEFycmF5PFNreUdyaWRDb2x1bW5XaWR0aE1vZGVsQ2hhbmdlPigpO1xuICAgIHRoaXMuY29sdW1ucy5mb3JFYWNoKChjb2x1bW4pID0+IHtcbiAgICAgIGNvbHVtbldpZHRoTW9kZWxDaGFuZ2UucHVzaCh7XG4gICAgICAgIGlkOiBjb2x1bW4uaWQsXG4gICAgICAgIGZpZWxkOiBjb2x1bW4uZmllbGQsXG4gICAgICAgIHdpZHRoOiBjb2x1bW4ud2lkdGgsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgICByZXR1cm4gY29sdW1uV2lkdGhNb2RlbENoYW5nZTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlTWF4UmFuZ2UoKSB7XG4gICAgY29uc3QgbGVmdG92ZXJXaWR0aCA9XG4gICAgICB0aGlzLmdldExhc3REaXNwbGF5ZWRDb2x1bW4oKS53aWR0aCAtIHRoaXMubWluQ29sV2lkdGg7XG4gICAgdGhpcy5kaXNwbGF5ZWRDb2x1bW5zLmZvckVhY2goKGNvbHVtbiwgaW5kZXgpID0+IHtcbiAgICAgIGNvbnN0IG5ld01heFJhbmdlID0gY29sdW1uLndpZHRoICsgbGVmdG92ZXJXaWR0aDtcbiAgICAgIGNvbnN0IHJhbmdlSW5wdXQgPSB0aGlzLmdldFJhbmdlSW5wdXRCeUluZGV4KGluZGV4KTtcbiAgICAgIHJhbmdlSW5wdXQubmF0aXZlRWxlbWVudC5tYXggPSBuZXdNYXhSYW5nZTtcbiAgICAgIHJhbmdlSW5wdXQubmF0aXZlRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2FyaWEtdmFsdWVtYXgnLCBuZXdNYXhSYW5nZSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGluaXRpYWxpemVSZXNpemVDb2x1bW4oZXZlbnQ6IGFueSkge1xuICAgIGNvbnN0IGNsaWNrVGFyZ2V0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xuICAgIHRoaXMuYWN0aXZlUmVzaXplQ29sdW1uSW5kZXggPSBjbGlja1RhcmdldC5nZXRBdHRyaWJ1dGUoJ3NreS1jbXAtaW5kZXgnKTtcbiAgICBjb25zdCBjb2x1bW4gPSB0aGlzLmdldENvbHVtbk1vZGVsQnlJbmRleCh0aGlzLmFjdGl2ZVJlc2l6ZUNvbHVtbkluZGV4KTtcbiAgICB0aGlzLnN0YXJ0Q29sdW1uV2lkdGggPSBjb2x1bW4ud2lkdGg7XG4gIH1cblxuICBwcml2YXRlIHJlc2V0VGFibGVXaWR0aCgpIHtcbiAgICB0aGlzLnNreVdpbmRvdy5uYXRpdmVXaW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmdyaWRBZGFwdGVyLnNldFN0eWxlKHRoaXMudGFibGVFbGVtZW50UmVmLCAnd2lkdGgnLCBgYXV0b2ApO1xuICAgICAgdGhpcy5jaGFuZ2VEZXRlY3Rvci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICB0aGlzLmdyaWRBZGFwdGVyLnNldFN0eWxlKFxuICAgICAgICB0aGlzLnRhYmxlRWxlbWVudFJlZixcbiAgICAgICAgJ3dpZHRoJyxcbiAgICAgICAgYCR7dGhpcy50YWJsZVdpZHRofXB4YFxuICAgICAgKTtcbiAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3IuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRSYW5nZUlucHV0QnlJbmRleChpbmRleDogc3RyaW5nIHwgbnVtYmVyKSB7XG4gICAgcmV0dXJuIHRoaXMuY29sdW1uUmFuZ2VJbnB1dEVsZW1lbnRSZWZzLmZpbmQoXG4gICAgICAoaW5wdXQpID0+XG4gICAgICAgIGlucHV0Lm5hdGl2ZUVsZW1lbnQuZ2V0QXR0cmlidXRlKCdza3ktY21wLWluZGV4JykgPT09IGluZGV4LnRvU3RyaW5nKClcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRDb2x1bW5Nb2RlbEJ5SW5kZXgoaW5kZXg6IHN0cmluZyB8IG51bWJlcikge1xuICAgIHJldHVybiB0aGlzLmRpc3BsYXllZENvbHVtbnNbTnVtYmVyKGluZGV4KV07XG4gIH1cblxuICBwcml2YXRlIGdldE1heFJhbmdlQnlJbmRleChpbmRleDogc3RyaW5nKSB7XG4gICAgY29uc3QgY29sdW1uRWxlbWVudFJlZiA9IHRoaXMuY29sdW1uRWxlbWVudFJlZnMuZmluZChcbiAgICAgICh0aCkgPT4gdGgubmF0aXZlRWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3NreS1jbXAtaW5kZXgnKSA9PT0gaW5kZXhcbiAgICApO1xuICAgIGNvbnN0IHJhbmdlSW5wdXQgPSBjb2x1bW5FbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICAgICcuc2t5LWdyaWQtY29sdW1uLWlucHV0LWFyaWEtb25seSdcbiAgICApO1xuICAgIHJldHVybiBOdW1iZXIocmFuZ2VJbnB1dC5tYXgpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRMYXN0RGlzcGxheWVkQ29sdW1uKCkge1xuICAgIHJldHVybiB0aGlzLmdldENvbHVtbk1vZGVsQnlJbmRleCh0aGlzLmRpc3BsYXllZENvbHVtbnMubGVuZ3RoIC0gMSk7XG4gIH1cblxuICBwcml2YXRlIGFkZERlbGltZXRlcih0ZXh0OiBzdHJpbmdbXSwgZGVsaW1pdGVyOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGV4dC5maWx0ZXIoKHZhbCkgPT4gdmFsKS5qb2luKGRlbGltaXRlcik7XG4gIH1cblxuICBwcml2YXRlIGRlc3Ryb3lSb3dEZWxldGUoaWQ6IHN0cmluZykge1xuICAgIGNvbnN0IHJvd0RlbGV0ZUNvbnRlbnRzID0gdGhpcy5yb3dEZWxldGVDb250ZW50c1tpZF07XG4gICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICBpZiAocm93RGVsZXRlQ29udGVudHMpIHtcbiAgICAgIHJvd0RlbGV0ZUNvbnRlbnRzLmFmZml4ZXIuZGVzdHJveSgpO1xuICAgICAgdGhpcy5vdmVybGF5U2VydmljZS5jbG9zZShyb3dEZWxldGVDb250ZW50cy5vdmVybGF5KTtcbiAgICAgIGRlbGV0ZSB0aGlzLnJvd0RlbGV0ZUNvbnRlbnRzW2lkXTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGVtaXRTZWxlY3RlZFJvd3Moc291cmNlOiBTa3lHcmlkU2VsZWN0ZWRSb3dzU291cmNlKSB7XG4gICAgY29uc3Qgc2VsZWN0ZWRSb3dzOiBTa3lHcmlkU2VsZWN0ZWRSb3dzTW9kZWxDaGFuZ2UgPSB7XG4gICAgICBzZWxlY3RlZFJvd0lkczogdGhpcy5nZXRTZWxlY3RlZFJvd3MoKSxcbiAgICAgIHNvdXJjZTogc291cmNlLFxuICAgIH07XG4gICAgdGhpcy5tdWx0aXNlbGVjdFNlbGVjdGlvbkNoYW5nZS5lbWl0KHNlbGVjdGVkUm93cyk7XG4gIH1cblxuICBwcml2YXRlIGdldFNlbGVjdGVkUm93cygpIHtcbiAgICByZXR1cm4gdGhpcy5pdGVtc1xuICAgICAgLmZpbHRlcigoaXRlbSkgPT4ge1xuICAgICAgICByZXR1cm4gaXRlbS5pc1NlbGVjdGVkO1xuICAgICAgfSlcbiAgICAgIC5tYXAoKGl0ZW0pID0+IHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChpdGVtLmRhdGEsIHRoaXMubXVsdGlzZWxlY3RSb3dJZClcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuIGl0ZW0uZGF0YVt0aGlzLm11bHRpc2VsZWN0Um93SWRdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpdGVtLmlkO1xuICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGlzSW50ZXJhY3RpdmVFbGVtZW50KGV2ZW50OiBhbnkpOiBhbnkge1xuICAgIGNvbnN0IGludGVyYWN0aXZlRWxTZWxlY3RvcnMgPSBgXG4gICAgICBhLFxuICAgICAgYnV0dG9uLFxuICAgICAgaW5wdXQsXG4gICAgICBsYWJlbCxcbiAgICAgIG9wdGlvbixcbiAgICAgIHNlbGVjdCxcbiAgICAgIHRleHRhcmVhLFxuICAgICAgZGV0YWlscyxcbiAgICAgIGRpYWxvZyxcbiAgICAgIG1lbnUsXG4gICAgICBtZW51aXRlbSxcbiAgICAgIHN1bW1hcnlgO1xuICAgIHJldHVybiBldmVudC50YXJnZXQuY2xvc2VzdChpbnRlcmFjdGl2ZUVsU2VsZWN0b3JzKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0UmVzaXplQmFyUG9zaXRpb24oeFBvc2l0aW9uOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBwYXJlbnRTY3JvbGwgPSB0aGlzLnRhYmxlQ29udGFpbmVyRWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnNjcm9sbExlZnQ7XG4gICAgY29uc3QgcmVzaXplQmFyWCA9XG4gICAgICB4UG9zaXRpb24gLVxuICAgICAgdGhpcy50YWJsZUVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5sZWZ0IC1cbiAgICAgIHBhcmVudFNjcm9sbDtcbiAgICB0aGlzLmdyaWRBZGFwdGVyLnNldFN0eWxlKHRoaXMucmVzaXplQmFyLCAnbGVmdCcsIHJlc2l6ZUJhclggKyAncHgnKTtcbiAgfVxuXG4gIHByaXZhdGUgYXBwbHlVc2VyQ29uZmlnKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4ge1xuICAgICAgdGhpcy51aUNvbmZpZ1NlcnZpY2VcbiAgICAgICAgLmdldENvbmZpZyh0aGlzLnNldHRpbmdzS2V5KVxuICAgICAgICAucGlwZSh0YWtlKDEpKVxuICAgICAgICAuc3Vic2NyaWJlKFxuICAgICAgICAgIChjb25maWc6IFNreUdyaWRVSUNvbmZpZykgPT4ge1xuICAgICAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICAgICAgICAgIGlmIChjb25maWcgJiYgY29uZmlnLnNlbGVjdGVkQ29sdW1uSWRzKSB7XG4gICAgICAgICAgICAgIC8vIFJlbW92ZSBhbnkgY29sdW1uSWRzIHRoYXQgZG9uJ3QgZXhpc3QgaW4gdGhlIGN1cnJlbnQgZGF0YSBzZXQuXG4gICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRDb2x1bW5JZHMgPSBjb25maWcuc2VsZWN0ZWRDb2x1bW5JZHMuZmlsdGVyKChpZCkgPT5cbiAgICAgICAgICAgICAgICB0aGlzLmNvbHVtbnMuZmluZCgoY29sdW1uKSA9PiBjb2x1bW4uaWQgPT09IGlkKVxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB0aGlzLmNoYW5nZURldGVjdG9yLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRVc2VyQ29uZmlnKGNvbmZpZzogU2t5R3JpZFVJQ29uZmlnKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnNldHRpbmdzS2V5KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy51aUNvbmZpZ1NlcnZpY2VcbiAgICAgIC5zZXRDb25maWcodGhpcy5zZXR0aW5nc0tleSwgY29uZmlnKVxuICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMubmdVbnN1YnNjcmliZSkpXG4gICAgICAuc3Vic2NyaWJlKFxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWVtcHR5LWZ1bmN0aW9uXG4gICAgICAgICgpID0+IHt9LFxuICAgICAgICAoZXJyKSA9PiB7XG4gICAgICAgICAgY29uc29sZS53YXJuKCdDb3VsZCBub3Qgc2F2ZSBncmlkIHNldHRpbmdzLicpO1xuICAgICAgICAgIGNvbnNvbGUud2FybihlcnIpO1xuICAgICAgICB9XG4gICAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBpbml0Q29sdW1ucygpOiB2b2lkIHtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgIGlmICh0aGlzLmNvbHVtbkNvbXBvbmVudHMubGVuZ3RoICE9PSAwIHx8IHRoaXMuY29sdW1ucyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgICAgLyogc2FuaXR5IGNoZWNrICovXG4gICAgICBpZiAodGhpcy5jb2x1bW5Db21wb25lbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhpcy5nZXRDb2x1bW5zRnJvbUNvbXBvbmVudCgpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnRyYW5zZm9ybURhdGEoKTtcbiAgICAgIHRoaXMuc2V0RGlzcGxheWVkQ29sdW1ucyh0cnVlKTtcbiAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3IubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuXG4gICAgLy8gV2F0Y2ggZm9yIGFkZGVkL3JlbW92ZWQgY29sdW1uczpcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMucHVzaChcbiAgICAgIHRoaXMuY29sdW1uQ29tcG9uZW50cy5jaGFuZ2VzLnN1YnNjcmliZSgoKSA9PiB0aGlzLnVwZGF0ZUNvbHVtbnMoKSlcbiAgICApO1xuXG4gICAgLy8gV2F0Y2ggZm9yIGNvbHVtbiBoZWFkaW5nIGNoYW5nZXM6XG4gICAgdGhpcy5jb2x1bW5Db21wb25lbnRzLmZvckVhY2goKGNvbXA6IFNreUdyaWRDb2x1bW5Db21wb25lbnQpID0+IHtcbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5wdXNoKFxuICAgICAgICBjb21wLmhlYWRpbmdNb2RlbENoYW5nZXMuc3Vic2NyaWJlKFxuICAgICAgICAgIChjaGFuZ2U6IFNreUdyaWRDb2x1bW5IZWFkaW5nTW9kZWxDaGFuZ2UpID0+IHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlQ29sdW1uSGVhZGluZyhjaGFuZ2UpO1xuICAgICAgICAgIH1cbiAgICAgICAgKVxuICAgICAgKTtcbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5wdXNoKFxuICAgICAgICBjb21wLmRlc2NyaXB0aW9uTW9kZWxDaGFuZ2VzLnN1YnNjcmliZShcbiAgICAgICAgICAoY2hhbmdlOiBTa3lHcmlkQ29sdW1uRGVzY3JpcHRpb25Nb2RlbENoYW5nZSkgPT4ge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVDb2x1bW5EZXNjcmlwdGlvbihjaGFuZ2UpO1xuICAgICAgICAgIH1cbiAgICAgICAgKVxuICAgICAgKTtcbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5wdXNoKFxuICAgICAgICBjb21wLmlubGluZUhlbHBQb3BvdmVyTW9kZWxDaGFuZ2VzLnN1YnNjcmliZShcbiAgICAgICAgICAoY2hhbmdlOiBTa3lHcmlkQ29sdW1uSW5saW5lSGVscFBvcG92ZXJNb2RlbENoYW5nZSkgPT4ge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVJbmxpbmVIZWxwUG9wb3ZlcihjaGFuZ2UpO1xuICAgICAgICAgIH1cbiAgICAgICAgKVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXJyYXlzRXF1YWwoYXJyYXlBOiBhbnlbXSwgYXJyYXlCOiBhbnlbXSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICBhcnJheUEubGVuZ3RoID09PSBhcnJheUIubGVuZ3RoICYmXG4gICAgICBhcnJheUEuZXZlcnkoKHZhbHVlLCBpbmRleCkgPT4gdmFsdWUgPT09IGFycmF5QltpbmRleF0pXG4gICAgKTtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cInNreS1ncmlkXCI+XG4gIDxkaXZcbiAgICAqbmdJZj1cInNob3dUb3BTY3JvbGxcIlxuICAgIGNsYXNzPVwic2t5LWdyaWQtdG9wLXNjcm9sbC1jb250YWluZXJcIlxuICAgIChzY3JvbGwpPVwib25Ub3BTY3JvbGwoJGV2ZW50KVwiXG4gICAgI3RvcFNjcm9sbENvbnRhaW5lclxuICA+XG4gICAgPGRpdlxuICAgICAgY2xhc3M9XCJza3ktZ3JpZC10b3Atc2Nyb2xsXCJcbiAgICAgIFtzdHlsZS53aWR0aC5weF09XCJnZXRUb3BTY3JvbGxXaWR0aCgpXCJcbiAgICA+PC9kaXY+XG4gIDwvZGl2PlxuICA8ZGl2XG4gICAgY2xhc3M9XCJza3ktZ3JpZC10YWJsZS1jb250YWluZXJcIlxuICAgIFtzdHlsZS5oZWlnaHQucHhdPVwiaGVpZ2h0XCJcbiAgICBbc3R5bGUud2lkdGgucHhdPVwid2lkdGhcIlxuICAgIChzY3JvbGwpPVwib25HcmlkU2Nyb2xsKCRldmVudClcIlxuICAgICNncmlkQ29udGFpbmVyXG4gID5cbiAgICA8dGFibGUgY2xhc3M9XCJza3ktZ3JpZC10YWJsZVwiIFtuZ0NsYXNzXT1cImdldFRhYmxlQ2xhc3NOYW1lcygpXCIgI2dyaWRUYWJsZT5cbiAgICAgIDx0aGVhZD5cbiAgICAgICAgPHRyIFtkcmFndWxhXT1cImRyYWd1bGFHcm91cE5hbWVcIj5cbiAgICAgICAgICA8dGhcbiAgICAgICAgICAgICpuZ0lmPVwiZW5hYmxlTXVsdGlzZWxlY3RcIlxuICAgICAgICAgICAgY2xhc3M9XCJza3ktZ3JpZC1oZWFkaW5nIHNreS1ncmlkLW11bHRpc2VsZWN0LWNlbGwgc2t5LWdyaWQtaGVhZGVyLWxvY2tlZFwiXG4gICAgICAgICAgICBzY29wZT1cImNvbFwiXG4gICAgICAgICAgICBbc3R5bGUubWF4LXdpZHRoLnB4XT1cIm1pbkNvbFdpZHRoXCJcbiAgICAgICAgICAgIFtzdHlsZS53aWR0aC5weF09XCJtaW5Db2xXaWR0aFwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzY3JlZW4tcmVhZGVyLW9ubHlcIj5cbiAgICAgICAgICAgICAge3sgJ3NreXV4X2dyaWRfbXVsdGlzZWxlY3Rfc2VsZWN0X3JvdycgfCBza3lMaWJSZXNvdXJjZXMgfX1cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICA8L3RoPlxuICAgICAgICAgIDx0aFxuICAgICAgICAgICAgKm5nRm9yPVwiXG4gICAgICAgICAgICAgIGxldCBjb2x1bW4gb2YgZGlzcGxheWVkQ29sdW1ucztcbiAgICAgICAgICAgICAgbGV0IGxhc3QgPSBsYXN0O1xuICAgICAgICAgICAgICBsZXQgaSA9IGluZGV4XG4gICAgICAgICAgICBcIlxuICAgICAgICAgICAgY2xhc3M9XCJza3ktZ3JpZC1oZWFkaW5nIHNreS1maWVsZC1sYWJlbFwiXG4gICAgICAgICAgICBzY29wZT1cImNvbFwiXG4gICAgICAgICAgICBbYXR0ci5za3ktY21wLWluZGV4XT1cImlcIlxuICAgICAgICAgICAgW2F0dHIuc2t5LWNtcC1pZF09XCJjb2x1bW4uaWQgfHwgY29sdW1uLmZpZWxkXCJcbiAgICAgICAgICAgIFthdHRyLmFyaWEtc29ydF09XCJnZXRBcmlhU29ydERpcmVjdGlvbihjb2x1bW4pIHwgYXN5bmNcIlxuICAgICAgICAgICAgW2lkXT1cIidza3ktZ3JpZC0nICsgZ3JpZElkICsgJy1jb2x1bW4tJyArIGlcIlxuICAgICAgICAgICAgW25nQ2xhc3NdPVwiJ3NreS1ncmlkLWNvbHVtbi1hbGlnbm1lbnQtJyArIGNvbHVtbi5hbGlnbm1lbnRcIlxuICAgICAgICAgICAgW3N0eWxlLm1heC13aWR0aC5weF09XCJjb2x1bW4ud2lkdGhcIlxuICAgICAgICAgICAgW3N0eWxlLndpZHRoLnB4XT1cImNvbHVtbi53aWR0aFwiXG4gICAgICAgICAgICBbdGFiSW5kZXhdPVwiY29sdW1uLmlzU29ydGFibGUgPyAwIDogLTFcIlxuICAgICAgICAgICAgKG1vdXNldXApPVwic29ydEJ5Q29sdW1uKGNvbHVtbilcIlxuICAgICAgICAgICAgKGtleWRvd24pPVwib25LZXlkb3duKCRldmVudCwgY29sdW1uKVwiXG4gICAgICAgICAgICAodG91Y2htb3ZlKT1cIm9uVG91Y2hNb3ZlKCRldmVudClcIlxuICAgICAgICAgICAgI2dyaWRDb2xcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgIGNsYXNzPVwib3ZlcmZsb3dcIlxuICAgICAgICAgICAgICBbbmdDbGFzc109XCJnZXRUYWJsZUhlYWRlckNsYXNzTmFtZXMoY29sdW1uKVwiXG4gICAgICAgICAgICAgIFtzdHlsZS5tYXgtd2lkdGgucHhdPVwiY29sdW1uLndpZHRoIC0gMVwiXG4gICAgICAgICAgICAgIFtzdHlsZS53aWR0aC5weF09XCJjb2x1bW4ud2lkdGggLSAxXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgICAqbmdJZj1cIihnZXRDYXJldFZpc2liaWxpdHkoY29sdW1uLmZpZWxkKSB8IGFzeW5jKSA9PT0gJ2hpZGRlbidcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwic2t5LWdyaWQtaGVhZGVyLWNhcmV0LWhpZGRlbi1zcGFjaW5nXCJcbiAgICAgICAgICAgICAgPjwvc3Bhbj5cbiAgICAgICAgICAgICAgPCEtLSBUaGUgbm8gc3BhY2luZyBoZXJlIGlzIGludGVudGlvbmFsIHRvIGF2b2lkIGV4dHJhIHNwYWNlcyBkdWUgdG8gdGhlc2UgYmVpbmcgaW5saW5lIGVsZW1lbnRzIC0tPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNreS1ncmlkLWhlYWRlci10ZXh0XCI+e3tcbiAgICAgICAgICAgICAgICBjb2x1bW4uaGVhZGluZz8udHJpbSgpXG4gICAgICAgICAgICAgIH19PC9zcGFuPlxuICAgICAgICAgICAgICA8c2t5LWljb25cbiAgICAgICAgICAgICAgICBjbGFzcz1cInNreS1ncmlkLWhlYWRpbmctc29ydFwiXG4gICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiXG4gICAgICAgICAgICAgICAgICAnc2t5LWdyaWQtaGVhZGluZy1zb3J0LScgK1xuICAgICAgICAgICAgICAgICAgKGdldENhcmV0VmlzaWJpbGl0eShjb2x1bW4uZmllbGQpIHwgYXN5bmMpXG4gICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICBbaWNvbl09XCJnZXRDYXJldEljb25OYW1lcyhjb2x1bW4pXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8L3NreS1pY29uPlxuICAgICAgICAgICAgICA8c2t5LWhlbHAtaW5saW5lXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJjb2x1bW4uaW5saW5lSGVscFBvcG92ZXJcIlxuICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIntcbiAgICAgICAgICAgICAgICAgICdza3ktZ3JpZC1oZWxwLWlubGluZS1zb3J0LWhpZGRlbic6XG4gICAgICAgICAgICAgICAgICAgIGdldEhlbHBJbmxpbmVDbGFzcyhjb2x1bW4uZmllbGQpIHwgYXN5bmNcbiAgICAgICAgICAgICAgICB9XCJcbiAgICAgICAgICAgICAgICBbc2t5UG9wb3Zlcl09XCJjb2x1bW4uaW5saW5lSGVscFBvcG92ZXJcIlxuICAgICAgICAgICAgICAgIChrZXlkb3duLmVudGVyKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgICAgICAgICAgKGtleWRvd24uc3BhY2UpPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAgICAgICAgICAobW91c2Vkb3duKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgICAgICAgICAgKG1vdXNldXApPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8L3NreS1oZWxwLWlubGluZT5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgKm5nSWY9XCIoZml0ID09PSAnd2lkdGgnICYmICFsYXN0KSB8fCBmaXQgPT09ICdzY3JvbGwnXCJcbiAgICAgICAgICAgICAgYXJpYS1oaWRkZW49XCJ0cnVlXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJza3ktZ3JpZC1yZXNpemUtaGFuZGxlXCJcbiAgICAgICAgICAgICAgdGFiaW5kZXg9XCItMVwiXG4gICAgICAgICAgICAgIFthdHRyLnNreS1jbXAtaW5kZXhdPVwiaVwiXG4gICAgICAgICAgICAgIChtb3VzZWRvd24pPVwib25SZXNpemVDb2x1bW5TdGFydCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgKHRvdWNoc3RhcnQpPVwib25SZXNpemVDb2x1bW5TdGFydCgkZXZlbnQpXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICBhcmlhLWxhYmVsPVwiV2lkdGggb2YgY29sdW1uXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJza3ktZ3JpZC1jb2x1bW4taW5wdXQtYXJpYS1vbmx5XCJcbiAgICAgICAgICAgICAgcm9sZT1cInNsaWRlclwiXG4gICAgICAgICAgICAgIHR5cGU9XCJyYW5nZVwiXG4gICAgICAgICAgICAgIFthdHRyLmFyaWEtY29udHJvbHNdPVwiJ3NreS1ncmlkLScgKyBncmlkSWQgKyAnLWNvbHVtbi0nICsgaVwiXG4gICAgICAgICAgICAgIFthdHRyLmFyaWEtdmFsdWVtaW5dPVwibWluQ29sV2lkdGhcIlxuICAgICAgICAgICAgICBbYXR0ci5hcmlhLXZhbHVlbWF4XT1cIm1heENvbFdpZHRoXCJcbiAgICAgICAgICAgICAgW2F0dHIuYXJpYS12YWx1ZW5vd109XCJjb2x1bW4ud2lkdGhcIlxuICAgICAgICAgICAgICBbYXR0ci5za3ktY21wLWluZGV4XT1cImlcIlxuICAgICAgICAgICAgICBbbWluXT1cIm1pbkNvbFdpZHRoXCJcbiAgICAgICAgICAgICAgW21heF09XCJtYXhDb2xXaWR0aFwiXG4gICAgICAgICAgICAgIFtzdGVwXT1cImNvbHVtblJlc2l6ZVN0ZXBcIlxuICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImNvbHVtbi53aWR0aFwiXG4gICAgICAgICAgICAgIChibHVyKT1cIm9uUmVzaXplSGFuZGxlQmx1cigkZXZlbnQpXCJcbiAgICAgICAgICAgICAgKGZvY3VzKT1cIm9uUmVzaXplSGFuZGxlRm9jdXMoJGV2ZW50KVwiXG4gICAgICAgICAgICAgIChrZXlkb3duKT1cIm9uS2V5ZG93blJlc2l6ZUNvbCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgKGNoYW5nZSk9XCJvbklucHV0Q2hhbmdlUmVzaXplQ29sKCRldmVudClcIlxuICAgICAgICAgICAgICAjY29sU2l6ZVJhbmdlXG4gICAgICAgICAgICAvPlxuICAgICAgICAgIDwvdGg+XG4gICAgICAgIDwvdHI+XG4gICAgICA8L3RoZWFkPlxuICAgICAgPHRib2R5IGNsYXNzPVwic2t5LWdyaWQtdGJvZHlcIj5cbiAgICAgICAgPHRyXG4gICAgICAgICAgY2xhc3M9XCJza3ktZ3JpZC1yb3dcIlxuICAgICAgICAgICpuZ0Zvcj1cImxldCBpdGVtIG9mIGl0ZW1zOyBsZXQgaSA9IGluZGV4XCJcbiAgICAgICAgICBbYXR0ci5hcmlhLWN1cnJlbnRdPVwiaXNSb3dIaWdobGlnaHRlZChpdGVtLmlkKSA/IHRydWUgOiBudWxsXCJcbiAgICAgICAgICBbYXR0ci5za3ktY21wLWlkXT1cIml0ZW0uaWRcIlxuICAgICAgICAgIFtuZ0NsYXNzXT1cIntcbiAgICAgICAgICAgICdza3ktZ3JpZC1tdWx0aXNlbGVjdC1zZWxlY3RlZC1yb3cnOiBpdGVtLmlzU2VsZWN0ZWQsXG4gICAgICAgICAgICAnc2t5LWdyaWQtbXVsdGlzZWxlY3Qtcm93JzogZW5hYmxlTXVsdGlzZWxlY3QsXG4gICAgICAgICAgICAnc2t5LWdyaWQtcm93LWhpZ2hsaWdodCc6IGlzUm93SGlnaGxpZ2h0ZWQoaXRlbS5pZClcbiAgICAgICAgICB9XCJcbiAgICAgICAgICAoY2xpY2spPVwib25Sb3dDbGljaygkZXZlbnQsIGl0ZW0pXCJcbiAgICAgICAgPlxuICAgICAgICAgIDx0ZFxuICAgICAgICAgICAgKm5nSWY9XCJlbmFibGVNdWx0aXNlbGVjdFwiXG4gICAgICAgICAgICBjbGFzcz1cInNreS1ncmlkLW11bHRpc2VsZWN0LWNlbGwgc2t5LWdyaWQtaGVhZGVyLWxvY2tlZFwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICBbc3R5bGUubWF4LXdpZHRoLnB4XT1cIm1pbkNvbFdpZHRoXCJcbiAgICAgICAgICAgICAgW3N0eWxlLndpZHRoLnB4XT1cIm1pbkNvbFdpZHRoXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPHNreS1jaGVja2JveFxuICAgICAgICAgICAgICAgIFtsYWJlbF09XCInc2t5dXhfZ3JpZF9tdWx0aXNlbGVjdF9zZWxlY3Rfcm93JyB8IHNreUxpYlJlc291cmNlc1wiXG4gICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJvbk11bHRpc2VsZWN0Q2hlY2tib3hDaGFuZ2UoKVwiXG4gICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJpdGVtLmlzU2VsZWN0ZWRcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDwvc2t5LWNoZWNrYm94PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgICA8dGRcbiAgICAgICAgICAgICpuZ0Zvcj1cIlxuICAgICAgICAgICAgICBsZXQgY29sdW1uIG9mIGRpc3BsYXllZENvbHVtbnM7XG4gICAgICAgICAgICAgIGxldCBsYXN0ID0gbGFzdDtcbiAgICAgICAgICAgICAgbGV0IGkgPSBpbmRleFxuICAgICAgICAgICAgXCJcbiAgICAgICAgICAgIGNsYXNzPVwic2t5LWdyaWQtY2VsbFwiXG4gICAgICAgICAgICBbbmdDbGFzc109XCInc2t5LWdyaWQtY29sdW1uLWFsaWdubWVudC0nICsgY29sdW1uLmFsaWdubWVudFwiXG4gICAgICAgICAgICBbc3R5bGUubWF4LXdpZHRoLnB4XT1cImNvbHVtbi53aWR0aFwiXG4gICAgICAgICAgICBbc3R5bGUud2lkdGgucHhdPVwiY29sdW1uLndpZHRoXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8c2t5LWdyaWQtY2VsbFxuICAgICAgICAgICAgICBbc2t5SGlnaGxpZ2h0XT1cIlxuICAgICAgICAgICAgICAgICFjb2x1bW4uZXhjbHVkZUZyb21IaWdobGlnaHRpbmcgPyBoaWdobGlnaHRUZXh0IDogdW5kZWZpbmVkXG4gICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgIFt0ZW1wbGF0ZV09XCJjb2x1bW4udGVtcGxhdGUgfHwgZGVmYXVsdENlbGxUZW1wbGF0ZVwiXG4gICAgICAgICAgICAgIFtmaWVsZFNlbGVjdG9yXT1cImNvbHVtbi5maWVsZFwiXG4gICAgICAgICAgICAgIFtpdGVtXT1cIml0ZW1cIlxuICAgICAgICAgICAgICBbY29sdW1uSWRdPVwiY29sdW1uLmlkXCJcbiAgICAgICAgICAgICAgW2F0dHIuc2t5LWNtcC1pZF09XCJjb2x1bW4uaWQgfHwgY29sdW1uLmZpZWxkXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgIDwvc2t5LWdyaWQtY2VsbD5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICA8L3RyPlxuICAgICAgPC90Ym9keT5cbiAgICA8L3RhYmxlPlxuICAgIDxkaXZcbiAgICAgICpuZ0lmPVwic2hvd1Jlc2l6ZUJhclwiXG4gICAgICBhcmlhLWhpZGRlbj1cInRydWVcIlxuICAgICAgaWQ9XCJza3ktZ3JpZC1yZXNpemUtYmFyXCJcbiAgICAgIHRhYmluZGV4PVwiLTFcIlxuICAgICAgI3Jlc2l6ZUJhclxuICAgID48L2Rpdj5cbiAgPC9kaXY+XG48L2Rpdj5cblxuPG5nLXRlbXBsYXRlICNkZWZhdWx0Q2VsbFRlbXBsYXRlIGxldC1yb3c9XCJyb3dcIiBsZXQtdmFsdWU9XCJ2YWx1ZVwiPnt7XG4gIHZhbHVlXG59fTwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSBsZXQtaXRlbSAjaW5saW5lRGVsZXRlVGVtcGxhdGVSZWY+XG4gIDxkaXZcbiAgICBbaWRdPVwiJ3Jvdy1kZWxldGUtcmVmLScgKyBpdGVtLmlkXCJcbiAgICBbbmdTdHlsZV09XCJ7XG4gICAgICBoZWlnaHQ6IGdldFJvd0hlaWdodCgwKSxcbiAgICAgIHBvc2l0aW9uOiAnZml4ZWQnLFxuICAgICAgd2lkdGg6IHRhYmxlV2lkdGggKyAncHgnXG4gICAgfVwiXG4gICAgI2lubGluZURlbGV0ZVJlZlxuICA+XG4gICAgPHNreS1pbmxpbmUtZGVsZXRlXG4gICAgICBbcGVuZGluZ109XCJnZXRSb3dEZWxldGVJdGVtKGl0ZW0uaWQpLnBlbmRpbmdcIlxuICAgICAgKGNhbmNlbFRyaWdnZXJlZCk9XCJjYW5jZWxSb3dEZWxldGUoaXRlbS5pZClcIlxuICAgICAgKGRlbGV0ZVRyaWdnZXJlZCk9XCJjb25maXJtUm93RGVsZXRlKGl0ZW0uaWQpXCJcbiAgICA+PC9za3ktaW5saW5lLWRlbGV0ZT5cbiAgPC9kaXY+XG48L25nLXRlbXBsYXRlPlxuIl19