@libs-ui/components-spreadsheet 0.2.356-43
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 +3 -0
- package/esm2022/index.mjs +3 -0
- package/esm2022/libs-ui-components-spreadsheet.mjs +5 -0
- package/esm2022/spreadsheet.component.mjs +869 -0
- package/esm2022/spreadsheet.indicator.mjs +204 -0
- package/esm2022/spreadsheet.locale.mjs +67 -0
- package/esm2022/spreadsheet.numfmt.mjs +209 -0
- package/esm2022/spreadsheet.type.mjs +2 -0
- package/fesm2022/libs-ui-components-spreadsheet.mjs +1350 -0
- package/fesm2022/libs-ui-components-spreadsheet.mjs.map +1 -0
- package/index.d.ts +4 -0
- package/package.json +38 -0
- package/spreadsheet.component.d.ts +178 -0
- package/spreadsheet.indicator.d.ts +123 -0
- package/spreadsheet.locale.d.ts +2 -0
- package/spreadsheet.numfmt.d.ts +24 -0
- package/spreadsheet.type.d.ts +43 -0
|
@@ -0,0 +1,869 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, Component, NgZone, effect, inject, input, output, signal, untracked, viewChild } from '@angular/core';
|
|
2
|
+
import { LocaleType, Univer, UniverInstanceType } from '@univerjs/core';
|
|
3
|
+
import { defaultTheme } from '@univerjs/design';
|
|
4
|
+
import { UniverDocsPlugin } from '@univerjs/docs';
|
|
5
|
+
import { UniverDocsUIPlugin } from '@univerjs/docs-ui';
|
|
6
|
+
import { UniverFormulaEnginePlugin } from '@univerjs/engine-formula';
|
|
7
|
+
import { UniverRenderEnginePlugin } from '@univerjs/engine-render';
|
|
8
|
+
import { FUniver } from '@univerjs/facade';
|
|
9
|
+
import { InsertColMutation, MoveColsMutation, RemoveColMutation, UniverSheetsPlugin } from '@univerjs/sheets';
|
|
10
|
+
import { UniverSheetsFormulaPlugin } from '@univerjs/sheets-formula';
|
|
11
|
+
import { UniverSheetsFormulaUIPlugin } from '@univerjs/sheets-formula-ui';
|
|
12
|
+
import { UniverSheetsNumfmtPlugin } from '@univerjs/sheets-numfmt';
|
|
13
|
+
import { UniverSheetsUIPlugin } from '@univerjs/sheets-ui';
|
|
14
|
+
import { UniverUIPlugin } from '@univerjs/ui';
|
|
15
|
+
import { univerLocaleEn, univerLocaleVi } from './spreadsheet.locale';
|
|
16
|
+
import { injectCustomDateFormats, syncActiveNumfmtHighlight } from './spreadsheet.numfmt';
|
|
17
|
+
import { applyMappingIndicators, stripMappingIndicators } from './spreadsheet.indicator';
|
|
18
|
+
import * as i0 from "@angular/core";
|
|
19
|
+
// Bộ đếm tạo class scope duy nhất cho mỗi instance spreadsheet (dùng cho <style> chỉnh width toolbar).
|
|
20
|
+
let spreadsheetInstanceCount = 0;
|
|
21
|
+
export class LibsUiComponentsSpreadsheetComponent {
|
|
22
|
+
univer = null;
|
|
23
|
+
univerAPI = null;
|
|
24
|
+
columnClickDisposable = null;
|
|
25
|
+
formatDisposable = null;
|
|
26
|
+
columnOpDisposable = null;
|
|
27
|
+
numfmtObserver = null;
|
|
28
|
+
toolbarResizeObserver = null;
|
|
29
|
+
// <style> riêng cho instance: pin width container đo qua CSS rule (React re-render KHÔNG strip được →
|
|
30
|
+
// tránh vòng lặp oscillation giữa set-inline-width và React strip gây kẹt ⋮). Xem registerToolbarWidthSync.
|
|
31
|
+
toolbarStyleEl = null;
|
|
32
|
+
toolbarScopeClass = `libs-ui-spreadsheet-tb-${(spreadsheetInstanceCount += 1)}`;
|
|
33
|
+
numfmtClickDisposable = null;
|
|
34
|
+
lastRangeSnapshot = null;
|
|
35
|
+
pendingNumfmtPattern = null;
|
|
36
|
+
// true CHỈ khi user bấm nút Confirm trong panel numfmt → giữ format; Cancel/X/click-ngoài = false → revert.
|
|
37
|
+
numfmtConfirmed = false;
|
|
38
|
+
// Snapshot numfmt từng ô của vùng chọn tại thời điểm mở panel — dùng khôi phục chính xác khi Cancel.
|
|
39
|
+
originalCellFormats = null;
|
|
40
|
+
numfmtPanelOpen = false;
|
|
41
|
+
// true khi luồng Date custom đang hoạt động (đã inject option ngày). CHỈ khi đó component mới
|
|
42
|
+
// can thiệp confirm/revert; các Type khác (Số, Tiền tệ, %, Text…) do Univer tự xử lý → không đụng vào.
|
|
43
|
+
numfmtDateActive = false;
|
|
44
|
+
// Đồng bộ lại panel Date (label + highlight + auto-apply) theo vùng chọn mới khi user đổi cột lúc panel mở.
|
|
45
|
+
numfmtResync = null;
|
|
46
|
+
listenEnabled = false;
|
|
47
|
+
listenEnableTimer = null;
|
|
48
|
+
// Defer initial empty-workbook init to allow parent's ngAfterViewInit to call loadData
|
|
49
|
+
// first (cancelling the empty init), avoiding a race with Univer's async React renders.
|
|
50
|
+
pendingInitTimer = null;
|
|
51
|
+
numfmtCleanup = null;
|
|
52
|
+
pendingReadyCb = null;
|
|
53
|
+
// Snapshot đã-decorate gần nhất — làm baseline để diff (style id ổn định 'h'/'m', không bị
|
|
54
|
+
// ảnh hưởng bởi style id tự sinh sau mỗi facade setValue). Dùng cho re-apply incremental.
|
|
55
|
+
lastDecorated = null;
|
|
56
|
+
readyObserver = null;
|
|
57
|
+
// Cache controller numfmt nội bộ của Univer (giữ _previewPattern). Tìm 1 lần qua injector.
|
|
58
|
+
// CONVENTION-EXCEPT: any — NumfmtController không export khỏi @univerjs/sheets-numfmt
|
|
59
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
60
|
+
numfmtController = null;
|
|
61
|
+
activeCellFormat = signal('General');
|
|
62
|
+
activeCellRef = signal('');
|
|
63
|
+
showToolbar = signal(true);
|
|
64
|
+
showSheetTabs = signal(true);
|
|
65
|
+
// Ngôn ngữ đang hiển thị thực tế. Khởi tạo từ input `locale` trong ngAfterViewInit,
|
|
66
|
+
// sau đó đổi runtime qua setLocale() (kéo theo reinit để Univer render lại UI).
|
|
67
|
+
activeLocale = signal('vi');
|
|
68
|
+
/** Ngôn ngữ khởi tạo của spreadsheet. Đổi runtime dùng FunctionControl.setLocale(). */
|
|
69
|
+
locale = input('vi');
|
|
70
|
+
/** Cấu hình ẩn / vô hiệu hoá toolbar items. Thay đổi sẽ reinit toàn bộ Univer. */
|
|
71
|
+
toolbarMenuConfig = input({
|
|
72
|
+
// 'sheet.command.numfmt.set.currency': { hidden: true },
|
|
73
|
+
// 'sheet.command.numfmt.add.decimal.command': { hidden: true },
|
|
74
|
+
// 'sheet.command.numfmt.subtract.decimal.command': { hidden: true },
|
|
75
|
+
// 'sheet.command.numfmt.set.percent': { hidden: true },
|
|
76
|
+
'sheet.command.set-once-format-painter': { hidden: true },
|
|
77
|
+
'sheet.command.set-text-rotation': { hidden: true },
|
|
78
|
+
'sheet.command.set-range-font-family': { hidden: true },
|
|
79
|
+
'sheet.command.set-border-basic': { hidden: true },
|
|
80
|
+
'sheet.command.add-worksheet-merge': { hidden: true },
|
|
81
|
+
'sheet.command.add-worksheet-merge-all': { hidden: true },
|
|
82
|
+
'sheet.command.add-worksheet-merge-vertical': { hidden: true },
|
|
83
|
+
'sheet.command.add-worksheet-merge-horizontal': { hidden: true },
|
|
84
|
+
'sheet.command.remove-worksheet-merge': { hidden: true },
|
|
85
|
+
});
|
|
86
|
+
/**
|
|
87
|
+
* Cấu hình highlight cột đã map (style / prefix / scope sheet).
|
|
88
|
+
* Truyền config này = "bật" luồng auto: component sẽ TỰ áp indicator khi load/reset,
|
|
89
|
+
* TỰ gỡ khi save, và TỰ vẽ lại mỗi khi `mappingTargets` đổi. Bỏ trống = spreadsheet thường.
|
|
90
|
+
*/
|
|
91
|
+
mappingIndicatorConfig = input();
|
|
92
|
+
/** Danh sách cột cần highlight (`{ sheetId, colIndex }`). Đổi runtime → tự vẽ lại header. */
|
|
93
|
+
mappingTargets = input([]);
|
|
94
|
+
outColumnDblClick = output();
|
|
95
|
+
/**
|
|
96
|
+
* Phát khi user insert / remove / move cột (kể cả chọn nhiều cột, và cả undo/redo).
|
|
97
|
+
* Consumer dùng `remapColumnIndexes(mappings, $event)` để dịch lại mảng mapping bên ngoài
|
|
98
|
+
* cho khớp vị trí mới — tránh lệch khi chèn/xóa cột ở giữa.
|
|
99
|
+
*/
|
|
100
|
+
outColumnStructureChange = output();
|
|
101
|
+
containerRef = viewChild('containerRef');
|
|
102
|
+
ngZone = inject(NgZone);
|
|
103
|
+
constructor() {
|
|
104
|
+
// Auto re-apply: chỉ chạy khi đã bật config + Univer đã khởi tạo. Lần đầu (chưa init) tự bỏ qua.
|
|
105
|
+
effect(() => {
|
|
106
|
+
this.mappingTargets();
|
|
107
|
+
this.mappingIndicatorConfig();
|
|
108
|
+
untracked(() => this.reapplyIndicators());
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
ngAfterViewInit() {
|
|
112
|
+
this.activeLocale.set(this.locale());
|
|
113
|
+
this.pendingInitTimer = setTimeout(() => {
|
|
114
|
+
this.pendingInitTimer = null;
|
|
115
|
+
this.initUniver(this.buildEmptyWorkbook());
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
get FunctionControl() {
|
|
119
|
+
return {
|
|
120
|
+
loadData: (data) => this.loadData(data),
|
|
121
|
+
saveData: () => this.saveData(),
|
|
122
|
+
getActiveSheetInfo: () => this.getActiveSheetInfo(),
|
|
123
|
+
getColumnNumfmt: (sheetId, colIndex) => this.getColumnNumfmt(sheetId, colIndex),
|
|
124
|
+
extractAllColumnFormats: (snapshot) => this.extractAllColumnFormats(snapshot),
|
|
125
|
+
toggleToolbar: () => this.toggleToolbar(),
|
|
126
|
+
toggleSheetTabs: () => this.toggleSheetTabs(),
|
|
127
|
+
reset: (data) => this.reset(data),
|
|
128
|
+
executeCommand: (commandId, params) => this.executeCommand(commandId, params),
|
|
129
|
+
applyNumfmt: (row, col, numRows, numCols, pattern) => this.applyNumfmt(row, col, numRows, numCols, pattern),
|
|
130
|
+
scheduleOnReady: (cb) => {
|
|
131
|
+
this.pendingReadyCb = cb;
|
|
132
|
+
},
|
|
133
|
+
setLocale: (locale) => this.setLocale(locale),
|
|
134
|
+
activeCellRef: this.activeCellRef,
|
|
135
|
+
activeCellFormat: this.activeCellFormat,
|
|
136
|
+
showToolbar: this.showToolbar,
|
|
137
|
+
showSheetTabs: this.showSheetTabs,
|
|
138
|
+
locale: this.activeLocale.asReadonly(),
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
setLocale(locale) {
|
|
142
|
+
if (locale === this.activeLocale())
|
|
143
|
+
return;
|
|
144
|
+
this.activeLocale.set(locale);
|
|
145
|
+
this.reinitUniver();
|
|
146
|
+
}
|
|
147
|
+
loadData(data) {
|
|
148
|
+
const decorated = this.decorateSnapshot(data);
|
|
149
|
+
if (this.pendingInitTimer !== null) {
|
|
150
|
+
clearTimeout(this.pendingInitTimer);
|
|
151
|
+
this.pendingInitTimer = null;
|
|
152
|
+
this.initUniver(decorated);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
this.destroyUniver();
|
|
156
|
+
setTimeout(() => this.initUniver(decorated));
|
|
157
|
+
}
|
|
158
|
+
/** Snapshot thô từ Univer (CÓ thể còn indicator). Dùng nội bộ cho re-apply. */
|
|
159
|
+
saveRaw() {
|
|
160
|
+
return (this.univerAPI?.getActiveWorkbook()?.save() ?? {});
|
|
161
|
+
}
|
|
162
|
+
/** Snapshot trả cho consumer — tự gỡ indicator nếu luồng auto đang bật. */
|
|
163
|
+
saveData() {
|
|
164
|
+
const config = this.mappingIndicatorConfig();
|
|
165
|
+
if (!config)
|
|
166
|
+
return this.saveRaw();
|
|
167
|
+
return stripMappingIndicators(this.saveRaw(), config);
|
|
168
|
+
}
|
|
169
|
+
/** Áp indicator vào snapshot trước khi load — chỉ khi luồng auto đang bật. Lưu baseline để diff. */
|
|
170
|
+
decorateSnapshot(data) {
|
|
171
|
+
const config = this.mappingIndicatorConfig();
|
|
172
|
+
if (!config)
|
|
173
|
+
return data;
|
|
174
|
+
const decorated = applyMappingIndicators(data, this.mappingTargets(), config);
|
|
175
|
+
this.lastDecorated = decorated;
|
|
176
|
+
return decorated;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Vẽ lại indicator KHÔNG reinit Univer: tính snapshot đích rồi CHỈ ghi đè đúng các ô header
|
|
180
|
+
* khác so với baseline trước đó (style + prefix + width) lên instance live qua facade.
|
|
181
|
+
* Diff theo baseline (style id ổn định 'h'/'m') → chỉ các cột vừa map/bỏ map mới được vẽ lại.
|
|
182
|
+
*/
|
|
183
|
+
reapplyIndicators() {
|
|
184
|
+
const config = this.mappingIndicatorConfig();
|
|
185
|
+
const wb = this.univerAPI?.getActiveWorkbook();
|
|
186
|
+
const prev = this.lastDecorated;
|
|
187
|
+
if (!config || !wb || !prev)
|
|
188
|
+
return;
|
|
189
|
+
const next = applyMappingIndicators(this.saveRaw(), this.mappingTargets(), config);
|
|
190
|
+
this.lastDecorated = next;
|
|
191
|
+
const headerKey = String(config.headerRowIndex ?? 0);
|
|
192
|
+
const headerRow = Number(headerKey);
|
|
193
|
+
const stylesNext = (next['styles'] ?? {});
|
|
194
|
+
const sheetsNext = (next['sheets'] ?? {});
|
|
195
|
+
const sheetsPrev = (prev['sheets'] ?? {});
|
|
196
|
+
for (const sheetId of Object.keys(sheetsNext)) {
|
|
197
|
+
const ws = wb.getSheetBySheetId(sheetId);
|
|
198
|
+
if (!ws)
|
|
199
|
+
continue;
|
|
200
|
+
const nextRow = sheetsNext[sheetId]?.cellData?.[headerKey] ?? {};
|
|
201
|
+
const prevRow = sheetsPrev[sheetId]?.cellData?.[headerKey] ?? {};
|
|
202
|
+
const colData = sheetsNext[sheetId]?.columnData ?? {};
|
|
203
|
+
for (const colKey of Object.keys(nextRow)) {
|
|
204
|
+
const cellNext = nextRow[colKey];
|
|
205
|
+
const cellPrev = prevRow[colKey];
|
|
206
|
+
// Ô không đổi cả value lẫn style → bỏ qua (mấu chốt: chỉ vẽ lại cột vừa map/bỏ map).
|
|
207
|
+
if (!cellNext || (cellNext.v === cellPrev?.v && cellNext.s === cellPrev?.s))
|
|
208
|
+
continue;
|
|
209
|
+
const style = (typeof cellNext.s === 'string' ? stylesNext[cellNext.s] : cellNext.s);
|
|
210
|
+
const cell = { v: cellNext.v, s: style };
|
|
211
|
+
void ws.getRange(headerRow, Number(colKey)).setValue(cell);
|
|
212
|
+
const width = colData[colKey]?.w;
|
|
213
|
+
if (typeof width === 'number')
|
|
214
|
+
void ws.setColumnWidth(Number(colKey), width);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
toggleToolbar() {
|
|
219
|
+
this.showToolbar.update((v) => !v);
|
|
220
|
+
this.reinitUniver();
|
|
221
|
+
}
|
|
222
|
+
toggleSheetTabs() {
|
|
223
|
+
this.showSheetTabs.update((v) => !v);
|
|
224
|
+
this.reinitUniver();
|
|
225
|
+
}
|
|
226
|
+
reset(data) {
|
|
227
|
+
this.destroyUniver();
|
|
228
|
+
this.initUniver(this.decorateSnapshot(data ?? this.buildEmptyWorkbook()));
|
|
229
|
+
}
|
|
230
|
+
executeCommand(commandId, params) {
|
|
231
|
+
// CONVENTION-EXCEPT: any — FUniver.executeCommand không expose typing
|
|
232
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
233
|
+
void this.univerAPI?.executeCommand?.(commandId, params);
|
|
234
|
+
}
|
|
235
|
+
applyNumfmt(row, col, numRows, numCols, pattern) {
|
|
236
|
+
// CONVENTION-EXCEPT: any — FWorkbook.getId / FWorksheet.getSheetId not exposed in public types
|
|
237
|
+
// Note: FRange.setNumberFormat() has a Univer facade bug — it builds `values` but never passes
|
|
238
|
+
// them to executeCommand. We call the command directly with the correct params instead.
|
|
239
|
+
// FWorkbook uses getId() (not getUnitId()) and FWorksheet uses getSheetId() for subUnitId.
|
|
240
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
241
|
+
const wb = this.univerAPI?.getActiveWorkbook();
|
|
242
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
243
|
+
const ws = wb?.getActiveSheet?.();
|
|
244
|
+
if (!wb || !ws)
|
|
245
|
+
return;
|
|
246
|
+
const unitId = (wb.getId?.() ?? '');
|
|
247
|
+
const subUnitId = (ws.getSheetId?.() ?? '');
|
|
248
|
+
const values = [];
|
|
249
|
+
for (let r = row; r < row + numRows; r++) {
|
|
250
|
+
for (let c = col; c < col + numCols; c++) {
|
|
251
|
+
values.push({ pattern, row: r, col: c });
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
this.executeCommand('sheet.command.numfmt.set.numfmt', { unitId, subUnitId, values });
|
|
255
|
+
}
|
|
256
|
+
getActiveSheetInfo() {
|
|
257
|
+
// CONVENTION-EXCEPT: any — FWorksheet public types chưa expose getSheetId/getName
|
|
258
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
259
|
+
const sheet = this.univerAPI?.getActiveWorkbook()?.getActiveSheet();
|
|
260
|
+
if (!sheet)
|
|
261
|
+
return null;
|
|
262
|
+
return {
|
|
263
|
+
sheetId: (sheet.getSheetId?.() ?? ''),
|
|
264
|
+
sheetName: (sheet.getSheetName?.() ?? sheet.getName?.() ?? ''),
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
/** Đọc numfmt pattern của một cell từ workbook snapshot. */
|
|
268
|
+
readCellNumfmt(sheetId, row, col) {
|
|
269
|
+
try {
|
|
270
|
+
// CONVENTION-EXCEPT: any — FWorkbook.save() không expose typing
|
|
271
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
272
|
+
const ss = this.univerAPI?.getActiveWorkbook()?.save();
|
|
273
|
+
const styles = ss?.styles;
|
|
274
|
+
const cells = ss?.sheets?.[sheetId]?.cellData;
|
|
275
|
+
const styleId = cells?.[String(row)]?.[String(col)]?.s;
|
|
276
|
+
if (!styleId || !styles)
|
|
277
|
+
return 'General';
|
|
278
|
+
return styles[styleId]?.n?.pattern ?? styles[styleId]?.nf?.pattern ?? 'General';
|
|
279
|
+
}
|
|
280
|
+
catch {
|
|
281
|
+
return 'General';
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
/** Đọc giá trị số (Excel serial) của một ô; null nếu ô rỗng/không phải số. */
|
|
285
|
+
readCellValue(sheetId, row, col) {
|
|
286
|
+
try {
|
|
287
|
+
// CONVENTION-EXCEPT: any — FWorkbook.save() không expose typing
|
|
288
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
289
|
+
const ss = this.univerAPI?.getActiveWorkbook()?.save();
|
|
290
|
+
const cells = ss?.sheets?.[sheetId]?.cellData;
|
|
291
|
+
const value = cells?.[String(row)]?.[String(col)]?.v;
|
|
292
|
+
return typeof value === 'number' && isFinite(value) ? value : null;
|
|
293
|
+
}
|
|
294
|
+
catch {
|
|
295
|
+
return null;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
getColumnNumfmt(sheetId, colIndex) {
|
|
299
|
+
for (const row of [1, 2, 3]) {
|
|
300
|
+
const pattern = this.readCellNumfmt(sheetId, row, colIndex);
|
|
301
|
+
if (pattern !== 'General')
|
|
302
|
+
return pattern;
|
|
303
|
+
}
|
|
304
|
+
return 'General';
|
|
305
|
+
}
|
|
306
|
+
/** Chụp numfmt gốc từng ô của vùng chọn (giới hạn 500 dòng như applyFormat) để Cancel khôi phục đúng. */
|
|
307
|
+
captureRangeNumfmt(snap) {
|
|
308
|
+
if (!snap)
|
|
309
|
+
return null;
|
|
310
|
+
const values = [];
|
|
311
|
+
const maxRow = Math.min(snap.endRow, snap.startRow + 499);
|
|
312
|
+
for (let r = snap.startRow; r <= maxRow; r++) {
|
|
313
|
+
for (let c = snap.startColumn; c <= snap.endColumn; c++) {
|
|
314
|
+
values.push({ pattern: this.readCellNumfmt(snap.subUnitId, r, c), row: r, col: c });
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return values.length ? values : null;
|
|
318
|
+
}
|
|
319
|
+
extractAllColumnFormats(snapshot) {
|
|
320
|
+
const styles = snapshot['styles'];
|
|
321
|
+
const sheets = snapshot['sheets'];
|
|
322
|
+
const order = snapshot['sheetOrder'];
|
|
323
|
+
if (!styles || !sheets)
|
|
324
|
+
return [];
|
|
325
|
+
const results = [];
|
|
326
|
+
const seen = new Set();
|
|
327
|
+
for (const sheetId of order ?? Object.keys(sheets)) {
|
|
328
|
+
const sheetData = sheets[sheetId];
|
|
329
|
+
if (!sheetData?.cellData)
|
|
330
|
+
continue;
|
|
331
|
+
const sheetName = sheetData.name ?? sheetId;
|
|
332
|
+
const headerRow = sheetData.cellData['0'] ?? {};
|
|
333
|
+
for (const rowKey of ['1', '2', '3']) {
|
|
334
|
+
const row = sheetData.cellData[rowKey];
|
|
335
|
+
if (!row)
|
|
336
|
+
continue;
|
|
337
|
+
for (const colKey of Object.keys(row)) {
|
|
338
|
+
const key = `${sheetId}:${colKey}`;
|
|
339
|
+
if (seen.has(key))
|
|
340
|
+
continue;
|
|
341
|
+
const styleId = row[colKey]?.s;
|
|
342
|
+
if (!styleId)
|
|
343
|
+
continue;
|
|
344
|
+
const pattern = styles[styleId]?.n?.pattern ?? styles[styleId]?.nf?.pattern;
|
|
345
|
+
if (!pattern)
|
|
346
|
+
continue;
|
|
347
|
+
seen.add(key);
|
|
348
|
+
const colIndex = parseInt(colKey, 10);
|
|
349
|
+
const colLetter = this.toColLetter(colIndex);
|
|
350
|
+
const headerV = headerRow[colKey]?.v;
|
|
351
|
+
results.push({
|
|
352
|
+
sheet: sheetName,
|
|
353
|
+
col: colLetter,
|
|
354
|
+
colIndex,
|
|
355
|
+
header: headerV ? String(headerV) : colLetter,
|
|
356
|
+
numfmt: pattern,
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
return results;
|
|
362
|
+
}
|
|
363
|
+
toColLetter(index) {
|
|
364
|
+
let result = '';
|
|
365
|
+
let n = index;
|
|
366
|
+
do {
|
|
367
|
+
result = String.fromCharCode(65 + (n % 26)) + result;
|
|
368
|
+
n = Math.floor(n / 26) - 1;
|
|
369
|
+
} while (n >= 0);
|
|
370
|
+
return result;
|
|
371
|
+
}
|
|
372
|
+
buildEmptyWorkbook() {
|
|
373
|
+
return {
|
|
374
|
+
id: 'workbook-default',
|
|
375
|
+
locale: this.resolveLocaleType(),
|
|
376
|
+
name: 'Sheet',
|
|
377
|
+
sheetOrder: ['sheet1'],
|
|
378
|
+
appVersion: '3.0.0-alpha',
|
|
379
|
+
sheets: {
|
|
380
|
+
sheet1: { id: 'sheet1', name: 'Sheet1', rowCount: 30, columnCount: 26, cellData: {} },
|
|
381
|
+
},
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
resolveLocaleType() {
|
|
385
|
+
return this.activeLocale() === 'vi' ? LocaleType.VI_VN : LocaleType.EN_US;
|
|
386
|
+
}
|
|
387
|
+
registerColumnClickListener() {
|
|
388
|
+
const wrapper = this.containerRef()?.nativeElement;
|
|
389
|
+
if (!wrapper)
|
|
390
|
+
return;
|
|
391
|
+
this.listenEnableTimer = setTimeout(() => {
|
|
392
|
+
this.listenEnabled = true;
|
|
393
|
+
}, 600);
|
|
394
|
+
const handleDblClick = (event) => {
|
|
395
|
+
if (!this.listenEnabled)
|
|
396
|
+
return;
|
|
397
|
+
if (event.target.tagName !== 'CANVAS')
|
|
398
|
+
return;
|
|
399
|
+
setTimeout(() => {
|
|
400
|
+
this.ngZone.run(() => {
|
|
401
|
+
const range = this.univerAPI?.getActiveWorkbook()?.getActiveSheet()?.getActiveRange();
|
|
402
|
+
if (!range)
|
|
403
|
+
return;
|
|
404
|
+
const { startRow, endRow, startColumn, rangeType } = range.getRange();
|
|
405
|
+
const isColHeader = rangeType === 2 || (startRow === 0 && endRow >= 29);
|
|
406
|
+
const isFirstRow = startRow === 0 && endRow === 0;
|
|
407
|
+
if (!isColHeader && !isFirstRow)
|
|
408
|
+
return;
|
|
409
|
+
this.outColumnDblClick.emit(startColumn);
|
|
410
|
+
});
|
|
411
|
+
}, 50);
|
|
412
|
+
};
|
|
413
|
+
wrapper.addEventListener('dblclick', handleDblClick);
|
|
414
|
+
this.columnClickDisposable = { dispose: () => wrapper.removeEventListener('dblclick', handleDblClick) };
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Lắng nghe MUTATION cột (insert/remove/move) — mức mutation để bắt cả undo/redo, một lần/thao tác.
|
|
418
|
+
* Chuẩn hoá thành `T_columnStructureChange` rồi phát ra ngoài cho consumer remap mapping.
|
|
419
|
+
*/
|
|
420
|
+
registerColumnOpListener() {
|
|
421
|
+
// CONVENTION-EXCEPT: any — FUniver.onCommandExecuted / commandInfo không expose trong public types
|
|
422
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
423
|
+
const api = this.univerAPI;
|
|
424
|
+
if (typeof api?.onCommandExecuted !== 'function')
|
|
425
|
+
return;
|
|
426
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
427
|
+
this.columnOpDisposable = api.onCommandExecuted((commandInfo) => {
|
|
428
|
+
const change = this.toColumnStructureChange(commandInfo?.id, commandInfo?.params);
|
|
429
|
+
if (change)
|
|
430
|
+
this.ngZone.run(() => this.outColumnStructureChange.emit(change));
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
toColumnStructureChange(id, params) {
|
|
434
|
+
const p = params;
|
|
435
|
+
const sheetId = p?.subUnitId ?? '';
|
|
436
|
+
if (id === InsertColMutation.id || id === RemoveColMutation.id) {
|
|
437
|
+
if (!p?.range)
|
|
438
|
+
return null;
|
|
439
|
+
const type = id === InsertColMutation.id ? 'insert' : 'remove';
|
|
440
|
+
return { sheetId, type, startColumn: p.range.startColumn, count: p.range.endColumn - p.range.startColumn + 1 };
|
|
441
|
+
}
|
|
442
|
+
if (id === MoveColsMutation.id) {
|
|
443
|
+
if (!p?.sourceRange || !p?.targetRange)
|
|
444
|
+
return null;
|
|
445
|
+
return {
|
|
446
|
+
sheetId,
|
|
447
|
+
type: 'move',
|
|
448
|
+
startColumn: p.sourceRange.startColumn,
|
|
449
|
+
count: p.sourceRange.endColumn - p.sourceRange.startColumn + 1,
|
|
450
|
+
toColumn: p.targetRange.startColumn,
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
return null;
|
|
454
|
+
}
|
|
455
|
+
registerFormatListener() {
|
|
456
|
+
// CONVENTION-EXCEPT: any — FUniver.onCommandExecuted / commandInfo không expose trong public types
|
|
457
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
458
|
+
const api = this.univerAPI;
|
|
459
|
+
if (typeof api?.onCommandExecuted !== 'function')
|
|
460
|
+
return;
|
|
461
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
462
|
+
this.formatDisposable = api.onCommandExecuted((commandInfo) => {
|
|
463
|
+
this.ngZone.run(() => {
|
|
464
|
+
if (commandInfo?.id === 'sheet.operation.open.numfmt.panel') {
|
|
465
|
+
this.numfmtPanelOpen = true;
|
|
466
|
+
this.numfmtConfirmed = false; // reset cờ — phiên mới mặc định chưa Confirm
|
|
467
|
+
this.numfmtDateActive = false; // chưa chọn Type=Date → chưa kích hoạt luồng custom
|
|
468
|
+
// Lưu numfmt gốc từng ô để Cancel khôi phục đúng (vùng chọn có thể nhiều format khác nhau)
|
|
469
|
+
this.originalCellFormats = this.captureRangeNumfmt(this.lastRangeSnapshot);
|
|
470
|
+
// Chỉ bật observer khi panel mở (tránh chạy liên tục theo mọi mutation toàn trang)
|
|
471
|
+
this.numfmtObserver?.observe(document.body, { childList: true, subtree: true });
|
|
472
|
+
// Reopen: Univer hiện lại panel cũ bằng CSS (không mutation) → observer không fire. Chủ động
|
|
473
|
+
// thử inject sau 1 nhịp để bắt trường hợp list ngày đã sẵn trong DOM tái dùng.
|
|
474
|
+
setTimeout(() => {
|
|
475
|
+
if (this.numfmtPanelOpen)
|
|
476
|
+
this.processNumfmtPanel();
|
|
477
|
+
}, 60);
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
if (commandInfo?.id === 'sheet.operation.close.numfmt.panel') {
|
|
481
|
+
this.numfmtPanelOpen = false;
|
|
482
|
+
// Tắt observer khi đóng (perf). KHÔNG gỡ listener: Univer tái dùng DOM panel, gỡ sẽ làm
|
|
483
|
+
// option chết khi mở lại. cleanup chạy trước lần inject mới (DOM mới) hoặc khi destroy.
|
|
484
|
+
this.numfmtObserver?.disconnect();
|
|
485
|
+
// Univer TÁI DÙNG DOM panel khi reopen (nhớ cả Type=Date) → guard data-custom-dates còn sót sẽ
|
|
486
|
+
// chặn re-inject ở lần mở sau, khiến highlight stale + dateActive=false (mất revert). Xoá guard
|
|
487
|
+
// để lần mở kế tiếp inject lại + resync highlight/auto-apply theo cột hiện tại.
|
|
488
|
+
document.querySelector('.numfmt-panel ul.univer-select-list')?.removeAttribute('data-custom-dates');
|
|
489
|
+
// Chỉ khi bấm CONFIRM (numfmtConfirmed=true) mới GIỮ pattern đã chọn cho cả vùng.
|
|
490
|
+
// Cancel / X / click-ngoài đều KHÔNG set cờ → KHÔI PHỤC numfmt GỐC TỪNG Ô (đã chụp khi mở panel).
|
|
491
|
+
const dateActive = this.numfmtDateActive;
|
|
492
|
+
const confirmed = this.numfmtConfirmed;
|
|
493
|
+
const pending = this.pendingNumfmtPattern;
|
|
494
|
+
const originalCells = this.originalCellFormats;
|
|
495
|
+
this.numfmtConfirmed = false;
|
|
496
|
+
this.pendingNumfmtPattern = null;
|
|
497
|
+
this.originalCellFormats = null;
|
|
498
|
+
this.numfmtDateActive = false;
|
|
499
|
+
// Type khác Date (Số/Tiền tệ/%/Text…) do Univer tự apply/cancel → KHÔNG can thiệp,
|
|
500
|
+
// nếu không sẽ revert nhầm format mà user vừa áp qua luồng native của Univer.
|
|
501
|
+
if (!dateActive) {
|
|
502
|
+
this.clearNumfmtPreview();
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
const snap = this.lastRangeSnapshot;
|
|
506
|
+
if (!snap)
|
|
507
|
+
return;
|
|
508
|
+
let values;
|
|
509
|
+
if (confirmed && pending) {
|
|
510
|
+
values = [];
|
|
511
|
+
for (let r = snap.startRow; r <= Math.min(snap.endRow, snap.startRow + 499); r++) {
|
|
512
|
+
for (let c = snap.startColumn; c <= snap.endColumn; c++) {
|
|
513
|
+
values.push({ pattern: pending, row: r, col: c });
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
else if (!confirmed && originalCells) {
|
|
518
|
+
values = originalCells;
|
|
519
|
+
}
|
|
520
|
+
else {
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
if (!values.length)
|
|
524
|
+
return;
|
|
525
|
+
// CONVENTION-EXCEPT: any — FUniver.executeCommand không expose typing
|
|
526
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
527
|
+
void this.univerAPI?.executeCommand?.('sheet.command.numfmt.set.numfmt', {
|
|
528
|
+
unitId: snap.unitId,
|
|
529
|
+
subUnitId: snap.subUnitId,
|
|
530
|
+
values,
|
|
531
|
+
});
|
|
532
|
+
this.clearNumfmtPreview();
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
// Khi panel đang mở: CHỈ user đổi vùng chọn trên grid (set-selections) mới được cập nhật snapshot
|
|
536
|
+
// để re-target panel sang cột/cell mới. Command nội bộ panel (numfmt.set, mutation…) KHÔNG đụng snapshot.
|
|
537
|
+
const isUserSelection = commandInfo?.id === 'sheet.operation.set-selections';
|
|
538
|
+
if (this.numfmtPanelOpen && !isUserSelection)
|
|
539
|
+
return;
|
|
540
|
+
const wb = this.univerAPI?.getActiveWorkbook();
|
|
541
|
+
const ws = wb?.getActiveSheet();
|
|
542
|
+
const range = ws?.getActiveRange();
|
|
543
|
+
if (!range || !wb || !ws)
|
|
544
|
+
return;
|
|
545
|
+
const rangeData = range.getRange();
|
|
546
|
+
this.activeCellRef.set(`${this.toColLetter(rangeData.startColumn)}${rangeData.startRow + 1}`);
|
|
547
|
+
// CONVENTION-EXCEPT: any — FWorkbook.getId / FWorksheet.getSheetId chưa expose trong types
|
|
548
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
549
|
+
const wbAny = wb;
|
|
550
|
+
const wsAny = ws;
|
|
551
|
+
/* eslint-enable @typescript-eslint/no-explicit-any */
|
|
552
|
+
this.lastRangeSnapshot = {
|
|
553
|
+
unitId: (wbAny.getId?.() ?? wbAny.getUnitId?.() ?? ''),
|
|
554
|
+
subUnitId: (wsAny.getSheetId?.() ?? wsAny.getUnitId?.() ?? ''),
|
|
555
|
+
startRow: rangeData.startRow,
|
|
556
|
+
endRow: rangeData.endRow,
|
|
557
|
+
startColumn: rangeData.startColumn,
|
|
558
|
+
endColumn: rangeData.endColumn,
|
|
559
|
+
};
|
|
560
|
+
// CONVENTION-EXCEPT: any — FRange.getCellStyleData chưa expose trong types
|
|
561
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
562
|
+
const rangeAny = range;
|
|
563
|
+
const style = rangeAny.getCellStyleData?.();
|
|
564
|
+
const numFmt = style?.n?.pattern ?? style?.nf?.pattern;
|
|
565
|
+
this.activeCellFormat.set(numFmt && numFmt !== '0' ? numFmt : 'General');
|
|
566
|
+
// User đổi vùng chọn LÚC panel Date đang mở → tích luỹ numfmt gốc của vùng mới (để Cancel
|
|
567
|
+
// revert đúng mọi ô đã chạm) rồi đồng bộ lại panel (label + highlight + auto-apply) theo cột mới.
|
|
568
|
+
if (this.numfmtPanelOpen && this.numfmtDateActive) {
|
|
569
|
+
this.mergeOriginalCellFormats(this.captureRangeNumfmt(this.lastRangeSnapshot));
|
|
570
|
+
this.numfmtResync?.();
|
|
571
|
+
}
|
|
572
|
+
});
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
/** Gộp numfmt gốc của vùng vừa chọn vào snapshot revert, giữ giá trị GỐC ĐẦU TIÊN cho mỗi ô. */
|
|
576
|
+
mergeOriginalCellFormats(extra) {
|
|
577
|
+
if (!extra)
|
|
578
|
+
return;
|
|
579
|
+
if (!this.originalCellFormats) {
|
|
580
|
+
this.originalCellFormats = extra;
|
|
581
|
+
return;
|
|
582
|
+
}
|
|
583
|
+
const seen = new Set(this.originalCellFormats.map((v) => `${v.row}:${v.col}`));
|
|
584
|
+
for (const cell of extra) {
|
|
585
|
+
if (seen.has(`${cell.row}:${cell.col}`))
|
|
586
|
+
continue;
|
|
587
|
+
this.originalCellFormats.push(cell);
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
591
|
+
* Xoá live-preview overlay của Univer numfmt panel.
|
|
592
|
+
*
|
|
593
|
+
* Khi panel numfmt mở, `NumfmtController._previewPattern` được Univer dùng để vẽ đè
|
|
594
|
+
* (preview) lên hiển thị thật của vùng chọn. Vì các option date custom ghi numfmt
|
|
595
|
+
* trực tiếp vào model (không đi qua panel gốc của Univer), preview này không bao giờ
|
|
596
|
+
* khớp model → cột không đổi hiển thị ngay. Set `_previewPattern = null` + force re-render
|
|
597
|
+
* (`_forceUpdate`) để canvas vẽ đúng giá trị model tức thì.
|
|
598
|
+
*
|
|
599
|
+
* NumfmtController không export khỏi `@univerjs/sheets-numfmt` nên phải tìm instance
|
|
600
|
+
* qua injector của Univer (cache lại sau lần đầu).
|
|
601
|
+
*/
|
|
602
|
+
clearNumfmtPreview() {
|
|
603
|
+
const controller = this.resolveNumfmtController();
|
|
604
|
+
if (!controller)
|
|
605
|
+
return;
|
|
606
|
+
if (controller._previewPattern != null)
|
|
607
|
+
controller._previewPattern = null;
|
|
608
|
+
// LUÔN force re-render: numfmt vừa áp vào model cần vẽ lại canvas ngay (kể cả khi không có preview).
|
|
609
|
+
controller._forceUpdate?.();
|
|
610
|
+
}
|
|
611
|
+
// CONVENTION-EXCEPT: any — truy cập injector + NumfmtController nội bộ của Univer (không có public API)
|
|
612
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
613
|
+
resolveNumfmtController() {
|
|
614
|
+
if (this.numfmtController)
|
|
615
|
+
return this.numfmtController;
|
|
616
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
617
|
+
const injector = this.univer?.__getInjector?.();
|
|
618
|
+
if (!injector)
|
|
619
|
+
return null;
|
|
620
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
621
|
+
const scanMap = (map) => {
|
|
622
|
+
if (!(map instanceof Map))
|
|
623
|
+
return null;
|
|
624
|
+
for (const value of map.values()) {
|
|
625
|
+
const candidates = Array.isArray(value) ? value : [value];
|
|
626
|
+
for (const candidate of candidates) {
|
|
627
|
+
const instance = candidate?.instance !== undefined ? candidate.instance : candidate;
|
|
628
|
+
if (instance && typeof instance === 'object' && '_previewPattern' in instance)
|
|
629
|
+
return instance;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
return null;
|
|
633
|
+
};
|
|
634
|
+
// Các instance của redi nằm trong Map lồng 1 cấp (vd injector.resolvedDependencyCollection.resolvedDependencies)
|
|
635
|
+
for (const key of Object.keys(injector)) {
|
|
636
|
+
const value = injector[key];
|
|
637
|
+
let found = scanMap(value);
|
|
638
|
+
if (!found && value && typeof value === 'object') {
|
|
639
|
+
for (const nestedKey of Object.keys(value)) {
|
|
640
|
+
found = scanMap(value[nestedKey]);
|
|
641
|
+
if (found)
|
|
642
|
+
break;
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
if (found) {
|
|
646
|
+
this.numfmtController = found;
|
|
647
|
+
return found;
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
return null;
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* Tạo observer để inject option ngày custom + highlight khi panel numfmt render.
|
|
654
|
+
* Observer CHỈ được bật/tắt theo vòng đời panel (xem open/close.numfmt.panel handler) để
|
|
655
|
+
* không chạy liên tục theo mọi mutation DOM toàn trang.
|
|
656
|
+
*/
|
|
657
|
+
registerNumfmtDropdownObserver() {
|
|
658
|
+
this.numfmtObserver = new MutationObserver(() => this.processNumfmtPanel());
|
|
659
|
+
}
|
|
660
|
+
/**
|
|
661
|
+
* Thử inject option ngày custom + highlight cho panel numfmt hiện tại.
|
|
662
|
+
* Gọi từ 2 nguồn: (1) MutationObserver khi Univer render list ngày; (2) trực tiếp lúc mở panel —
|
|
663
|
+
* vì Univer TÁI DÙNG DOM panel khi reopen (hiện lại bằng CSS, không phát sinh mutation) nên observer
|
|
664
|
+
* không kích hoạt, phải chủ động gọi để re-inject + resync theo cột hiện tại.
|
|
665
|
+
*/
|
|
666
|
+
processNumfmtPanel() {
|
|
667
|
+
syncActiveNumfmtHighlight();
|
|
668
|
+
const result = injectCustomDateFormats(() => this.lastRangeSnapshot,
|
|
669
|
+
// CONVENTION-EXCEPT: any — FUniver.executeCommand không expose typing
|
|
670
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
671
|
+
(cmdId, params) => void this.univerAPI.executeCommand?.(cmdId, params), (pattern) => {
|
|
672
|
+
this.pendingNumfmtPattern = pattern;
|
|
673
|
+
}, () => {
|
|
674
|
+
const snap = this.lastRangeSnapshot;
|
|
675
|
+
if (!snap)
|
|
676
|
+
return this.activeCellFormat();
|
|
677
|
+
// Quét vài dòng đầu của vùng chọn, bỏ qua header/General để lấy format ĐẠI DIỆN của dữ liệu.
|
|
678
|
+
// Khi chọn cả cột, startRow = 0 là header (thường General) → nếu chỉ đọc dòng đó sẽ highlight sai option.
|
|
679
|
+
const maxScan = Math.min(snap.endRow, snap.startRow + 4);
|
|
680
|
+
for (let r = snap.startRow; r <= maxScan; r++) {
|
|
681
|
+
const fmt = this.readCellNumfmt(snap.subUnitId, r, snap.startColumn);
|
|
682
|
+
if (fmt !== 'General')
|
|
683
|
+
return fmt;
|
|
684
|
+
}
|
|
685
|
+
return this.activeCellFormat();
|
|
686
|
+
}, () => this.clearNumfmtPreview(), () => {
|
|
687
|
+
// Giá trị thực của ô đại diện (dòng dữ liệu đầu có số) → label option khớp dữ liệu cột.
|
|
688
|
+
const snap = this.lastRangeSnapshot;
|
|
689
|
+
if (!snap)
|
|
690
|
+
return null;
|
|
691
|
+
const maxScan = Math.min(snap.endRow, snap.startRow + 4);
|
|
692
|
+
for (let r = snap.startRow; r <= maxScan; r++) {
|
|
693
|
+
const value = this.readCellValue(snap.subUnitId, r, snap.startColumn);
|
|
694
|
+
if (value !== null)
|
|
695
|
+
return value;
|
|
696
|
+
}
|
|
697
|
+
return null;
|
|
698
|
+
}, () => {
|
|
699
|
+
this.numfmtConfirmed = true;
|
|
700
|
+
});
|
|
701
|
+
// result chỉ truthy khi THỰC SỰ inject trên 1 listContainer Date mới (guard data-custom-dates chặn
|
|
702
|
+
// các lần gọi thừa). Gỡ listener của lần inject trước trước khi giữ cleanup mới → tránh tích tụ.
|
|
703
|
+
// Đồng thời lưu resync để re-target panel khi user đổi cột, và đánh dấu luồng Date đang hoạt động.
|
|
704
|
+
if (result) {
|
|
705
|
+
this.numfmtCleanup?.();
|
|
706
|
+
this.numfmtCleanup = result.cleanup;
|
|
707
|
+
this.numfmtResync = result.resync;
|
|
708
|
+
this.numfmtDateActive = true;
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
initUniver(data) {
|
|
712
|
+
const wrapper = this.containerRef()?.nativeElement;
|
|
713
|
+
if (!wrapper)
|
|
714
|
+
return;
|
|
715
|
+
wrapper.replaceChildren();
|
|
716
|
+
const container = document.createElement('div');
|
|
717
|
+
container.style.cssText = 'width:100%;height:100%';
|
|
718
|
+
wrapper.appendChild(container);
|
|
719
|
+
const univer = new Univer({
|
|
720
|
+
locale: this.resolveLocaleType(),
|
|
721
|
+
locales: {
|
|
722
|
+
[LocaleType.EN_US]: univerLocaleEn,
|
|
723
|
+
[LocaleType.VI_VN]: univerLocaleVi,
|
|
724
|
+
},
|
|
725
|
+
theme: defaultTheme,
|
|
726
|
+
});
|
|
727
|
+
this.univer = univer;
|
|
728
|
+
univer.registerPlugin(UniverRenderEnginePlugin);
|
|
729
|
+
univer.registerPlugin(UniverFormulaEnginePlugin);
|
|
730
|
+
univer.registerPlugin(UniverUIPlugin, { container, header: this.showToolbar(), footer: this.showSheetTabs() });
|
|
731
|
+
univer.registerPlugin(UniverDocsPlugin, { hasScroll: false });
|
|
732
|
+
univer.registerPlugin(UniverDocsUIPlugin);
|
|
733
|
+
univer.registerPlugin(UniverSheetsPlugin);
|
|
734
|
+
univer.registerPlugin(UniverSheetsUIPlugin, { menu: this.toolbarMenuConfig() });
|
|
735
|
+
univer.registerPlugin(UniverSheetsNumfmtPlugin);
|
|
736
|
+
univer.registerPlugin(UniverSheetsFormulaPlugin);
|
|
737
|
+
univer.registerPlugin(UniverSheetsFormulaUIPlugin);
|
|
738
|
+
univer.createUnit(UniverInstanceType.UNIVER_SHEET, data);
|
|
739
|
+
this.univerAPI = FUniver.newAPI(univer);
|
|
740
|
+
if (this.pendingReadyCb) {
|
|
741
|
+
// Wait for .more-numfmt-type to appear in DOM — this signals that UniverSheetsUIPlugin
|
|
742
|
+
// has fully rendered the toolbar and UniverSheetsNumfmtPlugin's INumfmtModel is ready.
|
|
743
|
+
const wrapper = this.containerRef()?.nativeElement;
|
|
744
|
+
if (wrapper) {
|
|
745
|
+
this.readyObserver = new MutationObserver(() => {
|
|
746
|
+
if (!wrapper.querySelector('.more-numfmt-type'))
|
|
747
|
+
return;
|
|
748
|
+
this.readyObserver?.disconnect();
|
|
749
|
+
this.readyObserver = null;
|
|
750
|
+
const cb = this.pendingReadyCb;
|
|
751
|
+
this.pendingReadyCb = null;
|
|
752
|
+
cb?.();
|
|
753
|
+
});
|
|
754
|
+
this.readyObserver.observe(wrapper, { childList: true, subtree: true });
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
this.registerColumnClickListener();
|
|
758
|
+
this.registerColumnOpListener();
|
|
759
|
+
this.registerFormatListener();
|
|
760
|
+
this.registerNumfmtDropdownObserver();
|
|
761
|
+
this.registerToolbarWidthSync();
|
|
762
|
+
this.registerNumfmtClickInterceptor();
|
|
763
|
+
}
|
|
764
|
+
/**
|
|
765
|
+
* Khắc phục lỗi toolbar collapse sai (gom item vào menu ⋮ dù còn khoảng trắng).
|
|
766
|
+
*
|
|
767
|
+
* Univer (component Ribbon) quyết định overflow bằng 1 container ĐO off-screen (con trực tiếp của
|
|
768
|
+
* header, position:absolute). Thuật toán: `total = 90; cho mỗi ITEM total += item.clientWidth + 8;
|
|
769
|
+
* nếu total > measuringContainer.clientWidth → collapse item`. Công thức này OVER-COUNT 2 chỗ:
|
|
770
|
+
* • +90px reserve cho nút ⋮ (cộng kể cả khi không cần collapse).
|
|
771
|
+
* • +8px MỖI item, trong khi khoảng cách (gap) thực tế chỉ nằm giữa các GROUP.
|
|
772
|
+
* Nếu set bề rộng container đo = đúng headerW thì `total` (vd 961) > headerW (vd 900) → Univer tưởng
|
|
773
|
+
* tràn và gom item vào ⋮ dù content thật chỉ ~829px (còn ~70px trống).
|
|
774
|
+
*
|
|
775
|
+
* Fix (triệt để, không phụ thuộc timing): pin bề rộng container ĐO = HẰNG SỐ rất lớn qua CSS RULE trong
|
|
776
|
+
* 1 <style> riêng. Khi đó `total` của Univer KHÔNG BAO GIỜ vượt → KHÔNG gom item vào ⋮ → luôn hiển thị
|
|
777
|
+
* ĐỦ option (đúng yêu cầu). Vì sao chọn cách này thay vì khớp width = headerW:
|
|
778
|
+
* • Thuật toán Univer over-count (90 reserve ⋮ + 8px/item) → khớp sát headerW vẫn collapse sai khi còn chỗ.
|
|
779
|
+
* • ResizeObserver của Univer hay KẸT STALE: 1 transient lúc load (icon/font làm item rộng nhất thời) đặt
|
|
780
|
+
* collapsedIds rồi KHÔNG re-fire → kẹt ⋮ vĩnh viễn dù sau đó còn chỗ (đúng triệu chứng reload luôn ⋮).
|
|
781
|
+
* • Set inline lại bị React re-render strip → oscillation. CSS rule !important React không strip được.
|
|
782
|
+
* Container đo vốn off-screen (position:absolute, opacity:0) nên width khổng lồ hoàn toàn vô hình. Khi
|
|
783
|
+
* vùng chứa quá hẹp (hiếm với spreadsheet) toolbar cuộn ngang — xem SCSS `.univer-toolbar` overflow-x.
|
|
784
|
+
*/
|
|
785
|
+
registerToolbarWidthSync() {
|
|
786
|
+
const wrapper = this.containerRef()?.nativeElement;
|
|
787
|
+
if (!wrapper)
|
|
788
|
+
return;
|
|
789
|
+
wrapper.classList.add(this.toolbarScopeClass);
|
|
790
|
+
const styleEl = document.createElement('style');
|
|
791
|
+
this.toolbarStyleEl = styleEl;
|
|
792
|
+
styleEl.textContent = `.${this.toolbarScopeClass} .univer-workbench-container-header > .univer-toolbar-container{width:100000px !important;max-width:none !important;}`;
|
|
793
|
+
document.head.appendChild(styleEl);
|
|
794
|
+
}
|
|
795
|
+
registerNumfmtClickInterceptor() {
|
|
796
|
+
const clickHandler = (e) => {
|
|
797
|
+
const target = e.target;
|
|
798
|
+
if (target.closest('.numfmt-panel') ?? target.closest('.more-numfmt-type-options'))
|
|
799
|
+
return;
|
|
800
|
+
const numfmtText = target.closest('.more-numfmt-type');
|
|
801
|
+
const numfmtSelect = target.closest('.univer-toolbar-item-select');
|
|
802
|
+
const isNumfmtBtn = numfmtText ?? (numfmtSelect?.querySelector('.more-numfmt-type') ? numfmtSelect : null);
|
|
803
|
+
if (!isNumfmtBtn)
|
|
804
|
+
return;
|
|
805
|
+
e.preventDefault();
|
|
806
|
+
e.stopPropagation();
|
|
807
|
+
this.executeCommand('sheet.operation.open.numfmt.panel', undefined);
|
|
808
|
+
};
|
|
809
|
+
document.body.addEventListener('click', clickHandler, true);
|
|
810
|
+
this.numfmtClickDisposable = { dispose: () => document.body.removeEventListener('click', clickHandler, true) };
|
|
811
|
+
}
|
|
812
|
+
destroyUniver() {
|
|
813
|
+
if (this.pendingInitTimer !== null) {
|
|
814
|
+
clearTimeout(this.pendingInitTimer);
|
|
815
|
+
this.pendingInitTimer = null;
|
|
816
|
+
}
|
|
817
|
+
this.columnClickDisposable?.dispose();
|
|
818
|
+
this.columnClickDisposable = null;
|
|
819
|
+
this.columnOpDisposable?.dispose();
|
|
820
|
+
this.columnOpDisposable = null;
|
|
821
|
+
this.formatDisposable?.dispose();
|
|
822
|
+
this.formatDisposable = null;
|
|
823
|
+
this.numfmtObserver?.disconnect();
|
|
824
|
+
this.numfmtObserver = null;
|
|
825
|
+
this.toolbarResizeObserver?.disconnect();
|
|
826
|
+
this.toolbarResizeObserver = null;
|
|
827
|
+
this.toolbarStyleEl?.remove();
|
|
828
|
+
this.toolbarStyleEl = null;
|
|
829
|
+
this.numfmtClickDisposable?.dispose();
|
|
830
|
+
this.numfmtClickDisposable = null;
|
|
831
|
+
this.numfmtCleanup?.();
|
|
832
|
+
this.numfmtCleanup = null;
|
|
833
|
+
this.numfmtResync = null;
|
|
834
|
+
this.numfmtDateActive = false;
|
|
835
|
+
this.readyObserver?.disconnect();
|
|
836
|
+
this.readyObserver = null;
|
|
837
|
+
this.activeCellFormat.set('General');
|
|
838
|
+
this.activeCellRef.set('');
|
|
839
|
+
this.lastRangeSnapshot = null;
|
|
840
|
+
this.pendingNumfmtPattern = null;
|
|
841
|
+
this.numfmtConfirmed = false;
|
|
842
|
+
this.originalCellFormats = null;
|
|
843
|
+
this.numfmtPanelOpen = false;
|
|
844
|
+
this.listenEnabled = false;
|
|
845
|
+
if (this.listenEnableTimer !== null) {
|
|
846
|
+
clearTimeout(this.listenEnableTimer);
|
|
847
|
+
this.listenEnableTimer = null;
|
|
848
|
+
}
|
|
849
|
+
this.numfmtController = null;
|
|
850
|
+
this.univer?.dispose();
|
|
851
|
+
this.univer = null;
|
|
852
|
+
this.univerAPI = null;
|
|
853
|
+
}
|
|
854
|
+
reinitUniver() {
|
|
855
|
+
const currentData = this.univerAPI?.getActiveWorkbook()?.save();
|
|
856
|
+
this.destroyUniver();
|
|
857
|
+
setTimeout(() => this.initUniver(currentData ?? this.buildEmptyWorkbook()));
|
|
858
|
+
}
|
|
859
|
+
ngOnDestroy() {
|
|
860
|
+
this.destroyUniver();
|
|
861
|
+
}
|
|
862
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiComponentsSpreadsheetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
863
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "18.2.14", type: LibsUiComponentsSpreadsheetComponent, isStandalone: true, selector: "libs_ui-components-spreadsheet", inputs: { locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, toolbarMenuConfig: { classPropertyName: "toolbarMenuConfig", publicName: "toolbarMenuConfig", isSignal: true, isRequired: false, transformFunction: null }, mappingIndicatorConfig: { classPropertyName: "mappingIndicatorConfig", publicName: "mappingIndicatorConfig", isSignal: true, isRequired: false, transformFunction: null }, mappingTargets: { classPropertyName: "mappingTargets", publicName: "mappingTargets", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { outColumnDblClick: "outColumnDblClick", outColumnStructureChange: "outColumnStructureChange" }, viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["containerRef"], descendants: true, isSignal: true }], ngImport: i0, template: "<div #containerRef class=\"libs-ui-components-spreadsheet-container\"></div>\n", styles: ["@charset \"UTF-8\";:host{display:block;width:100%;height:100%}.libs-ui-components-spreadsheet-container{width:100%;height:100%}::ng-deep .univer-toolbar-container{flex-grow:1!important;margin:0!important}::ng-deep .univer-toolbar{overflow-x:auto}::ng-deep .univer-toolbar>.univer-toolbar-container{justify-content:flex-start!important;flex-shrink:0!important}::ng-deep .univer-toolbar-more-container{display:flex!important;flex-wrap:wrap!important;gap:8px!important;width:max-content!important;max-width:320px!important;padding:8px!important}::ng-deep .univer-toolbar-more-container .univer-toolbar-group{flex-shrink:0!important}::ng-deep .univer-select-dropdown .univer-select-item[title=\"Custom Format\"]{display:none!important}::ng-deep .numfmt-panel{padding:0 4px}::ng-deep .univer-custom-format-title{margin-top:12px!important;font-size:11px!important;font-weight:700!important;color:#8c8c8c!important;text-transform:uppercase!important;letter-spacing:.5px!important}::ng-deep .univer-custom-format-input{margin-top:6px!important}::ng-deep .univer-custom-format-input input,::ng-deep .univer-custom-format-input textarea{font-family:SFMono-Regular,Consolas,monospace!important;font-size:12px!important;border-radius:6px!important}::ng-deep .univer-custom-format-history-list{margin-top:6px!important;padding:4px!important;border:1.5px solid #f0f0f0!important;border-radius:8px!important;max-height:260px!important;overflow-y:auto!important;background:#fafafa!important;scrollbar-width:thin;scrollbar-color:#d9d9d9 transparent}::ng-deep .univer-custom-format-history-list::-webkit-scrollbar{width:4px}::ng-deep .univer-custom-format-history-list::-webkit-scrollbar-thumb{background:#d9d9d9;border-radius:4px}::ng-deep .univer-custom-format-history-list-item{padding:5px 8px!important;border-radius:6px!important;gap:8px!important;transition:all .12s;border-bottom:1px solid transparent!important}::ng-deep .univer-custom-format-history-list-item:hover{background:#e6f4ff!important}::ng-deep .univer-custom-format-history-list-item:hover>span:last-child,::ng-deep .univer-custom-format-history-list-item:hover>div:last-child{color:#1677ff!important}::ng-deep .univer-custom-format-history-list-item>span:not(.univer-custom-format-history-list-item-icon-wrap),::ng-deep .univer-custom-format-history-list-item>div:not(.univer-custom-format-history-list-item-icon-wrap){font-family:SFMono-Regular,Consolas,monospace!important;font-size:11px!important;color:#434343!important;overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important;max-width:240px!important}::ng-deep .univer-custom-format-history-list-item-icon-wrap{flex-shrink:0!important;opacity:.6}::ng-deep .univer-custom-format-des{margin-top:6px!important;font-size:11px!important;line-height:1.5!important;color:#8c8c8c!important;padding:6px 8px!important;background:#f5f5f5!important;border-radius:6px!important;border-left:3px solid #d9d9d9!important}::ng-deep .univer-numfmt-custom-item{position:relative!important;padding:5px 8px!important;border-radius:6px!important;font-family:SFMono-Regular,Consolas,monospace!important;font-size:12px!important;color:#434343!important;cursor:pointer!important;transition:background .12s,color .12s;display:block!important;border-left:3px solid transparent}::ng-deep .univer-numfmt-custom-item:hover{background:#f0f5ff!important;color:#1677ff!important;border-left-color:#1677ff!important}::ng-deep .univer-numfmt-custom-item.univer-numfmt-active{background:#e6f4ff!important;color:#1677ff!important;font-weight:600!important;padding-left:24px!important;border-left:3px solid #1677ff!important}::ng-deep .univer-numfmt-custom-item.univer-numfmt-active:before{content:\"\\2713\";position:absolute;left:7px;top:50%;transform:translateY(-50%);font-size:10px;font-weight:700;color:#1677ff;line-height:1}::ng-deep .numfmt-panel li.univer-select-list-item.univer-select-list-item-select:not(.univer-numfmt-custom-item){background:#e6f4ff!important;border-left:3px solid #1677ff!important;border-radius:6px!important}::ng-deep .numfmt-panel li.univer-select-list-item.univer-select-list-item-select:not(.univer-numfmt-custom-item) a{color:#1677ff!important}::ng-deep .numfmt-panel li.univer-select-list-item.univer-select-list-item-select:not(.univer-numfmt-custom-item) .univer-select-list-item-icon{color:#1677ff!important}::ng-deep .more-numfmt-type{cursor:pointer;font-size:0!important;display:inline-flex;align-items:center;line-height:1}::ng-deep .more-numfmt-type:before{content:\"\";display:inline-block;width:31px;height:18px;background-color:currentColor;mask:url(\"data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2034%2020'%3E%3Ctext%20x='0'%20y='15'%20font-size='13'%20font-weight='700'%20fill='black'%20font-family='Arial,sans-serif'%3E123%3C/text%3E%3Ctext%20x='20'%20y='8'%20font-size='7'%20font-weight='700'%20fill='black'%20font-family='Arial,sans-serif'%3E%25%3C/text%3E%3Ctext%20x='27'%20y='8'%20font-size='7'%20font-weight='700'%20fill='black'%20font-family='Arial,sans-serif'%3E$%3C/text%3E%3Ccircle%20cx='26.5'%20cy='15'%20r='3.4'%20fill='none'%20stroke='black'%20stroke-width='1.1'/%3E%3Cpath%20d='M26.5%2013.2v1.8l1.2.9'%20fill='none'%20stroke='black'%20stroke-width='1.1'%20stroke-linecap='round'%20stroke-linejoin='round'/%3E%3C/svg%3E\") no-repeat center/contain;-webkit-mask:url(\"data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2034%2020'%3E%3Ctext%20x='0'%20y='15'%20font-size='13'%20font-weight='700'%20fill='black'%20font-family='Arial,sans-serif'%3E123%3C/text%3E%3Ctext%20x='20'%20y='8'%20font-size='7'%20font-weight='700'%20fill='black'%20font-family='Arial,sans-serif'%3E%25%3C/text%3E%3Ctext%20x='27'%20y='8'%20font-size='7'%20font-weight='700'%20fill='black'%20font-family='Arial,sans-serif'%3E$%3C/text%3E%3Ccircle%20cx='26.5'%20cy='15'%20r='3.4'%20fill='none'%20stroke='black'%20stroke-width='1.1'/%3E%3Cpath%20d='M26.5%2013.2v1.8l1.2.9'%20fill='none'%20stroke='black'%20stroke-width='1.1'%20stroke-linecap='round'%20stroke-linejoin='round'/%3E%3C/svg%3E\") no-repeat center/contain}::ng-deep .univer-toolbar-item-select:has(.more-numfmt-type):hover{background-color:rgb(var(--grey-100));border-radius:var(--border-radius-base)}::ng-deep .univer-toolbar-item-select:has(.more-numfmt-type) .more-numfmt-type,::ng-deep .univer-toolbar-item-select:has(.more-numfmt-type) .univer-toolbar-item-select-arrow{background-color:transparent!important}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
864
|
+
}
|
|
865
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiComponentsSpreadsheetComponent, decorators: [{
|
|
866
|
+
type: Component,
|
|
867
|
+
args: [{ selector: 'libs_ui-components-spreadsheet', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div #containerRef class=\"libs-ui-components-spreadsheet-container\"></div>\n", styles: ["@charset \"UTF-8\";:host{display:block;width:100%;height:100%}.libs-ui-components-spreadsheet-container{width:100%;height:100%}::ng-deep .univer-toolbar-container{flex-grow:1!important;margin:0!important}::ng-deep .univer-toolbar{overflow-x:auto}::ng-deep .univer-toolbar>.univer-toolbar-container{justify-content:flex-start!important;flex-shrink:0!important}::ng-deep .univer-toolbar-more-container{display:flex!important;flex-wrap:wrap!important;gap:8px!important;width:max-content!important;max-width:320px!important;padding:8px!important}::ng-deep .univer-toolbar-more-container .univer-toolbar-group{flex-shrink:0!important}::ng-deep .univer-select-dropdown .univer-select-item[title=\"Custom Format\"]{display:none!important}::ng-deep .numfmt-panel{padding:0 4px}::ng-deep .univer-custom-format-title{margin-top:12px!important;font-size:11px!important;font-weight:700!important;color:#8c8c8c!important;text-transform:uppercase!important;letter-spacing:.5px!important}::ng-deep .univer-custom-format-input{margin-top:6px!important}::ng-deep .univer-custom-format-input input,::ng-deep .univer-custom-format-input textarea{font-family:SFMono-Regular,Consolas,monospace!important;font-size:12px!important;border-radius:6px!important}::ng-deep .univer-custom-format-history-list{margin-top:6px!important;padding:4px!important;border:1.5px solid #f0f0f0!important;border-radius:8px!important;max-height:260px!important;overflow-y:auto!important;background:#fafafa!important;scrollbar-width:thin;scrollbar-color:#d9d9d9 transparent}::ng-deep .univer-custom-format-history-list::-webkit-scrollbar{width:4px}::ng-deep .univer-custom-format-history-list::-webkit-scrollbar-thumb{background:#d9d9d9;border-radius:4px}::ng-deep .univer-custom-format-history-list-item{padding:5px 8px!important;border-radius:6px!important;gap:8px!important;transition:all .12s;border-bottom:1px solid transparent!important}::ng-deep .univer-custom-format-history-list-item:hover{background:#e6f4ff!important}::ng-deep .univer-custom-format-history-list-item:hover>span:last-child,::ng-deep .univer-custom-format-history-list-item:hover>div:last-child{color:#1677ff!important}::ng-deep .univer-custom-format-history-list-item>span:not(.univer-custom-format-history-list-item-icon-wrap),::ng-deep .univer-custom-format-history-list-item>div:not(.univer-custom-format-history-list-item-icon-wrap){font-family:SFMono-Regular,Consolas,monospace!important;font-size:11px!important;color:#434343!important;overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important;max-width:240px!important}::ng-deep .univer-custom-format-history-list-item-icon-wrap{flex-shrink:0!important;opacity:.6}::ng-deep .univer-custom-format-des{margin-top:6px!important;font-size:11px!important;line-height:1.5!important;color:#8c8c8c!important;padding:6px 8px!important;background:#f5f5f5!important;border-radius:6px!important;border-left:3px solid #d9d9d9!important}::ng-deep .univer-numfmt-custom-item{position:relative!important;padding:5px 8px!important;border-radius:6px!important;font-family:SFMono-Regular,Consolas,monospace!important;font-size:12px!important;color:#434343!important;cursor:pointer!important;transition:background .12s,color .12s;display:block!important;border-left:3px solid transparent}::ng-deep .univer-numfmt-custom-item:hover{background:#f0f5ff!important;color:#1677ff!important;border-left-color:#1677ff!important}::ng-deep .univer-numfmt-custom-item.univer-numfmt-active{background:#e6f4ff!important;color:#1677ff!important;font-weight:600!important;padding-left:24px!important;border-left:3px solid #1677ff!important}::ng-deep .univer-numfmt-custom-item.univer-numfmt-active:before{content:\"\\2713\";position:absolute;left:7px;top:50%;transform:translateY(-50%);font-size:10px;font-weight:700;color:#1677ff;line-height:1}::ng-deep .numfmt-panel li.univer-select-list-item.univer-select-list-item-select:not(.univer-numfmt-custom-item){background:#e6f4ff!important;border-left:3px solid #1677ff!important;border-radius:6px!important}::ng-deep .numfmt-panel li.univer-select-list-item.univer-select-list-item-select:not(.univer-numfmt-custom-item) a{color:#1677ff!important}::ng-deep .numfmt-panel li.univer-select-list-item.univer-select-list-item-select:not(.univer-numfmt-custom-item) .univer-select-list-item-icon{color:#1677ff!important}::ng-deep .more-numfmt-type{cursor:pointer;font-size:0!important;display:inline-flex;align-items:center;line-height:1}::ng-deep .more-numfmt-type:before{content:\"\";display:inline-block;width:31px;height:18px;background-color:currentColor;mask:url(\"data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2034%2020'%3E%3Ctext%20x='0'%20y='15'%20font-size='13'%20font-weight='700'%20fill='black'%20font-family='Arial,sans-serif'%3E123%3C/text%3E%3Ctext%20x='20'%20y='8'%20font-size='7'%20font-weight='700'%20fill='black'%20font-family='Arial,sans-serif'%3E%25%3C/text%3E%3Ctext%20x='27'%20y='8'%20font-size='7'%20font-weight='700'%20fill='black'%20font-family='Arial,sans-serif'%3E$%3C/text%3E%3Ccircle%20cx='26.5'%20cy='15'%20r='3.4'%20fill='none'%20stroke='black'%20stroke-width='1.1'/%3E%3Cpath%20d='M26.5%2013.2v1.8l1.2.9'%20fill='none'%20stroke='black'%20stroke-width='1.1'%20stroke-linecap='round'%20stroke-linejoin='round'/%3E%3C/svg%3E\") no-repeat center/contain;-webkit-mask:url(\"data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2034%2020'%3E%3Ctext%20x='0'%20y='15'%20font-size='13'%20font-weight='700'%20fill='black'%20font-family='Arial,sans-serif'%3E123%3C/text%3E%3Ctext%20x='20'%20y='8'%20font-size='7'%20font-weight='700'%20fill='black'%20font-family='Arial,sans-serif'%3E%25%3C/text%3E%3Ctext%20x='27'%20y='8'%20font-size='7'%20font-weight='700'%20fill='black'%20font-family='Arial,sans-serif'%3E$%3C/text%3E%3Ccircle%20cx='26.5'%20cy='15'%20r='3.4'%20fill='none'%20stroke='black'%20stroke-width='1.1'/%3E%3Cpath%20d='M26.5%2013.2v1.8l1.2.9'%20fill='none'%20stroke='black'%20stroke-width='1.1'%20stroke-linecap='round'%20stroke-linejoin='round'/%3E%3C/svg%3E\") no-repeat center/contain}::ng-deep .univer-toolbar-item-select:has(.more-numfmt-type):hover{background-color:rgb(var(--grey-100));border-radius:var(--border-radius-base)}::ng-deep .univer-toolbar-item-select:has(.more-numfmt-type) .more-numfmt-type,::ng-deep .univer-toolbar-item-select:has(.more-numfmt-type) .univer-toolbar-item-select-arrow{background-color:transparent!important}\n"] }]
|
|
868
|
+
}], ctorParameters: () => [] });
|
|
869
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3ByZWFkc2hlZXQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGlicy11aS9jb21wb25lbnRzL3NwcmVhZHNoZWV0L3NyYy9zcHJlYWRzaGVldC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvc3ByZWFkc2hlZXQvc3JjL3NwcmVhZHNoZWV0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBaUIsdUJBQXVCLEVBQUUsU0FBUyxFQUFjLE1BQU0sRUFBYSxNQUFNLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDOUssT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUV4RSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDaEQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDbEQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDdkQsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDckUsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDbkUsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQzNDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxnQkFBZ0IsRUFBRSxpQkFBaUIsRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQzlHLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3JFLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQzFFLE9BQU8s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cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWZ0ZXJWaWV3SW5pdCwgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgRWxlbWVudFJlZiwgTmdab25lLCBPbkRlc3Ryb3ksIGVmZmVjdCwgaW5qZWN0LCBpbnB1dCwgb3V0cHV0LCBzaWduYWwsIHVudHJhY2tlZCwgdmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBMb2NhbGVUeXBlLCBVbml2ZXIsIFVuaXZlckluc3RhbmNlVHlwZSB9IGZyb20gJ0B1bml2ZXJqcy9jb3JlJztcbmltcG9ydCB0eXBlIHsgQ2VsbFZhbHVlLCBJQ2VsbERhdGEsIElTdHlsZURhdGEgfSBmcm9tICdAdW5pdmVyanMvY29yZSc7XG5pbXBvcnQgeyBkZWZhdWx0VGhlbWUgfSBmcm9tICdAdW5pdmVyanMvZGVzaWduJztcbmltcG9ydCB7IFVuaXZlckRvY3NQbHVnaW4gfSBmcm9tICdAdW5pdmVyanMvZG9jcyc7XG5pbXBvcnQgeyBVbml2ZXJEb2NzVUlQbHVnaW4gfSBmcm9tICdAdW5pdmVyanMvZG9jcy11aSc7XG5pbXBvcnQgeyBVbml2ZXJGb3JtdWxhRW5naW5lUGx1Z2luIH0gZnJvbSAnQHVuaXZlcmpzL2VuZ2luZS1mb3JtdWxhJztcbmltcG9ydCB7IFVuaXZlclJlbmRlckVuZ2luZVBsdWdpbiB9IGZyb20gJ0B1bml2ZXJqcy9lbmdpbmUtcmVuZGVyJztcbmltcG9ydCB7IEZVbml2ZXIgfSBmcm9tICdAdW5pdmVyanMvZmFjYWRlJztcbmltcG9ydCB7IEluc2VydENvbE11dGF0aW9uLCBNb3ZlQ29sc011dGF0aW9uLCBSZW1vdmVDb2xNdXRhdGlvbiwgVW5pdmVyU2hlZXRzUGx1Z2luIH0gZnJvbSAnQHVuaXZlcmpzL3NoZWV0cyc7XG5pbXBvcnQgeyBVbml2ZXJTaGVldHNGb3JtdWxhUGx1Z2luIH0gZnJvbSAnQHVuaXZlcmpzL3NoZWV0cy1mb3JtdWxhJztcbmltcG9ydCB7IFVuaXZlclNoZWV0c0Zvcm11bGFVSVBsdWdpbiB9IGZyb20gJ0B1bml2ZXJqcy9zaGVldHMtZm9ybXVsYS11aSc7XG5pbXBvcnQgeyBVbml2ZXJTaGVldHNOdW1mbXRQbHVnaW4gfSBmcm9tICdAdW5pdmVyanMvc2hlZXRzLW51bWZtdCc7XG5pbXBvcnQgeyBVbml2ZXJTaGVldHNVSVBsdWdpbiB9IGZyb20gJ0B1bml2ZXJqcy9zaGVldHMtdWknO1xuaW1wb3J0IHsgVW5pdmVyVUlQbHVnaW4gfSBmcm9tICdAdW5pdmVyanMvdWknO1xuaW1wb3J0IHsgdW5pdmVyTG9jYWxlRW4sIHVuaXZlckxvY2FsZVZpIH0gZnJvbSAnLi9zcHJlYWRzaGVldC5sb2NhbGUnO1xuaW1wb3J0IHsgaW5qZWN0Q3VzdG9tRGF0ZUZvcm1hdHMsIHN5bmNBY3RpdmVOdW1mbXRIaWdobGlnaHQgfSBmcm9tICcuL3NwcmVhZHNoZWV0Lm51bWZtdCc7XG5pbXBvcnQgeyBhcHBseU1hcHBpbmdJbmRpY2F0b3JzLCBzdHJpcE1hcHBpbmdJbmRpY2F0b3JzIH0gZnJvbSAnLi9zcHJlYWRzaGVldC5pbmRpY2F0b3InO1xuaW1wb3J0IHR5cGUgeyBUX2NvbHVtblN0cnVjdHVyZUNoYW5nZSwgVF9pbmRpY2F0b3JUYXJnZXQsIFRfbWFwcGluZ0luZGljYXRvckNvbmZpZyB9IGZyb20gJy4vc3ByZWFkc2hlZXQuaW5kaWNhdG9yJztcbmltcG9ydCB0eXBlIHsgVF9jZWxsRm9ybWF0UmVzdWx0LCBUX3JhbmdlU25hcHNob3QsIFRfc3ByZWFkc2hlZXRfbG9jYWxlLCBUX3Rvb2xiYXJfbWVudV9jb25maWcgfSBmcm9tICcuL3NwcmVhZHNoZWV0LnR5cGUnO1xuXG4vLyBC4buZIMSR4bq/bSB04bqhbyBjbGFzcyBzY29wZSBkdXkgbmjhuqV0IGNobyBt4buXaSBpbnN0YW5jZSBzcHJlYWRzaGVldCAoZMO5bmcgY2hvIDxzdHlsZT4gY2jhu4luaCB3aWR0aCB0b29sYmFyKS5cbmxldCBzcHJlYWRzaGVldEluc3RhbmNlQ291bnQgPSAwO1xuXG5AQ29tcG9uZW50KHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9jb21wb25lbnQtc2VsZWN0b3JcbiAgc2VsZWN0b3I6ICdsaWJzX3VpLWNvbXBvbmVudHMtc3ByZWFkc2hlZXQnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgdGVtcGxhdGVVcmw6ICcuL3NwcmVhZHNoZWV0LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmw6ICcuL3NwcmVhZHNoZWV0LmNvbXBvbmVudC5zY3NzJyxcbn0pXG5leHBvcnQgY2xhc3MgTGlic1VpQ29tcG9uZW50c1NwcmVhZHNoZWV0Q29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcbiAgcHJpdmF0ZSB1bml2ZXI6IFVuaXZlciB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHVuaXZlckFQSTogRlVuaXZlciB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGNvbHVtbkNsaWNrRGlzcG9zYWJsZTogeyBkaXNwb3NlOiAoKSA9PiB2b2lkIH0gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBmb3JtYXREaXNwb3NhYmxlOiB7IGRpc3Bvc2U6ICgpID0+IHZvaWQgfSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGNvbHVtbk9wRGlzcG9zYWJsZTogeyBkaXNwb3NlOiAoKSA9PiB2b2lkIH0gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBudW1mbXRPYnNlcnZlcjogTXV0YXRpb25PYnNlcnZlciB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHRvb2xiYXJSZXNpemVPYnNlcnZlcjogUmVzaXplT2JzZXJ2ZXIgfCBudWxsID0gbnVsbDtcbiAgLy8gPHN0eWxlPiByacOqbmcgY2hvIGluc3RhbmNlOiBwaW4gd2lkdGggY29udGFpbmVyIMSRbyBxdWEgQ1NTIHJ1bGUgKFJlYWN0IHJlLXJlbmRlciBLSMOUTkcgc3RyaXAgxJHGsOG7o2Mg4oaSXG4gIC8vIHRyw6FuaCB2w7JuZyBs4bq3cCBvc2NpbGxhdGlvbiBnaeG7r2Egc2V0LWlubGluZS13aWR0aCB2w6AgUmVhY3Qgc3RyaXAgZ8OieSBr4bq5dCDii64pLiBYZW0gcmVnaXN0ZXJUb29sYmFyV2lkdGhTeW5jLlxuICBwcml2YXRlIHRvb2xiYXJTdHlsZUVsOiBIVE1MU3R5bGVFbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgcmVhZG9ubHkgdG9vbGJhclNjb3BlQ2xhc3MgPSBgbGlicy11aS1zcHJlYWRzaGVldC10Yi0keyhzcHJlYWRzaGVldEluc3RhbmNlQ291bnQgKz0gMSl9YDtcbiAgcHJpdmF0ZSBudW1mbXRDbGlja0Rpc3Bvc2FibGU6IHsgZGlzcG9zZTogKCkgPT4gdm9pZCB9IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgbGFzdFJhbmdlU25hcHNob3Q6IFRfcmFuZ2VTbmFwc2hvdCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHBlbmRpbmdOdW1mbXRQYXR0ZXJuOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgLy8gdHJ1ZSBDSOG7iCBraGkgdXNlciBi4bqlbSBuw7p0IENvbmZpcm0gdHJvbmcgcGFuZWwgbnVtZm10IOKGkiBnaeG7ryBmb3JtYXQ7IENhbmNlbC9YL2NsaWNrLW5nb8OgaSA9IGZhbHNlIOKGkiByZXZlcnQuXG4gIHByaXZhdGUgbnVtZm10Q29uZmlybWVkID0gZmFsc2U7XG4gIC8vIFNuYXBzaG90IG51bWZtdCB04burbmcgw7QgY+G7p2EgdsO5bmcgY2jhu41uIHThuqFpIHRo4budaSDEkWnhu4NtIG3hu58gcGFuZWwg4oCUIGTDuW5nIGtow7RpIHBo4bulYyBjaMOtbmggeMOhYyBraGkgQ2FuY2VsLlxuICBwcml2YXRlIG9yaWdpbmFsQ2VsbEZvcm1hdHM6IHsgcGF0dGVybjogc3RyaW5nOyByb3c6IG51bWJlcjsgY29sOiBudW1iZXIgfVtdIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgbnVtZm10UGFuZWxPcGVuID0gZmFsc2U7XG4gIC8vIHRydWUga2hpIGx14buTbmcgRGF0ZSBjdXN0b20gxJFhbmcgaG/huqF0IMSR4buZbmcgKMSRw6MgaW5qZWN0IG9wdGlvbiBuZ8OgeSkuIENI4buIIGtoaSDEkcOzIGNvbXBvbmVudCBt4bubaVxuICAvLyBjYW4gdGhp4buHcCBjb25maXJtL3JldmVydDsgY8OhYyBUeXBlIGtow6FjIChT4buRLCBUaeG7gW4gdOG7hywgJSwgVGV4dOKApikgZG8gVW5pdmVyIHThu7EgeOG7rSBsw70g4oaSIGtow7RuZyDEkeG7pW5nIHbDoG8uXG4gIHByaXZhdGUgbnVtZm10RGF0ZUFjdGl2ZSA9IGZhbHNlO1xuICAvLyDEkOG7k25nIGLhu5kgbOG6oWkgcGFuZWwgRGF0ZSAobGFiZWwgKyBoaWdobGlnaHQgKyBhdXRvLWFwcGx5KSB0aGVvIHbDuW5nIGNo4buNbiBt4bubaSBraGkgdXNlciDEkeG7lWkgY+G7mXQgbMO6YyBwYW5lbCBt4bufLlxuICBwcml2YXRlIG51bWZtdFJlc3luYzogKCgpID0+IHZvaWQpIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgbGlzdGVuRW5hYmxlZCA9IGZhbHNlO1xuICBwcml2YXRlIGxpc3RlbkVuYWJsZVRpbWVyOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PiB8IG51bGwgPSBudWxsO1xuICAvLyBEZWZlciBpbml0aWFsIGVtcHR5LXdvcmtib29rIGluaXQgdG8gYWxsb3cgcGFyZW50J3MgbmdBZnRlclZpZXdJbml0IHRvIGNhbGwgbG9hZERhdGFcbiAgLy8gZmlyc3QgKGNhbmNlbGxpbmcgdGhlIGVtcHR5IGluaXQpLCBhdm9pZGluZyBhIHJhY2Ugd2l0aCBVbml2ZXIncyBhc3luYyBSZWFjdCByZW5kZXJzLlxuICBwcml2YXRlIHBlbmRpbmdJbml0VGltZXI6IFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgbnVtZm10Q2xlYW51cDogKCgpID0+IHZvaWQpIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgcGVuZGluZ1JlYWR5Q2I6ICgoKSA9PiB2b2lkKSB8IG51bGwgPSBudWxsO1xuICAvLyBTbmFwc2hvdCDEkcOjLWRlY29yYXRlIGfhuqduIG5o4bqldCDigJQgbMOgbSBiYXNlbGluZSDEkeG7gyBkaWZmIChzdHlsZSBpZCDhu5VuIMSR4buLbmggJ2gnLydtJywga2jDtG5nIGLhu4tcbiAgLy8g4bqjbmggaMaw4bufbmcgYuG7n2kgc3R5bGUgaWQgdOG7sSBzaW5oIHNhdSBt4buXaSBmYWNhZGUgc2V0VmFsdWUpLiBEw7luZyBjaG8gcmUtYXBwbHkgaW5jcmVtZW50YWwuXG4gIHByaXZhdGUgbGFzdERlY29yYXRlZDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSByZWFkeU9ic2VydmVyOiBNdXRhdGlvbk9ic2VydmVyIHwgbnVsbCA9IG51bGw7XG4gIC8vIENhY2hlIGNvbnRyb2xsZXIgbnVtZm10IG7hu5lpIGLhu5kgY+G7p2EgVW5pdmVyIChnaeG7ryBfcHJldmlld1BhdHRlcm4pLiBUw6xtIDEgbOG6p24gcXVhIGluamVjdG9yLlxuICAvLyBDT05WRU5USU9OLUVYQ0VQVDogYW55IOKAlCBOdW1mbXRDb250cm9sbGVyIGtow7RuZyBleHBvcnQga2jhu49pIEB1bml2ZXJqcy9zaGVldHMtbnVtZm10XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gIHByaXZhdGUgbnVtZm10Q29udHJvbGxlcjogYW55ID0gbnVsbDtcblxuICBwcml2YXRlIHJlYWRvbmx5IGFjdGl2ZUNlbGxGb3JtYXQgPSBzaWduYWwoJ0dlbmVyYWwnKTtcbiAgcHJpdmF0ZSByZWFkb25seSBhY3RpdmVDZWxsUmVmID0gc2lnbmFsKCcnKTtcbiAgcHJpdmF0ZSByZWFkb25seSBzaG93VG9vbGJhciA9IHNpZ25hbCh0cnVlKTtcbiAgcHJpdmF0ZSByZWFkb25seSBzaG93U2hlZXRUYWJzID0gc2lnbmFsKHRydWUpO1xuICAvLyBOZ8O0biBuZ+G7ryDEkWFuZyBoaeG7g24gdGjhu4sgdGjhu7FjIHThur8uIEto4bufaSB04bqhbyB04burIGlucHV0IGBsb2NhbGVgIHRyb25nIG5nQWZ0ZXJWaWV3SW5pdCxcbiAgLy8gc2F1IMSRw7MgxJHhu5VpIHJ1bnRpbWUgcXVhIHNldExvY2FsZSgpIChrw6lvIHRoZW8gcmVpbml0IMSR4buDIFVuaXZlciByZW5kZXIgbOG6oWkgVUkpLlxuICBwcml2YXRlIHJlYWRvbmx5IGFjdGl2ZUxvY2FsZSA9IHNpZ25hbDxUX3NwcmVhZHNoZWV0X2xvY2FsZT4oJ3ZpJyk7XG5cbiAgLyoqIE5nw7RuIG5n4buvIGto4bufaSB04bqhbyBj4bunYSBzcHJlYWRzaGVldC4gxJDhu5VpIHJ1bnRpbWUgZMO5bmcgRnVuY3Rpb25Db250cm9sLnNldExvY2FsZSgpLiAqL1xuICByZWFkb25seSBsb2NhbGUgPSBpbnB1dDxUX3NwcmVhZHNoZWV0X2xvY2FsZT4oJ3ZpJyk7XG5cbiAgLyoqIEPhuqV1IGjDrG5oIOG6qW4gLyB2w7QgaGnhu4d1IGhvw6EgdG9vbGJhciBpdGVtcy4gVGhheSDEkeG7lWkgc+G6vSByZWluaXQgdG/DoG4gYuG7mSBVbml2ZXIuICovXG4gIHJlYWRvbmx5IHRvb2xiYXJNZW51Q29uZmlnID0gaW5wdXQ8VF90b29sYmFyX21lbnVfY29uZmlnPih7XG4gICAgLy8gJ3NoZWV0LmNvbW1hbmQubnVtZm10LnNldC5jdXJyZW5jeSc6IHsgaGlkZGVuOiB0cnVlIH0sXG4gICAgLy8gJ3NoZWV0LmNvbW1hbmQubnVtZm10LmFkZC5kZWNpbWFsLmNvbW1hbmQnOiB7IGhpZGRlbjogdHJ1ZSB9LFxuICAgIC8vICdzaGVldC5jb21tYW5kLm51bWZtdC5zdWJ0cmFjdC5kZWNpbWFsLmNvbW1hbmQnOiB7IGhpZGRlbjogdHJ1ZSB9LFxuICAgIC8vICdzaGVldC5jb21tYW5kLm51bWZtdC5zZXQucGVyY2VudCc6IHsgaGlkZGVuOiB0cnVlIH0sXG4gICAgJ3NoZWV0LmNvbW1hbmQuc2V0LW9uY2UtZm9ybWF0LXBhaW50ZXInOiB7IGhpZGRlbjogdHJ1ZSB9LFxuICAgICdzaGVldC5jb21tYW5kLnNldC10ZXh0LXJvdGF0aW9uJzogeyBoaWRkZW46IHRydWUgfSxcbiAgICAnc2hlZXQuY29tbWFuZC5zZXQtcmFuZ2UtZm9udC1mYW1pbHknOiB7IGhpZGRlbjogdHJ1ZSB9LFxuICAgICdzaGVldC5jb21tYW5kLnNldC1ib3JkZXItYmFzaWMnOiB7IGhpZGRlbjogdHJ1ZSB9LFxuICAgICdzaGVldC5jb21tYW5kLmFkZC13b3Jrc2hlZXQtbWVyZ2UnOiB7IGhpZGRlbjogdHJ1ZSB9LFxuICAgICdzaGVldC5jb21tYW5kLmFkZC13b3Jrc2hlZXQtbWVyZ2UtYWxsJzogeyBoaWRkZW46IHRydWUgfSxcbiAgICAnc2hlZXQuY29tbWFuZC5hZGQtd29ya3NoZWV0LW1lcmdlLXZlcnRpY2FsJzogeyBoaWRkZW46IHRydWUgfSxcbiAgICAnc2hlZXQuY29tbWFuZC5hZGQtd29ya3NoZWV0LW1lcmdlLWhvcml6b250YWwnOiB7IGhpZGRlbjogdHJ1ZSB9LFxuICAgICdzaGVldC5jb21tYW5kLnJlbW92ZS13b3Jrc2hlZXQtbWVyZ2UnOiB7IGhpZGRlbjogdHJ1ZSB9LFxuICB9KTtcblxuICAvKipcbiAgICogQ+G6pXUgaMOsbmggaGlnaGxpZ2h0IGPhu5l0IMSRw6MgbWFwIChzdHlsZSAvIHByZWZpeCAvIHNjb3BlIHNoZWV0KS5cbiAgICogVHJ1eeG7gW4gY29uZmlnIG7DoHkgPSBcImLhuq10XCIgbHXhu5NuZyBhdXRvOiBjb21wb25lbnQgc+G6vSBU4buwIMOhcCBpbmRpY2F0b3Iga2hpIGxvYWQvcmVzZXQsXG4gICAqIFThu7AgZ+G7oSBraGkgc2F2ZSwgdsOgIFThu7AgduG6vSBs4bqhaSBt4buXaSBraGkgYG1hcHBpbmdUYXJnZXRzYCDEkeG7lWkuIELhu48gdHLhu5FuZyA9IHNwcmVhZHNoZWV0IHRoxrDhu51uZy5cbiAgICovXG4gIHJlYWRvbmx5IG1hcHBpbmdJbmRpY2F0b3JDb25maWcgPSBpbnB1dDxUX21hcHBpbmdJbmRpY2F0b3JDb25maWc+KCk7XG5cbiAgLyoqIERhbmggc8OhY2ggY+G7mXQgY+G6p24gaGlnaGxpZ2h0IChgeyBzaGVldElkLCBjb2xJbmRleCB9YCkuIMSQ4buVaSBydW50aW1lIOKGkiB04buxIHbhur0gbOG6oWkgaGVhZGVyLiAqL1xuICByZWFkb25seSBtYXBwaW5nVGFyZ2V0cyA9IGlucHV0PFRfaW5kaWNhdG9yVGFyZ2V0W10+KFtdKTtcblxuICByZWFkb25seSBvdXRDb2x1bW5EYmxDbGljayA9IG91dHB1dDxudW1iZXI+KCk7XG5cbiAgLyoqXG4gICAqIFBow6F0IGtoaSB1c2VyIGluc2VydCAvIHJlbW92ZSAvIG1vdmUgY+G7mXQgKGvhu4MgY+G6oyBjaOG7jW4gbmhp4buBdSBj4buZdCwgdsOgIGPhuqMgdW5kby9yZWRvKS5cbiAgICogQ29uc3VtZXIgZMO5bmcgYHJlbWFwQ29sdW1uSW5kZXhlcyhtYXBwaW5ncywgJGV2ZW50KWAgxJHhu4MgZOG7i2NoIGzhuqFpIG3huqNuZyBtYXBwaW5nIGLDqm4gbmdvw6BpXG4gICAqIGNobyBraOG7m3AgduG7iyB0csOtIG3hu5tpIOKAlCB0csOhbmggbOG7h2NoIGtoaSBjaMOobi94w7NhIGPhu5l0IOG7nyBnaeG7r2EuXG4gICAqL1xuICByZWFkb25seSBvdXRDb2x1bW5TdHJ1Y3R1cmVDaGFuZ2UgPSBvdXRwdXQ8VF9jb2x1bW5TdHJ1Y3R1cmVDaGFuZ2U+KCk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBjb250YWluZXJSZWYgPSB2aWV3Q2hpbGQ8RWxlbWVudFJlZj4oJ2NvbnRhaW5lclJlZicpO1xuICBwcml2YXRlIHJlYWRvbmx5IG5nWm9uZSA9IGluamVjdChOZ1pvbmUpO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIC8vIEF1dG8gcmUtYXBwbHk6IGNo4buJIGNo4bqheSBraGkgxJHDoyBi4bqtdCBjb25maWcgKyBVbml2ZXIgxJHDoyBraOG7n2kgdOG6oW8uIEzhuqduIMSR4bqndSAoY2jGsGEgaW5pdCkgdOG7sSBi4buPIHF1YS5cbiAgICBlZmZlY3QoKCkgPT4ge1xuICAgICAgdGhpcy5tYXBwaW5nVGFyZ2V0cygpO1xuICAgICAgdGhpcy5tYXBwaW5nSW5kaWNhdG9yQ29uZmlnKCk7XG4gICAgICB1bnRyYWNrZWQoKCkgPT4gdGhpcy5yZWFwcGx5SW5kaWNhdG9ycygpKTtcbiAgICB9KTtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICB0aGlzLmFjdGl2ZUxvY2FsZS5zZXQodGhpcy5sb2NhbGUoKSk7XG4gICAgdGhpcy5wZW5kaW5nSW5pdFRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnBlbmRpbmdJbml0VGltZXIgPSBudWxsO1xuICAgICAgdGhpcy5pbml0VW5pdmVyKHRoaXMuYnVpbGRFbXB0eVdvcmtib29rKCkpO1xuICAgIH0pO1xuICB9XG5cbiAgZ2V0IEZ1bmN0aW9uQ29udHJvbCgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgbG9hZERhdGE6IChkYXRhOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikgPT4gdGhpcy5sb2FkRGF0YShkYXRhKSxcbiAgICAgIHNhdmVEYXRhOiAoKSA9PiB0aGlzLnNhdmVEYXRhKCksXG4gICAgICBnZXRBY3RpdmVTaGVldEluZm86ICgpID0+IHRoaXMuZ2V0QWN0aXZlU2hlZXRJbmZvKCksXG4gICAgICBnZXRDb2x1bW5OdW1mbXQ6IChzaGVldElkOiBzdHJpbmcsIGNvbEluZGV4OiBudW1iZXIpID0+IHRoaXMuZ2V0Q29sdW1uTnVtZm10KHNoZWV0SWQsIGNvbEluZGV4KSxcbiAgICAgIGV4dHJhY3RBbGxDb2x1bW5Gb3JtYXRzOiAoc25hcHNob3Q6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PiB0aGlzLmV4dHJhY3RBbGxDb2x1bW5Gb3JtYXRzKHNuYXBzaG90KSxcbiAgICAgIHRvZ2dsZVRvb2xiYXI6ICgpID0+IHRoaXMudG9nZ2xlVG9vbGJhcigpLFxuICAgICAgdG9nZ2xlU2hlZXRUYWJzOiAoKSA9PiB0aGlzLnRvZ2dsZVNoZWV0VGFicygpLFxuICAgICAgcmVzZXQ6IChkYXRhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+IHRoaXMucmVzZXQoZGF0YSksXG4gICAgICBleGVjdXRlQ29tbWFuZDogKGNvbW1hbmRJZDogc3RyaW5nLCBwYXJhbXM6IHVua25vd24pID0+IHRoaXMuZXhlY3V0ZUNvbW1hbmQoY29tbWFuZElkLCBwYXJhbXMpLFxuICAgICAgYXBwbHlOdW1mbXQ6IChyb3c6IG51bWJlciwgY29sOiBudW1iZXIsIG51bVJvd3M6IG51bWJlciwgbnVtQ29sczogbnVtYmVyLCBwYXR0ZXJuOiBzdHJpbmcpID0+IHRoaXMuYXBwbHlOdW1mbXQocm93LCBjb2wsIG51bVJvd3MsIG51bUNvbHMsIHBhdHRlcm4pLFxuICAgICAgc2NoZWR1bGVPblJlYWR5OiAoY2I6ICgpID0+IHZvaWQpID0+IHtcbiAgICAgICAgdGhpcy5wZW5kaW5nUmVhZHlDYiA9IGNiO1xuICAgICAgfSxcbiAgICAgIHNldExvY2FsZTogKGxvY2FsZTogVF9zcHJlYWRzaGVldF9sb2NhbGUpID0+IHRoaXMuc2V0TG9jYWxlKGxvY2FsZSksXG4gICAgICBhY3RpdmVDZWxsUmVmOiB0aGlzLmFjdGl2ZUNlbGxSZWYsXG4gICAgICBhY3RpdmVDZWxsRm9ybWF0OiB0aGlzLmFjdGl2ZUNlbGxGb3JtYXQsXG4gICAgICBzaG93VG9vbGJhcjogdGhpcy5zaG93VG9vbGJhcixcbiAgICAgIHNob3dTaGVldFRhYnM6IHRoaXMuc2hvd1NoZWV0VGFicyxcbiAgICAgIGxvY2FsZTogdGhpcy5hY3RpdmVMb2NhbGUuYXNSZWFkb25seSgpLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIHNldExvY2FsZShsb2NhbGU6IFRfc3ByZWFkc2hlZXRfbG9jYWxlKSB7XG4gICAgaWYgKGxvY2FsZSA9PT0gdGhpcy5hY3RpdmVMb2NhbGUoKSkgcmV0dXJuO1xuICAgIHRoaXMuYWN0aXZlTG9jYWxlLnNldChsb2NhbGUpO1xuICAgIHRoaXMucmVpbml0VW5pdmVyKCk7XG4gIH1cblxuICBwcml2YXRlIGxvYWREYXRhKGRhdGE6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSB7XG4gICAgY29uc3QgZGVjb3JhdGVkID0gdGhpcy5kZWNvcmF0ZVNuYXBzaG90KGRhdGEpO1xuICAgIGlmICh0aGlzLnBlbmRpbmdJbml0VGltZXIgIT09IG51bGwpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLnBlbmRpbmdJbml0VGltZXIpO1xuICAgICAgdGhpcy5wZW5kaW5nSW5pdFRpbWVyID0gbnVsbDtcbiAgICAgIHRoaXMuaW5pdFVuaXZlcihkZWNvcmF0ZWQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmRlc3Ryb3lVbml2ZXIoKTtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMuaW5pdFVuaXZlcihkZWNvcmF0ZWQpKTtcbiAgfVxuXG4gIC8qKiBTbmFwc2hvdCB0aMO0IHThu6sgVW5pdmVyIChDw5MgdGjhu4MgY8OybiBpbmRpY2F0b3IpLiBEw7luZyBu4buZaSBi4buZIGNobyByZS1hcHBseS4gKi9cbiAgcHJpdmF0ZSBzYXZlUmF3KCk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgICByZXR1cm4gKHRoaXMudW5pdmVyQVBJPy5nZXRBY3RpdmVXb3JrYm9vaygpPy5zYXZlKCkgPz8ge30pIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICB9XG5cbiAgLyoqIFNuYXBzaG90IHRy4bqjIGNobyBjb25zdW1lciDigJQgdOG7sSBn4buhIGluZGljYXRvciBu4bq/dSBsdeG7k25nIGF1dG8gxJFhbmcgYuG6rXQuICovXG4gIHByaXZhdGUgc2F2ZURhdGEoKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMubWFwcGluZ0luZGljYXRvckNvbmZpZygpO1xuICAgIGlmICghY29uZmlnKSByZXR1cm4gdGhpcy5zYXZlUmF3KCk7XG4gICAgcmV0dXJuIHN0cmlwTWFwcGluZ0luZGljYXRvcnModGhpcy5zYXZlUmF3KCksIGNvbmZpZyk7XG4gIH1cblxuICAvKiogw4FwIGluZGljYXRvciB2w6BvIHNuYXBzaG90IHRyxrDhu5tjIGtoaSBsb2FkIOKAlCBjaOG7iSBraGkgbHXhu5NuZyBhdXRvIMSRYW5nIGLhuq10LiBMxrB1IGJhc2VsaW5lIMSR4buDIGRpZmYuICovXG4gIHByaXZhdGUgZGVjb3JhdGVTbmFwc2hvdChkYXRhOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgICBjb25zdCBjb25maWcgPSB0aGlzLm1hcHBpbmdJbmRpY2F0b3JDb25maWcoKTtcbiAgICBpZiAoIWNvbmZpZykgcmV0dXJuIGRhdGE7XG4gICAgY29uc3QgZGVjb3JhdGVkID0gYXBwbHlNYXBwaW5nSW5kaWNhdG9ycyhkYXRhLCB0aGlzLm1hcHBpbmdUYXJnZXRzKCksIGNvbmZpZyk7XG4gICAgdGhpcy5sYXN0RGVjb3JhdGVkID0gZGVjb3JhdGVkO1xuICAgIHJldHVybiBkZWNvcmF0ZWQ7XG4gIH1cblxuICAvKipcbiAgICogVuG6vSBs4bqhaSBpbmRpY2F0b3IgS0jDlE5HIHJlaW5pdCBVbml2ZXI6IHTDrW5oIHNuYXBzaG90IMSRw61jaCBy4buTaSBDSOG7iCBnaGkgxJHDqCDEkcO6bmcgY8OhYyDDtCBoZWFkZXJcbiAgICoga2jDoWMgc28gduG7m2kgYmFzZWxpbmUgdHLGsOG7m2MgxJHDsyAoc3R5bGUgKyBwcmVmaXggKyB3aWR0aCkgbMOqbiBpbnN0YW5jZSBsaXZlIHF1YSBmYWNhZGUuXG4gICAqIERpZmYgdGhlbyBiYXNlbGluZSAoc3R5bGUgaWQg4buVbiDEkeG7i25oICdoJy8nbScpIOKGkiBjaOG7iSBjw6FjIGPhu5l0IHbhu6thIG1hcC9i4buPIG1hcCBt4bubaSDEkcaw4bujYyB24bq9IGzhuqFpLlxuICAgKi9cbiAgcHJpdmF0ZSByZWFwcGx5SW5kaWNhdG9ycygpIHtcbiAgICBjb25zdCBjb25maWcgPSB0aGlzLm1hcHBpbmdJbmRpY2F0b3JDb25maWcoKTtcbiAgICBjb25zdCB3YiA9IHRoaXMudW5pdmVyQVBJPy5nZXRBY3RpdmVXb3JrYm9vaygpO1xuICAgIGNvbnN0IHByZXYgPSB0aGlzLmxhc3REZWNvcmF0ZWQ7XG4gICAgaWYgKCFjb25maWcgfHwgIXdiIHx8ICFwcmV2KSByZXR1cm47XG5cbiAgICBjb25zdCBuZXh0ID0gYXBwbHlNYXBwaW5nSW5kaWNhdG9ycyh0aGlzLnNhdmVSYXcoKSwgdGhpcy5tYXBwaW5nVGFyZ2V0cygpLCBjb25maWcpO1xuICAgIHRoaXMubGFzdERlY29yYXRlZCA9IG5leHQ7XG5cbiAgICB0eXBlIFRfY2VsbCA9IHsgdj86IHVua25vd247IHM/OiB1bmtub3duIH07XG4gICAgdHlwZSBUX3NoZWV0ID0geyBjZWxsRGF0YT86IFJlY29yZDxzdHJpbmcsIFJlY29yZDxzdHJpbmcsIFRfY2VsbD4+OyBjb2x1bW5EYXRhPzogUmVjb3JkPHN0cmluZywgeyB3PzogbnVtYmVyIH0+IH07XG4gICAgY29uc3QgaGVhZGVyS2V5ID0gU3RyaW5nKGNvbmZpZy5oZWFkZXJSb3dJbmRleCA/PyAwKTtcbiAgICBjb25zdCBoZWFkZXJSb3cgPSBOdW1iZXIoaGVhZGVyS2V5KTtcbiAgICBjb25zdCBzdHlsZXNOZXh0ID0gKG5leHRbJ3N0eWxlcyddID8/IHt9KSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICBjb25zdCBzaGVldHNOZXh0ID0gKG5leHRbJ3NoZWV0cyddID8/IHt9KSBhcyBSZWNvcmQ8c3RyaW5nLCBUX3NoZWV0PjtcbiAgICBjb25zdCBzaGVldHNQcmV2ID0gKHByZXZbJ3NoZWV0cyddID8/IHt9KSBhcyBSZWNvcmQ8c3RyaW5nLCBUX3NoZWV0PjtcblxuICAgIGZvciAoY29uc3Qgc2hlZXRJZCBvZiBPYmplY3Qua2V5cyhzaGVldHNOZXh0KSkge1xuICAgICAgY29uc3Qgd3MgPSB3Yi5nZXRTaGVldEJ5U2hlZXRJZChzaGVldElkKTtcbiAgICAgIGlmICghd3MpIGNvbnRpbnVlO1xuICAgICAgY29uc3QgbmV4dFJvdyA9IHNoZWV0c05leHRbc2hlZXRJZF0/LmNlbGxEYXRhPy5baGVhZGVyS2V5XSA/PyB7fTtcbiAgICAgIGNvbnN0IHByZXZSb3cgPSBzaGVldHNQcmV2W3NoZWV0SWRdPy5jZWxsRGF0YT8uW2hlYWRlcktleV0gPz8ge307XG4gICAgICBjb25zdCBjb2xEYXRhID0gc2hlZXRzTmV4dFtzaGVldElkXT8uY29sdW1uRGF0YSA/PyB7fTtcbiAgICAgIGZvciAoY29uc3QgY29sS2V5IG9mIE9iamVjdC5rZXlzKG5leHRSb3cpKSB7XG4gICAgICAgIGNvbnN0IGNlbGxOZXh0ID0gbmV4dFJvd1tjb2xLZXldO1xuICAgICAgICBjb25zdCBjZWxsUHJldiA9IHByZXZSb3dbY29sS2V5XTtcbiAgICAgICAgLy8gw5Qga2jDtG5nIMSR4buVaSBj4bqjIHZhbHVlIGzhuqtuIHN0eWxlIOKGkiBi4buPIHF1YSAobeG6pXUgY2jhu5F0OiBjaOG7iSB24bq9IGzhuqFpIGPhu5l0IHbhu6thIG1hcC9i4buPIG1hcCkuXG4gICAgICAgIGlmICghY2VsbE5leHQgfHwgKGNlbGxOZXh0LnYgPT09IGNlbGxQcmV2Py52ICYmIGNlbGxOZXh0LnMgPT09IGNlbGxQcmV2Py5zKSkgY29udGludWU7XG4gICAgICAgIGNvbnN0IHN0eWxlID0gKHR5cGVvZiBjZWxsTmV4dC5zID09PSAnc3RyaW5nJyA/IHN0eWxlc05leHRbY2VsbE5leHQuc10gOiBjZWxsTmV4dC5zKSBhcyBJU3R5bGVEYXRhO1xuICAgICAgICBjb25zdCBjZWxsOiBJQ2VsbERhdGEgPSB7IHY6IGNlbGxOZXh0LnYgYXMgQ2VsbFZhbHVlLCBzOiBzdHlsZSB9O1xuICAgICAgICB2b2lkIHdzLmdldFJhbmdlKGhlYWRlclJvdywgTnVtYmVyKGNvbEtleSkpLnNldFZhbHVlKGNlbGwpO1xuICAgICAgICBjb25zdCB3aWR0aCA9IGNvbERhdGFbY29sS2V5XT8udztcbiAgICAgICAgaWYgKHR5cGVvZiB3aWR0aCA9PT0gJ251bWJlcicpIHZvaWQgd3Muc2V0Q29sdW1uV2lkdGgoTnVtYmVyKGNvbEtleSksIHdpZHRoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHRvZ2dsZVRvb2xiYXIoKSB7XG4gICAgdGhpcy5zaG93VG9vbGJhci51cGRhdGUoKHYpID0+ICF2KTtcbiAgICB0aGlzLnJlaW5pdFVuaXZlcigpO1xuICB9XG5cbiAgcHJpdmF0ZSB0b2dnbGVTaGVldFRhYnMoKSB7XG4gICAgdGhpcy5zaG93U2hlZXRUYWJzLnVwZGF0ZSgodikgPT4gIXYpO1xuICAgIHRoaXMucmVpbml0VW5pdmVyKCk7XG4gIH1cblxuICBwcml2YXRlIHJlc2V0KGRhdGE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikge1xuICAgIHRoaXMuZGVzdHJveVVuaXZlcigpO1xuICAgIHRoaXMuaW5pdFVuaXZlcih0aGlzLmRlY29yYXRlU25hcHNob3QoZGF0YSA/PyB0aGlzLmJ1aWxkRW1wdHlXb3JrYm9vaygpKSk7XG4gIH1cblxuICBwcml2YXRlIGV4ZWN1dGVDb21tYW5kKGNvbW1hbmRJZDogc3RyaW5nLCBwYXJhbXM6IHVua25vd24pIHtcbiAgICAvLyBDT05WRU5USU9OLUVYQ0VQVDogYW55IOKAlCBGVW5pdmVyLmV4ZWN1dGVDb21tYW5kIGtow7RuZyBleHBvc2UgdHlwaW5nXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICB2b2lkICh0aGlzLnVuaXZlckFQSSBhcyBhbnkpPy5leGVjdXRlQ29tbWFuZD8uKGNvbW1hbmRJZCwgcGFyYW1zKTtcbiAgfVxuXG4gIHByaXZhdGUgYXBwbHlOdW1mbXQocm93OiBudW1iZXIsIGNvbDogbnVtYmVyLCBudW1Sb3dzOiBudW1iZXIsIG51bUNvbHM6IG51bWJlciwgcGF0dGVybjogc3RyaW5nKSB7XG4gICAgLy8gQ09OVkVOVElPTi1FWENFUFQ6IGFueSDigJQgRldvcmtib29rLmdldElkIC8gRldvcmtzaGVldC5nZXRTaGVldElkIG5vdCBleHBvc2VkIGluIHB1YmxpYyB0eXBlc1xuICAgIC8vIE5vdGU6IEZSYW5nZS5zZXROdW1iZXJGb3JtYXQoKSBoYXMgYSBVbml2ZXIgZmFjYWRlIGJ1ZyDigJQgaXQgYnVpbGRzIGB2YWx1ZXNgIGJ1dCBuZXZlciBwYXNzZXNcbiAgICAvLyB0aGVtIHRvIGV4ZWN1dGVDb21tYW5kLiBXZSBjYWxsIHRoZSBjb21tYW5kIGRpcmVjdGx5IHdpdGggdGhlIGNvcnJlY3QgcGFyYW1zIGluc3RlYWQuXG4gICAgLy8gRldvcmtib29rIHVzZXMgZ2V0SWQoKSAobm90IGdldFVuaXRJZCgpKSBhbmQgRldvcmtzaGVldCB1c2VzIGdldFNoZWV0SWQoKSBmb3Igc3ViVW5pdElkLlxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgY29uc3Qgd2IgPSB0aGlzLnVuaXZlckFQST8uZ2V0QWN0aXZlV29ya2Jvb2soKSBhcyBhbnk7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICBjb25zdCB3cyA9IHdiPy5nZXRBY3RpdmVTaGVldD8uKCkgYXMgYW55O1xuICAgIGlmICghd2IgfHwgIXdzKSByZXR1cm47XG4gICAgY29uc3QgdW5pdElkID0gKHdiLmdldElkPy4oKSA/PyAnJykgYXMgc3RyaW5nO1xuICAgIGNvbnN0IHN1YlVuaXRJZCA9ICh3cy5nZXRTaGVldElkPy4oKSA/PyAnJykgYXMgc3RyaW5nO1xuICAgIGNvbnN0IHZhbHVlczogeyBwYXR0ZXJuOiBzdHJpbmc7IHJvdzogbnVtYmVyOyBjb2w6IG51bWJlciB9W10gPSBbXTtcbiAgICBmb3IgKGxldCByID0gcm93OyByIDwgcm93ICsgbnVtUm93czsgcisrKSB7XG4gICAgICBmb3IgKGxldCBjID0gY29sOyBjIDwgY29sICsgbnVtQ29sczsgYysrKSB7XG4gICAgICAgIHZhbHVlcy5wdXNoKHsgcGF0dGVybiwgcm93OiByLCBjb2w6IGMgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuZXhlY3V0ZUNvbW1hbmQoJ3NoZWV0LmNvbW1hbmQubnVtZm10LnNldC5udW1mbXQnLCB7IHVuaXRJZCwgc3ViVW5pdElkLCB2YWx1ZXMgfSk7XG4gIH1cblxuICBwcml2YXRlIGdldEFjdGl2ZVNoZWV0SW5mbygpOiB7IHNoZWV0SWQ6IHN0cmluZzsgc2hlZXROYW1lOiBzdHJpbmcgfSB8IG51bGwge1xuICAgIC8vIENPTlZFTlRJT04tRVhDRVBUOiBhbnkg4oCUIEZXb3Jrc2hlZXQgcHVibGljIHR5cGVzIGNoxrBhIGV4cG9zZSBnZXRTaGVldElkL2dldE5hbWVcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgIGNvbnN0IHNoZWV0ID0gdGhpcy51bml2ZXJBUEk/LmdldEFjdGl2ZVdvcmtib29rKCk/LmdldEFjdGl2ZVNoZWV0KCkgYXMgYW55O1xuICAgIGlmICghc2hlZXQpIHJldHVybiBudWxsO1xuICAgIHJldHVybiB7XG4gICAgICBzaGVldElkOiAoc2hlZXQuZ2V0U2hlZXRJZD8uKCkgPz8gJycpIGFzIHN0cmluZyxcbiAgICAgIHNoZWV0TmFtZTogKHNoZWV0LmdldFNoZWV0TmFtZT8uKCkgPz8gc2hlZXQuZ2V0TmFtZT8uKCkgPz8gJycpIGFzIHN0cmluZyxcbiAgICB9O1xuICB9XG5cbiAgLyoqIMSQ4buNYyBudW1mbXQgcGF0dGVybiBj4bunYSBt4buZdCBjZWxsIHThu6sgd29ya2Jvb2sgc25hcHNob3QuICovXG4gIHByaXZhdGUgcmVhZENlbGxOdW1mbXQoc2hlZXRJZDogc3RyaW5nLCByb3c6IG51bWJlciwgY29sOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIHRyeSB7XG4gICAgICAvLyBDT05WRU5USU9OLUVYQ0VQVDogYW55IOKAlCBGV29ya2Jvb2suc2F2ZSgpIGtow7RuZyBleHBvc2UgdHlwaW5nXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgY29uc3Qgc3MgPSB0aGlzLnVuaXZlckFQST8uZ2V0QWN0aXZlV29ya2Jvb2soKT8uc2F2ZSgpIGFzIGFueTtcbiAgICAgIHR5cGUgU3R5bGVFbnRyeSA9IHsgbj86IHsgcGF0dGVybj86IHN0cmluZyB9OyBuZj86IHsgcGF0dGVybj86IHN0cmluZyB9IH07XG4gICAgICBjb25zdCBzdHlsZXMgPSBzcz8uc3R5bGVzIGFzIFJlY29yZDxzdHJpbmcsIFN0eWxlRW50cnk+IHwgdW5kZWZpbmVkO1xuICAgICAgY29uc3QgY2VsbHMgPSAoc3M/LnNoZWV0cyBhcyBSZWNvcmQ8c3RyaW5nLCB7IGNlbGxEYXRhPzogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgeyBzPzogc3RyaW5nIH0+PiB9Pik/LltzaGVldElkXT8uY2VsbERhdGE7XG4gICAgICBjb25zdCBzdHlsZUlkID0gY2VsbHM/LltTdHJpbmcocm93KV0/LltTdHJpbmcoY29sKV0/LnM7XG4gICAgICBpZiAoIXN0eWxlSWQgfHwgIXN0eWxlcykgcmV0dXJuICdHZW5lcmFsJztcbiAgICAgIHJldHVybiBzdHlsZXNbc3R5bGVJZF0/Lm4/LnBhdHRlcm4gPz8gc3R5bGVzW3N0eWxlSWRdPy5uZj8ucGF0dGVybiA/PyAnR2VuZXJhbCc7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gJ0dlbmVyYWwnO1xuICAgIH1cbiAgfVxuXG4gIC8qKiDEkOG7jWMgZ2nDoSB0cuG7iyBz4buRIChFeGNlbCBzZXJpYWwpIGPhu6dhIG3hu5l0IMO0OyBudWxsIG7hur91IMO0IHLhu5duZy9raMO0bmcgcGjhuqNpIHPhu5EuICovXG4gIHByaXZhdGUgcmVhZENlbGxWYWx1ZShzaGVldElkOiBzdHJpbmcsIHJvdzogbnVtYmVyLCBjb2w6IG51bWJlcik6IG51bWJlciB8IG51bGwge1xuICAgIHRyeSB7XG4gICAgICAvLyBDT05WRU5USU9OLUVYQ0VQVDogYW55IOKAlCBGV29ya2Jvb2suc2F2ZSgpIGtow7RuZyBleHBvc2UgdHlwaW5nXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgY29uc3Qgc3MgPSB0aGlzLnVuaXZlckFQST8uZ2V0QWN0aXZlV29ya2Jvb2soKT8uc2F2ZSgpIGFzIGFueTtcbiAgICAgIGNvbnN0IGNlbGxzID0gKHNzPy5zaGVldHMgYXMgUmVjb3JkPHN0cmluZywgeyBjZWxsRGF0YT86IFJlY29yZDxzdHJpbmcsIFJlY29yZDxzdHJpbmcsIHsgdj86IHVua25vd24gfT4+IH0+KT8uW3NoZWV0SWRdPy5jZWxsRGF0YTtcbiAgICAgIGNvbnN0IHZhbHVlID0gY2VsbHM/LltTdHJpbmcocm93KV0/LltTdHJpbmcoY29sKV0/LnY7XG4gICAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyAmJiBpc0Zpbml0ZSh2YWx1ZSkgPyB2YWx1ZSA6IG51bGw7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldENvbHVtbk51bWZtdChzaGVldElkOiBzdHJpbmcsIGNvbEluZGV4OiBudW1iZXIpOiBzdHJpbmcge1xuICAgIGZvciAoY29uc3Qgcm93IG9mIFsxLCAyLCAzXSkge1xuICAgICAgY29uc3QgcGF0dGVybiA9IHRoaXMucmVhZENlbGxOdW1mbXQoc2hlZXRJZCwgcm93LCBjb2xJbmRleCk7XG4gICAgICBpZiAocGF0dGVybiAhPT0gJ0dlbmVyYWwnKSByZXR1cm4gcGF0dGVybjtcbiAgICB9XG4gICAgcmV0dXJuICdHZW5lcmFsJztcbiAgfVxuXG4gIC8qKiBDaOG7pXAgbnVtZm10IGfhu5FjIHThu6tuZyDDtCBj4bunYSB2w7luZyBjaOG7jW4gKGdp4bubaSBo4bqhbiA1MDAgZMOybmcgbmjGsCBhcHBseUZvcm1hdCkgxJHhu4MgQ2FuY2VsIGtow7RpIHBo4bulYyDEkcO6bmcuICovXG4gIHByaXZhdGUgY2FwdHVyZVJhbmdlTnVtZm10KHNuYXA6IFRfcmFuZ2VTbmFwc2hvdCB8IG51bGwpOiB7IHBhdHRlcm46IHN0cmluZzsgcm93OiBudW1iZXI7IGNvbDogbnVtYmVyIH1bXSB8IG51bGwge1xuICAgIGlmICghc25hcCkgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgdmFsdWVzOiB7IHBhdHRlcm46IHN0cmluZzsgcm93OiBudW1iZXI7IGNvbDogbnVtYmVyIH1bXSA9IFtdO1xuICAgIGNvbnN0IG1heFJvdyA9IE1hdGgubWluKHNuYXAuZW5kUm93LCBzbmFwLnN0YXJ0Um93ICsgNDk5KTtcbiAgICBmb3IgKGxldCByID0gc25hcC5zdGFydFJvdzsgciA8PSBtYXhSb3c7IHIrKykge1xuICAgICAgZm9yIChsZXQgYyA9IHNuYXAuc3RhcnRDb2x1bW47IGMgPD0gc25hcC5lbmRDb2x1bW47IGMrKykge1xuICAgICAgICB2YWx1ZXMucHVzaCh7IHBhdHRlcm46IHRoaXMucmVhZENlbGxOdW1mbXQoc25hcC5zdWJVbml0SWQsIHIsIGMpLCByb3c6IHIsIGNvbDogYyB9KTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlcy5sZW5ndGggPyB2YWx1ZXMgOiBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBleHRyYWN0QWxsQ29sdW1uRm9ybWF0cyhzbmFwc2hvdDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBUX2NlbGxGb3JtYXRSZXN1bHRbXSB7XG4gICAgdHlwZSBTdHlsZUVudHJ5ID0geyBuPzogeyBwYXR0ZXJuPzogc3RyaW5nIH07IG5mPzogeyBwYXR0ZXJuPzogc3RyaW5nIH0gfTtcbiAgICB0eXBlIFN0eWxlTWFwID0gUmVjb3JkPHN0cmluZywgU3R5bGVFbnRyeT47XG4gICAgdHlwZSBTaGVldE1hcCA9IFJlY29yZDxzdHJpbmcsIHsgbmFtZT86IHN0cmluZzsgY2VsbERhdGE/OiBSZWNvcmQ8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCB7IHM/OiBzdHJpbmc7IHY/OiB1bmtub3duIH0+PiB9PjtcblxuICAgIGNvbnN0IHN0eWxlcyA9IHNuYXBzaG90WydzdHlsZXMnXSBhcyBTdHlsZU1hcCB8IHVuZGVmaW5lZDtcbiAgICBjb25zdCBzaGVldHMgPSBzbmFwc2hvdFsnc2hlZXRzJ10gYXMgU2hlZXRNYXAgfCB1bmRlZmluZWQ7XG4gICAgY29uc3Qgb3JkZXIgPSBzbmFwc2hvdFsnc2hlZXRPcmRlciddIGFzIHN0cmluZ1tdIHwgdW5kZWZpbmVkO1xuICAgIGlmICghc3R5bGVzIHx8ICFzaGVldHMpIHJldHVybiBbXTtcblxuICAgIGNvbnN0IHJlc3VsdHM6IFRfY2VsbEZvcm1hdFJlc3VsdFtdID0gW107XG4gICAgY29uc3Qgc2VlbiA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gICAgZm9yIChjb25zdCBzaGVldElkIG9mIG9yZGVyID8/IE9iamVjdC5rZXlzKHNoZWV0cykpIHtcbiAgICAgIGNvbnN0IHNoZWV0RGF0YSA9IHNoZWV0c1tzaGVldElkXTtcbiAgICAgIGlmICghc2hlZXREYXRhPy5jZWxsRGF0YSkgY29udGludWU7XG5cbiAgICAgIGNvbnN0IHNoZWV0TmFtZSA9IHNoZWV0RGF0YS5uYW1lID8/IHNoZWV0SWQ7XG4gICAgICBjb25zdCBoZWFkZXJSb3cgPSBzaGVldERhdGEuY2VsbERhdGFbJzAnXSA/PyB7fTtcblxuICAgICAgZm9yIChjb25zdCByb3dLZXkgb2YgWycxJywgJzInLCAnMyddKSB7XG4gICAgICAgIGNvbnN0IHJvdyA9IHNoZWV0RGF0YS5jZWxsRGF0YVtyb3dLZXldO1xuICAgICAgICBpZiAoIXJvdykgY29udGludWU7XG5cbiAgICAgICAgZm9yIChjb25zdCBjb2xLZXkgb2YgT2JqZWN0LmtleXMocm93KSkge1xuICAgICAgICAgIGNvbnN0IGtleSA9IGAke3NoZWV0SWR9OiR7Y29sS2V5fWA7XG4gICAgICAgICAgaWYgKHNlZW4uaGFzKGtleSkpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgY29uc3Qgc3R5bGVJZCA9IHJvd1tjb2xLZXldPy5zO1xuICAgICAgICAgIGlmICghc3R5bGVJZCkgY29udGludWU7XG5cbiAgICAgICAgICBjb25zdCBwYXR0ZXJuID0gc3R5bGVzW3N0eWxlSWRdPy5uPy5wYXR0ZXJuID8/IHN0eWxlc1tzdHlsZUlkXT8ubmY/LnBhdHRlcm47XG4gICAgICAgICAgaWYgKCFwYXR0ZXJuKSBjb250aW51ZTtcblxuICAgICAgICAgIHNlZW4uYWRkKGtleSk7XG4gICAgICAgICAgY29uc3QgY29sSW5kZXggPSBwYXJzZUludChjb2xLZXksIDEwKTtcbiAgICAgICAgICBjb25zdCBjb2xMZXR0ZXIgPSB0aGlzLnRvQ29sTGV0dGVyKGNvbEluZGV4KTtcbiAgICAgICAgICBjb25zdCBoZWFkZXJWID0gaGVhZGVyUm93W2NvbEtleV0/LnY7XG5cbiAgICAgICAgICByZXN1bHRzLnB1c2goe1xuICAgICAgICAgICAgc2hlZXQ6IHNoZWV0TmFtZSxcbiAgICAgICAgICAgIGNvbDogY29sTGV0dGVyLFxuICAgICAgICAgICAgY29sSW5kZXgsXG4gICAgICAgICAgICBoZWFkZXI6IGhlYWRlclYgPyBTdHJpbmcoaGVhZGVyVikgOiBjb2xMZXR0ZXIsXG4gICAgICAgICAgICBudW1mbXQ6IHBhdHRlcm4sXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH1cblxuICBwcml2YXRlIHRvQ29sTGV0dGVyKGluZGV4OiBudW1iZXIpOiBzdHJpbmcge1xuICAgIGxldCByZXN1bHQgPSAnJztcbiAgICBsZXQgbiA9IGluZGV4O1xuICAgIGRvIHtcbiAgICAgIHJlc3VsdCA9IFN0cmluZy5mcm9tQ2hhckNvZGUoNjUgKyAobiAlIDI2KSkgKyByZXN1bHQ7XG4gICAgICBuID0gTWF0aC5mbG9vcihuIC8gMjYpIC0gMTtcbiAgICB9IHdoaWxlIChuID49IDApO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkRW1wdHlXb3JrYm9vaygpOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiAnd29ya2Jvb2stZGVmYXVsdCcsXG4gICAgICBsb2NhbGU6IHRoaXMucmVzb2x2ZUxvY2FsZVR5cGUoKSxcbiAgICAgIG5hbWU6ICdTaGVldCcsXG4gICAgICBzaGVldE9yZGVyOiBbJ3NoZWV0MSddLFxuICAgICAgYXBwVmVyc2lvbjogJzMuMC4wLWFscGhhJyxcbiAgICAgIHNoZWV0czoge1xuICAgICAgICBzaGVldDE6IHsgaWQ6ICdzaGVldDEnLCBuYW1lOiAnU2hlZXQxJywgcm93Q291bnQ6IDMwLCBjb2x1bW5Db3VudDogMjYsIGNlbGxEYXRhOiB7fSB9LFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSByZXNvbHZlTG9jYWxlVHlwZSgpOiBMb2NhbGVUeXBlIHtcbiAgICByZXR1cm4gdGhpcy5hY3RpdmVMb2NhbGUoKSA9PT0gJ3ZpJyA/IExvY2FsZVR5cGUuVklfVk4gOiBMb2NhbGVUeXBlLkVOX1VTO1xuICB9XG5cbiAgcHJpdmF0ZSByZWdpc3RlckNvbHVtbkNsaWNrTGlzdGVuZXIoKSB7XG4gICAgY29uc3Qgd3JhcHBlciA9IHRoaXMuY29udGFpbmVyUmVmKCk/Lm5hdGl2ZUVsZW1lbnQgYXMgSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQ7XG4gICAgaWYgKCF3cmFwcGVyKSByZXR1cm47XG5cbiAgICB0aGlzLmxpc3RlbkVuYWJsZVRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmxpc3RlbkVuYWJsZWQgPSB0cnVlO1xuICAgIH0sIDYwMCk7XG5cbiAgICBjb25zdCBoYW5kbGVEYmxDbGljayA9IChldmVudDogTW91c2VFdmVudCkgPT4ge1xuICAgICAgaWYgKCF0aGlzLmxpc3RlbkVuYWJsZWQpIHJldHVybjtcbiAgICAgIGlmICgoZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50KS50YWdOYW1lICE9PSAnQ0FOVkFTJykgcmV0dXJuO1xuXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICBjb25zdCByYW5nZSA9IHRoaXMudW5pdmVyQVBJPy5nZXRBY3RpdmVXb3JrYm9vaygpPy5nZXRBY3RpdmVTaGVldCgpPy5nZXRBY3RpdmVSYW5nZSgpO1xuICAgICAgICAgIGlmICghcmFuZ2UpIHJldHVybjtcblxuICAgICAgICAgIGNvbnN0IHsgc3RhcnRSb3csIGVuZFJvdywgc3RhcnRDb2x1bW4sIHJhbmdlVHlwZSB9ID0gcmFuZ2UuZ2V0UmFuZ2UoKTtcbiAgICAgICAgICBjb25zdCBpc0NvbEhlYWRlciA9IHJhbmdlVHlwZSA9PT0gMiB8fCAoc3RhcnRSb3cgPT09IDAgJiYgZW5kUm93ID49IDI5KTtcbiAgICAgICAgICBjb25zdCBpc0ZpcnN0Um93ID0gc3RhcnRSb3cgPT09IDAgJiYgZW5kUm93ID09PSAwO1xuXG4gICAgICAgICAgaWYgKCFpc0NvbEhlYWRlciAmJiAhaXNGaXJzdFJvdykgcmV0dXJuO1xuICAgICAgICAgIHRoaXMub3V0Q29sdW1uRGJsQ2xpY2suZW1pdChzdGFydENvbHVtbik7XG4gICAgICAgIH0pO1xuICAgICAgfSwgNTApO1xuICAgIH07XG5cbiAgICB3cmFwcGVyLmFkZEV2ZW50TGlzdGVuZXIoJ2RibGNsaWNrJywgaGFuZGxlRGJsQ2xpY2spO1xuICAgIHRoaXMuY29sdW1uQ2xpY2tEaXNwb3NhYmxlID0geyBkaXNwb3NlOiAoKSA9PiB3cmFwcGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2RibGNsaWNrJywgaGFuZGxlRGJsQ2xpY2spIH07XG4gIH1cblxuICAvKipcbiAgICogTOG6r25nIG5naGUgTVVUQVRJT04gY+G7mXQgKGluc2VydC9yZW1vdmUvbW92ZSkg4oCUIG3hu6ljIG11dGF0aW9uIMSR4buDIGLhuq90IGPhuqMgdW5kby9yZWRvLCBt4buZdCBs4bqnbi90aGFvIHTDoWMuXG4gICAqIENodeG6qW4gaG/DoSB0aMOgbmggYFRfY29sdW1uU3RydWN0dXJlQ2hhbmdlYCBy4buTaSBwaMOhdCByYSBuZ2/DoGkgY2hvIGNvbnN1bWVyIHJlbWFwIG1hcHBpbmcuXG4gICAqL1xuICBwcml2YXRlIHJlZ2lzdGVyQ29sdW1uT3BMaXN0ZW5lcigpIHtcbiAgICAvLyBDT05WRU5USU9OLUVYQ0VQVDogYW55IOKAlCBGVW5pdmVyLm9uQ29tbWFuZEV4ZWN1dGVkIC8gY29tbWFuZEluZm8ga2jDtG5nIGV4cG9zZSB0cm9uZyBwdWJsaWMgdHlwZXNcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgIGNvbnN0IGFwaSA9IHRoaXMudW5pdmVyQVBJIGFzIGFueTtcbiAgICBpZiAodHlwZW9mIGFwaT8ub25Db21tYW5kRXhlY3V0ZWQgIT09ICdmdW5jdGlvbicpIHJldHVybjtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgIHRoaXMuY29sdW1uT3BEaXNwb3NhYmxlID0gYXBpLm9uQ29tbWFuZEV4ZWN1dGVkKChjb21tYW5kSW5mbzogYW55KSA9PiB7XG4gICAgICBjb25zdCBjaGFuZ2UgPSB0aGlzLnRvQ29sdW1uU3RydWN0dXJlQ2hhbmdlKGNvbW1hbmRJbmZvPy5pZCwgY29tbWFuZEluZm8/LnBhcmFtcyk7XG4gICAgICBpZiAoY2hhbmdlKSB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy5vdXRDb2x1bW5TdHJ1Y3R1cmVDaGFuZ2UuZW1pdChjaGFuZ2UpKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgdG9Db2x1bW5TdHJ1Y3R1cmVDaGFuZ2UoaWQ6IHVua25vd24sIHBhcmFtczogdW5rbm93bik6IFRfY29sdW1uU3RydWN0dXJlQ2hhbmdlIHwgbnVsbCB7XG4gICAgdHlwZSBUX3JhbmdlID0geyBzdGFydENvbHVtbjogbnVtYmVyOyBlbmRDb2x1bW46IG51bWJlciB9O1xuICAgIHR5cGUgVF9jb2xQYXJhbXMgPSB7IHN1YlVuaXRJZD86IHN0cmluZzsgcmFuZ2U/OiBUX3JhbmdlOyBzb3VyY2VSYW5nZT86IFRfcmFuZ2U7IHRhcmdldFJhbmdlPzogVF9yYW5nZSB9O1xuICAgIGNvbnN0IHAgPSBwYXJhbXMgYXMgVF9jb2xQYXJhbXMgfCB1bmRlZmluZWQ7XG4gICAgY29uc3Qgc2hlZXRJZCA9IHA/LnN1YlVuaXRJZCA/PyAnJztcblxuICAgIGlmIChpZCA9PT0gSW5zZXJ0Q29sTXV0YXRpb24uaWQgfHwgaWQgPT09IFJlbW92ZUNvbE11dGF0aW9uLmlkKSB7XG4gICAgICBpZiAoIXA/LnJhbmdlKSByZXR1cm4gbnVsbDtcbiAgICAgIGNvbnN0IHR5cGUgPSBpZCA9PT0gSW5zZXJ0Q29sTXV0YXRpb24uaWQgPyAnaW5zZXJ0JyA6ICdyZW1vdmUnO1xuICAgICAgcmV0dXJuIHsgc2hlZXRJZCwgdHlwZSwgc3RhcnRDb2x1bW46IHAucmFuZ2Uuc3RhcnRDb2x1bW4sIGNvdW50OiBwLnJhbmdlLmVuZENvbHVtbiAtIHAucmFuZ2Uuc3RhcnRDb2x1bW4gKyAxIH07XG4gICAgfVxuICAgIGlmIChpZCA9PT0gTW92ZUNvbHNNdXRhdGlvbi5pZCkge1xuICAgICAgaWYgKCFwPy5zb3VyY2VSYW5nZSB8fCAhcD8udGFyZ2V0UmFuZ2UpIHJldHVybiBudWxsO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc2hlZXRJZCxcbiAgICAgICAgdHlwZTogJ21vdmUnLFxuICAgICAgICBzdGFydENvbHVtbjogcC5zb3VyY2VSYW5nZS5zdGFydENvbHVtbixcbiAgICAgICAgY291bnQ6IHAuc291cmNlUmFuZ2UuZW5kQ29sdW1uIC0gcC5zb3VyY2VSYW5nZS5zdGFydENvbHVtbiArIDEsXG4gICAgICAgIHRvQ29sdW1uOiBwLnRhcmdldFJhbmdlLnN0YXJ0Q29sdW1uLFxuICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBwcml2YXRlIHJlZ2lzdGVyRm9ybWF0TGlzdGVuZXIoKSB7XG4gICAgLy8gQ09OVkVOVElPTi1FWENFUFQ6IGFueSDigJQgRlVuaXZlci5vbkNvbW1hbmRFeGVjdXRlZCAvIGNvbW1hbmRJbmZvIGtow7RuZyBleHBvc2UgdHJvbmcgcHVibGljIHR5cGVzXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICBjb25zdCBhcGkgPSB0aGlzLnVuaXZlckFQSSBhcyBhbnk7XG4gICAgaWYgKHR5cGVvZiBhcGk/Lm9uQ29tbWFuZEV4ZWN1dGVkICE9PSAnZnVuY3Rpb24nKSByZXR1cm47XG5cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgIHRoaXMuZm9ybWF0RGlzcG9zYWJsZSA9IGFwaS5vbkNvbW1hbmRFeGVjdXRlZCgoY29tbWFuZEluZm86IGFueSkgPT4ge1xuICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgaWYgKGNvbW1hbmRJbmZvPy5pZCA9PT0gJ3NoZWV0Lm9wZXJhdGlvbi5vcGVuLm51bWZtdC5wYW5lbCcpIHtcbiAgICAgICAgICB0aGlzLm51bWZtdFBhbmVsT3BlbiA9IHRydWU7XG4gICAgICAgICAgdGhpcy5udW1mbXRDb25maXJtZWQgPSBmYWxzZTsgLy8gcmVzZXQgY+G7nSDigJQgcGhpw6puIG3hu5tpIG3hurdjIMSR4buLbmggY2jGsGEgQ29uZmlybVxuICAgICAgICAgIHRoaXMubnVtZm10RGF0ZUFjdGl2ZSA9IGZhbHNlOyAvLyBjaMawYSBjaOG7jW4gVHlwZT1EYXRlIOKGkiBjaMawYSBrw61jaCBob+G6oXQgbHXhu5NuZyBjdXN0b21cbiAgICAgICAgICAvLyBMxrB1IG51bWZtdCBn4buRYyB04burbmcgw7QgxJHhu4MgQ2FuY2VsIGtow7RpIHBo4bulYyDEkcO6bmcgKHbDuW5nIGNo4buNbiBjw7MgdGjhu4Mgbmhp4buBdSBmb3JtYXQga2jDoWMgbmhhdSlcbiAgICAgICAgICB0aGlzLm9yaWdpbmFsQ2VsbEZvcm1hdHMgPSB0aGlzLmNhcHR1cmVSYW5nZU51bWZtdCh0aGlzLmxhc3RSYW5nZVNuYXBzaG90KTtcbiAgICAgICAgICAvLyBDaOG7iSBi4bqtdCBvYnNlcnZlciBraGkgcGFuZWwgbeG7nyAodHLDoW5oIGNo4bqheSBsacOqbiB04bulYyB0aGVvIG3hu41pIG11dGF0aW9uIHRvw6BuIHRyYW5nKVxuICAgICAgICAgIHRoaXMubnVtZm10T2JzZXJ2ZXI/Lm9ic2VydmUoZG9jdW1lbnQuYm9keSwgeyBjaGlsZExpc3Q6IHRydWUsIHN1YnRyZWU6IHRydWUgfSk7XG4gICAgICAgICAgLy8gUmVvcGVuOiBVbml2ZXIgaGnhu4duIGzhuqFpIHBhbmVsIGPFqSBi4bqxbmcgQ1NTIChraMO0bmcgbXV0YXRpb24pIOKGkiBvYnNlcnZlciBraMO0bmcgZmlyZS4gQ2jhu6cgxJHhu5luZ1xuICAgICAgICAgIC8vIHRo4butIGluamVjdCBzYXUgMSBuaOG7i3AgxJHhu4MgYuG6r3QgdHLGsOG7nW5nIGjhu6NwIGxpc3QgbmfDoHkgxJHDoyBz4bq1biB0cm9uZyBET00gdMOhaSBkw7luZy5cbiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLm51bWZtdFBhbmVsT3BlbikgdGhpcy5wcm9jZXNzTnVtZm10UGFuZWwoKTtcbiAgICAgICAgICB9LCA2MCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNvbW1hbmRJbmZvPy5pZCA9PT0gJ3NoZWV0Lm9wZXJhdGlvbi5jbG9zZS5udW1mbXQucGFuZWwnKSB7XG4gICAgICAgICAgdGhpcy5udW1mbXRQYW5lbE9wZW4gPSBmYWxzZTtcbiAgICAgICAgICAvLyBU4bqvdCBvYnNlcnZlciBraGkgxJHDs25nIChwZXJmKS4gS0jDlE5HIGfhu6EgbGlzdGVuZXI6IFVuaXZlciB0w6FpIGTDuW5nIERPTSBwYW5lbCwgZ+G7oSBz4bq9IGzDoG1cbiAgICAgICAgICAvLyBvcHRpb24gY2jhur90IGtoaSBt4bufIGzhuqFpLiBjbGVhbnVwIGNo4bqheSB0csaw4bubYyBs4bqnbiBpbmplY3QgbeG7m2kgKERPTSBt4bubaSkgaG/hurdjIGtoaSBkZXN0cm95LlxuICAgICAgICAgIHRoaXMubnVtZm10T2JzZXJ2ZXI/LmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAvLyBVbml2ZXIgVMOBSSBEw5lORyBET00gcGFuZWwga2hpIHJlb3BlbiAobmjhu5sgY+G6oyBUeXBlPURhdGUpIOKGkiBndWFyZCBkYXRhLWN1c3RvbS1kYXRlcyBjw7JuIHPDs3Qgc+G6vVxuICAgICAgICAgIC8vIGNo4bq3biByZS1pbmplY3Qg4bufIGzhuqduIG3hu58gc2F1LCBraGnhur9uIGhpZ2hsaWdodCBzdGFsZSArIGRhdGVBY3RpdmU9ZmFsc2UgKG3huqV0IHJldmVydCkuIFhvw6EgZ3VhcmRcbiAgICAgICAgICAvLyDEkeG7gyBs4bqnbiBt4bufIGvhur8gdGnhur9wIGluamVjdCBs4bqhaSArIHJlc3luYyBoaWdobGlnaHQvYXV0by1hcHBseSB0aGVvIGPhu5l0IGhp4buHbiB04bqhaS5cbiAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcubnVtZm10LXBhbmVsIHVsLnVuaXZlci1zZWxlY3QtbGlzdCcpPy5yZW1vdmVBdHRyaWJ1dGUoJ2RhdGEtY3VzdG9tLWRhdGVzJyk7XG4gICAgICAgICAgLy8gQ2jhu4kga2hpIGLhuqVtIENPTkZJUk0gKG51bWZtdENvbmZpcm1lZD10cnVlKSBt4bubaSBHSeG7riBwYXR0ZXJuIMSRw6MgY2jhu41uIGNobyBj4bqjIHbDuW5nLlxuICAgICAgICAgIC8vIENhbmNlbCAvIFggLyBjbGljay1uZ2/DoGkgxJHhu4F1IEtIw5RORyBzZXQgY+G7nSDihpIgS0jDlEkgUEjhu6RDIG51bWZtdCBH4buQQyBU4buqTkcgw5QgKMSRw6MgY2jhu6VwIGtoaSBt4bufIHBhbmVsKS5cbiAgICAgICAgICBjb25zdCBkYXRlQWN0aXZlID0gdGhpcy5udW1mbXREYXRlQWN0aXZlO1xuICAgICAgICAgIGNvbnN0IGNvbmZpcm1lZCA9IHRoaXMubnVtZm10Q29uZmlybWVkO1xuICAgICAgICAgIGNvbnN0IHBlbmRpbmcgPSB0aGlzLnBlbmRpbmdOdW1mbXRQYXR0ZXJuO1xuICAgICAgICAgIGNvbnN0IG9yaWdpbmFsQ2VsbHMgPSB0aGlzLm9yaWdpbmFsQ2VsbEZvcm1hdHM7XG4gICAgICAgICAgdGhpcy5udW1mbXRDb25maXJtZWQgPSBmYWxzZTtcbiAgICAgICAgICB0aGlzLnBlbmRpbmdOdW1mbXRQYXR0ZXJuID0gbnVsbDtcbiAgICAgICAgICB0aGlzLm9yaWdpbmFsQ2VsbEZvcm1hdHMgPSBudWxsO1xuICAgICAgICAgIHRoaXMubnVtZm10RGF0ZUFjdGl2ZSA9IGZhbHNlO1xuXG4gICAgICAgICAgLy8gVHlwZSBraMOhYyBEYXRlIChT4buRL1Rp4buBbiB04buHLyUvVGV4dOKApikgZG8gVW5pdmVyIHThu7EgYXBwbHkvY2FuY2VsIOKGkiBLSMOUTkcgY2FuIHRoaeG7h3AsXG4gICAgICAgICAgLy8gbuG6v3Uga2jDtG5nIHPhur0gcmV2ZXJ0IG5o4bqnbSBmb3JtYXQgbcOgIHVzZXIgduG7q2Egw6FwIHF1YSBsdeG7k25nIG5hdGl2ZSBj4bunYSBVbml2ZXIuXG4gICAgICAgICAgaWYgKCFkYXRlQWN0aXZlKSB7XG4gICAgICAgICAgICB0aGlzLmNsZWFyTnVtZm10UHJldmlldygpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IHNuYXAgPSB0aGlzLmxhc3RSYW5nZVNuYXBzaG90O1xuICAgICAgICAgIGlmICghc25hcCkgcmV0dXJuO1xuXG4gICAgICAgICAgbGV0IHZhbHVlczogeyBwYXR0ZXJuOiBzdHJpbmc7IHJvdzogbnVtYmVyOyBjb2w6IG51bWJlciB9W107XG4gICAgICAgICAgaWYgKGNvbmZpcm1lZCAmJiBwZW5kaW5nKSB7XG4gICAgICAgICAgICB2YWx1ZXMgPSBbXTtcbiAgICAgICAgICAgIGZvciAobGV0IHIgPSBzbmFwLnN0YXJ0Um93OyByIDw9IE1hdGgubWluKHNuYXAuZW5kUm93LCBzbmFwLnN0YXJ0Um93ICsgNDk5KTsgcisrKSB7XG4gICAgICAgICAgICAgIGZvciAobGV0IGMgPSBzbmFwLnN0YXJ0Q29sdW1uOyBjIDw9IHNuYXAuZW5kQ29sdW1uOyBjKyspIHtcbiAgICAgICAgICAgICAgICB2YWx1ZXMucHVzaCh7IHBhdHRlcm46IHBlbmRpbmcsIHJvdzogciwgY29sOiBjIH0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmICghY29uZmlybWVkICYmIG9yaWdpbmFsQ2VsbHMpIHtcbiAgICAgICAgICAgIHZhbHVlcyA9IG9yaWdpbmFsQ2VsbHM7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCF2YWx1ZXMubGVuZ3RoKSByZXR1cm47XG4gICAgICAgICAgLy8gQ09OVkVOVElPTi1FWENFUFQ6IGFueSDigJQgRlVuaXZlci5leGVjdXRlQ29tbWFuZCBraMO0bmcgZXhwb3NlIHR5cGluZ1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAgICAgdm9pZCAodGhpcy51bml2ZXJBUEkgYXMgYW55KT8uZXhlY3V0ZUNvbW1hbmQ/Lignc2hlZXQuY29tbWFuZC5udW1mbXQuc2V0Lm51bWZtdCcsIHtcbiAgICAgICAgICAgIHVuaXRJZDogc25hcC51bml0SWQsXG4gICAgICAgICAgICBzdWJVbml0SWQ6IHNuYXAuc3ViVW5pdElkLFxuICAgICAgICAgICAgdmFsdWVzLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHRoaXMuY2xlYXJOdW1mbXRQcmV2aWV3KCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gS2hpIHBhbmVsIMSRYW5nIG3hu586IENI4buIIHVzZXIgxJHhu5VpIHbDuW5nIGNo4buNbiB0csOqbiBncmlkIChzZXQtc2VsZWN0aW9ucykgbeG7m2kgxJHGsOG7o2MgY+G6rXAgbmjhuq10IHNuYXBzaG90XG4gICAgICAgIC8vIMSR4buDIHJlLXRhcmdldCBwYW5lbCBzYW5nIGPhu5l0L2NlbGwgbeG7m2kuIENvbW1hbmQgbuG7mWkgYuG7mSBwYW5lbCAobnVtZm10LnNldCwgbXV0YXRpb27igKYpIEtIw5RORyDEkeG7pW5nIHNuYXBzaG90LlxuICAgICAgICBjb25zdCBpc1VzZXJTZWxlY3Rpb24gPSBjb21tYW5kSW5mbz8uaWQgPT09ICdzaGVldC5vcGVyYXRpb24uc2V0LXNlbGVjdGlvbnMnO1xuICAgICAgICBpZiAodGhpcy5udW1mbXRQYW5lbE9wZW4gJiYgIWlzVXNlclNlbGVjdGlvbikgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IHdiID0gdGhpcy51bml2ZXJBUEk/LmdldEFjdGl2ZVdvcmtib29rKCk7XG4gICAgICAgIGNvbnN0IHdzID0gd2I/LmdldEFjdGl2ZVNoZWV0KCk7XG4gICAgICAgIGNvbnN0IHJhbmdlID0gd3M/LmdldEFjdGl2ZVJhbmdlKCk7XG4gICAgICAgIGlmICghcmFuZ2UgfHwgIXdiIHx8ICF3cykgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IHJhbmdlRGF0YSA9IHJhbmdlLmdldFJhbmdlKCk7XG4gICAgICAgIHRoaXMuYWN0aXZlQ2VsbFJlZi5zZXQoYCR7dGhpcy50b0NvbExldHRlcihyYW5nZURhdGEuc3RhcnRDb2x1bW4pfSR7cmFuZ2VEYXRhLnN0YXJ0Um93ICsgMX1gKTtcblxuICAgICAgICAvLyBDT05WRU5USU9OLUVYQ0VQVDogYW55IOKAlCBGV29ya2Jvb2suZ2V0SWQgLyBGV29ya3NoZWV0LmdldFNoZWV0SWQgY2jGsGEgZXhwb3NlIHRyb25nIHR5cGVzXG4gICAgICAgIC8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnkgKi9cbiAgICAgICAgY29uc3Qgd2JBbnkgPSB3YiBhcyBhbnk7XG4gICAgICAgIGNvbnN0IHdzQW55ID0gd3MgYXMgYW55O1xuICAgICAgICAvKiBlc2xpbnQtZW5hYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnkgKi9cbiAgICAgICAgdGhpcy5sYXN0UmFuZ2VTbmFwc2hvdCA9IHtcbiAgICAgICAgICB1bml0SWQ6ICh3YkFueS5nZXRJZD8uKCkgPz8gd2JBbnkuZ2V0VW5pdElkPy4oKSA/PyAnJykgYXMgc3RyaW5nLFxuICAgICAgICAgIHN1YlVuaXRJZDogKHdzQW55LmdldFNoZWV0SWQ/LigpID8/IHdzQW55LmdldFVuaXRJZD8uKCkgPz8gJycpIGFzIHN0cmluZyxcbiAgICAgICAgICBzdGFydFJvdzogcmFuZ2VEYXRhLnN0YXJ0Um93LFxuICAgICAgICAgIGVuZFJvdzogcmFuZ2VEYXRhLmVuZFJvdyxcbiAgICAgICAgICBzdGFydENvbHVtbjogcmFuZ2VEYXRhLnN0YXJ0Q29sdW1uLFxuICAgICAgICAgIGVuZENvbHVtbjogcmFuZ2VEYXRhLmVuZENvbHVtbixcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBDT05WRU5USU9OLUVYQ0VQVDogYW55IOKAlCBGUmFuZ2UuZ2V0Q2VsbFN0eWxlRGF0YSBjaMawYSBleHBvc2UgdHJvbmcgdHlwZXNcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgICAgY29uc3QgcmFuZ2VBbnkgPSByYW5nZSBhcyBhbnk7XG4gICAgICAgIGNvbnN0IHN0eWxlID0gcmFuZ2VBbnkuZ2V0Q2VsbFN0eWxlRGF0YT8uKCk7XG4gICAgICAgIGNvbnN0IG51bUZtdCA9IHN0eWxlPy5uPy5wYXR0ZXJuID8/IHN0eWxlPy5uZj8ucGF0dGVybjtcbiAgICAgICAgdGhpcy5hY3RpdmVDZWxsRm9ybWF0LnNldChudW1GbXQgJiYgbnVtRm10ICE9PSAnMCcgPyBudW1GbXQgOiAnR2VuZXJhbCcpO1xuXG4gICAgICAgIC8vIFVzZXIgxJHhu5VpIHbDuW5nIGNo4buNbiBMw5pDIHBhbmVsIERhdGUgxJFhbmcgbeG7nyDihpIgdMOtY2ggbHXhu7kgbnVtZm10IGfhu5FjIGPhu6dhIHbDuW5nIG3hu5tpICjEkeG7gyBDYW5jZWxcbiAgICAgICAgLy8gcmV2ZXJ0IMSRw7puZyBt4buNaSDDtCDEkcOjIGNo4bqhbSkgcuG7k2kgxJHhu5NuZyBi4buZIGzhuqFpIHBhbmVsIChsYWJlbCArIGhpZ2hsaWdodCArIGF1dG8tYXBwbHkpIHRoZW8gY+G7mXQgbeG7m2kuXG4gICAgICAgIGlmICh0aGlzLm51bWZtdFBhbmVsT3BlbiAmJiB0aGlzLm51bWZtdERhdGVBY3RpdmUpIHtcbiAgICAgICAgICB0aGlzLm1lcmdlT3JpZ2luYWxDZWxsRm9ybWF0cyh0aGlzLmNhcHR1cmVSYW5nZU51bWZtdCh0aGlzLmxhc3RSYW5nZVNuYXBzaG90KSk7XG4gICAgICAgICAgdGhpcy5udW1mbXRSZXN5bmM/LigpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKiBH4buZcCBudW1mbXQgZ+G7kWMgY+G7p2EgdsO5bmcgduG7q2EgY2jhu41uIHbDoG8gc25hcHNob3QgcmV2ZXJ0LCBnaeG7ryBnacOhIHRy4buLIEfhu5BDIMSQ4bqmVSBUScOKTiBjaG8gbeG7l2kgw7QuICovXG4gIHByaXZhdGUgbWVyZ2VPcmlnaW5hbENlbGxGb3JtYXRzKGV4dHJhOiB7IHBhdHRlcm46IHN0cmluZzsgcm93OiBudW1iZXI7IGNvbDogbnVtYmVyIH1bXSB8IG51bGwpIHtcbiAgICBpZiAoIWV4dHJhKSByZXR1cm47XG4gICAgaWYgKCF0aGlzLm9yaWdpbmFsQ2VsbEZvcm1hdHMpIHtcbiAgICAgIHRoaXMub3JpZ2luYWxDZWxsRm9ybWF0cyA9IGV4dHJhO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBzZWVuID0gbmV3IFNldCh0aGlzLm9yaWdpbmFsQ2VsbEZvcm1hdHMubWFwKCh2KSA9PiBgJHt2LnJvd306JHt2LmNvbH1gKSk7XG4gICAgZm9yIChjb25zdCBjZWxsIG9mIGV4dHJhKSB7XG4gICAgICBpZiAoc2Vlbi5oYXMoYCR7Y2VsbC5yb3d9OiR7Y2VsbC5jb2x9YCkpIGNvbnRpbnVlO1xuICAgICAgdGhpcy5vcmlnaW5hbENlbGxGb3JtYXRzLnB1c2goY2VsbCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFhvw6EgbGl2ZS1wcmV2aWV3IG92ZXJsYXkgY+G7p2EgVW5pdmVyIG51bWZtdCBwYW5lbC5cbiAgICpcbiAgICogS2hpIHBhbmVsIG51bWZtdCBt4bufLCBgTnVtZm10Q29udHJvbGxlci5fcHJldmlld1BhdHRlcm5gIMSRxrDhu6NjIFVuaXZlciBkw7luZyDEkeG7gyB24bq9IMSRw6hcbiAgICogKHByZXZpZXcpIGzDqm4gaGnhu4NuIHRo4buLIHRo4bqtdCBj4bunYSB2w7luZyBjaOG7jW4uIFbDrCBjw6FjIG9wdGlvbiBkYXRlIGN1c3RvbSBnaGkgbnVtZm10XG4gICAqIHRy4buxYyB0aeG6v3AgdsOgbyBtb2RlbCAoa2jDtG5nIMSRaSBxdWEgcGFuZWwgZ+G7kWMgY+G7p2EgVW5pdmVyKSwgcHJldmlldyBuw6B5IGtow7RuZyBiYW8gZ2nhu51cbiAgICoga2jhu5twIG1vZGVsIOKGkiBj4buZdCBraMO0bmcgxJHhu5VpIGhp4buDbiB0aOG7iyBuZ2F5LiBTZXQgYF9wcmV2aWV3UGF0dGVybiA9IG51bGxgICsgZm9yY2UgcmUtcmVuZGVyXG4gICAqIChgX2ZvcmNlVXBkYXRlYCkgxJHhu4MgY2FudmFzIHbhur0gxJHDum5nIGdpw6EgdHLhu4sgbW9kZWwgdOG7qWMgdGjDrC5cbiAgICpcbiAgICogTnVtZm10Q29udHJvbGxlciBraMO0bmcgZXhwb3J0IGto4buPaSBgQHVuaXZlcmpzL3NoZWV0cy1udW1mbXRgIG7Dqm4gcGjhuqNpIHTDrG0gaW5zdGFuY2VcbiAgICogcXVhIGluamVjdG9yIGPhu6dhIFVuaXZlciAoY2FjaGUgbOG6oWkgc2F1IGzhuqduIMSR4bqndSkuXG4gICAqL1xuICBwcml2YXRlIGNsZWFyTnVtZm10UHJldmlldygpIHtcbiAgICBjb25zdCBjb250cm9sbGVyID0gdGhpcy5yZXNvbHZlTnVtZm10Q29udHJvbGxlcigpO1xuICAgIGlmICghY29udHJvbGxlcikgcmV0dXJuO1xuICAgIGlmIChjb250cm9sbGVyLl9wcmV2aWV3UGF0dGVybiAhPSBudWxsKSBjb250cm9sbGVyLl9wcmV2aWV3UGF0dGVybiA9IG51bGw7XG4gICAgLy8gTFXDlE4gZm9yY2UgcmUtcmVuZGVyOiBudW1mbXQgduG7q2Egw6FwIHbDoG8gbW9kZWwgY+G6p24gduG6vSBs4bqhaSBjYW52YXMgbmdheSAoa+G7gyBj4bqjIGtoaSBraMO0bmcgY8OzIHByZXZpZXcpLlxuICAgIGNvbnRyb2xsZXIuX2ZvcmNlVXBkYXRlPy4oKTtcbiAgfVxuXG4gIC8vIENPTlZFTlRJT04tRVhDRVBUOiBhbnkg4oCUIHRydXkgY+G6rXAgaW5qZWN0b3IgKyBOdW1mbXRDb250cm9sbGVyIG7hu5lpIGLhu5kgY+G7p2EgVW5pdmVyIChraMO0bmcgY8OzIHB1YmxpYyBBUEkpXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gIHByaXZhdGUgcmVzb2x2ZU51bWZtdENvbnRyb2xsZXIoKTogYW55IHtcbiAgICBpZiAodGhpcy5udW1mbXRDb250cm9sbGVyKSByZXR1cm4gdGhpcy5udW1mbXRDb250cm9sbGVyO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgY29uc3QgaW5qZWN0b3IgPSAodGhpcy51bml2ZXIgYXMgYW55KT8uX19nZXRJbmplY3Rvcj8uKCk7XG4gICAgaWYgKCFpbmplY3RvcikgcmV0dXJuIG51bGw7XG5cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgIGNvbnN0IHNjYW5NYXAgPSAobWFwOiB1bmtub3duKTogYW55ID0+IHtcbiAgICAgIGlmICghKG1hcCBpbnN0YW5jZW9mIE1hcCkpIHJldHVybiBudWxsO1xuICAgICAgZm9yIChjb25zdCB2YWx1ZSBvZiBtYXAudmFsdWVzKCkpIHtcbiAgICAgICAgY29uc3QgY2FuZGlkYXRlcyA9IEFycmF5LmlzQXJyYXkodmFsdWUpID8gdmFsdWUgOiBbdmFsdWVdO1xuICAgICAgICBmb3IgKGNvbnN0IGNhbmRpZGF0ZSBvZiBjYW5kaWRhdGVzKSB7XG4gICAgICAgICAgY29uc3QgaW5zdGFuY2UgPSBjYW5kaWRhdGU/Lmluc3RhbmNlICE9PSB1bmRlZmluZWQgPyBjYW5kaWRhdGUuaW5zdGFuY2UgOiBjYW5kaWRhdGU7XG4gICAgICAgICAgaWYgKGluc3RhbmNlICYmIHR5cGVvZiBpbnN0YW5jZSA9PT0gJ29iamVjdCcgJiYgJ19wcmV2aWV3UGF0dGVybicgaW4gaW5zdGFuY2UpIHJldHVybiBpbnN0YW5jZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcblxuICAgIC8vIEPDoWMgaW5zdGFuY2UgY+G7p2EgcmVkaSBu4bqxbSB0cm9uZyBNYXAgbOG7k25nIDEgY+G6pXAgKHZkIGluamVjdG9yLnJlc29sdmVkRGVwZW5kZW5jeUNvbGxlY3Rpb24ucmVzb2x2ZWREZXBlbmRlbmNpZXMpXG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoaW5qZWN0b3IpKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGluamVjdG9yW2tleV07XG4gICAgICBsZXQgZm91bmQgPSBzY2FuTWFwKHZhbHVlKTtcbiAgICAgIGlmICghZm91bmQgJiYgdmFsdWUgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xuICAgICAgICBmb3IgKGNvbnN0IG5lc3RlZEtleSBvZiBPYmplY3Qua2V5cyh2YWx1ZSkpIHtcbiAgICAgICAgICBmb3VuZCA9IHNjYW5NYXAodmFsdWVbbmVzdGVkS2V5XSk7XG4gICAgICAgICAgaWYgKGZvdW5kKSBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGZvdW5kKSB7XG4gICAgICAgIHRoaXMubnVtZm10Q29udHJvbGxlciA9IGZvdW5kO1xuICAgICAgICByZXR1cm4gZm91bmQ7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFThuqFvIG9ic2VydmVyIMSR4buDIGluamVjdCBvcHRpb24gbmfDoHkgY3VzdG9tICsgaGlnaGxpZ2h0IGtoaSBwYW5lbCBudW1mbXQgcmVuZGVyLlxuICAgKiBPYnNlcnZlciBDSOG7iCDEkcaw4bujYyBi4bqtdC904bqvdCB0aGVvIHbDsm5nIMSR4budaSBwYW5lbCAoeGVtIG9wZW4vY2xvc2UubnVtZm10LnBhbmVsIGhhbmRsZXIpIMSR4buDXG4gICAqIGtow7RuZyBjaOG6oXkgbGnDqm4gdOG7pWMgdGhlbyBt4buNaSBtdXRhdGlvbiBET00gdG/DoG4gdHJhbmcuXG4gICAqL1xuICBwcml2YXRlIHJlZ2lzdGVyTnVtZm10RHJvcGRvd25PYnNlcnZlcigpIHtcbiAgICB0aGlzLm51bWZtdE9ic2VydmVyID0gbmV3IE11dGF0aW9uT2JzZXJ2ZXIoKCkgPT4gdGhpcy5wcm9jZXNzTnVtZm10UGFuZWwoKSk7XG4gIH1cblxuICAvKipcbiAgICogVGjhu60gaW5qZWN0IG9wdGlvbiBuZ8OgeSBjdXN0b20gKyBoaWdobGlnaHQgY2hvIHBhbmVsIG51bWZtdCBoaeG7h24gdOG6oWkuXG4gICAqIEfhu41pIHThu6sgMiBuZ3Xhu5NuOiAoMSkgTXV0YXRpb25PYnNlcnZlciBraGkgVW5pdmVyIHJlbmRlciBsaXN0IG5nw6B5OyAoMikgdHLhu7FjIHRp4bq/cCBsw7pjIG3hu58gcGFuZWwg4oCUXG4gICAqIHbDrCBVbml2ZXIgVMOBSSBEw5lORyBET00gcGFuZWwga2hpIHJlb3BlbiAoaGnhu4duIGzhuqFpIGLhurFuZyBDU1MsIGtow7RuZyBwaMOhdCBzaW5oIG11dGF0aW9uKSBuw6puIG9ic2VydmVyXG4gICAqIGtow7RuZyBrw61jaCBob+G6oXQsIHBo4bqjaSBjaOG7pyDEkeG7mW5nIGfhu41pIMSR4buDIHJlLWluamVjdCArIHJlc3luYyB0aGVvIGPhu5l0IGhp4buHbiB04bqhaS5cbiAgICovXG4gIHByaXZhdGUgcHJvY2Vzc051bWZtdFBhbmVsKCkge1xuICAgIHN5bmNBY3RpdmVOdW1mbXRIaWdobGlnaHQoKTtcbiAgICBjb25zdCByZXN1bHQgPSBpbmplY3RDdXN0b21EYXRlRm9ybWF0cyhcbiAgICAgICAgKCkgPT4gdGhpcy5sYXN0UmFuZ2VTbmFwc2hvdCxcbiAgICAgICAgLy8gQ09OVkVOVElPTi1FWENFUFQ6IGFueSDigJQgRlVuaXZlci5leGVjdXRlQ29tbWFuZCBraMO0bmcgZXhwb3NlIHR5cGluZ1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgICAoY21kSWQsIHBhcmFtcykgPT4gdm9pZCAodGhpcy51bml2ZXJBUEkgYXMgYW55KS5leGVjdXRlQ29tbWFuZD8uKGNtZElkLCBwYXJhbXMpLFxuICAgICAgICAocGF0dGVybikgPT4ge1xuICAgICAgICAgIHRoaXMucGVuZGluZ051bWZtdFBhdHRlcm4gPSBwYXR0ZXJuO1xuICAgICAgICB9LFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgY29uc3Qgc25hcCA9IHRoaXMubGFzdFJhbmdlU25hcHNob3Q7XG4gICAgICAgICAgaWYgKCFzbmFwKSByZXR1cm4gdGhpcy5hY3RpdmVDZWxsRm9ybWF0KCk7XG4gICAgICAgICAgLy8gUXXDqXQgdsOgaSBkw7JuZyDEkeG6p3UgY+G7p2EgdsO5bmcgY2jhu41uLCBi4buPIHF1YSBoZWFkZXIvR2VuZXJhbCDEkeG7gyBs4bqleSBmb3JtYXQgxJDhuqBJIERJ4buGTiBj4bunYSBk4buvIGxp4buHdS5cbiAgICAgICAgICAvLyBLaGkgY2jhu41uIGPhuqMgY+G7mXQsIHN0YXJ0Um93ID0gMCBsw6AgaGVhZGVyICh0aMaw4budbmcgR2VuZXJhbCkg4oaSIG7hur91IGNo4buJIMSR4buNYyBkw7JuZyDEkcOzIHPhur0gaGlnaGxpZ2h0IHNhaSBvcHRpb24uXG4gICAgICAgICAgY29uc3QgbWF4U2NhbiA9IE1hdGgubWluKHNuYXAuZW5kUm93LCBzbmFwLnN0YXJ0Um93ICsgNCk7XG4gICAgICAgICAgZm9yIChsZXQgciA9IHNuYXAuc3RhcnRSb3c7IHIgPD0gbWF4U2NhbjsgcisrKSB7XG4gICAgICAgICAgICBjb25zdCBmbXQgPSB0aGlzLnJlYWRDZWxsTnVtZm10KHNuYXAuc3ViVW5pdElkLCByLCBzbmFwLnN0YXJ0Q29sdW1uKTtcbiAgICAgICAgICAgIGlmIChmbXQgIT09ICdHZW5lcmFsJykgcmV0dXJuIGZtdDtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHRoaXMuYWN0aXZlQ2VsbEZvcm1hdCgpO1xuICAgICAgICB9LFxuICAgICAgICAoKSA9PiB0aGlzLmNsZWFyTnVtZm10UHJldmlldygpLFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgLy8gR2nDoSB0cuG7iyB0aOG7sWMgY+G7p2Egw7QgxJHhuqFpIGRp4buHbiAoZMOybmcgZOG7ryBsaeG7h3UgxJHhuqd1IGPDsyBz4buRKSDihpIgbGFiZWwgb3B0aW9uIGto4bubcCBk4buvIGxp4buHdSBj4buZdC5cbiAgICAgICAgICBjb25zdCBzbmFwID0gdGhpcy5sYXN0UmFuZ2VTbmFwc2hvdDtcbiAgICAgICAgICBpZiAoIXNuYXApIHJldHVybiBudWxsO1xuICAgICAgICAgIGNvbnN0IG1heFNjYW4gPSBNYXRoLm1pbihzbmFwLmVuZFJvdywgc25hcC5zdGFydFJvdyArIDQpO1xuICAgICAgICAgIGZvciAobGV0IHIgPSBzbmFwLnN0YXJ0Um93OyByIDw9IG1heFNjYW47IHIrKykge1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLnJlYWRDZWxsVmFsdWUoc25hcC5zdWJVbml0SWQsIHIsIHNuYXAuc3RhcnRDb2x1bW4pO1xuICAgICAgICAgICAgaWYgKHZhbHVlICE9PSBudWxsKSByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9LFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5udW1mbXRDb25maXJtZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICApO1xuICAgICAgLy8gcmVzdWx0IGNo4buJIHRydXRoeSBraGkgVEjhu7BDIFPhu7AgaW5qZWN0IHRyw6puIDEgbGlzdENvbnRhaW5lciBEYXRlIG3hu5tpIChndWFyZCBkYXRhLWN1c3RvbS1kYXRlcyBjaOG6t25cbiAgICAgIC8vIGPDoWMgbOG6p24gZ+G7jWkgdGjhu6thKS4gR+G7oSBsaXN0ZW5lciBj4bunYSBs4bqnbiBpbmplY3QgdHLGsOG7m2MgdHLGsOG7m2Mga2hpIGdp4buvIGNsZWFudXAgbeG7m2kg4oaSIHRyw6FuaCB0w61jaCB04bulLlxuICAgICAgLy8gxJDhu5NuZyB0aOG7nWkgbMawdSByZXN5bmMgxJHhu4MgcmUtdGFyZ2V0IHBhbmVsIGtoaSB1c2VyIMSR4buVaSBj4buZdCwgdsOgIMSRw6FuaCBk4bqldSBsdeG7k25nIERhdGUgxJFhbmcgaG/huqF0IMSR4buZbmcuXG4gICAgaWYgKHJlc3VsdCkge1xuICAgICAgdGhpcy5udW1mbXRDbGVhbnVwPy4oKTtcbiAgICAgIHRoaXMubnVtZm10Q2xlYW51cCA9IHJlc3VsdC5jbGVhbnVwO1xuICAgICAgdGhpcy5udW1mbXRSZXN5bmMgPSByZXN1bHQucmVzeW5jO1xuICAgICAgdGhpcy5udW1mbXREYXRlQWN0aXZlID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGluaXRVbml2ZXIoZGF0YTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pIHtcbiAgICBjb25zdCB3cmFwcGVyID0gdGhpcy5jb250YWluZXJSZWYoKT8ubmF0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZDtcbiAgICBpZiAoIXdyYXBwZXIpIHJldHVybjtcblxuICAgIHdyYXBwZXIucmVwbGFjZUNoaWxkcmVuKCk7XG4gICAgY29uc3QgY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgY29udGFpbmVyLnN0eWxlLmNzc1RleHQgPSAnd2lkdGg6MTAwJTtoZWlnaHQ6MTAwJSc7XG4gICAgd3JhcHBlci5hcHBlbmRDaGlsZChjb250YWluZXIpO1xuXG4gICAgY29uc3QgdW5pdmVyID0gbmV3IFVuaXZlcih7XG4gICAgICBsb2NhbGU6IHRoaXMucmVzb2x2ZUxvY2FsZVR5cGUoKSxcbiAgICAgIGxvY2FsZXM6IHtcbiAgICAgICAgW0xvY2FsZVR5cGUuRU5fVVNdOiB1bml2ZXJMb2NhbGVFbixcbiAgICAgICAgW0xvY2FsZVR5cGUuVklfVk5dOiB1bml2ZXJMb2NhbGVWaSxcbiAgICAgIH0sXG4gICAgICB0aGVtZTogZGVmYXVsdFRoZW1lLFxuICAgIH0pO1xuICAgIHRoaXMudW5pdmVyID0gdW5pdmVyO1xuXG4gICAgdW5pdmVyLnJlZ2lzdGVyUGx1Z2luKFVuaXZlclJlbmRlckVuZ2luZVBsdWdpbik7XG4gICAgdW5pdmVyLnJlZ2lzdGVyUGx1Z2luKFVuaXZlckZvcm11bGFFbmdpbmVQbHVnaW4pO1xuICAgIHVuaXZlci5yZWdpc3RlclBsdWdpbihVbml2ZXJVSVBsdWdpbiwgeyBjb250YWluZXIsIGhlYWRlcjogdGhpcy5zaG93VG9vbGJhcigpLCBmb290ZXI6IHRoaXMuc2hvd1NoZWV0VGFicygpIH0pO1xuICAgIHVuaXZlci5yZWdpc3RlclBsdWdpbihVbml2ZXJEb2NzUGx1Z2luLCB7IGhhc1Njcm9sbDogZmFsc2UgfSk7XG4gICAgdW5pdmVyLnJlZ2lzdGVyUGx1Z2luKFVuaXZlckRvY3NVSVBsdWdpbik7XG4gICAgdW5pdmVyLnJlZ2lzdGVyUGx1Z2luKFVuaXZlclNoZWV0c1BsdWdpbik7XG4gICAgdW5pdmVyLnJlZ2lzdGVyUGx1Z2luKFVuaXZlclNoZWV0c1VJUGx1Z2luLCB7IG1lbnU6IHRoaXMudG9vbGJhck1lbnVDb25maWcoKSB9KTtcbiAgICB1bml2ZXIucmVnaXN0ZXJQbHVnaW4oVW5pdmVyU2hlZXRzTnVtZm10UGx1Z2luKTtcbiAgICB1bml2ZXIucmVnaXN0ZXJQbHVnaW4oVW5pdmVyU2hlZXRzRm9ybXVsYVBsdWdpbik7XG4gICAgdW5pdmVyLnJlZ2lzdGVyUGx1Z2luKFVuaXZlclNoZWV0c0Zvcm11bGFVSVBsdWdpbik7XG4gICAgdW5pdmVyLmNyZWF0ZVVuaXQoVW5pdmVySW5zdGFuY2VUeXBlLlVOSVZFUl9TSEVFVCwgZGF0YSk7XG5cbiAgICB0aGlzLnVuaXZlckFQSSA9IEZVbml2ZXIubmV3QVBJKHVuaXZlcik7XG4gICAgaWYgKHRoaXMucGVuZGluZ1JlYWR5Q2IpIHtcbiAgICAgIC8vIFdhaXQgZm9yIC5tb3JlLW51bWZtdC10eXBlIHRvIGFwcGVhciBpbiBET00g4oCUIHRoaXMgc2lnbmFscyB0aGF0IFVuaXZlclNoZWV0c1VJUGx1Z2luXG4gICAgICAvLyBoYXMgZnVsbHkgcmVuZGVyZWQgdGhlIHRvb2xiYXIgYW5kIFVuaXZlclNoZWV0c051bWZtdFBsdWdpbidzIElOdW1mbXRNb2RlbCBpcyByZWFkeS5cbiAgICAgIGNvbnN0IHdyYXBwZXIgPSB0aGlzLmNvbnRhaW5lclJlZigpPy5uYXRpdmVFbGVtZW50IGFzIEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKHdyYXBwZXIpIHtcbiAgICAgICAgdGhpcy5yZWFkeU9ic2VydmVyID0gbmV3IE11dGF0aW9uT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgICAgIGlmICghd3JhcHBlci5xdWVyeVNlbGVjdG9yKCcubW9yZS1udW1mbXQtdHlwZScpKSByZXR1cm47XG4gICAgICAgICAgdGhpcy5yZWFkeU9ic2VydmVyPy5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgdGhpcy5yZWFkeU9ic2VydmVyID0gbnVsbDtcbiAgICAgICAgICBjb25zdCBjYiA9IHRoaXMucGVuZGluZ1JlYWR5Q2I7XG4gICAgICAgICAgdGhpcy5wZW5kaW5nUmVhZHlDYiA9IG51bGw7XG4gICAgICAgICAgY2I/LigpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5yZWFkeU9ic2VydmVyLm9ic2VydmUod3JhcHBlciwgeyBjaGlsZExpc3Q6IHRydWUsIHN1YnRyZWU6IHRydWUgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMucmVnaXN0ZXJDb2x1bW5DbGlja0xpc3RlbmVyKCk7XG4gICAgdGhpcy5yZWdpc3RlckNvbHVtbk9wTGlzdGVuZXIoKTtcbiAgICB0aGlzLnJlZ2lzdGVyRm9ybWF0TGlzdGVuZXIoKTtcbiAgICB0aGlzLnJlZ2lzdGVyTnVtZm10RHJvcGRvd25PYnNlcnZlcigpO1xuICAgIHRoaXMucmVnaXN0ZXJUb29sYmFyV2lkdGhTeW5jKCk7XG4gICAgdGhpcy5yZWdpc3Rlck51bWZtdENsaWNrSW50ZXJjZXB0b3IoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBLaOG6r2MgcGjhu6VjIGzhu5dpIHRvb2xiYXIgY29sbGFwc2Ugc2FpIChnb20gaXRlbSB2w6BvIG1lbnUg4ouuIGTDuSBjw7JuIGtob+G6o25nIHRy4bqvbmcpLlxuICAgKlxuICAgKiBVbml2ZXIgKGNvbXBvbmVudCBSaWJib24pIHF1eeG6v3QgxJHhu4tuaCBvdmVyZmxvdyBi4bqxbmcgMSBjb250YWluZXIgxJBPIG9mZi1zY3JlZW4gKGNvbiB0cuG7sWMgdGnhur9wIGPhu6dhXG4gICAqIGhlYWRlciwgcG9zaXRpb246YWJzb2x1dGUpLiBUaHXhuq10IHRvw6FuOiBgdG90YWwgPSA5MDsgY2hvIG3hu5dpIElURU0gdG90YWwgKz0gaXRlbS5jbGllbnRXaWR0aCArIDg7XG4gICAqIG7hur91IHRvdGFsID4gbWVhc3VyaW5nQ29udGFpbmVyLmNsaWVudFdpZHRoIOKGkiBjb2xsYXBzZSBpdGVtYC4gQ8O0bmcgdGjhu6ljIG7DoHkgT1ZFUi1DT1VOVCAyIGNo4buXOlxuICAgKiAgIOKAoiArOTBweCByZXNlcnZlIGNobyBuw7p0IOKLriAoY+G7mW5nIGvhu4MgY+G6oyBraGkga2jDtG5nIGPhuqduIGNvbGxhcHNlKS5cbiAgICogICDigKIgKzhweCBN4buWSSBpdGVtLCB0cm9uZyBraGkga2hv4bqjbmcgY8OhY2ggKGdhcCkgdGjhu7FjIHThur8gY2jhu4kgbuG6sW0gZ2nhu69hIGPDoWMgR1JPVVAuXG4gICAqIE7hur91IHNldCBi4buBIHLhu5luZyBjb250YWluZXIgxJFvID0gxJHDum5nIGhlYWRlclcgdGjDrCBgdG90YWxgICh2ZCA5NjEpID4gaGVhZGVyVyAodmQgOTAwKSDihpIgVW5pdmVyIHTGsOG7n25nXG4gICAqIHRyw6BuIHbDoCBnb20gaXRlbSB2w6BvIOKLriBkw7kgY29udGVudCB0aOG6rXQgY2jhu4kgfjgyOXB4IChjw7JuIH43MHB4IHRy4buRbmcpLlxuICAgKlxuICAgKiBGaXggKHRyaeG7h3QgxJHhu4MsIGtow7RuZyBwaOG7pSB0aHXhu5ljIHRpbWluZyk6IHBpbiBi4buBIHLhu5luZyBjb250YWluZXIgxJBPID0gSOG6sE5HIFPhu5AgcuG6pXQgbOG7m24gcXVhIENTUyBSVUxFIHRyb25nXG4gICAqIDEgPHN0eWxlPiByacOqbmcuIEtoaSDEkcOzIGB0b3RhbGAgY+G7p2EgVW5pdmVyIEtIw5RORyBCQU8gR0nhu5wgdsaw4bujdCDihpIgS0jDlE5HIGdvbSBpdGVtIHbDoG8g4ouuIOKGkiBsdcO0biBoaeG7g24gdGjhu4tcbiAgICogxJDhu6Ygb3B0aW9uICjEkcO6bmcgecOqdSBj4bqndSkuIFbDrCBzYW8gY2jhu41uIGPDoWNoIG7DoHkgdGhheSB2w6wga2jhu5twIHdpZHRoID0gaGVhZGVyVzpcbiAgICogICDigKIgVGh14bqtdCB0b8OhbiBVbml2ZXIgb3Zlci1jb3VudCAoOTAgcmVzZXJ2ZSDii64gKyA4cHgvaXRlbSkg4oaSIGto4bubcCBzw6F0IGhlYWRlclcgduG6q24gY29sbGFwc2Ugc2FpIGtoaSBjw7JuIGNo4buXLlxuICAgKiAgIOKAoiBSZXNpemVPYnNlcnZlciBj4bunYSBVbml2ZXIgaGF5IEvhurhUIFNUQUxFOiAxIHRyYW5zaWVudCBsw7pjIGxvYWQgKGljb24vZm9udCBsw6BtIGl0ZW0gcuG7mW5nIG5o4bqldCB0aOG7nWkpIMSR4bq3dFxuICAgKiAgICAgY29sbGFwc2VkSWRzIHLhu5NpIEtIw5RORyByZS1maXJlIOKGkiBr4bq5dCDii64gdsSpbmggdmnhu4VuIGTDuSBzYXUgxJHDsyBjw7JuIGNo4buXICjEkcO6bmcgdHJp4buHdSBjaOG7qW5nIHJlbG9hZCBsdcO0biDii64pLlxuICAgKiAgIOKAoiBTZXQgaW5saW5lIGzhuqFpIGLhu4sgUmVhY3QgcmUtcmVuZGVyIHN0cmlwIOKGkiBvc2NpbGxhdGlvbi4gQ1NTIHJ1bGUgIWltcG9ydGFudCBSZWFjdCBraMO0bmcgc3RyaXAgxJHGsOG7o2MuXG4gICAqIENvbnRhaW5lciDEkW8gduG7kW4gb2ZmLXNjcmVlbiAocG9zaXRpb246YWJzb2x1dGUsIG9wYWNpdHk6MCkgbsOqbiB3aWR0aCBraOG7lW5nIGzhu5MgaG/DoG4gdG/DoG4gdsO0IGjDrG5oLiBLaGlcbiAgICogdsO5bmcgY2jhu6lhIHF1w6EgaOG6uXAgKGhp4bq/bSB24bubaSBzcHJlYWRzaGVldCkgdG9vbGJhciBjdeG7mW4gbmdhbmcg4oCUIHhlbSBTQ1NTIGAudW5pdmVyLXRvb2xiYXJgIG92ZXJmbG93LXguXG4gICAqL1xuICBwcml2YXRlIHJlZ2lzdGVyVG9vbGJhcldpZHRoU3luYygpIHtcbiAgICBjb25zdCB3cmFwcGVyID0gdGhpcy5jb250YWluZXJSZWYoKT8ubmF0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZDtcbiAgICBpZiAoIXdyYXBwZXIpIHJldHVybjtcbiAgICB3cmFwcGVyLmNsYXNzTGlzdC5hZGQodGhpcy50b29sYmFyU2NvcGVDbGFzcyk7XG4gICAgY29uc3Qgc3R5bGVFbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJyk7XG4gICAgdGhpcy50b29sYmFyU3R5bGVFbCA9IHN0eWxlRWw7XG4gICAgc3R5bGVFbC50ZXh0Q29udGVudCA9IGAuJHt0aGlzLnRvb2xiYXJTY29wZUNsYXNzfSAudW5pdmVyLXdvcmtiZW5jaC1jb250YWluZXItaGVhZGVyID4gLnVuaXZlci10b29sYmFyLWNvbnRhaW5lcnt3aWR0aDoxMDAwMDBweCAhaW1wb3J0YW50O21heC13aWR0aDpub25lICFpbXBvcnRhbnQ7fWA7XG4gICAgZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChzdHlsZUVsKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVnaXN0ZXJOdW1mbXRDbGlja0ludGVyY2VwdG9yKCkge1xuICAgIGNvbnN0IGNsaWNrSGFuZGxlciA9IChlOiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgICBjb25zdCB0YXJnZXQgPSBlLnRhcmdldCBhcyBIVE1MRWxlbWVudDtcbiAgICAgIGlmICh0YXJnZXQuY2xvc2VzdCgnLm51bWZtdC1wYW5lbCcpID8/IHRhcmdldC5jbG9zZXN0KCcubW9yZS1udW1mbXQtdHlwZS1vcHRpb25zJykpIHJldHVybjtcblxuICAgICAgY29uc3QgbnVtZm10VGV4dCA9IHRhcmdldC5jbG9zZXN0KCcubW9yZS1udW1mbXQtdHlwZScpIGFzIEhUTUxFbGVtZW50IHwgbnVsbDtcbiAgICAgIGNvbnN0IG51bWZtdFNlbGVjdCA9IHRhcmdldC5jbG9zZXN0KCcudW5pdmVyLXRvb2xiYXItaXRlbS1zZWxlY3QnKSBhcyBIVE1MRWxlbWVudCB8IG51bGw7XG4gICAgICBjb25zdCBpc051bWZtdEJ0biA9IG51bWZtdFRleHQgPz8gKG51bWZtdFNlbGVjdD8ucXVlcnlTZWxlY3RvcignLm1vcmUtbnVtZm10LXR5cGUnKSA/IG51bWZtdFNlbGVjdCA6IG51bGwpO1xuXG4gICAgICBpZiAoIWlzTnVtZm10QnRuKSByZXR1cm47XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgdGhpcy5leGVjdXRlQ29tbWFuZCgnc2hlZXQub3BlcmF0aW9uLm9wZW4ubnVtZm10LnBhbmVsJywgdW5kZWZpbmVkKTtcbiAgICB9O1xuXG4gICAgZG9jdW1lbnQuYm9keS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGNsaWNrSGFuZGxlciwgdHJ1ZSk7XG4gICAgdGhpcy5udW1mbXRDbGlja0Rpc3Bvc2FibGUgPSB7IGRpc3Bvc2U6ICgpID0+IGRvY3VtZW50LmJvZHkucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xpY2snLCBjbGlja0hhbmRsZXIsIHRydWUpIH07XG4gIH1cblxuICBwcml2YXRlIGRlc3Ryb3lVbml2ZXIoKSB7XG4gICAgaWYgKHRoaXMucGVuZGluZ0luaXRUaW1lciAhPT0gbnVsbCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMucGVuZGluZ0luaXRUaW1lcik7XG4gICAgICB0aGlzLnBlbmRpbmdJbml0VGltZXIgPSBudWxsO1xuICAgIH1cbiAgICB0aGlzLmNvbHVtbkNsaWNrRGlzcG9zYWJsZT8uZGlzcG9zZSgpO1xuICAgIHRoaXMuY29sdW1uQ2xpY2tEaXNwb3NhYmxlID0gbnVsbDtcbiAgICB0aGlzLmNvbHVtbk9wRGlzcG9zYWJsZT8uZGlzcG9zZSgpO1xuICAgIHRoaXMuY29sdW1uT3BEaXNwb3NhYmxlID0gbnVsbDtcbiAgICB0aGlzLmZvcm1hdERpc3Bvc2FibGU/LmRpc3Bvc2UoKTtcbiAgICB0aGlzLmZvcm1hdERpc3Bvc2FibGUgPSBudWxsO1xuICAgIHRoaXMubnVtZm10T2JzZXJ2ZXI/LmRpc2Nvbm5lY3QoKTtcbiAgICB0aGlzLm51bWZtdE9ic2VydmVyID0gbnVsbDtcbiAgICB0aGlzLnRvb2xiYXJSZXNpemVPYnNlcnZlcj8uZGlzY29ubmVjdCgpO1xuICAgIHRoaXMudG9vbGJhclJlc2l6ZU9ic2VydmVyID0gbnVsbDtcbiAgICB0aGlzLnRvb2xiYXJTdHlsZUVsPy5yZW1vdmUoKTtcbiAgICB0aGlzLnRvb2xiYXJTdHlsZUVsID0gbnVsbDtcbiAgICB0aGlzLm51bWZtdENsaWNrRGlzcG9zYWJsZT8uZGlzcG9zZSgpO1xuICAgIHRoaXMubnVtZm10Q2xpY2tEaXNwb3NhYmxlID0gbnVsbDtcbiAgICB0aGlzLm51bWZtdENsZWFudXA/LigpO1xuICAgIHRoaXMubnVtZm10Q2xlYW51cCA9IG51bGw7XG4gICAgdGhpcy5udW1mbXRSZXN5bmMgPSBudWxsO1xuICAgIHRoaXMubnVtZm10RGF0ZUFjdGl2ZSA9IGZhbHNlO1xuICAgIHRoaXMucmVhZHlPYnNlcnZlcj8uZGlzY29ubmVjdCgpO1xuICAgIHRoaXMucmVhZHlPYnNlcnZlciA9IG51bGw7XG4gICAgdGhpcy5hY3RpdmVDZWxsRm9ybWF0LnNldCgnR2VuZXJhbCcpO1xuICAgIHRoaXMuYWN0aXZlQ2VsbFJlZi5zZXQoJycpO1xuICAgIHRoaXMubGFzdFJhbmdlU25hcHNob3QgPSBudWxsO1xuICAgIHRoaXMucGVuZGluZ051bWZtdFBhdHRlcm4gPSBudWxsO1xuICAgIHRoaXMubnVtZm10Q29uZmlybWVkID0gZmFsc2U7XG4gICAgdGhpcy5vcmlnaW5hbENlbGxGb3JtYXRzID0gbnVsbDtcbiAgICB0aGlzLm51bWZtdFBhbmVsT3BlbiA9IGZhbHNlO1xuICAgIHRoaXMubGlzdGVuRW5hYmxlZCA9IGZhbHNlO1xuICAgIGlmICh0aGlzLmxpc3RlbkVuYWJsZVRpbWVyICE9PSBudWxsKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5saXN0ZW5FbmFibGVUaW1lcik7XG4gICAgICB0aGlzLmxpc3RlbkVuYWJsZVRpbWVyID0gbnVsbDtcbiAgICB9XG4gICAgdGhpcy5udW1mbXRDb250cm9sbGVyID0gbnVsbDtcbiAgICB0aGlzLnVuaXZlcj8uZGlzcG9zZSgpO1xuICAgIHRoaXMudW5pdmVyID0gbnVsbDtcbiAgICB0aGlzLnVuaXZlckFQSSA9IG51bGw7XG4gIH1cblxuICBwcml2YXRlIHJlaW5pdFVuaXZlcigpIHtcbiAgICBjb25zdCBjdXJyZW50RGF0YSA9IHRoaXMudW5pdmVyQVBJPy5nZXRBY3RpdmVXb3JrYm9vaygpPy5zYXZlKCkgYXMgdW5rbm93biBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB8IHVuZGVmaW5lZDtcbiAgICB0aGlzLmRlc3Ryb3lVbml2ZXIoKTtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMuaW5pdFVuaXZlcihjdXJyZW50RGF0YSA/PyB0aGlzLmJ1aWxkRW1wdHlXb3JrYm9vaygpKSk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLmRlc3Ryb3lVbml2ZXIoKTtcbiAgfVxufVxuIiwiPGRpdiAjY29udGFpbmVyUmVmIGNsYXNzPVwibGlicy11aS1jb21wb25lbnRzLXNwcmVhZHNoZWV0LWNvbnRhaW5lclwiPjwvZGl2PlxuIl19
|