@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,734 @@
1
+ import { __rest } from "tslib";
2
+ import { Injectable } from "@angular/core";
3
+ import { FormArray, FormBuilder, FormGroup, } from "@angular/forms";
4
+ import { debounceTime, distinctUntilChanged } from "rxjs/operators";
5
+ import * as i0 from "@angular/core";
6
+ import * as i1 from "@angular/forms";
7
+ // ==================== 服务类 ====================
8
+ export class AntdFormService {
9
+ // ==================== 构造函数 ====================
10
+ constructor(fb) {
11
+ this.fb = fb;
12
+ // ==================== 公共属性 ====================
13
+ this.formStore = {};
14
+ this.formModifyType = "create";
15
+ // ==================== 私有属性 ====================
16
+ this.labelWidth = "120px";
17
+ this.labelAlign = "right";
18
+ this.labelObservers = {};
19
+ this.errorMessageStore = {};
20
+ this.formArrayConfigStore = {};
21
+ this.INTERNAL_ID_FIELD = "__formItemId";
22
+ this.classPrefix = "ant-form-";
23
+ this.defaultErrorMessages = {
24
+ required: "该字段为必填项",
25
+ minlength: "输入长度不足",
26
+ maxlength: "输入长度超限",
27
+ email: "请输入合法的邮箱地址",
28
+ pattern: "输入格式不正确",
29
+ };
30
+ }
31
+ // ==================== 表单创建和初始化 ====================
32
+ // 初始化表单(支持 FormArray)
33
+ createFormGroup(name, config, options) {
34
+ const groupConfig = {};
35
+ this.errorMessageStore[name] = {};
36
+ Object.entries(config).forEach(([key, field]) => {
37
+ var _a, _b, _c;
38
+ if (this.isFormArrayConfig(field)) {
39
+ // FormArray 配置处理
40
+ if (!this.formArrayConfigStore[name]) {
41
+ this.formArrayConfigStore[name] = {};
42
+ }
43
+ this.formArrayConfigStore[name][key] = {
44
+ itemConfig: field.itemConfig,
45
+ uniqueIdField: field.uniqueIdField,
46
+ };
47
+ const formArray = this.createFormArrayFromConfig(name, key, field.itemConfig, field.initialItems || [], field.uniqueIdField);
48
+ groupConfig[key] = formArray;
49
+ // 存储 FormArray 字段的错误消息配置,格式:arrayName[].fieldName
50
+ if (field.errorMessages) {
51
+ Object.entries(field.errorMessages).forEach(([fieldName, errorMessages]) => {
52
+ const errorMessageKey = `${key}[].${fieldName}`;
53
+ this.errorMessageStore[name][errorMessageKey] = errorMessages;
54
+ });
55
+ }
56
+ }
57
+ else {
58
+ // 普通字段配置
59
+ const fieldConfig = field;
60
+ groupConfig[key] = [
61
+ { value: fieldConfig.value, disabled: (_a = fieldConfig.disabled) !== null && _a !== void 0 ? _a : false },
62
+ (_c = (_b = fieldConfig.validators) === null || _b === void 0 ? void 0 : _b.call(fieldConfig)) !== null && _c !== void 0 ? _c : [],
63
+ ];
64
+ if (fieldConfig.errorMessages) {
65
+ this.errorMessageStore[name][key] = fieldConfig.errorMessages;
66
+ }
67
+ }
68
+ });
69
+ if (options === null || options === void 0 ? void 0 : options.labelWidth) {
70
+ this.labelWidth = options.labelWidth;
71
+ }
72
+ if (options === null || options === void 0 ? void 0 : options.labelAlign) {
73
+ this.labelAlign = options.labelAlign;
74
+ }
75
+ this.formStore[name] = this.fb.group(groupConfig);
76
+ this.setCSSVariablesToTarget(name);
77
+ return this.formStore[name];
78
+ }
79
+ // ==================== 表单操作 ====================
80
+ // 重置表单
81
+ resetFormGroup(name, value) {
82
+ var _a;
83
+ (_a = this.formStore[name]) === null || _a === void 0 ? void 0 : _a.reset(value);
84
+ }
85
+ // 批量添加字段配置
86
+ addFieldsConfig(formName, fieldsConfig, options) {
87
+ var _a;
88
+ const result = {
89
+ success: true,
90
+ added: [],
91
+ failed: [],
92
+ };
93
+ // 1. 验证表单是否存在
94
+ const formGroup = this.formStore[formName];
95
+ if (!formGroup) {
96
+ // 如果表单不存在,所有字段都失败
97
+ Object.keys(fieldsConfig).forEach((fieldName) => {
98
+ var _a;
99
+ const error = `Form "${formName}" not found`;
100
+ result.failed.push({
101
+ fieldName,
102
+ error,
103
+ });
104
+ (_a = options === null || options === void 0 ? void 0 : options.onFieldAdded) === null || _a === void 0 ? void 0 : _a.call(options, fieldName, false, error);
105
+ });
106
+ result.success = false;
107
+ return result;
108
+ }
109
+ // 2. 初始化 errorMessageStore 和 formArrayConfigStore(如果不存在)
110
+ if (!this.errorMessageStore[formName]) {
111
+ this.errorMessageStore[formName] = {};
112
+ }
113
+ if (!this.formArrayConfigStore[formName]) {
114
+ this.formArrayConfigStore[formName] = {};
115
+ }
116
+ // 3. 批量构建控件配置
117
+ const controlsToAdd = {};
118
+ const errorMessagesToAdd = {};
119
+ const formArrayConfigsToAdd = {};
120
+ // 4. 遍历所有字段配置,进行验证和构建
121
+ Object.entries(fieldsConfig).forEach(([fieldName, fieldConfig]) => {
122
+ var _a, _b, _c, _d, _e;
123
+ try {
124
+ // 4.1 检查字段是否已存在
125
+ if (formGroup.get(fieldName)) {
126
+ const error = `Field "${fieldName}" already exists`;
127
+ result.failed.push({
128
+ fieldName,
129
+ error,
130
+ });
131
+ (_a = options === null || options === void 0 ? void 0 : options.onFieldAdded) === null || _a === void 0 ? void 0 : _a.call(options, fieldName, false, error);
132
+ return;
133
+ }
134
+ // 4.2 根据字段类型创建控件
135
+ if (this.isFormArrayConfig(fieldConfig)) {
136
+ // FormArray 处理
137
+ const formArray = this.createFormArrayFromConfig(formName, fieldName, fieldConfig.itemConfig, fieldConfig.initialItems || [], fieldConfig.uniqueIdField);
138
+ controlsToAdd[fieldName] = formArray;
139
+ // 存储 FormArray 配置
140
+ formArrayConfigsToAdd[fieldName] = {
141
+ itemConfig: fieldConfig.itemConfig,
142
+ uniqueIdField: fieldConfig.uniqueIdField,
143
+ };
144
+ // 存储错误消息
145
+ if (fieldConfig.errorMessages) {
146
+ Object.entries(fieldConfig.errorMessages).forEach(([itemFieldName, errorMessages]) => {
147
+ const errorMessageKey = `${fieldName}[].${itemFieldName}`;
148
+ errorMessagesToAdd[errorMessageKey] = errorMessages;
149
+ });
150
+ }
151
+ }
152
+ else {
153
+ // 普通字段处理
154
+ const fieldConfigTyped = fieldConfig;
155
+ const controlOptions = {
156
+ validators: (_c = (_b = fieldConfigTyped.validators) === null || _b === void 0 ? void 0 : _b.call(fieldConfigTyped)) !== null && _c !== void 0 ? _c : [],
157
+ };
158
+ const control = this.fb.control(fieldConfigTyped.value, controlOptions);
159
+ // 设置 disabled 状态
160
+ if (fieldConfigTyped.disabled) {
161
+ control.disable();
162
+ }
163
+ controlsToAdd[fieldName] = control;
164
+ // 存储错误消息
165
+ if (fieldConfigTyped.errorMessages) {
166
+ errorMessagesToAdd[fieldName] = fieldConfigTyped.errorMessages;
167
+ }
168
+ }
169
+ result.added.push(fieldName);
170
+ (_d = options === null || options === void 0 ? void 0 : options.onFieldAdded) === null || _d === void 0 ? void 0 : _d.call(options, fieldName, true);
171
+ }
172
+ catch (error) {
173
+ const errorMessage = (error === null || error === void 0 ? void 0 : error.message) || (error === null || error === void 0 ? void 0 : error.toString()) || "Unknown error";
174
+ result.failed.push({
175
+ fieldName,
176
+ error: errorMessage,
177
+ });
178
+ (_e = options === null || options === void 0 ? void 0 : options.onFieldAdded) === null || _e === void 0 ? void 0 : _e.call(options, fieldName, false, errorMessage);
179
+ }
180
+ });
181
+ // 5. 批量添加到 FormGroup
182
+ if (Object.keys(controlsToAdd).length > 0) {
183
+ Object.entries(controlsToAdd).forEach(([fieldName, control]) => {
184
+ formGroup.addControl(fieldName, control);
185
+ });
186
+ // 6. 批量存储错误消息
187
+ Object.entries(errorMessagesToAdd).forEach(([key, messages]) => {
188
+ this.errorMessageStore[formName][key] = messages;
189
+ });
190
+ // 7. 批量存储 FormArray 配置
191
+ Object.entries(formArrayConfigsToAdd).forEach(([fieldName, config]) => {
192
+ this.formArrayConfigStore[formName][fieldName] = config;
193
+ });
194
+ // 8. 更新表单验证状态
195
+ if (options === null || options === void 0 ? void 0 : options.updateValueAndValidity) {
196
+ formGroup.updateValueAndValidity({
197
+ emitEvent: (_a = options === null || options === void 0 ? void 0 : options.emitEvent) !== null && _a !== void 0 ? _a : true,
198
+ });
199
+ }
200
+ }
201
+ // 9. 判断整体是否成功
202
+ result.success = result.failed.length === 0;
203
+ return result;
204
+ }
205
+ // 批量删除字段配置
206
+ removeFieldsConfig(formName, fieldNames, options) {
207
+ const result = {
208
+ success: true,
209
+ removed: [],
210
+ failed: [],
211
+ };
212
+ // 1. 验证表单是否存在
213
+ const formGroup = this.formStore[formName];
214
+ if (!formGroup) {
215
+ fieldNames.forEach((fieldName) => {
216
+ var _a;
217
+ const error = `Form "${formName}" not found`;
218
+ result.failed.push({
219
+ fieldName,
220
+ error,
221
+ });
222
+ (_a = options === null || options === void 0 ? void 0 : options.onFieldRemoved) === null || _a === void 0 ? void 0 : _a.call(options, fieldName, false, error);
223
+ });
224
+ result.success = false;
225
+ return result;
226
+ }
227
+ // 2. 批量收集需要清理的信息
228
+ const fieldsToRemove = [];
229
+ const errorMessageKeysToRemove = [];
230
+ const formArrayFields = [];
231
+ // 3. 验证每个字段并收集信息
232
+ fieldNames.forEach((fieldName) => {
233
+ var _a;
234
+ const control = formGroup.get(fieldName);
235
+ if (!control) {
236
+ const error = `Field "${fieldName}" not found`;
237
+ result.failed.push({
238
+ fieldName,
239
+ error,
240
+ });
241
+ (_a = options === null || options === void 0 ? void 0 : options.onFieldRemoved) === null || _a === void 0 ? void 0 : _a.call(options, fieldName, false, error);
242
+ return;
243
+ }
244
+ // 判断是否是 FormArray
245
+ if (control instanceof FormArray) {
246
+ formArrayFields.push(fieldName);
247
+ // 收集 FormArray 相关的错误消息键(格式:arrayName[].fieldName)
248
+ if (this.errorMessageStore[formName]) {
249
+ Object.keys(this.errorMessageStore[formName]).forEach((key) => {
250
+ if (key.startsWith(`${fieldName}[].`)) {
251
+ errorMessageKeysToRemove.push(key);
252
+ }
253
+ });
254
+ }
255
+ }
256
+ else {
257
+ // 普通字段的错误消息键
258
+ errorMessageKeysToRemove.push(fieldName);
259
+ }
260
+ fieldsToRemove.push(fieldName);
261
+ });
262
+ // 4. 批量执行删除操作
263
+ try {
264
+ // 4.1 从 FormGroup 中移除控件
265
+ fieldsToRemove.forEach((fieldName) => {
266
+ var _a;
267
+ formGroup.removeControl(fieldName);
268
+ result.removed.push(fieldName);
269
+ (_a = options === null || options === void 0 ? void 0 : options.onFieldRemoved) === null || _a === void 0 ? void 0 : _a.call(options, fieldName, true);
270
+ });
271
+ // 4.2 批量删除错误消息
272
+ if (this.errorMessageStore[formName]) {
273
+ errorMessageKeysToRemove.forEach((key) => {
274
+ delete this.errorMessageStore[formName][key];
275
+ });
276
+ }
277
+ // 4.3 批量删除 FormArray 配置
278
+ if (this.formArrayConfigStore[formName]) {
279
+ formArrayFields.forEach((fieldName) => {
280
+ delete this.formArrayConfigStore[formName][fieldName];
281
+ });
282
+ }
283
+ }
284
+ catch (error) {
285
+ // 如果批量删除过程中出错,标记为失败
286
+ fieldsToRemove.forEach((fieldName) => {
287
+ var _a;
288
+ if (!result.removed.includes(fieldName)) {
289
+ const errorMessage = (error === null || error === void 0 ? void 0 : error.message) || (error === null || error === void 0 ? void 0 : error.toString()) || "Failed to remove field";
290
+ result.failed.push({
291
+ fieldName,
292
+ error: errorMessage,
293
+ });
294
+ (_a = options === null || options === void 0 ? void 0 : options.onFieldRemoved) === null || _a === void 0 ? void 0 : _a.call(options, fieldName, false, errorMessage);
295
+ }
296
+ });
297
+ }
298
+ // 5. 判断整体是否成功
299
+ result.success = result.failed.length === 0;
300
+ return result;
301
+ }
302
+ // 局部赋值(支持 FormArray 的智能更新,统一根据 action 字段判断操作类型)
303
+ patchFormValues(name, values, options) {
304
+ var _a;
305
+ const formGroup = this.formStore[name];
306
+ if (!formGroup) {
307
+ console.warn(`[AntdFormService] patchFormValues: form "${name}" not found.`);
308
+ return;
309
+ }
310
+ const processedValues = {};
311
+ Object.entries(values).forEach(([key, value]) => {
312
+ const control = formGroup.get(key);
313
+ // 检测是否是 FormArray
314
+ if (control instanceof FormArray && Array.isArray(value)) {
315
+ this.patchFormArray(name, key, value);
316
+ return;
317
+ }
318
+ // 普通字段,直接加入
319
+ processedValues[key] = value;
320
+ });
321
+ // 处理普通字段
322
+ if (Object.keys(processedValues).length > 0) {
323
+ formGroup.patchValue(processedValues, {
324
+ emitEvent: (_a = options === null || options === void 0 ? void 0 : options.emitEvent) !== null && _a !== void 0 ? _a : true,
325
+ });
326
+ }
327
+ }
328
+ // 表单校验(自动过滤内部字段)
329
+ validateForm(name, options) {
330
+ var _a, _b;
331
+ if (this.formStore[name].valid) {
332
+ const rawValue = this.formStore[name].getRawValue();
333
+ return this.excludeInternalFields(rawValue);
334
+ }
335
+ else {
336
+ // 递归校验所有控件,包括 FormArray 中的项
337
+ this.markAllControlsAsDirty(this.formStore[name], (_a = options === null || options === void 0 ? void 0 : options.emitEvent) !== null && _a !== void 0 ? _a : true, (_b = options === null || options === void 0 ? void 0 : options.onlySelf) !== null && _b !== void 0 ? _b : false);
338
+ return false;
339
+ }
340
+ }
341
+ // 递归标记所有无效控件为 dirty(包括 FormArray 中的项)
342
+ markAllControlsAsDirty(control, emitEvent, onlySelf) {
343
+ if (control.invalid) {
344
+ control.markAsDirty();
345
+ control.updateValueAndValidity({
346
+ emitEvent,
347
+ onlySelf,
348
+ });
349
+ }
350
+ // 如果是 FormGroup,递归处理所有子控件
351
+ if (control instanceof FormGroup) {
352
+ Object.values(control.controls).forEach((childControl) => {
353
+ this.markAllControlsAsDirty(childControl, emitEvent, onlySelf);
354
+ });
355
+ }
356
+ // 如果是 FormArray,递归处理数组中的每一项
357
+ if (control instanceof FormArray) {
358
+ control.controls.forEach((childControl) => {
359
+ this.markAllControlsAsDirty(childControl, emitEvent, onlySelf);
360
+ });
361
+ }
362
+ }
363
+ // ==================== 错误消息相关 ====================
364
+ // 获取字段首条错误提示,支持普通字段和 FormArray 字段(格式:arrayName.index.fieldName)
365
+ getFieldErrorMessage(name, controlName) {
366
+ var _a;
367
+ const formGroup = this.formStore[name];
368
+ if (!formGroup) {
369
+ console.warn(`[AntdFormService] getFieldErrorMessage: form "${name}" not found.`);
370
+ return "";
371
+ }
372
+ const control = formGroup.get(controlName);
373
+ if (!control) {
374
+ console.warn(`[AntdFormService] getFieldErrorMessage: control "${controlName}" not found in form "${name}".`);
375
+ return "";
376
+ }
377
+ if (!control.errors) {
378
+ return "";
379
+ }
380
+ // 解析 controlName,支持 FormArray 格式:arrayName.index.fieldName
381
+ let errorMessageKey = controlName;
382
+ const arrayMatch = controlName.match(/^(.+)\.(\d+)\.(.+)$/);
383
+ if (arrayMatch) {
384
+ // FormArray 格式:arrayName.index.fieldName -> 使用 arrayName[].fieldName 作为 key
385
+ const [, arrayName, , fieldName] = arrayMatch;
386
+ errorMessageKey = `${arrayName}[].${fieldName}`;
387
+ }
388
+ // 从 errorMessageStore 获取错误消息配置
389
+ const errorMessages = (_a = this.errorMessageStore[name]) === null || _a === void 0 ? void 0 : _a[errorMessageKey];
390
+ const mergedMessages = Object.assign(Object.assign({}, this.defaultErrorMessages), (errorMessages !== null && errorMessages !== void 0 ? errorMessages : {}));
391
+ for (const errorKey of Object.keys(control.errors)) {
392
+ const message = mergedMessages[errorKey];
393
+ if (message) {
394
+ // 不再支持函数形式,只返回字符串
395
+ return typeof message === "string" ? message : "";
396
+ }
397
+ }
398
+ return "";
399
+ }
400
+ // ==================== 监听相关 ====================
401
+ // 监听表单所有字段变更
402
+ watchFormChanges(name, handler, options) {
403
+ const formGroup = this.formStore[name];
404
+ if (!formGroup) {
405
+ console.warn(`[AntdFormService] watchFormChanges: form "${name}" not found.`);
406
+ return undefined;
407
+ }
408
+ return this.setupValueChangeSubscription(formGroup, handler, options);
409
+ }
410
+ // 监听指定字段变更
411
+ watchFieldChanges(name, controlName, handler, options) {
412
+ const formGroup = this.formStore[name];
413
+ if (!formGroup) {
414
+ console.warn(`[AntdFormService] watchFieldChanges: form "${name}" not found.`);
415
+ return undefined;
416
+ }
417
+ const control = formGroup.get(controlName);
418
+ if (!control) {
419
+ console.warn(`[AntdFormService] watchFieldChanges: control "${controlName}" not found in form "${name}".`);
420
+ return undefined;
421
+ }
422
+ return this.setupValueChangeSubscription(control, handler, options);
423
+ }
424
+ // ==================== 工具方法 ====================
425
+ // 获取表单类名
426
+ getFormClassName(name) {
427
+ return `${this.classPrefix}${name}`;
428
+ }
429
+ // 设置 CSS 变量到目标元素(支持持久化监听动态添加的元素)
430
+ setCSSVariablesToTarget(name) {
431
+ const selector = `.${this.getFormClassName(name)} .ant-form-item-label`;
432
+ const formContainerSelector = `.${this.getFormClassName(name)}`;
433
+ const applyStyles = () => {
434
+ const dom = document.querySelectorAll(selector);
435
+ if (!dom.length) {
436
+ return false;
437
+ }
438
+ let appliedCount = 0;
439
+ dom.forEach((item) => {
440
+ const target = item;
441
+ if (target.style.width !== this.labelWidth ||
442
+ target.style.textAlign !== this.labelAlign) {
443
+ target.style.width = this.labelWidth;
444
+ target.style.textAlign = this.labelAlign;
445
+ appliedCount++;
446
+ }
447
+ });
448
+ return appliedCount > 0;
449
+ };
450
+ if (this.labelObservers[name]) {
451
+ return;
452
+ }
453
+ let timeout = null;
454
+ const observer = new MutationObserver(() => {
455
+ cancelAnimationFrame(timeout);
456
+ timeout = requestAnimationFrame(() => {
457
+ setTimeout(() => {
458
+ applyStyles();
459
+ }, 0);
460
+ });
461
+ });
462
+ const formContainer = document.querySelector(formContainerSelector);
463
+ observer.observe(formContainer || document.body, {
464
+ childList: true,
465
+ subtree: true,
466
+ attributes: true,
467
+ });
468
+ this.labelObservers[name] = observer;
469
+ }
470
+ // ==================== 私有方法 ====================
471
+ // 获取 FormArray
472
+ getFormArray(formName, arrayName) {
473
+ const formGroup = this.formStore[formName];
474
+ if (!formGroup) {
475
+ console.warn(`[AntdFormService] getFormArray: form "${formName}" not found.`);
476
+ return null;
477
+ }
478
+ const control = formGroup.get(arrayName);
479
+ if (!control || !(control instanceof FormArray)) {
480
+ console.warn(`[AntdFormService] getFormArray: array "${arrayName}" not found in form "${formName}".`);
481
+ return null;
482
+ }
483
+ return control;
484
+ }
485
+ // 判断是否是 FormArray 配置
486
+ isFormArrayConfig(field) {
487
+ return field.type === "array";
488
+ }
489
+ // 从配置创建 FormArray
490
+ createFormArrayFromConfig(formName, arrayName, itemConfig, initialItems, uniqueIdField) {
491
+ const formArray = this.fb.array([]);
492
+ initialItems.forEach((item) => {
493
+ const itemGroup = this.createItemFormGroup(itemConfig, item, uniqueIdField);
494
+ formArray.push(itemGroup);
495
+ });
496
+ return formArray;
497
+ }
498
+ // 生成内部ID(使用业务唯一字段或生成临时ID)
499
+ generateInternalId(itemData, uniqueIdField) {
500
+ // 优先使用业务唯一字段
501
+ if (uniqueIdField && (itemData === null || itemData === void 0 ? void 0 : itemData[uniqueIdField]) !== undefined) {
502
+ const businessId = itemData[uniqueIdField];
503
+ if (businessId !== null &&
504
+ businessId !== undefined &&
505
+ businessId !== "") {
506
+ return `business-${uniqueIdField}-${businessId}`;
507
+ }
508
+ }
509
+ // 如果没有业务ID,生成临时ID(用于新添加的项)
510
+ return `temp-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
511
+ }
512
+ // 创建单个项的 FormGroup
513
+ createItemFormGroup(itemConfig, itemData, uniqueIdField) {
514
+ const groupConfig = {};
515
+ // 添加内部ID字段
516
+ const itemId = this.generateInternalId(itemData, uniqueIdField);
517
+ groupConfig[this.INTERNAL_ID_FIELD] = [
518
+ { value: itemId, disabled: true },
519
+ [],
520
+ ];
521
+ // 添加业务字段
522
+ Object.entries(itemConfig).forEach(([key, field]) => {
523
+ var _a, _b, _c;
524
+ // itemConfig 中的字段应该是 FieldConfig,不应该包含 FormArrayConfig
525
+ if (this.isFormArrayConfig(field)) {
526
+ console.warn(`[AntdFormService] createItemFormGroup: FormArrayConfig is not allowed in itemConfig. Skipping field "${key}".`);
527
+ return;
528
+ }
529
+ const fieldConfig = field;
530
+ const value = (itemData === null || itemData === void 0 ? void 0 : itemData[key]) !== undefined ? itemData[key] : fieldConfig.value;
531
+ groupConfig[key] = [
532
+ { value: value, disabled: (_a = fieldConfig.disabled) !== null && _a !== void 0 ? _a : false },
533
+ (_c = (_b = fieldConfig.validators) === null || _b === void 0 ? void 0 : _b.call(fieldConfig)) !== null && _c !== void 0 ? _c : [],
534
+ ];
535
+ });
536
+ return this.fb.group(groupConfig);
537
+ }
538
+ // 通过业务唯一字段查找内部ID
539
+ findFormArrayItemIdByBusinessField(formName, arrayName, uniqueIdField, businessIdValue) {
540
+ const formArray = this.getFormArray(formName, arrayName);
541
+ if (!formArray)
542
+ return null;
543
+ for (let i = 0; i < formArray.length; i++) {
544
+ const item = formArray.at(i);
545
+ const itemValue = item.getRawValue();
546
+ const internalId = itemValue[this.INTERNAL_ID_FIELD];
547
+ // 检查内部ID是否匹配业务ID
548
+ if (internalId && internalId.startsWith(`business-${uniqueIdField}-`)) {
549
+ const idInInternalId = internalId.replace(`business-${uniqueIdField}-`, "");
550
+ if (String(idInInternalId) === String(businessIdValue)) {
551
+ return internalId;
552
+ }
553
+ }
554
+ // 也检查当前业务字段值是否匹配(处理业务ID更新的情况)
555
+ if (itemValue[uniqueIdField] === businessIdValue) {
556
+ return internalId;
557
+ }
558
+ }
559
+ return null;
560
+ }
561
+ // 通过内部ID查找项
562
+ findFormArrayItemById(formName, arrayName, itemId) {
563
+ var _a;
564
+ const formArray = this.getFormArray(formName, arrayName);
565
+ if (!formArray)
566
+ return null;
567
+ for (let i = 0; i < formArray.length; i++) {
568
+ const item = formArray.at(i);
569
+ const id = (_a = item.get(this.INTERNAL_ID_FIELD)) === null || _a === void 0 ? void 0 : _a.value;
570
+ if (id === itemId) {
571
+ return { index: i, formGroup: item };
572
+ }
573
+ }
574
+ return null;
575
+ }
576
+ // 获取操作类型(必须明确指定 action 字段)
577
+ getOperationType(itemData) {
578
+ if (!itemData || typeof itemData !== "object")
579
+ return null;
580
+ const action = itemData.action;
581
+ if (action === "delete" || action === "update" || action === "create") {
582
+ return action;
583
+ }
584
+ return null;
585
+ }
586
+ // 过滤操作字段(action 字段不保存到表单中)
587
+ filterOperationFields(itemData) {
588
+ if (!itemData || typeof itemData !== "object")
589
+ return itemData;
590
+ const filtered = {};
591
+ Object.entries(itemData).forEach(([key, value]) => {
592
+ if (key !== "action") {
593
+ filtered[key] = value;
594
+ }
595
+ });
596
+ return filtered;
597
+ }
598
+ // 处理 FormArray 的更新(统一根据 action 字段判断操作类型)
599
+ patchFormArray(formName, arrayName, newValues) {
600
+ var _a;
601
+ const formArray = this.getFormArray(formName, arrayName);
602
+ if (!formArray) {
603
+ console.warn(`[AntdFormService] patchFormArray: array "${arrayName}" not found in form "${formName}".`);
604
+ return;
605
+ }
606
+ const config = (_a = this.formArrayConfigStore[formName]) === null || _a === void 0 ? void 0 : _a[arrayName];
607
+ if (!config) {
608
+ console.warn(`[AntdFormService] patchFormArray: config not found for array "${arrayName}" in form "${formName}".`);
609
+ return;
610
+ }
611
+ const { itemConfig, uniqueIdField } = config;
612
+ // 统一根据 action 字段判断操作类型
613
+ const itemsToDelete = new Set();
614
+ const itemsToUpdate = new Map();
615
+ const itemsToAdd = [];
616
+ newValues.forEach((itemData) => {
617
+ if (!itemData || typeof itemData !== "object")
618
+ return;
619
+ const operationType = this.getOperationType(itemData);
620
+ if (!operationType) {
621
+ console.warn(`[AntdFormService] patchFormArray: Item missing required "action" field. Skipping.`, itemData);
622
+ return;
623
+ }
624
+ // 删除操作
625
+ if (operationType === "delete") {
626
+ if (uniqueIdField && itemData[uniqueIdField] !== undefined) {
627
+ const businessId = itemData[uniqueIdField];
628
+ const internalId = this.findFormArrayItemIdByBusinessField(formName, arrayName, uniqueIdField, businessId);
629
+ if (internalId) {
630
+ itemsToDelete.add(internalId);
631
+ }
632
+ else {
633
+ console.warn(`[AntdFormService] patchFormArray: Cannot delete item with ${uniqueIdField}=${businessId}, item not found.`);
634
+ }
635
+ }
636
+ else {
637
+ console.warn(`[AntdFormService] patchFormArray: Cannot delete item, missing required uniqueIdField "${uniqueIdField}".`);
638
+ }
639
+ return;
640
+ }
641
+ // 更新操作
642
+ if (operationType === "update") {
643
+ if (uniqueIdField && itemData[uniqueIdField] !== undefined) {
644
+ const businessId = itemData[uniqueIdField];
645
+ const internalId = this.findFormArrayItemIdByBusinessField(formName, arrayName, uniqueIdField, businessId);
646
+ if (internalId) {
647
+ const filteredData = this.filterOperationFields(itemData);
648
+ itemsToUpdate.set(internalId, filteredData);
649
+ }
650
+ else {
651
+ console.warn(`[AntdFormService] patchFormArray: Cannot update item with ${uniqueIdField}=${businessId}, item not found. Skipping.`);
652
+ }
653
+ }
654
+ else {
655
+ console.warn(`[AntdFormService] patchFormArray: Cannot update item, missing required uniqueIdField "${uniqueIdField}". Skipping.`);
656
+ }
657
+ return;
658
+ }
659
+ // 创建操作
660
+ if (operationType === "create") {
661
+ const filteredData = this.filterOperationFields(itemData);
662
+ itemsToAdd.push(filteredData);
663
+ }
664
+ });
665
+ // 执行删除(需要从后往前删除,避免索引变化)
666
+ const deleteIndices = [];
667
+ itemsToDelete.forEach((itemId) => {
668
+ const found = this.findFormArrayItemById(formName, arrayName, itemId);
669
+ if (found) {
670
+ deleteIndices.push(found.index);
671
+ }
672
+ });
673
+ deleteIndices
674
+ .sort((a, b) => b - a)
675
+ .forEach((index) => {
676
+ formArray.removeAt(index);
677
+ });
678
+ // 执行更新
679
+ itemsToUpdate.forEach((itemData, itemId) => {
680
+ const found = this.findFormArrayItemById(formName, arrayName, itemId);
681
+ if (found) {
682
+ const _a = itemData, _b = this.INTERNAL_ID_FIELD, _ = _a[_b], dataToUpdate = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
683
+ found.formGroup.patchValue(dataToUpdate);
684
+ }
685
+ });
686
+ // 执行添加
687
+ itemsToAdd.forEach((itemData) => {
688
+ const newItem = this.createItemFormGroup(itemConfig, itemData, uniqueIdField);
689
+ formArray.push(newItem);
690
+ });
691
+ }
692
+ // 过滤内部字段(递归处理对象和数组)
693
+ excludeInternalFields(value) {
694
+ if (value === null || value === undefined) {
695
+ return value;
696
+ }
697
+ if (Array.isArray(value)) {
698
+ return value.map((item) => this.excludeInternalFields(item));
699
+ }
700
+ if (typeof value !== "object") {
701
+ return value;
702
+ }
703
+ const filtered = {};
704
+ Object.entries(value).forEach(([key, val]) => {
705
+ // 过滤以 __ 开头的内部字段和 action 字段
706
+ if (!key.startsWith("__") && key !== "action") {
707
+ filtered[key] = this.excludeInternalFields(val);
708
+ }
709
+ });
710
+ return filtered;
711
+ }
712
+ // 设置值变更订阅
713
+ setupValueChangeSubscription(target, handler, options) {
714
+ let valueChanges$ = target.valueChanges;
715
+ if ((options === null || options === void 0 ? void 0 : options.debounce) != null) {
716
+ valueChanges$ = valueChanges$.pipe(debounceTime(options.debounce));
717
+ }
718
+ if ((options === null || options === void 0 ? void 0 : options.distinctUntilChanged) !== false) {
719
+ valueChanges$ = valueChanges$.pipe(distinctUntilChanged());
720
+ }
721
+ if (options === null || options === void 0 ? void 0 : options.emitInitial) {
722
+ handler(target.value);
723
+ }
724
+ return valueChanges$.subscribe(handler);
725
+ }
726
+ }
727
+ AntdFormService.ɵprov = i0.ɵɵdefineInjectable({ factory: function AntdFormService_Factory() { return new AntdFormService(i0.ɵɵinject(i1.FormBuilder)); }, token: AntdFormService, providedIn: "root" });
728
+ AntdFormService.decorators = [
729
+ { type: Injectable, args: [{ providedIn: "root" },] }
730
+ ];
731
+ AntdFormService.ctorParameters = () => [
732
+ { type: FormBuilder }
733
+ ];
734
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW50ZC1mb3JtLmpzIiwic291cmNlUm9vdCI6IkQ6L3Byb2plY3RzL3Zwcy1mcm9udC9Gcm9udC9EYXNQTVNXZWIvcHJvamVjdHMvcHJvLXRhYmxlL3NyYy8iLCJzb3VyY2VzIjpbImxpYi9wYWdlLXB1YmxpYy9hbnRkLWZvcm0udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUdMLFNBQVMsRUFDVCxXQUFXLEVBQ1gsU0FBUyxHQUVWLE1BQU0sZ0JBQWdCLENBQUM7QUFFeEIsT0FBTyxFQUFFLFlBQVksRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7QUFxRXBFLGdEQUFnRDtBQUdoRCxNQUFNLE9BQU8sZUFBZTtJQTJCMUIsaURBQWlEO0lBQ2pELFlBQW9CLEVBQWU7UUFBZixPQUFFLEdBQUYsRUFBRSxDQUFhO1FBM0JuQyxpREFBaUQ7UUFDakQsY0FBUyxHQUE4QixFQUFFLENBQUM7UUFDMUMsbUJBQWMsR0FBbUIsUUFBUSxDQUFDO1FBRTFDLGlEQUFpRDtRQUN6QyxlQUFVLEdBQVcsT0FBTyxDQUFDO1FBQzdCLGVBQVUsR0FBVyxPQUFPLENBQUM7UUFDN0IsbUJBQWMsR0FBcUMsRUFBRSxDQUFDO1FBQ3RELHNCQUFpQixHQUdyQixFQUFFLENBQUM7UUFDQyx5QkFBb0IsR0FHeEIsRUFBRSxDQUFDO1FBQ1Usc0JBQWlCLEdBQUcsY0FBYyxDQUFDO1FBQzVDLGdCQUFXLEdBQUcsV0FBVyxDQUFDO1FBQ2pCLHlCQUFvQixHQUF1QjtZQUMxRCxRQUFRLEVBQUUsU0FBUztZQUNuQixTQUFTLEVBQUUsUUFBUTtZQUNuQixTQUFTLEVBQUUsUUFBUTtZQUNuQixLQUFLLEVBQUUsWUFBWTtZQUNuQixPQUFPLEVBQUUsU0FBUztTQUNuQixDQUFDO0lBR29DLENBQUM7SUFFdkMscURBQXFEO0lBRXJELHNCQUFzQjtJQUN0QixlQUFlLENBQ2IsSUFBWSxFQUNa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QUMzQyw0QkFBNEI7WUFDNUIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxLQUFLLFFBQVEsRUFBRTtnQkFDN0MsUUFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsQ0FBQzthQUNqRDtRQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxRQUFRLENBQUM7SUFDbEIsQ0FBQztJQUVELFVBQVU7SUFDRiw0QkFBNEIsQ0FDbEMsTUFBeUMsRUFDekMsT0FBMkIsRUFDM0IsT0FBc0I7UUFFdEIsSUFBSSxhQUFhLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQztRQUV4QyxJQUFJLENBQUEsT0FBTyxhQUFQLE9BQU8sdUJBQVAsT0FBTyxDQUFFLFFBQVEsS0FBSSxJQUFJLEVBQUU7WUFDN0IsYUFBYSxHQUFHLGFBQWEsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO1NBQ3BFO1FBRUQsSUFBSSxDQUFBLE9BQU8sYUFBUCxPQUFPLHVCQUFQLE9BQU8sQ0FBRSxvQkFBb0IsTUFBSyxLQUFLLEVBQUU7WUFDM0MsYUFBYSxHQUFHLGFBQWEsQ0FBQyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQyxDQUFDO1NBQzVEO1FBRUQsSUFBSSxPQUFPLGFBQVAsT0FBTyx1QkFBUCxPQUFPLENBQUUsV0FBVyxFQUFFO1lBQ3hCLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDdkI7UUFFRCxPQUFPLGFBQWEsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDMUMsQ0FBQzs7OztZQTM3QkYsVUFBVSxTQUFDLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRTs7O1lBNUVoQyxXQUFXIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XHJcbmltcG9ydCB7XHJcbiAgQWJzdHJhY3RDb250cm9sLFxyXG4gIEFic3RyYWN0Q29udHJvbE9wdGlvbnMsXHJcbiAgRm9ybUFycmF5LFxyXG4gIEZvcm1CdWlsZGVyLFxyXG4gIEZvcm1Hcm91cCxcclxuICBWYWxpZGF0b3JGbixcclxufSBmcm9tIFwiQGFuZ3VsYXIvZm9ybXNcIjtcclxuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSBcInJ4anNcIjtcclxuaW1wb3J0IHsgZGVib3VuY2VUaW1lLCBkaXN0aW5jdFVudGlsQ2hhbmdlZCB9IGZyb20gXCJyeGpzL29wZXJhdG9yc1wiO1xyXG5cclxuLy8gPT09PT09PT09PT09PT09PT09PT0g57G75Z6L5a6a5LmJID09PT09PT09PT09PT09PT09PT09XHJcblxyXG4vLyDlrZfmrrXplJnor6/mtojmga/nsbvlnovvvIjlrZfnrKbkuLLmiJblh73mlbDvvIlcclxuZXhwb3J0IHR5cGUgRmllbGRFcnJvck1lc3NhZ2UgPVxyXG4gIHwgc3RyaW5nXHJcbiAgfCAoKGNvbnRleHQ6IHsgY29udHJvbDogQWJzdHJhY3RDb250cm9sOyBjb250cm9sTmFtZTogc3RyaW5nIH0pID0+IHN0cmluZyk7XHJcblxyXG4vLyDlrZfmrrXplJnor6/mtojmga/pm4blkIhcclxuZXhwb3J0IHR5cGUgRmllbGRFcnJvck1lc3NhZ2VzID0gUmVjb3JkPHN0cmluZywgRmllbGRFcnJvck1lc3NhZ2U+O1xyXG5cclxuLy8g5a2X5q616YWN572uXHJcbmV4cG9ydCB0eXBlIEZpZWxkQ29uZmlnID0ge1xyXG4gIHZhbHVlOiBhbnk7XHJcbiAgZGlzYWJsZWQ/OiBib29sZWFuO1xyXG4gIHZhbGlkYXRvcnM/OiAoKSA9PiBWYWxpZGF0b3JGbltdO1xyXG4gIGVycm9yTWVzc2FnZXM/OiBGaWVsZEVycm9yTWVzc2FnZXM7XHJcbn07XHJcblxyXG4vLyBGb3JtQXJyYXkg6YWN572u57G75Z6LXHJcbmV4cG9ydCB0eXBlIEZvcm1BcnJheUNvbmZpZyA9IHtcclxuICB0eXBlOiBcImFycmF5XCI7XHJcbiAgaXRlbUNvbmZpZzogRm9ybUNvbmZpZzsgLy8g5q+P6KGM55qE6KGo5Y2V6YWN572uXHJcbiAgaW5pdGlhbEl0ZW1zPzogYW55W107IC8vIOWIneWni+aVsOaNrumhuVxyXG4gIGVycm9yTWVzc2FnZXM/OiBSZWNvcmQ8c3RyaW5nLCBGaWVsZEVycm9yTWVzc2FnZXM+OyAvLyDooYzlrZfmrrXnmoTplJnor6/mtojmga/phY3nva5cclxuICB1bmlxdWVJZEZpZWxkPzogc3RyaW5nOyAvLyDkuJrliqHllK/kuIDmoIfor4blrZfmrrXvvIjlpoIgJ2RpY3RJZCcsICdpZCcg562J77yJXHJcbn07XHJcblxyXG4vLyDooajljZXkv67mlLnnsbvlnotcclxuZXhwb3J0IHR5cGUgRm9ybU1vZGlmeVR5cGUgPSBcImNyZWF0ZVwiIHwgXCJ1cGRhdGVcIjtcclxuXHJcbi8vIOihqOWNlemFjee9ru+8iOaUr+aMgeaZrumAmuWtl+auteWSjCBGb3JtQXJyYXnvvIlcclxuZXhwb3J0IHR5cGUgRm9ybUNvbmZpZyA9IFJlY29yZDxzdHJpbmcsIEZpZWxkQ29uZmlnIHwgRm9ybUFycmF5Q29uZmlnPjtcclxuXHJcbi8vIOebkeWQrOmAiemhuVxyXG5leHBvcnQgdHlwZSBXYXRjaE9wdGlvbnMgPSB7XHJcbiAgZGVib3VuY2U/OiBudW1iZXI7XHJcbiAgZGlzdGluY3RVbnRpbENoYW5nZWQ/OiBib29sZWFuO1xyXG4gIGVtaXRJbml0aWFsPzogYm9vbGVhbjtcclxufTtcclxuXHJcbi8vIOaJuemHj+a3u+WKoOWtl+autemFjee9rumAiemhuVxyXG5leHBvcnQgdHlwZSBBZGRGaWVsZHNDb25maWdPcHRpb25zID0ge1xyXG4gIGVtaXRFdmVudD86IGJvb2xlYW47XHJcbiAgdXBkYXRlVmFsdWVBbmRWYWxpZGl0eT86IGJvb2xlYW47XHJcbiAgb25GaWVsZEFkZGVkPzogKGZpZWxkTmFtZTogc3RyaW5nLCBzdWNjZXNzOiBib29sZWFuLCBlcnJvcj86IHN0cmluZykgPT4gdm9pZDsgLy8g5q+P5Liq5a2X5q615re75Yqg55qE5Zue6LCDXHJcbn07XHJcblxyXG4vLyDmibnph4/mt7vliqDlrZfmrrXphY3nva7nu5PmnpxcclxuZXhwb3J0IHR5cGUgQWRkRmllbGRzQ29uZmlnUmVzdWx0ID0ge1xyXG4gIHN1Y2Nlc3M6IGJvb2xlYW47XHJcbiAgYWRkZWQ6IHN0cmluZ1tdOyAvLyDmiJDlip/mt7vliqDnmoTlrZfmrrXlkI3liJfooahcclxuICBmYWlsZWQ6IEFycmF5PHsgZmllbGROYW1lOiBzdHJpbmc7IGVycm9yOiBzdHJpbmcgfT47IC8vIOWksei0peeahOWtl+auteWPiumUmeivr+S/oeaBr1xyXG59O1xyXG5cclxuLy8g5om56YeP5Yig6Zmk5a2X5q616YWN572u6YCJ6aG5XHJcbmV4cG9ydCB0eXBlIFJlbW92ZUZpZWxkc0NvbmZpZ09wdGlvbnMgPSB7XHJcbiAgZW1pdEV2ZW50PzogYm9vbGVhbjtcclxuICBvbkZpZWxkUmVtb3ZlZD86IChmaWVsZE5hbWU6IHN0cmluZywgc3VjY2VzczogYm9vbGVhbiwgZXJyb3I/OiBzdHJpbmcpID0+IHZvaWQ7IC8vIOavj+S4quWtl+auteWIoOmZpOeahOWbnuiwg1xyXG59O1xyXG5cclxuLy8g5om56YeP5Yig6Zmk5a2X5q616YWN572u57uT5p6cXHJcbmV4cG9ydCB0eXBlIFJlbW92ZUZpZWxkc0NvbmZpZ1Jlc3VsdCA9IHtcclxuICBzdWNjZXNzOiBib29sZWFuO1xyXG4gIHJlbW92ZWQ6IHN0cmluZ1tdOyAvLyDmiJDlip/liKDpmaTnmoTlrZfmrrXlkI3liJfooahcclxuICBmYWlsZWQ6IEFycmF5PHsgZmllbGROYW1lOiBzdHJpbmc7IGVycm9yOiBzdHJpbmcgfT47IC8vIOWksei0peeahOWtl+auteWPiumUmeivr+S/oeaBr1xyXG59O1xyXG5cclxuLy8gPT09PT09PT09PT09PT09PT09PT0g5pyN5Yqh57G7ID09PT09PT09PT09PT09PT09PT09XHJcblxyXG5ASW5qZWN0YWJsZSh7IHByb3ZpZGVkSW46IFwicm9vdFwiIH0pXHJcbmV4cG9ydCBjbGFzcyBBbnRkRm9ybVNlcnZpY2Uge1xyXG4gIC8vID09PT09PT09PT09PT09PT09PT09IOWFrOWFseWxnuaApyA9PT09PT09PT09PT09PT09PT09PVxyXG4gIGZvcm1TdG9yZTogUmVjb3JkPHN0cmluZywgRm9ybUdyb3VwPiA9IHt9O1xyXG4gIGZvcm1Nb2RpZnlUeXBlOiBGb3JtTW9kaWZ5VHlwZSA9IFwiY3JlYXRlXCI7XHJcblxyXG4gIC8vID09PT09PT09PT09PT09PT09PT09IOengeacieWxnuaApyA9PT09PT09PT09PT09PT09PT09PVxyXG4gIHByaXZhdGUgbGFiZWxXaWR0aDogc3RyaW5nID0gXCIxMjBweFwiO1xyXG4gIHByaXZhdGUgbGFiZWxBbGlnbjogc3RyaW5nID0gXCJyaWdodFwiO1xyXG4gIHByaXZhdGUgbGFiZWxPYnNlcnZlcnM6IFJlY29yZDxzdHJpbmcsIE11dGF0aW9uT2JzZXJ2ZXI+ID0ge307XHJcbiAgcHJpdmF0ZSBlcnJvck1lc3NhZ2VTdG9yZTogUmVjb3JkPFxyXG4gICAgc3RyaW5nLFxyXG4gICAgUmVjb3JkPHN0cmluZywgRmllbGRFcnJvck1lc3NhZ2VzPlxyXG4gID4gPSB7fTtcclxuICBwcml2YXRlIGZvcm1BcnJheUNvbmZpZ1N0b3JlOiBSZWNvcmQ8XHJcbiAgICBzdHJpbmcsXHJcbiAgICBSZWNvcmQ8c3RyaW5nLCB7IGl0ZW1Db25maWc6IEZvcm1Db25maWc7IHVuaXF1ZUlkRmllbGQ/OiBzdHJpbmcgfT5cclxuICA+ID0ge307XHJcbiAgcHJpdmF0ZSByZWFkb25seSBJTlRFUk5BTF9JRF9GSUVMRCA9IFwiX19mb3JtSXRlbUlkXCI7XHJcbiAgcHJpdmF0ZSBjbGFzc1ByZWZpeCA9IFwiYW50LWZvcm0tXCI7XHJcbiAgcHJpdmF0ZSByZWFkb25seSBkZWZhdWx0RXJyb3JNZXNzYWdlczogRmllbGRFcnJvck1lc3NhZ2VzID0ge1xyXG4gICAgcmVxdWlyZWQ6IFwi6K+l5a2X5q615Li65b+F5aGr6aG5XCIsXHJcbiAgICBtaW5sZW5ndGg6IFwi6L6T5YWl6ZW/5bqm5LiN6LazXCIsXHJcbiAgICBtYXhsZW5ndGg6IFwi6L6T5YWl6ZW/5bqm6LaF6ZmQXCIsXHJcbiAgICBlbWFpbDogXCLor7fovpPlhaXlkIjms5XnmoTpgq7nrrHlnLDlnYBcIixcclxuICAgIHBhdHRlcm46IFwi6L6T5YWl5qC85byP5LiN5q2j56GuXCIsXHJcbiAgfTtcclxuXHJcbiAgLy8gPT09PT09PT09PT09PT09PT09PT0g5p6E6YCg5Ye95pWwID09PT09PT09PT09PT09PT09PT09XHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBmYjogRm9ybUJ1aWxkZXIpIHt9XHJcblxyXG4gIC8vID09PT09PT09PT09PT09PT09PT09IOihqOWNleWIm+W7uuWSjOWIneWni+WMliA9PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICAvLyDliJ3lp4vljJbooajljZXvvIjmlK/mjIEgRm9ybUFycmF577yJXHJcbiAgY3JlYXRlRm9ybUdyb3VwKFxyXG4gICAgbmFtZTogc3RyaW5nLFxyXG4gICAgY29uZmlnOiBGb3JtQ29uZmlnLFxyXG4gICAgb3B0aW9ucz86IHsgbGFiZWxXaWR0aD86IHN0cmluZzsgbGFiZWxBbGlnbj86IHN0cmluZyB9XHJcbiAgKTogRm9ybUdyb3VwIHtcclxuICAgIGNvbnN0IGdyb3VwQ29uZmlnOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XHJcbiAgICB0aGlzLmVycm9yTWVzc2FnZVN0b3JlW25hbWVdID0ge307XHJcblxyXG4gICAgT2JqZWN0LmVudHJpZXMoY29uZmlnKS5mb3JFYWNoKChba2V5LCBmaWVsZF0pID0+IHtcclxuICAgICAgaWYgKHRoaXMuaXNGb3JtQXJyYXlDb25maWcoZmllbGQpKSB7XHJcbiAgICAgICAgLy8gRm9ybUFycmF5IOmFjee9ruWkhOeQhlxyXG4gICAgICAgIGlmICghdGhpcy5mb3JtQXJyYXlDb25maWdTdG9yZVtuYW1lXSkge1xyXG4gICAgICAgICAgdGhpcy5mb3JtQXJyYXlDb25maWdTdG9yZVtuYW1lXSA9IHt9O1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmZvcm1BcnJheUNvbmZpZ1N0b3JlW25hbWVdW2tleV0gPSB7XHJcbiAgICAgICAgICBpdGVtQ29uZmlnOiBmaWVsZC5pdGVtQ29uZmlnLFxyXG4gICAgICAgICAgdW5pcXVlSWRGaWVsZDogZmllbGQudW5pcXVlSWRGaWVsZCxcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBjb25zdCBmb3JtQXJyYXkgPSB0aGlzLmNyZWF0ZUZvcm1BcnJheUZyb21Db25maWcoXHJcbiAgICAgICAgICBuYW1lLFxyXG4gICAgICAgICAga2V5LFxyXG4gICAgICAgICAgZmllbGQuaXRlbUNvbmZpZyxcclxuICAgICAgICAgIGZpZWxkLmluaXRpYWxJdGVtcyB8fCBbXSxcclxuICAgICAgICAgIGZpZWxkLnVuaXF1ZUlkRmllbGRcclxuICAgICAgICApO1xyXG4gICAgICAgIGdyb3VwQ29uZmlnW2tleV0gPSBmb3JtQXJyYXk7XHJcblxyXG4gICAgICAgIC8vIOWtmOWCqCBGb3JtQXJyYXkg5a2X5q6155qE6ZSZ6K+v5raI5oGv6YWN572u77yM5qC85byP77yaYXJyYXlOYW1lW10uZmllbGROYW1lXHJcbiAgICAgICAgaWYgKGZpZWxkLmVycm9yTWVzc2FnZXMpIHtcclxuICAgICAgICAgIE9iamVjdC5lbnRyaWVzKGZpZWxkLmVycm9yTWVzc2FnZXMpLmZvckVhY2goXHJcbiAgICAgICAgICAgIChbZmllbGROYW1lLCBlcnJvck1lc3NhZ2VzXSkgPT4ge1xyXG4gICAgICAgICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZUtleSA9IGAke2tleX1bXS4ke2ZpZWxkTmFtZX1gO1xyXG4gICAgICAgICAgICAgIHRoaXMuZXJyb3JNZXNzYWdlU3RvcmVbbmFtZV1bZXJyb3JNZXNzYWdlS2V5XSA9IGVycm9yTWVzc2FnZXM7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIC8vIOaZrumAmuWtl+autemFjee9rlxyXG4gICAgICAgIGNvbnN0IGZpZWxkQ29uZmlnID0gZmllbGQgYXMgRmllbGRDb25maWc7XHJcbiAgICAgICAgZ3JvdXBDb25maWdba2V5XSA9IFtcclxuICAgICAgICAgIHsgdmFsdWU6IGZpZWxkQ29uZmlnLnZhbHVlLCBkaXNhYmxlZDogZmllbGRDb25maWcuZGlzYWJsZWQgPz8gZmFsc2UgfSxcclxuICAgICAgICAgIGZpZWxkQ29uZmlnLnZhbGlkYXRvcnM/LigpID8/IFtdLFxyXG4gICAgICAgIF07XHJcbiAgICAgICAgaWYgKGZpZWxkQ29uZmlnLmVycm9yTWVzc2FnZXMpIHtcclxuICAgICAgICAgIHRoaXMuZXJyb3JNZXNzYWdlU3RvcmVbbmFtZV1ba2V5XSA9IGZpZWxkQ29uZmlnLmVycm9yTWVzc2FnZXM7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICBpZiAob3B0aW9ucz8ubGFiZWxXaWR0aCkge1xyXG4gICAgICB0aGlzLmxhYmVsV2lkdGggPSBvcHRpb25zLmxhYmVsV2lkdGg7XHJcbiAgICB9XHJcbiAgICBpZiAob3B0aW9ucz8ubGFiZWxBbGlnbikge1xyXG4gICAgICB0aGlzLmxhYmVsQWxpZ24gPSBvcHRpb25zLmxhYmVsQWxpZ247XHJcbiAgICB9XHJcbiAgICB0aGlzLmZvcm1TdG9yZVtuYW1lXSA9IHRoaXMuZmIuZ3JvdXAoZ3JvdXBDb25maWcpO1xyXG4gICAgdGhpcy5zZXRDU1NWYXJpYWJsZXNUb1RhcmdldChuYW1lKTtcclxuICAgIHJldHVybiB0aGlzLmZvcm1TdG9yZVtuYW1lXTtcclxuICB9XHJcblxyXG4gIC8vID09PT09PT09PT09PT09PT09PT09IOihqOWNleaTjeS9nCA9PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICAvLyDph43nva7ooajljZVcclxuICByZXNldEZvcm1Hcm91cChuYW1lOiBzdHJpbmcsIHZhbHVlPzogYW55KTogdm9pZCB7XHJcbiAgICB0aGlzLmZvcm1TdG9yZVtuYW1lXT8ucmVzZXQodmFsdWUpO1xyXG4gIH1cclxuXHJcbiAgLy8g5om56YeP5re75Yqg5a2X5q616YWN572uXHJcbiAgYWRkRmllbGRzQ29uZmlnKFxyXG4gICAgZm9ybU5hbWU6IHN0cmluZyxcclxuICAgIGZpZWxkc0NvbmZpZzogRm9ybUNvbmZpZyxcclxuICAgIG9wdGlvbnM/OiBBZGRGaWVsZHNDb25maWdPcHRpb25zXHJcbiAgKTogQWRkRmllbGRzQ29uZmlnUmVzdWx0IHtcclxuICAgIGNvbnN0IHJlc3VsdDogQWRkRmllbGRzQ29uZmlnUmVzdWx0ID0ge1xyXG4gICAgICBzdWNjZXNzOiB0cnVlLFxyXG4gICAgICBhZGRlZDogW10sXHJcbiAgICAgIGZhaWxlZDogW10sXHJcbiAgICB9O1xyXG5cclxuICAgIC8vIDEuIOmqjOivgeihqOWNleaYr+WQpuWtmOWcqFxyXG4gICAgY29uc3QgZm9ybUdyb3VwID0gdGhpcy5mb3JtU3RvcmVbZm9ybU5hbWVdO1xyXG4gICAgaWYgKCFmb3JtR3JvdXApIHtcclxuICAgICAgLy8g5aaC5p6c6KGo5Y2V5LiN5a2Y5Zyo77yM5omA5pyJ5a2X5q616YO95aSx6LSlXHJcbiAgICAgIE9iamVjdC5rZXlzKGZpZWxkc0NvbmZpZykuZm9yRWFjaCgoZmllbGROYW1lKSA9PiB7XHJcbiAgICAgICAgY29uc3QgZXJyb3IgPSBgRm9ybSBcIiR7Zm9ybU5hbWV9XCIgbm90IGZvdW5kYDtcclxuICAgICAgICByZXN1bHQuZmFpbGVkLnB1c2goe1xyXG4gICAgICAgICAgZmllbGROYW1lLFxyXG4gICAgICAgICAgZXJyb3IsXHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgb3B0aW9ucz8ub25GaWVsZEFkZGVkPy4oZmllbGROYW1lLCBmYWxzZSwgZXJyb3IpO1xyXG4gICAgICB9KTtcclxuICAgICAgcmVzdWx0LnN1Y2Nlc3MgPSBmYWxzZTtcclxuICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH1cclxuXHJcbiAgICAvLyAyLiDliJ3lp4vljJYgZXJyb3JNZXNzYWdlU3RvcmUg5ZKMIGZvcm1BcnJheUNvbmZpZ1N0b3Jl77yI5aaC5p6c5LiN5a2Y5Zyo77yJXHJcbiAgICBpZiAoIXRoaXMuZXJyb3JNZXNzYWdlU3RvcmVbZm9ybU5hbWVdKSB7XHJcbiAgICAgIHRoaXMuZXJyb3JNZXNzYWdlU3RvcmVbZm9ybU5hbWVdID0ge307XHJcbiAgICB9XHJcbiAgICBpZiAoIXRoaXMuZm9ybUFycmF5Q29uZmlnU3RvcmVbZm9ybU5hbWVdKSB7XHJcbiAgICAgIHRoaXMuZm9ybUFycmF5Q29uZmlnU3RvcmVbZm9ybU5hbWVdID0ge307XHJcbiAgICB9XHJcblxyXG4gICAgLy8gMy4g5om56YeP5p6E5bu65o6n5Lu26YWN572uXHJcbiAgICBjb25zdCBjb250cm9sc1RvQWRkOiBSZWNvcmQ8c3RyaW5nLCBBYnN0cmFjdENvbnRyb2w+ID0ge307XHJcbiAgICBjb25zdCBlcnJvck1lc3NhZ2VzVG9BZGQ6IFJlY29yZDxzdHJpbmcsIEZpZWxkRXJyb3JNZXNzYWdlcz4gPSB7fTtcclxuICAgIGNvbnN0IGZvcm1BcnJheUNvbmZpZ3NUb0FkZDogUmVjb3JkPFxyXG4gICAgICBzdHJpbmcsXHJcbiAgICAgIHsgaXRlbUNvbmZpZzogRm9ybUNvbmZpZzsgdW5pcXVlSWRGaWVsZD86IHN0cmluZyB9XHJcbiAgICA+ID0ge307XHJcblxyXG4gICAgLy8gNC4g6YGN5Y6G5omA5pyJ5a2X5q616YWN572u77yM6L+b6KGM6aqM6K+B5ZKM5p6E5bu6XHJcbiAgICBPYmplY3QuZW50cmllcyhmaWVsZHNDb25maWcpLmZvckVhY2goKFtmaWVsZE5hbWUsIGZpZWxkQ29uZmlnXSkgPT4ge1xyXG4gICAgICB0cnkge1xyXG4gICAgICAgIC8vIDQuMSDmo4Dmn6XlrZfmrrXmmK/lkKblt7LlrZjlnKhcclxuICAgICAgICBpZiAoZm9ybUdyb3VwLmdldChmaWVsZE5hbWUpKSB7XHJcbiAgICAgICAgICBjb25zdCBlcnJvciA9IGBGaWVsZCBcIiR7ZmllbGROYW1lfVwiIGFscmVhZHkgZXhpc3RzYDtcclxuICAgICAgICAgIHJlc3VsdC5mYWlsZWQucHVzaCh7XHJcbiAgICAgICAgICAgIGZpZWxkTmFtZSxcclxuICAgICAgICAgICAgZXJyb3IsXHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICAgIG9wdGlvbnM/Lm9uRmllbGRBZGRlZD8uKGZpZWxkTmFtZSwgZmFsc2UsIGVycm9yKTtcclxuICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIDQuMiDmoLnmja7lrZfmrrXnsbvlnovliJvlu7rmjqfku7ZcclxuICAgICAgICBpZiAodGhpcy5pc0Zvcm1BcnJheUNvbmZpZyhmaWVsZENvbmZpZykpIHtcclxuICAgICAgICAgIC8vIEZvcm1BcnJheSDlpITnkIZcclxuICAgICAgICAgIGNvbnN0IGZvcm1BcnJheSA9IHRoaXMuY3JlYXRlRm9ybUFycmF5RnJvbUNvbmZpZyhcclxuICAgICAgICAgICAgZm9ybU5hbWUsXHJcbiAgICAgICAgICAgIGZpZWxkTmFtZSxcclxuICAgICAgICAgICAgZmllbGRDb25maWcuaXRlbUNvbmZpZyxcclxuICAgICAgICAgICAgZmllbGRDb25maWcuaW5pdGlhbEl0ZW1zIHx8IFtdLFxyXG4gICAgICAgICAgICBmaWVsZENvbmZpZy51bmlxdWVJZEZpZWxkXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgY29udHJvbHNUb0FkZFtmaWVsZE5hbWVdID0gZm9ybUFycmF5O1xyXG5cclxuICAgICAgICAgIC8vIOWtmOWCqCBGb3JtQXJyYXkg6YWN572uXHJcbiAgICAgICAgICBmb3JtQXJyYXlDb25maWdzVG9BZGRbZmllbGROYW1lXSA9IHtcclxuICAgICAgICAgICAgaXRlbUNvbmZpZzogZmllbGRDb25maWcuaXRlbUNvbmZpZyxcclxuICAgICAgICAgICAgdW5pcXVlSWRGaWVsZDogZmllbGRDb25maWcudW5pcXVlSWRGaWVsZCxcclxuICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgLy8g5a2Y5YKo6ZSZ6K+v5raI5oGvXHJcbiAgICAgICAgICBpZiAoZmllbGRDb25maWcuZXJyb3JNZXNzYWdlcykge1xyXG4gICAgICAgICAgICBPYmplY3QuZW50cmllcyhmaWVsZENvbmZpZy5lcnJvck1lc3NhZ2VzKS5mb3JFYWNoKFxyXG4gICAgICAgICAgICAgIChbaXRlbUZpZWxkTmFtZSwgZXJyb3JNZXNzYWdlc10pID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZUtleSA9IGAke2ZpZWxkTmFtZX1bXS4ke2l0ZW1GaWVsZE5hbWV9YDtcclxuICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZXNUb0FkZFtlcnJvck1lc3NhZ2VLZXldID0gZXJyb3JNZXNzYWdlcztcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIC8vIOaZrumAmuWtl+auteWkhOeQhlxyXG4gICAgICAgICAgY29uc3QgZmllbGRDb25maWdUeXBlZCA9IGZpZWxkQ29uZmlnIGFzIEZpZWxkQ29uZmlnO1xyXG4gICAgICAgICAgY29uc3QgY29udHJvbE9wdGlvbnM6IEFic3RyYWN0Q29udHJvbE9wdGlvbnMgPSB7XHJcbiAgICAgICAgICAgIHZhbGlkYXRvcnM6IGZpZWxkQ29uZmlnVHlwZWQudmFsaWRhdG9ycz8uKCkgPz8gW10sXHJcbiAgICAgICAgICB9O1xyXG4gICAgICAgICAgY29uc3QgY29udHJvbCA9IHRoaXMuZmIuY29udHJvbChcclxuICAgICAgICAgICAgZmllbGRDb25maWdUeXBlZC52YWx1ZSxcclxuICAgICAgICAgICAgY29udHJvbE9wdGlvbnNcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICAvLyDorr7nva4gZGlzYWJsZWQg54q25oCBXHJcbiAgICAgICAgICBpZiAoZmllbGRDb25maWdUeXBlZC5kaXNhYmxlZCkge1xyXG4gICAgICAgICAgICBjb250cm9sLmRpc2FibGUoKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGNvbnRyb2xzVG9BZGRbZmllbGROYW1lXSA9IGNvbnRyb2w7XHJcblxyXG4gICAgICAgICAgLy8g5a2Y5YKo6ZSZ6K+v5raI5oGvXHJcbiAgICAgICAgICBpZiAoZmllbGRDb25maWdUeXBlZC5lcnJvck1lc3NhZ2VzKSB7XHJcbiAgICAgICAgICAgIGVycm9yTWVzc2FnZXNUb0FkZFtmaWVsZE5hbWVdID0gZmllbGRDb25maWdUeXBlZC5lcnJvck1lc3NhZ2VzO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmVzdWx0LmFkZGVkLnB1c2goZmllbGROYW1lKTtcclxuICAgICAgICBvcHRpb25zPy5vbkZpZWxkQWRkZWQ/LihmaWVsZE5hbWUsIHRydWUpO1xyXG4gICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XHJcbiAgICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID1cclxuICAgICAgICAgIGVycm9yPy5tZXNzYWdlIHx8IGVycm9yPy50b1N0cmluZygpIHx8IFwiVW5rbm93biBlcnJvclwiO1xyXG4gICAgICAgIHJlc3VsdC5mYWlsZWQucHVzaCh7XHJcbiAgICAgICAgICBmaWVsZE5hbWUsXHJcbiAgICAgICAgICBlcnJvcjogZXJyb3JNZXNzYWdlLFxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIG9wdGlvbnM/Lm9uRmllbGRBZGRlZD8uKGZpZWxkTmFtZSwgZmFsc2UsIGVycm9yTWVzc2FnZSk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgIC8vIDUuIOaJuemHj+a3u+WKoOWIsCBGb3JtR3JvdXBcclxuICAgIGlmIChPYmplY3Qua2V5cyhjb250cm9sc1RvQWRkKS5sZW5ndGggPiAwKSB7XHJcbiAgICAgIE9iamVjdC5lbnRyaWVzKGNvbnRyb2xzVG9BZGQpLmZvckVhY2goKFtmaWVsZE5hbWUsIGNvbnRyb2xdKSA9PiB7XHJcbiAgICAgICAgZm9ybUdyb3VwLmFkZENvbnRyb2woZmllbGROYW1lLCBjb250cm9sKTtcclxuICAgICAgfSk7XHJcblxyXG4gICAgICAvLyA2LiDmibnph4/lrZjlgqjplJnor6/mtojmga9cclxuICAgICAgT2JqZWN0LmVudHJpZXMoZXJyb3JNZXNzYWdlc1RvQWRkKS5mb3JFYWNoKChba2V5LCBtZXNzYWdlc10pID0+IHtcclxuICAgICAgICB0aGlzLmVycm9yTWVzc2FnZVN0b3JlW2Zvcm1OYW1lXVtrZXldID0gbWVzc2FnZXM7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgLy8gNy4g5om56YeP5a2Y5YKoIEZvcm1BcnJheSDphY3nva5cclxuICAgICAgT2JqZWN0LmVudHJpZXMoZm9ybUFycmF5Q29uZmlnc1RvQWRkKS5mb3JFYWNoKChbZmllbGROYW1lLCBjb25maWddKSA9PiB7XHJcbiAgICAgICAgdGhpcy5mb3JtQXJyYXlDb25maWdTdG9yZVtmb3JtTmFtZV1bZmllbGROYW1lXSA9IGNvbmZpZztcclxuICAgICAgfSk7XHJcblxyXG4gICAgICAvLyA4LiDmm7TmlrDooajljZXpqozor4HnirbmgIFcclxuICAgICAgaWYgKG9wdGlvbnM/LnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkpIHtcclxuICAgICAgICBmb3JtR3JvdXAudXBkYXRlVmFsdWVBbmRWYWxpZGl0eSh7XHJcbiAgICAgICAgICBlbWl0RXZlbnQ6IG9wdGlvbnM/LmVtaXRFdmVudCA/PyB0cnVlLFxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gOS4g5Yik5pat5pW05L2T5piv5ZCm5oiQ5YqfXHJcbiAgICByZXN1bHQuc3VjY2VzcyA9IHJlc3VsdC5mYWlsZWQubGVuZ3RoID09PSAwO1xyXG5cclxuICAgIHJldHVybiByZXN1bHQ7XHJcbiAgfVxyXG5cclxuICAvLyDmibnph4/liKDpmaTlrZfmrrXphY3nva5cclxuICByZW1vdmVGaWVsZHNDb25maWcoXHJcbiAgICBmb3JtTmFtZTogc3RyaW5nLFxyXG4gICAgZmllbGROYW1lczogc3RyaW5nW10sXHJcbiAgICBvcHRpb25zPzogUmVtb3ZlRmllbGRzQ29uZmlnT3B0aW9uc1xyXG4gICk6IFJlbW92ZUZpZWxkc0NvbmZpZ1Jlc3VsdCB7XHJcbiAgICBjb25zdCByZXN1bHQ6IFJlbW92ZUZpZWxkc0NvbmZpZ1Jlc3VsdCA9IHtcclxuICAgICAgc3VjY2VzczogdHJ1ZSxcclxuICAgICAgcmVtb3ZlZDogW10sXHJcbiAgICAgIGZhaWxlZDogW10sXHJcbiAgICB9O1xyXG5cclxuICAgIC8vIDEuIOmqjOivgeihqOWNleaYr+WQpuWtmOWcqFxyXG4gICAgY29uc3QgZm9ybUdyb3VwID0gdGhpcy5mb3JtU3RvcmVbZm9ybU5hbWVdO1xyXG4gICAgaWYgKCFmb3JtR3JvdXApIHtcclxuICAgICAgZmllbGROYW1lcy5mb3JFYWNoKChmaWVsZE5hbWUpID0+IHtcclxuICAgICAgICBjb25zdCBlcnJvciA9IGBGb3JtIFwiJHtmb3JtTmFtZX1cIiBub3QgZm91bmRgO1xyXG4gICAgICAgIHJlc3VsdC5mYWlsZWQucHVzaCh7XHJcbiAgICAgICAgICBmaWVsZE5hbWUsXHJcbiAgICAgICAgICBlcnJvcixcclxuICAgICAgICB9KTtcclxuICAgICAgICBvcHRpb25zPy5vbkZpZWxkUmVtb3ZlZD8uKGZpZWxkTmFtZSwgZmFsc2UsIGVycm9yKTtcclxuICAgICAgfSk7XHJcbiAgICAgIHJlc3VsdC5zdWNjZXNzID0gZmFsc2U7XHJcbiAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gMi4g5om56YeP5pS26ZuG6ZyA6KaB5riF55CG55qE5L+h5oGvXHJcbiAgICBjb25zdCBmaWVsZHNUb1JlbW92ZTogc3RyaW5nW10gPSBbXTtcclxuICAgIGNvbnN0IGVycm9yTWVzc2FnZUtleXNUb1JlbW92ZTogc3RyaW5nW10gPSBbXTtcclxuICAgIGNvbnN0IGZvcm1BcnJheUZpZWxkczogc3RyaW5nW10gPSBbXTtcclxuXHJcbiAgICAvLyAzLiDpqozor4Hmr4/kuKrlrZfmrrXlubbmlLbpm4bkv6Hmga9cclxuICAgIGZpZWxkTmFtZXMuZm9yRWFjaCgoZmllbGROYW1lKSA9PiB7XHJcbiAgICAgIGNvbnN0IGNvbnRyb2wgPSBmb3JtR3JvdXAuZ2V0KGZpZWxkTmFtZSk7XHJcblxyXG4gICAgICBpZiAoIWNvbnRyb2wpIHtcclxuICAgICAgICBjb25zdCBlcnJvciA9IGBGaWVsZCBcIiR7ZmllbGROYW1lfVwiIG5vdCBmb3VuZGA7XHJcbiAgICAgICAgcmVzdWx0LmZhaWxlZC5wdXNoKHtcclxuICAgICAgICAgIGZpZWxkTmFtZSxcclxuICAgICAgICAgIGVycm9yLFxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIG9wdGlvbnM/Lm9uRmllbGRSZW1vdmVkPy4oZmllbGROYW1lLCBmYWxzZSwgZXJyb3IpO1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8g5Yik5pat5piv5ZCm5pivIEZvcm1BcnJheVxyXG4gICAgICBpZiAoY29udHJvbCBpbnN0YW5jZW9mIEZvcm1BcnJheSkge1xyXG4gICAgICAgIGZvcm1BcnJheUZpZWxkcy5wdXNoKGZpZWxkTmFtZSk7XHJcblxyXG4gICAgICAgIC8vIOaUtumbhiBGb3JtQXJyYXkg55u45YWz55qE6ZSZ6K+v5raI5oGv6ZSu77yI5qC85byP77yaYXJyYXlOYW1lW10uZmllbGROYW1l77yJXHJcbiAgICAgICAgaWYgKHRoaXMuZXJyb3JNZXNzYWdlU3RvcmVbZm9ybU5hbWVdKSB7XHJcbiAgICAgICAgICBPYmplY3Qua2V5cyh0aGlzLmVycm9yTWVzc2FnZVN0b3JlW2Zvcm1OYW1lXSkuZm9yRWFjaCgoa2V5KSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChrZXkuc3RhcnRzV2l0aChgJHtmaWVsZE5hbWV9W10uYCkpIHtcclxuICAgICAgICAgICAgICBlcnJvck1lc3NhZ2VLZXlzVG9SZW1vdmUucHVzaChrZXkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgLy8g5pmu6YCa5a2X5q6155qE6ZSZ6K+v5raI5oGv6ZSuXHJcbiAgICAgICAgZXJyb3JNZXNzYWdlS2V5c1RvUmVtb3ZlLnB1c2goZmllbGROYW1lKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgZmllbGRzVG9SZW1vdmUucHVzaChmaWVsZE5hbWUpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgLy8gNC4g5om56YeP5omn6KGM5Yig6Zmk5pON5L2cXHJcbiAgICB0cnkge1xyXG4gICAgICAvLyA0LjEg5LuOIEZvcm1Hcm91cCDkuK3np7vpmaTmjqfku7ZcclxuICAgICAgZmllbGRzVG9SZW1vdmUuZm9yRWFjaCgoZmllbGROYW1lKSA9PiB7XHJcbiAgICAgICAgZm9ybUdyb3VwLnJlbW92ZUNvbnRyb2woZmllbGROYW1lKTtcclxuICAgICAgICByZXN1bHQucmVtb3ZlZC5wdXNoKGZpZWxkTmFtZSk7XHJcbiAgICAgICAgb3B0aW9ucz8ub25GaWVsZFJlbW92ZWQ/LihmaWVsZE5hbWUsIHRydWUpO1xyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIC8vIDQuMiDmibnph4/liKDpmaTplJnor6/mtojmga9cclxuICAgICAgaWYgKHRoaXMuZXJyb3JNZXNzYWdlU3RvcmVbZm9ybU5hbWVdKSB7XHJcbiAgICAgICAgZXJyb3JNZXNzYWdlS2V5c1RvUmVtb3ZlLmZvckVhY2goKGtleSkgPT4ge1xyXG4gICAgICAgICAgZGVsZXRlIHRoaXMuZXJyb3JNZXNzYWdlU3RvcmVbZm9ybU5hbWVdW2tleV07XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIDQuMyDmibnph4/liKDpmaQgRm9ybUFycmF5IOmFjee9rlxyXG4gICAgICBpZiAodGhpcy5mb3JtQXJyYXlDb25maWdTdG9yZVtmb3JtTmFtZV0pIHtcclxuICAgICAgICBmb3JtQXJyYXlGaWVsZHMuZm9yRWFjaCgoZmllbGROYW1lKSA9PiB7XHJcbiAgICAgICAgICBkZWxldGUgdGhpcy5mb3JtQXJyYXlDb25maWdTdG9yZVtmb3JtTmFtZV1bZmllbGROYW1lXTtcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xyXG4gICAgICAvLyDlpoLmnpzmibnph4/liKDpmaTov4fnqIvkuK3lh7rplJnvvIzmoIforrDkuLrlpLHotKVcclxuICAgICAgZmllbGRzVG9SZW1vdmUuZm9yRWFjaCgoZmllbGROYW1lKSA9PiB7XHJcbiAgICAgICAgaWYgKCFyZXN1bHQucmVtb3ZlZC5pbmNsdWRlcyhmaWVsZE5hbWUpKSB7XHJcbiAgICAgICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPVxyXG4gICAgICAgICAgICBlcnJvcj8ubWVzc2FnZSB8fCBlcnJvcj8udG9TdHJpbmcoKSB8fCBcIkZhaWxlZCB0byByZW1vdmUgZmllbGRcIjtcclxuICAgICAgICAgIHJlc3VsdC5mYWlsZWQucHVzaCh7XHJcbiAgICAgICAgICAgIGZpZWxkTmFtZSxcclxuICAgICAgICAgICAgZXJyb3I6IGVycm9yTWVzc2FnZSxcclxuICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgb3B0aW9ucz8ub25GaWVsZFJlbW92ZWQ/LihmaWVsZE5hbWUsIGZhbHNlLCBlcnJvck1lc3NhZ2UpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gNS4g5Yik5pat5pW05L2T5piv5ZCm5oiQ5YqfXHJcbiAgICByZXN1bHQuc3VjY2VzcyA9IHJlc3VsdC5mYWlsZWQubGVuZ3RoID09PSAwO1xyXG5cclxuICAgIHJldHVybiByZXN1bHQ7XHJcbiAgfVxyXG5cclxuICAvLyDlsYDpg6jotYvlgLzvvIjmlK/mjIEgRm9ybUFycmF5IOeahOaZuuiDveabtOaWsO+8jOe7n+S4gOagueaNriBhY3Rpb24g5a2X5q615Yik5pat5pON5L2c57G75Z6L77yJXHJcbiAgcGF0Y2hGb3JtVmFsdWVzKFxyXG4gICAgbmFtZTogc3RyaW5nLFxyXG4gICAgdmFsdWVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxyXG4gICAgb3B0aW9ucz86IHsgZW1pdEV2ZW50PzogYm9vbGVhbiB9XHJcbiAgKTogdm9pZCB7XHJcbiAgICBjb25zdCBmb3JtR3JvdXAgPSB0aGlzLmZvcm1TdG9yZVtuYW1lXTtcclxuICAgIGlmICghZm9ybUdyb3VwKSB7XHJcbiAgICAgIGNvbnNvbGUud2FybihcclxuICAgICAgICBgW0FudGRGb3JtU2VydmljZV0gcGF0Y2hGb3JtVmFsdWVzOiBmb3JtIFwiJHtuYW1lfVwiIG5vdCBmb3VuZC5gXHJcbiAgICAgICk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBwcm9jZXNzZWRWYWx1ZXM6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcclxuXHJcbiAgICBPYmplY3QuZW50cmllcyh2YWx1ZXMpLmZvckVhY2goKFtrZXksIHZhbHVlXSkgPT4ge1xyXG4gICAgICBjb25zdCBjb250cm9sID0gZm9ybUdyb3VwLmdldChrZXkpO1xyXG5cclxuICAgICAgLy8g5qOA5rWL5piv5ZCm5pivIEZvcm1BcnJheVxyXG4gICAgICBpZiAoY29udHJvbCBpbnN0YW5jZW9mIEZvcm1BcnJheSAmJiBBcnJheS5pc0FycmF5KHZhbHVlKSkge1xyXG4gICAgICAgIHRoaXMucGF0Y2hGb3JtQXJyYXkobmFtZSwga2V5LCB2YWx1ZSk7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyDmma7pgJrlrZfmrrXvvIznm7TmjqXliqDlhaVcclxuICAgICAgcHJvY2Vzc2VkVmFsdWVzW2tleV0gPSB2YWx1ZTtcclxuICAgIH0pO1xyXG5cclxuICAgIC8vIOWkhOeQhuaZrumAmuWtl+autVxyXG4gICAgaWYgKE9iamVjdC5rZXlzKHByb2Nlc3NlZFZhbHVlcykubGVuZ3RoID4gMCkge1xyXG4gICAgICBmb3JtR3JvdXAucGF0Y2hWYWx1ZShwcm9jZXNzZWRWYWx1ZXMsIHtcclxuICAgICAgICBlbWl0RXZlbnQ6IG9wdGlvbnM/LmVtaXRFdmVudCA/PyB0cnVlLFxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIOihqOWNleagoemqjO+8iOiHquWKqOi/h+a7pOWGhemDqOWtl+aute+8iVxyXG4gIHZhbGlkYXRlRm9ybShcclxuICAgIG5hbWU6IHN0cmluZyxcclxuICAgIG9wdGlvbnM/OiB7IGVtaXRFdmVudD86IGJvb2xlYW47IG9ubHlTZWxmPzogYm9vbGVhbiB9XHJcbiAgKTogYm9vbGVhbiB8IFJlY29yZDxzdHJpbmcsIGFueT4ge1xyXG4gICAgaWYgKHRoaXMuZm9ybVN0b3JlW25hbWVdLnZhbGlkKSB7XHJcbiAgICAgIGNvbnN0IHJhd1ZhbHVlID0gdGhpcy5mb3JtU3RvcmVbbmFtZV0uZ2V0UmF3VmFsdWUoKTtcclxuICAgICAgcmV0dXJuIHRoaXMuZXhjbHVkZUludGVybmFsRmllbGRzKHJhd1ZhbHVlKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIC8vIOmAkuW9kuagoemqjOaJgOacieaOp+S7tu+8jOWMheaLrCBGb3JtQXJyYXkg5Lit55qE6aG5XHJcbiAgICAgIHRoaXMubWFya0FsbENvbnRyb2xzQXNEaXJ0eShcclxuICAgICAgICB0aGlzLmZvcm1TdG9yZVtuYW1lXSxcclxuICAgICAgICBvcHRpb25zPy5lbWl0RXZlbnQgPz8gdHJ1ZSxcclxuICAgICAgICBvcHRpb25zPy5vbmx5U2VsZiA/PyBmYWxzZVxyXG4gICAgICApO1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyDpgJLlvZLmoIforrDmiYDmnInml6DmlYjmjqfku7bkuLogZGlydHnvvIjljIXmi6wgRm9ybUFycmF5IOS4reeahOmhue+8iVxyXG4gIHByaXZhdGUgbWFya0FsbENvbnRyb2xzQXNEaXJ0eShcclxuICAgIGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCxcclxuICAgIGVtaXRFdmVudDogYm9vbGVhbixcclxuICAgIG9ubHlTZWxmOiBib29sZWFuXHJcbiAgKTogdm9pZCB7XHJcbiAgICBpZiAoY29udHJvbC5pbnZhbGlkKSB7XHJcbiAgICAgIGNvbnRyb2wubWFya0FzRGlydHkoKTtcclxuICAgICAgY29udHJvbC51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KHtcclxuICAgICAgICBlbWl0RXZlbnQsXHJcbiAgICAgICAgb25seVNlbGYsXHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIOWmguaenOaYryBGb3JtR3JvdXDvvIzpgJLlvZLlpITnkIbmiYDmnInlrZDmjqfku7ZcclxuICAgIGlmIChjb250cm9sIGluc3RhbmNlb2YgRm9ybUdyb3VwKSB7XHJcbiAgICAgIE9iamVjdC52YWx1ZXMoY29udHJvbC5jb250cm9scykuZm9yRWFjaCgoY2hpbGRDb250cm9sKSA9PiB7XHJcbiAgICAgICAgdGhpcy5tYXJrQWxsQ29udHJvbHNBc0RpcnR5KGNoaWxkQ29udHJvbCwgZW1pdEV2ZW50LCBvbmx5U2VsZik7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIOWmguaenOaYryBGb3JtQXJyYXnvvIzpgJLlvZLlpITnkIbmlbDnu4TkuK3nmoTmr4/kuIDpoblcclxuICAgIGlmIChjb250cm9sIGluc3RhbmNlb2YgRm9ybUFycmF5KSB7XHJcbiAgICAgIGNvbnRyb2wuY29udHJvbHMuZm9yRWFjaCgoY2hpbGRDb250cm9sKSA9PiB7XHJcbiAgICAgICAgdGhpcy5tYXJrQWxsQ29udHJvbHNBc0RpcnR5KGNoaWxkQ29udHJvbCwgZW1pdEV2ZW50LCBvbmx5U2VsZik7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8gPT09PT09PT09PT09PT09PT09PT0g6ZSZ6K+v5raI5oGv55u45YWzID09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gIC8vIOiOt+WPluWtl+autemmluadoemUmeivr+aPkOekuu+8jOaUr+aMgeaZrumAmuWtl+auteWSjCBGb3JtQXJyYXkg5a2X5q6177yI5qC85byP77yaYXJyYXlOYW1lLmluZGV4LmZpZWxkTmFtZe+8iVxyXG4gIGdldEZpZWxkRXJyb3JNZXNzYWdlKG5hbWU6IHN0cmluZywgY29udHJvbE5hbWU6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICBjb25zdCBmb3JtR3JvdXAgPSB0aGlzLmZvcm1TdG9yZVtuYW1lXTtcclxuICAgIGlmICghZm9ybUdyb3VwKSB7XHJcbiAgICAgIGNvbnNvbGUud2FybihcclxuICAgICAgICBgW0FudGRGb3JtU2VydmljZV0gZ2V0RmllbGRFcnJvck1lc3NhZ2U6IGZvcm0gXCIke25hbWV9XCIgbm90IGZvdW5kLmBcclxuICAgICAgKTtcclxuICAgICAgcmV0dXJuIFwiXCI7XHJcbiAgICB9XHJcbiAgICBjb25zdCBjb250cm9sID0gZm9ybUdyb3VwLmdldChjb250cm9sTmFtZSk7XHJcbiAgICBpZiAoIWNvbnRyb2wpIHtcclxuICAgICAgY29uc29sZS53YXJuKFxyXG4gICAgICAgIGBbQW50ZEZvcm1TZXJ2aWNlXSBnZXRGaWVsZEVycm9yTWVzc2FnZTogY29udHJvbCBcIiR7Y29udHJvbE5hbWV9XCIgbm90IGZvdW5kIGluIGZvcm0gXCIke25hbWV9XCIuYFxyXG4gICAgICApO1xyXG4gICAgICByZXR1cm4gXCJcIjtcclxuICAgIH1cclxuICAgIGlmICghY29udHJvbC5lcnJvcnMpIHtcclxuICAgICAgcmV0dXJuIFwiXCI7XHJcbiAgICB9XHJcblxyXG4gICAgLy8g6Kej5p6QIGNvbnRyb2xOYW1l77yM5pSv5oyBIEZvcm1BcnJheSDmoLzlvI/vvJphcnJheU5hbWUuaW5kZXguZmllbGROYW1lXHJcbiAgICBsZXQgZXJyb3JNZXNzYWdlS2V5ID0gY29udHJvbE5hbWU7XHJcbiAgICBjb25zdCBhcnJheU1hdGNoID0gY29udHJvbE5hbWUubWF0Y2goL14oLispXFwuKFxcZCspXFwuKC4rKSQvKTtcclxuICAgIGlmIChhcnJheU1hdGNoKSB7XHJcbiAgICAgIC8vIEZvcm1BcnJheSDmoLzlvI/vvJphcnJheU5hbWUuaW5kZXguZmllbGROYW1lIC0+IOS9v+eUqCBhcnJheU5hbWVbXS5maWVsZE5hbWUg5L2c5Li6IGtleVxyXG4gICAgICBjb25zdCBbLCBhcnJheU5hbWUsICwgZmllbGROYW1lXSA9IGFycmF5TWF0Y2g7XHJcbiAgICAgIGVycm9yTWVzc2FnZUtleSA9IGAke2FycmF5TmFtZX1bXS4ke2ZpZWxkTmFtZX1gO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIOS7jiBlcnJvck1lc3NhZ2VTdG9yZSDojrflj5bplJnor6/mtojmga/phY3nva5cclxuICAgIGNvbnN0IGVycm9yTWVzc2FnZXMgPSB0aGlzLmVycm9yTWVzc2FnZVN0b3JlW25hbWVdPy5bZXJyb3JNZXNzYWdlS2V5XTtcclxuICAgIGNvbnN0IG1lcmdlZE1lc3NhZ2VzID0ge1xyXG4gICAgICAuLi50aGlzLmRlZmF1bHRFcnJvck1lc3NhZ2VzLFxyXG4gICAgICAuLi4oZXJyb3JNZXNzYWdlcyA/PyB7fSksXHJcbiAgICB9O1xyXG5cclxuICAgIGZvciAoY29uc3QgZXJyb3JLZXkgb2YgT2JqZWN0LmtleXMoY29udHJvbC5lcnJvcnMpKSB7XHJcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBtZXJnZWRNZXNzYWdlc1tlcnJvcktleV07XHJcbiAgICAgIGlmIChtZXNzYWdlKSB7XHJcbiAgICAgICAgLy8g5LiN5YaN5pSv5oyB5Ye95pWw5b2i5byP77yM5Y+q6L+U5Zue5a2X56ym5LiyXHJcbiAgICAgICAgcmV0dXJuIHR5cGVvZiBtZXNzYWdlID09PSBcInN0cmluZ1wiID8gbWVzc2FnZSA6IFwiXCI7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBcIlwiO1xyXG4gIH1cclxuXHJcbiAgLy8gPT09PT09PT09PT09PT09PT09PT0g55uR5ZCs55u45YWzID09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gIC8vIOebkeWQrOihqOWNleaJgOacieWtl+auteWPmOabtFxyXG4gIHdhdGNoRm9ybUNoYW5nZXM8VCA9IGFueT4oXHJcbiAgICBuYW1lOiBzdHJpbmcsXHJcbiAgICBoYW5kbGVyOiAodmFsdWU6IFQpID0+IHZvaWQsXHJcbiAgICBvcHRpb25zPzogV2F0Y2hPcHRpb25zXHJcbiAgKTogU3Vic2NyaXB0aW9uIHwgdW5kZWZpbmVkIHtcclxuICAgIGNvbnN0IGZvcm1Hcm91cCA9IHRoaXMuZm9ybVN0b3JlW25hbWVdO1xyXG4gICAgaWYgKCFmb3JtR3JvdXApIHtcclxuICAgICAgY29uc29sZS53YXJuKFxyXG4gICAgICAgIGBbQW50ZEZvcm1TZXJ2aWNlXSB3YXRjaEZvcm1DaGFuZ2VzOiBmb3JtIFwiJHtuYW1lfVwiIG5vdCBmb3VuZC5gXHJcbiAgICAgICk7XHJcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuc2V0dXBWYWx1ZUNoYW5nZVN1YnNjcmlwdGlvbihmb3JtR3JvdXAsIGhhbmRsZXIsIG9wdGlvbnMpO1xyXG4gIH1cclxuXHJcbiAgLy8g55uR5ZCs5oyH5a6a5a2X5q615Y+Y5pu0XHJcbiAgd2F0Y2hGaWVsZENoYW5nZXM8VCA9IGFueT4oXHJcbiAgICBuYW1lOiBzdHJpbmcsXHJcbiAgICBjb250cm9sTmFtZTogc3RyaW5nLFxyXG4gICAgaGFuZGxlcjogKHZhbHVlOiBUKSA9PiB2b2lkLFxyXG4gICAgb3B0aW9ucz86IFdhdGNoT3B0aW9uc1xyXG4gICk6IFN1YnNjcmlwdGlvbiB8IHVuZGVmaW5lZCB7XHJcbiAgICBjb25zdCBmb3JtR3JvdXAgPSB0aGlzLmZvcm1TdG9yZVtuYW1lXTtcclxuICAgIGlmICghZm9ybUdyb3VwKSB7XHJcbiAgICAgIGNvbnNvbGUud2FybihcclxuICAgICAgICBgW0FudGRGb3JtU2VydmljZV0gd2F0Y2hGaWVsZENoYW5nZXM6IGZvcm0gXCIke25hbWV9XCIgbm90IGZvdW5kLmBcclxuICAgICAgKTtcclxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBjb250cm9sID0gZm9ybUdyb3VwLmdldChjb250cm9sTmFtZSk7XHJcbiAgICBpZiAoIWNvbnRyb2wpIHtcclxuICAgICAgY29uc29sZS53YXJuKFxyXG4gICAgICAgIGBbQW50ZEZvcm1TZXJ2aWNlXSB3YXRjaEZpZWxkQ2hhbmdlczogY29udHJvbCBcIiR7Y29udHJvbE5hbWV9XCIgbm90IGZvdW5kIGluIGZvcm0gXCIke25hbWV9XCIuYFxyXG4gICAgICApO1xyXG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzLnNldHVwVmFsdWVDaGFuZ2VTdWJzY3JpcHRpb24oY29udHJvbCwgaGFuZGxlciwgb3B0aW9ucyk7XHJcbiAgfVxyXG5cclxuICAvLyA9PT09PT09PT09PT09PT09PT09PSDlt6Xlhbfmlrnms5UgPT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgLy8g6I635Y+W6KGo5Y2V57G75ZCNXHJcbiAgZ2V0Rm9ybUNsYXNzTmFtZShuYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIGAke3RoaXMuY2xhc3NQcmVmaXh9JHtuYW1lfWA7XHJcbiAgfVxyXG5cclxuICAvLyDorr7nva4gQ1NTIOWPmOmHj+WIsOebruagh+WFg+e0oO+8iOaUr+aMgeaMgeS5heWMluebkeWQrOWKqOaAgea3u+WKoOeahOWFg+e0oO+8iVxyXG4gIHNldENTU1ZhcmlhYmxlc1RvVGFyZ2V0KG5hbWU6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgY29uc3Qgc2VsZWN0b3IgPSBgLiR7dGhpcy5nZXRGb3JtQ2xhc3NOYW1lKG5hbWUpfSAuYW50LWZvcm0taXRlbS1sYWJlbGA7XHJcbiAgICBjb25zdCBmb3JtQ29udGFpbmVyU2VsZWN0b3IgPSBgLiR7dGhpcy5nZXRGb3JtQ2xhc3NOYW1lKG5hbWUpfWA7XHJcbiAgICBjb25zdCBhcHBseVN0eWxlcyA9ICgpOiBib29sZWFuID0+IHtcclxuICAgICAgY29uc3QgZG9tID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7XHJcbiAgICAgIGlmICghZG9tLmxlbmd0aCkge1xyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgfVxyXG4gICAgICBsZXQgYXBwbGllZENvdW50ID0gMDtcclxuICAgICAgZG9tLmZvckVhY2goKGl0ZW0pID0+IHtcclxuICAgICAgICBjb25zdCB0YXJnZXQgPSBpdGVtIGFzIEhUTUxFbGVtZW50O1xyXG4gICAgICAgIGlmIChcclxuICAgICAgICAgIHRhcmdldC5zdHlsZS53aWR0aCAhPT0gdGhpcy5sYWJlbFdpZHRoIHx8XHJcbiAgICAgICAgICB0YXJnZXQuc3R5bGUudGV4dEFsaWduICE9PSB0aGlzLmxhYmVsQWxpZ25cclxuICAgICAgICApIHtcclxuICAgICAgICAgIHRhcmdldC5zdHlsZS53aWR0aCA9IHRoaXMubGFiZWxXaWR0aDtcclxuICAgICAgICAgIHRhcmdldC5zdHlsZS50ZXh0QWxpZ24gPSB0aGlzLmxhYmVsQWxpZ247XHJcbiAgICAgICAgICBhcHBsaWVkQ291bnQrKztcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgICByZXR1cm4gYXBwbGllZENvdW50ID4gMDtcclxuICAgIH07XHJcbiAgICBpZiAodGhpcy5sYWJlbE9ic2VydmVyc1tuYW1lXSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBsZXQgdGltZW91dDogYW55ID0gbnVsbDtcclxuICAgIGNvbnN0IG9ic2VydmVyID0gbmV3IE11dGF0aW9uT2JzZXJ2ZXIoKCkgPT4ge1xyXG4gICAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aW1lb3V0KTtcclxuICAgICAgdGltZW91dCA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XHJcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICBhcHBseVN0eWxlcygpO1xyXG4gICAgICAgIH0sIDApO1xyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG4gICAgY29uc3QgZm9ybUNvbnRhaW5lciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZm9ybUNvbnRhaW5lclNlbGVjdG9yKTtcclxuICAgIG9ic2VydmVyLm9ic2VydmUoZm9ybUNvbnRhaW5lciB8fCBkb2N1bWVudC5ib2R5LCB7XHJcbiAgICAgIGNoaWxkTGlzdDogdHJ1ZSxcclxuICAgICAgc3VidHJlZTogdHJ1ZSxcclxuICAgICAgYXR0cmlidXRlczogdHJ1ZSxcclxuICAgIH0pO1xyXG4gICAgdGhpcy5sYWJlbE9ic2VydmVyc1tuYW1lXSA9IG9ic2VydmVyO1xyXG4gIH1cclxuXHJcbiAgLy8gPT09PT09PT09PT09PT09PT09PT0g56eB5pyJ5pa55rOVID09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gIC8vIOiOt+WPliBGb3JtQXJyYXlcclxuICBwcml2YXRlIGdldEZvcm1BcnJheShmb3JtTmFtZTogc3RyaW5nLCBhcnJheU5hbWU6IHN0cmluZyk6IEZvcm1BcnJheSB8IG51bGwge1xyXG4gICAgY29uc3QgZm9ybUdyb3VwID0gdGhpcy5mb3JtU3RvcmVbZm9ybU5hbWVdO1xyXG4gICAgaWYgKCFmb3JtR3JvdXApIHtcclxuICAgICAgY29uc29sZS53YXJuKFxyXG4gICAgICAgIGBbQW50ZEZvcm1TZXJ2aWNlXSBnZXRGb3JtQXJyYXk6IGZvcm0gXCIke2Zvcm1OYW1lfVwiIG5vdCBmb3VuZC5gXHJcbiAgICAgICk7XHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGNvbnRyb2wgPSBmb3JtR3JvdXAuZ2V0KGFycmF5TmFtZSk7XHJcbiAgICBpZiAoIWNvbnRyb2wgfHwgIShjb250cm9sIGluc3RhbmNlb2YgRm9ybUFycmF5KSkge1xyXG4gICAgICBjb25zb2xlLndhcm4oXHJcbiAgICAgICAgYFtBbnRkRm9ybVNlcnZpY2VdIGdldEZvcm1BcnJheTogYXJyYXkgXCIke2FycmF5TmFtZX1cIiBub3QgZm91bmQgaW4gZm9ybSBcIiR7Zm9ybU5hbWV9XCIuYFxyXG4gICAgICApO1xyXG4gICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gY29udHJvbCBhcyBGb3JtQXJyYXk7XHJcbiAgfVxyXG5cclxuICAvLyDliKTmlq3mmK/lkKbmmK8gRm9ybUFycmF5IOmFjee9rlxyXG4gIHByaXZhdGUgaXNGb3JtQXJyYXlDb25maWcoXHJcbiAgICBmaWVsZDogRmllbGRDb25maWcgfCBGb3JtQXJyYXlDb25maWdcclxuICApOiBmaWVsZCBpcyBGb3JtQXJyYXlDb25maWcge1xyXG4gICAgcmV0dXJuIChmaWVsZCBhcyBGb3JtQXJyYXlDb25maWcpLnR5cGUgPT09IFwiYXJyYXlcIjtcclxuICB9XHJcblxyXG4gIC8vIOS7jumFjee9ruWIm+W7uiBGb3JtQXJyYXlcclxuICBwcml2YXRlIGNyZWF0ZUZvcm1BcnJheUZyb21Db25maWcoXHJcbiAgICBmb3JtTmFtZTogc3RyaW5nLFxyXG4gICAgYXJyYXlOYW1lOiBzdHJpbmcsXHJcbiAgICBpdGVtQ29uZmlnOiBGb3JtQ29uZmlnLFxyXG4gICAgaW5pdGlhbEl0ZW1zOiBhbnlbXSxcclxuICAgIHVuaXF1ZUlkRmllbGQ/OiBzdHJpbmdcclxuICApOiBGb3JtQXJyYXkge1xyXG4gICAgY29uc3QgZm9ybUFycmF5ID0gdGhpcy5mYi5hcnJheShbXSk7XHJcblxyXG4gICAgaW5pdGlhbEl0ZW1zLmZvckVhY2goKGl0ZW0pID0+IHtcclxuICAgICAgY29uc3QgaXRlbUdyb3VwID0gdGhpcy5jcmVhdGVJdGVtRm9ybUdyb3VwKFxyXG4gICAgICAgIGl0ZW1Db25maWcsXHJcbiAgICAgICAgaXRlbSxcclxuICAgICAgICB1bmlxdWVJZEZpZWxkXHJcbiAgICAgICk7XHJcbiAgICAgIGZvcm1BcnJheS5wdXNoKGl0ZW1Hcm91cCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4gZm9ybUFycmF5O1xyXG4gIH1cclxuXHJcbiAgLy8g55Sf5oiQ5YaF6YOoSUTvvIjkvb/nlKjkuJrliqHllK/kuIDlrZfmrrXmiJbnlJ/miJDkuLTml7ZJRO+8iVxyXG4gIHByaXZhdGUgZ2VuZXJhdGVJbnRlcm5hbElkKGl0ZW1EYXRhOiBhbnksIHVuaXF1ZUlkRmllbGQ/OiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgLy8g5LyY5YWI5L2/55So5Lia5Yqh5ZSv5LiA5a2X5q61XHJcbiAgICBpZiAodW5pcXVlSWRGaWVsZCAmJiBpdGVtRGF0YT8uW3VuaXF1ZUlkRmllbGRdICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgY29uc3QgYnVzaW5lc3NJZCA9IGl0ZW1EYXRhW3VuaXF1ZUlkRmllbGRdO1xyXG4gICAgICBpZiAoXHJcbiAgICAgICAgYnVzaW5lc3NJZCAhPT0gbnVsbCAmJlxyXG4gICAgICAgIGJ1c2luZXNzSWQgIT09IHVuZGVmaW5lZCAmJlxyXG4gICAgICAgIGJ1c2luZXNzSWQgIT09IFwiXCJcclxuICAgICAgKSB7XHJcbiAgICAgICAgcmV0dXJuIGBidXNpbmVzcy0ke3VuaXF1ZUlkRmllbGR9LSR7YnVzaW5lc3NJZH1gO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8g5aaC5p6c5rKh5pyJ5Lia5YqhSUTvvIznlJ/miJDkuLTml7ZJRO+8iOeUqOS6juaWsOa3u+WKoOeahOmhue+8iVxyXG4gICAgcmV0dXJuIGB0ZW1wLSR7RGF0ZS5ub3coKX0tJHtNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zdWJzdHIoMiwgOSl9YDtcclxuICB9XHJcblxyXG4gIC8vIOWIm+W7uuWNleS4qumhueeahCBGb3JtR3JvdXBcclxuICBwcml2YXRlIGNyZWF0ZUl0ZW1Gb3JtR3JvdXAoXHJcbiAgICBpdGVtQ29uZmlnOiBGb3JtQ29uZmlnLFxyXG4gICAgaXRlbURhdGE6IGFueSxcclxuICAgIHVuaXF1ZUlkRmllbGQ/OiBzdHJpbmdcclxuICApOiBGb3JtR3JvdXAge1xyXG4gICAgY29uc3QgZ3JvdXBDb25maWc6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcclxuXHJcbiAgICAvLyDmt7vliqDlhoXpg6hJROWtl+autVxyXG4gICAgY29uc3QgaXRlbUlkID0gdGhpcy5nZW5lcmF0ZUludGVybmFsSWQoaXRlbURhdGEsIHVuaXF1ZUlkRmllbGQpO1xyXG4gICAgZ3JvdXBDb25maWdbdGhpcy5JTlRFUk5BTF9JRF9GSUVMRF0gPSBbXHJcbiAgICAgIHsgdmFsdWU6IGl0ZW1JZCwgZGlzYWJsZWQ6IHRydWUgfSxcclxuICAgICAgW10sXHJcbiAgICBdO1xyXG5cclxuICAgIC8vIOa3u+WKoOS4muWKoeWtl+autVxyXG4gICAgT2JqZWN0LmVudHJpZXMoaXRlbUNvbmZpZykuZm9yRWFjaCgoW2tleSwgZmllbGRdKSA9PiB7XHJcbiAgICAgIC8vIGl0ZW1Db25maWcg5Lit55qE5a2X5q615bqU6K+l5pivIEZpZWxkQ29uZmln77yM5LiN5bqU6K+l5YyF5ZCrIEZvcm1BcnJheUNvbmZpZ1xyXG4gICAgICBpZiAodGhpcy5pc0Zvcm1BcnJheUNvbmZpZyhmaWVsZCkpIHtcclxuICAgICAgICBjb25zb2xlLndhcm4oXHJcbiAgICAgICAgICBgW0FudGRGb3JtU2VydmljZV0gY3JlYXRlSXRlbUZvcm1Hcm91cDogRm9ybUFycmF5Q29uZmlnIGlzIG5vdCBhbGxvd2VkIGluIGl0ZW1Db25maWcuIFNraXBwaW5nIGZpZWxkIFwiJHtrZXl9XCIuYFxyXG4gICAgICAgICk7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBjb25zdCBmaWVsZENvbmZpZyA9IGZpZWxkIGFzIEZpZWxkQ29uZmlnO1xyXG4gICAgICBjb25zdCB2YWx1ZSA9XHJcbiAgICAgICAgaXRlbURhdGE/LltrZXldICE9PSB1bmRlZmluZWQgPyBpdGVtRGF0YVtrZXldIDogZmllbGRDb25maWcudmFsdWU7XHJcbiAgICAgIGdyb3VwQ29uZmlnW2tleV0gPSBbXHJcbiAgICAgICAgeyB2YWx1ZTogdmFsdWUsIGRpc2FibGVkOiBmaWVsZENvbmZpZy5kaXNhYmxlZCA/PyBmYWxzZSB9LFxyXG4gICAgICAgIGZpZWxkQ29uZmlnLnZhbGlkYXRvcnM/LigpID8/IFtdLFxyXG4gICAgICBdO1xyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gdGhpcy5mYi5ncm91cChncm91cENvbmZpZyk7XHJcbiAgfVxyXG5cclxuICAvLyDpgJrov4fkuJrliqHllK/kuIDlrZfmrrXmn6Xmib7lhoXpg6hJRFxyXG4gIHByaXZhdGUgZmluZEZvcm1BcnJheUl0ZW1JZEJ5QnVzaW5lc3NGaWVsZChcclxuICAgIGZvcm1OYW1lOiBzdHJpbmcsXHJcbiAgICBhcnJheU5hbWU6IHN0cmluZyxcclxuICAgIHVuaXF1ZUlkRmllbGQ6IHN0cmluZyxcclxuICAgIGJ1c2luZXNzSWRWYWx1ZTogYW55XHJcbiAgKTogc3RyaW5nIHwgbnVsbCB7XHJcbiAgICBjb25zdCBmb3JtQXJyYXkgPSB0aGlzLmdldEZvcm1BcnJheShmb3JtTmFtZSwgYXJyYXlOYW1lKTtcclxuICAgIGlmICghZm9ybUFycmF5KSByZXR1cm4gbnVsbDtcclxuXHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGZvcm1BcnJheS5sZW5ndGg7IGkrKykge1xyXG4gICAgICBjb25zdCBpdGVtID0gZm9ybUFycmF5LmF0KGkpIGFzIEZvcm1Hcm91cDtcclxuICAgICAgY29uc3QgaXRlbVZhbHVlID0gaXRlbS5nZXRSYXdWYWx1ZSgpO1xyXG4gICAgICBjb25zdCBpbnRlcm5hbElkID0gaXRlbVZhbHVlW3RoaXMuSU5URVJOQUxfSURfRklFTERdO1xyXG5cclxuICAgICAgLy8g5qOA5p+l5YaF6YOoSUTmmK/lkKbljLnphY3kuJrliqFJRFxyXG4gICAgICBpZiAoaW50ZXJuYWxJZCAmJiBpbnRlcm5hbElkLnN0YXJ0c1dpdGgoYGJ1c2luZXNzLSR7dW5pcXVlSWRGaWVsZH0tYCkpIHtcclxuICAgICAgICBjb25zdCBpZEluSW50ZXJuYWxJZCA9IGludGVybmFsSWQucmVwbGFjZShcclxuICAgICAgICAgIGBidXNpbmVzcy0ke3VuaXF1ZUlkRmllbGR9LWAsXHJcbiAgICAgICAgICBcIlwiXHJcbiAgICAgICAgKTtcclxuICAgICAgICBpZiAoU3RyaW5nKGlkSW5JbnRlcm5hbElkKSA9PT0gU3RyaW5nKGJ1c2luZXNzSWRWYWx1ZSkpIHtcclxuICAgICAgICAgIHJldHVybiBpbnRlcm5hbElkO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgLy8g5Lmf5qOA5p+l5b2T5YmN5Lia5Yqh5a2X5q615YC85piv5ZCm5Yy56YWN77yI5aSE55CG5Lia5YqhSUTmm7TmlrDnmoTmg4XlhrXvvIlcclxuICAgICAgaWYgKGl0ZW1WYWx1ZVt1bmlxdWVJZEZpZWxkXSA9PT0gYnVzaW5lc3NJZFZhbHVlKSB7XHJcbiAgICAgICAgcmV0dXJuIGludGVybmFsSWQ7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBudWxsO1xyXG4gIH1cclxuXHJcbiAgLy8g6YCa6L+H5YaF6YOoSUTmn6Xmib7poblcclxuICBwcml2YXRlIGZpbmRGb3JtQXJyYXlJdGVtQnlJZChcclxuICAgIGZvcm1OYW1lOiBzdHJpbmcsXHJcbiAgICBhcnJheU5hbWU6IHN0cmluZyxcclxuICAgIGl0ZW1JZDogc3RyaW5nXHJcbiAgKTogeyBpbmRleDogbnVtYmVyOyBmb3JtR3JvdXA6IEZvcm1Hcm91cCB9IHwgbnVsbCB7XHJcbiAgICBjb25zdCBmb3JtQXJyYXkgPSB0aGlzLmdldEZvcm1BcnJheShmb3JtTmFtZSwgYXJyYXlOYW1lKTtcclxuICAgIGlmICghZm9ybUFycmF5KSByZXR1cm4gbnVsbDtcclxuXHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGZvcm1BcnJheS5sZW5ndGg7IGkrKykge1xyXG4gICAgICBjb25zdCBpdGVtID0gZm9ybUFycmF5LmF0KGkpIGFzIEZvcm1Hcm91cDtcclxuICAgICAgY29uc3QgaWQgPSBpdGVtLmdldCh0aGlzLklOVEVSTkFMX0lEX0ZJRUxEKT8udmFsdWU7XHJcbiAgICAgIGlmIChpZCA9PT0gaXRlbUlkKSB7XHJcbiAgICAgICAgcmV0dXJuIHsgaW5kZXg6IGksIGZvcm1Hcm91cDogaXRlbSB9O1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbnVsbDtcclxuICB9XHJcblxyXG4gIC8vIOiOt+WPluaTjeS9nOexu+Wei++8iOW/hemhu+aYjuehruaMh+WumiBhY3Rpb24g5a2X5q6177yJXHJcbiAgcHJpdmF0ZSBnZXRPcGVyYXRpb25UeXBlKFxyXG4gICAgaXRlbURhdGE6IGFueVxyXG4gICk6IFwiY3JlYXRlXCIgfCBcInVwZGF0ZVwiIHwgXCJkZWxldGVcIiB8IG51bGwge1xyXG4gICAgaWYgKCFpdGVtRGF0YSB8fCB0eXBlb2YgaXRlbURhdGEgIT09IFwib2JqZWN0XCIpIHJldHVybiBudWxsO1xyXG5cclxuICAgIGNvbnN0IGFjdGlvbiA9IGl0ZW1EYXRhLmFjdGlvbjtcclxuICAgIGlmIChhY3Rpb24gPT09IFwiZGVsZXRlXCIgfHwgYWN0aW9uID09PSBcInVwZGF0ZVwiIHx8IGFjdGlvbiA9PT0gXCJjcmVhdGVcIikge1xyXG4gICAgICByZXR1cm4gYWN0aW9uO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBudWxsO1xyXG4gIH1cclxuXHJcbiAgLy8g6L+H5ruk5pON5L2c5a2X5q6177yIYWN0aW9uIOWtl+auteS4jeS/neWtmOWIsOihqOWNleS4re+8iVxyXG4gIHByaXZhdGUgZmlsdGVyT3BlcmF0aW9uRmllbGRzKGl0ZW1EYXRhOiBhbnkpOiBhbnkge1xyXG4gICAgaWYgKCFpdGVtRGF0YSB8fCB0eXBlb2YgaXRlbURhdGEgIT09IFwib2JqZWN0XCIpIHJldHVybiBpdGVtRGF0YTtcclxuXHJcbiAgICBjb25zdCBmaWx0ZXJlZDogYW55ID0ge307XHJcbiAgICBPYmplY3QuZW50cmllcyhpdGVtRGF0YSkuZm9yRWFjaCgoW2tleSwgdmFsdWVdKSA9PiB7XHJcbiAgICAgIGlmIChrZXkgIT09IFwiYWN0aW9uXCIpIHtcclxuICAgICAgICBmaWx0ZXJlZFtrZXldID0gdmFsdWU7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIGZpbHRlcmVkO1xyXG4gIH1cclxuXHJcbiAgLy8g5aSE55CGIEZvcm1BcnJheSDnmoTmm7TmlrDvvIjnu5/kuIDmoLnmja4gYWN0aW9uIOWtl+auteWIpOaWreaTjeS9nOexu+Wei++8iVxyXG4gIHByaXZhdGUgcGF0Y2hGb3JtQXJyYXkoXHJcbiAgICBmb3JtTmFtZTogc3RyaW5nLFxyXG4gICAgYXJyYXlOYW1lOiBzdHJpbmcsXHJcbiAgICBuZXdWYWx1ZXM6IGFueVtdXHJcbiAgKTogdm9pZCB7XHJcbiAgICBjb25zdCBmb3JtQXJyYXkgPSB0aGlzLmdldEZvcm1BcnJheShmb3JtTmFtZSwgYXJyYXlOYW1lKTtcclxuICAgIGlmICghZm9ybUFycmF5KSB7XHJcbiAgICAgIGNvbnNvbGUud2FybihcclxuICAgICAgICBgW0FudGRGb3JtU2VydmljZV0gcGF0Y2hGb3JtQXJyYXk6IGFycmF5IFwiJHthcnJheU5hbWV9XCIgbm90IGZvdW5kIGluIGZvcm0gXCIke2Zvcm1OYW1lfVwiLmBcclxuICAgICAgKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuZm9ybUFycmF5Q29uZmlnU3RvcmVbZm9ybU5hbWVdPy5bYXJyYXlOYW1lXTtcclxuICAgIGlmICghY29uZmlnKSB7XHJcbiAgICAgIGNvbnNvbGUud2FybihcclxuICAgICAgICBgW0FudGRGb3JtU2VydmljZV0gcGF0Y2hGb3JtQXJyYXk6IGNvbmZpZyBub3QgZm91bmQgZm9yIGFycmF5IFwiJHthcnJheU5hbWV9XCIgaW4gZm9ybSBcIiR7Zm9ybU5hbWV9XCIuYFxyXG4gICAgICApO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgeyBpdGVtQ29uZmlnLCB1bmlxdWVJZEZpZWxkIH0gPSBjb25maWc7XHJcblxyXG4gICAgLy8g57uf5LiA5qC55o2uIGFjdGlvbiDlrZfmrrXliKTmlq3mk43kvZznsbvlnotcclxuICAgIGNvbnN0IGl0ZW1zVG9EZWxldGUgPSBuZXcgU2V0PHN0cmluZz4oKTtcclxuICAgIGNvbnN0IGl0ZW1zVG9VcGRhdGUgPSBuZXcgTWFwPHN0cmluZywgYW55PigpO1xyXG4gICAgY29uc3QgaXRlbXNUb0FkZDogYW55W10gPSBbXTtcclxuXHJcbiAgICBuZXdWYWx1ZXMuZm9yRWFjaCgoaXRlbURhdGEpID0+IHtcclxuICAgICAgaWYgKCFpdGVtRGF0YSB8fCB0eXBlb2YgaXRlbURhdGEgIT09IFwib2JqZWN0XCIpIHJldHVybjtcclxuXHJcbiAgICAgIGNvbnN0IG9wZXJhdGlvblR5cGUgPSB0aGlzLmdldE9wZXJhdGlvblR5cGUoaXRlbURhdGEpO1xyXG4gICAgICBpZiAoIW9wZXJhdGlvblR5cGUpIHtcclxuICAgICAgICBjb25zb2xlLndhcm4oXHJcbiAgICAgICAgICBgW0FudGRGb3JtU2VydmljZV0gcGF0Y2hGb3JtQXJyYXk6IEl0ZW0gbWlzc2luZyByZXF1aXJlZCBcImFjdGlvblwiIGZpZWxkLiBTa2lwcGluZy5gLFxyXG4gICAgICAgICAgaXRlbURhdGFcclxuICAgICAgICApO1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8g5Yig6Zmk5pON5L2cXHJcbiAgICAgIGlmIChvcGVyYXRpb25UeXBlID09PSBcImRlbGV0ZVwiKSB7XHJcbiAgICAgICAgaWYgKHVuaXF1ZUlkRmllbGQgJiYgaXRlbURhdGFbdW5pcXVlSWRGaWVsZF0gIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgY29uc3QgYnVzaW5lc3NJZCA9IGl0ZW1EYXRhW3VuaXF1ZUlkRmllbGRdO1xyXG4gICAgICAgICAgY29uc3QgaW50ZXJuYWxJZCA9IHRoaXMuZmluZEZvcm1BcnJheUl0ZW1JZEJ5QnVzaW5lc3NGaWVsZChcclxuICAgICAgICAgICAgZm9ybU5hbWUsXHJcbiAgICAgICAgICAgIGFycmF5TmFtZSxcclxuICAgICAgICAgICAgdW5pcXVlSWRGaWVsZCxcclxuICAgICAgICAgICAgYnVzaW5lc3NJZFxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIGlmIChpbnRlcm5hbElkKSB7XHJcbiAgICAgICAgICAgIGl0ZW1zVG9EZWxldGUuYWRkKGludGVybmFsSWQpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgY29uc29sZS53YXJuKFxyXG4gICAgICAgICAgICAgIGBbQW50ZEZvcm1TZXJ2aWNlXSBwYXRjaEZvcm1BcnJheTogQ2Fubm90IGRlbGV0ZSBpdGVtIHdpdGggJHt1bmlxdWVJZEZpZWxkfT0ke2J1c2luZXNzSWR9LCBpdGVtIG5vdCBmb3VuZC5gXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIGNvbnNvbGUud2FybihcclxuICAgICAgICAgICAgYFtBbnRkRm9ybVNlcnZpY2VdIHBhdGNoRm9ybUFycmF5OiBDYW5ub3QgZGVsZXRlIGl0ZW0sIG1pc3NpbmcgcmVxdWlyZWQgdW5pcXVlSWRGaWVsZCBcIiR7dW5pcXVlSWRGaWVsZH1cIi5gXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIOabtOaWsOaTjeS9nFxyXG4gICAgICBpZiAob3BlcmF0aW9uVHlwZSA9PT0gXCJ1cGRhdGVcIikge1xyXG4gICAgICAgIGlmICh1bmlxdWVJZEZpZWxkICYmIGl0ZW1EYXRhW3VuaXF1ZUlkRmllbGRdICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgIGNvbnN0IGJ1c2luZXNzSWQgPSBpdGVtRGF0YVt1bmlxdWVJZEZpZWxkXTtcclxuICAgICAgICAgIGNvbnN0IGludGVybmFsSWQgPSB0aGlzLmZpbmRGb3JtQXJyYXlJdGVtSWRCeUJ1c2luZXNzRmllbGQoXHJcbiAgICAgICAgICAgIGZvcm1OYW1lLFxyXG4gICAgICAgICAgICBhcnJheU5hbWUsXHJcbiAgICAgICAgICAgIHVuaXF1ZUlkRmllbGQsXHJcbiAgICAgICAgICAgIGJ1c2luZXNzSWRcclxuICAgICAgICAgICk7XHJcblxyXG4gICAgICAgICAgaWYgKGludGVybmFsSWQpIHtcclxuICAgICAgICAgICAgY29uc3QgZmlsdGVyZWREYXRhID0gdGhpcy5maWx0ZXJPcGVyYXRpb25GaWVsZHMoaXRlbURhdGEpO1xyXG4gICAgICAgICAgICBpdGVtc1RvVXBkYXRlLnNldChpbnRlcm5hbElkLCBmaWx0ZXJlZERhdGEpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgY29uc29sZS53YXJuKFxyXG4gICAgICAgICAgICAgIGBbQW50ZEZvcm1TZXJ2aWNlXSBwYXRjaEZvcm1BcnJheTogQ2Fubm90IHVwZGF0ZSBpdGVtIHdpdGggJHt1bmlxdWVJZEZpZWxkfT0ke2J1c2luZXNzSWR9LCBpdGVtIG5vdCBmb3VuZC4gU2tpcHBpbmcuYFxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBjb25zb2xlLndhcm4oXHJcbiAgICAgICAgICAgIGBbQW50ZEZvcm1TZXJ2aWNlXSBwYXRjaEZvcm1BcnJheTogQ2Fubm90IHVwZGF0ZSBpdGVtLCBtaXNzaW5nIHJlcXVpcmVkIHVuaXF1ZUlkRmllbGQgXCIke3VuaXF1ZUlkRmllbGR9XCIuIFNraXBwaW5nLmBcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8g5Yib5bu65pON5L2cXHJcbiAgICAgIGlmIChvcGVyYXRpb25UeXBlID09PSBcImNyZWF0ZVwiKSB7XHJcbiAgICAgICAgY29uc3QgZmlsdGVyZWREYXRhID0gdGhpcy5maWx0ZXJPcGVyYXRpb25GaWVsZHMoaXRlbURhdGEpO1xyXG4gICAgICAgIGl0ZW1zVG9BZGQucHVzaChmaWx0ZXJlZERhdGEpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICAvLyDmiafooYzliKDpmaTvvIjpnIDopoHku47lkI7lvoDliY3liKDpmaTvvIzpgb/lhY3ntKLlvJXlj5jljJbvvIlcclxuICAgIGNvbnN0IGRlbGV0ZUluZGljZXM6IG51bWJlcltdID0gW107XHJcbiAgICBpdGVtc1RvRGVsZXRlLmZvckVhY2goKGl0ZW1JZCkgPT4ge1xyXG4gICAgICBjb25zdCBmb3VuZCA9IHRoaXMuZmluZEZvcm1BcnJheUl0ZW1CeUlkKGZvcm1OYW1lLCBhcnJheU5hbWUsIGl0ZW1JZCk7XHJcbiAgICAgIGlmIChmb3VuZCkge1xyXG4gICAgICAgIGRlbGV0ZUluZGljZXMucHVzaChmb3VuZC5pbmRleCk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgZGVsZXRlSW5kaWNlc1xyXG4gICAgICAuc29ydCgoYSwgYikgPT4gYiAtIGEpXHJcbiAgICAgIC5mb3JFYWNoKChpbmRleCkgPT4ge1xyXG4gICAgICAgIGZvcm1BcnJheS5yZW1vdmVBdChpbmRleCk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgIC8vIOaJp+ihjOabtOaWsFxyXG4gICAgaXRlbXNUb1VwZGF0ZS5mb3JFYWNoKChpdGVtRGF0YSwgaXRlbUlkKSA9PiB7XHJcbiAgICAgIGNvbnN0IGZvdW5kID0gdGhpcy5maW5kRm9ybUFycmF5SXRlbUJ5SWQoZm9ybU5hbWUsIGFycmF5TmFtZSwgaXRlbUlkKTtcclxuICAgICAgaWYgKGZvdW5kKSB7XHJcbiAgICAgICAgY29uc3QgeyBbdGhpcy5JTlRFUk5BTF9JRF9GSUVMRF06IF8sIC4uLmRhdGFUb1VwZGF0ZSB9ID0gaXRlbURhdGE7XHJcbiAgICAgICAgZm91bmQuZm9ybUdyb3VwLnBhdGNoVmFsdWUoZGF0YVRvVXBkYXRlKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgLy8g5omn6KGM5re75YqgXHJcbiAgICBpdGVtc1RvQWRkLmZvckVhY2goKGl0ZW1EYXRhKSA9PiB7XHJcbiAgICAgIGNvbnN0IG5ld0l0ZW0gPSB0aGlzLmNyZWF0ZUl0ZW1Gb3JtR3JvdXAoXHJcbiAgICAgICAgaXRlbUNvbmZpZyxcclxuICAgICAgICBpdGVtRGF0YSxcclxuICAgICAgICB1bmlxdWVJZEZpZWxkXHJcbiAgICAgICk7XHJcbiAgICAgIGZvcm1BcnJheS5wdXNoKG5ld0l0ZW0pO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvLyDov4fmu6TlhoXpg6jlrZfmrrXvvIjpgJLlvZLlpITnkIblr7nosaHlkozmlbDnu4TvvIlcclxuICBwcml2YXRlIGV4Y2x1ZGVJbnRlcm5hbEZpZWxkcyh2YWx1ZTogYW55KTogYW55IHtcclxuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcclxuICAgICAgcmV0dXJuIHZhbHVlLm1hcCgoaXRlbSkgPT4gdGhpcy5leGNsdWRlSW50ZXJuYWxGaWVsZHMoaXRlbSkpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlb2YgdmFsdWUgIT09IFwib2JqZWN0XCIpIHtcclxuICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGZpbHRlcmVkOiBhbnkgPSB7fTtcclxuICAgIE9iamVjdC5lbnRyaWVzKHZhbHVlKS5mb3JFYWNoKChba2V5LCB2YWxdKSA9PiB7XHJcbiAgICAgIC8vIOi/h+a7pOS7pSBfXyDlvIDlpLTnmoTlhoXpg6jlrZfmrrXlkowgYWN0aW9uIOWtl+autVxyXG4gICAgICBpZiAoIWtleS5zdGFydHNXaXRoKFwiX19cIikgJiYga2V5ICE9PSBcImFjdGlvblwiKSB7XHJcbiAgICAgICAgZmlsdGVyZWRba2V5XSA9IHRoaXMuZXhjbHVkZUludGVybmFsRmllbGRzKHZhbCk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIGZpbHRlcmVkO1xyXG4gIH1cclxuXHJcbiAgLy8g6K6+572u5YC85Y+Y5pu06K6i6ZiFXHJcbiAgcHJpdmF0ZSBzZXR1cFZhbHVlQ2hhbmdlU3Vic2NyaXB0aW9uPFQ+KFxyXG4gICAgdGFyZ2V0OiB7IHZhbHVlQ2hhbmdlczogYW55OyB2YWx1ZTogYW55IH0sXHJcbiAgICBoYW5kbGVyOiAodmFsdWU6IFQpID0+IHZvaWQsXHJcbiAgICBvcHRpb25zPzogV2F0Y2hPcHRpb25zXHJcbiAgKTogU3Vic2NyaXB0aW9uIHtcclxuICAgIGxldCB2YWx1ZUNoYW5nZXMkID0gdGFyZ2V0LnZhbHVlQ2hhbmdlcztcclxuXHJcbiAgICBpZiAob3B0aW9ucz8uZGVib3VuY2UgIT0gbnVsbCkge1xyXG4gICAgICB2YWx1ZUNoYW5nZXMkID0gdmFsdWVDaGFuZ2VzJC5waXBlKGRlYm91bmNlVGltZShvcHRpb25zLmRlYm91bmNlKSk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKG9wdGlvbnM/LmRpc3RpbmN0VW50aWxDaGFuZ2VkICE9PSBmYWxzZSkge1xyXG4gICAgICB2YWx1ZUNoYW5nZXMkID0gdmFsdWVDaGFuZ2VzJC5waXBlKGRpc3RpbmN0VW50aWxDaGFuZ2VkKCkpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChvcHRpb25zPy5lbWl0SW5pdGlhbCkge1xyXG4gICAgICBoYW5kbGVyKHRhcmdldC52YWx1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHZhbHVlQ2hhbmdlcyQuc3Vic2NyaWJlKGhhbmRsZXIpO1xyXG4gIH1cclxufSJdfQ==