@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.
- package/README.md +1 -1
- package/cva-base/cva-base.d.ts +34 -0
- package/cva-base/cva-base.d.ts.map +1 -0
- package/cva-base/index.d.ts +2 -0
- package/cva-base/index.d.ts.map +1 -0
- package/cva-base/ngxsmk-cdk-cva-base.d.ts.map +1 -0
- package/esm2022/cva-base/cva-base.mjs +45 -0
- package/esm2022/cva-base/index.mjs +2 -0
- package/esm2022/cva-base/ngxsmk-cdk-cva-base.mjs +5 -0
- package/esm2022/input-group/index.mjs +3 -0
- package/esm2022/input-group/input-group-engine.mjs +219 -0
- package/esm2022/input-group/models/index.mjs +2 -0
- package/esm2022/input-group/models/input-group.model.mjs +2 -0
- package/esm2022/input-group/ngxsmk-cdk-input-group.mjs +5 -0
- package/esm2022/listbox-keyboard/index.mjs +2 -0
- package/esm2022/listbox-keyboard/listbox-keyboard.mjs +145 -0
- package/esm2022/listbox-keyboard/ngxsmk-cdk-listbox-keyboard.mjs +5 -0
- package/esm2022/public-api.mjs +10 -1
- package/esm2022/scheduler/index.mjs +5 -0
- package/esm2022/scheduler/models/date-range.mjs +2 -0
- package/esm2022/scheduler/models/event.model.mjs +2 -0
- package/esm2022/scheduler/models/index.mjs +6 -0
- package/esm2022/scheduler/models/resource.model.mjs +5 -0
- package/esm2022/scheduler/models/selection.model.mjs +7 -0
- package/esm2022/scheduler/models/view.model.mjs +7 -0
- package/esm2022/scheduler/ngxsmk-cdk-scheduler.mjs +5 -0
- package/esm2022/scheduler/plugin/drag-plugin.mjs +82 -0
- package/esm2022/scheduler/plugin/index.mjs +8 -0
- package/esm2022/scheduler/plugin/keyboard-plugin.mjs +150 -0
- package/esm2022/scheduler/plugin/plugin-host.mjs +48 -0
- package/esm2022/scheduler/plugin/plugin.types.mjs +2 -0
- package/esm2022/scheduler/plugin/resize-plugin.mjs +74 -0
- package/esm2022/scheduler/plugin/selection-plugin.mjs +84 -0
- package/esm2022/scheduler/plugin/tooltip-plugin.mjs +103 -0
- package/esm2022/scheduler/scheduler-engine.mjs +316 -0
- package/esm2022/scheduler/utils/date-utils.mjs +131 -0
- package/esm2022/scheduler/utils/index.mjs +3 -0
- package/esm2022/scheduler/utils/snap.mjs +24 -0
- package/esm2022/spreadsheet/index.mjs +5 -0
- package/esm2022/spreadsheet/models/cell.model.mjs +2 -0
- package/esm2022/spreadsheet/models/column.model.mjs +2 -0
- package/esm2022/spreadsheet/models/filter.model.mjs +2 -0
- package/esm2022/spreadsheet/models/formula.model.mjs +2 -0
- package/esm2022/spreadsheet/models/index.mjs +8 -0
- package/esm2022/spreadsheet/models/row.model.mjs +2 -0
- package/esm2022/spreadsheet/models/selection.model.mjs +2 -0
- package/esm2022/spreadsheet/models/sort.model.mjs +2 -0
- package/esm2022/spreadsheet/ngxsmk-cdk-spreadsheet.mjs +5 -0
- package/esm2022/spreadsheet/plugin/clipboard-plugin.mjs +171 -0
- package/esm2022/spreadsheet/plugin/filter-plugin.mjs +87 -0
- package/esm2022/spreadsheet/plugin/formula-plugin.mjs +456 -0
- package/esm2022/spreadsheet/plugin/index.mjs +10 -0
- package/esm2022/spreadsheet/plugin/plugin-host.mjs +188 -0
- package/esm2022/spreadsheet/plugin/plugin.types.mjs +2 -0
- package/esm2022/spreadsheet/plugin/selection-plugin.mjs +114 -0
- package/esm2022/spreadsheet/plugin/sort-plugin.mjs +63 -0
- package/esm2022/spreadsheet/plugin/undo-plugin.mjs +138 -0
- package/esm2022/spreadsheet/plugin/validation-plugin.mjs +71 -0
- package/esm2022/spreadsheet/spreadsheet-engine.mjs +547 -0
- package/esm2022/spreadsheet/utils/cell-utils.mjs +129 -0
- package/esm2022/spreadsheet/utils/index.mjs +2 -0
- package/esm2022/testing/a11y.mjs +6 -3
- package/fesm2022/ngxsmk-cdk-cva-base.mjs +52 -0
- package/fesm2022/ngxsmk-cdk-cva-base.mjs.map +1 -0
- package/fesm2022/ngxsmk-cdk-input-group.mjs +226 -0
- package/fesm2022/ngxsmk-cdk-input-group.mjs.map +1 -0
- package/fesm2022/ngxsmk-cdk-listbox-keyboard.mjs +152 -0
- package/fesm2022/ngxsmk-cdk-listbox-keyboard.mjs.map +1 -0
- package/fesm2022/ngxsmk-cdk-scheduler.mjs +1035 -0
- package/fesm2022/ngxsmk-cdk-scheduler.mjs.map +1 -0
- package/fesm2022/ngxsmk-cdk-spreadsheet.mjs +1969 -0
- package/fesm2022/ngxsmk-cdk-spreadsheet.mjs.map +1 -0
- package/fesm2022/ngxsmk-cdk-testing.mjs +5 -2
- package/fesm2022/ngxsmk-cdk-testing.mjs.map +1 -1
- package/fesm2022/ngxsmk-cdk.mjs +5 -0
- package/fesm2022/ngxsmk-cdk.mjs.map +1 -1
- package/input-group/index.d.ts +3 -0
- package/input-group/index.d.ts.map +1 -0
- package/input-group/input-group-engine.d.ts +88 -0
- package/input-group/input-group-engine.d.ts.map +1 -0
- package/input-group/models/index.d.ts +2 -0
- package/input-group/models/index.d.ts.map +1 -0
- package/input-group/models/input-group.model.d.ts +114 -0
- package/input-group/models/input-group.model.d.ts.map +1 -0
- package/input-group/ngxsmk-cdk-input-group.d.ts.map +1 -0
- package/listbox-keyboard/index.d.ts +2 -0
- package/listbox-keyboard/index.d.ts.map +1 -0
- package/listbox-keyboard/listbox-keyboard.d.ts +60 -0
- package/listbox-keyboard/listbox-keyboard.d.ts.map +1 -0
- package/listbox-keyboard/ngxsmk-cdk-listbox-keyboard.d.ts.map +1 -0
- package/package.json +40 -1
- package/public-api.d.ts +8 -0
- package/public-api.d.ts.map +1 -1
- package/scheduler/index.d.ts +5 -0
- package/scheduler/index.d.ts.map +1 -0
- package/scheduler/models/date-range.d.ts +6 -0
- package/scheduler/models/date-range.d.ts.map +1 -0
- package/scheduler/models/event.model.d.ts +50 -0
- package/scheduler/models/event.model.d.ts.map +1 -0
- package/scheduler/models/index.d.ts +6 -0
- package/scheduler/models/index.d.ts.map +1 -0
- package/scheduler/models/resource.model.d.ts +16 -0
- package/scheduler/models/resource.model.d.ts.map +1 -0
- package/scheduler/models/selection.model.d.ts +12 -0
- package/scheduler/models/selection.model.d.ts.map +1 -0
- package/scheduler/models/view.model.d.ts +21 -0
- package/scheduler/models/view.model.d.ts.map +1 -0
- package/scheduler/ngxsmk-cdk-scheduler.d.ts.map +1 -0
- package/scheduler/plugin/drag-plugin.d.ts +28 -0
- package/scheduler/plugin/drag-plugin.d.ts.map +1 -0
- package/scheduler/plugin/index.d.ts +8 -0
- package/scheduler/plugin/index.d.ts.map +1 -0
- package/scheduler/plugin/keyboard-plugin.d.ts +24 -0
- package/scheduler/plugin/keyboard-plugin.d.ts.map +1 -0
- package/scheduler/plugin/plugin-host.d.ts +16 -0
- package/scheduler/plugin/plugin-host.d.ts.map +1 -0
- package/scheduler/plugin/plugin.types.d.ts +9 -0
- package/scheduler/plugin/plugin.types.d.ts.map +1 -0
- package/scheduler/plugin/resize-plugin.d.ts +26 -0
- package/scheduler/plugin/resize-plugin.d.ts.map +1 -0
- package/scheduler/plugin/selection-plugin.d.ts +40 -0
- package/scheduler/plugin/selection-plugin.d.ts.map +1 -0
- package/scheduler/plugin/tooltip-plugin.d.ts +41 -0
- package/scheduler/plugin/tooltip-plugin.d.ts.map +1 -0
- package/scheduler/scheduler-engine.d.ts +95 -0
- package/scheduler/scheduler-engine.d.ts.map +1 -0
- package/scheduler/utils/date-utils.d.ts +26 -0
- package/scheduler/utils/date-utils.d.ts.map +1 -0
- package/scheduler/utils/index.d.ts +3 -0
- package/scheduler/utils/index.d.ts.map +1 -0
- package/scheduler/utils/snap.d.ts +7 -0
- package/scheduler/utils/snap.d.ts.map +1 -0
- package/spreadsheet/index.d.ts +5 -0
- package/spreadsheet/index.d.ts.map +1 -0
- package/spreadsheet/models/cell.model.d.ts +44 -0
- package/spreadsheet/models/cell.model.d.ts.map +1 -0
- package/spreadsheet/models/column.model.d.ts +77 -0
- package/spreadsheet/models/column.model.d.ts.map +1 -0
- package/spreadsheet/models/filter.model.d.ts +15 -0
- package/spreadsheet/models/filter.model.d.ts.map +1 -0
- package/spreadsheet/models/formula.model.d.ts +65 -0
- package/spreadsheet/models/formula.model.d.ts.map +1 -0
- package/spreadsheet/models/index.d.ts +8 -0
- package/spreadsheet/models/index.d.ts.map +1 -0
- package/spreadsheet/models/row.model.d.ts +33 -0
- package/spreadsheet/models/row.model.d.ts.map +1 -0
- package/spreadsheet/models/selection.model.d.ts +18 -0
- package/spreadsheet/models/selection.model.d.ts.map +1 -0
- package/spreadsheet/models/sort.model.d.ts +14 -0
- package/spreadsheet/models/sort.model.d.ts.map +1 -0
- package/spreadsheet/ngxsmk-cdk-spreadsheet.d.ts.map +1 -0
- package/spreadsheet/plugin/clipboard-plugin.d.ts +24 -0
- package/spreadsheet/plugin/clipboard-plugin.d.ts.map +1 -0
- package/spreadsheet/plugin/filter-plugin.d.ts +21 -0
- package/spreadsheet/plugin/filter-plugin.d.ts.map +1 -0
- package/spreadsheet/plugin/formula-plugin.d.ts +39 -0
- package/spreadsheet/plugin/formula-plugin.d.ts.map +1 -0
- package/spreadsheet/plugin/index.d.ts +10 -0
- package/spreadsheet/plugin/index.d.ts.map +1 -0
- package/spreadsheet/plugin/plugin-host.d.ts +66 -0
- package/spreadsheet/plugin/plugin-host.d.ts.map +1 -0
- package/spreadsheet/plugin/plugin.types.d.ts +58 -0
- package/spreadsheet/plugin/plugin.types.d.ts.map +1 -0
- package/spreadsheet/plugin/selection-plugin.d.ts +28 -0
- package/spreadsheet/plugin/selection-plugin.d.ts.map +1 -0
- package/spreadsheet/plugin/sort-plugin.d.ts +18 -0
- package/spreadsheet/plugin/sort-plugin.d.ts.map +1 -0
- package/spreadsheet/plugin/undo-plugin.d.ts +40 -0
- package/spreadsheet/plugin/undo-plugin.d.ts.map +1 -0
- package/spreadsheet/plugin/validation-plugin.d.ts +29 -0
- package/spreadsheet/plugin/validation-plugin.d.ts.map +1 -0
- package/spreadsheet/spreadsheet-engine.d.ts +194 -0
- package/spreadsheet/spreadsheet-engine.d.ts.map +1 -0
- package/spreadsheet/utils/cell-utils.d.ts +26 -0
- package/spreadsheet/utils/cell-utils.d.ts.map +1 -0
- package/spreadsheet/utils/index.d.ts +2 -0
- package/spreadsheet/utils/index.d.ts.map +1 -0
- package/testing/a11y.d.ts +5 -1
- 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3ByZWFkc2hlZXQtZW5naW5lLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY2RrL3NwcmVhZHNoZWV0L3NwcmVhZHNoZWV0LWVuZ2luZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBb0MsTUFBTSxlQUFlLENBQUM7QUFlbkYsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxhQUFhLEVBQUUsY0FBYyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUE4RG5FLE1BQU0sa0JBQWtCLEdBQXVDO0lBQzdELE9BQU8sRUFBRSxFQUFFO0lBQ1gsV0FBVyxFQUFFLEVBQUU7SUFDZixLQUFLLEVBQUUsRUFBRTtDQUNWLENBQUM7QUFFRixNQUFNLHFCQUFxQixHQUF1QztJQUNoRSxPQUFPLEVBQUUsRUFBRTtJQUNYLFdBQVcsRUFBRSxFQUFFO0lBQ2YsS0FBSyxFQUFFLEVBQUU7Q0FDVixDQUFDO0FBRUYsTUFBTSxvQkFBb0IsR0FBdUM7SUFDL0QsT0FBTyxFQUFFLFNBQVM7SUFDbEIsV0FBVyxFQUFFLFVBQVU7SUFDdkIsS0FBSyxFQUFFLFNBQVM7Q0FDakIsQ0FBQztBQUVGOzs7Ozs7R0FNRztBQUNILE1BQU0sT0FBTyxpQkFBaUI7SUFpRzVCLFlBQVksU0FBNEIsRUFBRTtRQUN4QyxJQUFJLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQztRQUN0QixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksVUFBVSxFQUFFLENBQUM7UUFFbkMsVUFBVTtRQUNWLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLElBQUksYUFBYSxDQUFDLENBQUM7UUFDdkQsSUFBSSxDQUFDLFFBQVEsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsQ0FBQztRQUNoRCxJQUFJLENBQUMsR0FBRyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxJQUFJLEtBQUssQ0FBQyxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxVQUFVLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxVQUFVLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDakQsSUFBSSxDQUFDLGFBQWEsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLGFBQWEsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUV2RCwwQ0FBMEM7UUFDMUMsSUFBSSxDQUFDLFNBQVMsR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNwRSxJQUFJLENBQUMsWUFBWSxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzFFLElBQUksQ0FBQyxXQUFXLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFFeEUscUJBQXFCO1FBQ3JCLElBQUksQ0FBQyxVQUFVLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDLENBQUM7UUFFL0MsK0NBQStDO1FBQy9DLE1BQU0sYUFBYSxHQUFHLElBQUksR0FBRyxFQUF1QixDQUFDO1FBQ3JELENBQUMsTUFBTSxDQUFDLE9BQU8sSUFBSSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEVBQUU7WUFDMUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFO2dCQUN4QixFQUFFLEVBQUUsR0FBRyxDQUFDLEVBQUU7Z0JBQ1YsS0FBSyxFQUFFLEdBQUcsQ0FBQyxLQUFLLElBQUksR0FBRztnQkFDdkIsT0FBTyxFQUFFLEdBQUcsQ0FBQyxPQUFPLEtBQUssS0FBSztnQkFDOUIsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNLElBQUksS0FBSztnQkFDM0IsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJLElBQUksSUFBSTtnQkFDdEIsU0FBUyxFQUFFLFNBQVM7Z0JBQ3BCLEtBQUssRUFBRSxHQUFHO2FBQ1gsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsWUFBWSxHQUFHLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUUxQyxXQUFXO1FBQ1gsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQztRQUV6QyxZQUFZO1FBQ1osSUFBSSxDQUFDLFNBQVMsR0FBRyxNQUFNLENBQWlCO1lBQ3RDLFVBQVUsRUFBRSxJQUFJO1lBQ2hCLEtBQUssRUFBRSxJQUFJO1lBQ1gsWUFBWSxFQUFFLElBQUksR0FBRyxFQUFFO1lBQ3ZCLFlBQVksRUFBRSxJQUFJLEdBQUcsRUFBRTtZQUN2QixJQUFJLEVBQUUsTUFBTSxDQUFDLGFBQWEsSUFBSSxNQUFNO1lBQ3BDLFFBQVEsRUFBRSxLQUFLO1NBQ2hCLENBQUMsQ0FBQztRQUVILE9BQU87UUFDUCxJQUFJLENBQUMsU0FBUyxHQUFHLE1BQU0sQ0FBWTtZQUNqQyxRQUFRLEVBQUUsQ0FBQyxNQUFNLENBQUMsT0FBTyxJQUFJLEVBQUUsQ0FBQztpQkFDN0IsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO2lCQUNyQixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxJQUFLLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDakUsU0FBUyxFQUFFLE1BQU0sQ0FBQyxTQUFTLElBQUksS0FBSztTQUNyQyxDQUFDLENBQUM7UUFFSCxTQUFTO1FBQ1QsSUFBSSxDQUFDLFdBQVcsR0FBRyxNQUFNLENBQWMsRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBRXRFLFVBQVU7UUFDVixJQUFJLENBQUMsV0FBVyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNoQyxJQUFJLENBQUMsWUFBWSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUVqQyxTQUFTO1FBQ1QsSUFBSSxDQUFDLFNBQVMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDM0IsSUFBSSxDQUFDLFVBQVUsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDNUIsSUFBSSxDQUFDLGNBQWMsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDbEMsSUFBSSxDQUFDLGFBQWEsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFakMsVUFBVTtRQUNWLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDLENBQUM7UUFFNUMsa0JBQWtCO1FBQ2xCLElBQUksQ0FBQyxTQUFTLEdBQUc7WUFDZixVQUFVLEVBQUUsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQztZQUM5QixTQUFTLEVBQUUsTUFBTSxDQUFDLEdBQUcsRUFBRTtnQkFDckIsVUFBVTtZQUNaLENBQUMsQ0FBQztZQUNGLFVBQVUsRUFBRSxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDO1lBQzlCLFNBQVMsRUFBRSxNQUFNLENBQUMsR0FBRyxFQUFFO2dCQUNyQixVQUFVO1lBQ1osQ0FBQyxDQUFDO1lBQ0YsWUFBWSxFQUFFLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUM7WUFDaEMsV0FBVyxFQUFFLE1BQU0sQ0FBQyxHQUFHLEVBQUU7Z0JBQ3ZCLFVBQVU7WUFDWixDQUFDLENBQUM7WUFDRixnQkFBZ0IsRUFBRSxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDO1lBQ3BDLGVBQWUsRUFBRSxNQUFNLENBQUMsR0FBRyxFQUFFO2dCQUMzQixVQUFVO1lBQ1osQ0FBQyxDQUFDO1lBQ0YsZ0JBQWdCLEVBQUUsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQztZQUNwQyxlQUFlLEVBQUUsTUFBTSxDQUFDLEdBQUcsRUFBRTtnQkFDM0IsVUFBVTtZQUNaLENBQUMsQ0FBQztZQUNGLG1CQUFtQixFQUFFLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUM7WUFDdkMsa0JBQWtCLEVBQUUsTUFBTSxDQUFDLEdBQUcsRUFBRTtnQkFDOUIsVUFBVTtZQUNaLENBQUMsQ0FBQztZQUNGLG1CQUFtQixFQUFFLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUM7WUFDdkMsa0JBQWtCLEVBQUUsTUFBTSxDQUFDLEdBQUcsRUFBRTtnQkFDOUIsVUFBVTtZQUNaLENBQUMsQ0FBQztZQUNGLFVBQVUsRUFBRSxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDO1lBQzlCLFNBQVMsRUFBRSxNQUFNLENBQUMsR0FBRyxFQUFFO2dCQUNyQixVQUFVO1lBQ1osQ0FBQyxDQUFDO1lBQ0YsV0FBVyxFQUFFLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUM7WUFDL0IsVUFBVSxFQUFFLE1BQU0sQ0FBQyxHQUFHLEVBQUU7Z0JBQ3RCLFVBQVU7WUFDWixDQUFDLENBQUM7U0FDSCxDQUFDO1FBRUYsaUJBQWlCO1FBRWpCLElBQUksQ0FBQyxjQUFjLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRTtZQUNsQyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDbkMsT0FBTyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7Z0JBQ3RDLE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUM5QixPQUFPLEVBQUUsRUFBRSxPQUFPLElBQUksSUFBSSxDQUFDO1lBQzdCLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsaUJBQWlCLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUNyQyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxLQUFLLE1BQU0sQ0FBQyxDQUN6RCxDQUFDO1FBRUYsSUFBSSxDQUFDLGtCQUFrQixHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FDdEMsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sS0FBSyxPQUFPLENBQUMsQ0FDMUQsQ0FBQztRQUVGLElBQUksQ0FBQyxlQUFlLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFFdEYsSUFBSSxDQUFDLFlBQVksR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFO1lBQ2hDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUNuQyxNQUFNLE1BQU0sR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztZQUN6QyxLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDO2dCQUNwQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxJQUFJLEdBQUcsQ0FBQyxLQUFLLElBQUksR0FBRyxDQUFDLENBQUM7WUFDcEUsQ0FBQztZQUNELE9BQU8sTUFBTSxDQUFDO1FBQ2hCLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLFlBQVksR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRWpFLElBQUksQ0FBQyxXQUFXLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRTtZQUMvQixPQUFPLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUN4QixDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxXQUFXLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRTtZQUMvQixPQUFPLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUM1QixDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxTQUFTLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUUzRCxJQUFJLENBQUMsU0FBUyxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRXBFLElBQUksQ0FBQyxXQUFXLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQztRQUV2RSxJQUFJLENBQUMsVUFBVSxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUU7WUFDOUIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ25DLElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQztZQUNkLEtBQUssTUFBTSxHQUFHLElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRSxFQUFFLENBQUM7Z0JBQ3hDLEtBQUssSUFBSSxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxHQUFHLENBQUM7WUFDckMsQ0FBQztZQUNELE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQyxDQUFDLENBQUM7UUFFSCxnREFBZ0Q7UUFDaEQsSUFBSSxDQUFDLGVBQWUsR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFO1lBQ25DLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUM1QixNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDakMsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQzVCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUMvQixNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsVUFBVSxJQUFJLENBQUMsQ0FBQztZQUV0QyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQztZQUN4RCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztZQUN4QyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxLQUFLLEdBQUcsWUFBWSxHQUFHLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztZQUUvRCxPQUFPO2dCQUNMLEtBQUs7Z0JBQ0wsR0FBRztnQkFDSCxPQUFPLEVBQUUsS0FBSyxHQUFHLEVBQUU7Z0JBQ25CLFdBQVcsRUFBRSxLQUFLLEdBQUcsRUFBRTthQUN4QixDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCxtREFBbUQ7UUFDbkQsSUFBSSxDQUFDLGVBQWUsR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFO1lBQ25DLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUNuQyxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDaEMsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQzdCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUNwQyxNQUFNLE1BQU0sR0FBRyxDQUFDLENBQUM7WUFFakIsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO1lBQ2QsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztZQUV0QixvQkFBb0I7WUFDcEIsSUFBSSxRQUFRLEdBQUcsQ0FBQyxDQUFDO1lBQ2pCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7Z0JBQ3JDLE1BQU0sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLEdBQUcsQ0FBQztnQkFDeEMsSUFBSSxRQUFRLEdBQUcsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDO29CQUN0QixLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDO29CQUNoQyxNQUFNO2dCQUNSLENBQUM7Z0JBQ0QsUUFBUSxJQUFJLENBQUMsQ0FBQztZQUNoQixDQUFDO1lBRUQsa0JBQWtCO1lBQ2xCLElBQUksU0FBUyxHQUFHLENBQUMsQ0FBQztZQUNsQixLQUFLLElBQUksQ0FBQyxHQUFHLEtBQUssRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO2dCQUN6QyxTQUFTLElBQUksTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksR0FBRyxDQUFDO2dCQUMzQyxJQUFJLFNBQVMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUM7b0JBQ3hCLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztvQkFDNUMsTUFBTTtnQkFDUixDQUFDO1lBQ0gsQ0FBQztZQUVELHNCQUFzQjtZQUN0QixJQUFJLFlBQVksR0FBRyxDQUFDLENBQUM7WUFDckIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO2dCQUMvQixZQUFZLElBQUksTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksR0FBRyxDQUFDO1lBQ2hELENBQUM7WUFFRCxPQUFPO2dCQUNMLEtBQUs7Z0JBQ0wsR0FBRztnQkFDSCxPQUFPLEVBQUUsWUFBWTtnQkFDckIsVUFBVSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7YUFDeEUsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBRUgscUJBQXFCO1FBQ3JCLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzdCLENBQUM7SUFFRCwwQkFBMEI7SUFFMUIsOEJBQThCO0lBQzlCLGNBQWMsQ0FBQyxLQUFhO1FBQzFCLE9BQU8sSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBRUQsd0JBQXdCO0lBQ3hCLGNBQWMsQ0FBQyxLQUFhLEVBQUUsS0FBYTtRQUN6QyxNQUFNLE1BQU0sR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQztRQUM1QyxNQUFNLEVBQUUsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzdCLElBQUksRUFBRSxFQUFFLENBQUM7WUFDUCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEtBQUssQ0FBQyxDQUFDO1lBQzFELE1BQU0sR0FBRyxHQUFHLEdBQUcsRUFBRSxRQUFRLElBQUksRUFBRSxDQUFDO1lBQ2hDLE1BQU0sR0FBRyxHQUFHLEdBQUcsRUFBRSxRQUFRLElBQUksR0FBRyxDQUFDO1lBQ2pDLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3pFLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2hDLENBQUM7SUFDSCxDQUFDO0lBRUQsZ0NBQWdDO0lBQ2hDLHNCQUFzQixDQUFDLEtBQWE7UUFDbEMsTUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUM7UUFDNUMsTUFBTSxFQUFFLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM3QixJQUFJLEVBQUUsRUFBRSxDQUFDO1lBQ1AsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUNuRCxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNoQyxDQUFDO0lBQ0gsQ0FBQztJQUVELGlDQUFpQztJQUNqQyxhQUFhLENBQUMsS0FBYSxFQUFFLFNBQWdDO1FBQzNELE1BQU0sTUFBTSxHQUFHLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDO1FBQzVDLE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDN0IsSUFBSSxFQUFFLEVBQUUsQ0FBQztZQUNQLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUM7WUFDOUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDaEMsQ0FBQztRQUVELG9CQUFvQjtRQUNwQixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDakMsSUFBSSxRQUF5QixDQUFDO1FBRTlCLElBQUksT0FBTyxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ3RCLE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxLQUFLLEtBQUssQ0FBQyxDQUFDO1lBQ25FLElBQUksU0FBUyxFQUFFLENBQUM7Z0JBQ2QsUUFBUSxHQUFHLENBQUMsR0FBRyxRQUFRLEVBQUUsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztZQUN6RSxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sUUFBUSxHQUFHLFFBQVEsQ0FBQztZQUN0QixDQUFDO1FBQ0gsQ0FBQzthQUFNLENBQUM7WUFDTixpQ0FBaUM7WUFDakMsS0FBSyxNQUFNLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLE1BQU0sRUFBRSxDQUFDO2dCQUM3QixJQUFJLEVBQUUsS0FBSyxLQUFLLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO29CQUMzQixNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxFQUFFLEdBQUcsQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO2dCQUN2QyxDQUFDO1lBQ0gsQ0FBQztZQUNELElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzlCLFFBQVEsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDL0QsQ0FBQztRQUVELElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxPQUFPLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztJQUMvQyxDQUFDO0lBRUQsdUJBQXVCO0lBQ3ZCLFVBQVUsQ0FBQyxTQUFpQixFQUFFLE9BQWU7UUFDM0MsTUFBTSxJQUFJLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDO1FBQ3BDLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMxQyxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ1YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQy9CLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzVCLENBQUM7SUFDSCxDQUFDO0lBRUQsdUJBQXVCO0lBRXZCLHNDQUFzQztJQUN0QyxVQUFVLENBQUMsS0FBYSxFQUFFLE9BQWdCO1FBQ3hDLE1BQU0sS0FBSyxHQUFHLE9BQU8sSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsTUFBTSxDQUFDO1FBQy9DLE1BQU0sSUFBSSxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUNqQyxNQUFNLFVBQVUsR0FBYSxFQUFFLENBQUM7UUFFaEMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQy9CLE1BQU0sTUFBTSxHQUFHLGNBQWMsQ0FBQyxhQUFhLEVBQUUsRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQztZQUNsRSxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ2xDLFVBQVUsQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQzdCLENBQUM7UUFFRCxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN2QixPQUFPLFVBQVUsQ0FBQztJQUNwQixDQUFDO0lBRUQsNEJBQTRCO0lBQzVCLFVBQVUsQ0FBQyxPQUFpQjtRQUMxQixNQUFNLE1BQU0sR0FBRyxDQUFDLEdBQUcsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ2xELE1BQU0sSUFBSSxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUNqQyxNQUFNLE9BQU8sR0FBYSxFQUFFLENBQUM7UUFFN0IsS0FBSyxNQUFNLEdBQUcsSUFBSSxNQUFNLEVBQUUsQ0FBQztZQUN6QixJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDbEMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFDeEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDdEIsQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN2QixPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0lBRUQsd0JBQXdCO0lBRXhCLHdCQUF3QjtJQUN4QixZQUFZLENBQUMsUUFBZ0IsRUFBRSxLQUFhO1FBQzFDLE9BQU8sSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFFLEtBQUssQ0FBQyxLQUFLLENBQUMsRUFBRSxLQUFLLElBQUksSUFBSSxDQUFDO0lBQy9ELENBQUM7SUFFRCx3QkFBd0I7SUFDeEIsWUFBWSxDQUFDLFFBQWdCLEVBQUUsS0FBYSxFQUFFLEtBQWdCO1FBQzVELE1BQU0sSUFBSSxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUNqQyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDM0IsSUFBSSxDQUFDLEdBQUc7WUFBRSxPQUFPO1FBRWpCLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRztZQUNmLEdBQUcsR0FBRztZQUNOLEtBQUssRUFBRTtnQkFDTCxHQUFHLEdBQUcsQ0FBQyxLQUFLO2dCQUNaLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxFQUFFO2FBQ2pEO1NBQ0YsQ0FBQztRQUVGLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3pCLENBQUM7SUFFRCx5QkFBeUI7SUFDekIsV0FBVyxDQUFDLFFBQWdCLEVBQUUsS0FBYTtRQUN6QyxPQUFPLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFBRSxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxDQUFDO0lBQ3RELENBQUM7SUFFRCxxQ0FBcUM7SUFDckMsWUFBWSxDQUFDLEtBQWE7UUFDeEIsT0FBTyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEtBQUssQ0FBQyxDQUFDO0lBQ3ZELENBQUM7SUFFRCwwQ0FBMEM7SUFDMUMsV0FBVyxDQUFDLEtBQWE7UUFDdkIsT0FBTyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEtBQUssQ0FBQyxDQUFDO0lBQ2hFLENBQUM7SUFFRCxnQkFBZ0I7SUFFaEIsNEJBQTRCO0lBQzVCLFNBQVMsQ0FBQyxRQUFnQixFQUFFLEtBQWE7UUFDdkMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUU7WUFBRSxPQUFPLEtBQUssQ0FBQztRQUNuQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQztZQUFFLE9BQU8sS0FBSyxDQUFDO1FBRS9ELE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ2pELElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDdEUsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDN0IsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsK0JBQStCO0lBQy9CLFVBQVU7UUFDUixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDaEMsSUFBSSxDQUFDLElBQUk7WUFBRSxPQUFPO1FBRWxCLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDNUMsSUFBSSxDQUFDLEdBQUc7WUFBRSxPQUFPO1FBRWpCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDckQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBRXJDLElBQUksUUFBUSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQzFCLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsRUFBRSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQzlDLElBQUksQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLEVBQUUsRUFBRSxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDbEUsQ0FBQztRQUVELElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzdCLENBQUM7SUFFRCwrQkFBK0I7SUFDL0IsVUFBVTtRQUNSLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzNCLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzlCLENBQUM7SUFFRCxhQUFhO0lBRWIsNENBQTRDO0lBQzVDLE1BQU0sQ0FBQyxLQUFhO1FBQ2xCLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUMsSUFBSSxDQUFDLEVBQUU7WUFBRSxPQUFPO1FBRWhCLE1BQU0sV0FBVyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUM7UUFDNUIsSUFBSSxZQUFtQyxDQUFDO1FBRXhDLElBQUksV0FBVyxLQUFLLElBQUksRUFBRSxDQUFDO1lBQ3pCLFlBQVksR0FBRyxLQUFLLENBQUM7UUFDdkIsQ0FBQzthQUFNLElBQUksV0FBVyxLQUFLLEtBQUssRUFBRSxDQUFDO1lBQ2pDLFlBQVksR0FBRyxNQUFNLENBQUM7UUFDeEIsQ0FBQzthQUFNLENBQUM7WUFDTixZQUFZLEdBQUcsSUFBSSxDQUFDO1FBQ3RCLENBQUM7UUFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLFlBQVksQ0FBQztZQUFFLE9BQU87UUFFN0QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDeEMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLEVBQUUsQ0FBQztJQUM5QixDQUFDO0lBRUQseUJBQXlCO0lBQ3pCLFNBQVM7UUFDUCxNQUFNLE1BQU0sR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQztRQUM1QyxLQUFLLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLElBQUksTUFBTSxFQUFFLENBQUM7WUFDOUIsSUFBSSxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ1osTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDO1lBQzlELENBQUM7UUFDSCxDQUFDO1FBQ0QsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDOUIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQztJQUM5RSxDQUFDO0lBRUQsZUFBZTtJQUVmLHNCQUFzQjtJQUN0QixXQUFXLENBQ1QsS0FBYSxFQUNiLFFBQXFDLEVBQ3JDLEtBQWMsRUFDZCxPQUFpQjtRQUVqQixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDbkMsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLEtBQUssS0FBSyxDQUFDLENBQUM7UUFDbkUsTUFBTSxRQUFRLEdBQUcsQ0FBQyxHQUFHLFFBQVEsRUFBRSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDcEUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLE9BQU8sRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDO0lBQ2pELENBQUM7SUFFRCxpQ0FBaUM7SUFDakMsaUJBQWlCLENBQUMsS0FBYTtRQUM3QixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDbkMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUM7WUFDbkIsR0FBRyxPQUFPO1lBQ1YsUUFBUSxFQUFFLE9BQU8sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxLQUFLLEtBQUssQ0FBQztTQUM1RCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQseUJBQXlCO0lBQ3pCLFlBQVk7UUFDVixJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7SUFDdEQsQ0FBQztJQUVELG1CQUFtQjtJQUVuQixxQ0FBcUM7SUFDckMsUUFBUSxDQUFDLFFBQWdCLEVBQUUsUUFBZ0I7UUFDekMsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQzdCLE1BQU0sT0FBTyxHQUFHLEdBQUcsQ0FBQyxVQUFVLElBQUksRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQztRQUNyRCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsR0FBRyxDQUFDLEVBQUUsT0FBTyxDQUFDLEdBQUcsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDO1FBQ25GLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxHQUFHLENBQUMsRUFBRSxPQUFPLENBQUMsR0FBRyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFFdEYsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUM7WUFDakIsR0FBRyxHQUFHO1lBQ04sVUFBVSxFQUFFLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFO1lBQ3hDLEtBQUssRUFBRSxFQUFFLEtBQUssRUFBRSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxFQUFFO1NBQ2xGLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxxQ0FBcUM7SUFDckMsWUFBWSxDQUFDLFFBQWdCLEVBQUUsU0FBaUI7UUFDOUMsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQzVCLE1BQU0sT0FBTyxHQUFHLFFBQVEsR0FBRyxFQUFFLENBQUM7UUFDOUIsTUFBTSxVQUFVLEdBQUcsT0FBTyxHQUFHLEVBQUUsQ0FBQztRQUVoQyxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDNUIsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBRWpDLElBQUksT0FBTyxHQUFHLEVBQUUsRUFBRSxDQUFDO1lBQ2pCLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzlCLENBQUM7YUFBTSxJQUFJLFVBQVUsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUM7WUFDaEMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsVUFBVSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQ3RDLENBQUM7SUFDSCxDQUFDO0lBRUQsa0JBQWtCO0lBRWxCLHFCQUFxQjtJQUNyQixVQUFVLENBQUMsR0FBVyxFQUFFLEdBQVc7UUFDakMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUM7WUFDakIsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFO1lBQ25CLFVBQVUsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUU7WUFDeEIsS0FBSyxFQUFFLEVBQUUsS0FBSyxFQUFFLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRTtZQUNqRCxJQUFJLEVBQUUsTUFBTTtTQUNiLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxzQkFBc0I7SUFDdEIsV0FBVyxDQUFDLEtBQWtCLEVBQUUsR0FBZ0I7UUFDOUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUM7WUFDakIsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFO1lBQ25CLEtBQUssRUFBRSxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUU7WUFDckIsSUFBSSxFQUFFLE9BQU87U0FDZCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsb0JBQW9CO0lBQ3BCLFNBQVMsQ0FBQyxRQUFnQjtRQUN4QixNQUFNLElBQUksR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDcEQsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7WUFDdkIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN4QixDQUFDO2FBQU0sQ0FBQztZQUNOLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDckIsQ0FBQztRQUNELElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUMvRSxDQUFDO0lBRUQsdUJBQXVCO0lBQ3ZCLFlBQVksQ0FBQyxRQUFnQjtRQUMzQixNQUFNLElBQUksR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDcEQsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7WUFDdkIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN4QixDQUFDO2FBQU0sQ0FBQztZQUNOLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDckIsQ0FBQztRQUNELElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztJQUNsRixDQUFDO0lBRUQsd0JBQXdCO0lBQ3hCLFNBQVM7UUFDUCxNQUFNLE9BQU8sR0FBRyxJQUFJLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMvRSxNQUFNLE9BQU8sR0FBRyxJQUFJLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsRixJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQztZQUNqQixVQUFVLEVBQUUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUU7WUFDOUIsS0FBSyxFQUFFO2dCQUNMLEtBQUssRUFBRSxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRTtnQkFDekIsR0FBRyxFQUFFLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUUsR0FBRyxDQUFDLEVBQUU7YUFDakU7WUFDRCxZQUFZLEVBQUUsT0FBTztZQUNyQixZQUFZLEVBQUUsT0FBTztZQUNyQixJQUFJLEVBQUUsT0FBTztZQUNiLFFBQVEsRUFBRSxLQUFLO1NBQ2hCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxtQ0FBbUM7SUFDbkMsY0FBYyxDQUFDLEdBQVcsRUFBRSxHQUFXO1FBQ3JDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUM3QixJQUFJLEdBQUcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNkLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQzlELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQzlELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQzlELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQzlELElBQUksR0FBRyxJQUFJLElBQUksSUFBSSxHQUFHLElBQUksSUFBSSxJQUFJLEdBQUcsSUFBSSxJQUFJLElBQUksR0FBRyxJQUFJLElBQUk7Z0JBQUUsT0FBTyxJQUFJLENBQUM7UUFDNUUsQ0FBQztRQUNELE9BQU8sR0FBRyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDaEUsQ0FBQztJQUVELDBDQUEwQztJQUMxQyxZQUFZLENBQUMsR0FBVyxFQUFFLEdBQVc7UUFDbkMsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLFVBQVUsQ0FBQztRQUN2QyxPQUFPLEVBQUUsRUFBRSxHQUFHLEtBQUssR0FBRyxJQUFJLEVBQUUsRUFBRSxHQUFHLEtBQUssR0FBRyxDQUFDO0lBQzVDLENBQUM7SUFFRCxnQkFBZ0I7SUFFaEIsOENBQThDO0lBQzlDLE9BQU87UUFDTCxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbkMsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUVELGdCQUFnQjtJQUVoQixPQUFPO1FBQ0wsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUM1QixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjb21wdXRlZCwgc2lnbmFsLCB0eXBlIFdyaXRhYmxlU2lnbmFsLCB0eXBlIFNpZ25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHR5cGUge1xuICBDZWxsVmFsdWUsXG4gIENlbGxBZGRyZXNzLFxuICBDZWxsTWV0YSxcbiAgQ29sdW1uRGVmLFxuICBDb2x1bW5TdGF0ZSxcbiAgUm93RGVmLFxuICBTZWxlY3Rpb25TdGF0ZSxcbiAgU29ydFN0YXRlLFxuICBTb3J0Q3JpdGVyaW9uLFxuICBGaWx0ZXJTdGF0ZSxcbiAgRmlsdGVyQ3JpdGVyaW9uLFxufSBmcm9tICcuL21vZGVscyc7XG5pbXBvcnQgdHlwZSB7IFNwcmVhZHNoZWV0UGx1Z2luIH0gZnJvbSAnLi9wbHVnaW4vcGx1Z2luLnR5cGVzJztcbmltcG9ydCB7IFBsdWdpbkhvc3QgfSBmcm9tICcuL3BsdWdpbi9wbHVnaW4taG9zdCc7XG5pbXBvcnQgeyBnZW5lcmF0ZVJvd0lkLCBjcmVhdGVFbXB0eVJvdyB9IGZyb20gJy4vdXRpbHMvY2VsbC11dGlscyc7XG5cbi8qKiBEZW5zaXR5IHByZXNldHMgY29udHJvbGxpbmcgcm93IGhlaWdodCBhbmQgY2VsbCBwYWRkaW5nLiAqL1xuZXhwb3J0IHR5cGUgU3ByZWFkc2hlZXREZW5zaXR5ID0gJ2NvbXBhY3QnIHwgJ2NvbWZvcnRhYmxlJyB8ICdkZW5zZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3ByZWFkc2hlZXRDb25maWcge1xuICAvKiogQ29sdW1uIGRlZmluaXRpb25zLiAqL1xuICBjb2x1bW5zPzogQ29sdW1uRGVmW107XG4gIC8qKiBJbml0aWFsIHJvdyBkYXRhLiAqL1xuICByb3dzPzogUm93RGVmW107XG4gIC8qKiBFbmFibGUgbXVsdGktY29sdW1uIHNvcnRpbmcuICovXG4gIG11bHRpU29ydD86IGJvb2xlYW47XG4gIC8qKiBTZWxlY3Rpb24gbW9kZS4gKi9cbiAgc2VsZWN0aW9uTW9kZT86ICdjZWxsJyB8ICdyYW5nZScgfCAncm93JyB8ICdjb2x1bW4nIHwgJ25vbmUnO1xuICAvKiogRGVuc2l0eSBwcmVzZXQuICovXG4gIGRlbnNpdHk/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=
|