@yibozhang/pro-table 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/README.md +24 -0
  2. package/bundles/yibozhang-pro-table.umd.js +3110 -0
  3. package/bundles/yibozhang-pro-table.umd.js.map +1 -0
  4. package/bundles/yibozhang-pro-table.umd.min.js +2 -0
  5. package/bundles/yibozhang-pro-table.umd.min.js.map +1 -0
  6. package/esm2015/lib/components/colmuns-setting/colmuns-setting.component.js +158 -0
  7. package/esm2015/lib/components/dynamic-search-field/dynamic-search-field.component.js +101 -0
  8. package/esm2015/lib/constants.js +89 -0
  9. package/esm2015/lib/page-container/page-container.component.js +21 -0
  10. package/esm2015/lib/page-container/page-container.module.js +25 -0
  11. package/esm2015/lib/page-public/antd-form.js +734 -0
  12. package/esm2015/lib/plate-input/plate-input.component.js +155 -0
  13. package/esm2015/lib/plate-input/plate-input.module.js +26 -0
  14. package/esm2015/lib/plate-input/plate-prefix-load.service.js +41 -0
  15. package/esm2015/lib/pro-table.component.js +983 -0
  16. package/esm2015/lib/pro-table.module.js +73 -0
  17. package/esm2015/lib/table-search-bar/table-search-bar-module.js +27 -0
  18. package/esm2015/lib/table-search-bar/table-search-bar.component.js +51 -0
  19. package/esm2015/lib/tokens.js +4 -0
  20. package/esm2015/lib/type.js +2 -0
  21. package/esm2015/public-api.js +12 -0
  22. package/esm2015/yibozhang-pro-table.js +13 -0
  23. package/fesm2015/yibozhang-pro-table.js +2448 -0
  24. package/fesm2015/yibozhang-pro-table.js.map +1 -0
  25. package/lib/components/colmuns-setting/colmuns-setting.component.d.ts +35 -0
  26. package/lib/components/colmuns-setting/colmuns-setting.component.d.ts.map +1 -0
  27. package/lib/components/dynamic-search-field/dynamic-search-field.component.d.ts +22 -0
  28. package/lib/components/dynamic-search-field/dynamic-search-field.component.d.ts.map +1 -0
  29. package/lib/constants.d.ts +20 -0
  30. package/lib/constants.d.ts.map +1 -0
  31. package/lib/page-container/page-container.component.d.ts +9 -0
  32. package/lib/page-container/page-container.component.d.ts.map +1 -0
  33. package/lib/page-container/page-container.module.d.ts +3 -0
  34. package/lib/page-container/page-container.module.d.ts.map +1 -0
  35. package/lib/page-public/antd-form.d.ts +99 -0
  36. package/lib/page-public/antd-form.d.ts.map +1 -0
  37. package/lib/plate-input/plate-input.component.d.ts +31 -0
  38. package/lib/plate-input/plate-input.component.d.ts.map +1 -0
  39. package/lib/plate-input/plate-input.module.d.ts +3 -0
  40. package/lib/plate-input/plate-input.module.d.ts.map +1 -0
  41. package/lib/plate-input/plate-prefix-load.service.d.ts +13 -0
  42. package/lib/plate-input/plate-prefix-load.service.d.ts.map +1 -0
  43. package/lib/pro-table.component.d.ts +122 -0
  44. package/lib/pro-table.component.d.ts.map +1 -0
  45. package/lib/pro-table.module.d.ts +3 -0
  46. package/lib/pro-table.module.d.ts.map +1 -0
  47. package/lib/table-search-bar/table-search-bar-module.d.ts +3 -0
  48. package/lib/table-search-bar/table-search-bar-module.d.ts.map +1 -0
  49. package/lib/table-search-bar/table-search-bar.component.d.ts +15 -0
  50. package/lib/table-search-bar/table-search-bar.component.d.ts.map +1 -0
  51. package/lib/tokens.d.ts +36 -0
  52. package/lib/tokens.d.ts.map +1 -0
  53. package/lib/type.d.ts +226 -0
  54. package/lib/type.d.ts.map +1 -0
  55. package/package.json +40 -0
  56. package/public-api.d.ts +9 -0
  57. package/public-api.d.ts.map +1 -0
  58. package/src/lib/styles/custom-antd.less +114 -0
  59. package/src/lib/styles/margin.css +90 -0
  60. package/src/lib/styles/theme.less +42 -0
  61. package/yibozhang-pro-table.d.ts +13 -0
  62. package/yibozhang-pro-table.d.ts.map +1 -0
  63. package/yibozhang-pro-table.metadata.json +1 -0
@@ -0,0 +1,983 @@
1
+ import { __awaiter } from "tslib";
2
+ import { Component, ContentChild, ContentChildren, EventEmitter, Inject, Input, Optional, Output, TemplateRef, } from "@angular/core";
3
+ import { cloneDeep, hasIn, isNil, debounce, isEqual } from "lodash-es";
4
+ import { PRO_TABLE_DEFAULT_COLUMN, PRO_TABLE_DEFAULT_PROPS } from "./constants";
5
+ import { PRO_TABLE_COLUMN_REMOTE } from "./tokens";
6
+ import { isObservable } from "rxjs";
7
+ export class ProTableComponent {
8
+ constructor(columnRemote) {
9
+ this.columnRemote = columnRemote;
10
+ this.showSearchBtn = true;
11
+ this.showClearBtn = true;
12
+ this.title = null;
13
+ this.tableName = "";
14
+ this.multiRow = false;
15
+ this.columns = [];
16
+ this.showSearchBar = true;
17
+ this.showActionBar = true;
18
+ this.confirmBtnText = "查询";
19
+ this.clearBtnText = "清空";
20
+ this.labelWidth = "90px";
21
+ this.labelAlign = "right";
22
+ this.dataSource = [];
23
+ this.bordered = true;
24
+ this.outerBordered = true;
25
+ this.showPagination = true;
26
+ this.frontPagination = false;
27
+ this.scroll = null;
28
+ this.summaryData = null;
29
+ // 排序模式:local 本地排序;server 在线排序(提交给接口)
30
+ this.sortMode = "local";
31
+ this.showColumnSetting = false;
32
+ // 是否开启多列排序(默认单列)
33
+ this.multipleSort = false;
34
+ this.showCheckbox = false;
35
+ // 判断行是否禁用的函数
36
+ this.rowDisabled = () => false;
37
+ // 是否自动触发请求
38
+ this.autoTriggerRequest = true;
39
+ this.onRowClick = new EventEmitter();
40
+ this.onRowDbClick = new EventEmitter();
41
+ this.onValuesChange = new EventEmitter();
42
+ this.onResetFormBeforeReload = new EventEmitter();
43
+ this._savedSearchParams = {};
44
+ // 存储模板映射关系 - 通过字符串名称映射到模板引用
45
+ this.templateMap = new Map();
46
+ // 存储所有自定义模板的引用
47
+ this.customTemplates = new Map();
48
+ // 记录各列排序状态:'ascend' | 'descend' | null
49
+ this._sortMap = {};
50
+ // 记录多列排序的优先级(后设置的优先)
51
+ this._sortPriority = [];
52
+ // 存储每个 autoComplete 字段的防抖函数
53
+ this._autoCompleteDebounceMap = new Map();
54
+ // 仅在初始化时运行列配置预检查,避免后续调用重复触发
55
+ this._preCheckDone = false;
56
+ this._columns = [];
57
+ // 筛选表单数据存储
58
+ this._searchParams = {};
59
+ // 筛选表单list渲染数据
60
+ this._searchFiledColumns = [];
61
+ this._pageInfo = {
62
+ pageIndex: 1,
63
+ pageSize: 15,
64
+ total: 100,
65
+ pageSizeOptions: [10, 15, 20, 50, 100, 500, 1000],
66
+ };
67
+ this._loading = false;
68
+ this._selectedTableRow = null;
69
+ // 选中的行数据(用于复选框选择)
70
+ this._selectedRows = [];
71
+ // 全选状态
72
+ this._checkedAll = false;
73
+ // 半选状态(部分选中)
74
+ this._indeterminate = false;
75
+ // 远程columns
76
+ this._serverColumns = [];
77
+ // 存储 autoComplete 字段的数据源
78
+ this._autoCompleteDataSources = {};
79
+ }
80
+ fetchRemoteColumns() {
81
+ var _a;
82
+ return __awaiter(this, void 0, void 0, function* () {
83
+ if (!((_a = this.columnRemote) === null || _a === void 0 ? void 0 : _a.getCol) || !this.tableName) {
84
+ return null;
85
+ }
86
+ try {
87
+ const res = yield this.columnRemote.getCol(this.tableName, this.multiRow);
88
+ return res;
89
+ }
90
+ catch (error) {
91
+ return null;
92
+ }
93
+ });
94
+ }
95
+ persistRemoteColumns(columns) {
96
+ var _a;
97
+ return __awaiter(this, void 0, void 0, function* () {
98
+ if (!((_a = this.columnRemote) === null || _a === void 0 ? void 0 : _a.setCol) || !this.tableName) {
99
+ return null;
100
+ }
101
+ try {
102
+ const result = this.columnRemote.setCol(this.tableName, columns, this.multiRow);
103
+ if (result && isObservable(result)) {
104
+ return yield result.toPromise();
105
+ }
106
+ return result;
107
+ }
108
+ catch (error) {
109
+ return null;
110
+ }
111
+ });
112
+ }
113
+ ngOnInit() {
114
+ return __awaiter(this, void 0, void 0, function* () {
115
+ this._searchParams = {};
116
+ this.formateInnerColumns(this.columns);
117
+ yield this.setSearchParams(this.columns);
118
+ // 使用 Proxy 包装 _searchParams,拦截表单项值变化并向外发出事件
119
+ this._searchParams = this.createSearchParamsProxy(this._searchParams);
120
+ if (this.autoTriggerRequest) {
121
+ this.handleQuery();
122
+ }
123
+ this.queryDynamicColumns();
124
+ });
125
+ }
126
+ ngAfterContentInit() {
127
+ // 自动注册所有自定义模板
128
+ this.autoRegisterTemplates();
129
+ }
130
+ preCheckServerColumns() {
131
+ return __awaiter(this, void 0, void 0, function* () {
132
+ const res = yield this.fetchRemoteColumns();
133
+ if (!res)
134
+ return false;
135
+ const initColumns = this.columns
136
+ .filter((col) => !col.auxiliaryColumn)
137
+ .map((column) => {
138
+ return {
139
+ field: column.prop,
140
+ isShow: !column.hideInTable,
141
+ header: column.title,
142
+ sortName: column.sortName || null,
143
+ };
144
+ });
145
+ if (res.code === 0) {
146
+ if (!isEqual(res.data.tabColumn, initColumns)) {
147
+ const initRes = yield this.persistRemoteColumns(initColumns);
148
+ if (initRes) {
149
+ this.queryDynamicColumns();
150
+ }
151
+ return false;
152
+ }
153
+ else {
154
+ console.log("一致");
155
+ return true;
156
+ }
157
+ }
158
+ else {
159
+ return false;
160
+ }
161
+ });
162
+ }
163
+ queryDynamicColumns() {
164
+ return __awaiter(this, void 0, void 0, function* () {
165
+ if (!this.tableName || !this.columnRemote)
166
+ return;
167
+ if (!this._preCheckDone) {
168
+ const checkResult = yield this.preCheckServerColumns();
169
+ this._preCheckDone = true;
170
+ if (!checkResult)
171
+ return;
172
+ }
173
+ const res = yield this.fetchRemoteColumns();
174
+ if (!res)
175
+ return;
176
+ if (res.code === 0) {
177
+ const _tabColumn = res.data.tabColumn.map((item) => {
178
+ return {
179
+ title: item.header,
180
+ prop: item.field,
181
+ sortName: item.sortName,
182
+ hideInTable: !item.isShow,
183
+ };
184
+ });
185
+ this._serverColumns = _tabColumn;
186
+ this.updateTableColumns(_tabColumn);
187
+ }
188
+ else if (res.code === 10) {
189
+ // 如果未设置接口返回,需要默认调用一次修改函数初始化数据
190
+ const initColumns = this.columns
191
+ .filter((col) => !col.auxiliaryColumn)
192
+ .map((column) => {
193
+ return {
194
+ field: column.prop,
195
+ isShow: true,
196
+ header: column.title,
197
+ sortName: column.sortName || null,
198
+ };
199
+ });
200
+ // 调用修改接口初始化数据
201
+ const initRes = yield this.persistRemoteColumns(initColumns);
202
+ if (initRes) {
203
+ this.queryDynamicColumns();
204
+ }
205
+ }
206
+ });
207
+ }
208
+ formateInnerColumns(columns) {
209
+ this._columns = columns
210
+ .filter((item) => !item.hideInTable)
211
+ .map((item) => {
212
+ return Object.assign(Object.assign({}, PRO_TABLE_DEFAULT_COLUMN), item);
213
+ });
214
+ }
215
+ // 自动注册模板的方法
216
+ autoRegisterTemplates() {
217
+ // 获取所有需要自定义模板的列
218
+ const columnsWithCustomRender = this._columns.filter((col) => col.customRender);
219
+ if (columnsWithCustomRender.length > 0) {
220
+ // 尝试从ContentChildren中查找对应的模板
221
+ columnsWithCustomRender.forEach((column) => {
222
+ const templateName = column.customRender;
223
+ const template = this.findTemplateByName(templateName);
224
+ if (template) {
225
+ this.customTemplates.set(templateName, template);
226
+ }
227
+ else {
228
+ }
229
+ });
230
+ }
231
+ // 获取所有需要自定义label模板的列(使用原始columns,确保顺序正确)
232
+ const columnsWithCustomLabel = this.columns.filter((col) => col.customLabelRender);
233
+ if (columnsWithCustomLabel.length > 0) {
234
+ // 尝试从ContentChildren中查找对应的label模板
235
+ columnsWithCustomLabel.forEach((column) => {
236
+ const templateName = column.customLabelRender;
237
+ const template = this.findLabelTemplateByName(templateName, columnsWithCustomLabel);
238
+ if (template) {
239
+ this.customTemplates.set(templateName, template);
240
+ }
241
+ else {
242
+ }
243
+ });
244
+ }
245
+ }
246
+ // 根据名称查找模板
247
+ findTemplateByName(templateName) {
248
+ return this.getTemplateFromContent(templateName);
249
+ }
250
+ // 从ContentChildren中查找指定名称的模板
251
+ getTemplateFromContent(templateName) {
252
+ const customRenderColumns = this._columns.filter((col) => col.customRender);
253
+ const templateIndex = customRenderColumns.findIndex((col) => col.customRender === templateName);
254
+ if (templateIndex >= 0) {
255
+ // 获取所有模板,并过滤掉特殊模板(actionBar和ImgActionBar)
256
+ // 这样可以避免因为特殊模板的位置导致索引计算错误
257
+ const templates = this.allTemplates.toArray();
258
+ const customTemplates = templates.filter((tpl) => tpl !== this.actionBarTpl && tpl !== this.imgActionBarTpl);
259
+ if (templateIndex < customTemplates.length) {
260
+ const template = customTemplates[templateIndex];
261
+ return template;
262
+ }
263
+ }
264
+ console.warn(`未找到模板 ${templateName}`);
265
+ return null;
266
+ }
267
+ // 根据名称查找label模板
268
+ findLabelTemplateByName(templateName, customLabelColumns) {
269
+ const templateIndex = customLabelColumns.findIndex((col) => col.customLabelRender === templateName);
270
+ if (templateIndex >= 0) {
271
+ // 获取所有模板,并过滤掉特殊模板(actionBar和ImgActionBar)
272
+ const templates = this.allTemplates.toArray();
273
+ const customTemplates = templates.filter((tpl) => tpl !== this.actionBarTpl && tpl !== this.imgActionBarTpl);
274
+ // 计算label模板的索引:需要跳过所有的customRender模板
275
+ const customRenderColumns = this._columns.filter((col) => col.customRender);
276
+ const labelTemplateIndex = customRenderColumns.length + templateIndex;
277
+ if (labelTemplateIndex < customTemplates.length) {
278
+ const template = customTemplates[labelTemplateIndex];
279
+ return template;
280
+ }
281
+ }
282
+ console.warn(`未找到label模板 ${templateName}`);
283
+ return null;
284
+ }
285
+ // 设置筛选表单默认属性
286
+ setSearchFormDefaultProp(columns) {
287
+ columns.forEach((item) => {
288
+ if (item.valueType) {
289
+ if (item.fieldProps) {
290
+ item.fieldProps = Object.assign(Object.assign({}, PRO_TABLE_DEFAULT_PROPS[item.valueType]), item.fieldProps);
291
+ }
292
+ else {
293
+ item.fieldProps = Object.assign({}, PRO_TABLE_DEFAULT_PROPS[item.valueType]);
294
+ }
295
+ }
296
+ });
297
+ }
298
+ // 动态设置Options
299
+ setSelectRequest(columns) {
300
+ columns.map((item) => __awaiter(this, void 0, void 0, function* () {
301
+ var _a, _b;
302
+ if (item.fieldProps && hasIn(item.fieldProps, "request")) {
303
+ try {
304
+ const options = yield ((_b = (_a = item.fieldProps).request) === null || _b === void 0 ? void 0 : _b.call(_a));
305
+ item.fieldProps.options = options;
306
+ }
307
+ catch (error) {
308
+ item.fieldProps.options = [];
309
+ }
310
+ }
311
+ }));
312
+ }
313
+ setSearchParams(columns) {
314
+ return __awaiter(this, void 0, void 0, function* () {
315
+ this._searchFiledColumns = [];
316
+ columns
317
+ .filter((item) => {
318
+ const flag = !item.hideInSearch && item.valueType;
319
+ if (flag) {
320
+ this._searchFiledColumns.push(cloneDeep(item));
321
+ }
322
+ return flag;
323
+ })
324
+ .forEach((column) => {
325
+ var _a, _b, _c;
326
+ const key = ((_a = column.fieldProps) === null || _a === void 0 ? void 0 : _a.name) || column.prop;
327
+ let defaultValue = PRO_TABLE_DEFAULT_PROPS[column.valueType].value;
328
+ // 对于checkbox类型,从options中找出checked为true的项作为默认值
329
+ if (column.valueType === "checkbox") {
330
+ const checkedValues = (((_b = column.fieldProps) === null || _b === void 0 ? void 0 : _b.options) || [])
331
+ .filter((opt) => opt.checked)
332
+ .map((opt) => opt.value);
333
+ this._searchParams[key] =
334
+ checkedValues.length > 0 ? checkedValues : defaultValue;
335
+ }
336
+ else {
337
+ this._searchParams[key] = ((_c = column.fieldProps) === null || _c === void 0 ? void 0 : _c.value) || defaultValue;
338
+ }
339
+ // 初始化 autoComplete 数据源
340
+ if (column.valueType === "autoComplete") {
341
+ this._autoCompleteDataSources[key] = [];
342
+ }
343
+ });
344
+ // 根据列的 order 字段进行排序,未设置 order 的放在最后
345
+ this._searchFiledColumns.sort((a, b) => {
346
+ const aOrder = isNil(a === null || a === void 0 ? void 0 : a.order) ? Number.MAX_SAFE_INTEGER : a.order;
347
+ const bOrder = isNil(b === null || b === void 0 ? void 0 : b.order) ? Number.MAX_SAFE_INTEGER : b.order;
348
+ if (aOrder === bOrder)
349
+ return 0;
350
+ return aOrder - bOrder;
351
+ });
352
+ this.setSearchFormDefaultProp(this._searchFiledColumns);
353
+ // 并发加载所有需要异步获取的选项
354
+ this.setSelectRequest(this._searchFiledColumns);
355
+ });
356
+ }
357
+ updateTableColumns(injectColumns) {
358
+ // 1. 使用最原始的columns作为数据源,确保辅助列完全不受影响
359
+ const originalColumns = cloneDeep(this.columns);
360
+ // 2. 处理字段映射(如果提供了fields参数)
361
+ let processedInjectColumns = injectColumns;
362
+ // 3. 分离辅助列和非辅助列(使用原始数据)
363
+ const nonAuxiliaryColumns = originalColumns.filter((col) => !col.auxiliaryColumn);
364
+ // 4. 按照injectColumns的顺序重新排列非辅助列
365
+ const reorderedNonAuxiliaryColumns = [];
366
+ const remainingNonAuxiliaryColumns = [...nonAuxiliaryColumns]; // 复制一份用于查找和移除
367
+ processedInjectColumns.forEach((injectCol) => {
368
+ // 查找非辅助列中对应的下标
369
+ const existingColIndex = remainingNonAuxiliaryColumns.findIndex((col) => col.prop === injectCol.prop);
370
+ if (existingColIndex !== -1) {
371
+ // 如果找到相同列,用injectColumns中的属性覆盖原始columns中的属性
372
+ const existingCol = remainingNonAuxiliaryColumns[existingColIndex];
373
+ const updatedCol = Object.assign(Object.assign({}, existingCol), injectCol);
374
+ reorderedNonAuxiliaryColumns.push(updatedCol);
375
+ // 从剩余数组中移除,避免重复
376
+ remainingNonAuxiliaryColumns.splice(existingColIndex, 1);
377
+ }
378
+ else {
379
+ // 如果没找到对应的列,直接添加injectColumns中的列
380
+ reorderedNonAuxiliaryColumns.push(injectCol);
381
+ }
382
+ });
383
+ // 5. 处理剩余的原始columns中的非辅助列(在injectColumns中未出现的列)
384
+ // 这些列应该被隐藏(设置hideInTable为true)
385
+ remainingNonAuxiliaryColumns.forEach((remainingCol) => {
386
+ const hiddenCol = Object.assign(Object.assign({}, remainingCol), { hideInTable: true });
387
+ reorderedNonAuxiliaryColumns.push(hiddenCol);
388
+ });
389
+ // 6. 按照原始columns的顺序重新组合:保持辅助列的原始位置和属性
390
+ const finalColumns = [];
391
+ let nonAuxiliaryIndex = 0;
392
+ let auxiliaryIndex = 0;
393
+ originalColumns.forEach((originalCol) => {
394
+ if (originalCol.auxiliaryColumn) {
395
+ // 如果是辅助列,使用原始列数据,完全不进行任何修改
396
+ finalColumns.push(originalCol);
397
+ auxiliaryIndex++;
398
+ }
399
+ else {
400
+ // 如果是非辅助列,使用重新排序后的列,但保留原始列的所有属性
401
+ const reorderedCol = reorderedNonAuxiliaryColumns[nonAuxiliaryIndex];
402
+ if (reorderedCol) {
403
+ // 合并原始列和重新排序后的列,确保保留所有原始属性
404
+ const mergedCol = Object.assign(Object.assign({}, originalCol), reorderedCol);
405
+ finalColumns.push(mergedCol);
406
+ }
407
+ else {
408
+ // 如果重新排序后的列不存在,使用原始列
409
+ finalColumns.push(originalCol);
410
+ }
411
+ nonAuxiliaryIndex++;
412
+ }
413
+ });
414
+ this.formateInnerColumns(finalColumns);
415
+ }
416
+ // 通过 Proxy 监听 _searchParams 的属性变更
417
+ createSearchParamsProxy(target) {
418
+ const self = this;
419
+ const handler = {
420
+ set(obj, prop, value) {
421
+ const key = String(prop);
422
+ const oldVal = obj[key];
423
+ if (oldVal === value) {
424
+ obj[key] = value;
425
+ return true;
426
+ }
427
+ obj[key] = value;
428
+ try {
429
+ self.onValuesChange.emit({
430
+ key,
431
+ value,
432
+ params: self.getSearchParams(),
433
+ });
434
+ }
435
+ catch (e) { }
436
+ return true;
437
+ },
438
+ };
439
+ return new Proxy(target, handler);
440
+ }
441
+ clearEmptySearchParams() {
442
+ const cloneSearchParams = cloneDeep(this._searchParams);
443
+ return cloneSearchParams;
444
+ }
445
+ buildServerSortPayload() {
446
+ // 构建激活排序集合(按优先级从低到高,末尾优先)
447
+ const activeKeys = this._sortPriority.filter((k) => !!this._sortMap[k]);
448
+ if (activeKeys.length === 0)
449
+ return null;
450
+ const sorts = activeKeys.map((field) => {
451
+ // 查找对应的列配置,优先使用sortName字段
452
+ const column = this._columns.find((col) => col.prop === field);
453
+ const sortField = (column === null || column === void 0 ? void 0 : column.sortName) || field;
454
+ return {
455
+ field: sortField,
456
+ order: this._sortMap[field],
457
+ };
458
+ });
459
+ if (this.multipleSort) {
460
+ return sorts; // 以数组形式提交多列排序
461
+ }
462
+ const [first] = sorts;
463
+ return first; // 兼容单列结构 { field, order }
464
+ }
465
+ sortDataSourceInPlace() {
466
+ if (!Array.isArray(this.dataSource) || this.dataSource.length === 0)
467
+ return;
468
+ const activeKeys = this._sortPriority.filter((k) => !!this._sortMap[k]);
469
+ if (activeKeys.length === 0)
470
+ return;
471
+ // 复制一份优先级,从前到后优先级从低到高(最后设置的字段优先)
472
+ const keysInPriority = [...activeKeys];
473
+ this.dataSource.sort((a, b) => {
474
+ for (let i = keysInPriority.length - 1; i >= 0; i--) {
475
+ const field = keysInPriority[i];
476
+ const order = this._sortMap[field];
477
+ const av = a === null || a === void 0 ? void 0 : a[field];
478
+ const bv = b === null || b === void 0 ? void 0 : b[field];
479
+ const cmp = this.compareValues(av, bv);
480
+ if (cmp !== 0)
481
+ return order === "ascend" ? cmp : -cmp;
482
+ }
483
+ return 0;
484
+ });
485
+ }
486
+ compareValues(aVal, bVal) {
487
+ if (aVal == null && bVal == null)
488
+ return 0;
489
+ if (aVal == null)
490
+ return -1;
491
+ if (bVal == null)
492
+ return 1;
493
+ if (aVal instanceof Date && bVal instanceof Date) {
494
+ return aVal.getTime() - bVal.getTime();
495
+ }
496
+ if (typeof aVal === "boolean" && typeof bVal === "boolean") {
497
+ return aVal === bVal ? 0 : aVal ? 1 : -1;
498
+ }
499
+ if (typeof aVal === "number" && typeof bVal === "number") {
500
+ return aVal - bVal;
501
+ }
502
+ if (typeof aVal === "string" && typeof bVal === "string") {
503
+ return aVal.localeCompare(bVal);
504
+ }
505
+ const aNum = Number(aVal);
506
+ const bNum = Number(bVal);
507
+ if (!isNaN(aNum) && !isNaN(bNum))
508
+ return aNum - bNum;
509
+ return String(aVal).localeCompare(String(bVal));
510
+ }
511
+ // 执行 autoComplete 数据源查询(实际执行逻辑)
512
+ executeAutoCompleteDataSource(event, column) {
513
+ var _a;
514
+ const fieldKey = ((_a = column.fieldProps) === null || _a === void 0 ? void 0 : _a.name) || column.prop;
515
+ if (column.fieldProps.dataSource &&
516
+ typeof column.fieldProps.dataSource ===
517
+ "function") {
518
+ try {
519
+ const result = column.fieldProps.dataSource(event);
520
+ // 如果返回的是 Promise,处理异步结果
521
+ if (result instanceof Promise) {
522
+ result
523
+ .then((data) => {
524
+ this._autoCompleteDataSources[fieldKey] = data || [];
525
+ })
526
+ .catch((error) => {
527
+ console.error("AutoComplete dataSource error:", error);
528
+ this._autoCompleteDataSources[fieldKey] = [];
529
+ });
530
+ }
531
+ else {
532
+ // 同步返回结果
533
+ this._autoCompleteDataSources[fieldKey] = result || [];
534
+ }
535
+ }
536
+ catch (error) {
537
+ console.error("AutoComplete dataSource error:", error);
538
+ this._autoCompleteDataSources[fieldKey] = [];
539
+ }
540
+ }
541
+ }
542
+ getSearchParams(options) {
543
+ const { useSaved = false } = options || {};
544
+ const rawParams = useSaved ? this._savedSearchParams : this._searchParams;
545
+ const params = cloneDeep(rawParams || {});
546
+ return Object.assign({ params, pageInfo: {
547
+ pageIndex: this._pageInfo.pageIndex,
548
+ pageSize: this._pageInfo.pageSize,
549
+ } }, (this.sortMode === "server"
550
+ ? { sort: this.buildServerSortPayload() }
551
+ : {}));
552
+ }
553
+ reload(afterDelete) {
554
+ this.handleQuery(afterDelete);
555
+ }
556
+ setFieldsValue(fields) {
557
+ Object.keys(fields).forEach((k) => {
558
+ this._searchParams[k] = fields[k]; // 保留 Proxy,逐项赋值触发拦截
559
+ });
560
+ }
561
+ setFieldValue(key, value) {
562
+ this._searchParams[key] = value;
563
+ }
564
+ clearSelectedRow() {
565
+ this._selectedTableRow = null;
566
+ }
567
+ setColumns(columns, options) {
568
+ return __awaiter(this, void 0, void 0, function* () {
569
+ // 更新 columns 输入属性
570
+ this.columns = cloneDeep(columns);
571
+ // 重新格式化内部列
572
+ this.formateInnerColumns(this.columns);
573
+ // 重新设置搜索参数(异步操作)
574
+ // 先清空旧的搜索参数,避免旧数据残留
575
+ this._searchParams = {};
576
+ yield this.setSearchParams(this.columns);
577
+ // 重新创建 Proxy,确保表单项值变化能正常触发事件
578
+ this._searchParams = this.createSearchParamsProxy(this._searchParams);
579
+ // 重新注册模板(如果组件已经初始化完成)
580
+ if (this.allTemplates) {
581
+ this.autoRegisterTemplates();
582
+ }
583
+ // 如果设置了 reload 选项为 true,则重新查询数据
584
+ if ((options === null || options === void 0 ? void 0 : options.reload) === true) {
585
+ this.handleQuery();
586
+ }
587
+ });
588
+ }
589
+ getSelectedRowData() {
590
+ return this._selectedTableRow;
591
+ }
592
+ getCheckedRows() {
593
+ return this._selectedRows;
594
+ }
595
+ // 获取指定名称的模板
596
+ getTemplate(name) {
597
+ if (!name)
598
+ return null;
599
+ try {
600
+ // 首先从自定义模板中查找
601
+ const customTemplate = this.customTemplates.get(name);
602
+ if (customTemplate) {
603
+ return customTemplate;
604
+ }
605
+ // 然后从通用模板映射中查找
606
+ const template = this.templateMap.get(name);
607
+ if (template) {
608
+ return template;
609
+ }
610
+ return null;
611
+ }
612
+ catch (error) {
613
+ return null;
614
+ }
615
+ }
616
+ getToolTipTextValue(column, data) {
617
+ const key = column.customRender && this.getTemplate(column.customRender)
618
+ ? ""
619
+ : column.ellipsis
620
+ ? column.prop
621
+ : "";
622
+ return !key ? "" : data[key];
623
+ }
624
+ getTableRowChecked(data) {
625
+ // 启用复选框时:行高亮应与复选框选中状态一致(支持多选)
626
+ if (this.showCheckbox) {
627
+ return this.isRowChecked(data);
628
+ }
629
+ // 未启用复选框时:仍然使用单选行高亮
630
+ if (!this._selectedTableRow)
631
+ return false;
632
+ return JSON.stringify(this._selectedTableRow) === JSON.stringify(data);
633
+ }
634
+ // 检查行是否被禁用
635
+ isRowDisabled(data) {
636
+ if (!this.showCheckbox)
637
+ return false;
638
+ return this.rowDisabled ? this.rowDisabled(data) : false;
639
+ }
640
+ // 检查行是否被复选框选中
641
+ isRowChecked(data) {
642
+ if (!this.showCheckbox)
643
+ return false;
644
+ return this._selectedRows.some((row) => JSON.stringify(row) === JSON.stringify(data));
645
+ }
646
+ // 切换行的选中状态
647
+ toggleRowChecked(data, checked, event) {
648
+ if (event) {
649
+ event.stopPropagation(); // 阻止事件冒泡,避免触发行点击
650
+ }
651
+ // 如果行被禁用,不允许切换选中状态
652
+ if (this.isRowDisabled(data)) {
653
+ return;
654
+ }
655
+ const index = this._selectedRows.findIndex((row) => JSON.stringify(row) === JSON.stringify(data));
656
+ if (checked) {
657
+ // 选中
658
+ if (index === -1) {
659
+ this._selectedRows.push(data);
660
+ }
661
+ // 勾选复选框时同步设置高亮选中行
662
+ this._selectedTableRow = data;
663
+ }
664
+ else {
665
+ // 取消选中
666
+ if (index > -1) {
667
+ this._selectedRows.splice(index, 1);
668
+ }
669
+ // 若当前高亮行为该行,则取消高亮
670
+ if (this._selectedTableRow &&
671
+ JSON.stringify(this._selectedTableRow) === JSON.stringify(data)) {
672
+ this._selectedTableRow = null;
673
+ }
674
+ }
675
+ this.updateCheckAllStatus();
676
+ }
677
+ // 更新全选状态
678
+ updateCheckAllStatus() {
679
+ if (!this.showCheckbox || !Array.isArray(this.dataSource)) {
680
+ this._checkedAll = false;
681
+ this._indeterminate = false;
682
+ return;
683
+ }
684
+ // 只计算可用的行(未禁用的行)
685
+ const availableRows = this.dataSource.filter((row) => !this.isRowDisabled(row));
686
+ const checkedCount = this._selectedRows.length;
687
+ const totalCount = availableRows.length;
688
+ this._checkedAll =
689
+ totalCount > 0 && checkedCount > 0 && checkedCount === totalCount;
690
+ this._indeterminate = checkedCount > 0 && checkedCount < totalCount;
691
+ }
692
+ // 全选/取消全选
693
+ toggleCheckAll(checked, event) {
694
+ if (event) {
695
+ event.stopPropagation();
696
+ }
697
+ if (checked) {
698
+ // 全选:只选中未禁用的行
699
+ this._selectedRows = this.dataSource.filter((row) => !this.isRowDisabled(row));
700
+ // 同步设置高亮选中行为第一条可选数据
701
+ const availableRows = this._selectedRows;
702
+ this._selectedTableRow =
703
+ availableRows.length > 0 ? availableRows[0] : null;
704
+ }
705
+ else {
706
+ // 取消全选
707
+ this._selectedRows = [];
708
+ // 取消高亮
709
+ this._selectedTableRow = null;
710
+ }
711
+ this.updateCheckAllStatus();
712
+ }
713
+ // 获取选中的行数据
714
+ getSelectedRows() {
715
+ return this._selectedRows;
716
+ }
717
+ // 清空选中的行
718
+ clearSelectedRows() {
719
+ this._selectedRows = [];
720
+ this._checkedAll = false;
721
+ this._indeterminate = false;
722
+ this._selectedTableRow = null;
723
+ }
724
+ handleFieldCheckBoxChange(checkBoxOptions, key) {
725
+ this.setFieldsValue({
726
+ [key]: checkBoxOptions
727
+ .filter((item) => item.checked)
728
+ .map((item) => item.value),
729
+ });
730
+ }
731
+ handleSearch() {
732
+ this._savedSearchParams = this.clearEmptySearchParams();
733
+ this._pageInfo.pageIndex = 1;
734
+ this.handleQuery();
735
+ }
736
+ handleResetForm() {
737
+ Object.keys(this._searchParams).forEach((key) => {
738
+ const targetColumn = this._searchFiledColumns.find((item) => {
739
+ var _a;
740
+ return (((_a = item.fieldProps) === null || _a === void 0 ? void 0 : _a.name) || item.prop) === key;
741
+ });
742
+ // 对于checkbox类型,需要特殊处理默认值
743
+ if ((targetColumn === null || targetColumn === void 0 ? void 0 : targetColumn.valueType) === "checkbox") {
744
+ // 从原始columns配置中获取初始配置,以确保使用正确的默认值
745
+ const originalColumn = this.columns.find((item) => {
746
+ var _a;
747
+ return (((_a = item.fieldProps) === null || _a === void 0 ? void 0 : _a.name) || item.prop) === key;
748
+ });
749
+ // 从原始options中找出checked为true的项作为默认值
750
+ const originalFieldProps = originalColumn === null || originalColumn === void 0 ? void 0 : originalColumn.fieldProps;
751
+ const checkedValues = ((originalFieldProps === null || originalFieldProps === void 0 ? void 0 : originalFieldProps.options) || [])
752
+ .filter((opt) => opt.checked)
753
+ .map((opt) => opt.value);
754
+ const defaultValue = checkedValues.length > 0
755
+ ? checkedValues
756
+ : PRO_TABLE_DEFAULT_PROPS[targetColumn.valueType].value;
757
+ this._searchParams[key] = defaultValue;
758
+ // 根据默认值恢复options的checked状态,使用原始options的结构
759
+ const defaultValues = Array.isArray(defaultValue) ? defaultValue : [];
760
+ const originalOptions = (originalFieldProps === null || originalFieldProps === void 0 ? void 0 : originalFieldProps.options) || [];
761
+ const targetFieldProps = targetColumn.fieldProps;
762
+ targetFieldProps.options = originalOptions.map((item) => {
763
+ return Object.assign(Object.assign({}, item), { checked: defaultValues.includes(item.value) });
764
+ });
765
+ }
766
+ else {
767
+ this._searchParams[key] = (targetColumn === null || targetColumn === void 0 ? void 0 : targetColumn.fieldProps) ? (targetColumn === null || targetColumn === void 0 ? void 0 : targetColumn.fieldProps.value) ||
768
+ PRO_TABLE_DEFAULT_PROPS[targetColumn.valueType].value
769
+ : PRO_TABLE_DEFAULT_PROPS[targetColumn.valueType].value;
770
+ }
771
+ });
772
+ this._savedSearchParams = {};
773
+ this._pageInfo.pageIndex = 1;
774
+ this.onResetFormBeforeReload.emit();
775
+ this.handleQuery();
776
+ }
777
+ handlePageIndexChange(pageIndex) {
778
+ this._pageInfo.pageIndex = pageIndex;
779
+ this.handleQuery();
780
+ }
781
+ handlePageSizeChange(pageSize) {
782
+ this._pageInfo.pageSize = pageSize;
783
+ this._pageInfo.pageIndex = 1;
784
+ this.handleQuery();
785
+ }
786
+ handleQuery(afterDelete) {
787
+ return __awaiter(this, void 0, void 0, function* () {
788
+ // 删除后刷新且当前页仅剩一条记录时,若不在第一页则先回退一页
789
+ if (afterDelete &&
790
+ Array.isArray(this.dataSource) &&
791
+ this.dataSource.length === 1 &&
792
+ this._pageInfo.pageIndex > 1) {
793
+ this._pageInfo.pageIndex = this._pageInfo.pageIndex - 1;
794
+ }
795
+ this._loading = true;
796
+ if (this.request) {
797
+ try {
798
+ const result = yield this.request(Object.assign({ params: this.clearEmptySearchParams(), pageInfo: {
799
+ pageIndex: this._pageInfo.pageIndex,
800
+ pageSize: this._pageInfo.pageSize,
801
+ } }, (this.sortMode === "server"
802
+ ? { sort: this.buildServerSortPayload() }
803
+ : {})));
804
+ this.dataSource = result.data || [];
805
+ this.summaryData = result.summaryData || null;
806
+ // 本地排序模式:拿到数据后在前端排序
807
+ if (this.sortMode === "local") {
808
+ this.sortDataSourceInPlace();
809
+ }
810
+ this._pageInfo.total = result.total || 0;
811
+ // 更新全选状态
812
+ if (this.showCheckbox) {
813
+ this.updateCheckAllStatus();
814
+ }
815
+ }
816
+ catch (error) {
817
+ console.error("查询失败:", error);
818
+ this.dataSource = [];
819
+ this._pageInfo.total = 0;
820
+ this.summaryData = null;
821
+ }
822
+ finally {
823
+ this._loading = false;
824
+ this._selectedTableRow = null;
825
+ // 清空选中行(可选,根据业务需求决定是否保留跨页选中)
826
+ // this.clearSelectedRows();
827
+ }
828
+ }
829
+ else {
830
+ console.warn("未提供 _request 回调函数");
831
+ this._loading = false;
832
+ }
833
+ this.clearSelectedRows();
834
+ });
835
+ }
836
+ // 触发列排序变更
837
+ onSortChange(sortKey, sortOrder) {
838
+ // 单列排序:重置其它列;多列排序:保留其它列
839
+ if (!this.multipleSort) {
840
+ Object.keys(this._sortMap).forEach((key) => {
841
+ if (key !== sortKey)
842
+ this._sortMap[key] = null;
843
+ });
844
+ }
845
+ this._sortMap[sortKey] = sortOrder;
846
+ // 维护优先级队列:有序列且非空 -> 置于末尾;为空 -> 移除
847
+ this._sortPriority = this._sortPriority.filter((k) => k !== sortKey);
848
+ if (sortOrder) {
849
+ this._sortPriority.push(sortKey);
850
+ }
851
+ if (this.sortMode === "local") {
852
+ this.sortDataSourceInPlace();
853
+ }
854
+ else {
855
+ // 在线排序:重新请求
856
+ this.handleQuery();
857
+ }
858
+ }
859
+ getSortOrder(sortKey) {
860
+ return this._sortMap[sortKey] || null;
861
+ }
862
+ handleTableRowClick(data) {
863
+ this._selectedTableRow = data;
864
+ // 如果开启了复选框,点击行时只选中点击行(如果行未被禁用)
865
+ if (this.showCheckbox && !this.isRowDisabled(data)) {
866
+ // 先清空所有选中行
867
+ this._selectedRows = [];
868
+ // 只选中当前点击的行
869
+ this.toggleRowChecked(data, true);
870
+ }
871
+ this.onRowClick.emit(this._selectedTableRow);
872
+ }
873
+ handleTableRowDbClick(data) {
874
+ this._selectedTableRow = data;
875
+ this.onRowDbClick.emit(this._selectedTableRow);
876
+ }
877
+ handleColumnsSettingConfirm() {
878
+ this.queryDynamicColumns();
879
+ }
880
+ // 处理 autoComplete 输入事件(带防抖)
881
+ handleAutoCompleteInput(event, column) {
882
+ var _a;
883
+ const fieldKey = ((_a = column.fieldProps) === null || _a === void 0 ? void 0 : _a.name) || column.prop;
884
+ // 如果该字段还没有防抖函数,创建一个
885
+ if (!this._autoCompleteDebounceMap.has(fieldKey)) {
886
+ const debouncedFn = debounce((evt) => {
887
+ // 重新查找对应的 column,确保使用最新的配置
888
+ const currentColumn = this._searchFiledColumns.find((col) => { var _a; return (((_a = col.fieldProps) === null || _a === void 0 ? void 0 : _a.name) || col.prop) === fieldKey; });
889
+ if (currentColumn) {
890
+ this.executeAutoCompleteDataSource(evt, currentColumn);
891
+ }
892
+ }, 300); // 300ms 防抖延迟
893
+ this._autoCompleteDebounceMap.set(fieldKey, debouncedFn);
894
+ }
895
+ // 调用防抖函数
896
+ const debouncedFn = this._autoCompleteDebounceMap.get(fieldKey);
897
+ if (debouncedFn) {
898
+ debouncedFn(event);
899
+ }
900
+ }
901
+ // 获取 autoComplete 的数据源
902
+ getAutoCompleteDataSource(column) {
903
+ var _a;
904
+ const fieldKey = ((_a = column.fieldProps) === null || _a === void 0 ? void 0 : _a.name) || column.prop;
905
+ return this._autoCompleteDataSources[fieldKey] || [];
906
+ }
907
+ getFieldProps(column) {
908
+ return column.fieldProps;
909
+ }
910
+ // 获取指定名称的label模板
911
+ getLabelTemplate(name) {
912
+ if (!name)
913
+ return null;
914
+ try {
915
+ // 首先从自定义模板中查找
916
+ const customTemplate = this.customTemplates.get(name);
917
+ if (customTemplate) {
918
+ return customTemplate;
919
+ }
920
+ // 然后从通用模板映射中查找
921
+ const template = this.templateMap.get(name);
922
+ if (template) {
923
+ return template;
924
+ }
925
+ return null;
926
+ }
927
+ catch (error) {
928
+ return null;
929
+ }
930
+ }
931
+ // 获取 form-item 的动态类名
932
+ getFormItemClassName(column) {
933
+ const fieldName = this.getFieldProps(column).name || column.prop;
934
+ return `pro-table-${fieldName}-form-item`;
935
+ }
936
+ }
937
+ ProTableComponent.decorators = [
938
+ { type: Component, args: [{
939
+ selector: "app-pro-table",
940
+ template: "<app-page-container [title]=\"title\">\r\n <ng-template #header>\r\n <app-table-search-bar\r\n *ngIf=\"showSearchBar\"\r\n [labelWidth]=\"labelWidth\"\r\n [labelAlign]=\"labelAlign\"\r\n >\r\n <ng-template #leftContent>\r\n <nz-form-item\r\n *ngFor=\"let column of _searchFiledColumns\"\r\n [ngClass]=\"getFormItemClassName(column)\"\r\n >\r\n <nz-form-label *ngIf=\"!getFieldProps(column).hideLabel\" nzNoColon>\r\n <!-- \u68C0\u67E5\u662F\u5426\u6709\u81EA\u5B9A\u4E49label\u6A21\u677F -->\r\n <ng-container\r\n *ngIf=\"\r\n column.customLabelRender &&\r\n getLabelTemplate(column.customLabelRender);\r\n else defaultLabel\r\n \"\r\n >\r\n <ng-container\r\n [ngTemplateOutlet]=\"getLabelTemplate(column.customLabelRender)\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: column,\r\n column: column,\r\n fieldProps: getFieldProps(column)\r\n }\"\r\n >\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #defaultLabel>\r\n {{ getFieldProps(column).label || column.title }}\r\n </ng-template>\r\n </nz-form-label>\r\n <nz-form-control *ngIf=\"column.valueType === 'input'\">\r\n <input\r\n nz-input\r\n [name]=\"getFieldProps(column).name || column.prop\"\r\n [placeholder]=\"getFieldProps(column).placeHolder\"\r\n [disabled]=\"getFieldProps(column).disabled\"\r\n [(ngModel)]=\"\r\n _searchParams[getFieldProps(column).name || column.prop]\r\n \"\r\n />\r\n </nz-form-control>\r\n <nz-form-control *ngIf=\"column.valueType === 'inputPlate'\">\r\n <app-plate-input\r\n [name]=\"getFieldProps(column).name || column.prop\"\r\n [(ngModel)]=\"\r\n _searchParams[getFieldProps(column).name || column.prop]\r\n \"\r\n ></app-plate-input>\r\n </nz-form-control>\r\n <nz-form-control *ngIf=\"column.valueType === 'select'\">\r\n <nz-select\r\n [(ngModel)]=\"\r\n _searchParams[getFieldProps(column).name || column.prop]\r\n \"\r\n [nzAllowClear]=\"getFieldProps(column).allowClear\"\r\n [nzPlaceHolder]=\"getFieldProps(column).placeHolder\"\r\n [name]=\"getFieldProps(column).name || column.prop\"\r\n [nzOptions]=\"getFieldProps(column).options\"\r\n [nzDisabled]=\"getFieldProps(column).disabled\"\r\n >\r\n </nz-select>\r\n </nz-form-control>\r\n <nz-form-control *ngIf=\"column.valueType === 'selectMultiple'\">\r\n <nz-select\r\n [(ngModel)]=\"\r\n _searchParams[getFieldProps(column).name || column.prop]\r\n \"\r\n [nzAllowClear]=\"getFieldProps(column).allowClear\"\r\n [nzPlaceHolder]=\"getFieldProps(column).placeHolder\"\r\n [name]=\"getFieldProps(column).name || column.prop\"\r\n [nzOptions]=\"getFieldProps(column).options\"\r\n [nzDisabled]=\"getFieldProps(column).disabled\"\r\n nzMode=\"multiple\"\r\n >\r\n </nz-select>\r\n </nz-form-control>\r\n <nz-form-control *ngIf=\"column.valueType === 'date'\">\r\n <nz-date-picker\r\n [nzShowTime]=\"getFieldProps(column).showTime\"\r\n [nzFormat]=\"getFieldProps(column).format\"\r\n [nzPlaceHolder]=\"getFieldProps(column).placeHolder\"\r\n [nzAllowClear]=\"getFieldProps(column).allowClear\"\r\n [nzDisabled]=\"getFieldProps(column).disabled\"\r\n [(ngModel)]=\"\r\n _searchParams[getFieldProps(column).name || column.prop]\r\n \"\r\n [nzMode]=\"getFieldProps(column).mode\"\r\n ></nz-date-picker>\r\n </nz-form-control>\r\n <nz-form-control *ngIf=\"column.valueType === 'checkbox'\">\r\n <nz-checkbox-group\r\n [class]=\"\r\n getFieldProps(column).noStyle\r\n ? 'pro-table-checkboxgroup-nostyle'\r\n : ''\r\n \"\r\n [(ngModel)]=\"getFieldProps(column).options\"\r\n [nzDisabled]=\"getFieldProps(column).disabled\"\r\n (ngModelChange)=\"\r\n handleFieldCheckBoxChange(\r\n $event,\r\n getFieldProps(column).name || column.prop\r\n )\r\n \"\r\n ></nz-checkbox-group>\r\n </nz-form-control>\r\n <nz-form-control *ngIf=\"column.valueType === 'autoComplete'\">\r\n <input\r\n nz-input\r\n [(ngModel)]=\"\r\n _searchParams[getFieldProps(column)?.name || column.prop]\r\n \"\r\n (input)=\"handleAutoCompleteInput($event, column)\"\r\n [nzAutocomplete]=\"auto\"\r\n [disabled]=\"getFieldProps(column)?.disabled\"\r\n [placeholder]=\"getFieldProps(column)?.placeHolder\"\r\n />\r\n <nz-autocomplete\r\n [nzBackfill]=\"getFieldProps(column).backFill\"\r\n [nzDefaultActiveFirstOption]=\"\r\n getFieldProps(column).defaultActiveFirstOption\r\n \"\r\n [nzWidth]=\"getFieldProps(column).width\"\r\n #auto\r\n >\r\n <nz-auto-option\r\n *ngFor=\"let option of getAutoCompleteDataSource(column)\"\r\n [nzValue]=\"\r\n getFieldProps(column).returnFullData ? option : option.value\r\n \"\r\n [nzLabel]=\"option.label\"\r\n [nzDisabled]=\"option.disabled\"\r\n >\r\n {{ option.label }}\r\n </nz-auto-option>\r\n </nz-autocomplete>\r\n </nz-form-control>\r\n <nz-form-control *ngIf=\"column.valueType === 'custom'\">\r\n <app-dynamic-search-field\r\n [component]=\"getFieldProps(column).component\"\r\n [value]=\"_searchParams[getFieldProps(column).name || column.prop]\"\r\n [props]=\"getFieldProps(column)\"\r\n (valueChange)=\"\r\n setFieldValue(getFieldProps(column).name || column.prop, $event)\r\n \"\r\n ></app-dynamic-search-field>\r\n </nz-form-control>\r\n <nz-form-control *ngIf=\"column.valueType === 'inputNumber'\">\r\n <nz-input-number\r\n [style.width]=\"'100%'\"\r\n [(ngModel)]=\"\r\n _searchParams[getFieldProps(column).name || column.prop]\r\n \"\r\n [nzPlaceHolder]=\"getFieldProps(column).placeHolder\"\r\n [nzDisabled]=\"getFieldProps(column).disabled\"\r\n [nzFormatter]=\"getFieldProps(column).formatterPercent\"\r\n [nzParser]=\"getFieldProps(column).parserPercent\"\r\n ></nz-input-number>\r\n </nz-form-control>\r\n </nz-form-item>\r\n </ng-template>\r\n <ng-template #actionTextBtn>\r\n <nz-space [nzSize]=\"4\">\r\n <nz-space-item *ngIf=\"showSearchBtn\">\r\n <button nz-button nzType=\"primary\" (click)=\"handleSearch()\">\r\n {{ confirmBtnText }}\r\n </button>\r\n </nz-space-item>\r\n <nz-space-item *ngIf=\"showClearBtn\">\r\n <button nz-button (click)=\"handleResetForm()\">\r\n {{ clearBtnText }}\r\n </button>\r\n </nz-space-item>\r\n </nz-space>\r\n </ng-template>\r\n <ng-template #actionImgBtn>\r\n <nz-space>\r\n <ng-container *ngTemplateOutlet=\"imgActionBarTpl\"></ng-container>\r\n <nz-space-item class=\"setting-space-item\" *ngIf=\"showColumnSetting\">\r\n <app-colmuns-setting\r\n [columns]=\"columns\"\r\n [selectedColumns]=\"_serverColumns\"\r\n [tableName]=\"tableName\"\r\n (afterConfirm)=\"handleColumnsSettingConfirm()\"\r\n ></app-colmuns-setting>\r\n </nz-space-item>\r\n </nz-space>\r\n </ng-template>\r\n </app-table-search-bar>\r\n </ng-template>\r\n <ng-template #body>\r\n <div class=\"mb-12\">\r\n <ng-container *ngIf=\"showActionBar\">\r\n <ng-container *ngTemplateOutlet=\"actionBarTpl\"></ng-container>\r\n </ng-container>\r\n </div>\r\n <ng-container *ngIf=\"customTableRender\">\r\n <ng-container *ngTemplateOutlet=\"customTableRender\"></ng-container>\r\n </ng-container>\r\n <nz-table\r\n *ngIf=\"!customTableRender\"\r\n #basicTable\r\n nzSize=\"small\"\r\n nzShowSizeChanger\r\n [nzBordered]=\"bordered\"\r\n [nzOuterBordered]=\"outerBordered\"\r\n [nzData]=\"dataSource\"\r\n [nzPageIndex]=\"_pageInfo.pageIndex\"\r\n [nzPageSize]=\"_pageInfo.pageSize\"\r\n [nzTotal]=\"_pageInfo.total\"\r\n [nzPageSizeOptions]=\"_pageInfo.pageSizeOptions\"\r\n [nzShowPagination]=\"showPagination\"\r\n [nzShowTotal]=\"totalTemplate\"\r\n [nzLoading]=\"_loading\"\r\n [nzFrontPagination]=\"frontPagination\"\r\n [nzScroll]=\"scroll\"\r\n (nzPageIndexChange)=\"handlePageIndexChange($event)\"\r\n (nzPageSizeChange)=\"handlePageSizeChange($event)\"\r\n >\r\n <thead>\r\n <tr>\r\n <!-- \u590D\u9009\u6846\u5217\uFF08\u5F53 showCheckbox=true \u65F6\u663E\u793A\uFF09 -->\r\n <th\r\n *ngIf=\"showCheckbox\"\r\n [nzWidth]=\"'50px'\"\r\n [nzAlign]=\"'center'\"\r\n style=\"text-align: center\"\r\n >\r\n <label\r\n nz-checkbox\r\n [(ngModel)]=\"_checkedAll\"\r\n [nzIndeterminate]=\"_indeterminate\"\r\n (ngModelChange)=\"toggleCheckAll($event)\"\r\n (click)=\"$event.stopPropagation()\"\r\n ></label>\r\n </th>\r\n <th\r\n *ngFor=\"let column of _columns\"\r\n [nzWidth]=\"column.width\"\r\n [nzAlign]=\"column.align\"\r\n [nzLeft]=\"column.fixedLeft\"\r\n [nzRight]=\"column.fixedRight\"\r\n [nzShowSort]=\"!!column.sorter\"\r\n [nzSortOrder]=\"getSortOrder(column.prop)\"\r\n (nzSortOrderChange)=\"onSortChange(column.prop, $event)\"\r\n >\r\n {{ column.title }}\r\n </th>\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n <tr\r\n style=\"cursor: pointer\"\r\n *ngFor=\"let data; let i = index; of: basicTable.data\"\r\n [ngClass]=\"{\r\n 'ant-table-custom-row-selected': !!getTableRowChecked(data),\r\n 'ant-table-custom-row-even': i % 2 === 0,\r\n 'ant-table-custom-row-odd': i % 2 !== 0\r\n }\"\r\n (click)=\"handleTableRowClick(data)\"\r\n (dblclick)=\"handleTableRowDbClick(data)\"\r\n >\r\n <!-- \u590D\u9009\u6846\u5217\uFF08\u5F53 showCheckbox=true \u65F6\u663E\u793A\uFF09 -->\r\n <td\r\n *ngIf=\"showCheckbox\"\r\n [nzAlign]=\"'center'\"\r\n style=\"text-align: center\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <label\r\n nz-checkbox\r\n [ngModel]=\"isRowChecked(data)\"\r\n [nzDisabled]=\"isRowDisabled(data)\"\r\n (ngModelChange)=\"toggleRowChecked(data, $event)\"\r\n ></label>\r\n </td>\r\n <td\r\n *ngFor=\"let column of _columns\"\r\n [nzLeft]=\"column.fixedLeft\"\r\n [nzRight]=\"column.fixedRight\"\r\n [nzAlign]=\"column.align\"\r\n class=\"pro-ellipsis\"\r\n [title]=\"data[column.prop]\"\r\n >\r\n <!-- \u68C0\u67E5\u662F\u5426\u6709\u81EA\u5B9A\u4E49\u6A21\u677F -->\r\n <ng-container\r\n *ngIf=\"\r\n column.customRender && getTemplate(column.customRender);\r\n let template\r\n \"\r\n >\r\n <ng-template\r\n [ngTemplateOutlet]=\"template\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: data,\r\n data: data,\r\n column: column,\r\n index: i,\r\n pageInfo: _pageInfo\r\n }\"\r\n >\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- \u9ED8\u8BA4\u6E32\u67D3\u903B\u8F91 -->\r\n <ng-container\r\n *ngIf=\"!column.customRender || !getTemplate(column.customRender)\"\r\n >\r\n {{ data[column.prop] }}\r\n </ng-container>\r\n </td>\r\n </tr>\r\n <tr *ngIf=\"summaryData && _pageInfo.total > 0\">\r\n <!-- \u6C47\u603B\u884C\u7684\u590D\u9009\u6846\u5217\uFF08\u5F53 showCheckbox=true \u65F6\u663E\u793A\uFF0C\u4F46\u4E3A\u7A7A\uFF09 -->\r\n <td\r\n *ngIf=\"showCheckbox\"\r\n style=\"font-weight: bold; border-right: 1px solid #e8e8e8\"\r\n ></td>\r\n <td\r\n *ngFor=\"let column; let i = index; of: _columns\"\r\n [nzLeft]=\"column.fixedLeft\"\r\n [nzRight]=\"column.fixedRight\"\r\n style=\"font-weight: bold; border-right: 1px solid #e8e8e8\"\r\n [nzAlign]=\"column.align\"\r\n >\r\n <span *ngIf=\"i === 0\">\u603B\u8BA1</span>\r\n <ng-container *ngIf=\"i !== 0 && column.summary\">\r\n {{\r\n column.summary?.format\r\n ? column.summary?.format(\r\n summaryData[column.summary?.name || column.prop]\r\n )\r\n : summaryData[column.summary?.name || column.prop]\r\n }}\r\n </ng-container>\r\n </td>\r\n </tr>\r\n </tbody>\r\n <ng-template #totalTemplate let-total\r\n >\u5171 {{ _pageInfo.total }} \u6761\u8BB0\u5F55</ng-template\r\n >\r\n </nz-table>\r\n </ng-template>\r\n</app-page-container>\r\n",
941
+ styles: [".pro-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}::ng-deep .setting-space-item{margin-right:0!important}::ng-deep .pro-table-checkboxgroup-nostyle{white-space:nowrap}::ng-deep .ant-table-bordered .ant-table-container .ant-table-content .ant-table-body table{border-collapse:separate;border-spacing:0}::ng-deep .ant-table-bordered .ant-table-container .ant-table-content .ant-table-body .ant-table-tbody>tr>td{border-right:1px solid #e8e8e8!important}::ng-deep .ant-table-bordered .ant-table-container .ant-table-content .ant-table-body .ant-table-thead>tr>th{border-bottom:1px solid #e8e8e8!important;border-right:1px solid #e8e8e8!important;white-space:nowrap}::ng-deep .ant-table-bordered .ant-table-container .ant-table-content .ant-table-body .ant-table-tbody>tr>td:first-child,::ng-deep .ant-table-bordered .ant-table-container .ant-table-content .ant-table-body .ant-table-thead>tr>th:first-child{border-left:none!important}::ng-deep .ant-table-bordered .ant-table-container .ant-table-content .ant-table-body .ant-table-cell-fix-left,::ng-deep .ant-table-bordered .ant-table-container .ant-table-content .ant-table-body .ant-table-cell-fix-right,::ng-deep .ant-table-bordered .ant-table-container .ant-table-content .ant-table-header .ant-table-thead>tr>th.ant-table-cell-fix-left,::ng-deep .ant-table-bordered .ant-table-container .ant-table-content .ant-table-header .ant-table-thead>tr>th.ant-table-cell-fix-right{border-bottom:1px solid #e8e8e8!important;border-right:1px solid #e8e8e8!important}::ng-deep .ant-table-bordered .ant-table-container .ant-table-content .ant-table-header .ant-table-thead>tr>th{border-top:1px solid #e8e8e8!important}::ng-deep .ant-table-bordered .ant-table-container .ant-table-content .ant-table-body .ant-table-tbody>tr>td:last-child,::ng-deep .ant-table-bordered .ant-table-container .ant-table-content .ant-table-body .ant-table-thead>tr>th:last-child{border-right:1px solid #e8e8e8!important}::ng-deep .ant-table-bordered .ant-table-container .ant-table-content .ant-table-body .ant-table-tbody>tr:last-child>td{border-bottom:1px solid #e8e8e8!important}::ng-deep .table-search-bar-left .ant-form-item{margin-bottom:8px}"]
942
+ },] }
943
+ ];
944
+ ProTableComponent.ctorParameters = () => [
945
+ { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [PRO_TABLE_COLUMN_REMOTE,] }] }
946
+ ];
947
+ ProTableComponent.propDecorators = {
948
+ showSearchBtn: [{ type: Input }],
949
+ showClearBtn: [{ type: Input }],
950
+ title: [{ type: Input }],
951
+ tableName: [{ type: Input }],
952
+ multiRow: [{ type: Input }],
953
+ columns: [{ type: Input }],
954
+ showSearchBar: [{ type: Input }],
955
+ showActionBar: [{ type: Input }],
956
+ confirmBtnText: [{ type: Input }],
957
+ clearBtnText: [{ type: Input }],
958
+ labelWidth: [{ type: Input }],
959
+ labelAlign: [{ type: Input }],
960
+ dataSource: [{ type: Input }],
961
+ bordered: [{ type: Input }],
962
+ outerBordered: [{ type: Input }],
963
+ showPagination: [{ type: Input }],
964
+ frontPagination: [{ type: Input }],
965
+ scroll: [{ type: Input }],
966
+ request: [{ type: Input }],
967
+ summaryData: [{ type: Input }],
968
+ sortMode: [{ type: Input }],
969
+ showColumnSetting: [{ type: Input }],
970
+ multipleSort: [{ type: Input }],
971
+ showCheckbox: [{ type: Input }],
972
+ rowDisabled: [{ type: Input }],
973
+ autoTriggerRequest: [{ type: Input }],
974
+ customTableRender: [{ type: Input }],
975
+ onRowClick: [{ type: Output }],
976
+ onRowDbClick: [{ type: Output }],
977
+ onValuesChange: [{ type: Output }],
978
+ onResetFormBeforeReload: [{ type: Output }],
979
+ actionBarTpl: [{ type: ContentChild, args: ["actionBar",] }],
980
+ imgActionBarTpl: [{ type: ContentChild, args: ["ImgActionBar",] }],
981
+ allTemplates: [{ type: ContentChildren, args: [TemplateRef,] }]
982
+ };
983
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvLXRhYmxlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJEOi9wcm9qZWN0cy92cHMtZnJvbnQvRnJvbnQvRGFzUE1TV2ViL3Byb2plY3RzL3Byby10YWJsZS9zcmMvIiwic291cmNlcyI6WyJsaWIvcHJvLXRhYmxlLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUVMLFNBQVMsRUFDVCxZQUFZLEVBQ1osZUFBZSxFQUNmLFlBQVksRUFDWixNQUFNLEVBQ04sS0FBSyxFQUVMLFFBQVEsRUFDUixNQUFNLEVBRU4sV0FBVyxHQUNaLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSx1QkFBdUIsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQVdoRixPQUFPLEVBQUUsdUJBQXVCLEVBQStCLE1BQU0sVUFBVSxDQUFDO0FBQ2hGLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFPcEMsTUFBTSxPQUFPLGlCQUFpQjtJQWlJNUIsWUFHVSxZQUFnRDtRQUFoRCxpQkFBWSxHQUFaLFlBQVksQ0FBb0M7UUFuSWpELGtCQUFhLEdBQVksSUFBSSxDQUFDO1FBRTlCLGlCQUFZLEdBQVksSUFBSSxDQUFDO1FBRTdCLFVBQUssR0FBa0IsSUFBSSxDQUFDO1FBRTVCLGNBQVMsR0FBVyxFQUFFLENBQUM7UUFFdkIsYUFBUSxHQUFZLEtBQUssQ0FBQztRQUUxQixZQUFPLEdBQXFCLEVBQUUsQ0FBQztRQUUvQixrQkFBYSxHQUFZLElBQUksQ0FBQztRQUU5QixrQkFBYSxHQUFZLElBQUksQ0FBQztRQUU5QixtQkFBYyxHQUFXLElBQUksQ0FBQztRQUU5QixpQkFBWSxHQUFXLElBQUksQ0FBQztRQUU1QixlQUFVLEdBQVcsTUFBTSxDQUFDO1FBRTVCLGVB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LENBQUM7SUFFRCxxQkFBcUI7SUFDckIsb0JBQW9CLENBQUMsTUFBc0I7UUFDekMsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQztRQUNqRSxPQUFPLGFBQWEsU0FBUyxZQUFZLENBQUM7SUFDNUMsQ0FBQzs7O1lBamxDRixTQUFTLFNBQUM7Z0JBQ1QsUUFBUSxFQUFFLGVBQWU7Z0JBQ3pCLGs2Y0FBeUM7O2FBRTFDOzs7NENBbUlJLFFBQVEsWUFDUixNQUFNLFNBQUMsdUJBQXVCOzs7NEJBbEloQyxLQUFLOzJCQUVMLEtBQUs7b0JBRUwsS0FBSzt3QkFFTCxLQUFLO3VCQUVMLEtBQUs7c0JBRUwsS0FBSzs0QkFFTCxLQUFLOzRCQUVMLEtBQUs7NkJBRUwsS0FBSzsyQkFFTCxLQUFLO3lCQUVMLEtBQUs7eUJBRUwsS0FBSzt5QkFFTCxLQUFLO3VCQUVMLEtBQUs7NEJBRUwsS0FBSzs2QkFFTCxLQUFLOzhCQUVMLEtBQUs7cUJBRUwsS0FBSztzQkFFTCxLQUFLOzBCQUVMLEtBQUs7dUJBR0wsS0FBSztnQ0FFTCxLQUFLOzJCQUdMLEtBQUs7MkJBRUwsS0FBSzswQkFHTCxLQUFLO2lDQUdMLEtBQUs7Z0NBRUwsS0FBSzt5QkFFTCxNQUFNOzJCQUVOLE1BQU07NkJBRU4sTUFBTTtzQ0FFTixNQUFNOzJCQUVOLFlBQVksU0FBQyxXQUFXOzhCQUV4QixZQUFZLFNBQUMsY0FBYzsyQkFFM0IsZUFBZSxTQUFDLFdBQVciLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIEFmdGVyQ29udGVudEluaXQsXHJcbiAgQ29tcG9uZW50LFxyXG4gIENvbnRlbnRDaGlsZCxcclxuICBDb250ZW50Q2hpbGRyZW4sXHJcbiAgRXZlbnRFbWl0dGVyLFxyXG4gIEluamVjdCxcclxuICBJbnB1dCxcclxuICBPbkluaXQsXHJcbiAgT3B0aW9uYWwsXHJcbiAgT3V0cHV0LFxyXG4gIFF1ZXJ5TGlzdCxcclxuICBUZW1wbGF0ZVJlZixcclxufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xyXG5pbXBvcnQgeyBjbG9uZURlZXAsIGhhc0luLCBpc05pbCwgZGVib3VuY2UsIGlzRXF1YWwgfSBmcm9tIFwibG9kYXNoLWVzXCI7XHJcbmltcG9ydCB7IFBST19UQUJMRV9ERUZBVUxUX0NPTFVNTiwgUFJPX1RBQkxFX0RFRkFVTFRfUFJPUFMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcclxuaW1wb3J0IHtcclxuICBBdXRvQ29tcGxldGVGaWVsZFByb3BzLFxyXG4gIENoZWNrYm94RmllbGRQcm9wcyxcclxuICBPcHRpb25zVHlwZSxcclxuICBQcm9UYWJsZUNvbHVtbixcclxuICBQcm9UYWJsZVBhZ2VJbmZvLFxyXG4gIFByb1RhYmxlUmVxdWVzdFJlc3VsdCxcclxuICBQcm9UYWJsZVZhbHVlc0NoYW5nZSxcclxuICBTZWxlY3RGaWVsZFByb3BzLFxyXG59IGZyb20gXCIuL3R5cGVcIjtcclxuaW1wb3J0IHsgUFJPX1RBQkxFX0NPTFVNTl9SRU1PVEUsIFByb1RhYmxlUmVtb3RlQ29sdW1uU2VydmljZSB9IGZyb20gXCIuL3Rva2Vuc1wiO1xyXG5pbXBvcnQgeyBpc09ic2VydmFibGUgfSBmcm9tIFwicnhqc1wiO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6IFwiYXBwLXByby10YWJsZVwiLFxyXG4gIHRlbXBsYXRlVXJsOiBcIi4vcHJvLXRhYmxlLmNvbXBvbmVudC5odG1sXCIsXHJcbiAgc3R5bGVVcmxzOiBbXCIuL3Byby10YWJsZS5jb21wb25lbnQuY3NzXCJdLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgUHJvVGFibGVDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIEFmdGVyQ29udGVudEluaXQge1xyXG4gIEBJbnB1dCgpIHNob3dTZWFyY2hCdG46IGJvb2xlYW4gPSB0cnVlO1xyXG5cclxuICBASW5wdXQoKSBzaG93Q2xlYXJCdG46IGJvb2xlYW4gPSB0cnVlO1xyXG5cclxuICBASW5wdXQoKSB0aXRsZTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XHJcblxyXG4gIEBJbnB1dCgpIHRhYmxlTmFtZTogc3RyaW5nID0gXCJcIjtcclxuXHJcbiAgQElucHV0KCkgbXVsdGlSb3c6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgQElucHV0KCkgY29sdW1uczogUHJvVGFibGVDb2x1bW5bXSA9IFtdO1xyXG5cclxuICBASW5wdXQoKSBzaG93U2VhcmNoQmFyOiBib29sZWFuID0gdHJ1ZTtcclxuXHJcbiAgQElucHV0KCkgc2hvd0FjdGlvbkJhcjogYm9vbGVhbiA9IHRydWU7XHJcblxyXG4gIEBJbnB1dCgpIGNvbmZpcm1CdG5UZXh0OiBzdHJpbmcgPSBcIuafpeivolwiO1xyXG5cclxuICBASW5wdXQoKSBjbGVhckJ0blRleHQ6IHN0cmluZyA9IFwi5riF56m6XCI7XHJcblxyXG4gIEBJbnB1dCgpIGxhYmVsV2lkdGg6IHN0cmluZyA9IFwiOTBweFwiO1xyXG5cclxuICBASW5wdXQoKSBsYWJlbEFsaWduOiBzdHJpbmcgPSBcInJpZ2h0XCI7XHJcblxyXG4gIEBJbnB1dCgpIGRhdGFTb3VyY2U6IGFueVtdID0gW107XHJcblxyXG4gIEBJbnB1dCgpIGJvcmRlcmVkOiBib29sZWFuID0gdHJ1ZTtcclxuXHJcbiAgQElucHV0KCkgb3V0ZXJCb3JkZXJlZDogYm9vbGVhbiA9IHRydWU7XHJcblxyXG4gIEBJbnB1dCgpIHNob3dQYWdpbmF0aW9uOiBib29sZWFuID0gdHJ1ZTtcclxuXHJcbiAgQElucHV0KCkgZnJvbnRQYWdpbmF0aW9uOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIEBJbnB1dCgpIHNjcm9sbDogeyB4Pzogc3RyaW5nIHwgbnVtYmVyOyB5Pzogc3RyaW5nIHwgbnVtYmVyIH0gfCBudWxsID0gbnVsbFxyXG5cclxuICBASW5wdXQoKSByZXF1ZXN0OiAocGFyYW1zOiBhbnkpID0+IFByb21pc2U8UHJvVGFibGVSZXF1ZXN0UmVzdWx0PjtcclxuXHJcbiAgQElucHV0KCkgc3VtbWFyeURhdGE6IFJlY29yZDxzdHJpbmcsIGFueT4gfCBudWxsID0gbnVsbDtcclxuXHJcbiAgLy8g5o6S5bqP5qih5byP77yabG9jYWwg5pys5Zyw5o6S5bqP77ybc2VydmVyIOWcqOe6v+aOkuW6j++8iOaPkOS6pOe7meaOpeWPo++8iVxyXG4gIEBJbnB1dCgpIHNvcnRNb2RlOiBcImxvY2FsXCIgfCBcInNlcnZlclwiID0gXCJsb2NhbFwiO1xyXG5cclxuICBASW5wdXQoKSBzaG93Q29sdW1uU2V0dGluZzogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAvLyDmmK/lkKblvIDlkK/lpJrliJfmjpLluo/vvIjpu5jorqTljZXliJfvvIlcclxuICBASW5wdXQoKSBtdWx0aXBsZVNvcnQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgQElucHV0KCkgc2hvd0NoZWNrYm94OiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIC8vIOWIpOaWreihjOaYr+WQpuemgeeUqOeahOWHveaVsFxyXG4gIEBJbnB1dCgpIHJvd0Rpc2FibGVkOiAoZGF0YTogYW55KSA9PiBib29sZWFuID0gKCkgPT4gZmFsc2U7XHJcblxyXG4gIC8vIOaYr+WQpuiHquWKqOinpuWPkeivt+axglxyXG4gIEBJbnB1dCgpIGF1dG9UcmlnZ2VyUmVxdWVzdDogYm9vbGVhbiA9IHRydWU7XHJcblxyXG4gIEBJbnB1dCgpIGN1c3RvbVRhYmxlUmVuZGVyPzogVGVtcGxhdGVSZWY8YW55PjtcclxuXHJcbiAgQE91dHB1dCgpIG9uUm93Q2xpY2sgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuXHJcbiAgQE91dHB1dCgpIG9uUm93RGJDbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xyXG5cclxuICBAT3V0cHV0KCkgb25WYWx1ZXNDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPFByb1RhYmxlVmFsdWVzQ2hhbmdlPigpO1xyXG5cclxuICBAT3V0cHV0KCkgb25SZXNldEZvcm1CZWZvcmVSZWxvYWQgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuXHJcbiAgQENvbnRlbnRDaGlsZChcImFjdGlvbkJhclwiKSBhY3Rpb25CYXJUcGwhOiBUZW1wbGF0ZVJlZjxhbnk+O1xyXG5cclxuICBAQ29udGVudENoaWxkKFwiSW1nQWN0aW9uQmFyXCIpIGltZ0FjdGlvbkJhclRwbCE6IFRlbXBsYXRlUmVmPGFueT47XHJcblxyXG4gIEBDb250ZW50Q2hpbGRyZW4oVGVtcGxhdGVSZWYpIGFsbFRlbXBsYXRlcyE6IFF1ZXJ5TGlzdDxUZW1wbGF0ZVJlZjxhbnk+PjtcclxuXHJcbiAgcHJpdmF0ZSBfc2F2ZWRTZWFyY2hQYXJhbXM6IGFueSA9IHt9O1xyXG5cclxuICAvLyDlrZjlgqjmqKHmnb/mmKDlsITlhbPns7sgLSDpgJrov4flrZfnrKbkuLLlkI3np7DmmKDlsITliLDmqKHmnb/lvJXnlKhcclxuICBwcml2YXRlIHRlbXBsYXRlTWFwID0gbmV3IE1hcDxzdHJpbmcsIFRlbXBsYXRlUmVmPGFueT4+KCk7XHJcblxyXG4gIC8vIOWtmOWCqOaJgOacieiHquWumuS5ieaooeadv+eahOW8leeUqFxyXG4gIHByaXZhdGUgY3VzdG9tVGVtcGxhdGVzID0gbmV3IE1hcDxzdHJpbmcsIFRlbXBsYXRlUmVmPGFueT4+KCk7XHJcblxyXG4gIC8vIOiusOW9leWQhOWIl+aOkuW6j+eKtuaAge+8midhc2NlbmQnIHwgJ2Rlc2NlbmQnIHwgbnVsbFxyXG5cclxuICBwcml2YXRlIF9zb3J0TWFwOiBSZWNvcmQ8c3RyaW5nLCBcImFzY2VuZFwiIHwgXCJkZXNjZW5kXCIgfCBudWxsPiA9IHt9O1xyXG5cclxuICAvLyDorrDlvZXlpJrliJfmjpLluo/nmoTkvJjlhYjnuqfvvIjlkI7orr7nva7nmoTkvJjlhYjvvIlcclxuICBwcml2YXRlIF9zb3J0UHJpb3JpdHk6IHN0cmluZ1tdID0gW107XHJcblxyXG4gIC8vIOWtmOWCqOavj+S4qiBhdXRvQ29tcGxldGUg5a2X5q6155qE6Ziy5oqW5Ye95pWwXHJcbiAgcHJpdmF0ZSBfYXV0b0NvbXBsZXRlRGVib3VuY2VNYXA6IE1hcDxzdHJpbmcsIChldmVudDogRXZlbnQpID0+IHZvaWQ+ID1cclxuICAgIG5ldyBNYXAoKTtcclxuXHJcbiAgLy8g5LuF5Zyo5Yid5aeL5YyW5pe26L+Q6KGM5YiX6YWN572u6aKE5qOA5p+l77yM6YG/5YWN5ZCO57ut6LCD55So6YeN5aSN6Kem5Y+RXHJcbiAgcHJpdmF0ZSBfcHJlQ2hlY2tEb25lOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIF9jb2x1bW5zOiBQcm9UYWJsZUNvbHVtbltdID0gW107XHJcblxyXG4gIC8vIOetm+mAieihqOWNleaVsOaNruWtmOWCqFxyXG4gIF9zZWFyY2hQYXJhbXM6IGFueSA9IHt9O1xyXG5cclxuICAvLyDnrZvpgInooajljZVsaXN05riy5p+T5pWw5o2uXHJcbiAgX3NlYXJjaEZpbGVkQ29sdW1uczogUHJvVGFibGVDb2x1bW5bXSA9IFtdO1xyXG5cclxuICBfcGFnZUluZm86IFByb1RhYmxlUGFnZUluZm8gPSB7XHJcbiAgICBwYWdlSW5kZXg6IDEsXHJcbiAgICBwYWdlU2l6ZTogMTUsXHJcbiAgICB0b3RhbDogMTAwLFxyXG4gICAgcGFnZVNpemVPcHRpb25zOiBbMTAsIDE1LCAyMCwgNTAsIDEwMCwgNTAwLCAxMDAwXSxcclxuICB9O1xyXG5cclxuICBfbG9hZGluZzogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICBfc2VsZWN0ZWRUYWJsZVJvdzogYW55ID0gbnVsbDtcclxuXHJcbiAgLy8g6YCJ5Lit55qE6KGM5pWw5o2u77yI55So5LqO5aSN6YCJ5qGG6YCJ5oup77yJXHJcbiAgX3NlbGVjdGVkUm93czogYW55W10gPSBbXTtcclxuXHJcbiAgLy8g5YWo6YCJ54q25oCBXHJcbiAgX2NoZWNrZWRBbGw6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgLy8g5Y2K6YCJ54q25oCB77yI6YOo5YiG6YCJ5Lit77yJXHJcbiAgX2luZGV0ZXJtaW5hdGU6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgLy8g6L+c56iLY29sdW1uc1xyXG4gIF9zZXJ2ZXJDb2x1bW5zOiBQcm9UYWJsZUNvbHVtbltdID0gW107XHJcblxyXG4gIC8vIOWtmOWCqCBhdXRvQ29tcGxldGUg5a2X5q6155qE5pWw5o2u5rqQXHJcbiAgX2F1dG9Db21wbGV0ZURhdGFTb3VyY2VzOiBSZWNvcmQ8c3RyaW5nLCBhbnlbXT4gPSB7fTtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBAT3B0aW9uYWwoKVxyXG4gICAgQEluamVjdChQUk9fVEFCTEVfQ09MVU1OX1JFTU9URSlcclxuICAgIHByaXZhdGUgY29sdW1uUmVtb3RlOiBQcm9UYWJsZVJlbW90ZUNvbHVtblNlcnZpY2UgfCBudWxsXHJcbiAgKSB7fVxyXG5cclxuICBwcml2YXRlIGFzeW5jIGZldGNoUmVtb3RlQ29sdW1ucygpIHtcclxuICAgIGlmICghdGhpcy5jb2x1bW5SZW1vdGU/LmdldENvbCB8fCAhdGhpcy50YWJsZU5hbWUpIHtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcbiAgICB0cnkge1xyXG4gICAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLmNvbHVtblJlbW90ZS5nZXRDb2wodGhpcy50YWJsZU5hbWUsIHRoaXMubXVsdGlSb3cpO1xyXG4gICAgICByZXR1cm4gcmVzO1xyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFzeW5jIHBlcnNpc3RSZW1vdGVDb2x1bW5zKGNvbHVtbnM6IGFueVtdKSB7XHJcbiAgICBpZiAoIXRoaXMuY29sdW1uUmVtb3RlPy5zZXRDb2wgfHwgIXRoaXMudGFibGVOYW1lKSB7XHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG4gICAgdHJ5IHtcclxuICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5jb2x1bW5SZW1vdGUuc2V0Q29sKFxyXG4gICAgICAgIHRoaXMudGFibGVOYW1lLFxyXG4gICAgICAgIGNvbHVtbnMsXHJcbiAgICAgICAgdGhpcy5tdWx0aVJvd1xyXG4gICAgICApO1xyXG4gICAgICBpZiAocmVzdWx0ICYmIGlzT2JzZXJ2YWJsZShyZXN1bHQpKSB7XHJcbiAgICAgICAgcmV0dXJuIGF3YWl0IHJlc3VsdC50b1Byb21pc2UoKTtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBhc3luYyBuZ09uSW5pdCgpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIHRoaXMuX3NlYXJjaFBhcmFtcyA9IHt9O1xyXG4gICAgdGhpcy5mb3JtYXRlSW5uZXJDb2x1bW5zKHRoaXMuY29sdW1ucyk7XHJcbiAgICBhd2FpdCB0aGlzLnNldFNlYXJjaFBhcmFtcyh0aGlzLmNvbHVtbnMpO1xyXG5cclxuICAgIC8vIOS9v+eUqCBQcm94eSDljIXoo4UgX3NlYXJjaFBhcmFtc++8jOaLpuaIquihqOWNlemhueWAvOWPmOWMluW5tuWQkeWkluWPkeWHuuS6i+S7tlxyXG4gICAgdGhpcy5fc2VhcmNoUGFyYW1zID0gdGhpcy5jcmVhdGVTZWFyY2hQYXJhbXNQcm94eSh0aGlzLl9zZWFyY2hQYXJhbXMpO1xyXG4gICAgaWYgKHRoaXMuYXV0b1RyaWdnZXJSZXF1ZXN0KSB7XHJcbiAgICAgIHRoaXMuaGFuZGxlUXVlcnkoKTtcclxuICAgIH1cclxuICAgIHRoaXMucXVlcnlEeW5hbWljQ29sdW1ucygpO1xyXG4gIH1cclxuXHJcbiAgbmdBZnRlckNvbnRlbnRJbml0KCkge1xyXG4gICAgLy8g6Ieq5Yqo5rOo5YaM5omA5pyJ6Ieq5a6a5LmJ5qih5p2/XHJcbiAgICB0aGlzLmF1dG9SZWdpc3RlclRlbXBsYXRlcygpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhc3luYyBwcmVDaGVja1NlcnZlckNvbHVtbnMoKTogUHJvbWlzZTxib29sZWFuPiB7XHJcbiAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLmZldGNoUmVtb3RlQ29sdW1ucygpO1xyXG4gICAgaWYgKCFyZXMpIHJldHVybiBmYWxzZTtcclxuICAgIGNvbnN0IGluaXRDb2x1bW5zID0gdGhpcy5jb2x1bW5zXHJcbiAgICAgIC5maWx0ZXIoKGNvbCkgPT4gIWNvbC5hdXhpbGlhcnlDb2x1bW4pXHJcbiAgICAgIC5tYXAoKGNvbHVtbikgPT4ge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICBmaWVsZDogY29sdW1uLnByb3AsXHJcbiAgICAgICAgICBpc1Nob3c6ICFjb2x1bW4uaGlkZUluVGFibGUsIC8vIOm7mOiupOWFqOmDqOaYvuekulxyXG4gICAgICAgICAgaGVhZGVyOiBjb2x1bW4udGl0bGUsXHJcbiAgICAgICAgICBzb3J0TmFtZTogY29sdW1uLnNvcnROYW1lIHx8IG51bGwsXHJcbiAgICAgICAgfTtcclxuICAgICAgfSk7XHJcbiAgICBpZiAocmVzLmNvZGUgPT09IDApIHtcclxuICAgICAgaWYgKCFpc0VxdWFsKHJlcy5kYXRhLnRhYkNvbHVtbiwgaW5pdENvbHVtbnMpKSB7XHJcbiAgICAgICAgY29uc3QgaW5pdFJlcyA9IGF3YWl0IHRoaXMucGVyc2lzdFJlbW90ZUNvbHVtbnMoaW5pdENvbHVtbnMpO1xyXG4gICAgICAgIGlmIChpbml0UmVzKSB7XHJcbiAgICAgICAgICB0aGlzLnF1ZXJ5RHluYW1pY0NvbHVtbnMoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBjb25zb2xlLmxvZyhcIuS4gOiHtFwiKTtcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhc3luYyBxdWVyeUR5bmFtaWNDb2x1bW5zKCkge1xyXG4gICAgaWYgKCF0aGlzLnRhYmxlTmFtZSB8fCAhdGhpcy5jb2x1bW5SZW1vdGUpIHJldHVybjtcclxuICAgIGlmICghdGhpcy5fcHJlQ2hlY2tEb25lKSB7XHJcbiAgICAgIGNvbnN0IGNoZWNrUmVzdWx0ID0gYXdhaXQgdGhpcy5wcmVDaGVja1NlcnZlckNvbHVtbnMoKTtcclxuICAgICAgdGhpcy5fcHJlQ2hlY2tEb25lID0gdHJ1ZTtcclxuICAgICAgaWYgKCFjaGVja1Jlc3VsdCkgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgY29uc3QgcmVzID0gYXdhaXQgdGhpcy5mZXRjaFJlbW90ZUNvbHVtbnMoKTtcclxuICAgIGlmICghcmVzKSByZXR1cm47XHJcbiAgICBpZiAocmVzLmNvZGUgPT09IDApIHtcclxuICAgICAgY29uc3QgX3RhYkNvbHVtbiA9IHJlcy5kYXRhLnRhYkNvbHVtbi5tYXAoKGl0ZW0pID0+IHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgdGl0bGU6IGl0ZW0uaGVhZGVyLFxyXG4gICAgICAgICAgcHJvcDogaXRlbS5maWVsZCxcclxuICAgICAgICAgIHNvcnROYW1lOiBpdGVtLnNvcnROYW1lLFxyXG4gICAgICAgICAgaGlkZUluVGFibGU6ICFpdGVtLmlzU2hvdyxcclxuICAgICAgICB9O1xyXG4gICAgICB9KTtcclxuICAgICAgdGhpcy5fc2VydmVyQ29sdW1ucyA9IF90YWJDb2x1bW47XHJcbiAgICAgIHRoaXMudXBkYXRlVGFibGVDb2x1bW5zKF90YWJDb2x1bW4pO1xyXG4gICAgfSBlbHNlIGlmIChyZXMuY29kZSA9PT0gMTApIHtcclxuICAgICAgLy8g5aaC5p6c5pyq6K6+572u5o6l5Y+j6L+U5Zue77yM6ZyA6KaB6buY6K6k6LCD55So5LiA5qyh5L+u5pS55Ye95pWw5Yid5aeL5YyW5pWw5o2uXHJcbiAgICAgIGNvbnN0IGluaXRDb2x1bW5zID0gdGhpcy5jb2x1bW5zXHJcbiAgICAgICAgLmZpbHRlcigoY29sKSA9PiAhY29sLmF1eGlsaWFyeUNvbHVtbilcclxuICAgICAgICAubWFwKChjb2x1bW4pID0+IHtcclxuICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIGZpZWxkOiBjb2x1bW4ucHJvcCxcclxuICAgICAgICAgICAgaXNTaG93OiB0cnVlLCAvLyDpu5jorqTlhajpg6jmmL7npLpcclxuICAgICAgICAgICAgaGVhZGVyOiBjb2x1bW4udGl0bGUsXHJcbiAgICAgICAgICAgIHNvcnROYW1lOiBjb2x1bW4uc29ydE5hbWUgfHwgbnVsbCxcclxuICAgICAgICAgIH07XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAvLyDosIPnlKjkv67mlLnmjqXlj6PliJ3lp4vljJbmlbDmja5cclxuICAgICAgY29uc3QgaW5pdFJlcyA9IGF3YWl0IHRoaXMucGVyc2lzdFJlbW90ZUNvbHVtbnMoaW5pdENvbHVtbnMpO1xyXG4gICAgICBpZiAoaW5pdFJlcykge1xyXG4gICAgICAgIHRoaXMucXVlcnlEeW5hbWljQ29sdW1ucygpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGZvcm1hdGVJbm5lckNvbHVtbnMoY29sdW1uczogUHJvVGFibGVDb2x1bW5bXSkge1xyXG4gICAgdGhpcy5fY29sdW1ucyA9IGNvbHVtbnNcclxuICAgICAgLmZpbHRlcigoaXRlbSkgPT4gIWl0ZW0uaGlkZUluVGFibGUpXHJcbiAgICAgIC5tYXAoKGl0ZW0pID0+IHtcclxuICAgICAgICByZXR1cm4geyAuLi5QUk9fVEFCTEVfREVGQVVMVF9DT0xVTU4sIC4uLml0ZW0gfSBhcyBQcm9UYWJsZUNvbHVtbjtcclxuICAgICAgfSk7XHJcbiAgfVxyXG5cclxuICAvLyDoh6rliqjms6jlhozmqKHmnb/nmoTmlrnms5VcclxuICBwcml2YXRlIGF1dG9SZWdpc3RlclRlbXBsYXRlcygpIHtcclxuICAgIC8vIOiOt+WPluaJgOaciemcgOimgeiHquWumuS5ieaooeadv+eahOWIl1xyXG4gICAgY29uc3QgY29sdW1uc1dpdGhDdXN0b21SZW5kZXIgPSB0aGlzLl9jb2x1bW5zLmZpbHRlcihcclxuICAgICAgKGNvbCkgPT4gY29sLmN1c3RvbVJlbmRlclxyXG4gICAgKTtcclxuXHJcbiAgICBpZiAoY29sdW1uc1dpdGhDdXN0b21SZW5kZXIubGVuZ3RoID4gMCkge1xyXG4gICAgICAvLyDlsJ3or5Xku45Db250ZW50Q2hpbGRyZW7kuK3mn6Xmib7lr7nlupTnmoTmqKHmnb9cclxuICAgICAgY29sdW1uc1dpdGhDdXN0b21SZW5kZXIuZm9yRWFjaCgoY29sdW1uKSA9PiB7XHJcbiAgICAgICAgY29uc3QgdGVtcGxhdGVOYW1lID0gY29sdW1uLmN1c3RvbVJlbmRlciE7XHJcbiAgICAgICAgY29uc3QgdGVtcGxhdGUgPSB0aGlzLmZpbmRUZW1wbGF0ZUJ5TmFtZSh0ZW1wbGF0ZU5hbWUpO1xyXG5cclxuICAgICAgICBpZiAodGVtcGxhdGUpIHtcclxuICAgICAgICAgIHRoaXMuY3VzdG9tVGVtcGxhdGVzLnNldCh0ZW1wbGF0ZU5hbWUsIHRlbXBsYXRlKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8g6I635Y+W5omA5pyJ6ZyA6KaB6Ieq5a6a5LmJbGFiZWzmqKHmnb/nmoTliJfvvIjkvb/nlKjljp/lp4tjb2x1bW5z77yM56Gu5L+d6aG65bqP5q2j56Gu77yJXHJcbiAgICBjb25zdCBjb2x1bW5zV2l0aEN1c3RvbUxhYmVsID0gdGhpcy5jb2x1bW5zLmZpbHRlcihcclxuICAgICAgKGNvbCkgPT4gY29sLmN1c3RvbUxhYmVsUmVuZGVyXHJcbiAgICApO1xyXG5cclxuICAgIGlmIChjb2x1bW5zV2l0aEN1c3RvbUxhYmVsLmxlbmd0aCA+IDApIHtcclxuICAgICAgLy8g5bCd6K+V5LuOQ29udGVudENoaWxkcmVu5Lit5p+l5om+5a+55bqU55qEbGFiZWzmqKHmnb9cclxuICAgICAgY29sdW1uc1dpdGhDdXN0b21MYWJlbC5mb3JFYWNoKChjb2x1bW4pID0+IHtcclxuICAgICAgICBjb25zdCB0ZW1wbGF0ZU5hbWUgPSBjb2x1bW4uY3VzdG9tTGFiZWxSZW5kZXIhO1xyXG4gICAgICAgIGNvbnN0IHRlbXBsYXRlID0gdGhpcy5maW5kTGFiZWxUZW1wbGF0ZUJ5TmFtZShcclxuICAgICAgICAgIHRlbXBsYXRlTmFtZSxcclxuICAgICAgICAgIGNvbHVtbnNXaXRoQ3VzdG9tTGFiZWxcclxuICAgICAgICApO1xyXG5cclxuICAgICAgICBpZiAodGVtcGxhdGUpIHtcclxuICAgICAgICAgIHRoaXMuY3VzdG9tVGVtcGxhdGVzLnNldCh0ZW1wbGF0ZU5hbWUsIHRlbXBsYXRlKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyDmoLnmja7lkI3np7Dmn6Xmib7mqKHmnb9cclxuICBwcml2YXRlIGZpbmRUZW1wbGF0ZUJ5TmFtZSh0ZW1wbGF0ZU5hbWU6IHN0cmluZyk6IFRlbXBsYXRlUmVmPGFueT4gfCBudWxsIHtcclxuICAgIHJldHVybiB0aGlzLmdldFRlbXBsYXRlRnJvbUNvbnRlbnQodGVtcGxhdGVOYW1lKTtcclxuICB9XHJcblxyXG4gIC8vIOS7jkNvbnRlbnRDaGlsZHJlbuS4reafpeaJvuaMh+WumuWQjeensOeahOaooeadv1xyXG4gIHByaXZhdGUgZ2V0VGVtcGxhdGVGcm9tQ29udGVudChcclxuICAgIHRlbXBsYXRlTmFtZTogc3RyaW5nXHJcbiAgKTogVGVtcGxhdGVSZWY8YW55PiB8IG51bGwge1xyXG4gICAgY29uc3QgY3VzdG9tUmVuZGVyQ29sdW1ucyA9IHRoaXMuX2NvbHVtbnMuZmlsdGVyKChjb2wpID0+IGNvbC5jdXN0b21SZW5kZXIpO1xyXG4gICAgY29uc3QgdGVtcGxhdGVJbmRleCA9IGN1c3RvbVJlbmRlckNvbHVtbnMuZmluZEluZGV4KFxyXG4gICAgICAoY29sKSA9PiBjb2wuY3VzdG9tUmVuZGVyID09PSB0ZW1wbGF0ZU5hbWVcclxuICAgICk7XHJcblxyXG4gICAgaWYgKHRlbXBsYXRlSW5kZXggPj0gMCkge1xyXG4gICAgICAvLyDojrflj5bmiYDmnInmqKHmnb/vvIzlubbov4fmu6TmjonnibnmrormqKHmnb/vvIhhY3Rpb25CYXLlkoxJbWdBY3Rpb25CYXLvvIlcclxuICAgICAgLy8g6L+Z5qC35Y+v5Lul6YG/5YWN5Zug5Li654m55q6K5qih5p2/55qE5L2N572u5a+86Ie057Si5byV6K6h566X6ZSZ6K+vXHJcbiAgICAgIGNvbnN0IHRlbXBsYXRlcyA9IHRoaXMuYWxsVGVtcGxhdGVzLnRvQXJyYXkoKTtcclxuICAgICAgY29uc3QgY3VzdG9tVGVtcGxhdGVzID0gdGVtcGxhdGVzLmZpbHRlcihcclxuICAgICAgICAodHBsKSA9PiB0cGwgIT09IHRoaXMuYWN0aW9uQmFyVHBsICYmIHRwbCAhPT0gdGhpcy5pbWdBY3Rpb25CYXJUcGxcclxuICAgICAgKTtcclxuXHJcbiAgICAgIGlmICh0ZW1wbGF0ZUluZGV4IDwgY3VzdG9tVGVtcGxhdGVzLmxlbmd0aCkge1xyXG4gICAgICAgIGNvbnN0IHRlbXBsYXRlID0gY3VzdG9tVGVtcGxhdGVzW3RlbXBsYXRlSW5kZXhdO1xyXG4gICAgICAgIHJldHVybiB0ZW1wbGF0ZTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGNvbnNvbGUud2Fybihg5pyq5om+5Yiw5qih5p2/ICR7dGVtcGxhdGVOYW1lfWApO1xyXG4gICAgcmV0dXJuIG51bGw7XHJcbiAgfVxyXG5cclxuICAvLyDmoLnmja7lkI3np7Dmn6Xmib5sYWJlbOaooeadv1xyXG4gIHByaXZhdGUgZmluZExhYmVsVGVtcGxhdGVCeU5hbWUoXHJcbiAgICB0ZW1wbGF0ZU5hbWU6IHN0cmluZyxcclxuICAgIGN1c3RvbUxhYmVsQ29sdW1uczogUHJvVGFibGVDb2x1bW5bXVxyXG4gICk6IFRlbXBsYXRlUmVmPGFueT4gfCBudWxsIHtcclxuICAgIGNvbnN0IHRlbXBsYXRlSW5kZXggPSBjdXN0b21MYWJlbENvbHVtbnMuZmluZEluZGV4KFxyXG4gICAgICAoY29sKSA9PiBjb2wuY3VzdG9tTGFiZWxSZW5kZXIgPT09IHRlbXBsYXRlTmFtZVxyXG4gICAgKTtcclxuXHJcbiAgICBpZiAodGVtcGxhdGVJbmRleCA+PSAwKSB7XHJcbiAgICAgIC8vIOiOt+WPluaJgOacieaooeadv++8jOW5tui/h+a7pOaOieeJueauiuaooeadv++8iGFjdGlvbkJhcuWSjEltZ0FjdGlvbkJhcu+8iVxyXG4gICAgICBjb25zdCB0ZW1wbGF0ZXMgPSB0aGlzLmFsbFRlbXBsYXRlcy50b0FycmF5KCk7XHJcbiAgICAgIGNvbnN0IGN1c3RvbVRlbXBsYXRlcyA9IHRlbXBsYXRlcy5maWx0ZXIoXHJcbiAgICAgICAgKHRwbCkgPT4gdHBsICE9PSB0aGlzLmFjdGlvbkJhclRwbCAmJiB0cGwgIT09IHRoaXMuaW1nQWN0aW9uQmFyVHBsXHJcbiAgICAgICk7XHJcblxyXG4gICAgICAvLyDorqHnrpdsYWJlbOaooeadv+eahOe0ouW8le+8mumcgOimgei3s+i/h+aJgOacieeahGN1c3RvbVJlbmRlcuaooeadv1xyXG4gICAgICBjb25zdCBjdXN0b21SZW5kZXJDb2x1bW5zID0gdGhpcy5fY29sdW1ucy5maWx0ZXIoXHJcbiAgICAgICAgKGNvbCkgPT4gY29sLmN1c3RvbVJlbmRlclxyXG4gICAgICApO1xyXG4gICAgICBjb25zdCBsYWJlbFRlbXBsYXRlSW5kZXggPSBjdXN0b21SZW5kZXJDb2x1bW5zLmxlbmd0aCArIHRlbXBsYXRlSW5kZXg7XHJcblxyXG4gICAgICBpZiAobGFiZWxUZW1wbGF0ZUluZGV4IDwgY3VzdG9tVGVtcGxhdGVzLmxlbmd0aCkge1xyXG4gICAgICAgIGNvbnN0IHRlbXBsYXRlID0gY3VzdG9tVGVtcGxhdGVzW2xhYmVsVGVtcGxhdGVJbmRleF07XHJcbiAgICAgICAgcmV0dXJuIHRlbXBsYXRlO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgY29uc29sZS53YXJuKGDmnKrmib7liLBsYWJlbOaooeadvyAke3RlbXBsYXRlTmFtZX1gKTtcclxuICAgIHJldHVybiBudWxsO1xyXG4gIH1cclxuXHJcbiAgLy8g6K6+572u562b6YCJ6KGo5Y2V6buY6K6k5bGe5oCnXHJcbiAgcHJpdmF0ZSBzZXRTZWFyY2hGb3JtRGVmYXVsdFByb3AoY29sdW1uczogUHJvVGFibGVDb2x1bW5bXSkge1xyXG4gICAgY29sdW1ucy5mb3JFYWNoKChpdGVtKSA9PiB7XHJcbiAgICAgIGlmIChpdGVtLnZhbHVlVHlwZSkge1xyXG4gICAgICAgIGlmIChpdGVtLmZpZWxkUHJvcHMpIHtcclxuICAgICAgICAgIGl0ZW0uZmllbGRQcm9wcyA9IHtcclxuICAgICAgICAgICAgLi4uUFJPX1RBQkxFX0RFRkFVTFRfUFJPUFNbaXRlbS52YWx1ZVR5cGVdLFxyXG4gICAgICAgICAgICAuLi5pdGVtLmZpZWxkUHJvcHMsXHJcbiAgICAgICAgICB9O1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBpdGVtLmZpZWxkUHJvcHMgPSB7IC4uLlBST19UQUJMRV9ERUZBVUxUX1BST1BTW2l0ZW0udmFsdWVUeXBlXSB9O1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvLyDliqjmgIHorr7nva5PcHRpb25zXHJcbiAgcHJpdmF0ZSBzZXRTZWxlY3RSZXF1ZXN0KGNvbHVtbnM6IFByb1RhYmxlQ29sdW1uW10pIHtcclxuICAgIGNvbHVtbnMubWFwKGFzeW5jIChpdGVtKSA9PiB7XHJcbiAgICAgIGlmIChpdGVtLmZpZWxkUHJvcHMgJiYgaGFzSW4oaXRlbS5maWVsZFByb3BzLCBcInJlcXVlc3RcIikpIHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IGF3YWl0IChcclxuICAgICAgICAgICAgaXRlbS5maWVsZFByb3BzIGFzIFNlbGVjdEZpZWxkUHJvcHNcclxuICAgICAgICAgICkucmVxdWVzdD8uKCk7XHJcbiAgICAgICAgICAoaXRlbS5maWVsZFByb3BzIGFzIFNlbGVjdEZpZWxkUHJvcHMpLm9wdGlvbnMgPSBvcHRpb25zO1xyXG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgICAgICAoaXRlbS5maWVsZFByb3BzIGFzIFNlbGVjdEZpZWxkUHJvcHMpLm9wdGlvbnMgPSBbXTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhc3luYyBzZXRTZWFyY2hQYXJhbXMoY29sdW1uczogUHJvVGFibGVDb2x1bW5bXSkge1xyXG4gICAgdGhpcy5fc2VhcmNoRmlsZWRDb2x1bW5zID0gW107XHJcbiAgICBjb2x1bW5zXHJcbiAgICAgIC5maWx0ZXIoKGl0ZW0pID0+IHtcclxuICAgICAgICBjb25zdCBmbGFnID0gIWl0ZW0uaGlkZUluU2VhcmNoICYmIGl0ZW0udmFsdWVUeXBlO1xyXG4gICAgICAgIGlmIChmbGFnKSB7XHJcbiAgICAgICAgICB0aGlzLl9zZWFyY2hGaWxlZENvbHVtbnMucHVzaChjbG9uZURlZXAoaXRlbSkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gZmxhZztcclxuICAgICAgfSlcclxuICAgICAgLmZvckVhY2goKGNvbHVtbikgPT4ge1xyXG4gICAgICAgIGNvbnN0IGtleSA9IGNvbHVtbi5maWVsZFByb3BzPy5uYW1lIHx8IGNvbHVtbi5wcm9wO1xyXG4gICAgICAgIGxldCBkZWZhdWx0VmFsdWUgPSBQUk9fVEFCTEVfREVGQVVMVF9QUk9QU1tjb2x1bW4udmFsdWVUeXBlXS52YWx1ZTtcclxuXHJcbiAgICAgICAgLy8g5a+55LqOY2hlY2tib3jnsbvlnovvvIzku45vcHRpb25z5Lit5om+5Ye6Y2hlY2tlZOS4unRydWXnmoTpobnkvZzkuLrpu5jorqTlgLxcclxuICAgICAgICBpZiAoY29sdW1uLnZhbHVlVHlwZSA9PT0gXCJjaGVja2JveFwiKSB7XHJcbiAgICAgICAgICBjb25zdCBjaGVja2VkVmFsdWVzID0gKGNvbHVtbi5maWVsZFByb3BzPy5vcHRpb25zIHx8IFtdKVxyXG4gICAgICAgICAgICAuZmlsdGVyKChvcHQ6IE9wdGlvbnNUeXBlKSA9PiBvcHQuY2hlY2tlZClcclxuICAgICAgICAgICAgLm1hcCgob3B0OiBPcHRpb25zVHlwZSkgPT4gb3B0LnZhbHVlKTtcclxuICAgICAgICAgIHRoaXMuX3NlYXJjaFBhcmFtc1trZXldID1cclxuICAgICAgICAgICAgY2hlY2tlZFZhbHVlcy5sZW5ndGggPiAwID8gY2hlY2tlZFZhbHVlcyA6IGRlZmF1bHRWYWx1ZTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdGhpcy5fc2VhcmNoUGFyYW1zW2tleV0gPSBjb2x1bW4uZmllbGRQcm9wcz8udmFsdWUgfHwgZGVmYXVsdFZhbHVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8g5Yid5aeL5YyWIGF1dG9Db21wbGV0ZSDmlbDmja7mupBcclxuICAgICAgICBpZiAoY29sdW1uLnZhbHVlVHlwZSA9PT0gXCJhdXRvQ29tcGxldGVcIikge1xyXG4gICAgICAgICAgdGhpcy5fYXV0b0NvbXBsZXRlRGF0YVNvdXJjZXNba2V5XSA9IFtdO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcblxyXG4gICAgLy8g5qC55o2u5YiX55qEIG9yZGVyIOWtl+autei/m+ihjOaOkuW6j++8jOacquiuvue9riBvcmRlciDnmoTmlL7lnKjmnIDlkI5cclxuICAgIHRoaXMuX3NlYXJjaEZpbGVkQ29sdW1ucy5zb3J0KChhOiBhbnksIGI6IGFueSkgPT4ge1xyXG4gICAgICBjb25zdCBhT3JkZXIgPSBpc05pbChhPy5vcmRlcikgPyBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUiA6IGEub3JkZXI7XHJcbiAgICAgIGNvbnN0IGJPcmRlciA9IGlzTmlsKGI/Lm9yZGVyKSA/IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSIDogYi5vcmRlcjtcclxuICAgICAgaWYgKGFPcmRlciA9PT0gYk9yZGVyKSByZXR1cm4gMDtcclxuICAgICAgcmV0dXJuIGFPcmRlciAtIGJPcmRlcjtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuc2V0U2VhcmNoRm9ybURlZmF1bHRQcm9wKHRoaXMuX3NlYXJjaEZpbGVkQ29sdW1ucyk7XHJcblxyXG4gICAgLy8g5bm25Y+R5Yqg6L295omA5pyJ6ZyA6KaB5byC5q2l6I635Y+W55qE6YCJ6aG5XHJcbiAgICB0aGlzLnNldFNlbGVjdFJlcXVlc3QodGhpcy5fc2VhcmNoRmlsZWRDb2x1bW5zKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgdXBkYXRlVGFibGVDb2x1bW5zKGluamVjdENvbHVtbnM6IFByb1RhYmxlQ29sdW1uW10pIHtcclxuICAgIC8vIDEuIOS9v+eUqOacgOWOn+Wni+eahGNvbHVtbnPkvZzkuLrmlbDmja7mupDvvIznoa7kv53ovoXliqnliJflrozlhajkuI3lj5flvbHlk41cclxuICAgIGNvbnN0IG9yaWdpbmFsQ29sdW1ucyA9IGNsb25lRGVlcCh0aGlzLmNvbHVtbnMpO1xyXG5cclxuICAgIC8vIDIuIOWkhOeQhuWtl+auteaYoOWwhO+8iOWmguaenOaPkOS+m+S6hmZpZWxkc+WPguaVsO+8iVxyXG4gICAgbGV0IHByb2Nlc3NlZEluamVjdENvbHVtbnMgPSBpbmplY3RDb2x1bW5zO1xyXG5cclxuICAgIC8vIDMuIOWIhuemu+i+heWKqeWIl+WSjOmdnui+heWKqeWIl++8iOS9v+eUqOWOn+Wni+aVsOaNru+8iVxyXG4gICAgY29uc3Qgbm9uQXV4aWxpYXJ5Q29sdW1ucyA9IG9yaWdpbmFsQ29sdW1ucy5maWx0ZXIoXHJcbiAgICAgIChjb2wpID0+ICFjb2wuYXV4aWxpYXJ5Q29sdW1uXHJcbiAgICApO1xyXG5cclxuICAgIC8vIDQuIOaMieeFp2luamVjdENvbHVtbnPnmoTpobrluo/ph43mlrDmjpLliJfpnZ7ovoXliqnliJdcclxuICAgIGNvbnN0IHJlb3JkZXJlZE5vbkF1eGlsaWFyeUNvbHVtbnM6IFByb1RhYmxlQ29sdW1uW10gPSBbXTtcclxuICAgIGNvbnN0IHJlbWFpbmluZ05vbkF1eGlsaWFyeUNvbHVtbnMgPSBbLi4ubm9uQXV4aWxpYXJ5Q29sdW1uc107IC8vIOWkjeWItuS4gOS7veeUqOS6juafpeaJvuWSjOenu+mZpFxyXG5cclxuICAgIHByb2Nlc3NlZEluamVjdENvbHVtbnMuZm9yRWFjaCgoaW5qZWN0Q29sKSA9PiB7XHJcbiAgICAgIC8vIOafpeaJvumdnui+heWKqeWIl+S4reWvueW6lOeahOS4i+agh1xyXG4gICAgICBjb25zdCBleGlzdGluZ0NvbEluZGV4ID0gcmVtYWluaW5nTm9uQXV4aWxpYXJ5Q29sdW1ucy5maW5kSW5kZXgoXHJcbiAgICAgICAgKGNvbCkgPT4gY29sLnByb3AgPT09IGluamVjdENvbC5wcm9wXHJcbiAgICAgICk7XHJcbiAgICAgIGlmIChleGlzdGluZ0NvbEluZGV4ICE9PSAtMSkge1xyXG4gICAgICAgIC8vIOWmguaenOaJvuWIsOebuOWQjOWIl++8jOeUqGluamVjdENvbHVtbnPkuK3nmoTlsZ7mgKfopobnm5bljp/lp4tjb2x1bW5z5Lit55qE5bGe5oCnXHJcbiAgICAgICAgY29uc3QgZXhpc3RpbmdDb2wgPSByZW1haW5pbmdOb25BdXhpbGlhcnlDb2x1bW5zW2V4aXN0aW5nQ29sSW5kZXhdO1xyXG5cclxuICAgICAgICBjb25zdCB1cGRhdGVkQ29sID0geyAuLi5leGlzdGluZ0NvbCwgLi4uaW5qZWN0Q29sIH07XHJcbiAgICAgICAgcmVvcmRlcmVkTm9uQXV4aWxpYXJ5Q29sdW1ucy5wdXNoKHVwZGF0ZWRDb2wpO1xyXG4gICAgICAgIC8vIOS7juWJqeS9meaVsOe7hOS4reenu+mZpO+8jOmBv+WFjemHjeWkjVxyXG4gICAgICAgIHJlbWFpbmluZ05vbkF1eGlsaWFyeUNvbHVtbnMuc3BsaWNlKGV4aXN0aW5nQ29sSW5kZXgsIDEpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIC8vIOWmguaenOayoeaJvuWIsOWvueW6lOeahOWIl++8jOebtOaOpea3u+WKoGluamVjdENvbHVtbnPkuK3nmoTliJdcclxuICAgICAgICByZW9yZGVyZWROb25BdXhpbGlhcnlDb2x1bW5zLnB1c2goaW5qZWN0Q29sKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgLy8gNS4g5aSE55CG5Ymp5L2Z55qE5Y6f5aeLY29sdW1uc+S4reeahOmdnui+heWKqeWIl++8iOWcqGluamVjdENvbHVtbnPkuK3mnKrlh7rnjrDnmoTliJfvvIlcclxuICAgIC8vIOi/meS6m+WIl+W6lOivpeiiq+makOiXj++8iOiuvue9rmhpZGVJblRhYmxl5Li6dHJ1Ze+8iVxyXG4gICAgcmVtYWluaW5nTm9uQXV4aWxpYXJ5Q29sdW1ucy5mb3JFYWNoKChyZW1haW5pbmdDb2wpID0+IHtcclxuICAgICAgY29uc3QgaGlkZGVuQ29sID0geyAuLi5yZW1haW5pbmdDb2wsIGhpZGVJblRhYmxlOiB0cnVlIH07XHJcbiAgICAgIHJlb3JkZXJlZE5vbkF1eGlsaWFyeUNvbHVtbnMucHVzaChoaWRkZW5Db2wpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgLy8gNi4g5oyJ54Wn5Y6f5aeLY29sdW1uc+eahOmhuuW6j+mHjeaWsOe7hOWQiO+8muS/neaMgei+heWKqeWIl+eahOWOn+Wni+S9jee9ruWSjOWxnuaAp1xyXG4gICAgY29uc3QgZmluYWxDb2x1bW5zOiBQcm9UYWJsZUNvbHVtbltdID0gW107XHJcbiAgICBsZXQgbm9uQXV4aWxpYXJ5SW5kZXggPSAwO1xyXG4gICAgbGV0IGF1eGlsaWFyeUluZGV4ID0gMDtcclxuXHJcbiAgICBvcmlnaW5hbENvbHVtbnMuZm9yRWFjaCgob3JpZ2luYWxDb2wpID0+IHtcclxuICAgICAgaWYgKG9yaWdpbmFsQ29sLmF1eGlsaWFyeUNvbHVtbikge1xyXG4gICAgICAgIC8vIOWmguaenOaYr+i+heWKqeWIl++8jOS9v+eUqOWOn+Wni+WIl+aVsOaNru+8jOWujOWFqOS4jei/m+ihjOS7u+S9leS/ruaUuVxyXG4gICAgICAgIGZpbmFsQ29sdW1ucy5wdXNoKG9yaWdpbmFsQ29sKTtcclxuICAgICAgICBhdXhpbGlhcnlJbmRleCsrO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIC8vIOWmguaenOaYr+mdnui+heWKqeWIl++8jOS9v+eUqOmHjeaWsOaOkuW6j+WQjueahOWIl++8jOS9huS/neeVmeWOn+Wni+WIl+eahOaJgOacieWxnuaAp1xyXG4gICAgICAgIGNvbnN0IHJlb3JkZXJlZENvbCA9IHJlb3JkZXJlZE5vbkF1eGlsaWFyeUNvbHVtbnNbbm9uQXV4aWxpYXJ5SW5kZXhdO1xyXG4gICAgICAgIGlmIChyZW9yZGVyZWRDb2wpIHtcclxuICAgICAgICAgIC8vIOWQiOW5tuWOn+Wni+WIl+WSjOmHjeaWsOaOkuW6j+WQjueahOWIl++8jOehruS/neS/neeVmeaJgOacieWOn+Wni+WxnuaAp1xyXG4gICAgICAgICAgY29uc3QgbWVyZ2VkQ29sID0geyAuLi5vcmlnaW5hbENvbCwgLi4ucmVvcmRlcmVkQ29sIH07XHJcbiAgICAgICAgICBmaW5hbENvbHVtbnMucHVzaChtZXJnZWRDb2wpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAvLyDlpoLmnpzph43mlrDmjpLluo/lkI7nmoTliJfkuI3lrZjlnKjvvIzkvb/nlKjljp/lp4vliJdcclxuICAgICAgICAgIGZpbmFsQ29sdW1ucy5wdXNoKG9yaWdpbmFsQ29sKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgbm9uQXV4aWxpYXJ5SW5kZXgrKztcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICB0aGlzLmZvcm1hdGVJbm5lckNvbHVtbnMoZmluYWxDb2x1bW5zKTtcclxuICB9XHJcblxyXG4gIC8vIOmAmui/hyBQcm94eSDnm5HlkKwgX3NlYXJjaFBhcmFtcyDnmoTlsZ7mgKflj5jmm7RcclxuICBwcml2YXRlIGNyZWF0ZVNlYXJjaFBhcmFtc1Byb3h5KHRhcmdldDogYW55KSB7XHJcbiAgICBjb25zdCBzZWxmID0gdGhpcztcclxuICAgIGNvbnN0IGhhbmRsZXI6IFByb3h5SGFuZGxlcjxhbnk+ID0ge1xyXG4gICAgICBzZXQob2JqOiBhbnksIHByb3A6IHN0cmluZyB8IHN5bWJvbCwgdmFsdWU6IGFueSkge1xyXG4gICAgICAgIGNvbnN0IGtleSA9IFN0cmluZyhwcm9wKTtcclxuICAgICAgICBjb25zdCBvbGRWYWwgPSBvYmpba2V5XTtcclxuICAgICAgICBpZiAob2xkVmFsID09PSB2YWx1ZSkge1xyXG4gICAgICAgICAgb2JqW2tleV0gPSB2YWx1ZTtcclxuICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBvYmpba2V5XSA9IHZhbHVlO1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICBzZWxmLm9uVmFsdWVzQ2hhbmdlLmVtaXQoe1xyXG4gICAgICAgICAgICBrZXksXHJcbiAgICAgICAgICAgIHZhbHVlLFxyXG4gICAgICAgICAgICBwYXJhbXM6IHNlbGYuZ2V0U2VhcmNoUGFyYW1zKCksXHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9IGNhdGNoIChlKSB7fVxyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICB9LFxyXG4gICAgfTtcclxuICAgIHJldHVybiBuZXcgUHJveHkodGFyZ2V0LCBoYW5kbGVyKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgY2xlYXJFbXB0eVNlYXJjaFBhcmFtcygpIHtcclxuICAgIGNvbnN0IGNsb25lU2VhcmNoUGFyYW1zID0gY2xvbmVEZWVwKHRoaXMuX3NlYXJjaFBhcmFtcyk7XHJcbiAgICByZXR1cm4gY2xvbmVTZWFyY2hQYXJhbXM7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGJ1aWxkU2VydmVyU29ydFBheWxvYWQoKSB7XHJcbiAgICAvLyDmnoTlu7rmv4DmtLvmjpLluo/pm4blkIjvvIjmjInkvJjlhYjnuqfku47kvY7liLDpq5jvvIzmnKvlsL7kvJjlhYjvvIlcclxuICAgIGNvbnN0IGFjdGl2ZUtleXMgPSB0aGlzLl9zb3J0UHJpb3JpdHkuZmlsdGVyKChrKSA9PiAhIXRoaXMuX3NvcnRNYXBba10pO1xyXG4gICAgaWYgKGFjdGl2ZUtleXMubGVuZ3RoID09PSAwKSByZXR1cm4gbnVsbDtcclxuICAgIGNvbnN0IHNvcnRzID0gYWN0aXZlS2V5cy5tYXAoKGZpZWxkKSA9PiB7XHJcbiAgICAgIC8vIOafpeaJvuWvueW6lOeahOWIl+mFjee9ru+8jOS8mOWFiOS9v+eUqHNvcnROYW1l5a2X5q61XHJcbiAgICAgIGNvbnN0IGNvbHVtbiA9IHRoaXMuX2NvbHVtbnMuZmluZCgoY29sKSA9PiBjb2wucHJvcCA9PT0gZmllbGQpO1xyXG4gICAgICBjb25zdCBzb3J0RmllbGQgPSBjb2x1bW4/LnNvcnROYW1lIHx8IGZpZWxkO1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGZpZWxkOiBzb3J0RmllbGQsXHJcbiAgICAgICAgb3JkZXI6IHRoaXMuX3NvcnRNYXBbZmllbGRdISxcclxuICAgICAgfTtcclxuICAgIH0pO1xyXG4gICAgaWYgKHRoaXMubXVsdGlwbGVTb3J0KSB7XHJcbiAgICAgIHJldHVybiBzb3J0czsgLy8g5Lul5pWw57uE5b2i5byP5o+Q5Lqk5aSa5YiX5o6S5bqPXHJcbiAgICB9XHJcbiAgICBjb25zdCBbZmlyc3RdID0gc29ydHM7XHJcbiAgICByZXR1cm4gZmlyc3Q7IC8vIOWFvOWuueWNleWIl+e7k+aehCB7IGZpZWxkLCBvcmRlciB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHNvcnREYXRhU291cmNlSW5QbGFjZSgpIHtcclxuICAgIGlmICghQXJyYXkuaXNBcnJheSh0aGlzLmRhdGFTb3VyY2UpIHx8IHRoaXMuZGF0YVNvdXJjZS5sZW5ndGggPT09IDApIHJldHVybjtcclxuICAgIGNvbnN0IGFjdGl2ZUtleXMgPSB0aGlzLl9zb3J0UHJpb3JpdHkuZmlsdGVyKChrKSA9PiAhIXRoaXMuX3NvcnRNYXBba10pO1xyXG4gICAgaWYgKGFjdGl2ZUtleXMubGVuZ3RoID09PSAwKSByZXR1cm47XHJcblxyXG4gICAgLy8g5aSN5Yi25LiA5Lu95LyY5YWI57qn77yM5LuO5YmN5Yiw5ZCO5LyY5YWI57qn5LuO5L2O5Yiw6auY77yI5pyA5ZCO6K6+572u55qE5a2X5q615LyY5YWI77yJXHJcbiAgICBjb25zdCBrZXlzSW5Qcmlvcml0eSA9IFsuLi5hY3RpdmVLZXlzXTtcclxuICAgIHRoaXMuZGF0YVNvdXJjZS5zb3J0KChhOiBhbnksIGI6IGFueSkgPT4ge1xyXG4gICAgICBmb3IgKGxldCBpID0ga2V5c0luUHJpb3JpdHkubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcclxuICAgICAgICBjb25zdCBmaWVsZCA9IGtleXNJblByaW9yaXR5W2ldO1xyXG4gICAgICAgIGNvbnN0IG9yZGVyID0gdGhpcy5fc29ydE1hcFtmaWVsZF0hO1xyXG4gICAgICAgIGNvbnN0IGF2ID0gYT8uW2ZpZWxkXTtcclxuICAgICAgICBjb25zdCBidiA9IGI/LltmaWVsZF07XHJcbiAgICAgICAgY29uc3QgY21wID0gdGhpcy5jb21wYXJlVmFsdWVzKGF2LCBidik7XHJcbiAgICAgICAgaWYgKGNtcCAhPT0gMCkgcmV0dXJuIG9yZGVyID09PSBcImFzY2VuZFwiID8gY21wIDogLWNtcDtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gMDtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjb21wYXJlVmFsdWVzKGFWYWw6IGFueSwgYlZhbDogYW55KTogbnVtYmVyIHtcclxuICAgIGlmIChhVmFsID09IG51bGwgJiYgYlZhbCA9PSBudWxsKSByZXR1cm4gMDtcclxuICAgIGlmIChhVmFsID09IG51bGwpIHJldHVybiAtMTtcclxuICAgIGlmIChiVmFsID09IG51bGwpIHJldHVybiAxO1xyXG4gICAgaWYgKGFWYWwgaW5zdGFuY2VvZiBEYXRlICYmIGJWYWwgaW5zdGFuY2VvZiBEYXRlKSB7XHJcbiAgICAgIHJldHVybiBhVmFsLmdldFRpbWUoKSAtIGJWYWwuZ2V0VGltZSgpO1xyXG4gICAgfVxyXG4gICAgaWYgKHR5cGVvZiBhVmFsID09PSBcImJvb2xlYW5cIiAmJiB0eXBlb2YgYlZhbCA9PT0gXCJib29sZWFuXCIpIHtcclxuICAgICAgcmV0dXJuIGFWYWwgPT09IGJWYWwgPyAwIDogYVZhbCA/IDEgOiAtMTtcclxuICAgIH1cclxuICAgIGlmICh0eXBlb2YgYVZhbCA9PT0gXCJudW1iZXJcIiAmJiB0eXBlb2YgYlZhbCA9PT0gXCJudW1iZXJcIikge1xyXG4gICAgICByZXR1cm4gYVZhbCAtIGJWYWw7XHJcbiAgICB9XHJcbiAgICBpZiAodHlwZW9mIGFWYWwgPT09IFwic3RyaW5nXCIgJiYgdHlwZW9mIGJWYWwgPT09IFwic3RyaW5nXCIpIHtcclxuICAgICAgcmV0dXJuIGFWYWwubG9jYWxlQ29tcGFyZShiVmFsKTtcclxuICAgIH1cclxuICAgIGNvbnN0IGFOdW0gPSBOdW1iZXIoYVZhbCk7XHJcbiAgICBjb25zdCBiTnVtID0gTnVtYmVyKGJWYWwpO1xyXG4gICAgaWYgKCFpc05hTihhTnVtKSAmJiAhaXNOYU4oYk51bSkpIHJldHVybiBhTnVtIC0gYk51bTtcclxuICAgIHJldHVybiBTdHJpbmcoYVZhbCkubG9jYWxlQ29tcGFyZShTdHJpbmcoYlZhbCkpO1xyXG4gIH1cclxuXHJcbiAgLy8g5omn6KGMIGF1dG9Db21wbGV0ZSDmlbDmja7mupDmn6Xor6LvvIjlrp7pmYXmiafooYzpgLvovpHvvIlcclxuICBwcml2YXRlIGV4ZWN1dGVBdXRvQ29tcGxldGVEYXRhU291cmNlKGV2ZW50OiBFdmVudCwgY29sdW1uOiBQcm9UYWJsZUNvbHVtbikge1xyXG4gICAgY29uc3QgZmllbGRLZXkgPSBjb2x1bW4uZmllbGRQcm9wcz8ubmFtZSB8fCBjb2x1bW4ucHJvcDtcclxuXHJcbiAgICBpZiAoXHJcbiAgICAgIChjb2x1bW4uZmllbGRQcm9wcyBhcyBBdXRvQ29tcGxldGVGaWVsZFByb3BzKS5kYXRhU291cmNlICYmXHJcbiAgICAgIHR5cGVvZiAoY29sdW1uLmZpZWxkUHJvcHMgYXMgQXV0b0NvbXBsZXRlRmllbGRQcm9wcykuZGF0YVNvdXJjZSA9PT1cclxuICAgICAgICBcImZ1bmN0aW9uXCJcclxuICAgICkge1xyXG4gICAgICB0cnkge1xyXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IChjb2x1bW4uZmllbGRQcm9wcyBhcyBBdXRvQ29tcGxldGVGaWVsZFByb3BzKS5kYXRhU291cmNlKFxyXG4gICAgICAgICAgZXZlbnRcclxuICAgICAgICApO1xyXG4gICAgICAgIC8vIOWmguaenOi/lOWbnueahOaYryBQcm9taXNl77yM5aSE55CG5byC5q2l57uT5p6cXHJcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHtcclxuICAgICAgICAgIHJlc3VsdFxyXG4gICAgICAgICAgICAudGhlbigoZGF0YSkgPT4ge1xyXG4gICAgICAgICAgICAgIHRoaXMuX2F1dG9Db21wbGV0ZURhdGFTb3VyY2VzW2ZpZWxkS2V5XSA9IGRhdGEgfHwgW107XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcclxuICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiQXV0b0NvbXBsZXRlIGRhdGFTb3VyY2UgZXJyb3I6XCIsIGVycm9yKTtcclxuICAgICAgICAgICAgICB0aGlzLl9hdXRvQ29tcGxldGVEYXRhU291cmNlc1tmaWVsZEtleV0gPSBbXTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIC8vIOWQjOatpei/lOWbnue7k+aenFxyXG4gICAgICAgICAgdGhpcy5fYXV0b0NvbXBsZXRlRGF0YVNvdXJjZXNbZmllbGRLZXldID0gcmVzdWx0IHx8IFtdO1xyXG4gICAgICAgIH1cclxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICBjb25zb2xlLmVycm9yKFwiQXV0b0NvbXBsZXRlIGRhdGFTb3VyY2UgZXJyb3I6XCIsIGVycm9yKTtcclxuICAgICAgICB0aGlzLl9hdXRvQ29tcGxldGVEYXRhU291cmNlc1tmaWVsZEtleV0gPSBbXTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldFNlYXJjaFBhcmFtcyhvcHRpb25zPzoge1xyXG4gICAgdXNlU2F2ZWQ/OiBib29sZWFuOyAvLyDkvb/nlKjmnIDov5HkuIDmrKHmn6Xor6Lmj5DkuqTnmoTlj4LmlbDvvIzpu5jorqTkuLogZmFsc2XvvJtmYWxzZSDkuLrlvZPliY3ooajljZXlgLxcclxuICB9KTogYW55IHtcclxuICAgIGNvbnN0IHsgdXNlU2F2ZWQgPSBmYWxzZSB9ID0gb3B0aW9ucyB8fCB7fTtcclxuICAgIGNvbnN0IHJhd1BhcmFtcyA9IHVzZVNhdmVkID8gdGhpcy5fc2F2ZWRTZWFyY2hQYXJhbXMgOiB0aGlzLl9zZWFyY2hQYXJhbXM7XHJcbiAgICBjb25zdCBwYXJhbXMgPSBjbG9uZURlZXAocmF3UGFyYW1zIHx8IHt9KTtcclxuXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBwYXJhbXMsXHJcbiAgICAgIHBhZ2VJbmZvOiB7XHJcbiAgICAgICAgcGFnZUluZGV4OiB0aGlzLl9wYWdlSW5mby5wYWdlSW5kZXgsXHJcbiAgICAgICAgcGFnZVNpemU6IHRoaXMuX3BhZ2VJbmZvLnBhZ2VTaXplLFxyXG4gICAgICB9LFxyXG4gICAgICAvLyDlnKjnur/mjpLluo/mqKHlvI/vvJrmiormjpLluo/lr7nosaHmj5DkuqTnu5nmjqXlj6NcclxuICAgICAgLi4uKHRoaXMuc29ydE1vZGUgPT09IFwic2VydmVyXCJcclxuICAgICAgICA/IHsgc29ydDogdGhpcy5idWlsZFNlcnZlclNvcnRQYXlsb2FkKCkgfVxyXG4gICAgICAgIDoge30pLFxyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyByZWxvYWQoYWZ0ZXJEZWxldGU/OiBib29sZWFuKSB7XHJcbiAgICB0aGlzLmhhbmRsZVF1ZXJ5KGFmdGVyRGVsZXRlKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBzZXRGaWVsZHNWYWx1ZShmaWVsZHM6IFJlY29yZDxzdHJpbmcsIGFueT4pIHtcclxuICAgIE9iamVjdC5rZXlzKGZpZWxkcykuZm9yRWFjaCgoaykgPT4ge1xyXG4gICAgICB0aGlzLl9zZWFyY2hQYXJhbXNba10gPSBmaWVsZHNba107IC8vIOS/neeVmSBQcm94ee+8jOmAkOmhuei1i+WAvOinpuWPkeaLpuaIqlxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc2V0RmllbGRWYWx1ZShrZXk6IHN0cmluZywgdmFsdWU6IGFueSkge1xyXG4gICAgdGhpcy5fc2VhcmNoUGFyYW1zW2tleV0gPSB2YWx1ZTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBjbGVhclNlbGVjdGVkUm93KCkge1xyXG4gICAgdGhpcy5fc2VsZWN0ZWRUYWJsZVJvdyA9IG51bGw7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgYXN5bmMgc2V0Q29sdW1ucyhcclxuICAgIGNvbHVtbnM6IFByb1RhYmxlQ29sdW1uW10sXHJcbiAgICBvcHRpb25zPzoge1xyXG4gICAgICByZWxvYWQ/OiBib29sZWFuOyAvLyDmmK/lkKbph43mlrDliqDovb3mlbDmja7vvIzpu5jorqTkuLogZmFsc2VcclxuICAgIH1cclxuICApOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIC8vIOabtOaWsCBjb2x1bW5zIOi+k+WFpeWxnuaAp1xyXG4gICAgdGhpcy5jb2x1bW5zID0gY2xvbmVEZWVwKGNvbHVtbnMpO1xyXG5cclxuICAgIC8vIOmHjeaWsOagvOW8j+WMluWGhemDqOWIl1xyXG4gICAgdGhpcy5mb3JtYXRlSW5uZXJDb2x1bW5zKHRoaXMuY29sdW1ucyk7XHJcblxyXG4gICAgLy8g6YeN5paw6K6+572u5pCc57Si5Y+C5pWw77yI5byC5q2l5pON5L2c77yJXHJcbiAgICAvLyDlhYjmuIXnqbrml6fnmoTmkJzntKLlj4LmlbDvvIzpgb/lhY3ml6fmlbDmja7mrovnlZlcclxuICAgIHRoaXMuX3NlYXJjaFBhcmFtcyA9IHt9O1xyXG4gICAgYXdhaXQgdGhpcy5zZXRTZWFyY2hQYXJhbXModGhpcy5jb2x1bW5zKTtcclxuXHJcbiAgICAvLyDph43mlrDliJvlu7ogUHJveHnvvIznoa7kv53ooajljZXpobnlgLzlj5jljJbog73mraPluLjop6blj5Hkuovku7ZcclxuICAgIHRoaXMuX3NlYXJjaFBhcmFtcyA9IHRoaXMuY3JlYXRlU2VhcmNoUGFyYW1zUHJveHkodGhpcy5fc2VhcmNoUGFyYW1zKTtcclxuXHJcbiAgICAvLyDph43mlrDms6jlhozmqKHmnb/vvIjlpoLmnpznu4Tku7blt7Lnu4/liJ3lp4vljJblrozmiJDvvIlcclxuICAgIGlmICh0aGlzLmFsbFRlbXBsYXRlcykge1xyXG4gICAgICB0aGlzLmF1dG9SZWdpc3RlclRlbXBsYXRlcygpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIOWmguaenOiuvue9ruS6hiByZWxvYWQg6YCJ6aG55Li6IHRydWXvvIzliJnph43mlrDmn6Xor6LmlbDmja5cclxuICAgIGlmIChvcHRpb25zPy5yZWxvYWQgPT09IHRydWUpIHtcclxuICAgICAgdGhpcy5oYW5kbGVRdWVyeSgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldFNlbGVjdGVkUm93RGF0YTxUID0gYW55PigpOiBUIHtcclxuICAgIHJldHVybiB0aGlzLl9zZWxlY3RlZFRhYmxlUm93O1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldENoZWNrZWRSb3dzPFQgPSBhbnk+KCk6IFRbXSB7XHJcbiAgICByZXR1cm4gdGhpcy5fc2VsZWN0ZWRSb3dzO1xyXG4gIH1cclxuXHJcbiAgLy8g6I635Y+W5oyH5a6a5ZCN56ew55qE5qih5p2/XHJcbiAgZ2V0VGVtcGxhdGUobmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkKTogVGVtcGxhdGVSZWY8YW55PiB8IG51bGwge1xyXG4gICAgaWYgKCFuYW1lKSByZXR1cm4gbnVsbDtcclxuICAgIHRyeSB7XHJcbiAgICAgIC8vIOmmluWFiOS7juiHquWumuS5ieaooeadv+S4reafpeaJvlxyXG4gICAgICBjb25zdCBjdXN0b21UZW1wbGF0ZSA9IHRoaXMuY3VzdG9tVGVtcGxhdGVzLmdldChuYW1lKTtcclxuICAgICAgaWYgKGN1c3RvbVRlbXBsYXRlKSB7XHJcbiAgICAgICAgcmV0dXJuIGN1c3RvbVRlbXBsYXRlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyDnhLblkI7ku47pgJrnlKjmqKHmnb/mmKDlsITkuK3mn6Xmib5cclxuICAgICAgY29uc3QgdGVtcGxhdGUgPSB0aGlzLnRlbXBsYXRlTWFwLmdldChuYW1lKTtcclxuICAgICAgaWYgKHRlbXBsYXRlKSB7XHJcbiAgICAgICAgcmV0dXJuIHRlbXBsYXRlO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnZXRUb29sVGlwVGV4dFZhbHVlKGNvbHVtbjogUHJvVGFibGVDb2x1bW4sIGRhdGE6IGFueSk6IHN0cmluZyB7XHJcbiAgICBjb25zdCBrZXkgPVxyXG4gICAgICBjb2x1bW4uY3VzdG9tUmVuZGVyICYmIHRoaXMuZ2V0VGVtcGxhdGUoY29sdW1uLmN1c3RvbVJlbmRlcilcclxuICAgICAgICA/IFwiXCJcclxuICAgICAgICA6IGNvbHVtbi5lbGxpcHNpc1xyXG4gICAgICAgID8gY29sdW1uLnByb3BcclxuICAgICAgICA6IFwiXCI7XHJcbiAgICByZXR1cm4gIWtleSA/IFwiXCIgOiBkYXRhW2tleV07XHJcbiAgfVxyXG5cclxuICBnZXRUYWJsZVJvd0NoZWNrZWQoZGF0YTogYW55KSB7XHJcbiAgICAvLyDlkK/nlKjlpI3pgInmoYbml7bvvJrooYzpq5jkuq7lupTkuI7lpI3pgInmoYbpgInkuK3nirbmgIHkuIDoh7TvvIjmlK/mjIHlpJrpgInvvIlcclxuICAgIGlmICh0aGlzLnNob3dDaGVja2JveCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5pc1Jvd0NoZWNrZWQoZGF0YSk7XHJcbiAgICB9XHJcbiAgICAvLyDmnKrlkK/nlKjlpI3pgInmoYbml7bvvJrku43nhLbkvb/nlKjljZXpgInooYzpq5jkuq5cclxuICAgIGlmICghdGhpcy5fc2VsZWN0ZWRUYWJsZVJvdykgcmV0dXJuIGZhbHNlO1xyXG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHRoaXMuX3NlbGVjdGVkVGFibGVSb3cpID09PSBKU09OLnN0cmluZ2lmeShkYXRhKTtcclxuICB9XHJcblxyXG4gIC8vIOajgOafpeihjOaYr+WQpuiiq+emgeeUqFxyXG4gIGlzUm93RGlzYWJsZWQoZGF0YTogYW55KTogYm9vbGVhbiB7XHJcbiAgICBpZiAoIXRoaXMuc2hvd0NoZWNrYm94KSByZXR1cm4gZmFsc2U7XHJcbiAgICByZXR1cm4gdGhpcy5yb3dEaXNhYmxlZCA/IHRoaXMucm93RGlzYWJsZWQoZGF0YSkgOiBmYWxzZTtcclxuICB9XHJcblxyXG4gIC8vIOajgOafpeihjOaYr+WQpuiiq+WkjemAieahhumAieS4rVxyXG4gIGlzUm93Q2hlY2tlZChkYXRhOiBhbnkpOiBib29sZWFuIHtcclxuICAgIGlmICghdGhpcy5zaG93Q2hlY2tib3gpIHJldHVybiBmYWxzZTtcclxuICAgIHJldHVybiB0aGlzLl9zZWxlY3RlZFJvd3Muc29tZShcclxuICAgICAgKHJvdykgPT4gSlNPTi5zdHJpbmdpZnkocm93KSA9PT0gSlNPTi5zdHJpbmdpZnkoZGF0YSlcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICAvLyDliIfmjaLooYznmoTpgInkuK3nirbmgIFcclxuICB0b2dnbGVSb3dDaGVja2VkKGRhdGE6IGFueSwgY2hlY2tlZDogYm9vbGVhbiwgZXZlbnQ/OiBFdmVudCkge1xyXG4gICAgaWYgKGV2ZW50KSB7XHJcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOyAvLyDpmLvmraLkuovku7blhpLms6HvvIzpgb/lhY3op6blj5HooYzngrnlh7tcclxuICAgIH1cclxuICAgIC8vIOWmguaenOihjOiiq+emgeeUqO+8jOS4jeWFgeiuuOWIh+aNoumAieS4reeKtuaAgVxyXG4gICAgaWYgKHRoaXMuaXNSb3dEaXNhYmxlZChkYXRhKSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBjb25zdCBpbmRleCA9IHRoaXMuX3NlbGVjdGVkUm93cy5maW5kSW5kZXgoXHJcbiAgICAgIChyb3cpID0+IEpTT04uc3RyaW5naWZ5KHJvdykgPT09IEpTT04uc3RyaW5naWZ5KGRhdGEpXHJcbiAgICApO1xyXG4gICAgaWYgKGNoZWNrZWQpIHtcclxuICAgICAgLy8g6YCJ5LitXHJcbiAgICAgIGlmIChpbmRleCA9PT0gLTEpIHtcclxuICAgICAgICB0aGlzLl9zZWxlY3RlZFJvd3MucHVzaChkYXRhKTtcclxuICAgICAgfVxyXG4gICAgICAvLyDli77pgInlpI3pgInmoYbml7blkIzmraXorr7nva7pq5jkuq7pgInkuK3ooYxcclxuICAgICAgdGhpcy5fc2VsZWN0ZWRUYWJsZVJvdyA9IGRhdGE7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAvLyDlj5bmtojpgInkuK1cclxuICAgICAgaWYgKGluZGV4ID4gLTEpIHtcclxuICAgICAgICB0aGlzLl9zZWxlY3RlZFJvd3Muc3BsaWNlKGluZGV4LCAxKTtcclxuICAgICAgfVxyXG4gICAgICAvLyDoi6XlvZPliY3pq5jkuq7ooYzkuLror6XooYzvvIzliJnlj5bmtojpq5jkuq5cclxuICAgICAgaWYgKFxyXG4gICAgICAgIHRoaXMuX3NlbGVjdGVkVGFibGVSb3cgJiZcclxuICAgICAgICBKU09OLnN0cmluZ2lmeSh0aGlzLl9zZWxlY3RlZFRhYmxlUm93KSA9PT0gSlNPTi5zdHJpbmdpZnkoZGF0YSlcclxuICAgICAgKSB7XHJcbiAgICAgICAgdGhpcy5fc2VsZWN0ZWRUYWJsZVJvdyA9IG51bGw7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHRoaXMudXBkYXRlQ2hlY2tBbGxTdGF0dXMoKTtcclxuICB9XHJcblxyXG4gIC8vIOabtOaWsOWFqOmAieeKtuaAgVxyXG4gIHVwZGF0ZUNoZWNrQWxsU3RhdHVzKCkge1xyXG4gICAgaWYgKCF0aGlzLnNob3dDaGVja2JveCB8fCAhQXJyYXkuaXNBcnJheSh0aGlzLmRhdGFTb3VyY2UpKSB7XHJcbiAgICAgIHRoaXMuX2NoZWNrZWRBbGwgPSBmYWxzZTtcclxuICAgICAgdGhpcy5faW5kZXRlcm1pbmF0ZSA9IGZhbHNlO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICAvLyDlj6rorqHnrpflj6/nlKjnmoTooYzvvIjmnKrnpoHnlKjnmoTooYzvvIlcclxuICAgIGNvbnN0IGF2YWlsYWJsZVJvd3MgPSB0aGlzLmRhdGFTb3VyY2UuZmlsdGVyKFxyXG4gICAgICAocm93KSA9PiAhdGhpcy5pc1Jvd0Rpc2FibGVkKHJvdylcclxuICAgICk7XHJcbiAgICBjb25zdCBjaGVja2VkQ291bnQgPSB0aGlzLl9zZWxlY3RlZFJvd3MubGVuZ3RoO1xyXG4gICAgY29uc3QgdG90YWxDb3VudCA9IGF2YWlsYWJsZVJvd3MubGVuZ3RoO1xyXG4gICAgdGhpcy5fY2hlY2tlZEFsbCA9XHJcbiAgICAgIHRvdGFsQ291bnQgPiAwICYmIGNoZWNrZWRDb3VudCA+IDAgJiYgY2hlY2tlZENvdW50ID09PSB0b3RhbENvdW50O1xyXG4gICAgdGhpcy5faW5kZXRlcm1pbmF0ZSA9IGNoZWNrZWRDb3VudCA+IDAgJiYgY2hlY2tlZENvdW50IDwgdG90YWxDb3VudDtcclxuICB9XHJcblxyXG4gIC8vIOWFqOmAiS/lj5bmtojlhajpgIlcclxuICB0b2dnbGVDaGVja0FsbChjaGVja2VkOiBib29sZWFuLCBldmVudD86IEV2ZW50KSB7XHJcbiAgICBpZiAoZXZlbnQpIHtcclxuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICB9XHJcbiAgICBpZiAoY2hlY2tlZCkge1xyXG4gICAgICAvLyDlhajpgInvvJrlj6rpgInkuK3mnKrnpoHnlKjnmoTooYxcclxuICAgICAgdGhpcy5fc2VsZWN0ZWRSb3dzID0gdGhpcy5kYXRhU291cmNlLmZpbHRlcihcclxuICAgICAgICAocm93KSA9PiAhdGhpcy5pc1Jvd0Rpc2FibGVkKHJvdylcclxuICAgICAgKTtcclxuICAgICAgLy8g5ZCM5q2l6K6+572u6auY5Lqu6YCJ5Lit6KGM5Li656ys5LiA5p2h5Y+v6YCJ5pWw5o2uXHJcbiAgICAgIGNvbnN0IGF2YWlsYWJsZVJvd3MgPSB0aGlzLl9zZWxlY3RlZFJvd3M7XHJcbiAgICAgIHRoaXMuX3NlbGVjdGVkVGFibGVSb3cgPVxyXG4gICAgICAgIGF2YWlsYWJsZVJvd3MubGVuZ3RoID4gMCA/IGF2YWlsYWJsZVJvd3NbMF0gOiBudWxsO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgLy8g5Y+W5raI5YWo6YCJXHJcbiAgICAgIHRoaXMuX3NlbGVjdGVkUm93cyA9IFtdO1xyXG4gICAgICAvLyDlj5bmtojpq5jkuq5cclxuICAgICAgdGhpcy5fc2VsZWN0ZWRUYWJsZVJvdyA9IG51bGw7XHJcbiAgICB9XHJcbiAgICB0aGlzLnVwZGF0ZUNoZWNrQWxsU3RhdHVzKCk7XHJcbiAgfVxyXG5cclxuICAvLyDojrflj5bpgInkuK3nmoTooYzmlbDmja5cclxuICBnZXRTZWxlY3RlZFJvd3MoKTogYW55W10ge1xyXG4gICAgcmV0dXJuIHRoaXMuX3NlbGVjdGVkUm93cztcclxuICB9XHJcblxyXG4gIC8vIOa4heepuumAieS4reeahOihjFxyXG4gIGNsZWFyU2VsZWN0ZWRSb3dzKCkge1xyXG4gICAgdGhpcy5fc2VsZWN0ZWRSb3dzID0gW107XHJcbiAgICB0aGlzLl9jaGVja2VkQWxsID0gZmFsc2U7XHJcbiAgICB0aGlzLl9pbmRldGVybWluYXRlID0gZmFsc2U7XHJcbiAgICB0aGlzLl9zZWxlY3RlZFRhYmxlUm93ID0gbnVsbDtcclxuICB9XHJcblxyXG4gIGhhbmRsZUZpZWxkQ2hlY2tCb3hDaGFuZ2UoY2hlY2tCb3hPcHRpb25zOiBPcHRpb25zVHlwZVtdLCBrZXk6IHN0cmluZykge1xyXG4gICAgdGhpcy5zZXRGaWVsZHNWYWx1ZSh7XHJcbiAgICAgIFtrZXldOiBjaGVja0JveE9wdGlvbnNcclxuICAgICAgICAuZmlsdGVyKChpdGVtKSA9PiBpdGVtLmNoZWNrZWQpXHJcbiAgICAgICAgLm1hcCgoaXRlbSkgPT4gaXRlbS52YWx1ZSksXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIGhhbmRsZVNlYXJjaCgpIHtcclxuICAgIHRoaXMuX3NhdmVkU2VhcmNoUGFyYW1zID0gdGhpcy5jbGVhckVtcHR5U2VhcmNoUGFyYW1zKCk7XHJcbiAgICB0aGlzLl9wYWdlSW5mby5wYWdlSW5kZXggPSAxO1xyXG4gICAgdGhpcy5oYW5kbGVRdWVyeSgpO1xyXG4gIH1cclxuXHJcbiAgaGFuZGxlUmVzZXRGb3JtKCkge1xyXG4gICAgT2JqZWN0LmtleXModGhpcy5fc2VhcmNoUGFyYW1zKS5mb3JFYWNoKChrZXkpID0+IHtcclxuICAgICAgY29uc3QgdGFyZ2V0Q29sdW1uID0gdGhpcy5fc2VhcmNoRmlsZWRDb2x1bW5zLmZpbmQoKGl0ZW0pID0+IHtcclxuICAgICAgICByZXR1cm4gKGl0ZW0uZmllbGRQcm9wcz8ubmFtZSB8fCBpdGVtLnByb3ApID09PSBrZXk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgLy8g5a+55LqOY2hlY2tib3jnsbvlnovvvIzpnIDopoHnibnmrorlpITnkIbpu5jorqTlgLxcclxuICAgICAgaWYgKHRhcmdldENvbHVtbj8udmFsdWVUeXBlID09PSBcImNoZWNrYm94XCIpIHtcclxuICAgICAgICAvLyDku47ljp/lp4tjb2x1bW5z6YWN572u5Lit6I635Y+W5Yid5aeL6YWN572u77yM5Lul56Gu5L+d5L2/55So5q2j56Gu55qE6buY6K6k5YC8XHJcbiAgICAgICAgY29uc3Qgb3JpZ2luYWxDb2x1bW4gPSB0aGlzLmNvbHVtbnMuZmluZCgoaXRlbSkgPT4ge1xyXG4gICAgICAgICAgcmV0dXJuIChpdGVtLmZpZWxkUHJvcHM/Lm5hbWUgfHwgaXRlbS5wcm9wKSA9PT0ga2V5O1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICAvLyDku47ljp/lp4tvcHRpb25z5Lit5om+5Ye6Y2hlY2tlZOS4unRydWXnmoTpobnkvZzkuLrpu5jorqTlgLxcclxuICAgICAgICBjb25zdCBvcmlnaW5hbEZpZWxkUHJvcHMgPSBvcmlnaW5hbENvbHVtbj8uZmllbGRQcm9wcyBhc1xyXG4gICAgICAgICAgfCBDaGVja2JveEZpZWxkUHJvcHNcclxuICAgICAgICAgIHwgdW5kZWZpbmVkO1xyXG4gICAgICAgIGNvbnN0IGNoZWNrZWRWYWx1ZXMgPSAob3JpZ2luYWxGaWVsZFByb3BzPy5vcHRpb25zIHx8IFtdKVxyXG4gICAgICAgICAgLmZpbHRlcigob3B0OiBPcHRpb25zVHlwZSkgPT4gb3B0LmNoZWNrZWQpXHJcbiAgICAgICAgICAubWFwKChvcHQ6IE9wdGlvbnNUeXBlKSA9PiBvcHQudmFsdWUpO1xyXG4gICAgICAgIGNvbnN0IGRlZmF1bHRWYWx1ZSA9XHJcbiAgICAgICAgICBjaGVja2VkVmFsdWVzLmxlbmd0aCA+IDBcclxuICAgICAgICAgICAgPyBjaGVja2VkVmFsdWVzXHJcbiAgICAgICAgICAgIDogUFJPX1RBQkxFX0RFRkFVTFRfUFJPUFNbdGFyZ2V0Q29sdW1uLnZhbHVlVHlwZV0udmFsdWU7XHJcblxyXG4gICAgICAgIHRoaXMuX3NlYXJjaFBhcmFtc1trZXldID0gZGVmYXVsdFZhbHVlO1xyXG5cclxuICAgICAgICAvLyDmoLnmja7pu5jorqTlgLzmgaLlpI1vcHRpb25z55qEY2hlY2tlZOeKtuaAge+8jOS9v+eUqOWOn+Wni29wdGlvbnPnmoTnu5PmnoRcclxuICAgICAgICBjb25zdCBkZWZhdWx0VmFsdWVzID0gQXJyYXkuaXNBcnJheShkZWZhdWx0VmFsdWUpID8gZGVmYXVsdFZhbHVlIDogW107XHJcbiAgICAgICAgY29uc3Qgb3JpZ2luYWxPcHRpb25zID0gb3JpZ2luYWxGaWVsZFByb3BzPy5vcHRpb25zIHx8IFtdO1xyXG4gICAgICAgIGNvbnN0IHRhcmdldEZpZWxkUHJvcHMgPSB0YXJnZXRDb2x1bW4uZmllbGRQcm9wcyBhcyBDaGVja2JveEZpZWxkUHJvcHM7XHJcbiAgICAgICAgdGFyZ2V0RmllbGRQcm9wcy5vcHRpb25zID0gb3JpZ2luYWxPcHRpb25zLm1hcCgoaXRlbTogT3B0aW9uc1R5cGUpID0+IHtcclxuICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIC4uLml0ZW0sXHJcbiAgICAgICAgICAgIGNoZWNrZWQ6IGRlZmF1bHRWYWx1ZXMuaW5jbHVkZXMoaXRlbS52YWx1ZSksXHJcbiAgICAgICAgICB9O1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuX3NlYXJjaFBhcmFtc1trZXldID0gdGFyZ2V0Q29sdW1uPy5maWVsZFByb3BzXHJcbiAgICAgICAgICA/IHRhcmdldENvbHVtbj8uZmllbGRQcm9wcy52YWx1ZSB8fFxyXG4gICAgICAgICAgICBQUk9fVEFCTEVfREVGQVVMVF9QUk9QU1t0YXJnZXRDb2x1bW4udmFsdWVUeXBlXS52YWx1ZVxyXG4gICAgICAgICAgOiBQUk9fVEFCTEVfREVGQVVMVF9QUk9QU1t0YXJnZXRDb2x1bW4udmFsdWVUeXBlXS52YWx1ZTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5fc2F2ZWRTZWFyY2hQYXJhbXMgPSB7fTtcclxuICAgIHRoaXMuX3BhZ2VJbmZvLnBhZ2VJbmRleCA9IDE7XHJcbiAgICB0aGlzLm9uUmVzZXRGb3JtQmVmb3JlUmVsb2FkLmVtaXQoKTtcclxuICAgIHRoaXMuaGFuZGxlUXVlcnkoKTtcclxuICB9XHJcblxyXG4gIGhhbmRsZVBhZ2VJbmRleENoYW5nZShwYWdlSW5kZXg6IG51bWJlcikge1xyXG4gICAgdGhpcy5fcGFnZUluZm8ucGFnZUluZGV4ID0gcGFnZUluZGV4O1xyXG4gICAgdGhpcy5oYW5kbGVRdWVyeSgpO1xyXG4gIH1cclxuXHJcbiAgaGFuZGxlUGFnZVNpemVDaGFuZ2UocGFnZVNpemU6IGFueSkge1xyXG4gICAgdGhpcy5fcGFnZUluZm8ucGFnZVNpemUgPSBwYWdlU2l6ZTtcclxuICAgIHRoaXMuX3BhZ2VJbmZvLnBhZ2VJbmRleCA9IDE7XHJcbiAgICB0aGlzLmhhbmRsZVF1ZXJ5KCk7XHJcbiAgfVxyXG5cclxuICBhc3luYyBoYW5kbGVRdWVyeShhZnRlckRlbGV0ZT86IGJvb2xlYW4pIHtcclxuICAgIC8vIOWIoOmZpOWQjuWIt+aWsOS4lOW9k+WJjemhteS7heWJqeS4gOadoeiusOW9leaXtu+8jOiLpeS4jeWcqOesrOS4gOmhteWImeWFiOWbnumAgOS4gOmhtVxyXG4gICAgaWYgKFxyXG4gICAgICBhZnRlckRlbGV0ZSAmJlxyXG4gICAgICBBcnJheS5pc0FycmF5KHRoaXMuZGF0YVNvdXJjZSkgJiZcclxuICAgICAgdGhpcy5kYXRhU291cmNlLmxlbmd0aCA9PT0gMSAmJlxyXG4gICAgICB0aGlzLl9wYWdlSW5mby5wYWdlSW5kZXggPiAxXHJcbiAgICApIHtcclxuICAgICAgdGhpcy5fcGFnZUluZm8ucGFnZUluZGV4ID0gdGhpcy5fcGFnZUluZm8ucGFnZUluZGV4IC0gMTtcclxuICAgIH1cclxuICAgIHRoaXMuX2xvYWRpbmcgPSB0cnVlO1xyXG4gICAgaWYgKHRoaXMucmVxdWVzdCkge1xyXG4gICAgICB0cnkge1xyXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMucmVxdWVzdCh7XHJcbiAgICAgICAgICBwYXJhbXM6IHRoaXMuY2xlYXJFbXB0eVNlYXJjaFBhcmFtcygpLFxyXG4gICAgICAgICAgcGFnZUluZm86IHtcclxuICAgICAgICAgICAgcGFnZUluZGV4OiB0aGlzLl9wYWdlSW5mby5wYWdlSW5kZXgsXHJcbiAgICAgICAgICAgIHBhZ2VTaXplOiB0aGlzLl9wYWdlSW5mby5wYWdlU2l6ZSxcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgICAvLyDlnKjnur/mjpLluo/mqKHlvI/vvJrmiormjpLluo/lr7nosaHmj5DkuqTnu5nmjqXlj6NcclxuICAgICAgICAgIC4uLih0aGlzLnNvcnRNb2RlID09PSBcInNlcnZlclwiXHJcbiAgICAgICAgICAgID8geyBzb3J0OiB0aGlzLmJ1aWxkU2VydmVyU29ydFBheWxvYWQoKSB9XHJcbiAgICAgICAgICAgIDoge30pLFxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMuZGF0YVNvdXJjZSA9IHJlc3VsdC5kYXRhIHx8IFtdO1xyXG4gICAgICAgIHRoaXMuc3VtbWFyeURhdGEgPSByZXN1bHQuc3VtbWFyeURhdGEgfHwgbnVsbDtcclxuICAgICAgICAvLyDmnKzlnLDmjpLluo/mqKHlvI/vvJrmi7/liLDmlbDmja7lkI7lnKjliY3nq6/mjpLluo9cclxuICAgICAgICBpZiAodGhpcy5zb3J0TW9kZSA9PT0gXCJsb2NhbFwiKSB7XHJcbiAgICAgICAgICB0aGlzLnNvcnREYXRhU291cmNlSW5QbGFjZSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9wYWdlSW5mby50b3RhbCA9IHJlc3VsdC50b3RhbCB8fCAwO1xyXG4gICAgICAgIC8vIOabtOaWsOWFqOmAieeKtuaAgVxyXG4gICAgICAgIGlmICh0aGlzLnNob3dDaGVja2JveCkge1xyXG4gICAgICAgICAgdGhpcy51cGRhdGVDaGVja0FsbFN0YXR1cygpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICBjb25zb2xlLmVycm9yKFwi5p+l6K+i5aSx6LSlOlwiLCBlcnJvcik7XHJcbiAgICAgICAgdGhpcy5kYXRhU291cmNlID0gW107XHJcbiAgICAgICAgdGhpcy5fcGFnZUluZm8udG90YWwgPSAwO1xyXG4gICAgICAgIHRoaXMuc3VtbWFyeURhdGEgPSBudWxsO1xyXG4gICAgICB9IGZpbmFsbHkge1xyXG4gICAgICAgIHRoaXMuX2xvYWRpbmcgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLl9zZWxlY3RlZFRhYmxlUm93ID0gbnVsbDtcclxuICAgICAgICAvLyDmuIXnqbrpgInkuK3ooYzvvIjlj6/pgInvvIzmoLnmja7kuJrliqHpnIDmsYLlhrPlrprmmK/lkKbkv53nlZnot6jpobXpgInkuK3vvIlcclxuICAgICAgICAvLyB0aGlzLmNsZWFyU2VsZWN0ZWRSb3dzKCk7XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGNvbnNvbGUud2FybihcIuacquaPkOS+myBfcmVxdWVzdCDlm57osIPlh73mlbBcIik7XHJcbiAgICAgIHRoaXMuX2xvYWRpbmcgPSBmYWxzZTtcclxuICAgIH1cclxuICAgIHRoaXMuY2xlYXJTZWxlY3RlZFJvd3MoKTtcclxuICB9XHJcblxyXG4gIC8vIOinpuWPkeWIl+aOkuW6j+WPmOabtFxyXG4gIG9uU29ydENoYW5nZShzb3J0S2V5OiBzdHJpbmcsIHNvcnRPcmRlcjogXCJhc2NlbmRcIiB8IFwiZGVzY2VuZFwiIHwgbnVsbCkge1xyXG4gICAgLy8g5Y2V5YiX5o6S5bqP77ya6YeN572u5YW25a6D5YiX77yb5aSa5YiX5o6S5bqP77ya5L+d55WZ5YW25a6D5YiXXHJcbiAgICBpZiAoIXRoaXMubXVsdGlwbGVTb3J0KSB7XHJcbiAgICAgIE9iamVjdC5rZXlzKHRoaXMuX3NvcnRNYXApLmZvckVhY2goKGtleSkgPT4ge1xyXG4gICAgICAgIGlmIChrZXkgIT09IHNvcnRLZXkpIHRoaXMuX3NvcnRNYXBba2V5XSA9IG51bGw7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgdGhpcy5fc29ydE1hcFtzb3J0S2V5XSA9IHNvcnRPcmRlcjtcclxuXHJcbiAgICAvLyDnu7TmiqTkvJjlhYjnuqfpmJ/liJfvvJrmnInluo/liJfkuJTpnZ7nqbogLT4g572u5LqO5pyr5bC+77yb5Li656m6IC0+IOenu+mZpFxyXG4gICAgdGhpcy5fc29ydFByaW9yaXR5ID0gdGhpcy5fc29ydFByaW9yaXR5LmZpbHRlcigoaykgPT4gayAhPT0gc29ydEtleSk7XHJcbiAgICBpZiAoc29ydE9yZGVyKSB7XHJcbiAgICAgIHRoaXMuX3NvcnRQcmlvcml0eS5wdXNoKHNvcnRLZXkpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLnNvcnRNb2RlID09PSBcImxvY2FsXCIpIHtcclxuICAgICAgdGhpcy5zb3J0RGF0YVNvdXJjZUluUGxhY2UoKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIC8vIOWcqOe6v+aOkuW6j++8mumHjeaWsOivt+axglxyXG4gICAgICB0aGlzLmhhbmRsZVF1ZXJ5KCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnZXRTb3J0T3JkZXIoc29ydEtleTogc3RyaW5nKTogXCJhc2NlbmRcIiB8IFwiZGVzY2VuZFwiIHwgbnVsbCB7XHJcbiAgICByZXR1cm4gdGhpcy5fc29ydE1hcFtzb3J0S2V5XSB8fCBudWxsO1xyXG4gIH1cclxuXHJcbiAgaGFuZGxlVGFibGVSb3dDbGljayhkYXRhOiBhbnkpIHtcclxuICAgIHRoaXMuX3NlbGVjdGVkVGFibGVSb3cgPSBkYXRhO1xyXG4gICAgLy8g5aaC5p6c5byA5ZCv5LqG5aSN6YCJ5qGG77yM54K55Ye76KGM5pe25Y+q6YCJ5Lit54K55Ye76KGM77yI5aaC5p6c6KGM5pyq6KKr56aB55So77yJXHJcbiAgICBpZiAodGhpcy5zaG93Q2hlY2tib3ggJiYgIXRoaXMuaXNSb3dEaXNhYmxlZChkYXRhKSkge1xyXG4gICAgICAvLyDlhYjmuIXnqbrmiYDmnInpgInkuK3ooYxcclxuICAgICAgdGhpcy5fc2VsZWN0ZWRSb3dzID0gW107XHJcbiAgICAgIC8vIOWPqumAieS4reW9k+WJjeeCueWHu+eahOihjFxyXG4gICAgICB0aGlzLnRvZ2dsZVJvd0NoZWNrZWQoZGF0YSwgdHJ1ZSk7XHJcbiAgICB9XHJcbiAgICB0aGlzLm9uUm93Q2xpY2suZW1pdCh0aGlzLl9zZWxlY3RlZFRhYmxlUm93KTtcclxuICB9XHJcblxyXG4gIGhhbmRsZVRhYmxlUm93RGJDbGljayhkYXRhOiBhbnkpIHtcclxuICAgIHRoaXMuX3NlbGVjdGVkVGFibGVSb3cgPSBkYXRhO1xyXG4gICAgdGhpcy5vblJvd0RiQ2xpY2suZW1pdCh0aGlzLl9zZWxlY3RlZFRhYmxlUm93KTtcclxuICB9XHJcblxyXG4gIGhhbmRsZUNvbHVtbnNTZXR0aW5nQ29uZmlybSgpIHtcclxuICAgIHRoaXMucXVlcnlEeW5hbWljQ29sdW1ucygpO1xyXG4gIH1cclxuXHJcbiAgLy8g5aSE55CGIGF1dG9Db21wbGV0ZSDovpPlhaXkuovku7bvvIjluKbpmLLmipbvvIlcclxuICBoYW5kbGVBdXRvQ29tcGxldGVJbnB1dChldmVudDogRXZlbnQsIGNvbHVtbjogUHJvVGFibGVDb2x1bW4pIHtcclxuICAgIGNvbnN0IGZpZWxkS2V5ID0gY29sdW1uLmZpZWxkUHJvcHM/Lm5hbWUgfHwgY29sdW1uLnByb3A7XHJcblxyXG4gICAgLy8g5aaC5p6c6K+l5a2X5q616L+Y5rKh5pyJ6Ziy5oqW5Ye95pWw77yM5Yib5bu65LiA5LiqXHJcbiAgICBpZiAoIXRoaXMuX2F1dG9Db21wbGV0ZURlYm91bmNlTWFwLmhhcyhmaWVsZEtleSkpIHtcclxuICAgICAgY29uc3QgZGVib3VuY2VkRm4gPSBkZWJvdW5jZSgoZXZ0OiBFdmVudCkgPT4ge1xyXG4gICAgICAgIC8vIOmHjeaWsOafpeaJvuWvueW6lOeahCBjb2x1bW7vvIznoa7kv53kvb/nlKjmnIDmlrDnmoTphY3nva5cclxuICAgICAgICBjb25zdCBjdXJyZW50Q29sdW1uID0gdGhpcy5fc2VhcmNoRmlsZWRDb2x1bW5zLmZpbmQoXHJcbiAgICAgICAgICAoY29sKSA9PiAoY29sLmZpZWxkUHJvcHM/Lm5hbWUgfHwgY29sLnByb3ApID09PSBmaWVsZEtleVxyXG4gICAgICAgICk7XHJcbiAgICAgICAgaWYgKGN1cnJlbnRDb2x1bW4pIHtcclxuICAgICAgICAgIHRoaXMuZXhlY3V0ZUF1dG9Db21wbGV0ZURhdGFTb3VyY2UoZXZ0LCBjdXJyZW50Q29sdW1uKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0sIDMwMCk7IC8vIDMwMG1zIOmYsuaKluW7tui/n1xyXG4gICAgICB0aGlzLl9hdXRvQ29tcGxldGVEZWJvdW5jZU1hcC5zZXQoZmllbGRLZXksIGRlYm91bmNlZEZuKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyDosIPnlKjpmLLmipblh73mlbBcclxuICAgIGNvbnN0IGRlYm91bmNlZEZuID0gdGhpcy5fYXV0b0NvbXBsZXRlRGVib3VuY2VNYXAuZ2V0KGZpZWxkS2V5KTtcclxuICAgIGlmIChkZWJvdW5jZWRGbikge1xyXG4gICAgICBkZWJvdW5jZWRGbihldmVudCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyDojrflj5YgYXV0b0NvbXBsZXRlIOeahOaVsOaNrua6kFxyXG4gIGdldEF1dG9Db21wbGV0ZURhdGFTb3VyY2UoY29sdW1uOiBQcm9UYWJsZUNvbHVtbik6IGFueVtdIHtcclxuICAgIGNvbnN0IGZpZWxkS2V5ID0gY29sdW1uLmZpZWxkUHJvcHM/Lm5hbWUgfHwgY29sdW1uLnByb3A7XHJcbiAgICByZXR1cm4gdGhpcy5fYXV0b0NvbXBsZXRlRGF0YVNvdXJjZXNbZmllbGRLZXldIHx8IFtdO1xyXG4gIH1cclxuXHJcbiAgZ2V0RmllbGRQcm9wcyhjb2x1bW46IFByb1RhYmxlQ29sdW1uKTogYW55IHtcclxuICAgIHJldHVybiBjb2x1bW4uZmllbGRQcm9wcztcclxuICB9XHJcblxyXG4gIC8vIOiOt+WPluaMh+WumuWQjeensOeahGxhYmVs5qih5p2/XHJcbiAgZ2V0TGFiZWxUZW1wbGF0ZShuYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBUZW1wbGF0ZVJlZjxhbnk+IHwgbnVsbCB7XHJcbiAgICBpZiAoIW5hbWUpIHJldHVybiBudWxsO1xyXG4gICAgdHJ5IHtcclxuICAgICAgLy8g6aaW5YWI5LuO6Ieq5a6a5LmJ5qih5p2/5Lit5p+l5om+XHJcbiAgICAgIGNvbnN0IGN1c3RvbVRlbXBsYXRlID0gdGhpcy5jdXN0b21UZW1wbGF0ZXMuZ2V0KG5hbWUpO1xyXG4gICAgICBpZiAoY3VzdG9tVGVtcGxhdGUpIHtcclxuICAgICAgICByZXR1cm4gY3VzdG9tVGVtcGxhdGU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIOeEtuWQjuS7jumAmueUqOaooeadv+aYoOWwhOS4reafpeaJvlxyXG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IHRoaXMudGVtcGxhdGVNYXAuZ2V0KG5hbWUpO1xyXG4gICAgICBpZiAodGVtcGxhdGUpIHtcclxuICAgICAgICByZXR1cm4gdGVtcGxhdGU7XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIOiOt+WPliBmb3JtLWl0ZW0g55qE5Yqo5oCB57G75ZCNXHJcbiAgZ2V0Rm9ybUl0ZW1DbGFzc05hbWUoY29sdW1uOiBQcm9UYWJsZUNvbHVtbik6IHN0cmluZyB7XHJcbiAgICBjb25zdCBmaWVsZE5hbWUgPSB0aGlzLmdldEZpZWxkUHJvcHMoY29sdW1uKS5uYW1lIHx8IGNvbHVtbi5wcm9wO1xyXG4gICAgcmV0dXJuIGBwcm8tdGFibGUtJHtmaWVsZE5hbWV9LWZvcm0taXRlbWA7XHJcbiAgfVxyXG59XHJcbiJdfQ==