@yibozhang/pro-table 0.0.4 → 0.0.5

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
+ }
167
197
  row.isEdit = false;
168
198
  }
169
- /**
170
- * 从表单中删除指定行
171
- *
172
- * @param formName 表单名称
173
- * @param row 行的uid
174
- * @returns 是否删除成功
175
- */
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
+ }
212
+ row.isEdit = false;
213
+ row.isAdd = false;
214
+ }
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,14 @@ 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
+ }
261
332
  }
262
333
  ArrayFormService.ɵprov = i0.ɵɵdefineInjectable({ factory: function ArrayFormService_Factory() { return new ArrayFormService(); }, token: ArrayFormService, providedIn: "root" });
263
334
  ArrayFormService.decorators = [
@@ -266,4 +337,4 @@ ArrayFormService.decorators = [
266
337
  },] }
267
338
  ];
268
339
  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==
340
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJyYXktZm9ybS5qcyIsInNvdXJjZVJvb3QiOiJEOi9wcm9qZWN0cy92cHMtZnJvbnQvRnJvbnQvRGFzUE1TV2ViL2xpYi9wcm8tdGFibGUvc3JjLyIsInNvdXJjZXMiOlsibGliL3BhZ2UtcHVibGljL2FycmF5LWZvcm0udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsRUFBRSxJQUFJLE1BQU0sRUFBRSxNQUFNLE1BQU0sQ0FBQzs7QUF3RHBDLGtCQUFrQjtBQUlsQixNQUFNLE9BQU8sZ0JBQWdCO0lBRzNCO1FBRlEsY0FBUyxHQUFtQixFQUFFLENBQUM7SUFFeEIsQ0FBQztJQUVoQixZQUFZO0lBQ0osVUFBVSxDQUFDLEtBQVU7UUFDM0IsSUFBSSxLQUFLLEtBQUssSUFBSSxJQUFJLEtBQUssS0FBSyxTQUFTLEVBQUU7WUFDekMsT0FBTyxLQUFLLENBQUM7U0FDZDtRQUNELElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUN4QixPQUFPLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztTQUNuRDtRQUNELElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFO1lBQzdCLE1BQU0sTUFBTSxHQUF3QixFQUFFLENBQUM7WUFDdkMsS0FBSyxNQUFNLEdBQUcsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFO2dCQUNwQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQzthQUMzQztZQUNELE9BQU8sTUFBTSxDQUFDO1NBQ2Y7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRCxnQkFBZ0I7SUFDUixPQUFPLENBQUMs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QUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN0QyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLGlCQUFpQixFQUFFO1lBQ3hFLE9BQU87U0FDUjtRQUNELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUNqRCxvQkFBb0I7UUFDbkIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFvQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsR0FBRyxRQUFRLENBQUM7SUFDOUUsQ0FBQztJQUVELGdCQUFnQjtJQUNoQixhQUFhLENBQUMsUUFBZ0I7UUFDNUIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN0QyxJQUFJLENBQUMsSUFBSSxFQUFFO1lBQ1QsT0FBTyxLQUFLLENBQUM7U0FDZDtRQUNELE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMvQyxDQUFDOzs7O1lBamJGLFVBQVUsU0FBQztnQkFDVixVQUFVLEVBQUUsTUFBTTthQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgdjQgYXMgdXVpZHY0IH0gZnJvbSBcInV1aWRcIjtcblxuLyoqIOWtl+auteagoemqjOe7k+aenOexu+WeiyAqL1xuZXhwb3J0IHR5cGUgVmFsaWRhdGlvblJlc3VsdCA9IHN0cmluZztcblxuLyoqIOWtl+auteagoemqjOaWueazleexu+WeiyAqL1xuZXhwb3J0IHR5cGUgRmllbGRWYWxpZGF0b3IgPSAoXG4gIHZhbHVlOiBhbnksXG4gIHJvdzogQXJyYXlGb3JtUm93LFxuICBmaWVsZE5hbWU6IHN0cmluZ1xuKSA9PiBWYWxpZGF0aW9uUmVzdWx0O1xuXG4vKiog5a2X5q616YWN572u5o6l5Y+jICovXG5leHBvcnQgaW50ZXJmYWNlIEZpZWxkQ29uZmlnIHtcbiAgbmFtZTogc3RyaW5nO1xuICB2YWxpZGF0b3I/OiBGaWVsZFZhbGlkYXRvcjtcbn1cblxuLyoqIOaVsOe7hOihqOWNleihjOaVsOaNruaOpeWPoyAqL1xuZXhwb3J0IGludGVyZmFjZSBBcnJheUZvcm1Sb3cge1xuICB1aWQ/OiBzdHJpbmc7XG4gIGlzRWRpdDogYm9vbGVhbjtcbiAgaXNBZGQ/OiBib29sZWFuO1xuICBkaXNhYmxlZD86IGJvb2xlYW47XG4gIFtrZXk6IHN0cmluZ106IGFueTtcbn1cblxuLyoqIOaVsOe7hOihqOWNlemFjee9ruaOpeWPoyAqL1xuZXhwb3J0IGludGVyZmFjZSBBcnJheUZvcm1Db25maWcge1xuICBmaWVsZHM6IEZpZWxkQ29uZmlnW107XG4gIGRlZmF1bHRWYWx1ZXM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuICAvLyDoh6rliqjmm7TmlrDnm67moIflr7nosaHlkozlsZ7mgKflkI3vvIznlKjkuo7op6blj5EgQW5ndWxhciDlj5jljJbmo4DmtYtcbiAgdGFyZ2V0T2JqZWN0PzogUmVjb3JkPHN0cmluZywgYW55PjtcbiAgYXJyYXlQcm9wZXJ0eU5hbWU/OiBzdHJpbmc7XG59XG5cbi8qKiDooajljZXlrZjlgqjpobnmjqXlj6MgKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXJyYXlGb3JtU3RvcmVJdGVtIHtcbiAgZGF0YTogQXJyYXlGb3JtUm93W107XG4gIGNvbmZpZzogQXJyYXlGb3JtQ29uZmlnO1xuICB2YWxpZGF0aW9uUmVzdWx0cz86IFJlY29yZDxzdHJpbmcsIFJlY29yZDxzdHJpbmcsIFZhbGlkYXRpb25SZXN1bHQ+PjtcbiAgLyoqIOWIneWni+WAvOW/q+eFp++8jOeUqOS6juiHquWKqOajgOa1i+Wtl+auteaYr+WQpuiiq+S/ruaUuSAqL1xuICBpbml0aWFsU25hcHNob3Q6IFJlY29yZDxzdHJpbmcsIFJlY29yZDxzdHJpbmcsIGFueT4+O1xuICAvKiog57yW6L6R5pe25b+r54Wn77yM55So5LqO5Y+W5raI57yW6L6R5pe25oGi5aSN5pWw5o2uICovXG4gIGVkaXRpbmdTbmFwc2hvdDogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgYW55Pj47XG4gIC8qKiDmmK/lkKbmoIforrDmiYDmnInlrZfmrrXkuLrlt7Lop6bnorDvvIjmlbTkuKrooajljZXmj5DkuqTml7borr7kuLogdHJ1Ze+8iSAqL1xuICBhbGxUb3VjaGVkOiBib29sZWFuO1xuICAvKiog5q+P6KGM55qEIHRvdWNoZWQg54q25oCB77yI5Y2V6KGM5L+d5a2Y5pe26K6+5Li6IHRydWXvvIkgKi9cbiAgcm93VG91Y2hlZDogUmVjb3JkPHN0cmluZywgYm9vbGVhbj47XG59XG5cbi8qKiDooajljZXlrZjlgqjmjqXlj6MgKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXJyYXlGb3JtU3RvcmUge1xuICBbZm9ybU5hbWU6IHN0cmluZ106IEFycmF5Rm9ybVN0b3JlSXRlbTtcbn1cblxuLyoqIOaVsOe7hOWei+aVsOaNruaUtumbhuWfuuehgOacjeWKoSAqL1xuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiBcInJvb3RcIixcbn0pXG5leHBvcnQgY2xhc3MgQXJyYXlGb3JtU2VydmljZSB7XG4gIHByaXZhdGUgZm9ybVN0b3JlOiBBcnJheUZvcm1TdG9yZSA9IHt9O1xuXG4gIGNvbnN0cnVjdG9yKCkge31cblxuICAvKiog5rex5bqm5YWL6ZqG5YC8ICovXG4gIHByaXZhdGUgY2xvbmVWYWx1ZSh2YWx1ZTogYW55KTogYW55IHtcbiAgICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZS5tYXAoKGl0ZW0pID0+IHRoaXMuY2xvbmVWYWx1ZShpdGVtKSk7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgIGNvbnN0IGNsb25lZDogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xuICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXModmFsdWUpKSB7XG4gICAgICAgIGNsb25lZFtrZXldID0gdGhpcy5jbG9uZVZhbHVlKHZhbHVlW2tleV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNsb25lZDtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cbiAgLyoqIOavlOi+g+S4pOS4quWAvOaYr+WQpuebuOetiSAqL1xuICBwcml2YXRlIGlzRXF1YWwoYTogYW55LCBiOiBhbnkpOiBib29sZWFuIHtcbiAgICBpZiAoYSA9PT0gYikgcmV0dXJuIHRydWU7XG4gICAgaWYgKGEgPT09IG51bGwgfHwgYiA9PT0gbnVsbCkgcmV0dXJuIGEgPT09IGI7XG4gICAgaWYgKGEgPT09IHVuZGVmaW5lZCB8fCBiID09PSB1bmRlZmluZWQpIHJldHVybiBhID09PSBiO1xuICAgIGlmICh0eXBlb2YgYSAhPT0gdHlwZW9mIGIpIHJldHVybiBmYWxzZTtcblxuICAgIGlmIChBcnJheS5pc0FycmF5KGEpICYmIEFycmF5LmlzQXJyYXkoYikpIHtcbiAgICAgIGlmIChhLmxlbmd0aCAhPT0gYi5sZW5ndGgpIHJldHVybiBmYWxzZTtcbiAgICAgIHJldHVybiBhLmV2ZXJ5KChpdGVtLCBpbmRleCkgPT4gdGhpcy5pc0VxdWFsKGl0ZW0sIGJbaW5kZXhdKSk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBhID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBiID09PSBcIm9iamVjdFwiKSB7XG4gICAgICBjb25zdCBrZXlzQSA9IE9iamVjdC5rZXlzKGEpO1xuICAgICAgY29uc3Qga2V5c0IgPSBPYmplY3Qua2V5cyhiKTtcbiAgICAgIGlmIChrZXlzQS5sZW5ndGggIT09IGtleXNCLmxlbmd0aCkgcmV0dXJuIGZhbHNlO1xuICAgICAgcmV0dXJuIGtleXNBLmV2ZXJ5KChrZXkpID0+IHRoaXMuaXNFcXVhbChhW2tleV0sIGJba2V5XSkpO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKiDliJvlu7rooYznmoTliJ3lp4vlgLzlv6vnhacgKi9cbiAgcHJpdmF0ZSBjcmVhdGVSb3dTbmFwc2hvdChcbiAgICByb3c6IEFycmF5Rm9ybVJvdyxcbiAgICBmaWVsZHM6IEZpZWxkQ29uZmlnW11cbiAgKTogUmVjb3JkPHN0cmluZywgYW55PiB7XG4gICAgY29uc3Qgc25hcHNob3Q6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcbiAgICBmaWVsZHMuZm9yRWFjaCgoZmllbGQpID0+IHtcbiAgICAgIHNuYXBzaG90W2ZpZWxkLm5hbWVdID0gdGhpcy5jbG9uZVZhbHVlKHJvd1tmaWVsZC5uYW1lXSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHNuYXBzaG90O1xuICB9XG5cbiAgLyoqIOWIneWni+WMluaVsOe7hOaVsOaNru+8jOa3u+WKoCB1aWQg5ZKMIGlzRWRpdCDlrZfmrrUgKi9cbiAgcHJpdmF0ZSBpbml0aWFsaXplRGF0YShkYXRhOiBhbnlbXSk6IEFycmF5Rm9ybVJvd1tdIHtcbiAgICByZXR1cm4gZGF0YS5tYXAoKGl0ZW0pID0+IHRoaXMuZW5yaWNoUm93KGl0ZW0pKTtcbiAgfVxuXG4gIC8qKiDkuLrljZXooYzmlbDmja7mt7vliqAgdWlkIOWSjCBpc0VkaXQg5a2X5q61ICovXG4gIHByaXZhdGUgZW5yaWNoUm93KHJvdzogYW55KTogQXJyYXlGb3JtUm93IHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4ucm93LFxuICAgICAgdWlkOiByb3cudWlkIHx8IHV1aWR2NCgpLFxuICAgICAgaXNFZGl0OiByb3cuaXNFZGl0ICE9PSB1bmRlZmluZWQgPyByb3cuaXNFZGl0IDogZmFsc2UsXG4gICAgICBkaXNhYmxlZDogcm93LmRpc2FibGVkICE9PSB1bmRlZmluZWQgPyByb3cuZGlzYWJsZWQgOiBmYWxzZSxcbiAgICB9O1xuICB9XG5cbiAgLyoqIOaWsOWinuS4gOihjOaVsOaNriAqL1xuICBwcml2YXRlIGFkZFJvdyhcbiAgICBkYXRhOiBBcnJheUZvcm1Sb3dbXSxcbiAgICBkZWZhdWx0VmFsdWVzPzogUmVjb3JkPHN0cmluZywgYW55PlxuICApOiBBcnJheUZvcm1Sb3cge1xuICAgIGNvbnN0IG5ld1JvdzogQXJyYXlGb3JtUm93ID0ge1xuICAgICAgLi4uZGVmYXVsdFZhbHVlcyxcbiAgICAgIHVpZDogdXVpZHY0KCksXG4gICAgICBpc0VkaXQ6IHRydWUsXG4gICAgICBpc0FkZDogdHJ1ZSxcbiAgICAgIGRpc2FibGVkOiBmYWxzZSxcbiAgICB9O1xuICAgIGRhdGEucHVzaChuZXdSb3cpO1xuICAgIHJldHVybiBuZXdSb3c7XG4gIH1cblxuICAvKiog5qCh6aqM5Y2V5Liq5a2X5q61ICovXG4gIHByaXZhdGUgdmFsaWRhdGVGaWVsZChcbiAgICByb3c6IEFycmF5Rm9ybVJvdyxcbiAgICBmaWVsZE5hbWU6IHN0cmluZyxcbiAgICBjb25maWc6IEFycmF5Rm9ybUNvbmZpZ1xuICApOiBWYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBjb25zdCBmaWVsZENvbmZpZyA9IGNvbmZpZy5maWVsZHMuZmluZCgoZikgPT4gZi5uYW1lID09PSBmaWVsZE5hbWUpO1xuXG4gICAgaWYgKCFmaWVsZENvbmZpZykge1xuICAgICAgcmV0dXJuIFwiXCI7XG4gICAgfVxuXG4gICAgaWYgKGZpZWxkQ29uZmlnLnZhbGlkYXRvcikge1xuICAgICAgcmV0dXJuIGZpZWxkQ29uZmlnLnZhbGlkYXRvcihyb3dbZmllbGROYW1lXSwgcm93LCBmaWVsZE5hbWUpO1xuICAgIH1cblxuICAgIHJldHVybiBcIlwiO1xuICB9XG5cbiAgLyoqIOagoemqjOaVtOihjOaVsOaNriAqL1xuICBwcml2YXRlIHZhbGlkYXRlUm93KFxuICAgIHJvdzogQXJyYXlGb3JtUm93LFxuICAgIGNvbmZpZzogQXJyYXlGb3JtQ29uZmlnXG4gICk6IFJlY29yZDxzdHJpbmcsIFZhbGlkYXRpb25SZXN1bHQ+IHtcbiAgICBjb25zdCByZXN1bHRzOiBSZWNvcmQ8c3RyaW5nLCBWYWxpZGF0aW9uUmVzdWx0PiA9IHt9O1xuXG4gICAgY29uZmlnLmZpZWxkcy5mb3JFYWNoKChmaWVsZENvbmZpZykgPT4ge1xuICAgICAgcmVzdWx0c1tmaWVsZENvbmZpZy5uYW1lXSA9IHRoaXMudmFsaWRhdGVGaWVsZChcbiAgICAgICAgcm93LFxuICAgICAgICBmaWVsZENvbmZpZy5uYW1lLFxuICAgICAgICBjb25maWdcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfVxuXG4gIC8qKiDmoKHpqozmlbTkuKrmlbDnu4QgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZURhdGEoXG4gICAgZGF0YTogQXJyYXlGb3JtUm93W10sXG4gICAgY29uZmlnOiBBcnJheUZvcm1Db25maWdcbiAgKTogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgVmFsaWRhdGlvblJlc3VsdD4+IHtcbiAgICBjb25zdCByZXN1bHRzOiBSZWNvcmQ8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCBWYWxpZGF0aW9uUmVzdWx0Pj4gPSB7fTtcblxuICAgIGRhdGEuZm9yRWFjaCgocm93KSA9PiB7XG4gICAgICByZXN1bHRzW3Jvdy51aWRdID0gdGhpcy52YWxpZGF0ZVJvdyhyb3csIGNvbmZpZyk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfVxuXG4gIC8qKiDms6jlhozooajljZXliLDlrZjlgqggKi9cbiAgcmVnaXN0ZXJGb3JtKFxuICAgIGZvcm1OYW1lOiBzdHJpbmcsXG4gICAgZGF0YTogQXJyYXlGb3JtUm93W10sXG4gICAgY29uZmlnOiBBcnJheUZvcm1Db25maWdcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgaW5pdGlhbGl6ZWREYXRhID0gdGhpcy5pbml0aWFsaXplRGF0YShkYXRhKTtcblxuICAgIC8vIOiusOW9leWIneWni+WAvOW/q+eFp1xuICAgIGNvbnN0IGluaXRpYWxTbmFwc2hvdDogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgYW55Pj4gPSB7fTtcbiAgICBpbml0aWFsaXplZERhdGEuZm9yRWFjaCgocm93KSA9PiB7XG4gICAgICBpbml0aWFsU25hcHNob3Rbcm93LnVpZCFdID0gdGhpcy5jcmVhdGVSb3dTbmFwc2hvdChyb3csIGNvbmZpZy5maWVsZHMpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5mb3JtU3RvcmVbZm9ybU5hbWVdID0ge1xuICAgICAgZGF0YTogaW5pdGlhbGl6ZWREYXRhLFxuICAgICAgY29uZmlnLFxuICAgICAgdmFsaWRhdGlvblJlc3VsdHM6IHt9LFxuICAgICAgaW5pdGlhbFNuYXBzaG90LFxuICAgICAgZWRpdGluZ1NuYXBzaG90OiB7fSxcbiAgICAgIGFsbFRvdWNoZWQ6IGZhbHNlLFxuICAgICAgcm93VG91Y2hlZDoge30sXG4gICAgfTtcbiAgICAvLyDlpoLmnpzphY3nva7kuoboh6rliqjmm7TmlrDvvIznq4vljbPmm7TmlrDkuIDmrKFcbiAgICB0aGlzLmF1dG9VcGRhdGVBcnJheVJlZmVyZW5jZShmb3JtTmFtZSk7XG4gIH1cblxuICAvKiog5LuO5a2Y5YKo5Lit6I635Y+W6KGo5Y2VICovXG4gIGdldEZvcm0oZm9ybU5hbWU6IHN0cmluZyk6IEFycmF5Rm9ybVN0b3JlSXRlbSB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuZm9ybVN0b3JlW2Zvcm1OYW1lXTtcbiAgfVxuXG4gIC8qKiDku47lrZjlgqjkuK3ojrflj5booajljZXmlbDmja4gKi9cbiAgZ2V0Rm9ybURhdGEoXG4gICAgZm9ybU5hbWU6IHN0cmluZ1xuICApOlxuICAgIHwgQXJyYXk8UGljazxBcnJheUZvcm1Sb3csIFwidWlkXCIgfCBcImlzRWRpdFwiIHwgXCJpc0FkZFwiIHwga2V5b2YgQXJyYXlGb3JtUm93Pj5cbiAgICB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgZm9ybSA9IHRoaXMuZm9ybVN0b3JlW2Zvcm1OYW1lXTtcbiAgICBpZiAoIWZvcm0pIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiBmb3JtLmRhdGEubWFwKChpdGVtKSA9PiB7XG4gICAgICBkZWxldGUgaXRlbS5pc0VkaXQ7XG4gICAgICBkZWxldGUgaXRlbS5pc0FkZDtcbiAgICAgIGRlbGV0ZSBpdGVtLnVpZDtcbiAgICAgIHJldHVybiBpdGVtO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqIOWQkeihqOWNlea3u+WKoOihjCAqL1xuICBhZGRSb3dUb0Zvcm0oXG4gICAgZm9ybU5hbWU6IHN0cmluZyxcbiAgICBkZWZhdWx0VmFsdWVzPzogUmVjb3JkPHN0cmluZywgYW55PlxuICApOiBBcnJheUZvcm1Sb3cgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGZvcm0gPSB0aGlzLmZvcm1TdG9yZVtmb3JtTmFtZV07XG4gICAgaWYgKCFmb3JtKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBjb25zdCBuZXdSb3cgPSB0aGlzLmFkZFJvdyhmb3JtLmRhdGEsIGRlZmF1bHRWYWx1ZXMpO1xuICAgIC8vIOS4uuaWsOihjOiusOW9leWIneWni+WAvOW/q+eFp1xuICAgIGZvcm0uaW5pdGlhbFNuYXBzaG90W25ld1Jvdy51aWQhXSA9IHRoaXMuY3JlYXRlUm93U25hcHNob3QoXG4gICAgICBuZXdSb3csXG4gICAgICBmb3JtLmNvbmZpZy5maWVsZHNcbiAgICApO1xuICAgIC8vIOiHquWKqOabtOaWsOWklumDqOaVsOe7hOW8leeUqFxuICAgIHRoaXMuYXV0b1VwZGF0ZUFycmF5UmVmZXJlbmNlKGZvcm1OYW1lKTtcbiAgICByZXR1cm4gbmV3Um93O1xuICB9XG5cbiAgLyoqIOagoemqjOihqOWNle+8jOiHquWKqOagh+iusOaJgOacieWtl+auteS4uuW3suinpueisCAqL1xuICB2YWxpZGF0ZUZvcm0oZm9ybU5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGZvcm0gPSB0aGlzLmZvcm1TdG9yZVtmb3JtTmFtZV07XG4gICAgaWYgKCFmb3JtKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgLy8g5qCH6K6w5omA5pyJ5a2X5q615Li65bey6Kem56KwXG4gICAgZm9ybS5hbGxUb3VjaGVkID0gdHJ1ZTtcbiAgICBjb25zdCByZXN1bHRzID0gdGhpcy52YWxpZGF0ZURhdGEoZm9ybS5kYXRhLCBmb3JtLmNvbmZpZyk7XG4gICAgZm9ybS52YWxpZGF0aW9uUmVzdWx0cyA9IHJlc3VsdHM7XG5cbiAgICAvLyDmo4Dmn6XmmK/lkKbmnInku7vkvZXplJnor69cbiAgICBmb3IgKGNvbnN0IHVpZCBvZiBPYmplY3Qua2V5cyhyZXN1bHRzKSkge1xuICAgICAgZm9yIChjb25zdCBmaWVsZE5hbWUgb2YgT2JqZWN0LmtleXMocmVzdWx0c1t1aWRdKSkge1xuICAgICAgICBpZiAocmVzdWx0c1t1aWRdW2ZpZWxkTmFtZV0pIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKiog5byA5ZCv57yW6L6R5qih5byP77yM5L+d5a2Y5b+r54Wn55So5LqO5Y+W5raI5oGi5aSNICovXG4gIGVuYWJsZUVkaXQoZm9ybU5hbWU6IHN0cmluZywgcm93OiBBcnJheUZvcm1Sb3cpOiB2b2lkIHtcbiAgICBjb25zdCBmb3JtID0gdGhpcy5mb3JtU3RvcmVbZm9ybU5hbWVdO1xuICAgIGlmIChmb3JtICYmIHJvdy51aWQpIHtcbiAgICAgIC8vIOS/neWtmOe8lui+keWJjeeahOW/q+eFp1xuICAgICAgZm9ybS5lZGl0aW5nU25hcHNob3Rbcm93LnVpZF0gPSB0aGlzLmNyZWF0ZVJvd1NuYXBzaG90KFxuICAgICAgICByb3csXG4gICAgICAgIGZvcm0uY29uZmlnLmZpZWxkc1xuICAgICAgKTtcbiAgICB9XG4gICAgcm93LmlzRWRpdCA9IHRydWU7XG4gIH1cblxuICAvKiog5Y+W5raI57yW6L6R77yM5oGi5aSN5Yiw57yW6L6R5YmN55qE5pWw5o2uICovXG4gIGRpc2FibGVFZGl0KGZvcm1OYW1lOiBzdHJpbmcsIHJvdzogQXJyYXlGb3JtUm93KTogdm9pZCB7XG4gICAgY29uc3QgZm9ybSA9IHRoaXMuZm9ybVN0b3JlW2Zvcm1OYW1lXTtcbiAgICBpZiAoZm9ybSAmJiByb3cudWlkICYmIGZvcm0uZWRpdGluZ1NuYXBzaG90W3Jvdy51aWRdKSB7XG4gICAgICAvLyDmgaLlpI3nvJbovpHliY3nmoTmlbDmja5cbiAgICAgIGNvbnN0IHNuYXBzaG90ID0gZm9ybS5lZGl0aW5nU25hcHNob3Rbcm93LnVpZF07XG4gICAgICBmb3JtLmNvbmZpZy5maWVsZHMuZm9yRWFjaCgoZmllbGQpID0+IHtcbiAgICAgICAgcm93W2ZpZWxkLm5hbWVdID0gdGhpcy5jbG9uZVZhbHVlKHNuYXBzaG90W2ZpZWxkLm5hbWVdKTtcbiAgICAgIH0pO1xuICAgICAgLy8g5pu05paw5Yid5aeL5b+r54Wn5Li65oGi5aSN5ZCO55qE5YC877yM5raI6ZmkIHRvdWNoZWQg54q25oCBXG4gICAgICBmb3JtLmluaXRpYWxTbmFwc2hvdFtyb3cudWlkXSA9IHRoaXMuY2xvbmVWYWx1ZShzbmFwc2hvdCk7XG4gICAgICAvLyDmuIXnkIbnvJbovpHlv6vnhaflkowgdG91Y2hlZCDnirbmgIFcbiAgICAgIGRlbGV0ZSBmb3JtLmVkaXRpbmdTbmFwc2hvdFtyb3cudWlkXTtcbiAgICAgIGRlbGV0ZSBmb3JtLnJvd1RvdWNoZWRbcm93LnVpZF07XG4gICAgICAvLyDmuIXnkIbor6XooYznmoTmoKHpqoznu5PmnpxcbiAgICAgIGlmIChmb3JtLnZhbGlkYXRpb25SZXN1bHRzKSB7XG4gICAgICAgIGRlbGV0ZSBmb3JtLnZhbGlkYXRpb25SZXN1bHRzW3Jvdy51aWRdO1xuICAgICAgfVxuICAgIH1cbiAgICByb3cuaXNFZGl0ID0gZmFsc2U7XG4gIH1cblxuICAvKiog56Gu6K6k57yW6L6R77yM5L+d55WZ5L+u5pS55ZCO55qE5pWw5o2uICovXG4gIGNvbmZpcm1FZGl0KGZvcm1OYW1lOiBzdHJpbmcsIHJvdzogQXJyYXlGb3JtUm93KTogdm9pZCB7XG4gICAgY29uc3QgZm9ybSA9IHRoaXMuZm9ybVN0b3JlW2Zvcm1OYW1lXTtcbiAgICBpZiAoZm9ybSAmJiByb3cudWlkKSB7XG4gICAgICAvLyDmuIXnkIbnvJbovpHlv6vnhafvvIjkv53nlZnlvZPliY3mlbDmja7vvIlcbiAgICAgIGlmIChmb3JtLmVkaXRpbmdTbmFwc2hvdFtyb3cudWlkXSkge1xuICAgICAgICBkZWxldGUgZm9ybS5lZGl0aW5nU25hcHNob3Rbcm93LnVpZF07XG4gICAgICB9XG4gICAgICAvLyDmm7TmlrDliJ3lp4vlv6vnhafkuLrlvZPliY3lgLzvvIjnlKjkuo7lkI7nu60gdG91Y2hlZCDmo4DmtYvvvIlcbiAgICAgIGZvcm0uaW5pdGlhbFNuYXBzaG90W3Jvdy51aWRdID0gdGhpcy5jcmVhdGVSb3dTbmFwc2hvdChcbiAgICAgICAgcm93LFxuICAgICAgICBmb3JtLmNvbmZpZy5maWVsZHNcbiAgICAgICk7XG4gICAgICAvLyDmuIXpmaQgdG91Y2hlZCDnirbmgIHvvIzln7rkuo7mlrDnmoQgaW5pdGlhbFNuYXBzaG90IOmHjeaWsOWIpOaWrVxuICAgICAgZGVsZXRlIGZvcm0ucm93VG91Y2hlZFtyb3cudWlkXTtcbiAgICB9XG4gICAgcm93LmlzRWRpdCA9IGZhbHNlO1xuICAgIHJvdy5pc0FkZCA9IGZhbHNlO1xuICB9XG5cbiAgLyoqIOS7juihqOWNleS4reWIoOmZpOaMh+WumuihjCAqL1xuICBkZWxldGVSb3dGcm9tRm9ybShmb3JtTmFtZTogc3RyaW5nLCByb3c6IEFycmF5Rm9ybVJvdyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGZvcm0gPSB0aGlzLmZvcm1TdG9yZVtmb3JtTmFtZV07XG4gICAgaWYgKCFmb3JtIHx8ICFyb3cudWlkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IGluZGV4ID0gZm9ybS5kYXRhLmZpbmRJbmRleCgoaXRlbSkgPT4gaXRlbS51aWQgPT09IHJvdy51aWQpO1xuICAgIGlmIChpbmRleCA9PT0gLTEpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgZm9ybS5kYXRhLnNwbGljZShpbmRleCwgMSk7XG4gICAgLy8g5riF55CG6K+l6KGM55qE5omA5pyJ5b+r54Wn44CBdG91Y2hlZCDnirbmgIHlkozmoKHpqoznu5PmnpxcbiAgICBkZWxldGUgZm9ybS5pbml0aWFsU25hcHNob3Rbcm93LnVpZF07XG4gICAgZGVsZXRlIGZvcm0uZWRpdGluZ1NuYXBzaG90W3Jvdy51aWRdO1xuICAgIGRlbGV0ZSBmb3JtLnJvd1RvdWNoZWRbcm93LnVpZF07XG4gICAgaWYgKGZvcm0udmFsaWRhdGlvblJlc3VsdHMpIHtcbiAgICAgIGRlbGV0ZSBmb3JtLnZhbGlkYXRpb25SZXN1bHRzW3Jvdy51aWRdO1xuICAgIH1cbiAgICAvLyDoh6rliqjmm7TmlrDlpJbpg6jmlbDnu4TlvJXnlKhcbiAgICB0aGlzLmF1dG9VcGRhdGVBcnJheVJlZmVyZW5jZShmb3JtTmFtZSk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKiog5qOA5rWL5a2X5q615piv5ZCm5bey6KKr6Kem56KwICovXG4gIHByaXZhdGUgaXNGaWVsZFRvdWNoZWQoXG4gICAgZm9ybTogQXJyYXlGb3JtU3RvcmVJdGVtLFxuICAgIHJvdzogQXJyYXlGb3JtUm93LFxuICAgIGZpZWxkTmFtZTogc3RyaW5nXG4gICk6IGJvb2xlYW4ge1xuICAgIC8vIOaVtOS4quihqOWNleW3siB0b3VjaGVk77yI5pW05Liq6KGo5Y2V5o+Q5Lqk5pe277yJXG4gICAgaWYgKGZvcm0uYWxsVG91Y2hlZCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIC8vIOW9k+WJjeihjOW3siB0b3VjaGVk77yI5Y2V6KGM5L+d5a2Y5pe277yJXG4gICAgaWYgKGZvcm0ucm93VG91Y2hlZFtyb3cudWlkIV0pIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICAvLyDmo4DmtYvlvZPliY3lgLzkuI7liJ3lp4vlgLzmmK/lkKbkuI3lkIxcbiAgICBjb25zdCBpbml0aWFsVmFsdWUgPSBmb3JtLmluaXRpYWxTbmFwc2hvdFtyb3cudWlkIV0/LltmaWVsZE5hbWVdO1xuICAgIGNvbnN0IGN1cnJlbnRWYWx1ZSA9IHJvd1tmaWVsZE5hbWVdO1xuICAgIHJldHVybiAhdGhpcy5pc0VxdWFsKGluaXRpYWxWYWx1ZSwgY3VycmVudFZhbHVlKTtcbiAgfVxuXG4gIC8qKiDmoKHpqozmjIflrprooYznmoTmjIflrprlrZfmrrXvvIzmnKrkv67mlLnml7bkuI3mmL7npLrmoKHpqoznirbmgIEgKi9cbiAgdmFsaWRhdGVGaWVsZEluUm93KFxuICAgIGZvcm1OYW1lOiBzdHJpbmcsXG4gICAgcm93OiBBcnJheUZvcm1Sb3csXG4gICAgZmllbGROYW1lOiBzdHJpbmdcbiAgKTogXCJzdWNjZXNzXCIgfCBcImVycm9yXCIgfCBcIlwiIHtcbiAgICBjb25zdCBmb3JtID0gdGhpcy5mb3JtU3RvcmVbZm9ybU5hbWVdO1xuICAgIGlmICghZm9ybSkge1xuICAgICAgcmV0dXJuIFwiXCI7XG4gICAgfVxuXG4gICAgY29uc3QgZmllbGRDb25maWcgPSBmb3JtLmNvbmZpZy5maWVsZHMuZmluZCgoZikgPT4gZi5uYW1lID09PSBmaWVsZE5hbWUpO1xuICAgIGlmICghZmllbGRDb25maWcpIHtcbiAgICAgIHJldHVybiBcIlwiO1xuICAgIH1cblxuICAgIC8vIOaJp+ihjOagoemqjFxuICAgIGxldCByZXN1bHQ6IFZhbGlkYXRpb25SZXN1bHQgPSBcIlwiO1xuICAgIGlmIChmaWVsZENvbmZpZy52YWxpZGF0b3IpIHtcbiAgICAgIHJlc3VsdCA9IGZpZWxkQ29uZmlnLnZhbGlkYXRvcihyb3dbZmllbGROYW1lXSwgcm93LCBmaWVsZE5hbWUpO1xuICAgIH1cblxuICAgIC8vIOabtOaWsOagoemqjOe7k+aenOWtmOWCqFxuICAgIGlmICghZm9ybS52YWxpZGF0aW9uUmVzdWx0cykge1xuICAgICAgZm9ybS52YWxpZGF0aW9uUmVzdWx0cyA9IHt9O1xuICAgIH1cbiAgICBpZiAoIWZvcm0udmFsaWRhdGlvblJlc3VsdHNbcm93LnVpZCFdKSB7XG4gICAgICBmb3JtLnZhbGlkYXRpb25SZXN1bHRzW3Jvdy51aWQhXSA9IHt9O1xuICAgIH1cbiAgICBmb3JtLnZhbGlkYXRpb25SZXN1bHRzW3Jvdy51aWQhXVtmaWVsZE5hbWVdID0gcmVzdWx0O1xuXG4gICAgLy8g5aaC5p6c5a2X5q615pyq6KKr6Kem56Kw77yM5LiN5pi+56S65qCh6aqM54q25oCBXG4gICAgaWYgKCF0aGlzLmlzRmllbGRUb3VjaGVkKGZvcm0sIHJvdywgZmllbGROYW1lKSkge1xuICAgICAgcmV0dXJuIFwiXCI7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdCA/IFwiZXJyb3JcIiA6IFwic3VjY2Vzc1wiO1xuICB9XG5cbiAgLyoqIOiOt+WPluaMh+WumuihjOaMh+WumuWtl+auteeahOagoemqjOmUmeivr+S/oeaBryAqL1xuICBnZXRGaWVsZEVycm9yTWVzc2FnZShcbiAgICBmb3JtTmFtZTogc3RyaW5nLFxuICAgIHJvdzogQXJyYXlGb3JtUm93LFxuICAgIGZpZWxkTmFtZTogc3RyaW5nXG4gICk6IHN0cmluZyB7XG4gICAgY29uc3QgZm9ybSA9IHRoaXMuZm9ybVN0b3JlW2Zvcm1OYW1lXTtcbiAgICBpZiAoIWZvcm0gfHwgIXJvdy51aWQpIHtcbiAgICAgIHJldHVybiBcIlwiO1xuICAgIH1cbiAgICAvLyDlpoLmnpzlrZfmrrXmnKrooqvop6bnorDvvIzkuI3mmL7npLrplJnor6/kv6Hmga9cbiAgICBpZiAoIXRoaXMuaXNGaWVsZFRvdWNoZWQoZm9ybSwgcm93LCBmaWVsZE5hbWUpKSB7XG4gICAgICByZXR1cm4gXCJcIjtcbiAgICB9XG4gICAgcmV0dXJuIGZvcm0udmFsaWRhdGlvblJlc3VsdHM/Lltyb3cudWlkXT8uW2ZpZWxkTmFtZV0gfHwgXCJcIjtcbiAgfVxuXG4gIC8qKiDmoKHpqozmjIflrprooYznmoTmiYDmnInlrZfmrrUgKi9cbiAgdmFsaWRhdGVSb3dBbGxGaWVsZHMoZm9ybU5hbWU6IHN0cmluZywgcm93OiBBcnJheUZvcm1Sb3cpOiBib29sZWFuIHtcbiAgICBjb25zdCBmb3JtID0gdGhpcy5mb3JtU3RvcmVbZm9ybU5hbWVdO1xuICAgIGlmICghZm9ybSB8fCAhcm93LnVpZCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLy8g5pu05paw5Yid5aeL5b+r54Wn5Li65b2T5YmN5YC8XG4gICAgZm9ybS5pbml0aWFsU25hcHNob3Rbcm93LnVpZF0gPSB0aGlzLmNyZWF0ZVJvd1NuYXBzaG90KFxuICAgICAgcm93LFxuICAgICAgZm9ybS5jb25maWcuZmllbGRzXG4gICAgKTtcbiAgICAvLyDmoIforrDlvZPliY3ooYzkuLogdG91Y2hlZO+8iOWPquW9seWTjeW9k+WJjeihjO+8jOS4jeW9seWTjeWFtuS7luihjO+8iVxuICAgIGZvcm0ucm93VG91Y2hlZFtyb3cudWlkXSA9IHRydWU7XG5cbiAgICBsZXQgaGFzRXJyb3IgPSBmYWxzZTtcblxuICAgIGZvcm0uY29uZmlnLmZpZWxkcy5mb3JFYWNoKChmaWVsZENvbmZpZykgPT4ge1xuICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy52YWxpZGF0ZUZpZWxkSW5Sb3coZm9ybU5hbWUsIHJvdywgZmllbGRDb25maWcubmFtZSk7XG4gICAgICBpZiAocmVzdWx0ID09PSBcImVycm9yXCIpIHtcbiAgICAgICAgaGFzRXJyb3IgPSB0cnVlO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuICFoYXNFcnJvcjtcbiAgfVxuXG4gIC8qKiDoh6rliqjmm7TmlrDlpJbpg6jmlbDnu4TlvJXnlKggKi9cbiAgcHJpdmF0ZSBhdXRvVXBkYXRlQXJyYXlSZWZlcmVuY2UoZm9ybU5hbWU6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IGZvcm0gPSB0aGlzLmZvcm1TdG9yZVtmb3JtTmFtZV07XG4gICAgaWYgKCFmb3JtIHx8ICFmb3JtLmNvbmZpZy50YXJnZXRPYmplY3QgfHwgIWZvcm0uY29uZmlnLmFycmF5UHJvcGVydHlOYW1lKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IG5ld0FycmF5ID0gZm9ybS5kYXRhID8gWy4uLmZvcm0uZGF0YV0gOiBbXTtcbiAgICAvLyDmm7TmlrDnm67moIflr7nosaHnmoTmlbDnu4TlsZ7mgKfkuLrmlrDmlbDnu4TlvJXnlKhcbiAgICAoZm9ybS5jb25maWcudGFyZ2V0T2JqZWN0IGFzIGFueSlbZm9ybS5jb25maWcuYXJyYXlQcm9wZXJ0eU5hbWVdID0gbmV3QXJyYXk7XG4gIH1cblxuICAvKiog5piv5ZCm5pyJ5q2j5Zyo57yW6L6R55qE6KGMICovXG4gIGhhc0VkaXRpbmdSb3coZm9ybU5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGZvcm0gPSB0aGlzLmZvcm1TdG9yZVtmb3JtTmFtZV07XG4gICAgaWYgKCFmb3JtKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBmb3JtLmRhdGEuc29tZSgoaXRlbSkgPT4gaXRlbS5pc0VkaXQpO1xuICB9XG59XG4iXX0=