@ngxsmk/cdk 1.3.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/README.md +1 -1
  2. package/cva-base/cva-base.d.ts +34 -0
  3. package/cva-base/cva-base.d.ts.map +1 -0
  4. package/cva-base/index.d.ts +2 -0
  5. package/cva-base/index.d.ts.map +1 -0
  6. package/cva-base/ngxsmk-cdk-cva-base.d.ts.map +1 -0
  7. package/esm2022/cva-base/cva-base.mjs +45 -0
  8. package/esm2022/cva-base/index.mjs +2 -0
  9. package/esm2022/cva-base/ngxsmk-cdk-cva-base.mjs +5 -0
  10. package/esm2022/input-group/index.mjs +3 -0
  11. package/esm2022/input-group/input-group-engine.mjs +219 -0
  12. package/esm2022/input-group/models/index.mjs +2 -0
  13. package/esm2022/input-group/models/input-group.model.mjs +2 -0
  14. package/esm2022/input-group/ngxsmk-cdk-input-group.mjs +5 -0
  15. package/esm2022/listbox-keyboard/index.mjs +2 -0
  16. package/esm2022/listbox-keyboard/listbox-keyboard.mjs +145 -0
  17. package/esm2022/listbox-keyboard/ngxsmk-cdk-listbox-keyboard.mjs +5 -0
  18. package/esm2022/public-api.mjs +10 -1
  19. package/esm2022/scheduler/index.mjs +5 -0
  20. package/esm2022/scheduler/models/date-range.mjs +2 -0
  21. package/esm2022/scheduler/models/event.model.mjs +2 -0
  22. package/esm2022/scheduler/models/index.mjs +6 -0
  23. package/esm2022/scheduler/models/resource.model.mjs +5 -0
  24. package/esm2022/scheduler/models/selection.model.mjs +7 -0
  25. package/esm2022/scheduler/models/view.model.mjs +7 -0
  26. package/esm2022/scheduler/ngxsmk-cdk-scheduler.mjs +5 -0
  27. package/esm2022/scheduler/plugin/drag-plugin.mjs +82 -0
  28. package/esm2022/scheduler/plugin/index.mjs +8 -0
  29. package/esm2022/scheduler/plugin/keyboard-plugin.mjs +150 -0
  30. package/esm2022/scheduler/plugin/plugin-host.mjs +48 -0
  31. package/esm2022/scheduler/plugin/plugin.types.mjs +2 -0
  32. package/esm2022/scheduler/plugin/resize-plugin.mjs +74 -0
  33. package/esm2022/scheduler/plugin/selection-plugin.mjs +84 -0
  34. package/esm2022/scheduler/plugin/tooltip-plugin.mjs +103 -0
  35. package/esm2022/scheduler/scheduler-engine.mjs +316 -0
  36. package/esm2022/scheduler/utils/date-utils.mjs +131 -0
  37. package/esm2022/scheduler/utils/index.mjs +3 -0
  38. package/esm2022/scheduler/utils/snap.mjs +24 -0
  39. package/esm2022/spreadsheet/index.mjs +5 -0
  40. package/esm2022/spreadsheet/models/cell.model.mjs +2 -0
  41. package/esm2022/spreadsheet/models/column.model.mjs +2 -0
  42. package/esm2022/spreadsheet/models/filter.model.mjs +2 -0
  43. package/esm2022/spreadsheet/models/formula.model.mjs +2 -0
  44. package/esm2022/spreadsheet/models/index.mjs +8 -0
  45. package/esm2022/spreadsheet/models/row.model.mjs +2 -0
  46. package/esm2022/spreadsheet/models/selection.model.mjs +2 -0
  47. package/esm2022/spreadsheet/models/sort.model.mjs +2 -0
  48. package/esm2022/spreadsheet/ngxsmk-cdk-spreadsheet.mjs +5 -0
  49. package/esm2022/spreadsheet/plugin/clipboard-plugin.mjs +171 -0
  50. package/esm2022/spreadsheet/plugin/filter-plugin.mjs +87 -0
  51. package/esm2022/spreadsheet/plugin/formula-plugin.mjs +456 -0
  52. package/esm2022/spreadsheet/plugin/index.mjs +10 -0
  53. package/esm2022/spreadsheet/plugin/plugin-host.mjs +188 -0
  54. package/esm2022/spreadsheet/plugin/plugin.types.mjs +2 -0
  55. package/esm2022/spreadsheet/plugin/selection-plugin.mjs +114 -0
  56. package/esm2022/spreadsheet/plugin/sort-plugin.mjs +63 -0
  57. package/esm2022/spreadsheet/plugin/undo-plugin.mjs +138 -0
  58. package/esm2022/spreadsheet/plugin/validation-plugin.mjs +71 -0
  59. package/esm2022/spreadsheet/spreadsheet-engine.mjs +547 -0
  60. package/esm2022/spreadsheet/utils/cell-utils.mjs +129 -0
  61. package/esm2022/spreadsheet/utils/index.mjs +2 -0
  62. package/esm2022/testing/a11y.mjs +6 -3
  63. package/fesm2022/ngxsmk-cdk-cva-base.mjs +52 -0
  64. package/fesm2022/ngxsmk-cdk-cva-base.mjs.map +1 -0
  65. package/fesm2022/ngxsmk-cdk-input-group.mjs +226 -0
  66. package/fesm2022/ngxsmk-cdk-input-group.mjs.map +1 -0
  67. package/fesm2022/ngxsmk-cdk-listbox-keyboard.mjs +152 -0
  68. package/fesm2022/ngxsmk-cdk-listbox-keyboard.mjs.map +1 -0
  69. package/fesm2022/ngxsmk-cdk-scheduler.mjs +1035 -0
  70. package/fesm2022/ngxsmk-cdk-scheduler.mjs.map +1 -0
  71. package/fesm2022/ngxsmk-cdk-spreadsheet.mjs +1969 -0
  72. package/fesm2022/ngxsmk-cdk-spreadsheet.mjs.map +1 -0
  73. package/fesm2022/ngxsmk-cdk-testing.mjs +5 -2
  74. package/fesm2022/ngxsmk-cdk-testing.mjs.map +1 -1
  75. package/fesm2022/ngxsmk-cdk.mjs +5 -0
  76. package/fesm2022/ngxsmk-cdk.mjs.map +1 -1
  77. package/input-group/index.d.ts +3 -0
  78. package/input-group/index.d.ts.map +1 -0
  79. package/input-group/input-group-engine.d.ts +88 -0
  80. package/input-group/input-group-engine.d.ts.map +1 -0
  81. package/input-group/models/index.d.ts +2 -0
  82. package/input-group/models/index.d.ts.map +1 -0
  83. package/input-group/models/input-group.model.d.ts +114 -0
  84. package/input-group/models/input-group.model.d.ts.map +1 -0
  85. package/input-group/ngxsmk-cdk-input-group.d.ts.map +1 -0
  86. package/listbox-keyboard/index.d.ts +2 -0
  87. package/listbox-keyboard/index.d.ts.map +1 -0
  88. package/listbox-keyboard/listbox-keyboard.d.ts +60 -0
  89. package/listbox-keyboard/listbox-keyboard.d.ts.map +1 -0
  90. package/listbox-keyboard/ngxsmk-cdk-listbox-keyboard.d.ts.map +1 -0
  91. package/package.json +40 -1
  92. package/public-api.d.ts +8 -0
  93. package/public-api.d.ts.map +1 -1
  94. package/scheduler/index.d.ts +5 -0
  95. package/scheduler/index.d.ts.map +1 -0
  96. package/scheduler/models/date-range.d.ts +6 -0
  97. package/scheduler/models/date-range.d.ts.map +1 -0
  98. package/scheduler/models/event.model.d.ts +50 -0
  99. package/scheduler/models/event.model.d.ts.map +1 -0
  100. package/scheduler/models/index.d.ts +6 -0
  101. package/scheduler/models/index.d.ts.map +1 -0
  102. package/scheduler/models/resource.model.d.ts +16 -0
  103. package/scheduler/models/resource.model.d.ts.map +1 -0
  104. package/scheduler/models/selection.model.d.ts +12 -0
  105. package/scheduler/models/selection.model.d.ts.map +1 -0
  106. package/scheduler/models/view.model.d.ts +21 -0
  107. package/scheduler/models/view.model.d.ts.map +1 -0
  108. package/scheduler/ngxsmk-cdk-scheduler.d.ts.map +1 -0
  109. package/scheduler/plugin/drag-plugin.d.ts +28 -0
  110. package/scheduler/plugin/drag-plugin.d.ts.map +1 -0
  111. package/scheduler/plugin/index.d.ts +8 -0
  112. package/scheduler/plugin/index.d.ts.map +1 -0
  113. package/scheduler/plugin/keyboard-plugin.d.ts +24 -0
  114. package/scheduler/plugin/keyboard-plugin.d.ts.map +1 -0
  115. package/scheduler/plugin/plugin-host.d.ts +16 -0
  116. package/scheduler/plugin/plugin-host.d.ts.map +1 -0
  117. package/scheduler/plugin/plugin.types.d.ts +9 -0
  118. package/scheduler/plugin/plugin.types.d.ts.map +1 -0
  119. package/scheduler/plugin/resize-plugin.d.ts +26 -0
  120. package/scheduler/plugin/resize-plugin.d.ts.map +1 -0
  121. package/scheduler/plugin/selection-plugin.d.ts +40 -0
  122. package/scheduler/plugin/selection-plugin.d.ts.map +1 -0
  123. package/scheduler/plugin/tooltip-plugin.d.ts +41 -0
  124. package/scheduler/plugin/tooltip-plugin.d.ts.map +1 -0
  125. package/scheduler/scheduler-engine.d.ts +95 -0
  126. package/scheduler/scheduler-engine.d.ts.map +1 -0
  127. package/scheduler/utils/date-utils.d.ts +26 -0
  128. package/scheduler/utils/date-utils.d.ts.map +1 -0
  129. package/scheduler/utils/index.d.ts +3 -0
  130. package/scheduler/utils/index.d.ts.map +1 -0
  131. package/scheduler/utils/snap.d.ts +7 -0
  132. package/scheduler/utils/snap.d.ts.map +1 -0
  133. package/spreadsheet/index.d.ts +5 -0
  134. package/spreadsheet/index.d.ts.map +1 -0
  135. package/spreadsheet/models/cell.model.d.ts +44 -0
  136. package/spreadsheet/models/cell.model.d.ts.map +1 -0
  137. package/spreadsheet/models/column.model.d.ts +77 -0
  138. package/spreadsheet/models/column.model.d.ts.map +1 -0
  139. package/spreadsheet/models/filter.model.d.ts +15 -0
  140. package/spreadsheet/models/filter.model.d.ts.map +1 -0
  141. package/spreadsheet/models/formula.model.d.ts +65 -0
  142. package/spreadsheet/models/formula.model.d.ts.map +1 -0
  143. package/spreadsheet/models/index.d.ts +8 -0
  144. package/spreadsheet/models/index.d.ts.map +1 -0
  145. package/spreadsheet/models/row.model.d.ts +33 -0
  146. package/spreadsheet/models/row.model.d.ts.map +1 -0
  147. package/spreadsheet/models/selection.model.d.ts +18 -0
  148. package/spreadsheet/models/selection.model.d.ts.map +1 -0
  149. package/spreadsheet/models/sort.model.d.ts +14 -0
  150. package/spreadsheet/models/sort.model.d.ts.map +1 -0
  151. package/spreadsheet/ngxsmk-cdk-spreadsheet.d.ts.map +1 -0
  152. package/spreadsheet/plugin/clipboard-plugin.d.ts +24 -0
  153. package/spreadsheet/plugin/clipboard-plugin.d.ts.map +1 -0
  154. package/spreadsheet/plugin/filter-plugin.d.ts +21 -0
  155. package/spreadsheet/plugin/filter-plugin.d.ts.map +1 -0
  156. package/spreadsheet/plugin/formula-plugin.d.ts +39 -0
  157. package/spreadsheet/plugin/formula-plugin.d.ts.map +1 -0
  158. package/spreadsheet/plugin/index.d.ts +10 -0
  159. package/spreadsheet/plugin/index.d.ts.map +1 -0
  160. package/spreadsheet/plugin/plugin-host.d.ts +66 -0
  161. package/spreadsheet/plugin/plugin-host.d.ts.map +1 -0
  162. package/spreadsheet/plugin/plugin.types.d.ts +58 -0
  163. package/spreadsheet/plugin/plugin.types.d.ts.map +1 -0
  164. package/spreadsheet/plugin/selection-plugin.d.ts +28 -0
  165. package/spreadsheet/plugin/selection-plugin.d.ts.map +1 -0
  166. package/spreadsheet/plugin/sort-plugin.d.ts +18 -0
  167. package/spreadsheet/plugin/sort-plugin.d.ts.map +1 -0
  168. package/spreadsheet/plugin/undo-plugin.d.ts +40 -0
  169. package/spreadsheet/plugin/undo-plugin.d.ts.map +1 -0
  170. package/spreadsheet/plugin/validation-plugin.d.ts +29 -0
  171. package/spreadsheet/plugin/validation-plugin.d.ts.map +1 -0
  172. package/spreadsheet/spreadsheet-engine.d.ts +194 -0
  173. package/spreadsheet/spreadsheet-engine.d.ts.map +1 -0
  174. package/spreadsheet/utils/cell-utils.d.ts +26 -0
  175. package/spreadsheet/utils/cell-utils.d.ts.map +1 -0
  176. package/spreadsheet/utils/index.d.ts +2 -0
  177. package/spreadsheet/utils/index.d.ts.map +1 -0
  178. package/testing/a11y.d.ts +5 -1
  179. package/testing/a11y.d.ts.map +1 -1
@@ -0,0 +1,547 @@
1
+ import { computed, signal } from '@angular/core';
2
+ import { PluginHost } from './plugin/plugin-host';
3
+ import { generateRowId, createEmptyRow } from './utils/cell-utils';
4
+ const DENSITY_ROW_HEIGHT = {
5
+ compact: 28,
6
+ comfortable: 36,
7
+ dense: 24,
8
+ };
9
+ const DENSITY_HEADER_HEIGHT = {
10
+ compact: 32,
11
+ comfortable: 40,
12
+ dense: 28,
13
+ };
14
+ const DENSITY_CELL_PADDING = {
15
+ compact: '2px 6px',
16
+ comfortable: '6px 10px',
17
+ dense: '2px 4px',
18
+ };
19
+ /**
20
+ * SpreadsheetEngine — headless, signal-based state machine for spreadsheet data.
21
+ * Zero DOM, zero Angular dependencies beyond signals.
22
+ *
23
+ * Supports: columns, rows, sorting, filtering, selection, editing,
24
+ * undo/redo, clipboard, formulas, tree data, virtual scrolling state.
25
+ */
26
+ export class SpreadsheetEngine {
27
+ constructor(config = {}) {
28
+ this._config = config;
29
+ this.pluginHost = new PluginHost();
30
+ // Density
31
+ this.density = signal(config.density ?? 'comfortable');
32
+ this.editable = signal(config.editable ?? true);
33
+ this.rtl = signal(config.rtl ?? false);
34
+ this.frozenRows = signal(config.frozenRows ?? 0);
35
+ this.frozenColumns = signal(config.frozenColumns ?? 0);
36
+ // Row/column height computed from density
37
+ this.rowHeight = computed(() => DENSITY_ROW_HEIGHT[this.density()]);
38
+ this.headerHeight = computed(() => DENSITY_HEADER_HEIGHT[this.density()]);
39
+ this.cellPadding = computed(() => DENSITY_CELL_PADDING[this.density()]);
40
+ // Column definitions
41
+ this.columnDefs = signal(config.columns ?? []);
42
+ // Column states (width, visibility, pin, sort)
43
+ const initialStates = new Map();
44
+ (config.columns ?? []).forEach((col, idx) => {
45
+ initialStates.set(col.id, {
46
+ id: col.id,
47
+ width: col.width ?? 150,
48
+ visible: col.visible !== false,
49
+ pinned: col.pinned ?? false,
50
+ sort: col.sort ?? null,
51
+ sortIndex: undefined,
52
+ order: idx,
53
+ });
54
+ });
55
+ this.columnStates = signal(initialStates);
56
+ // Row data
57
+ this.rowData = signal(config.rows ?? []);
58
+ // Selection
59
+ this.selection = signal({
60
+ activeCell: null,
61
+ range: null,
62
+ selectedRows: new Set(),
63
+ selectedCols: new Set(),
64
+ mode: config.selectionMode ?? 'cell',
65
+ dragging: false,
66
+ });
67
+ // Sort
68
+ this.sortState = signal({
69
+ criteria: (config.columns ?? [])
70
+ .filter((c) => c.sort)
71
+ .map((c, i) => ({ colId: c.id, direction: c.sort, index: i })),
72
+ multiSort: config.multiSort ?? false,
73
+ });
74
+ // Filter
75
+ this.filterState = signal({ criteria: [], mode: 'and' });
76
+ // Editing
77
+ this.editingCell = signal(null);
78
+ this.editingValue = signal(null);
79
+ // Scroll
80
+ this.scrollTop = signal(0);
81
+ this.scrollLeft = signal(0);
82
+ this.viewportHeight = signal(600);
83
+ this.viewportWidth = signal(800);
84
+ // Plugins
85
+ this.plugins = signal(config.plugins ?? []);
86
+ // Lifecycle hooks
87
+ this.lifecycle = {
88
+ beforeEdit: signal(() => true),
89
+ afterEdit: signal(() => {
90
+ /* noop */
91
+ }),
92
+ beforeSort: signal(() => true),
93
+ afterSort: signal(() => {
94
+ /* noop */
95
+ }),
96
+ beforeFilter: signal(() => true),
97
+ afterFilter: signal(() => {
98
+ /* noop */
99
+ }),
100
+ beforeInsertRows: signal(() => true),
101
+ afterInsertRows: signal(() => {
102
+ /* noop */
103
+ }),
104
+ beforeDeleteRows: signal(() => true),
105
+ afterDeleteRows: signal(() => {
106
+ /* noop */
107
+ }),
108
+ beforeInsertColumns: signal(() => true),
109
+ afterInsertColumns: signal(() => {
110
+ /* noop */
111
+ }),
112
+ beforeDeleteColumns: signal(() => true),
113
+ afterDeleteColumns: signal(() => {
114
+ /* noop */
115
+ }),
116
+ beforeCopy: signal(() => true),
117
+ afterCopy: signal(() => {
118
+ /* noop */
119
+ }),
120
+ beforePaste: signal(() => true),
121
+ afterPaste: signal(() => {
122
+ /* noop */
123
+ }),
124
+ };
125
+ // ── Computed ──
126
+ this.visibleColumns = computed(() => {
127
+ const states = this.columnStates();
128
+ return this.columnDefs().filter((col) => {
129
+ const st = states.get(col.id);
130
+ return st?.visible ?? true;
131
+ });
132
+ });
133
+ this.pinnedLeftColumns = computed(() => this.visibleColumns().filter((c) => c.pinned === 'left'));
134
+ this.pinnedRightColumns = computed(() => this.visibleColumns().filter((c) => c.pinned === 'right'));
135
+ this.unpinnedColumns = computed(() => this.visibleColumns().filter((c) => !c.pinned));
136
+ this.columnWidths = computed(() => {
137
+ const states = this.columnStates();
138
+ const widths = new Map();
139
+ for (const col of this.columnDefs()) {
140
+ widths.set(col.id, states.get(col.id)?.width ?? col.width ?? 150);
141
+ }
142
+ return widths;
143
+ });
144
+ this.totalColumns = computed(() => this.visibleColumns().length);
145
+ this.visibleRows = computed(() => {
146
+ return this.rowData();
147
+ });
148
+ this.displayRows = computed(() => {
149
+ return this.visibleRows();
150
+ });
151
+ this.totalRows = computed(() => this.displayRows().length);
152
+ this.rowHeight = computed(() => DENSITY_ROW_HEIGHT[this.density()]);
153
+ this.totalHeight = computed(() => this.totalRows() * this.rowHeight());
154
+ this.totalWidth = computed(() => {
155
+ const widths = this.columnWidths();
156
+ let total = 0;
157
+ for (const col of this.visibleColumns()) {
158
+ total += widths.get(col.id) ?? 150;
159
+ }
160
+ return total;
161
+ });
162
+ // Virtual scroll range — which rows are visible
163
+ this.virtualRowRange = computed(() => {
164
+ const rh = this.rowHeight();
165
+ const vh = this.viewportHeight();
166
+ const st = this.scrollTop();
167
+ const total = this.totalRows();
168
+ const buffer = config.bufferRows ?? 5;
169
+ const start = Math.max(0, Math.floor(st / rh) - buffer);
170
+ const visibleCount = Math.ceil(vh / rh);
171
+ const end = Math.min(total, start + visibleCount + buffer * 2);
172
+ return {
173
+ start,
174
+ end,
175
+ offsetY: start * rh,
176
+ totalHeight: total * rh,
177
+ };
178
+ });
179
+ // Virtual scroll range — which columns are visible
180
+ this.virtualColRange = computed(() => {
181
+ const widths = this.columnWidths();
182
+ const vw = this.viewportWidth();
183
+ const sl = this.scrollLeft();
184
+ const cols = this.unpinnedColumns();
185
+ const buffer = 3;
186
+ let start = 0;
187
+ let end = cols.length;
188
+ // Find start column
189
+ let accWidth = 0;
190
+ for (let i = 0; i < cols.length; i++) {
191
+ const w = widths.get(cols[i].id) ?? 150;
192
+ if (accWidth + w > sl) {
193
+ start = Math.max(0, i - buffer);
194
+ break;
195
+ }
196
+ accWidth += w;
197
+ }
198
+ // Find end column
199
+ let accWidth2 = 0;
200
+ for (let i = start; i < cols.length; i++) {
201
+ accWidth2 += widths.get(cols[i].id) ?? 150;
202
+ if (accWidth2 > vw + sl) {
203
+ end = Math.min(cols.length, i + buffer + 1);
204
+ break;
205
+ }
206
+ }
207
+ // Recalculate offsetX
208
+ let finalOffsetX = 0;
209
+ for (let i = 0; i < start; i++) {
210
+ finalOffsetX += widths.get(cols[i].id) ?? 150;
211
+ }
212
+ return {
213
+ start,
214
+ end,
215
+ offsetX: finalOffsetX,
216
+ totalWidth: cols.reduce((sum, c) => sum + (widths.get(c.id) ?? 150), 0),
217
+ };
218
+ });
219
+ // Initialize plugins
220
+ this.pluginHost.init(this);
221
+ }
222
+ // ── Column Operations ──
223
+ /** Get column state by ID. */
224
+ getColumnState(colId) {
225
+ return this.columnStates().get(colId);
226
+ }
227
+ /** Set column width. */
228
+ setColumnWidth(colId, width) {
229
+ const states = new Map(this.columnStates());
230
+ const st = states.get(colId);
231
+ if (st) {
232
+ const col = this.columnDefs().find((c) => c.id === colId);
233
+ const min = col?.minWidth ?? 40;
234
+ const max = col?.maxWidth ?? 600;
235
+ states.set(colId, { ...st, width: Math.max(min, Math.min(max, width)) });
236
+ this.columnStates.set(states);
237
+ }
238
+ }
239
+ /** Toggle column visibility. */
240
+ toggleColumnVisibility(colId) {
241
+ const states = new Map(this.columnStates());
242
+ const st = states.get(colId);
243
+ if (st) {
244
+ states.set(colId, { ...st, visible: !st.visible });
245
+ this.columnStates.set(states);
246
+ }
247
+ }
248
+ /** Set column sort direction. */
249
+ setColumnSort(colId, direction) {
250
+ const states = new Map(this.columnStates());
251
+ const st = states.get(colId);
252
+ if (st) {
253
+ states.set(colId, { ...st, sort: direction });
254
+ this.columnStates.set(states);
255
+ }
256
+ // Update sort state
257
+ const current = this.sortState();
258
+ let criteria;
259
+ if (current.multiSort) {
260
+ const existing = current.criteria.filter((c) => c.colId !== colId);
261
+ if (direction) {
262
+ criteria = [...existing, { colId, direction, index: existing.length }];
263
+ }
264
+ else {
265
+ criteria = existing;
266
+ }
267
+ }
268
+ else {
269
+ // Single sort: clear other sorts
270
+ for (const [id, s] of states) {
271
+ if (id !== colId && s.sort) {
272
+ states.set(id, { ...s, sort: null });
273
+ }
274
+ }
275
+ this.columnStates.set(states);
276
+ criteria = direction ? [{ colId, direction, index: 0 }] : [];
277
+ }
278
+ this.sortState.set({ ...current, criteria });
279
+ }
280
+ /** Reorder columns. */
281
+ moveColumn(fromIndex, toIndex) {
282
+ const cols = [...this.columnDefs()];
283
+ const [moved] = cols.splice(fromIndex, 1);
284
+ if (moved) {
285
+ cols.splice(toIndex, 0, moved);
286
+ this.columnDefs.set(cols);
287
+ }
288
+ }
289
+ // ── Row Operations ──
290
+ /** Insert rows at the given index. */
291
+ insertRows(count, atIndex) {
292
+ const index = atIndex ?? this.rowData().length;
293
+ const rows = [...this.rowData()];
294
+ const newIndices = [];
295
+ for (let i = 0; i < count; i++) {
296
+ const newRow = createEmptyRow(generateRowId(), this.columnDefs());
297
+ rows.splice(index + i, 0, newRow);
298
+ newIndices.push(index + i);
299
+ }
300
+ this.rowData.set(rows);
301
+ return newIndices;
302
+ }
303
+ /** Delete rows by index. */
304
+ deleteRows(indices) {
305
+ const sorted = [...indices].sort((a, b) => b - a);
306
+ const rows = [...this.rowData()];
307
+ const deleted = [];
308
+ for (const idx of sorted) {
309
+ if (idx >= 0 && idx < rows.length) {
310
+ deleted.push(rows[idx]);
311
+ rows.splice(idx, 1);
312
+ }
313
+ }
314
+ this.rowData.set(rows);
315
+ return deleted;
316
+ }
317
+ // ── Cell Operations ──
318
+ /** Get a cell value. */
319
+ getCellValue(rowIndex, colId) {
320
+ return this.rowData()[rowIndex]?.cells[colId]?.value ?? null;
321
+ }
322
+ /** Set a cell value. */
323
+ setCellValue(rowIndex, colId, value) {
324
+ const rows = [...this.rowData()];
325
+ const row = rows[rowIndex];
326
+ if (!row)
327
+ return;
328
+ rows[rowIndex] = {
329
+ ...row,
330
+ cells: {
331
+ ...row.cells,
332
+ [colId]: { value, meta: row.cells[colId]?.meta },
333
+ },
334
+ };
335
+ this.rowData.set(rows);
336
+ }
337
+ /** Get cell metadata. */
338
+ getCellMeta(rowIndex, colId) {
339
+ return this.rowData()[rowIndex]?.cells[colId]?.meta;
340
+ }
341
+ /** Get a column definition by ID. */
342
+ getColumnDef(colId) {
343
+ return this.columnDefs().find((c) => c.id === colId);
344
+ }
345
+ /** Get the 0-based column index by ID. */
346
+ getColIndex(colId) {
347
+ return this.visibleColumns().findIndex((c) => c.id === colId);
348
+ }
349
+ // ── Editing ──
350
+ /** Begin editing a cell. */
351
+ startEdit(rowIndex, colId) {
352
+ if (!this.editable())
353
+ return false;
354
+ if (!this.pluginHost.beforeEdit(rowIndex, colId))
355
+ return false;
356
+ const value = this.getCellValue(rowIndex, colId);
357
+ this.editingCell.set({ row: rowIndex, col: this.getColIndex(colId) });
358
+ this.editingValue.set(value);
359
+ return true;
360
+ }
361
+ /** Commit the current edit. */
362
+ commitEdit() {
363
+ const cell = this.editingCell();
364
+ if (!cell)
365
+ return;
366
+ const col = this.visibleColumns()[cell.col];
367
+ if (!col)
368
+ return;
369
+ const oldValue = this.getCellValue(cell.row, col.id);
370
+ const newValue = this.editingValue();
371
+ if (oldValue !== newValue) {
372
+ this.setCellValue(cell.row, col.id, newValue);
373
+ this.pluginHost.afterEdit(cell.row, col.id, oldValue, newValue);
374
+ }
375
+ this.editingCell.set(null);
376
+ }
377
+ /** Cancel the current edit. */
378
+ cancelEdit() {
379
+ this.editingCell.set(null);
380
+ this.editingValue.set(null);
381
+ }
382
+ // ── Sort ──
383
+ /** Sort by a column (toggles direction). */
384
+ sortBy(colId) {
385
+ const st = this.columnStates().get(colId);
386
+ if (!st)
387
+ return;
388
+ const currentSort = st.sort;
389
+ let newDirection;
390
+ if (currentSort === null) {
391
+ newDirection = 'asc';
392
+ }
393
+ else if (currentSort === 'asc') {
394
+ newDirection = 'desc';
395
+ }
396
+ else {
397
+ newDirection = null;
398
+ }
399
+ if (!this.pluginHost.beforeSort(colId, newDirection))
400
+ return;
401
+ this.setColumnSort(colId, newDirection);
402
+ this.pluginHost.afterSort();
403
+ }
404
+ /** Clear all sorting. */
405
+ clearSort() {
406
+ const states = new Map(this.columnStates());
407
+ for (const [id, st] of states) {
408
+ if (st.sort) {
409
+ states.set(id, { ...st, sort: null, sortIndex: undefined });
410
+ }
411
+ }
412
+ this.columnStates.set(states);
413
+ this.sortState.set({ criteria: [], multiSort: this.sortState().multiSort });
414
+ }
415
+ // ── Filter ──
416
+ /** Apply a filter. */
417
+ applyFilter(colId, operator, value, valueTo) {
418
+ const current = this.filterState();
419
+ const existing = current.criteria.filter((c) => c.colId !== colId);
420
+ const criteria = [...existing, { colId, operator, value, valueTo }];
421
+ this.filterState.set({ ...current, criteria });
422
+ }
423
+ /** Clear filter for a column. */
424
+ clearColumnFilter(colId) {
425
+ const current = this.filterState();
426
+ this.filterState.set({
427
+ ...current,
428
+ criteria: current.criteria.filter((c) => c.colId !== colId),
429
+ });
430
+ }
431
+ /** Clear all filters. */
432
+ clearFilters() {
433
+ this.filterState.set({ criteria: [], mode: 'and' });
434
+ }
435
+ // ── Navigation ──
436
+ /** Move the active cell by delta. */
437
+ navigate(deltaRow, deltaCol) {
438
+ const sel = this.selection();
439
+ const current = sel.activeCell ?? { row: 0, col: 0 };
440
+ const newRow = Math.max(0, Math.min(this.totalRows() - 1, current.row + deltaRow));
441
+ const newCol = Math.max(0, Math.min(this.totalColumns() - 1, current.col + deltaCol));
442
+ this.selection.set({
443
+ ...sel,
444
+ activeCell: { row: newRow, col: newCol },
445
+ range: { start: { row: newRow, col: newCol }, end: { row: newRow, col: newCol } },
446
+ });
447
+ }
448
+ /** Scroll to make a cell visible. */
449
+ scrollToCell(rowIndex, _colIndex) {
450
+ const rh = this.rowHeight();
451
+ const cellTop = rowIndex * rh;
452
+ const cellBottom = cellTop + rh;
453
+ const st = this.scrollTop();
454
+ const vh = this.viewportHeight();
455
+ if (cellTop < st) {
456
+ this.scrollTop.set(cellTop);
457
+ }
458
+ else if (cellBottom > st + vh) {
459
+ this.scrollTop.set(cellBottom - vh);
460
+ }
461
+ }
462
+ // ── Selection ──
463
+ /** Select a cell. */
464
+ selectCell(row, col) {
465
+ this.selection.set({
466
+ ...this.selection(),
467
+ activeCell: { row, col },
468
+ range: { start: { row, col }, end: { row, col } },
469
+ mode: 'cell',
470
+ });
471
+ }
472
+ /** Select a range. */
473
+ selectRange(start, end) {
474
+ this.selection.set({
475
+ ...this.selection(),
476
+ range: { start, end },
477
+ mode: 'range',
478
+ });
479
+ }
480
+ /** Select a row. */
481
+ selectRow(rowIndex) {
482
+ const rows = new Set(this.selection().selectedRows);
483
+ if (rows.has(rowIndex)) {
484
+ rows.delete(rowIndex);
485
+ }
486
+ else {
487
+ rows.add(rowIndex);
488
+ }
489
+ this.selection.set({ ...this.selection(), selectedRows: rows, mode: 'row' });
490
+ }
491
+ /** Select a column. */
492
+ selectColumn(colIndex) {
493
+ const cols = new Set(this.selection().selectedCols);
494
+ if (cols.has(colIndex)) {
495
+ cols.delete(colIndex);
496
+ }
497
+ else {
498
+ cols.add(colIndex);
499
+ }
500
+ this.selection.set({ ...this.selection(), selectedCols: cols, mode: 'column' });
501
+ }
502
+ /** Select all cells. */
503
+ selectAll() {
504
+ const allRows = new Set(Array.from({ length: this.totalRows() }, (_, i) => i));
505
+ const allCols = new Set(Array.from({ length: this.totalColumns() }, (_, i) => i));
506
+ this.selection.set({
507
+ activeCell: { row: 0, col: 0 },
508
+ range: {
509
+ start: { row: 0, col: 0 },
510
+ end: { row: this.totalRows() - 1, col: this.totalColumns() - 1 },
511
+ },
512
+ selectedRows: allRows,
513
+ selectedCols: allCols,
514
+ mode: 'range',
515
+ dragging: false,
516
+ });
517
+ }
518
+ /** Check if a cell is selected. */
519
+ isCellSelected(row, col) {
520
+ const sel = this.selection();
521
+ if (sel.range) {
522
+ const minR = Math.min(sel.range.start.row, sel.range.end.row);
523
+ const maxR = Math.max(sel.range.start.row, sel.range.end.row);
524
+ const minC = Math.min(sel.range.start.col, sel.range.end.col);
525
+ const maxC = Math.max(sel.range.start.col, sel.range.end.col);
526
+ if (row >= minR && row <= maxR && col >= minC && col <= maxC)
527
+ return true;
528
+ }
529
+ return sel.selectedRows.has(row) || sel.selectedCols.has(col);
530
+ }
531
+ /** Check if a cell is the active cell. */
532
+ isCellActive(row, col) {
533
+ const ac = this.selection().activeCell;
534
+ return ac?.row === row && ac?.col === col;
535
+ }
536
+ // ── Refresh ──
537
+ /** Force recalculation by re-setting data. */
538
+ refresh() {
539
+ this.rowData.update((r) => [...r]);
540
+ this.columnStates.update((s) => new Map(s));
541
+ }
542
+ // ── Destroy ──
543
+ destroy() {
544
+ this.pluginHost.destroy();
545
+ }
546
+ }
547
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3ByZWFkc2hlZXQtZW5naW5lLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY2RrL3NwcmVhZHNoZWV0L3NwcmVhZHNoZWV0LWVuZ2luZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBb0MsTUFBTSxlQUFlLENBQUM7QUFlbkYsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxhQUFhLEVBQUUsY0FBYyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUE4RG5FLE1BQU0sa0JBQWtCLEdBQXVDO0lBQzdELE9BQU8sRUFBRSxFQUFFO0lBQ1gsV0FBVyxFQUFFLEVBQUU7SUFDZixLQUFLLEVBQUUsRUFBRTtDQUNWLENBQUM7QUFFRixNQUFNLHFCQUFxQixHQUF1QztJQUNoRSxPQUFPLEVBQUUsRUFBRTtJQUNYLFdBQVcsRUFBRSxFQUFFO0lBQ2YsS0FBSyxFQUFFLEVBQUU7Q0FDVixDQUFDO0FBRUYsTUFBTSxvQkFBb0IsR0FBdUM7SUFDL0QsT0FBTyxFQUFFLFNBQVM7SUFDbEIsV0FBVyxFQUFFLFVBQVU7SUFDdkIsS0FBSyxFQUFFLFNBQVM7Q0FDakIsQ0FBQztBQUVGOzs7Ozs7R0FNRztBQUNILE1BQU0sT0FBTyxpQkFBaUI7SUFpRzVCLFlBQVksU0FBNEIsRUFBRTtRQUN4QyxJQUFJLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQztRQUN0QixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksVUFBVSxFQUFFLENBQUM7UUFFbkMsVUFBVTtRQUNWLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLElBQUksYUFBYSxDQUFDLENBQUM7UUFDdkQsSUFBSSxDQUFDLFFBQVEsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsQ0FBQztRQUNoRCxJQUFJLENB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QyxTQUFTLEVBQUUsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUUsR0FBRyxDQUFDLEVBQUU7YUFDakU7WUFDRCxZQUFZLEVBQUUsT0FBTztZQUNyQixZQUFZLEVBQUUsT0FBTztZQUNyQixJQUFJLEVBQUUsT0FBTztZQUNiLFFBQVEsRUFBRSxLQUFLO1NBQ2hCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxtQ0FBbUM7SUFDbkMsY0FBYyxDQUFDLEdBQVcsRUFBRSxHQUFXO1FBQ3JDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUM3QixJQUFJLEdBQUcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNkLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQzlELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQzlELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQzlELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQzlELElBQUksR0FBRyxJQUFJLElBQUksSUFBSSxHQUFHLElBQUksSUFBSSxJQUFJLEdBQUcsSUFBSSxJQUFJLElBQUksR0FBRyxJQUFJLElBQUk7Z0JBQUUsT0FBTyxJQUFJLENBQUM7UUFDNUUsQ0FBQztRQUNELE9BQU8sR0FBRyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDaEUsQ0FBQztJQUVELDBDQUEwQztJQUMxQyxZQUFZLENBQUMsR0FBVyxFQUFFLEdBQVc7UUFDbkMsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLFVBQVUsQ0FBQztRQUN2QyxPQUFPLEVBQUUsRUFBRSxHQUFHLEtBQUssR0FBRyxJQUFJLEVBQUUsRUFBRSxHQUFHLEtBQUssR0FBRyxDQUFDO0lBQzVDLENBQUM7SUFFRCxnQkFBZ0I7SUFFaEIsOENBQThDO0lBQzlDLE9BQU87UUFDTCxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbkMsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUVELGdCQUFnQjtJQUVoQixPQUFPO1FBQ0wsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUM1QixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjb21wdXRlZCwgc2lnbmFsLCB0eXBlIFdyaXRhYmxlU2lnbmFsLCB0eXBlIFNpZ25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHR5cGUge1xuICBDZWxsVmFsdWUsXG4gIENlbGxBZGRyZXNzLFxuICBDZWxsTWV0YSxcbiAgQ29sdW1uRGVmLFxuICBDb2x1bW5TdGF0ZSxcbiAgUm93RGVmLFxuICBTZWxlY3Rpb25TdGF0ZSxcbiAgU29ydFN0YXRlLFxuICBTb3J0Q3JpdGVyaW9uLFxuICBGaWx0ZXJTdGF0ZSxcbiAgRmlsdGVyQ3JpdGVyaW9uLFxufSBmcm9tICcuL21vZGVscyc7XG5pbXBvcnQgdHlwZSB7IFNwcmVhZHNoZWV0UGx1Z2luIH0gZnJvbSAnLi9wbHVnaW4vcGx1Z2luLnR5cGVzJztcbmltcG9ydCB7IFBsdWdpbkhvc3QgfSBmcm9tICcuL3BsdWdpbi9wbHVnaW4taG9zdCc7XG5pbXBvcnQgeyBnZW5lcmF0ZVJvd0lkLCBjcmVhdGVFbXB0eVJvdyB9IGZyb20gJy4vdXRpbHMvY2VsbC11dGlscyc7XG5cbi8qKiBEZW5zaXR5IHByZXNldHMgY29udHJvbGxpbmcgcm93IGhlaWdodCBhbmQgY2VsbCBwYWRkaW5nLiAqL1xuZXhwb3J0IHR5cGUgU3ByZWFkc2hlZXREZW5zaXR5ID0gJ2NvbXBhY3QnIHwgJ2NvbWZvcnRhYmxlJyB8ICdkZW5zZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3ByZWFkc2hlZXRDb25maWcge1xuICAvKiogQ29sdW1uIGRlZmluaXRpb25zLiAqL1xuICBjb2x1bW5zPzogQ29sdW1uRGVmW107XG4gIC8qKiBJbml0aWFsIHJvdyBkYXRhLiAqL1xuICByb3dzPzogUm93RGVmW107XG4gIC8qKiBFbmFibGUgbXVsdGktY29sdW1uIHNvcnRpbmcuICovXG4gIG11bHRpU29ydD86IGJvb2xlYW47XG4gIC8qKiBTZWxlY3Rpb24gbW9kZS4gKi9cbiAgc2VsZWN0aW9uTW9kZT86ICdjZWxsJyB8ICdyYW5nZScgfCAncm93JyB8ICdjb2x1bW4nIHwgJ25vbmUnO1xuICAvKiogRGVuc2l0eSBwcmVzZXQuICovXG4gIGRlbnNpdHk/OiBTcHJlYWRzaGVldERlbnNpdHk7XG4gIC8qKiBFbmFibGUgaW5saW5lIGVkaXRpbmcuICovXG4gIGVkaXRhYmxlPzogYm9vbGVhbjtcbiAgLyoqIEVuYWJsZSBmb3JtdWxhIGV2YWx1YXRpb24uICovXG4gIGZvcm11bGFzPzogYm9vbGVhbjtcbiAgLyoqIE51bWJlciBvZiByb3dzIHRvIHJlbmRlciBpbiB0aGUgdmlld3BvcnQgYnVmZmVyLiAqL1xuICBidWZmZXJSb3dzPzogbnVtYmVyO1xuICAvKiogUm93IGhlaWdodCBpbiBweCAodXNlZCBmb3IgdmlydHVhbCBzY3JvbGwgY2FsY3VsYXRpb25zKS4gKi9cbiAgcm93SGVpZ2h0PzogbnVtYmVyO1xuICAvKiogSGVhZGVyIGhlaWdodCBpbiBweC4gKi9cbiAgaGVhZGVySGVpZ2h0PzogbnVtYmVyO1xuICAvKiogUGx1Z2lucyB0byByZWdpc3Rlci4gKi9cbiAgcGx1Z2lucz86IFNwcmVhZHNoZWV0UGx1Z2luW107XG4gIC8qKiBFbmFibGUgdHJlZSAvIGhpZXJhcmNoaWNhbCBkYXRhLiAqL1xuICB0cmVlRGF0YT86IGJvb2xlYW47XG4gIC8qKiBSVEwgbGF5b3V0LiAqL1xuICBydGw/OiBib29sZWFuO1xuICAvKiogRnJvemVuIHJvdyBjb3VudC4gKi9cbiAgZnJvemVuUm93cz86IG51bWJlcjtcbiAgLyoqIEZyb3plbiBjb2x1bW4gY291bnQuICovXG4gIGZyb3plbkNvbHVtbnM/OiBudW1iZXI7XG59XG5cbi8qKiBMaWZlY3ljbGUgaG9va3MgZm9yIGJlZm9yZS9hZnRlciBvcGVyYXRpb25zLiAqL1xuZXhwb3J0IGludGVyZmFjZSBTcHJlYWRzaGVldExpZmVjeWNsZUhvb2tzIHtcbiAgYmVmb3JlRWRpdDogU2lnbmFsPChyb3dJbmRleDogbnVtYmVyLCBjb2xJZDogc3RyaW5nKSA9PiBib29sZWFuPjtcbiAgYWZ0ZXJFZGl0OiBTaWduYWw8XG4gICAgKHJvd0luZGV4OiBudW1iZXIsIGNvbElkOiBzdHJpbmcsIG9sZFZhbHVlOiBDZWxsVmFsdWUsIG5ld1ZhbHVlOiBDZWxsVmFsdWUpID0+IHZvaWRcbiAgPjtcbiAgYmVmb3JlU29ydDogU2lnbmFsPChjb2xJZDogc3RyaW5nLCBkaXJlY3Rpb246ICdhc2MnIHwgJ2Rlc2MnIHwgbnVsbCkgPT4gYm9vbGVhbj47XG4gIGFmdGVyU29ydDogU2lnbmFsPCgpID0+IHZvaWQ+O1xuICBiZWZvcmVGaWx0ZXI6IFNpZ25hbDwoKSA9PiBib29sZWFuPjtcbiAgYWZ0ZXJGaWx0ZXI6IFNpZ25hbDwoKSA9PiB2b2lkPjtcbiAgYmVmb3JlSW5zZXJ0Um93czogU2lnbmFsPChjb3VudDogbnVtYmVyLCBhdEluZGV4OiBudW1iZXIpID0+IGJvb2xlYW4+O1xuICBhZnRlckluc2VydFJvd3M6IFNpZ25hbDwoaW5kaWNlczogbnVtYmVyW10pID0+IHZvaWQ+O1xuICBiZWZvcmVEZWxldGVSb3dzOiBTaWduYWw8KGluZGljZXM6IG51bWJlcltdKSA9PiBib29sZWFuPjtcbiAgYWZ0ZXJEZWxldGVSb3dzOiBTaWduYWw8KGluZGljZXM6IG51bWJlcltdKSA9PiB2b2lkPjtcbiAgYmVmb3JlSW5zZXJ0Q29sdW1uczogU2lnbmFsPChjb3VudDogbnVtYmVyLCBhdEluZGV4OiBudW1iZXIpID0+IGJvb2xlYW4+O1xuICBhZnRlckluc2VydENvbHVtbnM6IFNpZ25hbDwoaW5kaWNlczogbnVtYmVyW10pID0+IHZvaWQ+O1xuICBiZWZvcmVEZWxldGVDb2x1bW5zOiBTaWduYWw8KGluZGljZXM6IG51bWJlcltdKSA9PiBib29sZWFuPjtcbiAgYWZ0ZXJEZWxldGVDb2x1bW5zOiBTaWduYWw8KGluZGljZXM6IG51bWJlcltdKSA9PiB2b2lkPjtcbiAgYmVmb3JlQ29weTogU2lnbmFsPCgpID0+IGJvb2xlYW4+O1xuICBhZnRlckNvcHk6IFNpZ25hbDwoKSA9PiB2b2lkPjtcbiAgYmVmb3JlUGFzdGU6IFNpZ25hbDwoZGF0YTogc3RyaW5nLCBzdGFydENlbGw6IENlbGxBZGRyZXNzKSA9PiBib29sZWFuPjtcbiAgYWZ0ZXJQYXN0ZTogU2lnbmFsPCgpID0+IHZvaWQ+O1xufVxuXG5jb25zdCBERU5TSVRZX1JPV19IRUlHSFQ6IFJlY29yZDxTcHJlYWRzaGVldERlbnNpdHksIG51bWJlcj4gPSB7XG4gIGNvbXBhY3Q6IDI4LFxuICBjb21mb3J0YWJsZTogMzYsXG4gIGRlbnNlOiAyNCxcbn07XG5cbmNvbnN0IERFTlNJVFlfSEVBREVSX0hFSUdIVDogUmVjb3JkPFNwcmVhZHNoZWV0RGVuc2l0eSwgbnVtYmVyPiA9IHtcbiAgY29tcGFjdDogMzIsXG4gIGNvbWZvcnRhYmxlOiA0MCxcbiAgZGVuc2U6IDI4LFxufTtcblxuY29uc3QgREVOU0lUWV9DRUxMX1BBRERJTkc6IFJlY29yZDxTcHJlYWRzaGVldERlbnNpdHksIHN0cmluZz4gPSB7XG4gIGNvbXBhY3Q6ICcycHggNnB4JyxcbiAgY29tZm9ydGFibGU6ICc2cHggMTBweCcsXG4gIGRlbnNlOiAnMnB4IDRweCcsXG59O1xuXG4vKipcbiAqIFNwcmVhZHNoZWV0RW5naW5lIOKAlCBoZWFkbGVzcywgc2lnbmFsLWJhc2VkIHN0YXRlIG1hY2hpbmUgZm9yIHNwcmVhZHNoZWV0IGRhdGEuXG4gKiBaZXJvIERPTSwgemVybyBBbmd1bGFyIGRlcGVuZGVuY2llcyBiZXlvbmQgc2lnbmFscy5cbiAqXG4gKiBTdXBwb3J0czogY29sdW1ucywgcm93cywgc29ydGluZywgZmlsdGVyaW5nLCBzZWxlY3Rpb24sIGVkaXRpbmcsXG4gKiB1bmRvL3JlZG8sIGNsaXBib2FyZCwgZm9ybXVsYXMsIHRyZWUgZGF0YSwgdmlydHVhbCBzY3JvbGxpbmcgc3RhdGUuXG4gKi9cbmV4cG9ydCBjbGFzcyBTcHJlYWRzaGVldEVuZ2luZSB7XG4gIC8vIOKUgOKUgCBDb3JlIERhdGEg4pSA4pSAXG4gIHJlYWRvbmx5IGNvbHVtbkRlZnM6IFdyaXRhYmxlU2lnbmFsPENvbHVtbkRlZltdPjtcbiAgcmVhZG9ubHkgcm93RGF0YTogV3JpdGFibGVTaWduYWw8Um93RGVmW10+O1xuICByZWFkb25seSBjb2x1bW5TdGF0ZXM6IFdyaXRhYmxlU2lnbmFsPE1hcDxzdHJpbmcsIENvbHVtblN0YXRlPj47XG5cbiAgLy8g4pSA4pSAIFN0YXRlIOKUgOKUgFxuICByZWFkb25seSBzZWxlY3Rpb246IFdyaXRhYmxlU2lnbmFsPFNlbGVjdGlvblN0YXRlPjtcbiAgcmVhZG9ubHkgc29ydFN0YXRlOiBXcml0YWJsZVNpZ25hbDxTb3J0U3RhdGU+O1xuICByZWFkb25seSBmaWx0ZXJTdGF0ZTogV3JpdGFibGVTaWduYWw8RmlsdGVyU3RhdGU+O1xuICByZWFkb25seSBwbHVnaW5zOiBXcml0YWJsZVNpZ25hbDxTcHJlYWRzaGVldFBsdWdpbltdPjtcblxuICAvLyDilIDilIAgRWRpdGluZyDilIDilIBcbiAgcmVhZG9ubHkgZWRpdGluZ0NlbGw6IFdyaXRhYmxlU2lnbmFsPENlbGxBZGRyZXNzIHwgbnVsbD47XG4gIHJlYWRvbmx5IGVkaXRpbmdWYWx1ZTogV3JpdGFibGVTaWduYWw8Q2VsbFZhbHVlPjtcblxuICAvLyDilIDilIAgQ29uZmlnIOKUgOKUgFxuICByZWFkb25seSBkZW5zaXR5OiBXcml0YWJsZVNpZ25hbDxTcHJlYWRzaGVldERlbnNpdHk+O1xuICByZWFkb25seSBlZGl0YWJsZTogV3JpdGFibGVTaWduYWw8Ym9vbGVhbj47XG4gIHJlYWRvbmx5IHJ0bDogV3JpdGFibGVTaWduYWw8Ym9vbGVhbj47XG4gIHJlYWRvbmx5IGZyb3plblJvd3M6IFdyaXRhYmxlU2lnbmFsPG51bWJlcj47XG4gIHJlYWRvbmx5IGZyb3plbkNvbHVtbnM6IFdyaXRhYmxlU2lnbmFsPG51bWJlcj47XG5cbiAgLy8g4pSA4pSAIFNjcm9sbCBTdGF0ZSDilIDilIBcbiAgcmVhZG9ubHkgc2Nyb2xsVG9wOiBXcml0YWJsZVNpZ25hbDxudW1iZXI+O1xuICByZWFkb25seSBzY3JvbGxMZWZ0OiBXcml0YWJsZVNpZ25hbDxudW1iZXI+O1xuICByZWFkb25seSB2aWV3cG9ydEhlaWdodDogV3JpdGFibGVTaWduYWw8bnVtYmVyPjtcbiAgcmVhZG9ubHkgdmlld3BvcnRXaWR0aDogV3JpdGFibGVTaWduYWw8bnVtYmVyPjtcblxuICAvLyDilIDilIAgUGx1Z2luIEhvc3Qg4pSA4pSAXG4gIHJlYWRvbmx5IHBsdWdpbkhvc3Q6IFBsdWdpbkhvc3Q7XG5cbiAgLy8g4pSA4pSAIENvbXB1dGVkIOKUgOKUgFxuXG4gIC8qKiBWaXNpYmxlIHJvd3MgYWZ0ZXIgZmlsdGVyaW5nLiAqL1xuICByZWFkb25seSB2aXNpYmxlUm93czogU2lnbmFsPFJvd0RlZltdPjtcblxuICAvKiogU29ydGVkICsgZmlsdGVyZWQgcm93cy4gKi9cbiAgcmVhZG9ubHkgZGlzcGxheVJvd3M6IFNpZ25hbDxSb3dEZWZbXT47XG5cbiAgLyoqIFZpc2libGUgcm93IHJhbmdlIGZvciB2aXJ0dWFsIHNjcm9sbGluZyAoc3RhcnRJbmRleCwgZW5kSW5kZXgpLiAqL1xuICByZWFkb25seSB2aXJ0dWFsUm93UmFuZ2U6IFNpZ25hbDx7XG4gICAgc3RhcnQ6IG51bWJlcjtcbiAgICBlbmQ6IG51bWJlcjtcbiAgICBvZmZzZXRZOiBudW1iZXI7XG4gICAgdG90YWxIZWlnaHQ6IG51bWJlcjtcbiAgfT47XG5cbiAgLyoqIFZpc2libGUgY29sdW1uIHJhbmdlIGZvciBob3Jpem9udGFsIHZpcnR1YWwgc2Nyb2xsaW5nLiAqL1xuICByZWFkb25seSB2aXJ0dWFsQ29sUmFuZ2U6IFNpZ25hbDx7XG4gICAgc3RhcnQ6IG51bWJlcjtcbiAgICBlbmQ6IG51bWJlcjtcbiAgICBvZmZzZXRYOiBudW1iZXI7XG4gICAgdG90YWxXaWR0aDogbnVtYmVyO1xuICB9PjtcblxuICAvKiogUm93IGhlaWdodCBmb3IgY3VycmVudCBkZW5zaXR5LiAqL1xuICByZWFkb25seSByb3dIZWlnaHQ6IFNpZ25hbDxudW1iZXI+O1xuXG4gIC8qKiBIZWFkZXIgaGVpZ2h0IGZvciBjdXJyZW50IGRlbnNpdHkuICovXG4gIHJlYWRvbmx5IGhlYWRlckhlaWdodDogU2lnbmFsPG51bWJlcj47XG5cbiAgLyoqIENlbGwgcGFkZGluZyBmb3IgY3VycmVudCBkZW5zaXR5LiAqL1xuICByZWFkb25seSBjZWxsUGFkZGluZzogU2lnbmFsPHN0cmluZz47XG5cbiAgLyoqIFRvdGFsIG51bWJlciBvZiByb3dzLiAqL1xuICByZWFkb25seSB0b3RhbFJvd3M6IFNpZ25hbDxudW1iZXI+O1xuXG4gIC8qKiBUb3RhbCBudW1iZXIgb2YgY29sdW1ucy4gKi9cbiAgcmVhZG9ubHkgdG90YWxDb2x1bW5zOiBTaWduYWw8bnVtYmVyPjtcblxuICAvKiogVG90YWwgc2Nyb2xsYWJsZSBoZWlnaHQuICovXG4gIHJlYWRvbmx5IHRvdGFsSGVpZ2h0OiBTaWduYWw8bnVtYmVyPjtcblxuICAvKiogVG90YWwgc2Nyb2xsYWJsZSB3aWR0aC4gKi9cbiAgcmVhZG9ubHkgdG90YWxXaWR0aDogU2lnbmFsPG51bWJlcj47XG5cbiAgLyoqIFZpc2libGUgKG5vbi1oaWRkZW4pIGNvbHVtbnMuICovXG4gIHJlYWRvbmx5IHZpc2libGVDb2x1bW5zOiBTaWduYWw8Q29sdW1uRGVmW10+O1xuXG4gIC8qKiBQaW5uZWQgbGVmdCBjb2x1bW5zLiAqL1xuICByZWFkb25seSBwaW5uZWRMZWZ0Q29sdW1uczogU2lnbmFsPENvbHVtbkRlZltdPjtcblxuICAvKiogUGlubmVkIHJpZ2h0IGNvbHVtbnMuICovXG4gIHJlYWRvbmx5IHBpbm5lZFJpZ2h0Q29sdW1uczogU2lnbmFsPENvbHVtbkRlZltdPjtcblxuICAvKiogVW5waW5uZWQgKHNjcm9sbGFibGUpIGNvbHVtbnMuICovXG4gIHJlYWRvbmx5IHVucGlubmVkQ29sdW1uczogU2lnbmFsPENvbHVtbkRlZltdPjtcblxuICAvKiogQ29sdW1uIHdpZHRoIG1hcCBmb3IgY29tcHV0ZWQgd2lkdGhzLiAqL1xuICByZWFkb25seSBjb2x1bW5XaWR0aHM6IFNpZ25hbDxNYXA8c3RyaW5nLCBudW1iZXI+PjtcblxuICAvLyDilIDilIAgTGlmZWN5Y2xlIOKUgOKUgFxuICByZWFkb25seSBsaWZlY3ljbGU6IFNwcmVhZHNoZWV0TGlmZWN5Y2xlSG9va3M7XG5cbiAgcHJpdmF0ZSBfY29uZmlnOiBTcHJlYWRzaGVldENvbmZpZztcblxuICBjb25zdHJ1Y3Rvcihjb25maWc6IFNwcmVhZHNoZWV0Q29uZmlnID0ge30pIHtcbiAgICB0aGlzLl9jb25maWcgPSBjb25maWc7XG4gICAgdGhpcy5wbHVnaW5Ib3N0ID0gbmV3IFBsdWdpbkhvc3QoKTtcblxuICAgIC8vIERlbnNpdHlcbiAgICB0aGlzLmRlbnNpdHkgPSBzaWduYWwoY29uZmlnLmRlbnNpdHkgPz8gJ2NvbWZvcnRhYmxlJyk7XG4gICAgdGhpcy5lZGl0YWJsZSA9IHNpZ25hbChjb25maWcuZWRpdGFibGUgPz8gdHJ1ZSk7XG4gICAgdGhpcy5ydGwgPSBzaWduYWwoY29uZmlnLnJ0bCA/PyBmYWxzZSk7XG4gICAgdGhpcy5mcm96ZW5Sb3dzID0gc2lnbmFsKGNvbmZpZy5mcm96ZW5Sb3dzID8/IDApO1xuICAgIHRoaXMuZnJvemVuQ29sdW1ucyA9IHNpZ25hbChjb25maWcuZnJvemVuQ29sdW1ucyA/PyAwKTtcblxuICAgIC8vIFJvdy9jb2x1bW4gaGVpZ2h0IGNvbXB1dGVkIGZyb20gZGVuc2l0eVxuICAgIHRoaXMucm93SGVpZ2h0ID0gY29tcHV0ZWQoKCkgPT4gREVOU0lUWV9ST1dfSEVJR0hUW3RoaXMuZGVuc2l0eSgpXSk7XG4gICAgdGhpcy5oZWFkZXJIZWlnaHQgPSBjb21wdXRlZCgoKSA9PiBERU5TSVRZX0hFQURFUl9IRUlHSFRbdGhpcy5kZW5zaXR5KCldKTtcbiAgICB0aGlzLmNlbGxQYWRkaW5nID0gY29tcHV0ZWQoKCkgPT4gREVOU0lUWV9DRUxMX1BBRERJTkdbdGhpcy5kZW5zaXR5KCldKTtcblxuICAgIC8vIENvbHVtbiBkZWZpbml0aW9uc1xuICAgIHRoaXMuY29sdW1uRGVmcyA9IHNpZ25hbChjb25maWcuY29sdW1ucyA/PyBbXSk7XG5cbiAgICAvLyBDb2x1bW4gc3RhdGVzICh3aWR0aCwgdmlzaWJpbGl0eSwgcGluLCBzb3J0KVxuICAgIGNvbnN0IGluaXRpYWxTdGF0ZXMgPSBuZXcgTWFwPHN0cmluZywgQ29sdW1uU3RhdGU+KCk7XG4gICAgKGNvbmZpZy5jb2x1bW5zID8/IFtdKS5mb3JFYWNoKChjb2wsIGlkeCkgPT4ge1xuICAgICAgaW5pdGlhbFN0YXRlcy5zZXQoY29sLmlkLCB7XG4gICAgICAgIGlkOiBjb2wuaWQsXG4gICAgICAgIHdpZHRoOiBjb2wud2lkdGggPz8gMTUwLFxuICAgICAgICB2aXNpYmxlOiBjb2wudmlzaWJsZSAhPT0gZmFsc2UsXG4gICAgICAgIHBpbm5lZDogY29sLnBpbm5lZCA/PyBmYWxzZSxcbiAgICAgICAgc29ydDogY29sLnNvcnQgPz8gbnVsbCxcbiAgICAgICAgc29ydEluZGV4OiB1bmRlZmluZWQsXG4gICAgICAgIG9yZGVyOiBpZHgsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgICB0aGlzLmNvbHVtblN0YXRlcyA9IHNpZ25hbChpbml0aWFsU3RhdGVzKTtcblxuICAgIC8vIFJvdyBkYXRhXG4gICAgdGhpcy5yb3dEYXRhID0gc2lnbmFsKGNvbmZpZy5yb3dzID8/IFtdKTtcblxuICAgIC8vIFNlbGVjdGlvblxuICAgIHRoaXMuc2VsZWN0aW9uID0gc2lnbmFsPFNlbGVjdGlvblN0YXRlPih7XG4gICAgICBhY3RpdmVDZWxsOiBudWxsLFxuICAgICAgcmFuZ2U6IG51bGwsXG4gICAgICBzZWxlY3RlZFJvd3M6IG5ldyBTZXQoKSxcbiAgICAgIHNlbGVjdGVkQ29sczogbmV3IFNldCgpLFxuICAgICAgbW9kZTogY29uZmlnLnNlbGVjdGlvbk1vZGUgPz8gJ2NlbGwnLFxuICAgICAgZHJhZ2dpbmc6IGZhbHNlLFxuICAgIH0pO1xuXG4gICAgLy8gU29ydFxuICAgIHRoaXMuc29ydFN0YXRlID0gc2lnbmFsPFNvcnRTdGF0ZT4oe1xuICAgICAgY3JpdGVyaWE6IChjb25maWcuY29sdW1ucyA/PyBbXSlcbiAgICAgICAgLmZpbHRlcigoYykgPT4gYy5zb3J0KVxuICAgICAgICAubWFwKChjLCBpKSA9PiAoeyBjb2xJZDogYy5pZCwgZGlyZWN0aW9uOiBjLnNvcnQhLCBpbmRleDogaSB9KSksXG4gICAgICBtdWx0aVNvcnQ6IGNvbmZpZy5tdWx0aVNvcnQgPz8gZmFsc2UsXG4gICAgfSk7XG5cbiAgICAvLyBGaWx0ZXJcbiAgICB0aGlzLmZpbHRlclN0YXRlID0gc2lnbmFsPEZpbHRlclN0YXRlPih7IGNyaXRlcmlhOiBbXSwgbW9kZTogJ2FuZCcgfSk7XG5cbiAgICAvLyBFZGl0aW5nXG4gICAgdGhpcy5lZGl0aW5nQ2VsbCA9IHNpZ25hbChudWxsKTtcbiAgICB0aGlzLmVkaXRpbmdWYWx1ZSA9IHNpZ25hbChudWxsKTtcblxuICAgIC8vIFNjcm9sbFxuICAgIHRoaXMuc2Nyb2xsVG9wID0gc2lnbmFsKDApO1xuICAgIHRoaXMuc2Nyb2xsTGVmdCA9IHNpZ25hbCgwKTtcbiAgICB0aGlzLnZpZXdwb3J0SGVpZ2h0ID0gc2lnbmFsKDYwMCk7XG4gICAgdGhpcy52aWV3cG9ydFdpZHRoID0gc2lnbmFsKDgwMCk7XG5cbiAgICAvLyBQbHVnaW5zXG4gICAgdGhpcy5wbHVnaW5zID0gc2lnbmFsKGNvbmZpZy5wbHVnaW5zID8/IFtdKTtcblxuICAgIC8vIExpZmVjeWNsZSBob29rc1xuICAgIHRoaXMubGlmZWN5Y2xlID0ge1xuICAgICAgYmVmb3JlRWRpdDogc2lnbmFsKCgpID0+IHRydWUpLFxuICAgICAgYWZ0ZXJFZGl0OiBzaWduYWwoKCkgPT4ge1xuICAgICAgICAvKiBub29wICovXG4gICAgICB9KSxcbiAgICAgIGJlZm9yZVNvcnQ6IHNpZ25hbCgoKSA9PiB0cnVlKSxcbiAgICAgIGFmdGVyU29ydDogc2lnbmFsKCgpID0+IHtcbiAgICAgICAgLyogbm9vcCAqL1xuICAgICAgfSksXG4gICAgICBiZWZvcmVGaWx0ZXI6IHNpZ25hbCgoKSA9PiB0cnVlKSxcbiAgICAgIGFmdGVyRmlsdGVyOiBzaWduYWwoKCkgPT4ge1xuICAgICAgICAvKiBub29wICovXG4gICAgICB9KSxcbiAgICAgIGJlZm9yZUluc2VydFJvd3M6IHNpZ25hbCgoKSA9PiB0cnVlKSxcbiAgICAgIGFmdGVySW5zZXJ0Um93czogc2lnbmFsKCgpID0+IHtcbiAgICAgICAgLyogbm9vcCAqL1xuICAgICAgfSksXG4gICAgICBiZWZvcmVEZWxldGVSb3dzOiBzaWduYWwoKCkgPT4gdHJ1ZSksXG4gICAgICBhZnRlckRlbGV0ZVJvd3M6IHNpZ25hbCgoKSA9PiB7XG4gICAgICAgIC8qIG5vb3AgKi9cbiAgICAgIH0pLFxuICAgICAgYmVmb3JlSW5zZXJ0Q29sdW1uczogc2lnbmFsKCgpID0+IHRydWUpLFxuICAgICAgYWZ0ZXJJbnNlcnRDb2x1bW5zOiBzaWduYWwoKCkgPT4ge1xuICAgICAgICAvKiBub29wICovXG4gICAgICB9KSxcbiAgICAgIGJlZm9yZURlbGV0ZUNvbHVtbnM6IHNpZ25hbCgoKSA9PiB0cnVlKSxcbiAgICAgIGFmdGVyRGVsZXRlQ29sdW1uczogc2lnbmFsKCgpID0+IHtcbiAgICAgICAgLyogbm9vcCAqL1xuICAgICAgfSksXG4gICAgICBiZWZvcmVDb3B5OiBzaWduYWwoKCkgPT4gdHJ1ZSksXG4gICAgICBhZnRlckNvcHk6IHNpZ25hbCgoKSA9PiB7XG4gICAgICAgIC8qIG5vb3AgKi9cbiAgICAgIH0pLFxuICAgICAgYmVmb3JlUGFzdGU6IHNpZ25hbCgoKSA9PiB0cnVlKSxcbiAgICAgIGFmdGVyUGFzdGU6IHNpZ25hbCgoKSA9PiB7XG4gICAgICAgIC8qIG5vb3AgKi9cbiAgICAgIH0pLFxuICAgIH07XG5cbiAgICAvLyDilIDilIAgQ29tcHV0ZWQg4pSA4pSAXG5cbiAgICB0aGlzLnZpc2libGVDb2x1bW5zID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgICAgY29uc3Qgc3RhdGVzID0gdGhpcy5jb2x1bW5TdGF0ZXMoKTtcbiAgICAgIHJldHVybiB0aGlzLmNvbHVtbkRlZnMoKS5maWx0ZXIoKGNvbCkgPT4ge1xuICAgICAgICBjb25zdCBzdCA9IHN0YXRlcy5nZXQoY29sLmlkKTtcbiAgICAgICAgcmV0dXJuIHN0Py52aXNpYmxlID8/IHRydWU7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRoaXMucGlubmVkTGVmdENvbHVtbnMgPSBjb21wdXRlZCgoKSA9PlxuICAgICAgdGhpcy52aXNpYmxlQ29sdW1ucygpLmZpbHRlcigoYykgPT4gYy5waW5uZWQgPT09ICdsZWZ0JyksXG4gICAgKTtcblxuICAgIHRoaXMucGlubmVkUmlnaHRDb2x1bW5zID0gY29tcHV0ZWQoKCkgPT5cbiAgICAgIHRoaXMudmlzaWJsZUNvbHVtbnMoKS5maWx0ZXIoKGMpID0+IGMucGlubmVkID09PSAncmlnaHQnKSxcbiAgICApO1xuXG4gICAgdGhpcy51bnBpbm5lZENvbHVtbnMgPSBjb21wdXRlZCgoKSA9PiB0aGlzLnZpc2libGVDb2x1bW5zKCkuZmlsdGVyKChjKSA9PiAhYy5waW5uZWQpKTtcblxuICAgIHRoaXMuY29sdW1uV2lkdGhzID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgICAgY29uc3Qgc3RhdGVzID0gdGhpcy5jb2x1bW5TdGF0ZXMoKTtcbiAgICAgIGNvbnN0IHdpZHRocyA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gICAgICBmb3IgKGNvbnN0IGNvbCBvZiB0aGlzLmNvbHVtbkRlZnMoKSkge1xuICAgICAgICB3aWR0aHMuc2V0KGNvbC5pZCwgc3RhdGVzLmdldChjb2wuaWQpPy53aWR0aCA/PyBjb2wud2lkdGggPz8gMTUwKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB3aWR0aHM7XG4gICAgfSk7XG5cbiAgICB0aGlzLnRvdGFsQ29sdW1ucyA9IGNvbXB1dGVkKCgpID0+IHRoaXMudmlzaWJsZUNvbHVtbnMoKS5sZW5ndGgpO1xuXG4gICAgdGhpcy52aXNpYmxlUm93cyA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnJvd0RhdGEoKTtcbiAgICB9KTtcblxuICAgIHRoaXMuZGlzcGxheVJvd3MgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy52aXNpYmxlUm93cygpO1xuICAgIH0pO1xuXG4gICAgdGhpcy50b3RhbFJvd3MgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmRpc3BsYXlSb3dzKCkubGVuZ3RoKTtcblxuICAgIHRoaXMucm93SGVpZ2h0ID0gY29tcHV0ZWQoKCkgPT4gREVOU0lUWV9ST1dfSEVJR0hUW3RoaXMuZGVuc2l0eSgpXSk7XG5cbiAgICB0aGlzLnRvdGFsSGVpZ2h0ID0gY29tcHV0ZWQoKCkgPT4gdGhpcy50b3RhbFJvd3MoKSAqIHRoaXMucm93SGVpZ2h0KCkpO1xuXG4gICAgdGhpcy50b3RhbFdpZHRoID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgICAgY29uc3Qgd2lkdGhzID0gdGhpcy5jb2x1bW5XaWR0aHMoKTtcbiAgICAgIGxldCB0b3RhbCA9IDA7XG4gICAgICBmb3IgKGNvbnN0IGNvbCBvZiB0aGlzLnZpc2libGVDb2x1bW5zKCkpIHtcbiAgICAgICAgdG90YWwgKz0gd2lkdGhzLmdldChjb2wuaWQpID8/IDE1MDtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0b3RhbDtcbiAgICB9KTtcblxuICAgIC8vIFZpcnR1YWwgc2Nyb2xsIHJhbmdlIOKAlCB3aGljaCByb3dzIGFyZSB2aXNpYmxlXG4gICAgdGhpcy52aXJ0dWFsUm93UmFuZ2UgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgICBjb25zdCByaCA9IHRoaXMucm93SGVpZ2h0KCk7XG4gICAgICBjb25zdCB2aCA9IHRoaXMudmlld3BvcnRIZWlnaHQoKTtcbiAgICAgIGNvbnN0IHN0ID0gdGhpcy5zY3JvbGxUb3AoKTtcbiAgICAgIGNvbnN0IHRvdGFsID0gdGhpcy50b3RhbFJvd3MoKTtcbiAgICAgIGNvbnN0IGJ1ZmZlciA9IGNvbmZpZy5idWZmZXJSb3dzID8/IDU7XG5cbiAgICAgIGNvbnN0IHN0YXJ0ID0gTWF0aC5tYXgoMCwgTWF0aC5mbG9vcihzdCAvIHJoKSAtIGJ1ZmZlcik7XG4gICAgICBjb25zdCB2aXNpYmxlQ291bnQgPSBNYXRoLmNlaWwodmggLyByaCk7XG4gICAgICBjb25zdCBlbmQgPSBNYXRoLm1pbih0b3RhbCwgc3RhcnQgKyB2aXNpYmxlQ291bnQgKyBidWZmZXIgKiAyKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc3RhcnQsXG4gICAgICAgIGVuZCxcbiAgICAgICAgb2Zmc2V0WTogc3RhcnQgKiByaCxcbiAgICAgICAgdG90YWxIZWlnaHQ6IHRvdGFsICogcmgsXG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgLy8gVmlydHVhbCBzY3JvbGwgcmFuZ2Ug4oCUIHdoaWNoIGNvbHVtbnMgYXJlIHZpc2libGVcbiAgICB0aGlzLnZpcnR1YWxDb2xSYW5nZSA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICAgIGNvbnN0IHdpZHRocyA9IHRoaXMuY29sdW1uV2lkdGhzKCk7XG4gICAgICBjb25zdCB2dyA9IHRoaXMudmlld3BvcnRXaWR0aCgpO1xuICAgICAgY29uc3Qgc2wgPSB0aGlzLnNjcm9sbExlZnQoKTtcbiAgICAgIGNvbnN0IGNvbHMgPSB0aGlzLnVucGlubmVkQ29sdW1ucygpO1xuICAgICAgY29uc3QgYnVmZmVyID0gMztcblxuICAgICAgbGV0IHN0YXJ0ID0gMDtcbiAgICAgIGxldCBlbmQgPSBjb2xzLmxlbmd0aDtcblxuICAgICAgLy8gRmluZCBzdGFydCBjb2x1bW5cbiAgICAgIGxldCBhY2NXaWR0aCA9IDA7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgdyA9IHdpZHRocy5nZXQoY29sc1tpXS5pZCkgPz8gMTUwO1xuICAgICAgICBpZiAoYWNjV2lkdGggKyB3ID4gc2wpIHtcbiAgICAgICAgICBzdGFydCA9IE1hdGgubWF4KDAsIGkgLSBidWZmZXIpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGFjY1dpZHRoICs9IHc7XG4gICAgICB9XG5cbiAgICAgIC8vIEZpbmQgZW5kIGNvbHVtblxuICAgICAgbGV0IGFjY1dpZHRoMiA9IDA7XG4gICAgICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPCBjb2xzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGFjY1dpZHRoMiArPSB3aWR0aHMuZ2V0KGNvbHNbaV0uaWQpID8/IDE1MDtcbiAgICAgICAgaWYgKGFjY1dpZHRoMiA+IHZ3ICsgc2wpIHtcbiAgICAgICAgICBlbmQgPSBNYXRoLm1pbihjb2xzLmxlbmd0aCwgaSArIGJ1ZmZlciArIDEpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFJlY2FsY3VsYXRlIG9mZnNldFhcbiAgICAgIGxldCBmaW5hbE9mZnNldFggPSAwO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdGFydDsgaSsrKSB7XG4gICAgICAgIGZpbmFsT2Zmc2V0WCArPSB3aWR0aHMuZ2V0KGNvbHNbaV0uaWQpID8/IDE1MDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc3RhcnQsXG4gICAgICAgIGVuZCxcbiAgICAgICAgb2Zmc2V0WDogZmluYWxPZmZzZXRYLFxuICAgICAgICB0b3RhbFdpZHRoOiBjb2xzLnJlZHVjZSgoc3VtLCBjKSA9PiBzdW0gKyAod2lkdGhzLmdldChjLmlkKSA/PyAxNTApLCAwKSxcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvLyBJbml0aWFsaXplIHBsdWdpbnNcbiAgICB0aGlzLnBsdWdpbkhvc3QuaW5pdCh0aGlzKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBDb2x1bW4gT3BlcmF0aW9ucyDilIDilIBcblxuICAvKiogR2V0IGNvbHVtbiBzdGF0ZSBieSBJRC4gKi9cbiAgZ2V0Q29sdW1uU3RhdGUoY29sSWQ6IHN0cmluZyk6IENvbHVtblN0YXRlIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5jb2x1bW5TdGF0ZXMoKS5nZXQoY29sSWQpO1xuICB9XG5cbiAgLyoqIFNldCBjb2x1bW4gd2lkdGguICovXG4gIHNldENvbHVtbldpZHRoKGNvbElkOiBzdHJpbmcsIHdpZHRoOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBzdGF0ZXMgPSBuZXcgTWFwKHRoaXMuY29sdW1uU3RhdGVzKCkpO1xuICAgIGNvbnN0IHN0ID0gc3RhdGVzLmdldChjb2xJZCk7XG4gICAgaWYgKHN0KSB7XG4gICAgICBjb25zdCBjb2wgPSB0aGlzLmNvbHVtbkRlZnMoKS5maW5kKChjKSA9PiBjLmlkID09PSBjb2xJZCk7XG4gICAgICBjb25zdCBtaW4gPSBjb2w/Lm1pbldpZHRoID8/IDQwO1xuICAgICAgY29uc3QgbWF4ID0gY29sPy5tYXhXaWR0aCA/PyA2MDA7XG4gICAgICBzdGF0ZXMuc2V0KGNvbElkLCB7IC4uLnN0LCB3aWR0aDogTWF0aC5tYXgobWluLCBNYXRoLm1pbihtYXgsIHdpZHRoKSkgfSk7XG4gICAgICB0aGlzLmNvbHVtblN0YXRlcy5zZXQoc3RhdGVzKTtcbiAgICB9XG4gIH1cblxuICAvKiogVG9nZ2xlIGNvbHVtbiB2aXNpYmlsaXR5LiAqL1xuICB0b2dnbGVDb2x1bW5WaXNpYmlsaXR5KGNvbElkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBzdGF0ZXMgPSBuZXcgTWFwKHRoaXMuY29sdW1uU3RhdGVzKCkpO1xuICAgIGNvbnN0IHN0ID0gc3RhdGVzLmdldChjb2xJZCk7XG4gICAgaWYgKHN0KSB7XG4gICAgICBzdGF0ZXMuc2V0KGNvbElkLCB7IC4uLnN0LCB2aXNpYmxlOiAhc3QudmlzaWJsZSB9KTtcbiAgICAgIHRoaXMuY29sdW1uU3RhdGVzLnNldChzdGF0ZXMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBTZXQgY29sdW1uIHNvcnQgZGlyZWN0aW9uLiAqL1xuICBzZXRDb2x1bW5Tb3J0KGNvbElkOiBzdHJpbmcsIGRpcmVjdGlvbjogJ2FzYycgfCAnZGVzYycgfCBudWxsKTogdm9pZCB7XG4gICAgY29uc3Qgc3RhdGVzID0gbmV3IE1hcCh0aGlzLmNvbHVtblN0YXRlcygpKTtcbiAgICBjb25zdCBzdCA9IHN0YXRlcy5nZXQoY29sSWQpO1xuICAgIGlmIChzdCkge1xuICAgICAgc3RhdGVzLnNldChjb2xJZCwgeyAuLi5zdCwgc29ydDogZGlyZWN0aW9uIH0pO1xuICAgICAgdGhpcy5jb2x1bW5TdGF0ZXMuc2V0KHN0YXRlcyk7XG4gICAgfVxuXG4gICAgLy8gVXBkYXRlIHNvcnQgc3RhdGVcbiAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5zb3J0U3RhdGUoKTtcbiAgICBsZXQgY3JpdGVyaWE6IFNvcnRDcml0ZXJpb25bXTtcblxuICAgIGlmIChjdXJyZW50Lm11bHRpU29ydCkge1xuICAgICAgY29uc3QgZXhpc3RpbmcgPSBjdXJyZW50LmNyaXRlcmlhLmZpbHRlcigoYykgPT4gYy5jb2xJZCAhPT0gY29sSWQpO1xuICAgICAgaWYgKGRpcmVjdGlvbikge1xuICAgICAgICBjcml0ZXJpYSA9IFsuLi5leGlzdGluZywgeyBjb2xJZCwgZGlyZWN0aW9uLCBpbmRleDogZXhpc3RpbmcubGVuZ3RoIH1dO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY3JpdGVyaWEgPSBleGlzdGluZztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gU2luZ2xlIHNvcnQ6IGNsZWFyIG90aGVyIHNvcnRzXG4gICAgICBmb3IgKGNvbnN0IFtpZCwgc10gb2Ygc3RhdGVzKSB7XG4gICAgICAgIGlmIChpZCAhPT0gY29sSWQgJiYgcy5zb3J0KSB7XG4gICAgICAgICAgc3RhdGVzLnNldChpZCwgeyAuLi5zLCBzb3J0OiBudWxsIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLmNvbHVtblN0YXRlcy5zZXQoc3RhdGVzKTtcbiAgICAgIGNyaXRlcmlhID0gZGlyZWN0aW9uID8gW3sgY29sSWQsIGRpcmVjdGlvbiwgaW5kZXg6IDAgfV0gOiBbXTtcbiAgICB9XG5cbiAgICB0aGlzLnNvcnRTdGF0ZS5zZXQoeyAuLi5jdXJyZW50LCBjcml0ZXJpYSB9KTtcbiAgfVxuXG4gIC8qKiBSZW9yZGVyIGNvbHVtbnMuICovXG4gIG1vdmVDb2x1bW4oZnJvbUluZGV4OiBudW1iZXIsIHRvSW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IGNvbHMgPSBbLi4udGhpcy5jb2x1bW5EZWZzKCldO1xuICAgIGNvbnN0IFttb3ZlZF0gPSBjb2xzLnNwbGljZShmcm9tSW5kZXgsIDEpO1xuICAgIGlmIChtb3ZlZCkge1xuICAgICAgY29scy5zcGxpY2UodG9JbmRleCwgMCwgbW92ZWQpO1xuICAgICAgdGhpcy5jb2x1bW5EZWZzLnNldChjb2xzKTtcbiAgICB9XG4gIH1cblxuICAvLyDilIDilIAgUm93IE9wZXJhdGlvbnMg4pSA4pSAXG5cbiAgLyoqIEluc2VydCByb3dzIGF0IHRoZSBnaXZlbiBpbmRleC4gKi9cbiAgaW5zZXJ0Um93cyhjb3VudDogbnVtYmVyLCBhdEluZGV4PzogbnVtYmVyKTogbnVtYmVyW10ge1xuICAgIGNvbnN0IGluZGV4ID0gYXRJbmRleCA/PyB0aGlzLnJvd0RhdGEoKS5sZW5ndGg7XG4gICAgY29uc3Qgcm93cyA9IFsuLi50aGlzLnJvd0RhdGEoKV07XG4gICAgY29uc3QgbmV3SW5kaWNlczogbnVtYmVyW10gPSBbXTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xuICAgICAgY29uc3QgbmV3Um93ID0gY3JlYXRlRW1wdHlSb3coZ2VuZXJhdGVSb3dJZCgpLCB0aGlzLmNvbHVtbkRlZnMoKSk7XG4gICAgICByb3dzLnNwbGljZShpbmRleCArIGksIDAsIG5ld1Jvdyk7XG4gICAgICBuZXdJbmRpY2VzLnB1c2goaW5kZXggKyBpKTtcbiAgICB9XG5cbiAgICB0aGlzLnJvd0RhdGEuc2V0KHJvd3MpO1xuICAgIHJldHVybiBuZXdJbmRpY2VzO1xuICB9XG5cbiAgLyoqIERlbGV0ZSByb3dzIGJ5IGluZGV4LiAqL1xuICBkZWxldGVSb3dzKGluZGljZXM6IG51bWJlcltdKTogUm93RGVmW10ge1xuICAgIGNvbnN0IHNvcnRlZCA9IFsuLi5pbmRpY2VzXS5zb3J0KChhLCBiKSA9PiBiIC0gYSk7XG4gICAgY29uc3Qgcm93cyA9IFsuLi50aGlzLnJvd0RhdGEoKV07XG4gICAgY29uc3QgZGVsZXRlZDogUm93RGVmW10gPSBbXTtcblxuICAgIGZvciAoY29uc3QgaWR4IG9mIHNvcnRlZCkge1xuICAgICAgaWYgKGlkeCA+PSAwICYmIGlkeCA8IHJvd3MubGVuZ3RoKSB7XG4gICAgICAgIGRlbGV0ZWQucHVzaChyb3dzW2lkeF0pO1xuICAgICAgICByb3dzLnNwbGljZShpZHgsIDEpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMucm93RGF0YS5zZXQocm93cyk7XG4gICAgcmV0dXJuIGRlbGV0ZWQ7XG4gIH1cblxuICAvLyDilIDilIAgQ2VsbCBPcGVyYXRpb25zIOKUgOKUgFxuXG4gIC8qKiBHZXQgYSBjZWxsIHZhbHVlLiAqL1xuICBnZXRDZWxsVmFsdWUocm93SW5kZXg6IG51bWJlciwgY29sSWQ6IHN0cmluZyk6IENlbGxWYWx1ZSB7XG4gICAgcmV0dXJuIHRoaXMucm93RGF0YSgpW3Jvd0luZGV4XT8uY2VsbHNbY29sSWRdPy52YWx1ZSA/PyBudWxsO1xuICB9XG5cbiAgLyoqIFNldCBhIGNlbGwgdmFsdWUuICovXG4gIHNldENlbGxWYWx1ZShyb3dJbmRleDogbnVtYmVyLCBjb2xJZDogc3RyaW5nLCB2YWx1ZTogQ2VsbFZhbHVlKTogdm9pZCB7XG4gICAgY29uc3Qgcm93cyA9IFsuLi50aGlzLnJvd0RhdGEoKV07XG4gICAgY29uc3Qgcm93ID0gcm93c1tyb3dJbmRleF07XG4gICAgaWYgKCFyb3cpIHJldHVybjtcblxuICAgIHJvd3Nbcm93SW5kZXhdID0ge1xuICAgICAgLi4ucm93LFxuICAgICAgY2VsbHM6IHtcbiAgICAgICAgLi4ucm93LmNlbGxzLFxuICAgICAgICBbY29sSWRdOiB7IHZhbHVlLCBtZXRhOiByb3cuY2VsbHNbY29sSWRdPy5tZXRhIH0sXG4gICAgICB9LFxuICAgIH07XG5cbiAgICB0aGlzLnJvd0RhdGEuc2V0KHJvd3MpO1xuICB9XG5cbiAgLyoqIEdldCBjZWxsIG1ldGFkYXRhLiAqL1xuICBnZXRDZWxsTWV0YShyb3dJbmRleDogbnVtYmVyLCBjb2xJZDogc3RyaW5nKTogQ2VsbE1ldGEgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnJvd0RhdGEoKVtyb3dJbmRleF0/LmNlbGxzW2NvbElkXT8ubWV0YTtcbiAgfVxuXG4gIC8qKiBHZXQgYSBjb2x1bW4gZGVmaW5pdGlvbiBieSBJRC4gKi9cbiAgZ2V0Q29sdW1uRGVmKGNvbElkOiBzdHJpbmcpOiBDb2x1bW5EZWYgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmNvbHVtbkRlZnMoKS5maW5kKChjKSA9PiBjLmlkID09PSBjb2xJZCk7XG4gIH1cblxuICAvKiogR2V0IHRoZSAwLWJhc2VkIGNvbHVtbiBpbmRleCBieSBJRC4gKi9cbiAgZ2V0Q29sSW5kZXgoY29sSWQ6IHN0cmluZyk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMudmlzaWJsZUNvbHVtbnMoKS5maW5kSW5kZXgoKGMpID0+IGMuaWQgPT09IGNvbElkKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBFZGl0aW5nIOKUgOKUgFxuXG4gIC8qKiBCZWdpbiBlZGl0aW5nIGEgY2VsbC4gKi9cbiAgc3RhcnRFZGl0KHJvd0luZGV4OiBudW1iZXIsIGNvbElkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBpZiAoIXRoaXMuZWRpdGFibGUoKSkgcmV0dXJuIGZhbHNlO1xuICAgIGlmICghdGhpcy5wbHVnaW5Ib3N0LmJlZm9yZUVkaXQocm93SW5kZXgsIGNvbElkKSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLmdldENlbGxWYWx1ZShyb3dJbmRleCwgY29sSWQpO1xuICAgIHRoaXMuZWRpdGluZ0NlbGwuc2V0KHsgcm93OiByb3dJbmRleCwgY29sOiB0aGlzLmdldENvbEluZGV4KGNvbElkKSB9KTtcbiAgICB0aGlzLmVkaXRpbmdWYWx1ZS5zZXQodmFsdWUpO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqIENvbW1pdCB0aGUgY3VycmVudCBlZGl0LiAqL1xuICBjb21taXRFZGl0KCk6IHZvaWQge1xuICAgIGNvbnN0IGNlbGwgPSB0aGlzLmVkaXRpbmdDZWxsKCk7XG4gICAgaWYgKCFjZWxsKSByZXR1cm47XG5cbiAgICBjb25zdCBjb2wgPSB0aGlzLnZpc2libGVDb2x1bW5zKClbY2VsbC5jb2xdO1xuICAgIGlmICghY29sKSByZXR1cm47XG5cbiAgICBjb25zdCBvbGRWYWx1ZSA9IHRoaXMuZ2V0Q2VsbFZhbHVlKGNlbGwucm93LCBjb2wuaWQpO1xuICAgIGNvbnN0IG5ld1ZhbHVlID0gdGhpcy5lZGl0aW5nVmFsdWUoKTtcblxuICAgIGlmIChvbGRWYWx1ZSAhPT0gbmV3VmFsdWUpIHtcbiAgICAgIHRoaXMuc2V0Q2VsbFZhbHVlKGNlbGwucm93LCBjb2wuaWQsIG5ld1ZhbHVlKTtcbiAgICAgIHRoaXMucGx1Z2luSG9zdC5hZnRlckVkaXQoY2VsbC5yb3csIGNvbC5pZCwgb2xkVmFsdWUsIG5ld1ZhbHVlKTtcbiAgICB9XG5cbiAgICB0aGlzLmVkaXRpbmdDZWxsLnNldChudWxsKTtcbiAgfVxuXG4gIC8qKiBDYW5jZWwgdGhlIGN1cnJlbnQgZWRpdC4gKi9cbiAgY2FuY2VsRWRpdCgpOiB2b2lkIHtcbiAgICB0aGlzLmVkaXRpbmdDZWxsLnNldChudWxsKTtcbiAgICB0aGlzLmVkaXRpbmdWYWx1ZS5zZXQobnVsbCk7XG4gIH1cblxuICAvLyDilIDilIAgU29ydCDilIDilIBcblxuICAvKiogU29ydCBieSBhIGNvbHVtbiAodG9nZ2xlcyBkaXJlY3Rpb24pLiAqL1xuICBzb3J0QnkoY29sSWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IHN0ID0gdGhpcy5jb2x1bW5TdGF0ZXMoKS5nZXQoY29sSWQpO1xuICAgIGlmICghc3QpIHJldHVybjtcblxuICAgIGNvbnN0IGN1cnJlbnRTb3J0ID0gc3Quc29ydDtcbiAgICBsZXQgbmV3RGlyZWN0aW9uOiAnYXNjJyB8ICdkZXNjJyB8IG51bGw7XG5cbiAgICBpZiAoY3VycmVudFNvcnQgPT09IG51bGwpIHtcbiAgICAgIG5ld0RpcmVjdGlvbiA9ICdhc2MnO1xuICAgIH0gZWxzZSBpZiAoY3VycmVudFNvcnQgPT09ICdhc2MnKSB7XG4gICAgICBuZXdEaXJlY3Rpb24gPSAnZGVzYyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5ld0RpcmVjdGlvbiA9IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLnBsdWdpbkhvc3QuYmVmb3JlU29ydChjb2xJZCwgbmV3RGlyZWN0aW9uKSkgcmV0dXJuO1xuXG4gICAgdGhpcy5zZXRDb2x1bW5Tb3J0KGNvbElkLCBuZXdEaXJlY3Rpb24pO1xuICAgIHRoaXMucGx1Z2luSG9zdC5hZnRlclNvcnQoKTtcbiAgfVxuXG4gIC8qKiBDbGVhciBhbGwgc29ydGluZy4gKi9cbiAgY2xlYXJTb3J0KCk6IHZvaWQge1xuICAgIGNvbnN0IHN0YXRlcyA9IG5ldyBNYXAodGhpcy5jb2x1bW5TdGF0ZXMoKSk7XG4gICAgZm9yIChjb25zdCBbaWQsIHN0XSBvZiBzdGF0ZXMpIHtcbiAgICAgIGlmIChzdC5zb3J0KSB7XG4gICAgICAgIHN0YXRlcy5zZXQoaWQsIHsgLi4uc3QsIHNvcnQ6IG51bGwsIHNvcnRJbmRleDogdW5kZWZpbmVkIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmNvbHVtblN0YXRlcy5zZXQoc3RhdGVzKTtcbiAgICB0aGlzLnNvcnRTdGF0ZS5zZXQoeyBjcml0ZXJpYTogW10sIG11bHRpU29ydDogdGhpcy5zb3J0U3RhdGUoKS5tdWx0aVNvcnQgfSk7XG4gIH1cblxuICAvLyDilIDilIAgRmlsdGVyIOKUgOKUgFxuXG4gIC8qKiBBcHBseSBhIGZpbHRlci4gKi9cbiAgYXBwbHlGaWx0ZXIoXG4gICAgY29sSWQ6IHN0cmluZyxcbiAgICBvcGVyYXRvcjogRmlsdGVyQ3JpdGVyaW9uWydvcGVyYXRvciddLFxuICAgIHZhbHVlOiB1bmtub3duLFxuICAgIHZhbHVlVG8/OiB1bmtub3duLFxuICApOiB2b2lkIHtcbiAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5maWx0ZXJTdGF0ZSgpO1xuICAgIGNvbnN0IGV4aXN0aW5nID0gY3VycmVudC5jcml0ZXJpYS5maWx0ZXIoKGMpID0+IGMuY29sSWQgIT09IGNvbElkKTtcbiAgICBjb25zdCBjcml0ZXJpYSA9IFsuLi5leGlzdGluZywgeyBjb2xJZCwgb3BlcmF0b3IsIHZhbHVlLCB2YWx1ZVRvIH1dO1xuICAgIHRoaXMuZmlsdGVyU3RhdGUuc2V0KHsgLi4uY3VycmVudCwgY3JpdGVyaWEgfSk7XG4gIH1cblxuICAvKiogQ2xlYXIgZmlsdGVyIGZvciBhIGNvbHVtbi4gKi9cbiAgY2xlYXJDb2x1bW5GaWx0ZXIoY29sSWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLmZpbHRlclN0YXRlKCk7XG4gICAgdGhpcy5maWx0ZXJTdGF0ZS5zZXQoe1xuICAgICAgLi4uY3VycmVudCxcbiAgICAgIGNyaXRlcmlhOiBjdXJyZW50LmNyaXRlcmlhLmZpbHRlcigoYykgPT4gYy5jb2xJZCAhPT0gY29sSWQpLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqIENsZWFyIGFsbCBmaWx0ZXJzLiAqL1xuICBjbGVhckZpbHRlcnMoKTogdm9pZCB7XG4gICAgdGhpcy5maWx0ZXJTdGF0ZS5zZXQoeyBjcml0ZXJpYTogW10sIG1vZGU6ICdhbmQnIH0pO1xuICB9XG5cbiAgLy8g4pSA4pSAIE5hdmlnYXRpb24g4pSA4pSAXG5cbiAgLyoqIE1vdmUgdGhlIGFjdGl2ZSBjZWxsIGJ5IGRlbHRhLiAqL1xuICBuYXZpZ2F0ZShkZWx0YVJvdzogbnVtYmVyLCBkZWx0YUNvbDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3Qgc2VsID0gdGhpcy5zZWxlY3Rpb24oKTtcbiAgICBjb25zdCBjdXJyZW50ID0gc2VsLmFjdGl2ZUNlbGwgPz8geyByb3c6IDAsIGNvbDogMCB9O1xuICAgIGNvbnN0IG5ld1JvdyA9IE1hdGgubWF4KDAsIE1hdGgubWluKHRoaXMudG90YWxSb3dzKCkgLSAxLCBjdXJyZW50LnJvdyArIGRlbHRhUm93KSk7XG4gICAgY29uc3QgbmV3Q29sID0gTWF0aC5tYXgoMCwgTWF0aC5taW4odGhpcy50b3RhbENvbHVtbnMoKSAtIDEsIGN1cnJlbnQuY29sICsgZGVsdGFDb2wpKTtcblxuICAgIHRoaXMuc2VsZWN0aW9uLnNldCh7XG4gICAgICAuLi5zZWwsXG4gICAgICBhY3RpdmVDZWxsOiB7IHJvdzogbmV3Um93LCBjb2w6IG5ld0NvbCB9LFxuICAgICAgcmFuZ2U6IHsgc3RhcnQ6IHsgcm93OiBuZXdSb3csIGNvbDogbmV3Q29sIH0sIGVuZDogeyByb3c6IG5ld1JvdywgY29sOiBuZXdDb2wgfSB9LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqIFNjcm9sbCB0byBtYWtlIGEgY2VsbCB2aXNpYmxlLiAqL1xuICBzY3JvbGxUb0NlbGwocm93SW5kZXg6IG51bWJlciwgX2NvbEluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCByaCA9IHRoaXMucm93SGVpZ2h0KCk7XG4gICAgY29uc3QgY2VsbFRvcCA9IHJvd0luZGV4ICogcmg7XG4gICAgY29uc3QgY2VsbEJvdHRvbSA9IGNlbGxUb3AgKyByaDtcblxuICAgIGNvbnN0IHN0ID0gdGhpcy5zY3JvbGxUb3AoKTtcbiAgICBjb25zdCB2aCA9IHRoaXMudmlld3BvcnRIZWlnaHQoKTtcblxuICAgIGlmIChjZWxsVG9wIDwgc3QpIHtcbiAgICAgIHRoaXMuc2Nyb2xsVG9wLnNldChjZWxsVG9wKTtcbiAgICB9IGVsc2UgaWYgKGNlbGxCb3R0b20gPiBzdCArIHZoKSB7XG4gICAgICB0aGlzLnNjcm9sbFRvcC5zZXQoY2VsbEJvdHRvbSAtIHZoKTtcbiAgICB9XG4gIH1cblxuICAvLyDilIDilIAgU2VsZWN0aW9uIOKUgOKUgFxuXG4gIC8qKiBTZWxlY3QgYSBjZWxsLiAqL1xuICBzZWxlY3RDZWxsKHJvdzogbnVtYmVyLCBjb2w6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuc2VsZWN0aW9uLnNldCh7XG4gICAgICAuLi50aGlzLnNlbGVjdGlvbigpLFxuICAgICAgYWN0aXZlQ2VsbDogeyByb3csIGNvbCB9LFxuICAgICAgcmFuZ2U6IHsgc3RhcnQ6IHsgcm93LCBjb2wgfSwgZW5kOiB7IHJvdywgY29sIH0gfSxcbiAgICAgIG1vZGU6ICdjZWxsJyxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKiBTZWxlY3QgYSByYW5nZS4gKi9cbiAgc2VsZWN0UmFuZ2Uoc3RhcnQ6IENlbGxBZGRyZXNzLCBlbmQ6IENlbGxBZGRyZXNzKTogdm9pZCB7XG4gICAgdGhpcy5zZWxlY3Rpb24uc2V0KHtcbiAgICAgIC4uLnRoaXMuc2VsZWN0aW9uKCksXG4gICAgICByYW5nZTogeyBzdGFydCwgZW5kIH0sXG4gICAgICBtb2RlOiAncmFuZ2UnLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqIFNlbGVjdCBhIHJvdy4gKi9cbiAgc2VsZWN0Um93KHJvd0luZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCByb3dzID0gbmV3IFNldCh0aGlzLnNlbGVjdGlvbigpLnNlbGVjdGVkUm93cyk7XG4gICAgaWYgKHJvd3MuaGFzKHJvd0luZGV4KSkge1xuICAgICAgcm93cy5kZWxldGUocm93SW5kZXgpO1xuICAgIH0gZWxzZSB7XG4gICAgICByb3dzLmFkZChyb3dJbmRleCk7XG4gICAgfVxuICAgIHRoaXMuc2VsZWN0aW9uLnNldCh7IC4uLnRoaXMuc2VsZWN0aW9uKCksIHNlbGVjdGVkUm93czogcm93cywgbW9kZTogJ3JvdycgfSk7XG4gIH1cblxuICAvKiogU2VsZWN0IGEgY29sdW1uLiAqL1xuICBzZWxlY3RDb2x1bW4oY29sSW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IGNvbHMgPSBuZXcgU2V0KHRoaXMuc2VsZWN0aW9uKCkuc2VsZWN0ZWRDb2xzKTtcbiAgICBpZiAoY29scy5oYXMoY29sSW5kZXgpKSB7XG4gICAgICBjb2xzLmRlbGV0ZShjb2xJbmRleCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbHMuYWRkKGNvbEluZGV4KTtcbiAgICB9XG4gICAgdGhpcy5zZWxlY3Rpb24uc2V0KHsgLi4udGhpcy5zZWxlY3Rpb24oKSwgc2VsZWN0ZWRDb2xzOiBjb2xzLCBtb2RlOiAnY29sdW1uJyB9KTtcbiAgfVxuXG4gIC8qKiBTZWxlY3QgYWxsIGNlbGxzLiAqL1xuICBzZWxlY3RBbGwoKTogdm9pZCB7XG4gICAgY29uc3QgYWxsUm93cyA9IG5ldyBTZXQoQXJyYXkuZnJvbSh7IGxlbmd0aDogdGhpcy50b3RhbFJvd3MoKSB9LCAoXywgaSkgPT4gaSkpO1xuICAgIGNvbnN0IGFsbENvbHMgPSBuZXcgU2V0KEFycmF5LmZyb20oeyBsZW5ndGg6IHRoaXMudG90YWxDb2x1bW5zKCkgfSwgKF8sIGkpID0+IGkpKTtcbiAgICB0aGlzLnNlbGVjdGlvbi5zZXQoe1xuICAgICAgYWN0aXZlQ2VsbDogeyByb3c6IDAsIGNvbDogMCB9LFxuICAgICAgcmFuZ2U6IHtcbiAgICAgICAgc3RhcnQ6IHsgcm93OiAwLCBjb2w6IDAgfSxcbiAgICAgICAgZW5kOiB7IHJvdzogdGhpcy50b3RhbFJvd3MoKSAtIDEsIGNvbDogdGhpcy50b3RhbENvbHVtbnMoKSAtIDEgfSxcbiAgICAgIH0sXG4gICAgICBzZWxlY3RlZFJvd3M6IGFsbFJvd3MsXG4gICAgICBzZWxlY3RlZENvbHM6IGFsbENvbHMsXG4gICAgICBtb2RlOiAncmFuZ2UnLFxuICAgICAgZHJhZ2dpbmc6IGZhbHNlLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqIENoZWNrIGlmIGEgY2VsbCBpcyBzZWxlY3RlZC4gKi9cbiAgaXNDZWxsU2VsZWN0ZWQocm93OiBudW1iZXIsIGNvbDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgY29uc3Qgc2VsID0gdGhpcy5zZWxlY3Rpb24oKTtcbiAgICBpZiAoc2VsLnJhbmdlKSB7XG4gICAgICBjb25zdCBtaW5SID0gTWF0aC5taW4oc2VsLnJhbmdlLnN0YXJ0LnJvdywgc2VsLnJhbmdlLmVuZC5yb3cpO1xuICAgICAgY29uc3QgbWF4UiA9IE1hdGgubWF4KHNlbC5yYW5nZS5zdGFydC5yb3csIHNlbC5yYW5nZS5lbmQucm93KTtcbiAgICAgIGNvbnN0IG1pbkMgPSBNYXRoLm1pbihzZWwucmFuZ2Uuc3RhcnQuY29sLCBzZWwucmFuZ2UuZW5kLmNvbCk7XG4gICAgICBjb25zdCBtYXhDID0gTWF0aC5tYXgoc2VsLnJhbmdlLnN0YXJ0LmNvbCwgc2VsLnJhbmdlLmVuZC5jb2wpO1xuICAgICAgaWYgKHJvdyA+PSBtaW5SICYmIHJvdyA8PSBtYXhSICYmIGNvbCA+PSBtaW5DICYmIGNvbCA8PSBtYXhDKSByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHNlbC5zZWxlY3RlZFJvd3MuaGFzKHJvdykgfHwgc2VsLnNlbGVjdGVkQ29scy5oYXMoY29sKTtcbiAgfVxuXG4gIC8qKiBDaGVjayBpZiBhIGNlbGwgaXMgdGhlIGFjdGl2ZSBjZWxsLiAqL1xuICBpc0NlbGxBY3RpdmUocm93OiBudW1iZXIsIGNvbDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgY29uc3QgYWMgPSB0aGlzLnNlbGVjdGlvbigpLmFjdGl2ZUNlbGw7XG4gICAgcmV0dXJuIGFjPy5yb3cgPT09IHJvdyAmJiBhYz8uY29sID09PSBjb2w7XG4gIH1cblxuICAvLyDilIDilIAgUmVmcmVzaCDilIDilIBcblxuICAvKiogRm9yY2UgcmVjYWxjdWxhdGlvbiBieSByZS1zZXR0aW5nIGRhdGEuICovXG4gIHJlZnJlc2goKTogdm9pZCB7XG4gICAgdGhpcy5yb3dEYXRhLnVwZGF0ZSgocikgPT4gWy4uLnJdKTtcbiAgICB0aGlzLmNvbHVtblN0YXRlcy51cGRhdGUoKHMpID0+IG5ldyBNYXAocykpO1xuICB9XG5cbiAgLy8g4pSA4pSAIERlc3Ryb3kg4pSA4pSAXG5cbiAgZGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLnBsdWdpbkhvc3QuZGVzdHJveSgpO1xuICB9XG59XG4iXX0=