@rosen-bridge/config 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/.eslintignore +1 -0
  2. package/CHANGELOG.md +8 -0
  3. package/README.md +24 -0
  4. package/dist/cli.d.ts +3 -0
  5. package/dist/cli.d.ts.map +1 -0
  6. package/dist/cli.js +102 -0
  7. package/dist/config.d.ts +131 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +578 -0
  10. package/dist/index.d.ts +2 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +2 -0
  13. package/dist/schema/Validators/fieldProperties.d.ts +29 -0
  14. package/dist/schema/Validators/fieldProperties.d.ts.map +1 -0
  15. package/dist/schema/Validators/fieldProperties.js +254 -0
  16. package/dist/schema/types/fields.d.ts +37 -0
  17. package/dist/schema/types/fields.d.ts.map +1 -0
  18. package/dist/schema/types/fields.js +2 -0
  19. package/dist/schema/types/validations.d.ts +46 -0
  20. package/dist/schema/types/validations.d.ts.map +1 -0
  21. package/dist/schema/types/validations.js +2 -0
  22. package/dist/tsconfig.tsbuildinfo +1 -0
  23. package/dist/utils.d.ts +36 -0
  24. package/dist/utils.d.ts.map +1 -0
  25. package/dist/utils.js +59 -0
  26. package/dist/value/validators.d.ts +3 -0
  27. package/dist/value/validators.d.ts.map +1 -0
  28. package/dist/value/validators.js +188 -0
  29. package/lib/cli.ts +113 -0
  30. package/lib/config.ts +664 -0
  31. package/lib/index.ts +1 -0
  32. package/lib/schema/Validators/fieldProperties.ts +273 -0
  33. package/lib/schema/types/fields.ts +46 -0
  34. package/lib/schema/types/validations.ts +63 -0
  35. package/lib/utils.ts +68 -0
  36. package/lib/value/validators.ts +268 -0
  37. package/package.json +48 -0
  38. package/tests/.gitkeep +0 -0
  39. package/tests/config.spec.ts +895 -0
  40. package/tests/configEnvSetup.ts +34 -0
  41. package/tests/configTestData.ts +977 -0
  42. package/tests/configTestFiles/custom-environment-variables.json +5 -0
  43. package/tests/configTestFiles/default.json +12 -0
  44. package/tests/configTestFiles/local.json +5 -0
  45. package/tests/utils.spec.ts +117 -0
  46. package/tests/utilsTestData.ts +26 -0
  47. package/tsconfig.build.json +7 -0
  48. package/tsconfig.build.tsbuildinfo +1 -0
  49. package/tsconfig.json +7 -0
  50. package/vitest.config.ts +11 -0
package/dist/config.js ADDED
@@ -0,0 +1,578 @@
1
+ import * as fs from 'fs';
2
+ import * as yaml from 'js-yaml';
3
+ import JsonBigIntFactory from 'json-bigint';
4
+ import path from 'path';
5
+ import {
6
+ propertyValidators,
7
+ supportedTypes,
8
+ } from './schema/Validators/fieldProperties';
9
+ import { getSourceName, getValueFromConfigSources } from './utils';
10
+ import { valueValidations, valueValidators } from './value/validators';
11
+ export class ConfigValidator {
12
+ schema;
13
+ constructor(schema) {
14
+ this.schema = schema;
15
+ this.validateSchema();
16
+ }
17
+ /**
18
+ * validates the passed config against the instance's schema
19
+ *
20
+ * @param {Record<string, any>} config
21
+ */
22
+ validateConfig(config) {
23
+ const errorPreamble = (path) =>
24
+ `config validation failed for "${path.join('.')}" field`;
25
+ const stack = [
26
+ {
27
+ subSchema: this.schema,
28
+ subConfig: config,
29
+ parentPath: [],
30
+ },
31
+ ];
32
+ this.validateValue(
33
+ config,
34
+ { type: 'object', children: this.schema },
35
+ config
36
+ );
37
+ // Traverses the schema object tree depth first in coordination with config
38
+ // object tree and validate config using the schema
39
+ while (stack.length > 0) {
40
+ const { subSchema, subConfig, parentPath } = stack.pop();
41
+ // Process children of current field
42
+ for (const name of Object.keys(subSchema)) {
43
+ const path = parentPath.concat([name]);
44
+ try {
45
+ const field = subSchema[name];
46
+ let value = undefined;
47
+ if (subConfig != undefined && Object.hasOwn(subConfig, name)) {
48
+ value = subConfig[name];
49
+ }
50
+ this.validateValue(value, field, config);
51
+ // if a node/field is of type object and thus is a subtree, add it to
52
+ // the stack to be traversed later
53
+ if (field.type === 'object') {
54
+ stack.push({
55
+ subSchema: field.children,
56
+ subConfig: value,
57
+ parentPath: path,
58
+ });
59
+ }
60
+ } catch (error) {
61
+ throw new Error(`${errorPreamble(path)}: ${error.message}`);
62
+ }
63
+ }
64
+ }
65
+ }
66
+ /**
67
+ * validates a value in config object
68
+ *
69
+ * @private
70
+ * @param {*} value
71
+ * @param {ConfigField} field the field specification in schema
72
+ * @param {Record<string, any>} config the config object
73
+ */
74
+ validateValue = (value, field, config) => {
75
+ if (value != undefined) {
76
+ if (field.type === 'bigint') {
77
+ value = BigInt(value);
78
+ } else if (field.type === 'number' && value && !isNaN(value)) {
79
+ value = Number(value);
80
+ }
81
+ valueValidators[field.type](value, field);
82
+ }
83
+ if (field.type != 'object' && field.validations) {
84
+ for (const validation of field.validations) {
85
+ const name = Object.keys(validation).filter(
86
+ (key) => key !== 'when' && key !== 'error'
87
+ )[0];
88
+ if (Object.hasOwn(valueValidations[field.type], name)) {
89
+ try {
90
+ valueValidations[field.type][name](value, validation, config, this);
91
+ } catch (error) {
92
+ if (validation.error != undefined) {
93
+ throw new Error(validation.error);
94
+ }
95
+ throw error;
96
+ }
97
+ }
98
+ }
99
+ }
100
+ };
101
+ /**
102
+ * determines if a when clause in validations section of a schema field is
103
+ * satisfied
104
+ *
105
+ * @param {When} when
106
+ * @param {Record<string, any>} config
107
+ * @return {boolean}
108
+ */
109
+ isWhenTrue = (when, config) => {
110
+ const pathParts = when.path.split('.');
111
+ const value = ConfigValidator.valueAt(config, pathParts);
112
+ return value != undefined && value === when.value;
113
+ };
114
+ /**
115
+ * returns the value at specified path in config object
116
+ *
117
+ * @static
118
+ * @param {Record<string, any>} config
119
+ * @param {string[]} path
120
+ * @return {*}
121
+ */
122
+ static valueAt = (config, path) => {
123
+ let value = config;
124
+ for (const key of path) {
125
+ if (value != undefined && Object.hasOwn(value, key)) {
126
+ value = value[key];
127
+ } else {
128
+ return undefined;
129
+ }
130
+ }
131
+ return value;
132
+ };
133
+ /**
134
+ * validates this.schema and throws exception if any errors found
135
+ */
136
+ validateSchema = () => {
137
+ const errorPreamble = (path) =>
138
+ `Schema validation failed for "${path.join('.')}" field`;
139
+ const stack = [
140
+ {
141
+ subSchema: this.schema,
142
+ parentPath: [],
143
+ },
144
+ ];
145
+ // Traverses the schema object tree depth first and validate fields
146
+ while (stack.length > 0) {
147
+ const { subSchema, parentPath } = stack.pop();
148
+ // process children of current object field
149
+ for (const name of Object.keys(subSchema).reverse()) {
150
+ const path = parentPath.concat([name]);
151
+ try {
152
+ this.validateConfigName(name);
153
+ const field = subSchema[name];
154
+ if (!Object.hasOwn(field, 'type') || typeof field.type !== 'string') {
155
+ throw new Error(
156
+ `every schema field must have a "type" property of type "string"`
157
+ );
158
+ }
159
+ if (!supportedTypes.includes(field.type)) {
160
+ throw new Error(`unsupported field type "${field.type}"`);
161
+ }
162
+ this.validateSchemaField(field);
163
+ // if the child is an object field itself add it to stack for
164
+ // processing
165
+ if (field.type === 'object') {
166
+ stack.push({
167
+ subSchema: field.children,
168
+ parentPath: path,
169
+ });
170
+ }
171
+ } catch (error) {
172
+ throw new Error(`${errorPreamble(path)}: ${error.message}`);
173
+ }
174
+ }
175
+ }
176
+ };
177
+ /**
178
+ * validates config key name
179
+ *
180
+ * @param {string} name
181
+ */
182
+ validateConfigName = (name) => {
183
+ if (name.includes('.')) {
184
+ throw new Error(`config key name can not contain the '.' character`);
185
+ }
186
+ };
187
+ /**
188
+ * validates passed schema field structure
189
+ *
190
+ * @param {ConfigField} field
191
+ */
192
+ validateSchemaField = (field) => {
193
+ for (const key of Object.keys(field)) {
194
+ if (
195
+ !Object.hasOwn(propertyValidators.all, key) &&
196
+ !(
197
+ field.type !== 'object' &&
198
+ Object.hasOwn(propertyValidators.primitive, key)
199
+ ) &&
200
+ !Object.hasOwn(propertyValidators[field.type], key)
201
+ ) {
202
+ throw new Error(`schema field has unknown property "${key}"`);
203
+ }
204
+ }
205
+ for (const validator of Object.values(propertyValidators.all)) {
206
+ validator(field, this);
207
+ }
208
+ if (field.type !== 'object') {
209
+ for (const validator of Object.values(propertyValidators.primitive)) {
210
+ validator(field, this);
211
+ }
212
+ }
213
+ for (const validator of Object.values(propertyValidators[field.type])) {
214
+ validator(field, this);
215
+ }
216
+ };
217
+ /**
218
+ * returns a field corresponding to a path in schema tree
219
+ *
220
+ * @param {string[]} path
221
+ * @return {(ConfigField | undefined)} returns undefined if field is not found
222
+ */
223
+ getSchemaField = (path) => {
224
+ let subTree = this.schema;
225
+ let field = undefined;
226
+ for (const part of path) {
227
+ if (subTree != undefined && Object.hasOwn(subTree, part)) {
228
+ field = subTree[part];
229
+ subTree = 'children' in field ? field.children : undefined;
230
+ } else {
231
+ return undefined;
232
+ }
233
+ }
234
+ return field;
235
+ };
236
+ /**
237
+ * extracts default values from a schema
238
+ *
239
+ * @return {Record<string, any>} object of default values
240
+ */
241
+ generateDefault = () => {
242
+ const valueTree = Object.create(null);
243
+ const stack = [
244
+ {
245
+ schema: this.schema,
246
+ parentValue: undefined,
247
+ fieldName: '',
248
+ children: Object.keys(this.schema).reverse(),
249
+ },
250
+ ];
251
+ // Traverses the schema object tree depth first
252
+ while (stack.length > 0) {
253
+ const { schema, parentValue, fieldName, children } = stack.at(-1);
254
+ // if a subtree's processing is finished go to the previous level
255
+ if (children.length === 0) {
256
+ // if a subtree is empty (has no values) remove it from the result
257
+ if (
258
+ parentValue != undefined &&
259
+ Object.keys(parentValue[fieldName]).length === 0
260
+ ) {
261
+ delete parentValue[fieldName];
262
+ }
263
+ stack.pop();
264
+ continue;
265
+ }
266
+ const childName = children.pop();
267
+ const value =
268
+ parentValue != undefined ? parentValue[fieldName] : valueTree;
269
+ const field = schema[childName];
270
+ // if a node/field is of type object and thus is a subtree, add it both to
271
+ // value tree and to the stack to be traversed later. Otherwise it's a
272
+ // leaf and needs no traversal, so add it only to the value tree.
273
+ if (field.type === 'object') {
274
+ value[childName] = Object.create(null);
275
+ stack.push({
276
+ schema: field.children,
277
+ parentValue: value,
278
+ fieldName: childName,
279
+ children: Object.keys(field.children).reverse(),
280
+ });
281
+ } else if (field.default != undefined) {
282
+ value[childName] = field.default;
283
+ }
284
+ }
285
+ return valueTree;
286
+ };
287
+ /**
288
+ * generates compatible TypeScript interface for this instance's schema
289
+ *
290
+ * @param {string} name the name of root type
291
+ * @return {string}
292
+ */
293
+ generateTSTypes = (name) => {
294
+ const errorPreamble = (path) =>
295
+ `TypeScript type generation failed for "${path.join('.')}" field`;
296
+ const types = [];
297
+ const typeNames = new Map();
298
+ typeNames.set(name, 1n);
299
+ const stack = [
300
+ {
301
+ subSchema: this.schema,
302
+ children: Object.keys(this.schema),
303
+ parentPath: [],
304
+ typeName: name,
305
+ attributes: [],
306
+ },
307
+ ];
308
+ // Traverses the schema object tree depth first
309
+ while (stack.length > 0) {
310
+ const { subSchema, children, parentPath, typeName, attributes } =
311
+ stack.at(-1);
312
+ const path = parentPath.concat([name]);
313
+ try {
314
+ // if a subtree's processing is finished go to the previous level
315
+ if (children.length == 0) {
316
+ types.push(this.genTSInterface(typeName, attributes));
317
+ stack.pop();
318
+ continue;
319
+ }
320
+ const childName = children.pop();
321
+ const field = subSchema[childName];
322
+ // if a node/field is of type object and thus is a subtree, add it to
323
+ // the stack to be traversed later. Otherwise it's a leaf and needs no
324
+ // traversal.
325
+ if (field.type === 'object') {
326
+ let childTypeName = `${childName[0].toUpperCase()}${childName.substring(
327
+ 1
328
+ )}`;
329
+ const typeNameCount = typeNames.get(childTypeName);
330
+ typeNames.set(childTypeName, (typeNames.get(childName) || 0n) + 1n);
331
+ if (typeNameCount) {
332
+ childTypeName += typeNameCount.toString();
333
+ }
334
+ stack.push({
335
+ subSchema: field.children,
336
+ children: Object.keys(field.children).reverse(),
337
+ parentPath: path,
338
+ typeName: childTypeName,
339
+ attributes: [],
340
+ });
341
+ attributes.push([childName, childTypeName]);
342
+ } else {
343
+ attributes.push([childName, field.type]);
344
+ }
345
+ } catch (error) {
346
+ throw new Error(`${errorPreamble(path)}: ${error.message}`);
347
+ }
348
+ }
349
+ return types.reverse().join('\n\n') + '\n';
350
+ };
351
+ /**
352
+ * generates a TypeScript interface definition for passed name and attributes
353
+ *
354
+ * @param {string} name
355
+ * @param {Array<[string, string]>} attributes
356
+ * @return {string}
357
+ */
358
+ genTSInterface = (name, attributes) => {
359
+ return `interface ${name} {
360
+ ${attributes.map((attr) => `${attr[0]}: ${attr[1]};`).join('\n ')}
361
+ }`;
362
+ };
363
+ /**
364
+ * returns a characteristic object for values at a specific node config level
365
+ *
366
+ * @param {IConfig} config
367
+ * @param {string} level
368
+ * @return {Record<string, any>}
369
+ */
370
+ getConfigForLevel(config, level) {
371
+ const confLevels = ConfigValidator.getNodeConfigLevels(config);
372
+ const levelIndex = confLevels.indexOf(level);
373
+ if (levelIndex === -1) {
374
+ throw new Error(
375
+ `The "${level}" level not found in the current system configuration levels`
376
+ );
377
+ }
378
+ const higherLevelSources = config.util
379
+ .getConfigSources()
380
+ .filter(
381
+ (source) => confLevels.indexOf(getSourceName(source)) > levelIndex
382
+ );
383
+ const currentLevelSource = config.util
384
+ .getConfigSources()
385
+ .filter((source) => getSourceName(source) === level)
386
+ .at(0);
387
+ const lowerLevelSources = config.util
388
+ .getConfigSources()
389
+ .filter(
390
+ (source) => confLevels.indexOf(getSourceName(source)) < levelIndex
391
+ );
392
+ // Traverses the schema object tree depth first
393
+ const valueTree = ConfigValidator.processConfigForLevelNode(
394
+ this.schema,
395
+ [],
396
+ higherLevelSources,
397
+ currentLevelSource,
398
+ lowerLevelSources
399
+ );
400
+ return valueTree;
401
+ }
402
+ /**
403
+ *traverses the config schema depth first to produce characteristic object
404
+ *
405
+ * @private
406
+ * @static
407
+ * @param {ConfigSchema} schema
408
+ * @param {string[]} path
409
+ * @param {IConfigSource[]} higherLevelSources
410
+ * @param {(IConfigSource | undefined)} currentLevelSource
411
+ * @param {IConfigSource[]} lowerLevelSources
412
+ * @return {Record<string, any>}
413
+ * @memberof ConfigValidator
414
+ */
415
+ static processConfigForLevelNode(
416
+ schema,
417
+ path,
418
+ higherLevelSources,
419
+ currentLevelSource,
420
+ lowerLevelSources
421
+ ) {
422
+ const value = Object.create(null);
423
+ for (const childName of Object.keys(schema).reverse()) {
424
+ const childPath = path.concat([childName]);
425
+ const field = schema[childName];
426
+ // if a field is of type object and thus is a subtree, recurse on it.
427
+ // Otherwise it's a leaf and needs no traversal.
428
+ value[childName] = Object.create(null);
429
+ if (field.type === 'object') {
430
+ value[childName] = ConfigValidator.processConfigForLevelNode(
431
+ field.children,
432
+ childPath,
433
+ higherLevelSources,
434
+ currentLevelSource,
435
+ lowerLevelSources
436
+ );
437
+ } else {
438
+ value[childName]['label'] =
439
+ field.label != undefined ? field.label : null;
440
+ value[childName]['description'] =
441
+ field.description != undefined ? field.description : null;
442
+ value[childName]['default'] = getValueFromConfigSources(
443
+ lowerLevelSources,
444
+ childPath
445
+ );
446
+ value[childName]['value'] = getValueFromConfigSources(
447
+ [...(currentLevelSource != undefined ? [currentLevelSource] : [])],
448
+ childPath
449
+ );
450
+ value[childName]['override'] = getValueFromConfigSources(
451
+ higherLevelSources,
452
+ childPath
453
+ );
454
+ }
455
+ }
456
+ return value;
457
+ }
458
+ /**
459
+ * returns a list of config sources used by node config package, ordered from
460
+ * the lowest to the highest priority
461
+ *
462
+ * @static
463
+ * @param {IConfig} config
464
+ * @return {string[]}
465
+ */
466
+ static getNodeConfigLevels = (config) => {
467
+ const instance = config.util.getEnv('NODE_APP_INSTANCE');
468
+ let deployment = config.util.getEnv('NODE_ENV');
469
+ deployment = config.util.getEnv('NODE_CONFIG_ENV');
470
+ const fullHostname = config.util.getEnv('HOSTNAME');
471
+ const shortHostname =
472
+ fullHostname != undefined ? fullHostname.split('.')[0] : undefined;
473
+ const configLevels = [
474
+ 'default',
475
+ ...(instance != undefined ? [`default-${instance}`] : []),
476
+ ...(deployment != undefined ? [`${deployment}`] : []),
477
+ ...(instance != undefined && deployment != undefined
478
+ ? [`${deployment}-${instance}`]
479
+ : []),
480
+ ...(shortHostname != undefined ? [`${shortHostname}`] : []),
481
+ ...(shortHostname != undefined && instance != undefined
482
+ ? [`${shortHostname}-${instance}`]
483
+ : []),
484
+ ...(shortHostname != undefined && deployment != undefined
485
+ ? [`${shortHostname}-${deployment}`]
486
+ : []),
487
+ ...(shortHostname != undefined &&
488
+ deployment != undefined &&
489
+ instance != undefined
490
+ ? [`${shortHostname}-${deployment}-${instance}`]
491
+ : []),
492
+ ...(fullHostname != undefined ? [`${fullHostname}`] : []),
493
+ ...(fullHostname != undefined && instance != undefined
494
+ ? [`${fullHostname}-${instance}`]
495
+ : []),
496
+ ...(fullHostname != undefined && deployment != undefined
497
+ ? [`${fullHostname}-${deployment}`]
498
+ : []),
499
+ ...(fullHostname != undefined &&
500
+ deployment != undefined &&
501
+ instance != undefined
502
+ ? [`${fullHostname}-${deployment}-${instance}`]
503
+ : []),
504
+ `local`,
505
+ ...(instance != undefined ? [`local-${instance}`] : []),
506
+ ...(deployment != undefined ? [`local-${deployment}`] : []),
507
+ ...(deployment != undefined && instance != undefined
508
+ ? [`local-${deployment}-${instance}`]
509
+ : []),
510
+ '$NODE_CONFIG',
511
+ 'custom-environment-variables',
512
+ ];
513
+ return configLevels;
514
+ };
515
+ /**
516
+ * validates a config object and writes it to the node-config file
517
+ * corresponding to the passed level
518
+ *
519
+ * @param {Record<string, any>} configObj
520
+ * @param {IConfig} config
521
+ * @param {string} level output node-config file level
522
+ * @param {string} format the format of the output file
523
+ */
524
+ validateAndWriteConfig = (configObj, config, level, format) => {
525
+ const confLevels = ConfigValidator.getNodeConfigLevels(config).filter(
526
+ (l) => l !== 'custom-environment-variables'
527
+ );
528
+ const levelIndex = confLevels.indexOf(level);
529
+ if (levelIndex === -1) {
530
+ throw new Error(
531
+ `The [${level}] level not found in the current system's configuration levels`
532
+ );
533
+ }
534
+ const configDir =
535
+ process.env['NODE_CONFIG_DIR'] != undefined
536
+ ? process.env['NODE_CONFIG_DIR']
537
+ : './config';
538
+ let output = '';
539
+ let ext = '';
540
+ switch (format) {
541
+ case 'json': {
542
+ const JsonBigInt = JsonBigIntFactory({
543
+ alwaysParseAsBig: false,
544
+ useNativeBigInt: true,
545
+ });
546
+ output = JsonBigInt.stringify(configObj);
547
+ ext = 'json';
548
+ break;
549
+ }
550
+ case 'yaml': {
551
+ output = yaml.dump(configObj);
552
+ ext = 'yaml';
553
+ break;
554
+ }
555
+ default:
556
+ throw Error(`Invalid format: ${format}`);
557
+ }
558
+ const outputPath = path.join(configDir, `${level}.${ext}`);
559
+ const backupPath = path.join(configDir, `${level}-backup.${ext}`);
560
+ const confFileExists = fs.existsSync(outputPath);
561
+ if (confFileExists) {
562
+ fs.renameSync(outputPath, backupPath);
563
+ }
564
+ fs.writeFileSync(outputPath, output);
565
+ const updatedConfObj = config.util.loadFileConfigs();
566
+ try {
567
+ this.validateConfig(updatedConfObj);
568
+ fs.unlinkSync(backupPath);
569
+ } catch (error) {
570
+ fs.unlinkSync(outputPath);
571
+ if (confFileExists) {
572
+ fs.renameSync(backupPath, outputPath);
573
+ }
574
+ throw error;
575
+ }
576
+ };
577
+ }
578
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vbGliL2NvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEtBQUssRUFBRSxNQUFNLElBQUksQ0FBQztBQUN6QixPQUFPLEtBQUssSUFBSSxNQUFNLFNBQVMsQ0FBQztBQUNoQyxPQUFPLGlCQUFpQixNQUFNLGFBQWEsQ0FBQztBQUM1QyxPQUFPLElBQUksTUFBTSxNQUFNLENBQUM7QUFDeEIsT0FBTyxFQUNMLGtCQUFrQixFQUNsQixjQUFjLEdBQ2YsTUFBTSxxQ0FBcUMsQ0FBQztBQUc3QyxPQUFPLEVBQUUsYUFBYSxFQUFFLHlCQUF5QixFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ25FLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxlQUFlLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUV2RSxNQUFNLE9BQU8sZUFBZTtJQUNOO0lBQXBCLFlBQW9CLE1BQW9CO1FBQXBCLFdBQU0sR0FBTixNQUFNLENBQWM7UUFDdEMsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO0lBQ3hCLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ksY0FBYyxDQUFDLE1BQTJCO1FBQy9DLE1BQU0sYUFBYSxHQUFHLENBQUMsSUFBbUIsRUFBRSxFQUFFLENBQzVDLGlDQUFpQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUM7UUFFM0QsTUFBTSxLQUFLLEdBSU47WUFDSDtnQkFDRSxTQUFTLEVBQUUsSUFBSSxDQUFDLE1BQU07Z0JBQ3RCLFNBQVMsRUFBRSxNQUFNO2dCQUNqQixVQUFVLEVBQUUsRUFBRTthQUNmO1NBQ0YsQ0FBQztRQUVGLElBQUksQ0FBQyxhQUFhLENBQ2hCLE1BQU0sRUFDTixFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsRUFDekMsTUFBTSxDQUNQLENBQUM7UUFFRiwyRUFBMkU7UUFDM0UsbURBQW1EO1FBQ25E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QUMsVUFBVSxDQUFDLENBQUM7UUFDakQsSUFBSSxjQUFjLEVBQUU7WUFDbEIsRUFBRSxDQUFDLFVBQVUsQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDLENBQUM7U0FDdkM7UUFDRCxFQUFFLENBQUMsYUFBYSxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUVyQyxNQUFNLGNBQWMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBRXJELElBQUk7WUFDRixJQUFJLENBQUMsY0FBYyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBQ3BDLEVBQUUsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUM7U0FDM0I7UUFBQyxPQUFPLEtBQUssRUFBRTtZQUNkLEVBQUUsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDMUIsSUFBSSxjQUFjLEVBQUU7Z0JBQ2xCLEVBQUUsQ0FBQyxVQUFVLENBQUMsVUFBVSxFQUFFLFVBQVUsQ0FBQyxDQUFDO2FBQ3ZDO1lBQ0QsTUFBTSxLQUFLLENBQUM7U0FDYjtJQUNILENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IElDb25maWcsIElDb25maWdTb3VyY2UgfSBmcm9tICdjb25maWcnO1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgeWFtbCBmcm9tICdqcy15YW1sJztcbmltcG9ydCBKc29uQmlnSW50RmFjdG9yeSBmcm9tICdqc29uLWJpZ2ludCc7XG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7XG4gIHByb3BlcnR5VmFsaWRhdG9ycyxcbiAgc3VwcG9ydGVkVHlwZXMsXG59IGZyb20gJy4vc2NoZW1hL1ZhbGlkYXRvcnMvZmllbGRQcm9wZXJ0aWVzJztcbmltcG9ydCB7IENvbmZpZ0ZpZWxkLCBDb25maWdTY2hlbWEgfSBmcm9tICcuL3NjaGVtYS90eXBlcy9maWVsZHMnO1xuaW1wb3J0IHsgV2hlbiB9IGZyb20gJy4vc2NoZW1hL3R5cGVzL3ZhbGlkYXRpb25zJztcbmltcG9ydCB7IGdldFNvdXJjZU5hbWUsIGdldFZhbHVlRnJvbUNvbmZpZ1NvdXJjZXMgfSBmcm9tICcuL3V0aWxzJztcbmltcG9ydCB7IHZhbHVlVmFsaWRhdGlvbnMsIHZhbHVlVmFsaWRhdG9ycyB9IGZyb20gJy4vdmFsdWUvdmFsaWRhdG9ycyc7XG5cbmV4cG9ydCBjbGFzcyBDb25maWdWYWxpZGF0b3Ige1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHNjaGVtYTogQ29uZmlnU2NoZW1hKSB7XG4gICAgdGhpcy52YWxpZGF0ZVNjaGVtYSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIHZhbGlkYXRlcyB0aGUgcGFzc2VkIGNvbmZpZyBhZ2FpbnN0IHRoZSBpbnN0YW5jZSdzIHNjaGVtYVxuICAgKlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IGNvbmZpZ1xuICAgKi9cbiAgcHVibGljIHZhbGlkYXRlQ29uZmlnKGNvbmZpZzogUmVjb3JkPHN0cmluZywgYW55Pikge1xuICAgIGNvbnN0IGVycm9yUHJlYW1ibGUgPSAocGF0aDogQXJyYXk8c3RyaW5nPikgPT5cbiAgICAgIGBjb25maWcgdmFsaWRhdGlvbiBmYWlsZWQgZm9yIFwiJHtwYXRoLmpvaW4oJy4nKX1cIiBmaWVsZGA7XG5cbiAgICBjb25zdCBzdGFjazogQXJyYXk8e1xuICAgICAgc3ViU2NoZW1hOiBDb25maWdTY2hlbWE7XG4gICAgICBzdWJDb25maWc6IFJlY29yZDxzdHJpbmcsIGFueT4gfCB1bmRlZmluZWQ7XG4gICAgICBwYXJlbnRQYXRoOiBBcnJheTxzdHJpbmc+O1xuICAgIH0+ID0gW1xuICAgICAge1xuICAgICAgICBzdWJTY2hlbWE6IHRoaXMuc2NoZW1hLFxuICAgICAgICBzdWJDb25maWc6IGNvbmZpZyxcbiAgICAgICAgcGFyZW50UGF0aDogW10sXG4gICAgICB9LFxuICAgIF07XG5cbiAgICB0aGlzLnZhbGlkYXRlVmFsdWUoXG4gICAgICBjb25maWcsXG4gICAgICB7IHR5cGU6ICdvYmplY3QnLCBjaGlsZHJlbjogdGhpcy5zY2hlbWEgfSxcbiAgICAgIGNvbmZpZ1xuICAgICk7XG5cbiAgICAvLyBUcmF2ZXJzZXMgdGhlIHNjaGVtYSBvYmplY3QgdHJlZSBkZXB0aCBmaXJzdCBpbiBjb29yZGluYXRpb24gd2l0aCBjb25maWdcbiAgICAvLyBvYmplY3QgdHJlZSBhbmQgdmFsaWRhdGUgY29uZmlnIHVzaW5nIHRoZSBzY2hlbWFcbiAgICB3aGlsZSAoc3RhY2subGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgeyBzdWJTY2hlbWEsIHN1YkNvbmZpZywgcGFyZW50UGF0aCB9ID0gc3RhY2sucG9wKCkhO1xuICAgICAgLy8gUHJvY2VzcyBjaGlsZHJlbiBvZiBjdXJyZW50IGZpZWxkXG4gICAgICBmb3IgKGNvbnN0IG5hbWUgb2YgT2JqZWN0LmtleXMoc3ViU2NoZW1hKSkge1xuICAgICAgICBjb25zdCBwYXRoID0gcGFyZW50UGF0aC5jb25jYXQoW25hbWVdKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBmaWVsZCA9IHN1YlNjaGVtYVtuYW1lXTtcbiAgICAgICAgICBsZXQgdmFsdWUgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgaWYgKHN1YkNvbmZpZyAhPSB1bmRlZmluZWQgJiYgT2JqZWN0Lmhhc093bihzdWJDb25maWcsIG5hbWUpKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IHN1YkNvbmZpZ1tuYW1lXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLnZhbGlkYXRlVmFsdWUodmFsdWUsIGZpZWxkLCBjb25maWcpO1xuXG4gICAgICAgICAgLy8gaWYgYSBub2RlL2ZpZWxkIGlzIG9mIHR5cGUgb2JqZWN0IGFuZCB0aHVzIGlzIGEgc3VidHJlZSwgYWRkIGl0IHRvXG4gICAgICAgICAgLy8gdGhlIHN0YWNrIHRvIGJlIHRyYXZlcnNlZCBsYXRlclxuICAgICAgICAgIGlmIChmaWVsZC50eXBlID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgc3RhY2sucHVzaCh7XG4gICAgICAgICAgICAgIHN1YlNjaGVtYTogZmllbGQuY2hpbGRyZW4sXG4gICAgICAgICAgICAgIHN1YkNvbmZpZzogdmFsdWUsXG4gICAgICAgICAgICAgIHBhcmVudFBhdGg6IHBhdGgsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7ZXJyb3JQcmVhbWJsZShwYXRoKX06ICR7ZXJyb3IubWVzc2FnZX1gKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiB2YWxpZGF0ZXMgYSB2YWx1ZSBpbiBjb25maWcgb2JqZWN0XG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAgICogQHBhcmFtIHtDb25maWdGaWVsZH0gZmllbGQgdGhlIGZpZWxkIHNwZWNpZmljYXRpb24gaW4gc2NoZW1hXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gY29uZmlnIHRoZSBjb25maWcgb2JqZWN0XG4gICAqL1xuICBwcml2YXRlIHZhbGlkYXRlVmFsdWUgPSAoXG4gICAgdmFsdWU6IGFueSxcbiAgICBmaWVsZDogQ29uZmlnRmllbGQsXG4gICAgY29uZmlnOiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gICkgPT4ge1xuICAgIGlmICh2YWx1ZSAhPSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChmaWVsZC50eXBlID09PSAnYmlnaW50Jykge1xuICAgICAgICB2YWx1ZSA9IEJpZ0ludCh2YWx1ZSk7XG4gICAgICB9IGVsc2UgaWYgKGZpZWxkLnR5cGUgPT09ICdudW1iZXInICYmIHZhbHVlICYmICFpc05hTih2YWx1ZSkpIHtcbiAgICAgICAgdmFsdWUgPSBOdW1iZXIodmFsdWUpO1xuICAgICAgfVxuICAgICAgdmFsdWVWYWxpZGF0b3JzW2ZpZWxkLnR5cGVdKHZhbHVlLCBmaWVsZCk7XG4gICAgfVxuXG4gICAgaWYgKGZpZWxkLnR5cGUgIT0gJ29iamVjdCcgJiYgZmllbGQudmFsaWRhdGlvbnMpIHtcbiAgICAgIGZvciAoY29uc3QgdmFsaWRhdGlvbiBvZiBmaWVsZC52YWxpZGF0aW9ucykge1xuICAgICAgICBjb25zdCBuYW1lID0gT2JqZWN0LmtleXModmFsaWRhdGlvbikuZmlsdGVyKFxuICAgICAgICAgIChrZXkpID0+IGtleSAhPT0gJ3doZW4nICYmIGtleSAhPT0gJ2Vycm9yJ1xuICAgICAgICApWzBdO1xuICAgICAgICBpZiAoT2JqZWN0Lmhhc093bih2YWx1ZVZhbGlkYXRpb25zW2ZpZWxkLnR5cGVdLCBuYW1lKSkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICB2YWx1ZVZhbGlkYXRpb25zW2ZpZWxkLnR5cGVdW25hbWVdKHZhbHVlLCB2YWxpZGF0aW9uLCBjb25maWcsIHRoaXMpO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgICAgIGlmICh2YWxpZGF0aW9uLmVycm9yICE9IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IodmFsaWRhdGlvbi5lcnJvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIGRldGVybWluZXMgaWYgYSB3aGVuIGNsYXVzZSBpbiB2YWxpZGF0aW9ucyBzZWN0aW9uIG9mIGEgc2NoZW1hIGZpZWxkIGlzXG4gICAqIHNhdGlzZmllZFxuICAgKlxuICAgKiBAcGFyYW0ge1doZW59IHdoZW5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBjb25maWdcbiAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICovXG4gIHB1YmxpYyBpc1doZW5UcnVlID0gKHdoZW46IFdoZW4sIGNvbmZpZzogUmVjb3JkPHN0cmluZywgYW55Pik6IGJvb2xlYW4gPT4ge1xuICAgIGNvbnN0IHBhdGhQYXJ0cyA9IHdoZW4ucGF0aC5zcGxpdCgnLicpO1xuICAgIGNvbnN0IHZhbHVlID0gQ29uZmlnVmFsaWRhdG9yLnZhbHVlQXQoY29uZmlnLCBwYXRoUGFydHMpO1xuICAgIHJldHVybiB2YWx1ZSAhPSB1bmRlZmluZWQgJiYgdmFsdWUgPT09IHdoZW4udmFsdWU7XG4gIH07XG5cbiAgLyoqXG4gICAqIHJldHVybnMgdGhlIHZhbHVlIGF0IHNwZWNpZmllZCBwYXRoIGluIGNvbmZpZyBvYmplY3RcbiAgICpcbiAgICogQHN0YXRpY1xuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IGNvbmZpZ1xuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBwYXRoXG4gICAqIEByZXR1cm4geyp9XG4gICAqL1xuICBzdGF0aWMgdmFsdWVBdCA9IChjb25maWc6IFJlY29yZDxzdHJpbmcsIGFueT4sIHBhdGg6IHN0cmluZ1tdKSA9PiB7XG4gICAgbGV0IHZhbHVlOiBhbnkgPSBjb25maWc7XG4gICAgZm9yIChjb25zdCBrZXkgb2YgcGF0aCkge1xuICAgICAgaWYgKHZhbHVlICE9IHVuZGVmaW5lZCAmJiBPYmplY3QuaGFzT3duKHZhbHVlLCBrZXkpKSB7XG4gICAgICAgIHZhbHVlID0gdmFsdWVba2V5XTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlO1xuICB9O1xuXG4gIC8qKlxuICAgKiB2YWxpZGF0ZXMgdGhpcy5zY2hlbWEgYW5kIHRocm93cyBleGNlcHRpb24gaWYgYW55IGVycm9ycyBmb3VuZFxuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZVNjaGVtYSA9ICgpID0+IHtcbiAgICBjb25zdCBlcnJvclByZWFtYmxlID0gKHBhdGg6IEFycmF5PHN0cmluZz4pID0+XG4gICAgICBgU2NoZW1hIHZhbGlkYXRpb24gZmFpbGVkIGZvciBcIiR7cGF0aC5qb2luKCcuJyl9XCIgZmllbGRgO1xuXG4gICAgY29uc3Qgc3RhY2s6IEFycmF5PHtcbiAgICAgIHN1YlNjaGVtYTogQ29uZmlnU2NoZW1hO1xuICAgICAgcGFyZW50UGF0aDogQXJyYXk8c3RyaW5nPjtcbiAgICB9PiA9IFtcbiAgICAgIHtcbiAgICAgICAgc3ViU2NoZW1hOiB0aGlzLnNjaGVtYSxcbiAgICAgICAgcGFyZW50UGF0aDogW10sXG4gICAgICB9LFxuICAgIF07XG5cbiAgICAvLyBUcmF2ZXJzZXMgdGhlIHNjaGVtYSBvYmplY3QgdHJlZSBkZXB0aCBmaXJzdCBhbmQgdmFsaWRhdGUgZmllbGRzXG4gICAgd2hpbGUgKHN0YWNrLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IHsgc3ViU2NoZW1hLCBwYXJlbnRQYXRoIH0gPSBzdGFjay5wb3AoKSE7XG5cbiAgICAgIC8vIHByb2Nlc3MgY2hpbGRyZW4gb2YgY3VycmVudCBvYmplY3QgZmllbGRcbiAgICAgIGZvciAoY29uc3QgbmFtZSBvZiBPYmplY3Qua2V5cyhzdWJTY2hlbWEpLnJldmVyc2UoKSkge1xuICAgICAgICBjb25zdCBwYXRoID0gcGFyZW50UGF0aC5jb25jYXQoW25hbWVdKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB0aGlzLnZhbGlkYXRlQ29uZmlnTmFtZShuYW1lKTtcbiAgICAgICAgICBjb25zdCBmaWVsZCA9IHN1YlNjaGVtYVtuYW1lXTtcblxuICAgICAgICAgIGlmICghT2JqZWN0Lmhhc093bihmaWVsZCwgJ3R5cGUnKSB8fCB0eXBlb2YgZmllbGQudHlwZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgYGV2ZXJ5IHNjaGVtYSBmaWVsZCBtdXN0IGhhdmUgYSBcInR5cGVcIiBwcm9wZXJ0eSBvZiB0eXBlIFwic3RyaW5nXCJgXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICghc3VwcG9ydGVkVHlwZXMuaW5jbHVkZXMoZmllbGQudHlwZSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgdW5zdXBwb3J0ZWQgZmllbGQgdHlwZSBcIiR7ZmllbGQudHlwZX1cImApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMudmFsaWRhdGVTY2hlbWFGaWVsZChmaWVsZCk7XG5cbiAgICAgICAgICAvLyBpZiB0aGUgY2hpbGQgaXMgYW4gb2JqZWN0IGZpZWxkIGl0c2VsZiBhZGQgaXQgdG8gc3RhY2sgZm9yXG4gICAgICAgICAgLy8gcHJvY2Vzc2luZ1xuICAgICAgICAgIGlmIChmaWVsZC50eXBlID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgc3RhY2sucHVzaCh7XG4gICAgICAgICAgICAgIHN1YlNjaGVtYTogZmllbGQuY2hpbGRyZW4sXG4gICAgICAgICAgICAgIHBhcmVudFBhdGg6IHBhdGgsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7ZXJyb3JQcmVhbWJsZShwYXRoKX06ICR7ZXJyb3IubWVzc2FnZX1gKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogdmFsaWRhdGVzIGNvbmZpZyBrZXkgbmFtZVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZUNvbmZpZ05hbWUgPSAobmFtZTogc3RyaW5nKSA9PiB7XG4gICAgaWYgKG5hbWUuaW5jbHVkZXMoJy4nKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBjb25maWcga2V5IG5hbWUgY2FuIG5vdCBjb250YWluIHRoZSAnLicgY2hhcmFjdGVyYCk7XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiB2YWxpZGF0ZXMgcGFzc2VkIHNjaGVtYSBmaWVsZCBzdHJ1Y3R1cmVcbiAgICpcbiAgICogQHBhcmFtIHtDb25maWdGaWVsZH0gZmllbGRcbiAgICovXG4gIHByaXZhdGUgdmFsaWRhdGVTY2hlbWFGaWVsZCA9IChmaWVsZDogQ29uZmlnRmllbGQpID0+IHtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhmaWVsZCkpIHtcbiAgICAgIGlmIChcbiAgICAgICAgIU9iamVjdC5oYXNPd24ocHJvcGVydHlWYWxpZGF0b3JzLmFsbCwga2V5KSAmJlxuICAgICAgICAhKFxuICAgICAgICAgIGZpZWxkLnR5cGUgIT09ICdvYmplY3QnICYmXG4gICAgICAgICAgT2JqZWN0Lmhhc093bihwcm9wZXJ0eVZhbGlkYXRvcnMucHJpbWl0aXZlLCBrZXkpXG4gICAgICAgICkgJiZcbiAgICAgICAgIU9iamVjdC5oYXNPd24ocHJvcGVydHlWYWxpZGF0b3JzW2ZpZWxkLnR5cGVdLCBrZXkpXG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBzY2hlbWEgZmllbGQgaGFzIHVua25vd24gcHJvcGVydHkgXCIke2tleX1cImApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgdmFsaWRhdG9yIG9mIE9iamVjdC52YWx1ZXMocHJvcGVydHlWYWxpZGF0b3JzLmFsbCkpIHtcbiAgICAgIHZhbGlkYXRvcihmaWVsZCwgdGhpcyk7XG4gICAgfVxuXG4gICAgaWYgKGZpZWxkLnR5cGUgIT09ICdvYmplY3QnKSB7XG4gICAgICBmb3IgKGNvbnN0IHZhbGlkYXRvciBvZiBPYmplY3QudmFsdWVzKHByb3BlcnR5VmFsaWRhdG9ycy5wcmltaXRpdmUpKSB7XG4gICAgICAgIHZhbGlkYXRvcihmaWVsZCwgdGhpcyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCB2YWxpZGF0b3Igb2YgT2JqZWN0LnZhbHVlcyhwcm9wZXJ0eVZhbGlkYXRvcnNbZmllbGQudHlwZV0pKSB7XG4gICAgICB2YWxpZGF0b3IoZmllbGQsIHRoaXMpO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogcmV0dXJucyBhIGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gYSBwYXRoIGluIHNjaGVtYSB0cmVlXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IHBhdGhcbiAgICogQHJldHVybiB7KENvbmZpZ0ZpZWxkIHwgdW5kZWZpbmVkKX0gcmV0dXJucyB1bmRlZmluZWQgaWYgZmllbGQgaXMgbm90IGZvdW5kXG4gICAqL1xuICBnZXRTY2hlbWFGaWVsZCA9IChwYXRoOiBzdHJpbmdbXSk6IENvbmZpZ0ZpZWxkIHwgdW5kZWZpbmVkID0+IHtcbiAgICBsZXQgc3ViVHJlZTogQ29uZmlnU2NoZW1hIHwgdW5kZWZpbmVkID0gdGhpcy5zY2hlbWE7XG4gICAgbGV0IGZpZWxkOiBDb25maWdGaWVsZCB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICBmb3IgKGNvbnN0IHBhcnQgb2YgcGF0aCkge1xuICAgICAgaWYgKHN1YlRyZWUgIT0gdW5kZWZpbmVkICYmIE9iamVjdC5oYXNPd24oc3ViVHJlZSwgcGFydCkpIHtcbiAgICAgICAgZmllbGQgPSBzdWJUcmVlW3BhcnRdO1xuICAgICAgICBzdWJUcmVlID0gJ2NoaWxkcmVuJyBpbiBmaWVsZCA/IGZpZWxkLmNoaWxkcmVuIDogdW5kZWZpbmVkO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZpZWxkO1xuICB9O1xuXG4gIC8qKlxuICAgKiBleHRyYWN0cyBkZWZhdWx0IHZhbHVlcyBmcm9tIGEgc2NoZW1hXG4gICAqXG4gICAqIEByZXR1cm4ge1JlY29yZDxzdHJpbmcsIGFueT59IG9iamVjdCBvZiBkZWZhdWx0IHZhbHVlc1xuICAgKi9cbiAgZ2VuZXJhdGVEZWZhdWx0ID0gKCk6IFJlY29yZDxzdHJpbmcsIGFueT4gPT4ge1xuICAgIGNvbnN0IHZhbHVlVHJlZTogUmVjb3JkPHN0cmluZywgYW55PiA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5cbiAgICBjb25zdCBzdGFjazoge1xuICAgICAgc2NoZW1hOiBDb25maWdTY2hlbWE7XG4gICAgICBwYXJlbnRWYWx1ZTogUmVjb3JkPHN0cmluZywgYW55PiB8IHVuZGVmaW5lZDtcbiAgICAgIGZpZWxkTmFtZTogc3RyaW5nO1xuICAgICAgY2hpbGRyZW46IHN0cmluZ1tdO1xuICAgIH1bXSA9IFtcbiAgICAgIHtcbiAgICAgICAgc2NoZW1hOiB0aGlzLnNjaGVtYSxcbiAgICAgICAgcGFyZW50VmFsdWU6IHVuZGVmaW5lZCxcbiAgICAgICAgZmllbGROYW1lOiAnJyxcbiAgICAgICAgY2hpbGRyZW46IE9iamVjdC5rZXlzKHRoaXMuc2NoZW1hKS5yZXZlcnNlKCksXG4gICAgICB9LFxuICAgIF07XG5cbiAgICAvLyBUcmF2ZXJzZXMgdGhlIHNjaGVtYSBvYmplY3QgdHJlZSBkZXB0aCBmaXJzdFxuICAgIHdoaWxlIChzdGFjay5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCB7IHNjaGVtYSwgcGFyZW50VmFsdWUsIGZpZWxkTmFtZSwgY2hpbGRyZW4gfSA9IHN0YWNrLmF0KC0xKSE7XG5cbiAgICAgIC8vIGlmIGEgc3VidHJlZSdzIHByb2Nlc3NpbmcgaXMgZmluaXNoZWQgZ28gdG8gdGhlIHByZXZpb3VzIGxldmVsXG4gICAgICBpZiAoY2hpbGRyZW4ubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIC8vIGlmIGEgc3VidHJlZSBpcyBlbXB0eSAoaGFzIG5vIHZhbHVlcykgcmVtb3ZlIGl0IGZyb20gdGhlIHJlc3VsdFxuICAgICAgICBpZiAoXG4gICAgICAgICAgcGFyZW50VmFsdWUgIT0gdW5kZWZpbmVkICYmXG4gICAgICAgICAgT2JqZWN0LmtleXMocGFyZW50VmFsdWVbZmllbGROYW1lXSkubGVuZ3RoID09PSAwXG4gICAgICAgICkge1xuICAgICAgICAgIGRlbGV0ZSBwYXJlbnRWYWx1ZVtmaWVsZE5hbWVdO1xuICAgICAgICB9XG4gICAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgY2hpbGROYW1lID0gY2hpbGRyZW4ucG9wKCkhO1xuICAgICAgY29uc3QgdmFsdWUgPVxuICAgICAgICBwYXJlbnRWYWx1ZSAhPSB1bmRlZmluZWQgPyBwYXJlbnRWYWx1ZVtmaWVsZE5hbWVdIDogdmFsdWVUcmVlO1xuICAgICAgY29uc3QgZmllbGQgPSBzY2hlbWFbY2hpbGROYW1lXTtcbiAgICAgIC8vIGlmIGEgbm9kZS9maWVsZCBpcyBvZiB0eXBlIG9iamVjdCBhbmQgdGh1cyBpcyBhIHN1YnRyZWUsIGFkZCBpdCBib3RoIHRvXG4gICAgICAvLyB2YWx1ZSB0cmVlIGFuZCB0byB0aGUgc3RhY2sgdG8gYmUgdHJhdmVyc2VkIGxhdGVyLiBPdGhlcndpc2UgaXQncyBhXG4gICAgICAvLyBsZWFmIGFuZCBuZWVkcyBubyB0cmF2ZXJzYWwsIHNvIGFkZCBpdCBvbmx5IHRvIHRoZSB2YWx1ZSB0cmVlLlxuICAgICAgaWYgKGZpZWxkLnR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIHZhbHVlW2NoaWxkTmFtZV0gPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICBzdGFjay5wdXNoKHtcbiAgICAgICAgICBzY2hlbWE6IGZpZWxkLmNoaWxkcmVuLFxuICAgICAgICAgIHBhcmVudFZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICBmaWVsZE5hbWU6IGNoaWxkTmFtZSxcbiAgICAgICAgICBjaGlsZHJlbjogT2JqZWN0LmtleXMoZmllbGQuY2hpbGRyZW4pLnJldmVyc2UoKSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKGZpZWxkLmRlZmF1bHQgIT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHZhbHVlW2NoaWxkTmFtZV0gPSBmaWVsZC5kZWZhdWx0O1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZVRyZWU7XG4gIH07XG5cbiAgLyoqXG4gICAqIGdlbmVyYXRlcyBjb21wYXRpYmxlIFR5cGVTY3JpcHQgaW50ZXJmYWNlIGZvciB0aGlzIGluc3RhbmNlJ3Mgc2NoZW1hXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIHRoZSBuYW1lIG9mIHJvb3QgdHlwZVxuICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAqL1xuICBnZW5lcmF0ZVRTVHlwZXMgPSAobmFtZTogc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgICBjb25zdCBlcnJvclByZWFtYmxlID0gKHBhdGg6IEFycmF5PHN0cmluZz4pID0+XG4gICAgICBgVHlwZVNjcmlwdCB0eXBlIGdlbmVyYXRpb24gZmFpbGVkIGZvciBcIiR7cGF0aC5qb2luKCcuJyl9XCIgZmllbGRgO1xuXG4gICAgY29uc3QgdHlwZXM6IEFycmF5PHN0cmluZz4gPSBbXTtcblxuICAgIGNvbnN0IHR5cGVOYW1lczogTWFwPHN0cmluZywgYmlnaW50PiA9IG5ldyBNYXA8c3RyaW5nLCBiaWdpbnQ+KCk7XG4gICAgdHlwZU5hbWVzLnNldChuYW1lLCAxbik7XG5cbiAgICBjb25zdCBzdGFjazogQXJyYXk8e1xuICAgICAgc3ViU2NoZW1hOiBDb25maWdTY2hlbWE7XG4gICAgICBjaGlsZHJlbjogc3RyaW5nW107XG4gICAgICBwYXJlbnRQYXRoOiBBcnJheTxzdHJpbmc+O1xuICAgICAgdHlwZU5hbWU6IHN0cmluZztcbiAgICAgIGF0dHJpYnV0ZXM6IEFycmF5PFtzdHJpbmcsIHN0cmluZ10+O1xuICAgIH0+ID0gW1xuICAgICAge1xuICAgICAgICBzdWJTY2hlbWE6IHRoaXMuc2NoZW1hLFxuICAgICAgICBjaGlsZHJlbjogT2JqZWN0LmtleXModGhpcy5zY2hlbWEpLFxuICAgICAgICBwYXJlbnRQYXRoOiBbXSxcbiAgICAgICAgdHlwZU5hbWU6IG5hbWUsXG4gICAgICAgIGF0dHJpYnV0ZXM6IFtdLFxuICAgICAgfSxcbiAgICBdO1xuXG4gICAgLy8gVHJhdmVyc2VzIHRoZSBzY2hlbWEgb2JqZWN0IHRyZWUgZGVwdGggZmlyc3RcbiAgICB3aGlsZSAoc3RhY2subGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgeyBzdWJTY2hlbWEsIGNoaWxkcmVuLCBwYXJlbnRQYXRoLCB0eXBlTmFtZSwgYXR0cmlidXRlcyB9ID1cbiAgICAgICAgc3RhY2suYXQoLTEpITtcbiAgICAgIGNvbnN0IHBhdGggPSBwYXJlbnRQYXRoLmNvbmNhdChbbmFtZV0pO1xuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gaWYgYSBzdWJ0cmVlJ3MgcHJvY2Vzc2luZyBpcyBmaW5pc2hlZCBnbyB0byB0aGUgcHJldmlvdXMgbGV2ZWxcbiAgICAgICAgaWYgKGNoaWxkcmVuLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgICAgdHlwZXMucHVzaCh0aGlzLmdlblRTSW50ZXJmYWNlKHR5cGVOYW1lLCBhdHRyaWJ1dGVzKSk7XG4gICAgICAgICAgc3RhY2sucG9wKCk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjaGlsZE5hbWUgPSBjaGlsZHJlbi5wb3AoKSE7XG4gICAgICAgIGNvbnN0IGZpZWxkID0gc3ViU2NoZW1hW2NoaWxkTmFtZV07XG5cbiAgICAgICAgLy8gaWYgYSBub2RlL2ZpZWxkIGlzIG9mIHR5cGUgb2JqZWN0IGFuZCB0aHVzIGlzIGEgc3VidHJlZSwgYWRkIGl0IHRvXG4gICAgICAgIC8vIHRoZSBzdGFjayB0byBiZSB0cmF2ZXJzZWQgbGF0ZXIuIE90aGVyd2lzZSBpdCdzIGEgbGVhZiBhbmQgbmVlZHMgbm9cbiAgICAgICAgLy8gdHJhdmVyc2FsLlxuICAgICAgICBpZiAoZmllbGQudHlwZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICBsZXQgY2hpbGRUeXBlTmFtZSA9IGAke2NoaWxkTmFtZVswXS50b1VwcGVyQ2FzZSgpfSR7Y2hpbGROYW1lLnN1YnN0cmluZyhcbiAgICAgICAgICAgIDFcbiAgICAgICAgICApfWA7XG4gICAgICAgICAgY29uc3QgdHlwZU5hbWVDb3VudCA9IHR5cGVOYW1lcy5nZXQoY2hpbGRUeXBlTmFtZSk7XG4gICAgICAgICAgdHlwZU5hbWVzLnNldChjaGlsZFR5cGVOYW1lLCAodHlwZU5hbWVzLmdldChjaGlsZE5hbWUpIHx8IDBuKSArIDFuKTtcbiAgICAgICAgICBpZiAodHlwZU5hbWVDb3VudCkge1xuICAgICAgICAgICAgY2hpbGRUeXBlTmFtZSArPSB0eXBlTmFtZUNvdW50LnRvU3RyaW5nKCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc3RhY2sucHVzaCh7XG4gICAgICAgICAgICBzdWJTY2hlbWE6IGZpZWxkLmNoaWxkcmVuLFxuICAgICAgICAgICAgY2hpbGRyZW46IE9iamVjdC5rZXlzKGZpZWxkLmNoaWxkcmVuKS5yZXZlcnNlKCksXG4gICAgICAgICAgICBwYXJlbnRQYXRoOiBwYXRoLFxuICAgICAgICAgICAgdHlwZU5hbWU6IGNoaWxkVHlwZU5hbWUsXG4gICAgICAgICAgICBhdHRyaWJ1dGVzOiBbXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGF0dHJpYnV0ZXMucHVzaChbY2hpbGROYW1lLCBjaGlsZFR5cGVOYW1lXSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYXR0cmlidXRlcy5wdXNoKFtjaGlsZE5hbWUsIGZpZWxkLnR5cGVdKTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7ZXJyb3JQcmVhbWJsZShwYXRoKX06ICR7ZXJyb3IubWVzc2FnZX1gKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHlwZXMucmV2ZXJzZSgpLmpvaW4oJ1xcblxcbicpICsgJ1xcbic7XG4gIH07XG5cbiAgLyoqXG4gICAqIGdlbmVyYXRlcyBhIFR5cGVTY3JpcHQgaW50ZXJmYWNlIGRlZmluaXRpb24gZm9yIHBhc3NlZCBuYW1lIGFuZCBhdHRyaWJ1dGVzXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gICAqIEBwYXJhbSB7QXJyYXk8W3N0cmluZywgc3RyaW5nXT59IGF0dHJpYnV0ZXNcbiAgICogQHJldHVybiB7c3RyaW5nfVxuICAgKi9cbiAgcHJpdmF0ZSBnZW5UU0ludGVyZmFjZSA9IChcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgYXR0cmlidXRlczogQXJyYXk8W3N0cmluZywgc3RyaW5nXT5cbiAgKTogc3RyaW5nID0+IHtcbiAgICByZXR1cm4gYGludGVyZmFjZSAke25hbWV9IHtcbiAgJHthdHRyaWJ1dGVzLm1hcCgoYXR0cikgPT4gYCR7YXR0clswXX06ICR7YXR0clsxXX07YCkuam9pbignXFxuICAnKX1cbn1gO1xuICB9O1xuXG4gIC8qKlxuICAgKiByZXR1cm5zIGEgY2hhcmFjdGVyaXN0aWMgb2JqZWN0IGZvciB2YWx1ZXMgYXQgYSBzcGVjaWZpYyBub2RlIGNvbmZpZyBsZXZlbFxuICAgKlxuICAgKiBAcGFyYW0ge0lDb25maWd9IGNvbmZpZ1xuICAgKiBAcGFyYW0ge3N0cmluZ30gbGV2ZWxcbiAgICogQHJldHVybiB7UmVjb3JkPHN0cmluZywgYW55Pn1cbiAgICovXG4gIGdldENvbmZpZ0ZvckxldmVsKGNvbmZpZzogSUNvbmZpZywgbGV2ZWw6IHN0cmluZyk6IFJlY29yZDxzdHJpbmcsIGFueT4ge1xuICAgIGNvbnN0IGNvbmZMZXZlbHMgPSBDb25maWdWYWxpZGF0b3IuZ2V0Tm9kZUNvbmZpZ0xldmVscyhjb25maWcpO1xuICAgIGNvbnN0IGxldmVsSW5kZXggPSBjb25mTGV2ZWxzLmluZGV4T2YobGV2ZWwpO1xuICAgIGlmIChsZXZlbEluZGV4ID09PSAtMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgVGhlIFwiJHtsZXZlbH1cIiBsZXZlbCBub3QgZm91bmQgaW4gdGhlIGN1cnJlbnQgc3lzdGVtIGNvbmZpZ3VyYXRpb24gbGV2ZWxzYFxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgaGlnaGVyTGV2ZWxTb3VyY2VzID0gY29uZmlnLnV0aWxcbiAgICAgIC5nZXRDb25maWdTb3VyY2VzKClcbiAgICAgIC5maWx0ZXIoXG4gICAgICAgIChzb3VyY2UpID0+IGNvbmZMZXZlbHMuaW5kZXhPZihnZXRTb3VyY2VOYW1lKHNvdXJjZSkpID4gbGV2ZWxJbmRleFxuICAgICAgKTtcbiAgICBjb25zdCBjdXJyZW50TGV2ZWxTb3VyY2UgPSBjb25maWcudXRpbFxuICAgICAgLmdldENvbmZpZ1NvdXJjZXMoKVxuICAgICAgLmZpbHRlcigoc291cmNlKSA9PiBnZXRTb3VyY2VOYW1lKHNvdXJjZSkgPT09IGxldmVsKVxuICAgICAgLmF0KDApO1xuICAgIGNvbnN0IGxvd2VyTGV2ZWxTb3VyY2VzID0gY29uZmlnLnV0aWxcbiAgICAgIC5nZXRDb25maWdTb3VyY2VzKClcbiAgICAgIC5maWx0ZXIoXG4gICAgICAgIChzb3VyY2UpID0+IGNvbmZMZXZlbHMuaW5kZXhPZihnZXRTb3VyY2VOYW1lKHNvdXJjZSkpIDwgbGV2ZWxJbmRleFxuICAgICAgKTtcblxuICAgIC8vIFRyYXZlcnNlcyB0aGUgc2NoZW1hIG9iamVjdCB0cmVlIGRlcHRoIGZpcnN0XG4gICAgY29uc3QgdmFsdWVUcmVlID0gQ29uZmlnVmFsaWRhdG9yLnByb2Nlc3NDb25maWdGb3JMZXZlbE5vZGUoXG4gICAgICB0aGlzLnNjaGVtYSxcbiAgICAgIFtdLFxuICAgICAgaGlnaGVyTGV2ZWxTb3VyY2VzLFxuICAgICAgY3VycmVudExldmVsU291cmNlLFxuICAgICAgbG93ZXJMZXZlbFNvdXJjZXNcbiAgICApO1xuXG4gICAgcmV0dXJuIHZhbHVlVHJlZTtcbiAgfVxuXG4gIC8qKlxuICAgKnRyYXZlcnNlcyB0aGUgY29uZmlnIHNjaGVtYSBkZXB0aCBmaXJzdCB0byBwcm9kdWNlIGNoYXJhY3RlcmlzdGljIG9iamVjdFxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAc3RhdGljXG4gICAqIEBwYXJhbSB7Q29uZmlnU2NoZW1hfSBzY2hlbWFcbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gcGF0aFxuICAgKiBAcGFyYW0ge0lDb25maWdTb3VyY2VbXX0gaGlnaGVyTGV2ZWxTb3VyY2VzXG4gICAqIEBwYXJhbSB7KElDb25maWdTb3VyY2UgfCB1bmRlZmluZWQpfSBjdXJyZW50TGV2ZWxTb3VyY2VcbiAgICogQHBhcmFtIHtJQ29uZmlnU291cmNlW119IGxvd2VyTGV2ZWxTb3VyY2VzXG4gICAqIEByZXR1cm4ge1JlY29yZDxzdHJpbmcsIGFueT59XG4gICAqIEBtZW1iZXJvZiBDb25maWdWYWxpZGF0b3JcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIHByb2Nlc3NDb25maWdGb3JMZXZlbE5vZGUoXG4gICAgc2NoZW1hOiBDb25maWdTY2hlbWEsXG4gICAgcGF0aDogc3RyaW5nW10sXG4gICAgaGlnaGVyTGV2ZWxTb3VyY2VzOiBJQ29uZmlnU291cmNlW10sXG4gICAgY3VycmVudExldmVsU291cmNlOiBJQ29uZmlnU291cmNlIHwgdW5kZWZpbmVkLFxuICAgIGxvd2VyTGV2ZWxTb3VyY2VzOiBJQ29uZmlnU291cmNlW11cbiAgKTogUmVjb3JkPHN0cmluZywgYW55PiB7XG4gICAgY29uc3QgdmFsdWUgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIGZvciAoY29uc3QgY2hpbGROYW1lIG9mIE9iamVjdC5rZXlzKHNjaGVtYSkucmV2ZXJzZSgpKSB7XG4gICAgICBjb25zdCBjaGlsZFBhdGggPSBwYXRoLmNvbmNhdChbY2hpbGROYW1lXSk7XG4gICAgICBjb25zdCBmaWVsZCA9IHNjaGVtYVtjaGlsZE5hbWVdO1xuICAgICAgLy8gaWYgYSBmaWVsZCBpcyBvZiB0eXBlIG9iamVjdCBhbmQgdGh1cyBpcyBhIHN1YnRyZWUsIHJlY3Vyc2Ugb24gaXQuXG4gICAgICAvLyBPdGhlcndpc2UgaXQncyBhIGxlYWYgYW5kIG5lZWRzIG5vIHRyYXZlcnNhbC5cbiAgICAgIHZhbHVlW2NoaWxkTmFtZV0gPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgaWYgKGZpZWxkLnR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIHZhbHVlW2NoaWxkTmFtZV0gPSBDb25maWdWYWxpZGF0b3IucHJvY2Vzc0NvbmZpZ0ZvckxldmVsTm9kZShcbiAgICAgICAgICBmaWVsZC5jaGlsZHJlbixcbiAgICAgICAgICBjaGlsZFBhdGgsXG4gICAgICAgICAgaGlnaGVyTGV2ZWxTb3VyY2VzLFxuICAgICAgICAgIGN1cnJlbnRMZXZlbFNvdXJjZSxcbiAgICAgICAgICBsb3dlckxldmVsU291cmNlc1xuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFsdWVbY2hpbGROYW1lXVsnbGFiZWwnXSA9XG4gICAgICAgICAgZmllbGQubGFiZWwgIT0gdW5kZWZpbmVkID8gZmllbGQubGFiZWwgOiBudWxsO1xuICAgICAgICB2YWx1ZVtjaGlsZE5hbWVdWydkZXNjcmlwdGlvbiddID1cbiAgICAgICAgICBmaWVsZC5kZXNjcmlwdGlvbiAhPSB1bmRlZmluZWQgPyBmaWVsZC5kZXNjcmlwdGlvbiA6IG51bGw7XG4gICAgICAgIHZhbHVlW2NoaWxkTmFtZV1bJ2RlZmF1bHQnXSA9IGdldFZhbHVlRnJvbUNvbmZpZ1NvdXJjZXMoXG4gICAgICAgICAgbG93ZXJMZXZlbFNvdXJjZXMsXG4gICAgICAgICAgY2hpbGRQYXRoXG4gICAgICAgICk7XG4gICAgICAgIHZhbHVlW2NoaWxkTmFtZV1bJ3ZhbHVlJ10gPSBnZXRWYWx1ZUZyb21Db25maWdTb3VyY2VzKFxuICAgICAgICAgIFsuLi4oY3VycmVudExldmVsU291cmNlICE9IHVuZGVmaW5lZCA/IFtjdXJyZW50TGV2ZWxTb3VyY2VdIDogW10pXSxcbiAgICAgICAgICBjaGlsZFBhdGhcbiAgICAgICAgKTtcbiAgICAgICAgdmFsdWVbY2hpbGROYW1lXVsnb3ZlcnJpZGUnXSA9IGdldFZhbHVlRnJvbUNvbmZpZ1NvdXJjZXMoXG4gICAgICAgICAgaGlnaGVyTGV2ZWxTb3VyY2VzLFxuICAgICAgICAgIGNoaWxkUGF0aFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiByZXR1cm5zIGEgbGlzdCBvZiBjb25maWcgc291cmNlcyB1c2VkIGJ5IG5vZGUgY29uZmlnIHBhY2thZ2UsIG9yZGVyZWQgZnJvbVxuICAgKiB0aGUgbG93ZXN0IHRvIHRoZSBoaWdoZXN0IHByaW9yaXR5XG4gICAqXG4gICAqIEBzdGF0aWNcbiAgICogQHBhcmFtIHtJQ29uZmlnfSBjb25maWdcbiAgICogQHJldHVybiAge3N0cmluZ1tdfVxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0Tm9kZUNvbmZpZ0xldmVscyA9IChjb25maWc6IElDb25maWcpOiBzdHJpbmdbXSA9PiB7XG4gICAgY29uc3QgaW5zdGFuY2UgPSBjb25maWcudXRpbC5nZXRFbnYoJ05PREVfQVBQX0lOU1RBTkNFJyk7XG4gICAgbGV0IGRlcGxveW1lbnQgPSBjb25maWcudXRpbC5nZXRFbnYoJ05PREVfRU5WJyk7XG4gICAgZGVwbG95bWVudCA9IGNvbmZpZy51dGlsLmdldEVudignTk9ERV9DT05GSUdfRU5WJyk7XG4gICAgY29uc3QgZnVsbEhvc3RuYW1lID0gY29uZmlnLnV0aWwuZ2V0RW52KCdIT1NUTkFNRScpO1xuICAgIGNvbnN0IHNob3J0SG9zdG5hbWUgPVxuICAgICAgZnVsbEhvc3RuYW1lICE9IHVuZGVmaW5lZCA/IGZ1bGxIb3N0bmFtZS5zcGxpdCgnLicpWzBdIDogdW5kZWZpbmVkO1xuXG4gICAgY29uc3QgY29uZmlnTGV2ZWxzID0gW1xuICAgICAgJ2RlZmF1bHQnLFxuICAgICAgLi4uKGluc3RhbmNlICE9IHVuZGVmaW5lZCA/IFtgZGVmYXVsdC0ke2luc3RhbmNlfWBdIDogW10pLFxuICAgICAgLi4uKGRlcGxveW1lbnQgIT0gdW5kZWZpbmVkID8gW2Ake2RlcGxveW1lbnR9YF0gOiBbXSksXG4gICAgICAuLi4oaW5zdGFuY2UgIT0gdW5kZWZpbmVkICYmIGRlcGxveW1lbnQgIT0gdW5kZWZpbmVkXG4gICAgICAgID8gW2Ake2RlcGxveW1lbnR9LSR7aW5zdGFuY2V9YF1cbiAgICAgICAgOiBbXSksXG4gICAgICAuLi4oc2hvcnRIb3N0bmFtZSAhPSB1bmRlZmluZWQgPyBbYCR7c2hvcnRIb3N0bmFtZX1gXSA6IFtdKSxcbiAgICAgIC4uLihzaG9ydEhvc3RuYW1lICE9IHVuZGVmaW5lZCAmJiBpbnN0YW5jZSAhPSB1bmRlZmluZWRcbiAgICAgICAgPyBbYCR7c2hvcnRIb3N0bmFtZX0tJHtpbnN0YW5jZX1gXVxuICAgICAgICA6IFtdKSxcbiAgICAgIC4uLihzaG9ydEhvc3RuYW1lICE9IHVuZGVmaW5lZCAmJiBkZXBsb3ltZW50ICE9IHVuZGVmaW5lZFxuICAgICAgICA/IFtgJHtzaG9ydEhvc3RuYW1lfS0ke2RlcGxveW1lbnR9YF1cbiAgICAgICAgOiBbXSksXG4gICAgICAuLi4oc2hvcnRIb3N0bmFtZSAhPSB1bmRlZmluZWQgJiZcbiAgICAgIGRlcGxveW1lbnQgIT0gdW5kZWZpbmVkICYmXG4gICAgICBpbnN0YW5jZSAhPSB1bmRlZmluZWRcbiAgICAgICAgPyBbYCR7c2hvcnRIb3N0bmFtZX0tJHtkZXBsb3ltZW50fS0ke2luc3RhbmNlfWBdXG4gICAgICAgIDogW10pLFxuICAgICAgLi4uKGZ1bGxIb3N0bmFtZSAhPSB1bmRlZmluZWQgPyBbYCR7ZnVsbEhvc3RuYW1lfWBdIDogW10pLFxuICAgICAgLi4uKGZ1bGxIb3N0bmFtZSAhPSB1bmRlZmluZWQgJiYgaW5zdGFuY2UgIT0gdW5kZWZpbmVkXG4gICAgICAgID8gW2Ake2Z1bGxIb3N0bmFtZX0tJHtpbnN0YW5jZX1gXVxuICAgICAgICA6IFtdKSxcbiAgICAgIC4uLihmdWxsSG9zdG5hbWUgIT0gdW5kZWZpbmVkICYmIGRlcGxveW1lbnQgIT0gdW5kZWZpbmVkXG4gICAgICAgID8gW2Ake2Z1bGxIb3N0bmFtZX0tJHtkZXBsb3ltZW50fWBdXG4gICAgICAgIDogW10pLFxuICAgICAgLi4uKGZ1bGxIb3N0bmFtZSAhPSB1bmRlZmluZWQgJiZcbiAgICAgIGRlcGxveW1lbnQgIT0gdW5kZWZpbmVkICYmXG4gICAgICBpbnN0YW5jZSAhPSB1bmRlZmluZWRcbiAgICAgICAgPyBbYCR7ZnVsbEhvc3RuYW1lfS0ke2RlcGxveW1lbnR9LSR7aW5zdGFuY2V9YF1cbiAgICAgICAgOiBbXSksXG4gICAgICBgbG9jYWxgLFxuICAgICAgLi4uKGluc3RhbmNlICE9IHVuZGVmaW5lZCA/IFtgbG9jYWwtJHtpbnN0YW5jZX1gXSA6IFtdKSxcbiAgICAgIC4uLihkZXBsb3ltZW50ICE9IHVuZGVmaW5lZCA/IFtgbG9jYWwtJHtkZXBsb3ltZW50fWBdIDogW10pLFxuICAgICAgLi4uKGRlcGxveW1lbnQgIT0gdW5kZWZpbmVkICYmIGluc3RhbmNlICE9IHVuZGVmaW5lZFxuICAgICAgICA/IFtgbG9jYWwtJHtkZXBsb3ltZW50fS0ke2luc3RhbmNlfWBdXG4gICAgICAgIDogW10pLFxuICAgICAgJyROT0RFX0NPTkZJRycsXG4gICAgICAnY3VzdG9tLWVudmlyb25tZW50LXZhcmlhYmxlcycsXG4gICAgXTtcblxuICAgIHJldHVybiBjb25maWdMZXZlbHM7XG4gIH07XG5cbiAgLyoqXG4gICAqIHZhbGlkYXRlcyBhIGNvbmZpZyBvYmplY3QgYW5kIHdyaXRlcyBpdCB0byB0aGUgbm9kZS1jb25maWcgZmlsZVxuICAgKiBjb3JyZXNwb25kaW5nIHRvIHRoZSBwYXNzZWQgbGV2ZWxcbiAgICpcbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBjb25maWdPYmpcbiAgICogQHBhcmFtIHtJQ29uZmlnfSBjb25maWdcbiAgICogQHBhcmFtIHtzdHJpbmd9IGxldmVsIG91dHB1dCBub2RlLWNvbmZpZyBmaWxlIGxldmVsXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmb3JtYXQgdGhlIGZvcm1hdCBvZiB0aGUgb3V0cHV0IGZpbGVcbiAgICovXG4gIHZhbGlkYXRlQW5kV3JpdGVDb25maWcgPSAoXG4gICAgY29uZmlnT2JqOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICAgIGNvbmZpZzogSUNvbmZpZyxcbiAgICBsZXZlbDogc3RyaW5nLFxuICAgIGZvcm1hdDogc3RyaW5nXG4gICkgPT4ge1xuICAgIGNvbnN0IGNvbmZMZXZlbHMgPSBDb25maWdWYWxpZGF0b3IuZ2V0Tm9kZUNvbmZpZ0xldmVscyhjb25maWcpLmZpbHRlcihcbiAgICAgIChsKSA9PiBsICE9PSAnY3VzdG9tLWVudmlyb25tZW50LXZhcmlhYmxlcydcbiAgICApO1xuICAgIGNvbnN0IGxldmVsSW5kZXggPSBjb25mTGV2ZWxzLmluZGV4T2YobGV2ZWwpO1xuICAgIGlmIChsZXZlbEluZGV4ID09PSAtMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgVGhlIFske2xldmVsfV0gbGV2ZWwgbm90IGZvdW5kIGluIHRoZSBjdXJyZW50IHN5c3RlbSdzIGNvbmZpZ3VyYXRpb24gbGV2ZWxzYFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBjb25maWdEaXIgPVxuICAgICAgcHJvY2Vzcy5lbnZbJ05PREVfQ09ORklHX0RJUiddICE9IHVuZGVmaW5lZFxuICAgICAgICA/IHByb2Nlc3MuZW52WydOT0RFX0NPTkZJR19ESVInXVxuICAgICAgICA6ICcuL2NvbmZpZyc7XG4gICAgbGV0IG91dHB1dCA9ICcnO1xuICAgIGxldCBleHQgPSAnJztcbiAgICBzd2l0Y2ggKGZvcm1hdCkge1xuICAgICAgY2FzZSAnanNvbic6IHtcbiAgICAgICAgY29uc3QgSnNvbkJpZ0ludCA9IEpzb25CaWdJbnRGYWN0b3J5KHtcbiAgICAgICAgICBhbHdheXNQYXJzZUFzQmlnOiBmYWxzZSxcbiAgICAgICAgICB1c2VOYXRpdmVCaWdJbnQ6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgICBvdXRwdXQgPSBKc29uQmlnSW50LnN0cmluZ2lmeShjb25maWdPYmopO1xuICAgICAgICBleHQgPSAnanNvbic7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAneWFtbCc6IHtcbiAgICAgICAgb3V0cHV0ID0geWFtbC5kdW1wKGNvbmZpZ09iaik7XG4gICAgICAgIGV4dCA9ICd5YW1sJztcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBFcnJvcihgSW52YWxpZCBmb3JtYXQ6ICR7Zm9ybWF0fWApO1xuICAgIH1cblxuICAgIGNvbnN0IG91dHB1dFBhdGggPSBwYXRoLmpvaW4oY29uZmlnRGlyLCBgJHtsZXZlbH0uJHtleHR9YCk7XG4gICAgY29uc3QgYmFja3VwUGF0aCA9IHBhdGguam9pbihjb25maWdEaXIsIGAke2xldmVsfS1iYWNrdXAuJHtleHR9YCk7XG4gICAgY29uc3QgY29uZkZpbGVFeGlzdHMgPSBmcy5leGlzdHNTeW5jKG91dHB1dFBhdGgpO1xuICAgIGlmIChjb25mRmlsZUV4aXN0cykge1xuICAgICAgZnMucmVuYW1lU3luYyhvdXRwdXRQYXRoLCBiYWNrdXBQYXRoKTtcbiAgICB9XG4gICAgZnMud3JpdGVGaWxlU3luYyhvdXRwdXRQYXRoLCBvdXRwdXQpO1xuXG4gICAgY29uc3QgdXBkYXRlZENvbmZPYmogPSBjb25maWcudXRpbC5sb2FkRmlsZUNvbmZpZ3MoKTtcblxuICAgIHRyeSB7XG4gICAgICB0aGlzLnZhbGlkYXRlQ29uZmlnKHVwZGF0ZWRDb25mT2JqKTtcbiAgICAgIGZzLnVubGlua1N5bmMoYmFja3VwUGF0aCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGZzLnVubGlua1N5bmMob3V0cHV0UGF0aCk7XG4gICAgICBpZiAoY29uZkZpbGVFeGlzdHMpIHtcbiAgICAgICAgZnMucmVuYW1lU3luYyhiYWNrdXBQYXRoLCBvdXRwdXRQYXRoKTtcbiAgICAgIH1cbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfTtcbn1cbiJdfQ==
@@ -0,0 +1,2 @@
1
+ export * from './config';
2
+ //# sourceMappingURL=index.d.ts.map