@yibozhang/pro-table 0.0.4 → 0.0.6

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.
@@ -1,59 +1,75 @@
1
1
  import { Injectable } from "@angular/core";
2
2
  import { v4 as uuidv4 } from "uuid";
3
3
  import * as i0 from "@angular/core";
4
- /**
5
- * 数组型数据收集基础服务
6
- *
7
- * 功能:
8
- * 1. 支持通过 ngModel 绑定对应行的数据源
9
- * 2. 自动为数组数据添加 isEdit 和 uid 字段
10
- * 3. 支持每个字段的自定义校验方法,返回 'success' | 'warning' | 'error'
11
- * 4. 提供公共方法支持删除、新增、编辑等操作
12
- */
4
+ /** 数组型数据收集基础服务 */
13
5
  export class ArrayFormService {
14
6
  constructor() {
15
7
  this.formStore = {};
16
8
  }
17
- /**
18
- * 初始化数组数据
19
- * 为现有数据添加 uid isEdit 字段
20
- *
21
- * @param data 原始数据数组
22
- * @param config 表单配置
23
- * @returns 初始化后的数据数组
24
- */
9
+ /** 深度克隆值 */
10
+ cloneValue(value) {
11
+ if (value === null || value === undefined) {
12
+ return value;
13
+ }
14
+ if (Array.isArray(value)) {
15
+ return value.map((item) => this.cloneValue(item));
16
+ }
17
+ if (typeof value === "object") {
18
+ const cloned = {};
19
+ for (const key of Object.keys(value)) {
20
+ cloned[key] = this.cloneValue(value[key]);
21
+ }
22
+ return cloned;
23
+ }
24
+ return value;
25
+ }
26
+ /** 比较两个值是否相等 */
27
+ isEqual(a, b) {
28
+ if (a === b)
29
+ return true;
30
+ if (a === null || b === null)
31
+ return a === b;
32
+ if (a === undefined || b === undefined)
33
+ return a === b;
34
+ if (typeof a !== typeof b)
35
+ return false;
36
+ if (Array.isArray(a) && Array.isArray(b)) {
37
+ if (a.length !== b.length)
38
+ return false;
39
+ return a.every((item, index) => this.isEqual(item, b[index]));
40
+ }
41
+ if (typeof a === "object" && typeof b === "object") {
42
+ const keysA = Object.keys(a);
43
+ const keysB = Object.keys(b);
44
+ if (keysA.length !== keysB.length)
45
+ return false;
46
+ return keysA.every((key) => this.isEqual(a[key], b[key]));
47
+ }
48
+ return false;
49
+ }
50
+ /** 创建行的初始值快照 */
51
+ createRowSnapshot(row, fields) {
52
+ const snapshot = {};
53
+ fields.forEach((field) => {
54
+ snapshot[field.name] = this.cloneValue(row[field.name]);
55
+ });
56
+ return snapshot;
57
+ }
58
+ /** 初始化数组数据,添加 uid 和 isEdit 字段 */
25
59
  initializeData(data) {
26
60
  return data.map((item) => this.enrichRow(item));
27
61
  }
28
- /**
29
- * 为单行数据添加 uid 和 isEdit 字段
30
- *
31
- * @param row 原始行数据
32
- * @returns 增强后的行数据
33
- */
62
+ /** 为单行数据添加 uid 和 isEdit 字段 */
34
63
  enrichRow(row) {
35
- return Object.assign(Object.assign({}, row), { uid: row.uid || uuidv4(), isEdit: row.isEdit !== undefined ? row.isEdit : false });
64
+ return Object.assign(Object.assign({}, row), { uid: row.uid || uuidv4(), isEdit: row.isEdit !== undefined ? row.isEdit : false, disabled: row.disabled !== undefined ? row.disabled : false });
36
65
  }
37
- /**
38
- * 新增一行数据
39
- *
40
- * @param data 数据数组引用
41
- * @param defaultValues 默认值
42
- * @returns 新增的行数据
43
- */
66
+ /** 新增一行数据 */
44
67
  addRow(data, defaultValues) {
45
- const newRow = Object.assign(Object.assign({}, defaultValues), { uid: uuidv4(), isEdit: true, isAdd: true });
68
+ const newRow = Object.assign(Object.assign({}, defaultValues), { uid: uuidv4(), isEdit: true, isAdd: true, disabled: false });
46
69
  data.push(newRow);
47
70
  return newRow;
48
71
  }
49
- /**
50
- * 校验单个字段
51
- *
52
- * @param row 行数据
53
- * @param fieldName 字段名
54
- * @param config 表单配置
55
- * @returns 校验结果
56
- */
72
+ /** 校验单个字段 */
57
73
  validateField(row, fieldName, config) {
58
74
  const fieldConfig = config.fields.find((f) => f.name === fieldName);
59
75
  if (!fieldConfig) {
@@ -64,13 +80,7 @@ export class ArrayFormService {
64
80
  }
65
81
  return "";
66
82
  }
67
- /**
68
- * 校验整行数据
69
- *
70
- * @param row 行数据
71
- * @param config 表单配置
72
- * @returns 校验结果对象,key为字段名,value为校验结果
73
- */
83
+ /** 校验整行数据 */
74
84
  validateRow(row, config) {
75
85
  const results = {};
76
86
  config.fields.forEach((fieldConfig) => {
@@ -78,13 +88,7 @@ export class ArrayFormService {
78
88
  });
79
89
  return results;
80
90
  }
81
- /**
82
- * 校验整个数组
83
- *
84
- * @param data 数据数组
85
- * @param config 表单配置
86
- * @returns 校验结果对象,key为行的uid,value为该行的校验结果
87
- */
91
+ /** 校验整个数组 */
88
92
  validateData(data, config) {
89
93
  const results = {};
90
94
  data.forEach((row) => {
@@ -92,90 +96,126 @@ export class ArrayFormService {
92
96
  });
93
97
  return results;
94
98
  }
95
- /**
96
- * 注册表单到存储
97
- * 如果表单已存在,则更新其配置
98
- *
99
- * @param formName 表单名称
100
- * @param data 数据数组
101
- * @param config 表单配置
102
- */
99
+ /** 注册表单到存储 */
103
100
  registerForm(formName, data, config) {
101
+ const initializedData = this.initializeData(data);
102
+ // 记录初始值快照
103
+ const initialSnapshot = {};
104
+ initializedData.forEach((row) => {
105
+ initialSnapshot[row.uid] = this.createRowSnapshot(row, config.fields);
106
+ });
104
107
  this.formStore[formName] = {
105
- data: this.initializeData(data),
108
+ data: initializedData,
106
109
  config,
107
110
  validationResults: {},
111
+ initialSnapshot,
112
+ editingSnapshot: {},
113
+ allTouched: false,
114
+ rowTouched: {},
108
115
  };
109
116
  // 如果配置了自动更新,立即更新一次
110
117
  this.autoUpdateArrayReference(formName);
111
118
  }
112
- /**
113
- * 从存储中获取表单
114
- *
115
- * @param formName 表单名称
116
- * @returns 表单存储项或undefined
117
- */
119
+ /** 从存储中获取表单 */
118
120
  getForm(formName) {
119
121
  return this.formStore[formName];
120
122
  }
121
- /**
122
- * 向表单添加行
123
- *
124
- * @param formName 表单名称
125
- * @param defaultValues 默认值
126
- * @returns 新增的行数据或undefined
127
- */
123
+ /** 从存储中获取表单数据 */
124
+ getFormData(formName) {
125
+ const form = this.formStore[formName];
126
+ if (!form) {
127
+ return undefined;
128
+ }
129
+ return form.data.map((item) => {
130
+ delete item.isEdit;
131
+ delete item.isAdd;
132
+ delete item.uid;
133
+ return item;
134
+ });
135
+ }
136
+ /** 向表单添加行 */
128
137
  addRowToForm(formName, defaultValues) {
129
138
  const form = this.formStore[formName];
130
139
  if (!form) {
131
140
  return undefined;
132
141
  }
133
142
  const newRow = this.addRow(form.data, defaultValues);
143
+ // 为新行记录初始值快照
144
+ form.initialSnapshot[newRow.uid] = this.createRowSnapshot(newRow, form.config.fields);
134
145
  // 自动更新外部数组引用
135
146
  this.autoUpdateArrayReference(formName);
136
147
  return newRow;
137
148
  }
138
- /**
139
- * 校验表单
140
- *
141
- * @param formName 表单名称
142
- * @returns 校验结果或undefined
143
- */
149
+ /** 校验表单,自动标记所有字段为已触碰 */
144
150
  validateForm(formName) {
145
151
  const form = this.formStore[formName];
146
152
  if (!form) {
147
- return undefined;
153
+ return true;
148
154
  }
155
+ // 标记所有字段为已触碰
156
+ form.allTouched = true;
149
157
  const results = this.validateData(form.data, form.config);
150
158
  form.validationResults = results;
151
- return results;
159
+ // 检查是否有任何错误
160
+ for (const uid of Object.keys(results)) {
161
+ for (const fieldName of Object.keys(results[uid])) {
162
+ if (results[uid][fieldName]) {
163
+ return false;
164
+ }
165
+ }
166
+ }
167
+ return true;
152
168
  }
153
- /**
154
- * 开启指定行的编辑模式
155
- *
156
- * @param row 行数据
157
- */
158
- enableEdit(row) {
169
+ /** 开启编辑模式,保存快照用于取消恢复 */
170
+ enableEdit(formName, row) {
171
+ const form = this.formStore[formName];
172
+ if (form && row.uid) {
173
+ // 保存编辑前的快照
174
+ form.editingSnapshot[row.uid] = this.createRowSnapshot(row, form.config.fields);
175
+ }
159
176
  row.isEdit = true;
160
177
  }
161
- /**
162
- * 关闭指定行的编辑模式
163
- *
164
- * @param row 行数据
165
- */
166
- disableEdit(row) {
178
+ /** 取消编辑,恢复到编辑前的数据 */
179
+ disableEdit(formName, row) {
180
+ const form = this.formStore[formName];
181
+ if (form && row.uid && form.editingSnapshot[row.uid]) {
182
+ // 恢复编辑前的数据
183
+ const snapshot = form.editingSnapshot[row.uid];
184
+ form.config.fields.forEach((field) => {
185
+ row[field.name] = this.cloneValue(snapshot[field.name]);
186
+ });
187
+ // 更新初始快照为恢复后的值,消除 touched 状态
188
+ form.initialSnapshot[row.uid] = this.cloneValue(snapshot);
189
+ // 清理编辑快照和 touched 状态
190
+ delete form.editingSnapshot[row.uid];
191
+ delete form.rowTouched[row.uid];
192
+ // 清理该行的校验结果
193
+ if (form.validationResults) {
194
+ delete form.validationResults[row.uid];
195
+ }
196
+ }
197
+ row.isEdit = false;
198
+ }
199
+ /** 确认编辑,保留修改后的数据 */
200
+ confirmEdit(formName, row) {
201
+ const form = this.formStore[formName];
202
+ if (form && row.uid) {
203
+ // 清理编辑快照(保留当前数据)
204
+ if (form.editingSnapshot[row.uid]) {
205
+ delete form.editingSnapshot[row.uid];
206
+ }
207
+ // 更新初始快照为当前值(用于后续 touched 检测)
208
+ form.initialSnapshot[row.uid] = this.createRowSnapshot(row, form.config.fields);
209
+ // 清除 touched 状态,基于新的 initialSnapshot 重新判断
210
+ delete form.rowTouched[row.uid];
211
+ }
167
212
  row.isEdit = false;
213
+ row.isAdd = false;
168
214
  }
169
- /**
170
- * 从表单中删除指定行
171
- *
172
- * @param formName 表单名称
173
- * @param row 行的uid
174
- * @returns 是否删除成功
175
- */
215
+ /** 从表单中删除指定行 */
176
216
  deleteRowFromForm(formName, row) {
177
217
  const form = this.formStore[formName];
178
- if (!form) {
218
+ if (!form || !row.uid) {
179
219
  return false;
180
220
  }
181
221
  const index = form.data.findIndex((item) => item.uid === row.uid);
@@ -183,31 +223,44 @@ export class ArrayFormService {
183
223
  return false;
184
224
  }
185
225
  form.data.splice(index, 1);
186
- if (form.validationResults && form.validationResults[row.uid]) {
226
+ // 清理该行的所有快照、touched 状态和校验结果
227
+ delete form.initialSnapshot[row.uid];
228
+ delete form.editingSnapshot[row.uid];
229
+ delete form.rowTouched[row.uid];
230
+ if (form.validationResults) {
187
231
  delete form.validationResults[row.uid];
188
232
  }
189
233
  // 自动更新外部数组引用
190
234
  this.autoUpdateArrayReference(formName);
191
235
  return true;
192
236
  }
193
- /**
194
- * 校验指定行的指定字段并返回校验结果
195
- * 实时执行校验,用于模板中的实时校验显示
196
- *
197
- * @param formName 表单名称
198
- * @param row 行数据
199
- * @param fieldName 字段名
200
- * @returns 校验结果
201
- */
237
+ /** 检测字段是否已被触碰 */
238
+ isFieldTouched(form, row, fieldName) {
239
+ var _a;
240
+ // 整个表单已 touched(整个表单提交时)
241
+ if (form.allTouched) {
242
+ return true;
243
+ }
244
+ // 当前行已 touched(单行保存时)
245
+ if (form.rowTouched[row.uid]) {
246
+ return true;
247
+ }
248
+ // 检测当前值与初始值是否不同
249
+ const initialValue = (_a = form.initialSnapshot[row.uid]) === null || _a === void 0 ? void 0 : _a[fieldName];
250
+ const currentValue = row[fieldName];
251
+ return !this.isEqual(initialValue, currentValue);
252
+ }
253
+ /** 校验指定行的指定字段,未修改时不显示校验状态 */
202
254
  validateFieldInRow(formName, row, fieldName) {
203
255
  const form = this.formStore[formName];
204
256
  if (!form) {
205
- return "success";
257
+ return "";
206
258
  }
207
259
  const fieldConfig = form.config.fields.find((f) => f.name === fieldName);
208
260
  if (!fieldConfig) {
209
- return "success";
261
+ return "";
210
262
  }
263
+ // 执行校验
211
264
  let result = "";
212
265
  if (fieldConfig.validator) {
213
266
  result = fieldConfig.validator(row[fieldName], row, fieldName);
@@ -220,20 +273,35 @@ export class ArrayFormService {
220
273
  form.validationResults[row.uid] = {};
221
274
  }
222
275
  form.validationResults[row.uid][fieldName] = result;
276
+ // 如果字段未被触碰,不显示校验状态
277
+ if (!this.isFieldTouched(form, row, fieldName)) {
278
+ return "";
279
+ }
223
280
  return result ? "error" : "success";
224
281
  }
225
- /**
226
- * 校验指定行的所有字段
227
- *
228
- * @param formName 表单名称
229
- * @param row 行数据
230
- * @returns 是否所有字段都通过校验
231
- */
282
+ /** 获取指定行指定字段的校验错误信息 */
283
+ getFieldErrorMessage(formName, row, fieldName) {
284
+ var _a, _b;
285
+ const form = this.formStore[formName];
286
+ if (!form || !row.uid) {
287
+ return "";
288
+ }
289
+ // 如果字段未被触碰,不显示错误信息
290
+ if (!this.isFieldTouched(form, row, fieldName)) {
291
+ return "";
292
+ }
293
+ return ((_b = (_a = form.validationResults) === null || _a === void 0 ? void 0 : _a[row.uid]) === null || _b === void 0 ? void 0 : _b[fieldName]) || "";
294
+ }
295
+ /** 校验指定行的所有字段 */
232
296
  validateRowAllFields(formName, row) {
233
297
  const form = this.formStore[formName];
234
- if (!form) {
298
+ if (!form || !row.uid) {
235
299
  return true;
236
300
  }
301
+ // 更新初始快照为当前值
302
+ form.initialSnapshot[row.uid] = this.createRowSnapshot(row, form.config.fields);
303
+ // 标记当前行为 touched(只影响当前行,不影响其他行)
304
+ form.rowTouched[row.uid] = true;
237
305
  let hasError = false;
238
306
  form.config.fields.forEach((fieldConfig) => {
239
307
  const result = this.validateFieldInRow(formName, row, fieldConfig.name);
@@ -243,12 +311,7 @@ export class ArrayFormService {
243
311
  });
244
312
  return !hasError;
245
313
  }
246
- /**
247
- * 自动更新外部数组引用(如果配置了)
248
- * 私有方法,在数据变化时自动调用
249
- *
250
- * @param formName 表单名称
251
- */
314
+ /** 自动更新外部数组引用 */
252
315
  autoUpdateArrayReference(formName) {
253
316
  const form = this.formStore[formName];
254
317
  if (!form || !form.config.targetObject || !form.config.arrayPropertyName) {
@@ -258,6 +321,42 @@ export class ArrayFormService {
258
321
  // 更新目标对象的数组属性为新数组引用
259
322
  form.config.targetObject[form.config.arrayPropertyName] = newArray;
260
323
  }
324
+ /** 是否有正在编辑的行 */
325
+ hasEditingRow(formName) {
326
+ const form = this.formStore[formName];
327
+ if (!form) {
328
+ return false;
329
+ }
330
+ return form.data.some((item) => item.isEdit);
331
+ }
332
+ // 销毁对应的表单
333
+ destory(names) {
334
+ names.forEach((name) => {
335
+ if (this.formStore[name]) {
336
+ // 清理表单数据
337
+ delete this.formStore[name];
338
+ }
339
+ });
340
+ }
341
+ // 重置表单数组
342
+ resetFormArray(name) {
343
+ const form = this.formStore[name];
344
+ if (!form) {
345
+ return;
346
+ }
347
+ // 1. 清空数据数组
348
+ form.data = [];
349
+ // 2. 清理所有快照
350
+ form.initialSnapshot = {};
351
+ form.editingSnapshot = {};
352
+ // 3. 清理校验结果
353
+ form.validationResults = {};
354
+ // 4. 重置 touched 状态
355
+ form.allTouched = false;
356
+ form.rowTouched = {};
357
+ // 5. 如果配置了自动更新,更新外部数组引用
358
+ this.autoUpdateArrayReference(name);
359
+ }
261
360
  }
262
361
  ArrayFormService.ɵprov = i0.ɵɵdefineInjectable({ factory: function ArrayFormService_Factory() { return new ArrayFormService(); }, token: ArrayFormService, providedIn: "root" });
263
362
  ArrayFormService.decorators = [
@@ -266,4 +365,4 @@ ArrayFormService.decorators = [
266
365
  },] }
267
366
  ];
268
367
  ArrayFormService.ctorParameters = () => [];
269
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJyYXktZm9ybS5qcyIsInNvdXJjZVJvb3QiOiJEOi9wcm9qZWN0cy92cHMtZnJvbnQvRnJvbnQvRGFzUE1TV2ViL2xpYi9wcm8tdGFibGUvc3JjLyIsInNvdXJjZXMiOlsibGliL3BhZ2UtcHVibGljL2FycmF5LWZvcm0udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsRUFBRSxJQUFJLE1BQU0sRUFBRSxNQUFNLE1BQU0sQ0FBQzs7QUE2RHBDOzs7Ozs7OztHQVFHO0FBSUgsTUFBTSxPQUFPLGdCQUFnQjtJQUczQjtRQUZRLGNBQVMsR0FBbUIsRUFBRSxDQUFDO0lBRXhCLENBQUM7SUFFaEI7Ozs7Ozs7T0FPRztJQUNLLGNBQWMsQ0FBQyxJQUFXO1FBQ2hDLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFFRDs7Ozs7T0FLRztJQUNLLFNBQVMsQ0FBQyxHQUFRO1FBQ3hCLHVDQUNLLEdBQUcsS0FDTixHQUFHLEVBQUUsR0FBRyxDQUFDLEdBQUcsSUFBSSxNQUFNLEVBQUUsRUFDeEIsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQ3JEO0lBQ0osQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNLLE1BQU0sQ0FDWixJQUFvQixFQUNwQixhQUFtQztRQUVuQyxNQUFNLE1BQU0sbUNBQ1AsYUFBYSxLQUNoQixHQUFHLEVBQUUsTUFBTSxFQUFFLEVBQ2IsTUFBTSxFQUFFLElBQUksRUFDWixLQUFLLEVBQUUsSUFBSSxHQUNaLENBQUM7UUFDRixJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2xCLE9BQU8s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QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xyXG5pbXBvcnQgeyB2NCBhcyB1dWlkdjQgfSBmcm9tIFwidXVpZFwiO1xyXG5cclxuLyoqXHJcbiAqIOWtl+auteagoemqjOe7k+aenOexu+Wei1xyXG4gKi9cclxuZXhwb3J0IHR5cGUgVmFsaWRhdGlvblJlc3VsdCA9IHN0cmluZztcclxuXHJcbi8qKlxyXG4gKiDlrZfmrrXmoKHpqozmlrnms5XnsbvlnotcclxuICovXHJcbmV4cG9ydCB0eXBlIEZpZWxkVmFsaWRhdG9yID0gKFxyXG4gIHZhbHVlOiBhbnksXHJcbiAgcm93OiBBcnJheUZvcm1Sb3csXHJcbiAgZmllbGROYW1lOiBzdHJpbmdcclxuKSA9PiBWYWxpZGF0aW9uUmVzdWx0O1xyXG5cclxuLyoqXHJcbiAqIOWtl+autemFjee9ruaOpeWPo1xyXG4gKi9cclxuZXhwb3J0IGludGVyZmFjZSBGaWVsZENvbmZpZyB7XHJcbiAgbmFtZTogc3RyaW5nO1xyXG4gIHZhbGlkYXRvcj86IEZpZWxkVmFsaWRhdG9yO1xyXG59XHJcblxyXG4vKipcclxuICog5pWw57uE6KGo5Y2V6KGM5pWw5o2u5o6l5Y+jXHJcbiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIEFycmF5Rm9ybVJvdyB7XHJcbiAgdWlkOiBzdHJpbmc7XHJcbiAgaXNFZGl0OiBib29sZWFuO1xyXG4gIGlzQWRkPzogYm9vbGVhbjtcclxuICBba2V5OiBzdHJpbmddOiBhbnk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiDmlbDnu4TooajljZXphY3nva7mjqXlj6NcclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgQXJyYXlGb3JtQ29uZmlnIHtcclxuICBmaWVsZHM6IEZpZWxkQ29uZmlnW107XHJcbiAgZGVmYXVsdFZhbHVlcz86IFJlY29yZDxzdHJpbmcsIGFueT47XHJcbiAgLy8g6Ieq5Yqo5pu05paw55uu5qCH5a+56LGh5ZKM5bGe5oCn5ZCN77yM55So5LqO6Kem5Y+RIEFuZ3VsYXIg5Y+Y5YyW5qOA5rWLXHJcbiAgdGFyZ2V0T2JqZWN0PzogUmVjb3JkPHN0cmluZywgYW55PjtcclxuICBhcnJheVByb3BlcnR5TmFtZT86IHN0cmluZztcclxufVxyXG5cclxuLyoqXHJcbiAqIOihqOWNleWtmOWCqOmhueaOpeWPo1xyXG4gKi9cclxuZXhwb3J0IGludGVyZmFjZSBBcnJheUZvcm1TdG9yZUl0ZW0ge1xyXG4gIGRhdGE6IEFycmF5Rm9ybVJvd1tdO1xyXG4gIGNvbmZpZzogQXJyYXlGb3JtQ29uZmlnO1xyXG4gIHZhbGlkYXRpb25SZXN1bHRzPzogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgVmFsaWRhdGlvblJlc3VsdD4+O1xyXG59XHJcblxyXG4vKipcclxuICog6KGo5Y2V5a2Y5YKo5o6l5Y+jXHJcbiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIEFycmF5Rm9ybVN0b3JlIHtcclxuICBbZm9ybU5hbWU6IHN0cmluZ106IEFycmF5Rm9ybVN0b3JlSXRlbTtcclxufVxyXG5cclxuLyoqXHJcbiAqIOaVsOe7hOWei+aVsOaNruaUtumbhuWfuuehgOacjeWKoVxyXG4gKlxyXG4gKiDlip/og73vvJpcclxuICogMS4g5pSv5oyB6YCa6L+HIG5nTW9kZWwg57uR5a6a5a+55bqU6KGM55qE5pWw5o2u5rqQXHJcbiAqIDIuIOiHquWKqOS4uuaVsOe7hOaVsOaNrua3u+WKoCBpc0VkaXQg5ZKMIHVpZCDlrZfmrrVcclxuICogMy4g5pSv5oyB5q+P5Liq5a2X5q6155qE6Ieq5a6a5LmJ5qCh6aqM5pa55rOV77yM6L+U5ZueICdzdWNjZXNzJyB8ICd3YXJuaW5nJyB8ICdlcnJvcidcclxuICogNC4g5o+Q5L6b5YWs5YWx5pa55rOV5pSv5oyB5Yig6Zmk44CB5paw5aKe44CB57yW6L6R562J5pON5L2cXHJcbiAqL1xyXG5ASW5qZWN0YWJsZSh7XHJcbiAgcHJvdmlkZWRJbjogXCJyb290XCIsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBBcnJheUZvcm1TZXJ2aWNlIHtcclxuICBwcml2YXRlIGZvcm1TdG9yZTogQXJyYXlGb3JtU3RvcmUgPSB7fTtcclxuXHJcbiAgY29uc3RydWN0b3IoKSB7fVxyXG5cclxuICAvKipcclxuICAgKiDliJ3lp4vljJbmlbDnu4TmlbDmja5cclxuICAgKiDkuLrnjrDmnInmlbDmja7mt7vliqAgdWlkIOWSjCBpc0VkaXQg5a2X5q61XHJcbiAgICpcclxuICAgKiBAcGFyYW0gZGF0YSDljp/lp4vmlbDmja7mlbDnu4RcclxuICAgKiBAcGFyYW0gY29uZmlnIOihqOWNlemFjee9rlxyXG4gICAqIEByZXR1cm5zIOWIneWni+WMluWQjueahOaVsOaNruaVsOe7hFxyXG4gICAqL1xyXG4gIHByaXZhdGUgaW5pdGlhbGl6ZURhdGEoZGF0YTogYW55W10pOiBBcnJheUZvcm1Sb3dbXSB7XHJcbiAgICByZXR1cm4gZGF0YS5tYXAoKGl0ZW0pID0+IHRoaXMuZW5yaWNoUm93KGl0ZW0pKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIOS4uuWNleihjOaVsOaNrua3u+WKoCB1aWQg5ZKMIGlzRWRpdCDlrZfmrrVcclxuICAgKlxyXG4gICAqIEBwYXJhbSByb3cg5Y6f5aeL6KGM5pWw5o2uXHJcbiAgICogQHJldHVybnMg5aKe5by65ZCO55qE6KGM5pWw5o2uXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBlbnJpY2hSb3cocm93OiBhbnkpOiBBcnJheUZvcm1Sb3cge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgLi4ucm93LFxyXG4gICAgICB1aWQ6IHJvdy51aWQgfHwgdXVpZHY0KCksXHJcbiAgICAgIGlzRWRpdDogcm93LmlzRWRpdCAhPT0gdW5kZWZpbmVkID8gcm93LmlzRWRpdCA6IGZhbHNlLFxyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIOaWsOWinuS4gOihjOaVsOaNrlxyXG4gICAqXHJcbiAgICogQHBhcmFtIGRhdGEg5pWw5o2u5pWw57uE5byV55SoXHJcbiAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZXMg6buY6K6k5YC8XHJcbiAgICogQHJldHVybnMg5paw5aKe55qE6KGM5pWw5o2uXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBhZGRSb3coXHJcbiAgICBkYXRhOiBBcnJheUZvcm1Sb3dbXSxcclxuICAgIGRlZmF1bHRWYWx1ZXM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+XHJcbiAgKTogQXJyYXlGb3JtUm93IHtcclxuICAgIGNvbnN0IG5ld1JvdzogQXJyYXlGb3JtUm93ID0ge1xyXG4gICAgICAuLi5kZWZhdWx0VmFsdWVzLFxyXG4gICAgICB1aWQ6IHV1aWR2NCgpLFxyXG4gICAgICBpc0VkaXQ6IHRydWUsXHJcbiAgICAgIGlzQWRkOiB0cnVlLFxyXG4gICAgfTtcclxuICAgIGRhdGEucHVzaChuZXdSb3cpO1xyXG4gICAgcmV0dXJuIG5ld1JvdztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIOagoemqjOWNleS4quWtl+autVxyXG4gICAqXHJcbiAgICogQHBhcmFtIHJvdyDooYzmlbDmja5cclxuICAgKiBAcGFyYW0gZmllbGROYW1lIOWtl+auteWQjVxyXG4gICAqIEBwYXJhbSBjb25maWcg6KGo5Y2V6YWN572uXHJcbiAgICogQHJldHVybnMg5qCh6aqM57uT5p6cXHJcbiAgICovXHJcbiAgcHJpdmF0ZSB2YWxpZGF0ZUZpZWxkKFxyXG4gICAgcm93OiBBcnJheUZvcm1Sb3csXHJcbiAgICBmaWVsZE5hbWU6IHN0cmluZyxcclxuICAgIGNvbmZpZzogQXJyYXlGb3JtQ29uZmlnXHJcbiAgKTogVmFsaWRhdGlvblJlc3VsdCB7XHJcbiAgICBjb25zdCBmaWVsZENvbmZpZyA9IGNvbmZpZy5maWVsZHMuZmluZCgoZikgPT4gZi5uYW1lID09PSBmaWVsZE5hbWUpO1xyXG5cclxuICAgIGlmICghZmllbGRDb25maWcpIHtcclxuICAgICAgcmV0dXJuIFwiXCI7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGZpZWxkQ29uZmlnLnZhbGlkYXRvcikge1xyXG4gICAgICByZXR1cm4gZmllbGRDb25maWcudmFsaWRhdG9yKHJvd1tmaWVsZE5hbWVdLCByb3csIGZpZWxkTmFtZSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIFwiXCI7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiDmoKHpqozmlbTooYzmlbDmja5cclxuICAgKlxyXG4gICAqIEBwYXJhbSByb3cg6KGM5pWw5o2uXHJcbiAgICogQHBhcmFtIGNvbmZpZyDooajljZXphY3nva5cclxuICAgKiBAcmV0dXJucyDmoKHpqoznu5Pmnpzlr7nosaHvvIxrZXnkuLrlrZfmrrXlkI3vvIx2YWx1ZeS4uuagoemqjOe7k+aenFxyXG4gICAqL1xyXG4gIHByaXZhdGUgdmFsaWRhdGVSb3coXHJcbiAgICByb3c6IEFycmF5Rm9ybVJvdyxcclxuICAgIGNvbmZpZzogQXJyYXlGb3JtQ29uZmlnXHJcbiAgKTogUmVjb3JkPHN0cmluZywgVmFsaWRhdGlvblJlc3VsdD4ge1xyXG4gICAgY29uc3QgcmVzdWx0czogUmVjb3JkPHN0cmluZywgVmFsaWRhdGlvblJlc3VsdD4gPSB7fTtcclxuXHJcbiAgICBjb25maWcuZmllbGRzLmZvckVhY2goKGZpZWxkQ29uZmlnKSA9PiB7XHJcbiAgICAgIHJlc3VsdHNbZmllbGRDb25maWcubmFtZV0gPSB0aGlzLnZhbGlkYXRlRmllbGQoXHJcbiAgICAgICAgcm93LFxyXG4gICAgICAgIGZpZWxkQ29uZmlnLm5hbWUsXHJcbiAgICAgICAgY29uZmlnXHJcbiAgICAgICk7XHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4gcmVzdWx0cztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIOagoemqjOaVtOS4quaVsOe7hFxyXG4gICAqXHJcbiAgICogQHBhcmFtIGRhdGEg5pWw5o2u5pWw57uEXHJcbiAgICogQHBhcmFtIGNvbmZpZyDooajljZXphY3nva5cclxuICAgKiBAcmV0dXJucyDmoKHpqoznu5Pmnpzlr7nosaHvvIxrZXnkuLrooYznmoR1aWTvvIx2YWx1ZeS4uuivpeihjOeahOagoemqjOe7k+aenFxyXG4gICAqL1xyXG4gIHByaXZhdGUgdmFsaWRhdGVEYXRhKFxyXG4gICAgZGF0YTogQXJyYXlGb3JtUm93W10sXHJcbiAgICBjb25maWc6IEFycmF5Rm9ybUNvbmZpZ1xyXG4gICk6IFJlY29yZDxzdHJpbmcsIFJlY29yZDxzdHJpbmcsIFZhbGlkYXRpb25SZXN1bHQ+PiB7XHJcbiAgICBjb25zdCByZXN1bHRzOiBSZWNvcmQ8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCBWYWxpZGF0aW9uUmVzdWx0Pj4gPSB7fTtcclxuXHJcbiAgICBkYXRhLmZvckVhY2goKHJvdykgPT4ge1xyXG4gICAgICByZXN1bHRzW3Jvdy51aWRdID0gdGhpcy52YWxpZGF0ZVJvdyhyb3csIGNvbmZpZyk7XHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4gcmVzdWx0cztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIOazqOWGjOihqOWNleWIsOWtmOWCqFxyXG4gICAqIOWmguaenOihqOWNleW3suWtmOWcqO+8jOWImeabtOaWsOWFtumFjee9rlxyXG4gICAqXHJcbiAgICogQHBhcmFtIGZvcm1OYW1lIOihqOWNleWQjeensFxyXG4gICAqIEBwYXJhbSBkYXRhIOaVsOaNruaVsOe7hFxyXG4gICAqIEBwYXJhbSBjb25maWcg6KGo5Y2V6YWN572uXHJcbiAgICovXHJcbiAgcmVnaXN0ZXJGb3JtKFxyXG4gICAgZm9ybU5hbWU6IHN0cmluZyxcclxuICAgIGRhdGE6IEFycmF5Rm9ybVJvd1tdLFxyXG4gICAgY29uZmlnOiBBcnJheUZvcm1Db25maWdcclxuICApOiB2b2lkIHtcclxuICAgIHRoaXMuZm9ybVN0b3JlW2Zvcm1OYW1lXSA9IHtcclxuICAgICAgZGF0YTogdGhpcy5pbml0aWFsaXplRGF0YShkYXRhKSxcclxuICAgICAgY29uZmlnLFxyXG4gICAgICB2YWxpZGF0aW9uUmVzdWx0czoge30sXHJcbiAgICB9O1xyXG4gICAgLy8g5aaC5p6c6YWN572u5LqG6Ieq5Yqo5pu05paw77yM56uL5Y2z5pu05paw5LiA5qyhXHJcbiAgICB0aGlzLmF1dG9VcGRhdGVBcnJheVJlZmVyZW5jZShmb3JtTmFtZSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiDku47lrZjlgqjkuK3ojrflj5booajljZVcclxuICAgKlxyXG4gICAqIEBwYXJhbSBmb3JtTmFtZSDooajljZXlkI3np7BcclxuICAgKiBAcmV0dXJucyDooajljZXlrZjlgqjpobnmiJZ1bmRlZmluZWRcclxuICAgKi9cclxuICBnZXRGb3JtKGZvcm1OYW1lOiBzdHJpbmcpOiBBcnJheUZvcm1TdG9yZUl0ZW0gfCB1bmRlZmluZWQge1xyXG4gICAgcmV0dXJuIHRoaXMuZm9ybVN0b3JlW2Zvcm1OYW1lXTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIOWQkeihqOWNlea3u+WKoOihjFxyXG4gICAqXHJcbiAgICogQHBhcmFtIGZvcm1OYW1lIOihqOWNleWQjeensFxyXG4gICAqIEBwYXJhbSBkZWZhdWx0VmFsdWVzIOm7mOiupOWAvFxyXG4gICAqIEByZXR1cm5zIOaWsOWinueahOihjOaVsOaNruaIlnVuZGVmaW5lZFxyXG4gICAqL1xyXG4gIGFkZFJvd1RvRm9ybShcclxuICAgIGZvcm1OYW1lOiBzdHJpbmcsXHJcbiAgICBkZWZhdWx0VmFsdWVzPzogUmVjb3JkPHN0cmluZywgYW55PlxyXG4gICk6IEFycmF5Rm9ybVJvdyB8IHVuZGVmaW5lZCB7XHJcbiAgICBjb25zdCBmb3JtID0gdGhpcy5mb3JtU3RvcmVbZm9ybU5hbWVdO1xyXG4gICAgaWYgKCFmb3JtKSB7XHJcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgICB9XHJcbiAgICBjb25zdCBuZXdSb3cgPSB0aGlzLmFkZFJvdyhmb3JtLmRhdGEsIGRlZmF1bHRWYWx1ZXMpO1xyXG4gICAgLy8g6Ieq5Yqo5pu05paw5aSW6YOo5pWw57uE5byV55SoXHJcbiAgICB0aGlzLmF1dG9VcGRhdGVBcnJheVJlZmVyZW5jZShmb3JtTmFtZSk7XHJcbiAgICByZXR1cm4gbmV3Um93O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICog5qCh6aqM6KGo5Y2VXHJcbiAgICpcclxuICAgKiBAcGFyYW0gZm9ybU5hbWUg6KGo5Y2V5ZCN56ewXHJcbiAgICogQHJldHVybnMg5qCh6aqM57uT5p6c5oiWdW5kZWZpbmVkXHJcbiAgICovXHJcbiAgdmFsaWRhdGVGb3JtKFxyXG4gICAgZm9ybU5hbWU6IHN0cmluZ1xyXG4gICk6IFJlY29yZDxzdHJpbmcsIFJlY29yZDxzdHJpbmcsIFZhbGlkYXRpb25SZXN1bHQ+PiB8IHVuZGVmaW5lZCB7XHJcbiAgICBjb25zdCBmb3JtID0gdGhpcy5mb3JtU3RvcmVbZm9ybU5hbWVdO1xyXG4gICAgaWYgKCFmb3JtKSB7XHJcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgICB9XHJcbiAgICBjb25zdCByZXN1bHRzID0gdGhpcy52YWxpZGF0ZURhdGEoZm9ybS5kYXRhLCBmb3JtLmNvbmZpZyk7XHJcbiAgICBmb3JtLnZhbGlkYXRpb25SZXN1bHRzID0gcmVzdWx0cztcclxuICAgIHJldHVybiByZXN1bHRzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICog5byA5ZCv5oyH5a6a6KGM55qE57yW6L6R5qih5byPXHJcbiAgICpcclxuICAgKiBAcGFyYW0gcm93IOihjOaVsOaNrlxyXG4gICAqL1xyXG4gIGVuYWJsZUVkaXQocm93OiBBcnJheUZvcm1Sb3cpOiB2b2lkIHtcclxuICAgIHJvdy5pc0VkaXQgPSB0cnVlO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICog5YWz6Zet5oyH5a6a6KGM55qE57yW6L6R5qih5byPXHJcbiAgICpcclxuICAgKiBAcGFyYW0gcm93IOihjOaVsOaNrlxyXG4gICAqL1xyXG4gIGRpc2FibGVFZGl0KHJvdzogQXJyYXlGb3JtUm93KTogdm9pZCB7XHJcbiAgICByb3cuaXNFZGl0ID0gZmFsc2U7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiDku47ooajljZXkuK3liKDpmaTmjIflrprooYxcclxuICAgKlxyXG4gICAqIEBwYXJhbSBmb3JtTmFtZSDooajljZXlkI3np7BcclxuICAgKiBAcGFyYW0gcm93IOihjOeahHVpZFxyXG4gICAqIEByZXR1cm5zIOaYr+WQpuWIoOmZpOaIkOWKn1xyXG4gICAqL1xyXG4gIGRlbGV0ZVJvd0Zyb21Gb3JtKGZvcm1OYW1lOiBzdHJpbmcsIHJvdzogQXJyYXlGb3JtUm93KTogYm9vbGVhbiB7XHJcbiAgICBjb25zdCBmb3JtID0gdGhpcy5mb3JtU3RvcmVbZm9ybU5hbWVdO1xyXG4gICAgaWYgKCFmb3JtKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIGNvbnN0IGluZGV4ID0gZm9ybS5kYXRhLmZpbmRJbmRleCgoaXRlbSkgPT4gaXRlbS51aWQgPT09IHJvdy51aWQpO1xyXG4gICAgaWYgKGluZGV4ID09PSAtMSkge1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICBmb3JtLmRhdGEuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgIGlmIChmb3JtLnZhbGlkYXRpb25SZXN1bHRzICYmIGZvcm0udmFsaWRhdGlvblJlc3VsdHNbcm93LnVpZF0pIHtcclxuICAgICAgZGVsZXRlIGZvcm0udmFsaWRhdGlvblJlc3VsdHNbcm93LnVpZF07XHJcbiAgICB9XHJcbiAgICAvLyDoh6rliqjmm7TmlrDlpJbpg6jmlbDnu4TlvJXnlKhcclxuICAgIHRoaXMuYXV0b1VwZGF0ZUFycmF5UmVmZXJlbmNlKGZvcm1OYW1lKTtcclxuICAgIHJldHVybiB0cnVlO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICog5qCh6aqM5oyH5a6a6KGM55qE5oyH5a6a5a2X5q615bm26L+U5Zue5qCh6aqM57uT5p6cXHJcbiAgICog5a6e5pe25omn6KGM5qCh6aqM77yM55So5LqO5qih5p2/5Lit55qE5a6e5pe25qCh6aqM5pi+56S6XHJcbiAgICpcclxuICAgKiBAcGFyYW0gZm9ybU5hbWUg6KGo5Y2V5ZCN56ewXHJcbiAgICogQHBhcmFtIHJvdyDooYzmlbDmja5cclxuICAgKiBAcGFyYW0gZmllbGROYW1lIOWtl+auteWQjVxyXG4gICAqIEByZXR1cm5zIOagoemqjOe7k+aenFxyXG4gICAqL1xyXG4gIHZhbGlkYXRlRmllbGRJblJvdyhcclxuICAgIGZvcm1OYW1lOiBzdHJpbmcsXHJcbiAgICByb3c6IEFycmF5Rm9ybVJvdyxcclxuICAgIGZpZWxkTmFtZTogc3RyaW5nXHJcbiAgKTogXCJzdWNjZXNzXCIgfCBcImVycm9yXCIge1xyXG4gICAgY29uc3QgZm9ybSA9IHRoaXMuZm9ybVN0b3JlW2Zvcm1OYW1lXTtcclxuICAgIGlmICghZm9ybSkge1xyXG4gICAgICByZXR1cm4gXCJzdWNjZXNzXCI7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgZmllbGRDb25maWcgPSBmb3JtLmNvbmZpZy5maWVsZHMuZmluZCgoZikgPT4gZi5uYW1lID09PSBmaWVsZE5hbWUpO1xyXG4gICAgaWYgKCFmaWVsZENvbmZpZykge1xyXG4gICAgICByZXR1cm4gXCJzdWNjZXNzXCI7XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IHJlc3VsdDogVmFsaWRhdGlvblJlc3VsdCA9IFwiXCI7XHJcbiAgICBpZiAoZmllbGRDb25maWcudmFsaWRhdG9yKSB7XHJcbiAgICAgIHJlc3VsdCA9IGZpZWxkQ29uZmlnLnZhbGlkYXRvcihyb3dbZmllbGROYW1lXSwgcm93LCBmaWVsZE5hbWUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIOabtOaWsOagoemqjOe7k+aenOWtmOWCqFxyXG4gICAgaWYgKCFmb3JtLnZhbGlkYXRpb25SZXN1bHRzKSB7XHJcbiAgICAgIGZvcm0udmFsaWRhdGlvblJlc3VsdHMgPSB7fTtcclxuICAgIH1cclxuICAgIGlmICghZm9ybS52YWxpZGF0aW9uUmVzdWx0c1tyb3cudWlkXSkge1xyXG4gICAgICBmb3JtLnZhbGlkYXRpb25SZXN1bHRzW3Jvdy51aWRdID0ge307XHJcbiAgICB9XHJcbiAgICBmb3JtLnZhbGlkYXRpb25SZXN1bHRzW3Jvdy51aWRdW2ZpZWxkTmFtZV0gPSByZXN1bHQ7XHJcblxyXG4gICAgcmV0dXJuIHJlc3VsdCA/IFwiZXJyb3JcIiA6IFwic3VjY2Vzc1wiO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICog5qCh6aqM5oyH5a6a6KGM55qE5omA5pyJ5a2X5q61XHJcbiAgICpcclxuICAgKiBAcGFyYW0gZm9ybU5hbWUg6KGo5Y2V5ZCN56ewXHJcbiAgICogQHBhcmFtIHJvdyDooYzmlbDmja5cclxuICAgKiBAcmV0dXJucyDmmK/lkKbmiYDmnInlrZfmrrXpg73pgJrov4fmoKHpqoxcclxuICAgKi9cclxuICB2YWxpZGF0ZVJvd0FsbEZpZWxkcyhmb3JtTmFtZTogc3RyaW5nLCByb3c6IEFycmF5Rm9ybVJvdyk6IGJvb2xlYW4ge1xyXG4gICAgY29uc3QgZm9ybSA9IHRoaXMuZm9ybVN0b3JlW2Zvcm1OYW1lXTtcclxuICAgIGlmICghZm9ybSkge1xyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICBsZXQgaGFzRXJyb3IgPSBmYWxzZTtcclxuXHJcbiAgICBmb3JtLmNvbmZpZy5maWVsZHMuZm9yRWFjaCgoZmllbGRDb25maWcpID0+IHtcclxuICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy52YWxpZGF0ZUZpZWxkSW5Sb3coZm9ybU5hbWUsIHJvdywgZmllbGRDb25maWcubmFtZSk7XHJcbiAgICAgIGlmIChyZXN1bHQgPT09IFwiZXJyb3JcIikge1xyXG4gICAgICAgIGhhc0Vycm9yID0gdHJ1ZTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuICFoYXNFcnJvcjtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIOiHquWKqOabtOaWsOWklumDqOaVsOe7hOW8leeUqO+8iOWmguaenOmFjee9ruS6hu+8iVxyXG4gICAqIOengeacieaWueazle+8jOWcqOaVsOaNruWPmOWMluaXtuiHquWKqOiwg+eUqFxyXG4gICAqXHJcbiAgICogQHBhcmFtIGZvcm1OYW1lIOihqOWNleWQjeensFxyXG4gICAqL1xyXG4gIHByaXZhdGUgYXV0b1VwZGF0ZUFycmF5UmVmZXJlbmNlKGZvcm1OYW1lOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIGNvbnN0IGZvcm0gPSB0aGlzLmZvcm1TdG9yZVtmb3JtTmFtZV07XHJcbiAgICBpZiAoIWZvcm0gfHwgIWZvcm0uY29uZmlnLnRhcmdldE9iamVjdCB8fCAhZm9ybS5jb25maWcuYXJyYXlQcm9wZXJ0eU5hbWUpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgY29uc3QgbmV3QXJyYXkgPSBmb3JtLmRhdGEgPyBbLi4uZm9ybS5kYXRhXSA6IFtdO1xyXG4gICAgLy8g5pu05paw55uu5qCH5a+56LGh55qE5pWw57uE5bGe5oCn5Li65paw5pWw57uE5byV55SoXHJcbiAgICAoZm9ybS5jb25maWcudGFyZ2V0T2JqZWN0IGFzIGFueSlbZm9ybS5jb25maWcuYXJyYXlQcm9wZXJ0eU5hbWVdID0gbmV3QXJyYXk7XHJcbiAgfVxyXG59XHJcbiJdfQ==
368
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJyYXktZm9ybS5qcyIsInNvdXJjZVJvb3QiOiJEOi9wcm9qZWN0cy92cHMtZnJvbnQvRnJvbnQvRGFzUE1TV2ViL2xpYi9wcm8tdGFibGUvc3JjLyIsInNvdXJjZXMiOlsibGliL3BhZ2UtcHVibGljL2FycmF5LWZvcm0udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsRUFBRSxJQUFJLE1BQU0sRUFBRSxNQUFNLE1BQU0sQ0FBQzs7QUF3RHBDLGtCQUFrQjtBQUlsQixNQUFNLE9BQU8sZ0JBQWdCO0lBRzNCO1FBRlEsY0FBUyxHQUFtQixFQUFFLENBQUM7SUFFeEIsQ0FBQztJQUVoQixZQUFZO0lBQ0osVUFBVSxDQUFDLEtBQVU7UUFDM0IsSUFBSSxLQUFLLEtBQUssSUFBSSxJQUFJLEtBQUssS0FBSyxTQUFTLEVBQUU7WUFDekMsT0FBTyxLQUFLLENBQUM7U0FDZDtRQUNELElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUN4QixPQUFPLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztTQUNuRDtRQUNELElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFO1lBQzdCLE1BQU0sTUFBTSxHQUF3QixFQUFFLENBQUM7WUFDdkMsS0FBSyxNQUFNLEdBQUcsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFO2dCQUNwQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQzthQUMzQztZQUNELE9BQU8sTUFBTSxDQUFDO1NBQ2Y7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRCxnQkFBZ0I7SUFDUixPQUFPLENBQUMs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QUFDLENBQUM7UUFDbEMsSUFBSSxDQUFDLElBQUksRUFBRTtZQUNULE9BQU87U0FDUjtRQUVELFlBQVk7UUFDWixJQUFJLENBQUMsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUVmLFlBQVk7UUFDWixJQUFJLENBQUMsZUFBZSxHQUFHLEVBQUUsQ0FBQztRQUMxQixJQUFJLENBQUMsZUFBZSxHQUFHLEVBQUUsQ0FBQztRQUUxQixZQUFZO1FBQ1osSUFBSSxDQUFDLGlCQUFpQixHQUFHLEVBQUUsQ0FBQztRQUU1QixtQkFBbUI7UUFDbkIsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7UUFDeEIsSUFBSSxDQUFDLFVBQVUsR0FBRyxFQUFFLENBQUM7UUFFckIsd0JBQXdCO1FBQ3hCLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN0QyxDQUFDOzs7O1lBcGRGLFVBQVUsU0FBQztnQkFDVixVQUFVLEVBQUUsTUFBTTthQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xyXG5pbXBvcnQgeyB2NCBhcyB1dWlkdjQgfSBmcm9tIFwidXVpZFwiO1xyXG5cclxuLyoqIOWtl+auteagoemqjOe7k+aenOexu+WeiyAqL1xyXG5leHBvcnQgdHlwZSBWYWxpZGF0aW9uUmVzdWx0ID0gc3RyaW5nO1xyXG5cclxuLyoqIOWtl+auteagoemqjOaWueazleexu+WeiyAqL1xyXG5leHBvcnQgdHlwZSBGaWVsZFZhbGlkYXRvciA9IChcclxuICB2YWx1ZTogYW55LFxyXG4gIHJvdzogQXJyYXlGb3JtUm93LFxyXG4gIGZpZWxkTmFtZTogc3RyaW5nXHJcbikgPT4gVmFsaWRhdGlvblJlc3VsdDtcclxuXHJcbi8qKiDlrZfmrrXphY3nva7mjqXlj6MgKi9cclxuZXhwb3J0IGludGVyZmFjZSBGaWVsZENvbmZpZyB7XHJcbiAgbmFtZTogc3RyaW5nO1xyXG4gIHZhbGlkYXRvcj86IEZpZWxkVmFsaWRhdG9yO1xyXG59XHJcblxyXG4vKiog5pWw57uE6KGo5Y2V6KGM5pWw5o2u5o6l5Y+jICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgQXJyYXlGb3JtUm93IHtcclxuICB1aWQ/OiBzdHJpbmc7XHJcbiAgaXNFZGl0OiBib29sZWFuO1xyXG4gIGlzQWRkPzogYm9vbGVhbjtcclxuICBkaXNhYmxlZD86IGJvb2xlYW47XHJcbiAgW2tleTogc3RyaW5nXTogYW55O1xyXG59XHJcblxyXG4vKiog5pWw57uE6KGo5Y2V6YWN572u5o6l5Y+jICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgQXJyYXlGb3JtQ29uZmlnIHtcclxuICBmaWVsZHM6IEZpZWxkQ29uZmlnW107XHJcbiAgZGVmYXVsdFZhbHVlcz86IFJlY29yZDxzdHJpbmcsIGFueT47XHJcbiAgLy8g6Ieq5Yqo5pu05paw55uu5qCH5a+56LGh5ZKM5bGe5oCn5ZCN77yM55So5LqO6Kem5Y+RIEFuZ3VsYXIg5Y+Y5YyW5qOA5rWLXHJcbiAgdGFyZ2V0T2JqZWN0PzogUmVjb3JkPHN0cmluZywgYW55PjtcclxuICBhcnJheVByb3BlcnR5TmFtZT86IHN0cmluZztcclxufVxyXG5cclxuLyoqIOihqOWNleWtmOWCqOmhueaOpeWPoyAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIEFycmF5Rm9ybVN0b3JlSXRlbSB7XHJcbiAgZGF0YTogQXJyYXlGb3JtUm93W107XHJcbiAgY29uZmlnOiBBcnJheUZvcm1Db25maWc7XHJcbiAgdmFsaWRhdGlvblJlc3VsdHM/OiBSZWNvcmQ8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCBWYWxpZGF0aW9uUmVzdWx0Pj47XHJcbiAgLyoqIOWIneWni+WAvOW/q+eFp++8jOeUqOS6juiHquWKqOajgOa1i+Wtl+auteaYr+WQpuiiq+S/ruaUuSAqL1xyXG4gIGluaXRpYWxTbmFwc2hvdDogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgYW55Pj47XHJcbiAgLyoqIOe8lui+keaXtuW/q+eFp++8jOeUqOS6juWPlua2iOe8lui+keaXtuaBouWkjeaVsOaNriAqL1xyXG4gIGVkaXRpbmdTbmFwc2hvdDogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgYW55Pj47XHJcbiAgLyoqIOaYr+WQpuagh+iusOaJgOacieWtl+auteS4uuW3suinpueisO+8iOaVtOS4quihqOWNleaPkOS6pOaXtuiuvuS4uiB0cnVl77yJICovXHJcbiAgYWxsVG91Y2hlZDogYm9vbGVhbjtcclxuICAvKiog5q+P6KGM55qEIHRvdWNoZWQg54q25oCB77yI5Y2V6KGM5L+d5a2Y5pe26K6+5Li6IHRydWXvvIkgKi9cclxuICByb3dUb3VjaGVkOiBSZWNvcmQ8c3RyaW5nLCBib29sZWFuPjtcclxufVxyXG5cclxuLyoqIOihqOWNleWtmOWCqOaOpeWPoyAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIEFycmF5Rm9ybVN0b3JlIHtcclxuICBbZm9ybU5hbWU6IHN0cmluZ106IEFycmF5Rm9ybVN0b3JlSXRlbTtcclxufVxyXG5cclxuLyoqIOaVsOe7hOWei+aVsOaNruaUtumbhuWfuuehgOacjeWKoSAqL1xyXG5ASW5qZWN0YWJsZSh7XHJcbiAgcHJvdmlkZWRJbjogXCJyb290XCIsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBBcnJheUZvcm1TZXJ2aWNlIHtcclxuICBwcml2YXRlIGZvcm1TdG9yZTogQXJyYXlGb3JtU3RvcmUgPSB7fTtcclxuXHJcbiAgY29uc3RydWN0b3IoKSB7fVxyXG5cclxuICAvKiog5rex5bqm5YWL6ZqG5YC8ICovXHJcbiAgcHJpdmF0ZSBjbG9uZVZhbHVlKHZhbHVlOiBhbnkpOiBhbnkge1xyXG4gICAgaWYgKHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgfVxyXG4gICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XHJcbiAgICAgIHJldHVybiB2YWx1ZS5tYXAoKGl0ZW0pID0+IHRoaXMuY2xvbmVWYWx1ZShpdGVtKSk7XHJcbiAgICB9XHJcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiKSB7XHJcbiAgICAgIGNvbnN0IGNsb25lZDogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xyXG4gICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyh2YWx1ZSkpIHtcclxuICAgICAgICBjbG9uZWRba2V5XSA9IHRoaXMuY2xvbmVWYWx1ZSh2YWx1ZVtrZXldKTtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gY2xvbmVkO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHZhbHVlO1xyXG4gIH1cclxuXHJcbiAgLyoqIOavlOi+g+S4pOS4quWAvOaYr+WQpuebuOetiSAqL1xyXG4gIHByaXZhdGUgaXNFcXVhbChhOiBhbnksIGI6IGFueSk6IGJvb2xlYW4ge1xyXG4gICAgaWYgKGEgPT09IGIpIHJldHVybiB0cnVlO1xyXG4gICAgaWYgKGEgPT09IG51bGwgfHwgYiA9PT0gbnVsbCkgcmV0dXJuIGEgPT09IGI7XHJcbiAgICBpZiAoYSA9PT0gdW5kZWZpbmVkIHx8IGIgPT09IHVuZGVmaW5lZCkgcmV0dXJuIGEgPT09IGI7XHJcbiAgICBpZiAodHlwZW9mIGEgIT09IHR5cGVvZiBiKSByZXR1cm4gZmFsc2U7XHJcblxyXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoYSkgJiYgQXJyYXkuaXNBcnJheShiKSkge1xyXG4gICAgICBpZiAoYS5sZW5ndGggIT09IGIubGVuZ3RoKSByZXR1cm4gZmFsc2U7XHJcbiAgICAgIHJldHVybiBhLmV2ZXJ5KChpdGVtLCBpbmRleCkgPT4gdGhpcy5pc0VxdWFsKGl0ZW0sIGJbaW5kZXhdKSk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGVvZiBhID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBiID09PSBcIm9iamVjdFwiKSB7XHJcbiAgICAgIGNvbnN0IGtleXNBID0gT2JqZWN0LmtleXMoYSk7XHJcbiAgICAgIGNvbnN0IGtleXNCID0gT2JqZWN0LmtleXMoYik7XHJcbiAgICAgIGlmIChrZXlzQS5sZW5ndGggIT09IGtleXNCLmxlbmd0aCkgcmV0dXJuIGZhbHNlO1xyXG4gICAgICByZXR1cm4ga2V5c0EuZXZlcnkoKGtleSkgPT4gdGhpcy5pc0VxdWFsKGFba2V5XSwgYltrZXldKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG4gIH1cclxuXHJcbiAgLyoqIOWIm+W7uuihjOeahOWIneWni+WAvOW/q+eFpyAqL1xyXG4gIHByaXZhdGUgY3JlYXRlUm93U25hcHNob3QoXHJcbiAgICByb3c6IEFycmF5Rm9ybVJvdyxcclxuICAgIGZpZWxkczogRmllbGRDb25maWdbXVxyXG4gICk6IFJlY29yZDxzdHJpbmcsIGFueT4ge1xyXG4gICAgY29uc3Qgc25hcHNob3Q6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcclxuICAgIGZpZWxkcy5mb3JFYWNoKChmaWVsZCkgPT4ge1xyXG4gICAgICBzbmFwc2hvdFtmaWVsZC5uYW1lXSA9IHRoaXMuY2xvbmVWYWx1ZShyb3dbZmllbGQubmFtZV0pO1xyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gc25hcHNob3Q7XHJcbiAgfVxyXG5cclxuICAvKiog5Yid5aeL5YyW5pWw57uE5pWw5o2u77yM5re75YqgIHVpZCDlkowgaXNFZGl0IOWtl+autSAqL1xyXG4gIHByaXZhdGUgaW5pdGlhbGl6ZURhdGEoZGF0YTogYW55W10pOiBBcnJheUZvcm1Sb3dbXSB7XHJcbiAgICByZXR1cm4gZGF0YS5tYXAoKGl0ZW0pID0+IHRoaXMuZW5yaWNoUm93KGl0ZW0pKTtcclxuICB9XHJcblxyXG4gIC8qKiDkuLrljZXooYzmlbDmja7mt7vliqAgdWlkIOWSjCBpc0VkaXQg5a2X5q61ICovXHJcbiAgcHJpdmF0ZSBlbnJpY2hSb3cocm93OiBhbnkpOiBBcnJheUZvcm1Sb3cge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgLi4ucm93LFxyXG4gICAgICB1aWQ6IHJvdy51aWQgfHwgdXVpZHY0KCksXHJcbiAgICAgIGlzRWRpdDogcm93LmlzRWRpdCAhPT0gdW5kZWZpbmVkID8gcm93LmlzRWRpdCA6IGZhbHNlLFxyXG4gICAgICBkaXNhYmxlZDogcm93LmRpc2FibGVkICE9PSB1bmRlZmluZWQgPyByb3cuZGlzYWJsZWQgOiBmYWxzZSxcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICAvKiog5paw5aKe5LiA6KGM5pWw5o2uICovXHJcbiAgcHJpdmF0ZSBhZGRSb3coXHJcbiAgICBkYXRhOiBBcnJheUZvcm1Sb3dbXSxcclxuICAgIGRlZmF1bHRWYWx1ZXM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+XHJcbiAgKTogQXJyYXlGb3JtUm93IHtcclxuICAgIGNvbnN0IG5ld1JvdzogQXJyYXlGb3JtUm93ID0ge1xyXG4gICAgICAuLi5kZWZhdWx0VmFsdWVzLFxyXG4gICAgICB1aWQ6IHV1aWR2NCgpLFxyXG4gICAgICBpc0VkaXQ6IHRydWUsXHJcbiAgICAgIGlzQWRkOiB0cnVlLFxyXG4gICAgICBkaXNhYmxlZDogZmFsc2UsXHJcbiAgICB9O1xyXG4gICAgZGF0YS5wdXNoKG5ld1Jvdyk7XHJcbiAgICByZXR1cm4gbmV3Um93O1xyXG4gIH1cclxuXHJcbiAgLyoqIOagoemqjOWNleS4quWtl+autSAqL1xyXG4gIHByaXZhdGUgdmFsaWRhdGVGaWVsZChcclxuICAgIHJvdzogQXJyYXlGb3JtUm93LFxyXG4gICAgZmllbGROYW1lOiBzdHJpbmcsXHJcbiAgICBjb25maWc6IEFycmF5Rm9ybUNvbmZpZ1xyXG4gICk6IFZhbGlkYXRpb25SZXN1bHQge1xyXG4gICAgY29uc3QgZmllbGRDb25maWcgPSBjb25maWcuZmllbGRzLmZpbmQoKGYpID0+IGYubmFtZSA9PT0gZmllbGROYW1lKTtcclxuXHJcbiAgICBpZiAoIWZpZWxkQ29uZmlnKSB7XHJcbiAgICAgIHJldHVybiBcIlwiO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChmaWVsZENvbmZpZy52YWxpZGF0b3IpIHtcclxuICAgICAgcmV0dXJuIGZpZWxkQ29uZmlnLnZhbGlkYXRvcihyb3dbZmllbGROYW1lXSwgcm93LCBmaWVsZE5hbWUpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBcIlwiO1xyXG4gIH1cclxuXHJcbiAgLyoqIOagoemqjOaVtOihjOaVsOaNriAqL1xyXG4gIHByaXZhdGUgdmFsaWRhdGVSb3coXHJcbiAgICByb3c6IEFycmF5Rm9ybVJvdyxcclxuICAgIGNvbmZpZzogQXJyYXlGb3JtQ29uZmlnXHJcbiAgKTogUmVjb3JkPHN0cmluZywgVmFsaWRhdGlvblJlc3VsdD4ge1xyXG4gICAgY29uc3QgcmVzdWx0czogUmVjb3JkPHN0cmluZywgVmFsaWRhdGlvblJlc3VsdD4gPSB7fTtcclxuXHJcbiAgICBjb25maWcuZmllbGRzLmZvckVhY2goKGZpZWxkQ29uZmlnKSA9PiB7XHJcbiAgICAgIHJlc3VsdHNbZmllbGRDb25maWcubmFtZV0gPSB0aGlzLnZhbGlkYXRlRmllbGQoXHJcbiAgICAgICAgcm93LFxyXG4gICAgICAgIGZpZWxkQ29uZmlnLm5hbWUsXHJcbiAgICAgICAgY29uZmlnXHJcbiAgICAgICk7XHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4gcmVzdWx0cztcclxuICB9XHJcblxyXG4gIC8qKiDmoKHpqozmlbTkuKrmlbDnu4QgKi9cclxuICBwcml2YXRlIHZhbGlkYXRlRGF0YShcclxuICAgIGRhdGE6IEFycmF5Rm9ybVJvd1tdLFxyXG4gICAgY29uZmlnOiBBcnJheUZvcm1Db25maWdcclxuICApOiBSZWNvcmQ8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCBWYWxpZGF0aW9uUmVzdWx0Pj4ge1xyXG4gICAgY29uc3QgcmVzdWx0czogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgVmFsaWRhdGlvblJlc3VsdD4+ID0ge307XHJcblxyXG4gICAgZGF0YS5mb3JFYWNoKChyb3cpID0+IHtcclxuICAgICAgcmVzdWx0c1tyb3cudWlkXSA9IHRoaXMudmFsaWRhdGVSb3cocm93LCBjb25maWcpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuIHJlc3VsdHM7XHJcbiAgfVxyXG5cclxuICAvKiog5rOo5YaM6KGo5Y2V5Yiw5a2Y5YKoICovXHJcbiAgcmVnaXN0ZXJGb3JtKFxyXG4gICAgZm9ybU5hbWU6IHN0cmluZyxcclxuICAgIGRhdGE6IEFycmF5Rm9ybVJvd1tdLFxyXG4gICAgY29uZmlnOiBBcnJheUZvcm1Db25maWdcclxuICApOiB2b2lkIHtcclxuICAgIGNvbnN0IGluaXRpYWxpemVkRGF0YSA9IHRoaXMuaW5pdGlhbGl6ZURhdGEoZGF0YSk7XHJcblxyXG4gICAgLy8g6K6w5b2V5Yid5aeL5YC85b+r54WnXHJcbiAgICBjb25zdCBpbml0aWFsU25hcHNob3Q6IFJlY29yZDxzdHJpbmcsIFJlY29yZDxzdHJpbmcsIGFueT4+ID0ge307XHJcbiAgICBpbml0aWFsaXplZERhdGEuZm9yRWFjaCgocm93KSA9PiB7XHJcbiAgICAgIGluaXRpYWxTbmFwc2hvdFtyb3cudWlkIV0gPSB0aGlzLmNyZWF0ZVJvd1NuYXBzaG90KHJvdywgY29uZmlnLmZpZWxkcyk7XHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLmZvcm1TdG9yZVtmb3JtTmFtZV0gPSB7XHJcbiAgICAgIGRhdGE6IGluaXRpYWxpemVkRGF0YSxcclxuICAgICAgY29uZmlnLFxyXG4gICAgICB2YWxpZGF0aW9uUmVzdWx0czoge30sXHJcbiAgICAgIGluaXRpYWxTbmFwc2hvdCxcclxuICAgICAgZWRpdGluZ1NuYXBzaG90OiB7fSxcclxuICAgICAgYWxsVG91Y2hlZDogZmFsc2UsXHJcbiAgICAgIHJvd1RvdWNoZWQ6IHt9LFxyXG4gICAgfTtcclxuICAgIC8vIOWmguaenOmFjee9ruS6huiHquWKqOabtOaWsO+8jOeri+WNs+abtOaWsOS4gOasoVxyXG4gICAgdGhpcy5hdXRvVXBkYXRlQXJyYXlSZWZlcmVuY2UoZm9ybU5hbWUpO1xyXG4gIH1cclxuXHJcbiAgLyoqIOS7juWtmOWCqOS4reiOt+WPluihqOWNlSAqL1xyXG4gIGdldEZvcm0oZm9ybU5hbWU6IHN0cmluZyk6IEFycmF5Rm9ybVN0b3JlSXRlbSB8IHVuZGVmaW5lZCB7XHJcbiAgICByZXR1cm4gdGhpcy5mb3JtU3RvcmVbZm9ybU5hbWVdO1xyXG4gIH1cclxuXHJcbiAgLyoqIOS7juWtmOWCqOS4reiOt+WPluihqOWNleaVsOaNriAqL1xyXG4gIGdldEZvcm1EYXRhKFxyXG4gICAgZm9ybU5hbWU6IHN0cmluZ1xyXG4gICk6XHJcbiAgICB8IEFycmF5PFBpY2s8QXJyYXlGb3JtUm93LCBcInVpZFwiIHwgXCJpc0VkaXRcIiB8IFwiaXNBZGRcIiB8IGtleW9mIEFycmF5Rm9ybVJvdz4+XHJcbiAgICB8IHVuZGVmaW5lZCB7XHJcbiAgICBjb25zdCBmb3JtID0gdGhpcy5mb3JtU3RvcmVbZm9ybU5hbWVdO1xyXG4gICAgaWYgKCFmb3JtKSB7XHJcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZm9ybS5kYXRhLm1hcCgoaXRlbSkgPT4ge1xyXG4gICAgICBkZWxldGUgaXRlbS5pc0VkaXQ7XHJcbiAgICAgIGRlbGV0ZSBpdGVtLmlzQWRkO1xyXG4gICAgICBkZWxldGUgaXRlbS51aWQ7XHJcbiAgICAgIHJldHVybiBpdGVtO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKiog5ZCR6KGo5Y2V5re75Yqg6KGMICovXHJcbiAgYWRkUm93VG9Gb3JtKFxyXG4gICAgZm9ybU5hbWU6IHN0cmluZyxcclxuICAgIGRlZmF1bHRWYWx1ZXM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+XHJcbiAgKTogQXJyYXlGb3JtUm93IHwgdW5kZWZpbmVkIHtcclxuICAgIGNvbnN0IGZvcm0gPSB0aGlzLmZvcm1TdG9yZVtmb3JtTmFtZV07XHJcbiAgICBpZiAoIWZvcm0pIHtcclxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgIH1cclxuICAgIGNvbnN0IG5ld1JvdyA9IHRoaXMuYWRkUm93KGZvcm0uZGF0YSwgZGVmYXVsdFZhbHVlcyk7XHJcbiAgICAvLyDkuLrmlrDooYzorrDlvZXliJ3lp4vlgLzlv6vnhadcclxuICAgIGZvcm0uaW5pdGlhbFNuYXBzaG90W25ld1Jvdy51aWQhXSA9IHRoaXMuY3JlYXRlUm93U25hcHNob3QoXHJcbiAgICAgIG5ld1JvdyxcclxuICAgICAgZm9ybS5jb25maWcuZmllbGRzXHJcbiAgICApO1xyXG4gICAgLy8g6Ieq5Yqo5pu05paw5aSW6YOo5pWw57uE5byV55SoXHJcbiAgICB0aGlzLmF1dG9VcGRhdGVBcnJheVJlZmVyZW5jZShmb3JtTmFtZSk7XHJcbiAgICByZXR1cm4gbmV3Um93O1xyXG4gIH1cclxuXHJcbiAgLyoqIOagoemqjOihqOWNle+8jOiHquWKqOagh+iusOaJgOacieWtl+auteS4uuW3suinpueisCAqL1xyXG4gIHZhbGlkYXRlRm9ybShmb3JtTmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICBjb25zdCBmb3JtID0gdGhpcy5mb3JtU3RvcmVbZm9ybU5hbWVdO1xyXG4gICAgaWYgKCFmb3JtKSB7XHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG4gICAgLy8g5qCH6K6w5omA5pyJ5a2X5q615Li65bey6Kem56KwXHJcbiAgICBmb3JtLmFsbFRvdWNoZWQgPSB0cnVlO1xyXG4gICAgY29uc3QgcmVzdWx0cyA9IHRoaXMudmFsaWRhdGVEYXRhKGZvcm0uZGF0YSwgZm9ybS5jb25maWcpO1xyXG4gICAgZm9ybS52YWxpZGF0aW9uUmVzdWx0cyA9IHJlc3VsdHM7XHJcblxyXG4gICAgLy8g5qOA5p+l5piv5ZCm5pyJ5Lu75L2V6ZSZ6K+vXHJcbiAgICBmb3IgKGNvbnN0IHVpZCBvZiBPYmplY3Qua2V5cyhyZXN1bHRzKSkge1xyXG4gICAgICBmb3IgKGNvbnN0IGZpZWxkTmFtZSBvZiBPYmplY3Qua2V5cyhyZXN1bHRzW3VpZF0pKSB7XHJcbiAgICAgICAgaWYgKHJlc3VsdHNbdWlkXVtmaWVsZE5hbWVdKSB7XHJcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdHJ1ZTtcclxuICB9XHJcblxyXG4gIC8qKiDlvIDlkK/nvJbovpHmqKHlvI/vvIzkv53lrZjlv6vnhafnlKjkuo7lj5bmtojmgaLlpI0gKi9cclxuICBlbmFibGVFZGl0KGZvcm1OYW1lOiBzdHJpbmcsIHJvdzogQXJyYXlGb3JtUm93KTogdm9pZCB7XHJcbiAgICBjb25zdCBmb3JtID0gdGhpcy5mb3JtU3RvcmVbZm9ybU5hbWVdO1xyXG4gICAgaWYgKGZvcm0gJiYgcm93LnVpZCkge1xyXG4gICAgICAvLyDkv53lrZjnvJbovpHliY3nmoTlv6vnhadcclxuICAgICAgZm9ybS5lZGl0aW5nU25hcHNob3Rbcm93LnVpZF0gPSB0aGlzLmNyZWF0ZVJvd1NuYXBzaG90KFxyXG4gICAgICAgIHJvdyxcclxuICAgICAgICBmb3JtLmNvbmZpZy5maWVsZHNcclxuICAgICAgKTtcclxuICAgIH1cclxuICAgIHJvdy5pc0VkaXQgPSB0cnVlO1xyXG4gIH1cclxuXHJcbiAgLyoqIOWPlua2iOe8lui+ke+8jOaBouWkjeWIsOe8lui+keWJjeeahOaVsOaNriAqL1xyXG4gIGRpc2FibGVFZGl0KGZvcm1OYW1lOiBzdHJpbmcsIHJvdzogQXJyYXlGb3JtUm93KTogdm9pZCB7XHJcbiAgICBjb25zdCBmb3JtID0gdGhpcy5mb3JtU3RvcmVbZm9ybU5hbWVdO1xyXG4gICAgaWYgKGZvcm0gJiYgcm93LnVpZCAmJiBmb3JtLmVkaXRpbmdTbmFwc2hvdFtyb3cudWlkXSkge1xyXG4gICAgICAvLyDmgaLlpI3nvJbovpHliY3nmoTmlbDmja5cclxuICAgICAgY29uc3Qgc25hcHNob3QgPSBmb3JtLmVkaXRpbmdTbmFwc2hvdFtyb3cudWlkXTtcclxuICAgICAgZm9ybS5jb25maWcuZmllbGRzLmZvckVhY2goKGZpZWxkKSA9PiB7XHJcbiAgICAgICAgcm93W2ZpZWxkLm5hbWVdID0gdGhpcy5jbG9uZVZhbHVlKHNuYXBzaG90W2ZpZWxkLm5hbWVdKTtcclxuICAgICAgfSk7XHJcbiAgICAgIC8vIOabtOaWsOWIneWni+W/q+eFp+S4uuaBouWkjeWQjueahOWAvO+8jOa2iOmZpCB0b3VjaGVkIOeKtuaAgVxyXG4gICAgICBmb3JtLmluaXRpYWxTbmFwc2hvdFtyb3cudWlkXSA9IHRoaXMuY2xvbmVWYWx1ZShzbmFwc2hvdCk7XHJcbiAgICAgIC8vIOa4heeQhue8lui+keW/q+eFp+WSjCB0b3VjaGVkIOeKtuaAgVxyXG4gICAgICBkZWxldGUgZm9ybS5lZGl0aW5nU25hcHNob3Rbcm93LnVpZF07XHJcbiAgICAgIGRlbGV0ZSBmb3JtLnJvd1RvdWNoZWRbcm93LnVpZF07XHJcbiAgICAgIC8vIOa4heeQhuivpeihjOeahOagoemqjOe7k+aenFxyXG4gICAgICBpZiAoZm9ybS52YWxpZGF0aW9uUmVzdWx0cykge1xyXG4gICAgICAgIGRlbGV0ZSBmb3JtLnZhbGlkYXRpb25SZXN1bHRzW3Jvdy51aWRdO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByb3cuaXNFZGl0ID0gZmFsc2U7XHJcbiAgfVxyXG5cclxuICAvKiog56Gu6K6k57yW6L6R77yM5L+d55WZ5L+u5pS55ZCO55qE5pWw5o2uICovXHJcbiAgY29uZmlybUVkaXQoZm9ybU5hbWU6IHN0cmluZywgcm93OiBBcnJheUZvcm1Sb3cpOiB2b2lkIHtcclxuICAgIGNvbnN0IGZvcm0gPSB0aGlzLmZvcm1TdG9yZVtmb3JtTmFtZV07XHJcbiAgICBpZiAoZm9ybSAmJiByb3cudWlkKSB7XHJcbiAgICAgIC8vIOa4heeQhue8lui+keW/q+eFp++8iOS/neeVmeW9k+WJjeaVsOaNru+8iVxyXG4gICAgICBpZiAoZm9ybS5lZGl0aW5nU25hcHNob3Rbcm93LnVpZF0pIHtcclxuICAgICAgICBkZWxldGUgZm9ybS5lZGl0aW5nU25hcHNob3Rbcm93LnVpZF07XHJcbiAgICAgIH1cclxuICAgICAgLy8g5pu05paw5Yid5aeL5b+r54Wn5Li65b2T5YmN5YC877yI55So5LqO5ZCO57utIHRvdWNoZWQg5qOA5rWL77yJXHJcbiAgICAgIGZvcm0uaW5pdGlhbFNuYXBzaG90W3Jvdy51aWRdID0gdGhpcy5jcmVhdGVSb3dTbmFwc2hvdChcclxuICAgICAgICByb3csXHJcbiAgICAgICAgZm9ybS5jb25maWcuZmllbGRzXHJcbiAgICAgICk7XHJcbiAgICAgIC8vIOa4hemZpCB0b3VjaGVkIOeKtuaAge+8jOWfuuS6juaWsOeahCBpbml0aWFsU25hcHNob3Qg6YeN5paw5Yik5patXHJcbiAgICAgIGRlbGV0ZSBmb3JtLnJvd1RvdWNoZWRbcm93LnVpZF07XHJcbiAgICB9XHJcbiAgICByb3cuaXNFZGl0ID0gZmFsc2U7XHJcbiAgICByb3cuaXNBZGQgPSBmYWxzZTtcclxuICB9XHJcblxyXG4gIC8qKiDku47ooajljZXkuK3liKDpmaTmjIflrprooYwgKi9cclxuICBkZWxldGVSb3dGcm9tRm9ybShmb3JtTmFtZTogc3RyaW5nLCByb3c6IEFycmF5Rm9ybVJvdyk6IGJvb2xlYW4ge1xyXG4gICAgY29uc3QgZm9ybSA9IHRoaXMuZm9ybVN0b3JlW2Zvcm1OYW1lXTtcclxuICAgIGlmICghZm9ybSB8fCAhcm93LnVpZCkge1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICBjb25zdCBpbmRleCA9IGZvcm0uZGF0YS5maW5kSW5kZXgoKGl0ZW0pID0+IGl0ZW0udWlkID09PSByb3cudWlkKTtcclxuICAgIGlmIChpbmRleCA9PT0gLTEpIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgZm9ybS5kYXRhLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICAvLyDmuIXnkIbor6XooYznmoTmiYDmnInlv6vnhafjgIF0b3VjaGVkIOeKtuaAgeWSjOagoemqjOe7k+aenFxyXG4gICAgZGVsZXRlIGZvcm0uaW5pdGlhbFNuYXBzaG90W3Jvdy51aWRdO1xyXG4gICAgZGVsZXRlIGZvcm0uZWRpdGluZ1NuYXBzaG90W3Jvdy51aWRdO1xyXG4gICAgZGVsZXRlIGZvcm0ucm93VG91Y2hlZFtyb3cudWlkXTtcclxuICAgIGlmIChmb3JtLnZhbGlkYXRpb25SZXN1bHRzKSB7XHJcbiAgICAgIGRlbGV0ZSBmb3JtLnZhbGlkYXRpb25SZXN1bHRzW3Jvdy51aWRdO1xyXG4gICAgfVxyXG4gICAgLy8g6Ieq5Yqo5pu05paw5aSW6YOo5pWw57uE5byV55SoXHJcbiAgICB0aGlzLmF1dG9VcGRhdGVBcnJheVJlZmVyZW5jZShmb3JtTmFtZSk7XHJcbiAgICByZXR1cm4gdHJ1ZTtcclxuICB9XHJcblxyXG4gIC8qKiDmo4DmtYvlrZfmrrXmmK/lkKblt7Looqvop6bnorAgKi9cclxuICBwcml2YXRlIGlzRmllbGRUb3VjaGVkKFxyXG4gICAgZm9ybTogQXJyYXlGb3JtU3RvcmVJdGVtLFxyXG4gICAgcm93OiBBcnJheUZvcm1Sb3csXHJcbiAgICBmaWVsZE5hbWU6IHN0cmluZ1xyXG4gICk6IGJvb2xlYW4ge1xyXG4gICAgLy8g5pW05Liq6KGo5Y2V5beyIHRvdWNoZWTvvIjmlbTkuKrooajljZXmj5DkuqTml7bvvIlcclxuICAgIGlmIChmb3JtLmFsbFRvdWNoZWQpIHtcclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcbiAgICAvLyDlvZPliY3ooYzlt7IgdG91Y2hlZO+8iOWNleihjOS/neWtmOaXtu+8iVxyXG4gICAgaWYgKGZvcm0ucm93VG91Y2hlZFtyb3cudWlkIV0pIHtcclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcbiAgICAvLyDmo4DmtYvlvZPliY3lgLzkuI7liJ3lp4vlgLzmmK/lkKbkuI3lkIxcclxuICAgIGNvbnN0IGluaXRpYWxWYWx1ZSA9IGZvcm0uaW5pdGlhbFNuYXBzaG90W3Jvdy51aWQhXT8uW2ZpZWxkTmFtZV07XHJcbiAgICBjb25zdCBjdXJyZW50VmFsdWUgPSByb3dbZmllbGROYW1lXTtcclxuICAgIHJldHVybiAhdGhpcy5pc0VxdWFsKGluaXRpYWxWYWx1ZSwgY3VycmVudFZhbHVlKTtcclxuICB9XHJcblxyXG4gIC8qKiDmoKHpqozmjIflrprooYznmoTmjIflrprlrZfmrrXvvIzmnKrkv67mlLnml7bkuI3mmL7npLrmoKHpqoznirbmgIEgKi9cclxuICB2YWxpZGF0ZUZpZWxkSW5Sb3coXHJcbiAgICBmb3JtTmFtZTogc3RyaW5nLFxyXG4gICAgcm93OiBBcnJheUZvcm1Sb3csXHJcbiAgICBmaWVsZE5hbWU6IHN0cmluZ1xyXG4gICk6IFwic3VjY2Vzc1wiIHwgXCJlcnJvclwiIHwgXCJcIiB7XHJcbiAgICBjb25zdCBmb3JtID0gdGhpcy5mb3JtU3RvcmVbZm9ybU5hbWVdO1xyXG4gICAgaWYgKCFmb3JtKSB7XHJcbiAgICAgIHJldHVybiBcIlwiO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGZpZWxkQ29uZmlnID0gZm9ybS5jb25maWcuZmllbGRzLmZpbmQoKGYpID0+IGYubmFtZSA9PT0gZmllbGROYW1lKTtcclxuICAgIGlmICghZmllbGRDb25maWcpIHtcclxuICAgICAgcmV0dXJuIFwiXCI7XHJcbiAgICB9XHJcblxyXG4gICAgLy8g5omn6KGM5qCh6aqMXHJcbiAgICBsZXQgcmVzdWx0OiBWYWxpZGF0aW9uUmVzdWx0ID0gXCJcIjtcclxuICAgIGlmIChmaWVsZENvbmZpZy52YWxpZGF0b3IpIHtcclxuICAgICAgcmVzdWx0ID0gZmllbGRDb25maWcudmFsaWRhdG9yKHJvd1tmaWVsZE5hbWVdLCByb3csIGZpZWxkTmFtZSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8g5pu05paw5qCh6aqM57uT5p6c5a2Y5YKoXHJcbiAgICBpZiAoIWZvcm0udmFsaWRhdGlvblJlc3VsdHMpIHtcclxuICAgICAgZm9ybS52YWxpZGF0aW9uUmVzdWx0cyA9IHt9O1xyXG4gICAgfVxyXG4gICAgaWYgKCFmb3JtLnZhbGlkYXRpb25SZXN1bHRzW3Jvdy51aWQhXSkge1xyXG4gICAgICBmb3JtLnZhbGlkYXRpb25SZXN1bHRzW3Jvdy51aWQhXSA9IHt9O1xyXG4gICAgfVxyXG4gICAgZm9ybS52YWxpZGF0aW9uUmVzdWx0c1tyb3cudWlkIV1bZmllbGROYW1lXSA9IHJlc3VsdDtcclxuXHJcbiAgICAvLyDlpoLmnpzlrZfmrrXmnKrooqvop6bnorDvvIzkuI3mmL7npLrmoKHpqoznirbmgIFcclxuICAgIGlmICghdGhpcy5pc0ZpZWxkVG91Y2hlZChmb3JtLCByb3csIGZpZWxkTmFtZSkpIHtcclxuICAgICAgcmV0dXJuIFwiXCI7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHJlc3VsdCA/IFwiZXJyb3JcIiA6IFwic3VjY2Vzc1wiO1xyXG4gIH1cclxuXHJcbiAgLyoqIOiOt+WPluaMh+WumuihjOaMh+WumuWtl+auteeahOagoemqjOmUmeivr+S/oeaBryAqL1xyXG4gIGdldEZpZWxkRXJyb3JNZXNzYWdlKFxyXG4gICAgZm9ybU5hbWU6IHN0cmluZyxcclxuICAgIHJvdzogQXJyYXlGb3JtUm93LFxyXG4gICAgZmllbGROYW1lOiBzdHJpbmdcclxuICApOiBzdHJpbmcge1xyXG4gICAgY29uc3QgZm9ybSA9IHRoaXMuZm9ybVN0b3JlW2Zvcm1OYW1lXTtcclxuICAgIGlmICghZm9ybSB8fCAhcm93LnVpZCkge1xyXG4gICAgICByZXR1cm4gXCJcIjtcclxuICAgIH1cclxuICAgIC8vIOWmguaenOWtl+auteacquiiq+inpueisO+8jOS4jeaYvuekuumUmeivr+S/oeaBr1xyXG4gICAgaWYgKCF0aGlzLmlzRmllbGRUb3VjaGVkKGZvcm0sIHJvdywgZmllbGROYW1lKSkge1xyXG4gICAgICByZXR1cm4gXCJcIjtcclxuICAgIH1cclxuICAgIHJldHVybiBmb3JtLnZhbGlkYXRpb25SZXN1bHRzPy5bcm93LnVpZF0/LltmaWVsZE5hbWVdIHx8IFwiXCI7XHJcbiAgfVxyXG5cclxuICAvKiog5qCh6aqM5oyH5a6a6KGM55qE5omA5pyJ5a2X5q61ICovXHJcbiAgdmFsaWRhdGVSb3dBbGxGaWVsZHMoZm9ybU5hbWU6IHN0cmluZywgcm93OiBBcnJheUZvcm1Sb3cpOiBib29sZWFuIHtcclxuICAgIGNvbnN0IGZvcm0gPSB0aGlzLmZvcm1TdG9yZVtmb3JtTmFtZV07XHJcbiAgICBpZiAoIWZvcm0gfHwgIXJvdy51aWQpIHtcclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgLy8g5pu05paw5Yid5aeL5b+r54Wn5Li65b2T5YmN5YC8XHJcbiAgICBmb3JtLmluaXRpYWxTbmFwc2hvdFtyb3cudWlkXSA9IHRoaXMuY3JlYXRlUm93U25hcHNob3QoXHJcbiAgICAgIHJvdyxcclxuICAgICAgZm9ybS5jb25maWcuZmllbGRzXHJcbiAgICApO1xyXG4gICAgLy8g5qCH6K6w5b2T5YmN6KGM5Li6IHRvdWNoZWTvvIjlj6rlvbHlk43lvZPliY3ooYzvvIzkuI3lvbHlk43lhbbku5booYzvvIlcclxuICAgIGZvcm0ucm93VG91Y2hlZFtyb3cudWlkXSA9IHRydWU7XHJcblxyXG4gICAgbGV0IGhhc0Vycm9yID0gZmFsc2U7XHJcblxyXG4gICAgZm9ybS5jb25maWcuZmllbGRzLmZvckVhY2goKGZpZWxkQ29uZmlnKSA9PiB7XHJcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMudmFsaWRhdGVGaWVsZEluUm93KGZvcm1OYW1lLCByb3csIGZpZWxkQ29uZmlnLm5hbWUpO1xyXG4gICAgICBpZiAocmVzdWx0ID09PSBcImVycm9yXCIpIHtcclxuICAgICAgICBoYXNFcnJvciA9IHRydWU7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgIHJldHVybiAhaGFzRXJyb3I7XHJcbiAgfVxyXG5cclxuICAvKiog6Ieq5Yqo5pu05paw5aSW6YOo5pWw57uE5byV55SoICovXHJcbiAgcHJpdmF0ZSBhdXRvVXBkYXRlQXJyYXlSZWZlcmVuY2UoZm9ybU5hbWU6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgY29uc3QgZm9ybSA9IHRoaXMuZm9ybVN0b3JlW2Zvcm1OYW1lXTtcclxuICAgIGlmICghZm9ybSB8fCAhZm9ybS5jb25maWcudGFyZ2V0T2JqZWN0IHx8ICFmb3JtLmNvbmZpZy5hcnJheVByb3BlcnR5TmFtZSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBjb25zdCBuZXdBcnJheSA9IGZvcm0uZGF0YSA/IFsuLi5mb3JtLmRhdGFdIDogW107XHJcbiAgICAvLyDmm7TmlrDnm67moIflr7nosaHnmoTmlbDnu4TlsZ7mgKfkuLrmlrDmlbDnu4TlvJXnlKhcclxuICAgIChmb3JtLmNvbmZpZy50YXJnZXRPYmplY3QgYXMgYW55KVtmb3JtLmNvbmZpZy5hcnJheVByb3BlcnR5TmFtZV0gPSBuZXdBcnJheTtcclxuICB9XHJcblxyXG4gIC8qKiDmmK/lkKbmnInmraPlnKjnvJbovpHnmoTooYwgKi9cclxuICBoYXNFZGl0aW5nUm93KGZvcm1OYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgIGNvbnN0IGZvcm0gPSB0aGlzLmZvcm1TdG9yZVtmb3JtTmFtZV07XHJcbiAgICBpZiAoIWZvcm0pIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGZvcm0uZGF0YS5zb21lKChpdGVtKSA9PiBpdGVtLmlzRWRpdCk7XHJcbiAgfVxyXG5cclxuICAvLyDplIDmr4Hlr7nlupTnmoTooajljZVcclxuICBkZXN0b3J5KG5hbWVzOiBzdHJpbmdbXSk6IHZvaWQge1xyXG4gICAgbmFtZXMuZm9yRWFjaCgobmFtZSkgPT4ge1xyXG4gICAgICBpZiAodGhpcy5mb3JtU3RvcmVbbmFtZV0pIHtcclxuICAgICAgICAvLyDmuIXnkIbooajljZXmlbDmja5cclxuICAgICAgICBkZWxldGUgdGhpcy5mb3JtU3RvcmVbbmFtZV07XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLy8g6YeN572u6KGo5Y2V5pWw57uEXHJcbiAgcmVzZXRGb3JtQXJyYXkobmFtZTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICBjb25zdCBmb3JtID0gdGhpcy5mb3JtU3RvcmVbbmFtZV07XHJcbiAgICBpZiAoIWZvcm0pIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIDEuIOa4heepuuaVsOaNruaVsOe7hFxyXG4gICAgZm9ybS5kYXRhID0gW107XHJcblxyXG4gICAgLy8gMi4g5riF55CG5omA5pyJ5b+r54WnXHJcbiAgICBmb3JtLmluaXRpYWxTbmFwc2hvdCA9IHt9O1xyXG4gICAgZm9ybS5lZGl0aW5nU25hcHNob3QgPSB7fTtcclxuXHJcbiAgICAvLyAzLiDmuIXnkIbmoKHpqoznu5PmnpxcclxuICAgIGZvcm0udmFsaWRhdGlvblJlc3VsdHMgPSB7fTtcclxuXHJcbiAgICAvLyA0LiDph43nva4gdG91Y2hlZCDnirbmgIFcclxuICAgIGZvcm0uYWxsVG91Y2hlZCA9IGZhbHNlO1xyXG4gICAgZm9ybS5yb3dUb3VjaGVkID0ge307XHJcblxyXG4gICAgLy8gNS4g5aaC5p6c6YWN572u5LqG6Ieq5Yqo5pu05paw77yM5pu05paw5aSW6YOo5pWw57uE5byV55SoXHJcbiAgICB0aGlzLmF1dG9VcGRhdGVBcnJheVJlZmVyZW5jZShuYW1lKTtcclxuICB9XHJcbn1cclxuIl19