@decaf-ts/injectable-decorators 1.6.16 → 1.7.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 (45) hide show
  1. package/README.md +22 -2
  2. package/dist/injectable-decorators.cjs +2 -541
  3. package/dist/injectable-decorators.cjs.map +1 -0
  4. package/dist/injectable-decorators.js +2 -0
  5. package/dist/injectable-decorators.js.map +1 -0
  6. package/lib/Injectables.cjs +1 -1
  7. package/lib/Injectables.js.map +1 -0
  8. package/lib/Metadata.cjs +1 -1
  9. package/lib/Metadata.js.map +1 -0
  10. package/lib/constants.cjs +1 -1
  11. package/lib/constants.js.map +1 -0
  12. package/lib/decorators.cjs +1 -1
  13. package/lib/decorators.js.map +1 -0
  14. package/lib/esm/Injectables.js +1 -1
  15. package/lib/esm/Injectables.js.map +1 -0
  16. package/lib/esm/Metadata.js +1 -1
  17. package/lib/esm/Metadata.js.map +1 -0
  18. package/lib/esm/constants.js +1 -1
  19. package/lib/esm/constants.js.map +1 -0
  20. package/lib/esm/decorators.js +1 -1
  21. package/lib/esm/decorators.js.map +1 -0
  22. package/lib/esm/index.d.ts +2 -2
  23. package/lib/esm/index.js +3 -3
  24. package/lib/esm/index.js.map +1 -0
  25. package/lib/esm/overrides.js +1 -1
  26. package/lib/esm/overrides.js.map +1 -0
  27. package/lib/esm/registry.js +1 -1
  28. package/lib/esm/registry.js.map +1 -0
  29. package/lib/esm/types.js +1 -1
  30. package/lib/esm/types.js.map +1 -0
  31. package/lib/esm/utils.js +1 -1
  32. package/lib/esm/utils.js.map +1 -0
  33. package/lib/index.cjs +3 -3
  34. package/lib/index.d.ts +2 -2
  35. package/lib/index.js.map +1 -0
  36. package/lib/overrides.cjs +1 -1
  37. package/lib/overrides.js.map +1 -0
  38. package/lib/registry.cjs +1 -1
  39. package/lib/registry.js.map +1 -0
  40. package/lib/types.cjs +1 -1
  41. package/lib/types.js.map +1 -0
  42. package/lib/utils.cjs +1 -1
  43. package/lib/utils.js.map +1 -0
  44. package/package.json +10 -16
  45. package/dist/injectable-decorators.esm.cjs +0 -522
@@ -1,522 +0,0 @@
1
- import { Decoration, prop, Metadata } from '@decaf-ts/decoration';
2
-
3
- /**
4
- * @description Constants used for reflection metadata keys in the dependency injection system.
5
- * @summary Injectables Reflection keys used to store and retrieve metadata about injectable classes and properties.
6
- * @property {string} REFLECT Reflection injectables base key prefix for all metadata keys
7
- * @property {string} INJECTABLE Reflection key suffix for marking a class as injectable
8
- * @property {string} INJECT Reflection key suffix for marking a property for injection
9
- * @const InjectablesKeys
10
- * @memberOf module:injectable-decorators
11
- */
12
- const InjectablesKeys = {
13
- REFLECT: "inject.db.",
14
- INJECTABLE: "injectable",
15
- INJECT: "inject",
16
- };
17
- /**
18
- * @description Default configuration applied by the @injectable decorator when none is provided.
19
- * @summary Sets sensible defaults such as singleton lifecycle for newly registered injectables.
20
- * @const DefaultInjectablesConfig
21
- * @memberOf module:injectable-decorators
22
- */
23
- const DefaultInjectablesConfig = {
24
- singleton: true,
25
- };
26
- /**
27
- * @description Reflection metadata key for accessing TypeScript type information.
28
- * @summary Holds the key for retrieving the design type from TypeScript's reflection metadata.
29
- * @const TypeKey
30
- * @memberOf module:injectable-decorators
31
- */
32
- const TypeKey = "design:type";
33
-
34
- /**
35
- * @description Generates a fully qualified reflection metadata key.
36
- * @summary Returns the reflection key for injectables by prefixing the provided key with the base reflection key.
37
- * @param {string} key The key to be prefixed
38
- * @return {string} The fully qualified reflection key
39
- * @function getInjectKey
40
- * @memberOf module:injectable-decorators
41
- */
42
- const getInjectKey = (key) => InjectablesKeys.REFLECT + key;
43
-
44
- /**
45
- * @description Default implementation of the InjectablesRegistry interface.
46
- * @summary Holds the various {@link Injectable}s in a cache and provides methods to register, retrieve, and build them.
47
- * @template T Type parameter used in the class methods
48
- *
49
- * @class InjectableRegistryImp
50
- * @implements InjectablesRegistry
51
- *
52
- * @memberOf module:injectable-decorators
53
- *
54
- * @example
55
- * // Create a new registry
56
- * const registry = new InjectableRegistryImp();
57
- *
58
- * // Register a class
59
- * class MyService {
60
- * doSomething() {
61
- * return 'Hello World';
62
- * }
63
- * }
64
- * registry.register(MyService, 'MyService', true);
65
- *
66
- * // Get the instance
67
- * const service = registry.get('MyService');
68
- * service.doSomething(); // 'Hello World'
69
- *
70
- * @mermaid
71
- * sequenceDiagram
72
- * participant Client
73
- * participant Registry
74
- *
75
- * Client->>Registry: register(MyService)
76
- * Registry->>Registry: Store in cache
77
- *
78
- * Client->>Registry: get("MyService")
79
- * alt Instance exists and is singleton
80
- * Registry-->>Client: Return cached instance
81
- * else No instance or not singleton
82
- * Registry->>Registry: build(name)
83
- * Registry-->>Client: Return new instance
84
- * end
85
- */
86
- class InjectableRegistryImp {
87
- constructor() {
88
- this.cache = {};
89
- }
90
- has(name) {
91
- if (typeof name === "symbol")
92
- return name in this.cache;
93
- return Symbol.for(name.toString()) in this.cache;
94
- }
95
- /**
96
- * @inheritDoc
97
- */
98
- get(name, ...args) {
99
- if (typeof name === "string")
100
- name = Symbol.for(name);
101
- if (typeof name !== "symbol") {
102
- const meta = Reflect.getMetadata(getInjectKey(InjectablesKeys.INJECTABLE), name);
103
- name = meta?.symbol || Symbol.for(name.toString());
104
- }
105
- if (!name)
106
- throw new Error(`Injectable ${name} not found`);
107
- if (!(name in this.cache)) {
108
- return undefined;
109
- }
110
- const cache = this.cache[name];
111
- if (!cache.options.singleton && !cache.instance)
112
- return this.build(name, ...args);
113
- return cache.instance || this.build(name, ...args);
114
- }
115
- /**
116
- * @inheritDoc
117
- */
118
- register(obj, category, options, force = false) {
119
- const castObj = obj;
120
- const constructor = !castObj.name && castObj.constructor;
121
- if (typeof castObj !== "function" && !constructor)
122
- throw new Error(`Injectable registering failed. Missing Class name or constructor`);
123
- const name = category || Symbol.for(obj.toString());
124
- if (!this.cache[name] || force)
125
- this.cache[name] = {
126
- instance: options.singleton && constructor ? obj : undefined,
127
- constructor: !constructor ? obj : obj.constructor,
128
- options: options,
129
- };
130
- }
131
- /**
132
- * @inheritDoc
133
- */
134
- build(name, ...args) {
135
- const { constructor, options } = this.cache[name];
136
- let instance;
137
- try {
138
- instance = new constructor(...args);
139
- }
140
- catch (e) {
141
- throw new Error(`failed to build ${name.toString()} with args ${args}: ${e}`);
142
- }
143
- if (options.singleton) {
144
- this.cache[name].instance = instance;
145
- }
146
- if (options.callback)
147
- instance = options.callback(instance, ...args);
148
- return instance;
149
- }
150
- }
151
-
152
- /**
153
- * @description Central registry for managing injectable dependencies.
154
- * @summary Static class holding the access to the injectables functions. Provides methods for registering,
155
- * retrieving, and building injectable objects.
156
- * @template T Type of the injectable object
157
- *
158
- * @class Injectables
159
- *
160
- * @example
161
- * // Define an injectable class
162
- * @injectable()
163
- * class MyService {
164
- * doSomething() {
165
- * return 'Hello World';
166
- * }
167
- * }
168
- *
169
- * // Inject the service into another class
170
- * class MyComponent {
171
- * @inject()
172
- * private service!: MyService;
173
- *
174
- * useService() {
175
- * return this.service.doSomething();
176
- * }
177
- * }
178
- *
179
- * @mermaid
180
- * sequenceDiagram
181
- * participant Client
182
- * participant Injectables
183
- * participant Registry
184
- *
185
- * Client->>Injectables: register(MyService)
186
- * Injectables->>Registry: register(MyService)
187
- * Registry-->>Injectables: void
188
- *
189
- * Client->>Injectables: get("MyService")
190
- * Injectables->>Registry: get("MyService")
191
- * Registry-->>Injectables: MyService instance
192
- * Injectables-->>Client: MyService instance
193
- */
194
- class Injectables {
195
- /**
196
- * @description Holds the active registry implementation used by the Injectables facade.
197
- * @summary Internal static reference that can be swapped via setRegistry to customize how injectables are stored and retrieved.
198
- * @type {InjectablesRegistry | undefined}
199
- */
200
- static { this.actingInjectablesRegistry = undefined; }
201
- constructor() { }
202
- /**
203
- * @description Fetches an injectable instance by its registered name.
204
- * @summary Retrieves the named {@link Injectable} from the registry. If the injectable is a singleton,
205
- * returns the existing instance. Otherwise, creates a new instance.
206
- * @template T Type of the injectable object to retrieve
207
- * @param {string} name The registered name of the injectable to retrieve
208
- * @param {any[]} args Constructor arguments to pass when instantiating the injectable
209
- * @return {Injectable<T> | undefined} The injectable instance or undefined if not found
210
- */
211
- static get(name, ...args) {
212
- return Injectables.getRegistry().get(name, ...args);
213
- }
214
- /**
215
- * @description Adds a class or object to the injectable registry.
216
- * @summary Registers an injectable constructor or instance with the registry, making it available for injection.
217
- * @template T Type of the injectable object to register
218
- * @param {Injectable<T>} constructor The class constructor or object instance to register
219
- * @param {any[]} args Additional arguments for registration (category, singleton flag, etc.)
220
- * @return {void}
221
- */
222
- static register(constructor, ...args) {
223
- return Injectables.getRegistry().register(constructor, ...args);
224
- }
225
- /**
226
- * @description Creates a new instance of an injectable class.
227
- * @summary Instantiates an injectable class using its constructor and the provided arguments.
228
- * @template T Type of the object to build
229
- * @param {symbol} name symbol referencing the injectable
230
- * @param {any[]} args Constructor arguments to pass when instantiating the injectable
231
- * @return {T} The newly created instance
232
- */
233
- static build(name, ...args) {
234
- return Injectables.getRegistry().build(name, ...args);
235
- }
236
- /**
237
- * @description Replaces the current registry implementation.
238
- * @summary Sets a new {@link InjectablesRegistry} implementation, allowing for custom registry behavior.
239
- * @param {InjectablesRegistry} operationsRegistry The new implementation of Registry to use
240
- * @return {void}
241
- */
242
- static setRegistry(operationsRegistry) {
243
- Injectables.actingInjectablesRegistry = operationsRegistry;
244
- }
245
- /**
246
- * @description Provides access to the current registry instance.
247
- * @summary Returns the current {@link InjectablesRegistry} or creates a default one if none exists.
248
- * @return {InjectablesRegistry} The current registry instance
249
- */
250
- static getRegistry() {
251
- if (!Injectables.actingInjectablesRegistry)
252
- Injectables.actingInjectablesRegistry = new InjectableRegistryImp();
253
- return Injectables.actingInjectablesRegistry;
254
- }
255
- /**
256
- * @description Clears all registered injectables.
257
- * @summary Resets the registry to a clean state by creating a new empty registry instance.
258
- * @return {void}
259
- */
260
- static reset() {
261
- Injectables.setRegistry(new InjectableRegistryImp());
262
- }
263
- /**
264
- * @description Removes specific injectables from the registry based on a pattern.
265
- * @summary Selectively resets the registry by removing only the injectables whose names match the provided pattern.
266
- * @param {string | RegExp} match A string or regular expression pattern to match against injectable names
267
- * @return {void}
268
- */
269
- static selectiveReset(match) {
270
- const regexp = typeof match === "string" ? new RegExp(match) : match;
271
- Injectables.actingInjectablesRegistry["cache"] = Object.entries(Injectables.actingInjectablesRegistry["cache"]).reduce((accum, [key, val]) => {
272
- if (!key.match(regexp))
273
- accum[key] = val;
274
- return accum;
275
- }, {});
276
- }
277
- }
278
-
279
- function injectableBaseDecorator(category, cfg) {
280
- cfg =
281
- cfg ||
282
- (typeof category === "object"
283
- ? Object.assign(category, DefaultInjectablesConfig)
284
- : DefaultInjectablesConfig);
285
- category =
286
- typeof category === "object"
287
- ? undefined
288
- : typeof category === "string"
289
- ? category
290
- : typeof category === "function" && category.name
291
- ? category
292
- : undefined;
293
- return function injectableInnerDecorator(original) {
294
- const symbol = Symbol.for(category || original.toString());
295
- category = category || original.name;
296
- const metadata = {
297
- class: category,
298
- symbol: symbol,
299
- };
300
- Reflect.defineMetadata(getInjectKey(InjectablesKeys.INJECTABLE), metadata, original);
301
- // the new constructor behaviour
302
- const newConstructor = function (...args) {
303
- return Injectables.get(symbol, ...args);
304
- };
305
- // copy prototype so instanceof operator still works
306
- newConstructor.prototype = original.prototype;
307
- // newConstructor.__proto__ = original.__proto__;
308
- // Sets the proper constructor name for type verification
309
- Object.defineProperty(newConstructor, "name", {
310
- writable: false,
311
- enumerable: true,
312
- configurable: false,
313
- value: original.prototype.constructor.name,
314
- });
315
- Reflect.defineMetadata(getInjectKey(InjectablesKeys.INJECTABLE), metadata, newConstructor);
316
- Injectables.register(original, symbol, cfg);
317
- // return new constructor (will override original)
318
- return newConstructor;
319
- };
320
- }
321
- /**
322
- * @description Decorator that marks a class as available for dependency injection.
323
- * @summary Defines a class as an injectable that can be retrieved from the registry.
324
- * When applied to a class, replaces its constructor with one that returns an instance.
325
- *
326
- * @param {string | Constructor} [category] Defaults to the class category. Useful when minification occurs and names are changed,
327
- * or when you want to upcast the object to a different type.
328
- * @param {Partial<InjectableConfig>} [cfg=DefaultInjectableConfig] Allows overriding the default singleton behavior and adding a callback function.
329
- *
330
- * @return {function(any): any} A decorator function that transforms the class into an injectable.
331
- *
332
- * @function injectable
333
- * @category Class Decorators
334
- *
335
- * @mermaid
336
- * sequenceDiagram
337
- * participant Client
338
- * participant Decorator
339
- * participant Injectables
340
- *
341
- * Client->>Decorator: @injectable()
342
- * Decorator->>Decorator: Create new constructor
343
- *
344
- * Note over Decorator: When new instance requested
345
- * Decorator->>Injectables: get(category)
346
- * alt Instance exists
347
- * Injectables-->>Decorator: Return existing instance
348
- * else No instance
349
- * Decorator->>Injectables: register(original, category)
350
- * Decorator->>Injectables: get(category)
351
- * Injectables-->>Decorator: Return new instance
352
- * opt Has callback
353
- * Decorator->>Decorator: Call instanceCallback
354
- * end
355
- * end
356
- * Decorator->>Decorator: Define metadata
357
- * Decorator-->>Client: Return instance
358
- */
359
- function injectable(category, cfg) {
360
- return Decoration.for(InjectablesKeys.INJECTABLE)
361
- .define({ decorator: injectableBaseDecorator, args: [category, cfg] })
362
- .apply();
363
- }
364
- /**
365
- * @description Convenience decorator to register an injectable as a singleton.
366
- * @summary Wraps {@link injectable} forcing the singleton lifecycle so only one instance is created and reused.
367
- * @param {string|Constructor} [category] Optional explicit category/symbol source; defaults to the class.
368
- * @param {Omit<InjectableConfig, "singleton">} [cfg] Additional injectable configuration excluding the singleton flag.
369
- * @return {function(any): any} A class decorator that registers the target as a singleton injectable.
370
- * @function singleton
371
- * @category Class Decorators
372
- */
373
- function singleton(category, cfg) {
374
- return injectable(category, Object.assign({}, cfg || {}, { singleton: true }));
375
- }
376
- /**
377
- * @description Convenience decorator to register an injectable as on-demand (non-singleton).
378
- * @summary Wraps {@link injectable} forcing new instances to be created on every injection or retrieval.
379
- * @param {string|Constructor} [category] Optional explicit category/symbol source; defaults to the class.
380
- * @param {Omit<InjectableConfig, "singleton">} [cfg] Additional injectable configuration excluding the singleton flag.
381
- * @return {function(any): any} A class decorator that registers the target as a non-singleton injectable.
382
- * @function onDemand
383
- * @category Class Decorators
384
- */
385
- function onDemand(category, cfg) {
386
- return injectable(category, Object.assign({}, cfg || {}, { singleton: false }));
387
- }
388
- function injectBaseDecorator(category, cfg) {
389
- return function injectInnerDecorator(target, propertyKey) {
390
- const config = (cfg || typeof category === "object" ? category : {});
391
- if (propertyKey) {
392
- prop()(target, propertyKey);
393
- }
394
- const name = (typeof category !== "object" &&
395
- category) ||
396
- Metadata.type(target.constructor, propertyKey);
397
- if (!name) {
398
- throw new Error(`Could not get Type from decorator`);
399
- }
400
- // prop()(target, propertyKey);
401
- Reflect.defineMetadata(getInjectKey(InjectablesKeys.INJECT), {
402
- injectable: name,
403
- }, target, propertyKey);
404
- const values = new WeakMap();
405
- Object.defineProperty(target, propertyKey, {
406
- configurable: true,
407
- get() {
408
- const descriptor = Object.getOwnPropertyDescriptor(target, propertyKey);
409
- if (descriptor.configurable) {
410
- // let /obj: any;
411
- Object.defineProperty(this, propertyKey, {
412
- enumerable: true,
413
- configurable: false,
414
- get() {
415
- let obj = values.get(this);
416
- if (obj)
417
- return obj;
418
- obj = Injectables.get(name, ...(config.args || []));
419
- if (!obj)
420
- throw new Error(`Could not get Injectable ${name.toString()} to inject in ${target.constructor ? target.constructor.name : target.name}'s ${propertyKey}`);
421
- if (config.transformer)
422
- try {
423
- obj = config.transformer(obj, target);
424
- }
425
- catch (e) {
426
- console.error(e);
427
- }
428
- values.set(this, obj);
429
- return obj;
430
- },
431
- });
432
- return this[propertyKey];
433
- }
434
- },
435
- });
436
- };
437
- }
438
- /**
439
- * @description Property decorator that injects a dependency into a class property.
440
- * @summary Allows for the injection of an {@link injectable} decorated dependency into a class property.
441
- * The property must be typed for the requested dependency. Only concrete classes are supported; generics are not.
442
- *
443
- * Injected properties should be described like so:
444
- * <pre>
445
- * class ClassName {
446
- * ...
447
- *
448
- * @inject()
449
- * propertyName!: InjectableClass;
450
- *
451
- * ...
452
- * }
453
- * </pre>
454
- *
455
- * where InjectableClass is the class you want to inject.
456
- * Notice the use of '!:' to ensure the transpiler the property will be set outside the constructor but will always be defined.
457
- * For projects where minification occurs, you should use the category param to ensure the name is the same throughout.
458
- *
459
- * @param {string} [category] Defaults to the class name derived from the property type. Useful when minification occurs
460
- * and names are changed, or when you want to upcast the object to a different type.
461
- * @param {Partial<InjectOptions>} [cfg={}] Optional function to transform the injectable instance before it's injected, or arguments to pass the constructor when injecting onDemand
462
- * @return {function(any, any): void} A property decorator function that sets up the dependency injection.
463
- *
464
- * @function inject
465
- * @category Property Decorators
466
- *
467
- * @mermaid
468
- * sequenceDiagram
469
- * participant Client
470
- * participant Decorator
471
- * participant Injectables
472
- *
473
- * Client->>Decorator: @inject()
474
- * Decorator->>Decorator: Get type from property
475
- * Decorator->>Decorator: Define metadata
476
- * Decorator->>Decorator: Define property getter
477
- *
478
- * Note over Decorator: When property accessed
479
- * Client->>Decorator: access property
480
- * Decorator->>Decorator: Check if instance exists
481
- * alt Instance exists in WeakMap
482
- * Decorator-->>Client: Return cached instance
483
- * else No instance
484
- * Decorator->>Injectables: get(name)
485
- * alt Injectable found
486
- * Injectables-->>Decorator: Return injectable instance
487
- * opt Has transformer
488
- * Decorator->>Decorator: Call transformer
489
- * end
490
- * Decorator->>Decorator: Store in WeakMap
491
- * Decorator-->>Client: Return instance
492
- * else No injectable
493
- * Decorator-->>Client: Throw error
494
- * end
495
- * end
496
- */
497
- function inject(category, cfg) {
498
- return Decoration.for(InjectablesKeys.INJECT)
499
- .define({ decorator: injectBaseDecorator, args: [category, cfg] })
500
- .apply();
501
- }
502
-
503
- /**
504
- * @description A lightweight dependency injection library for TypeScript applications.
505
- * @summary Adds a simple Injectables implementation to create singleton instances of an object
506
- * and easily inject it into other objects. Provides decorators for marking classes as injectable
507
- * and for injecting dependencies into class properties.
508
- *
509
- * @module injectable-decorators
510
- */
511
- /**
512
- * @description Current version of the injectable-decorators library.
513
- * @summary Defined on library build. Holds the library's current version string.
514
- * @const VERSION
515
- * @memberOf module:injectable-decorators
516
- */
517
- const VERSION = "1.6.15";
518
- const PACKAGE_NAME = "##PACKAGE_NAME##";
519
- Metadata.registerLibrary(PACKAGE_NAME, VERSION);
520
-
521
- export { DefaultInjectablesConfig, InjectableRegistryImp, Injectables, InjectablesKeys, PACKAGE_NAME, TypeKey, VERSION, getInjectKey, inject, injectBaseDecorator, injectable, injectableBaseDecorator, onDemand, singleton };
522
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5qZWN0YWJsZS1kZWNvcmF0b3JzLmVzbS5janMiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb25zdGFudHMudHMiLCIuLi9zcmMvdXRpbHMudHMiLCIuLi9zcmMvcmVnaXN0cnkudHMiLCIuLi9zcmMvSW5qZWN0YWJsZXMudHMiLCIuLi9zcmMvZGVjb3JhdG9ycy50cyIsIi4uL3NyYy9pbmRleC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlQ29uZmlnIH0gZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDb25zdGFudHMgdXNlZCBmb3IgcmVmbGVjdGlvbiBtZXRhZGF0YSBrZXlzIGluIHRoZSBkZXBlbmRlbmN5IGluamVjdGlvbiBzeXN0ZW0uXG4gKiBAc3VtbWFyeSBJbmplY3RhYmxlcyBSZWZsZWN0aW9uIGtleXMgdXNlZCB0byBzdG9yZSBhbmQgcmV0cmlldmUgbWV0YWRhdGEgYWJvdXQgaW5qZWN0YWJsZSBjbGFzc2VzIGFuZCBwcm9wZXJ0aWVzLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFJFRkxFQ1QgUmVmbGVjdGlvbiBpbmplY3RhYmxlcyBiYXNlIGtleSBwcmVmaXggZm9yIGFsbCBtZXRhZGF0YSBrZXlzXG4gKiBAcHJvcGVydHkge3N0cmluZ30gSU5KRUNUQUJMRSBSZWZsZWN0aW9uIGtleSBzdWZmaXggZm9yIG1hcmtpbmcgYSBjbGFzcyBhcyBpbmplY3RhYmxlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gSU5KRUNUIFJlZmxlY3Rpb24ga2V5IHN1ZmZpeCBmb3IgbWFya2luZyBhIHByb3BlcnR5IGZvciBpbmplY3Rpb25cbiAqIEBjb25zdCBJbmplY3RhYmxlc0tleXNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6aW5qZWN0YWJsZS1kZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBjb25zdCBJbmplY3RhYmxlc0tleXMgPSB7XG4gIFJFRkxFQ1Q6IFwiaW5qZWN0LmRiLlwiLFxuICBJTkpFQ1RBQkxFOiBcImluamVjdGFibGVcIixcbiAgSU5KRUNUOiBcImluamVjdFwiLFxufTtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVmYXVsdCBjb25maWd1cmF0aW9uIGFwcGxpZWQgYnkgdGhlIEBpbmplY3RhYmxlIGRlY29yYXRvciB3aGVuIG5vbmUgaXMgcHJvdmlkZWQuXG4gKiBAc3VtbWFyeSBTZXRzIHNlbnNpYmxlIGRlZmF1bHRzIHN1Y2ggYXMgc2luZ2xldG9uIGxpZmVjeWNsZSBmb3IgbmV3bHkgcmVnaXN0ZXJlZCBpbmplY3RhYmxlcy5cbiAqIEBjb25zdCBEZWZhdWx0SW5qZWN0YWJsZXNDb25maWdcbiAqIEBtZW1iZXJPZiBtb2R1bGU6aW5qZWN0YWJsZS1kZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBjb25zdCBEZWZhdWx0SW5qZWN0YWJsZXNDb25maWc6IEluamVjdGFibGVDb25maWcgPSB7XG4gIHNpbmdsZXRvbjogdHJ1ZSxcbn07XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFJlZmxlY3Rpb24gbWV0YWRhdGEga2V5IGZvciBhY2Nlc3NpbmcgVHlwZVNjcmlwdCB0eXBlIGluZm9ybWF0aW9uLlxuICogQHN1bW1hcnkgSG9sZHMgdGhlIGtleSBmb3IgcmV0cmlldmluZyB0aGUgZGVzaWduIHR5cGUgZnJvbSBUeXBlU2NyaXB0J3MgcmVmbGVjdGlvbiBtZXRhZGF0YS5cbiAqIEBjb25zdCBUeXBlS2V5XG4gKiBAbWVtYmVyT2YgbW9kdWxlOmluamVjdGFibGUtZGVjb3JhdG9yc1xuICovXG5leHBvcnQgY29uc3QgVHlwZUtleSA9IFwiZGVzaWduOnR5cGVcIjtcbiIsImltcG9ydCB7IEluamVjdGFibGVzS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBHZW5lcmF0ZXMgYSBmdWxseSBxdWFsaWZpZWQgcmVmbGVjdGlvbiBtZXRhZGF0YSBrZXkuXG4gKiBAc3VtbWFyeSBSZXR1cm5zIHRoZSByZWZsZWN0aW9uIGtleSBmb3IgaW5qZWN0YWJsZXMgYnkgcHJlZml4aW5nIHRoZSBwcm92aWRlZCBrZXkgd2l0aCB0aGUgYmFzZSByZWZsZWN0aW9uIGtleS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSB0byBiZSBwcmVmaXhlZFxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgZnVsbHkgcXVhbGlmaWVkIHJlZmxlY3Rpb24ga2V5XG4gKiBAZnVuY3Rpb24gZ2V0SW5qZWN0S2V5XG4gKiBAbWVtYmVyT2YgbW9kdWxlOmluamVjdGFibGUtZGVjb3JhdG9yc1xuICovXG5leHBvcnQgY29uc3QgZ2V0SW5qZWN0S2V5ID0gKGtleTogc3RyaW5nKSA9PiBJbmplY3RhYmxlc0tleXMuUkVGTEVDVCArIGtleTtcbiIsImltcG9ydCB7IEluamVjdGFibGVEZWYsIEluamVjdGFibGVPcHRpb25zIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IEluamVjdGFibGVzS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgZ2V0SW5qZWN0S2V5IH0gZnJvbSBcIi4vdXRpbHNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gVHlwZSByZXByZXNlbnRpbmcgZWl0aGVyIGEgY2xhc3MgY29uc3RydWN0b3Igb3IgYW4gaW5zdGFuY2UuXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGFuIEluamVjdGFibGUgdHlwZSB0aGF0IGNhbiBiZSBlaXRoZXIgYSBjbGFzcyBjb25zdHJ1Y3RvciBvciBhbiBpbnN0YW5jZSBvZiBhIGNsYXNzLlxuICogQHRlbXBsYXRlIFQgVGhlIHR5cGUgb2YgdGhlIGluamVjdGFibGUgb2JqZWN0XG4gKiBAdHlwZWRlZiB7ZnVuY3Rpb24oYW55KTogVCB8IFR9IEluamVjdGFibGVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6aW5qZWN0YWJsZS1kZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCB0eXBlIEluamVjdGFibGU8VD4gPSB7IG5ldyAoLi4uYXJnczogYW55W10pOiBUIH0gfCBUO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDb250cmFjdCBmb3IgYSByZWdpc3RyeSB0aGF0IG1hbmFnZXMgaW5qZWN0YWJsZSBvYmplY3RzLlxuICogQHN1bW1hcnkgSW50ZXJmYWNlIGZvciBhbiBpbmplY3RhYmxlIHJlZ2lzdHJ5IHRoYXQgcHJvdmlkZXMgbWV0aG9kcyBmb3IgcmV0cmlldmluZywgcmVnaXN0ZXJpbmcsIGFuZCBidWlsZGluZyBpbmplY3RhYmxlIG9iamVjdHMuXG4gKiBAdGVtcGxhdGUgVCBUeXBlIHBhcmFtZXRlciB1c2VkIGluIHRoZSBpbnRlcmZhY2UgbWV0aG9kc1xuICogQGludGVyZmFjZSBJbmplY3RhYmxlc1JlZ2lzdHJ5XG4gKiBAbWVtYmVyT2YgbW9kdWxlOmluamVjdGFibGUtZGVjb3JhdG9yc1xuICovXG5leHBvcnQgaW50ZXJmYWNlIEluamVjdGFibGVzUmVnaXN0cnkge1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEZldGNoZXMgYW4gaW5qZWN0YWJsZSBpbnN0YW5jZSBieSBpdHMgcmVnaXN0ZXJlZCBuYW1lLlxuICAgKiBAc3VtbWFyeSBSZXRyaWV2ZXMgYW4ge0BsaW5rIEluamVjdGFibGV9IGZyb20gdGhlIHJlZ2lzdHJ5IGJ5IG5hbWUsIG9wdGlvbmFsbHkgcGFzc2luZyBjb25zdHJ1Y3RvciBhcmd1bWVudHMuXG4gICAqIEB0ZW1wbGF0ZSBUIFR5cGUgb2YgdGhlIGluamVjdGFibGUgb2JqZWN0IHRvIHJldHJpZXZlXG4gICAqIEBwYXJhbSB7c3ltYm9sfSBuYW1lIFRoZSByZWdpc3RlcmVkIG5hbWUgb2YgdGhlIGluamVjdGFibGUgdG8gcmV0cmlldmVcbiAgICogQHBhcmFtIHthbnlbXX0gYXJncyBDb25zdHJ1Y3RvciBhcmd1bWVudHMgdG8gcGFzcyB3aGVuIGluc3RhbnRpYXRpbmcgdGhlIGluamVjdGFibGVcbiAgICogQHJldHVybiB7SW5qZWN0YWJsZTxUPiB8IHVuZGVmaW5lZH0gVGhlIGluamVjdGFibGUgaW5zdGFuY2Ugb3IgdW5kZWZpbmVkIGlmIG5vdCBmb3VuZFxuICAgKiBAbWVtYmVyT2YgbW9kdWxlOmluamVjdGFibGUtZGVjb3JhdG9yc1xuICAgKi9cbiAgZ2V0PFQ+KFxuICAgIG5hbWU6IHN5bWJvbCB8IHN0cmluZyB8IHsgbmV3ICguLi5hcmdzOiBhbnlbXSk6IFQgfSxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBUIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQWRkcyBhIGNsYXNzIG9yIG9iamVjdCB0byB0aGUgaW5qZWN0YWJsZSByZWdpc3RyeS5cbiAgICogQHN1bW1hcnkgUmVnaXN0ZXJzIGFuIGluamVjdGFibGUgY29uc3RydWN0b3Igb3IgaW5zdGFuY2Ugd2l0aCB0aGUgcmVnaXN0cnksIG1ha2luZyBpdCBhdmFpbGFibGUgZm9yIGluamVjdGlvbi5cbiAgICogQHRlbXBsYXRlIFQgVHlwZSBvZiB0aGUgaW5qZWN0YWJsZSBvYmplY3QgdG8gcmVnaXN0ZXJcbiAgICogQHBhcmFtIHtJbmplY3RhYmxlPFQ+fSBjb25zdHJ1Y3RvciBUaGUgY2xhc3MgY29uc3RydWN0b3Igb3Igb2JqZWN0IGluc3RhbmNlIHRvIHJlZ2lzdGVyXG4gICAqIEBwYXJhbSBvcHRpb25zXG4gICAqIEBwYXJhbSB7YW55W119IGFyZ3MgQWRkaXRpb25hbCBhcmd1bWVudHMgZm9yIHJlZ2lzdHJhdGlvbiAoY2F0ZWdvcnksIHNpbmdsZXRvbiBmbGFnLCBldGMuKVxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKiBAbWVtYmVyT2YgbW9kdWxlOmluamVjdGFibGUtZGVjb3JhdG9yc1xuICAgKi9cbiAgcmVnaXN0ZXI8VD4oXG4gICAgY29uc3RydWN0b3I6IEluamVjdGFibGU8VD4sXG4gICAgY2F0ZWdvcnk6IHN5bWJvbCB8IHVuZGVmaW5lZCxcbiAgICBvcHRpb25zOiBJbmplY3RhYmxlT3B0aW9uczxUPixcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiB2b2lkO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBhbiBpbmplY3RhYmxlIGNsYXNzLlxuICAgKiBAc3VtbWFyeSBJbnN0YW50aWF0ZXMgYW4gaW5qZWN0YWJsZSBjbGFzcyB1c2luZyBpdHMgY29uc3RydWN0b3IgYW5kIHRoZSBwcm92aWRlZCBhcmd1bWVudHMuXG4gICAqIEB0ZW1wbGF0ZSBUIFR5cGUgb2YgdGhlIG9iamVjdCB0byBidWlsZFxuICAgKiBAcGFyYW0ge3N5bWJvbH0gbmFtZSBPYmplY3QgY29udGFpbmluZyB0aGUgbmFtZSBvZiB0aGUgaW5qZWN0YWJsZSB0byBidWlsZFxuICAgKiBAcGFyYW0ge2FueVtdfSBhcmdzIENvbnN0cnVjdG9yIGFyZ3VtZW50cyB0byBwYXNzIHdoZW4gaW5zdGFudGlhdGluZyB0aGUgaW5qZWN0YWJsZVxuICAgKiBAcmV0dXJuIHtUfSBUaGUgbmV3bHkgY3JlYXRlZCBpbnN0YW5jZVxuICAgKiBAbWVtYmVyT2YgbW9kdWxlOmluamVjdGFibGUtZGVjb3JhdG9yc1xuICAgKi9cbiAgYnVpbGQ8VD4obmFtZTogc3ltYm9sLCAuLi5hcmdzOiBhbnlbXSk6IFQ7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlZmF1bHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIEluamVjdGFibGVzUmVnaXN0cnkgaW50ZXJmYWNlLlxuICogQHN1bW1hcnkgSG9sZHMgdGhlIHZhcmlvdXMge0BsaW5rIEluamVjdGFibGV9cyBpbiBhIGNhY2hlIGFuZCBwcm92aWRlcyBtZXRob2RzIHRvIHJlZ2lzdGVyLCByZXRyaWV2ZSwgYW5kIGJ1aWxkIHRoZW0uXG4gKiBAdGVtcGxhdGUgVCBUeXBlIHBhcmFtZXRlciB1c2VkIGluIHRoZSBjbGFzcyBtZXRob2RzXG4gKlxuICogQGNsYXNzIEluamVjdGFibGVSZWdpc3RyeUltcFxuICogQGltcGxlbWVudHMgSW5qZWN0YWJsZXNSZWdpc3RyeVxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6aW5qZWN0YWJsZS1kZWNvcmF0b3JzXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIENyZWF0ZSBhIG5ldyByZWdpc3RyeVxuICogY29uc3QgcmVnaXN0cnkgPSBuZXcgSW5qZWN0YWJsZVJlZ2lzdHJ5SW1wKCk7XG4gKlxuICogLy8gUmVnaXN0ZXIgYSBjbGFzc1xuICogY2xhc3MgTXlTZXJ2aWNlIHtcbiAqICAgZG9Tb21ldGhpbmcoKSB7XG4gKiAgICAgcmV0dXJuICdIZWxsbyBXb3JsZCc7XG4gKiAgIH1cbiAqIH1cbiAqIHJlZ2lzdHJ5LnJlZ2lzdGVyKE15U2VydmljZSwgJ015U2VydmljZScsIHRydWUpO1xuICpcbiAqIC8vIEdldCB0aGUgaW5zdGFuY2VcbiAqIGNvbnN0IHNlcnZpY2UgPSByZWdpc3RyeS5nZXQoJ015U2VydmljZScpO1xuICogc2VydmljZS5kb1NvbWV0aGluZygpOyAvLyAnSGVsbG8gV29ybGQnXG4gKlxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDbGllbnRcbiAqICAgcGFydGljaXBhbnQgUmVnaXN0cnlcbiAqXG4gKiAgIENsaWVudC0+PlJlZ2lzdHJ5OiByZWdpc3RlcihNeVNlcnZpY2UpXG4gKiAgIFJlZ2lzdHJ5LT4+UmVnaXN0cnk6IFN0b3JlIGluIGNhY2hlXG4gKlxuICogICBDbGllbnQtPj5SZWdpc3RyeTogZ2V0KFwiTXlTZXJ2aWNlXCIpXG4gKiAgIGFsdCBJbnN0YW5jZSBleGlzdHMgYW5kIGlzIHNpbmdsZXRvblxuICogICAgIFJlZ2lzdHJ5LS0+PkNsaWVudDogUmV0dXJuIGNhY2hlZCBpbnN0YW5jZVxuICogICBlbHNlIE5vIGluc3RhbmNlIG9yIG5vdCBzaW5nbGV0b25cbiAqICAgICBSZWdpc3RyeS0+PlJlZ2lzdHJ5OiBidWlsZChuYW1lKVxuICogICAgIFJlZ2lzdHJ5LS0+PkNsaWVudDogUmV0dXJuIG5ldyBpbnN0YW5jZVxuICogICBlbmRcbiAqL1xuZXhwb3J0IGNsYXNzIEluamVjdGFibGVSZWdpc3RyeUltcCBpbXBsZW1lbnRzIEluamVjdGFibGVzUmVnaXN0cnkge1xuICBwcml2YXRlIGNhY2hlOiBSZWNvcmQ8c3ltYm9sLCBJbmplY3RhYmxlRGVmPiA9IHt9O1xuXG4gIGhhczxUPihuYW1lOiBzeW1ib2wgfCB7IG5ldyAoLi4uYXJnczogYW55W10pOiBUIH0pOiBib29sZWFuIHtcbiAgICBpZiAodHlwZW9mIG5hbWUgPT09IFwic3ltYm9sXCIpIHJldHVybiBuYW1lIGluIHRoaXMuY2FjaGU7XG4gICAgcmV0dXJuIFN5bWJvbC5mb3IobmFtZS50b1N0cmluZygpKSBpbiB0aGlzLmNhY2hlO1xuICB9XG5cbiAgLyoqXG4gICAqIEBpbmhlcml0RG9jXG4gICAqL1xuICBnZXQ8VD4oXG4gICAgbmFtZTogc3ltYm9sIHwgc3RyaW5nIHwgeyBuZXcgKC4uLmFyZ3M6IGFueVtdKTogVCB9LFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFQgfCB1bmRlZmluZWQge1xuICAgIGlmICh0eXBlb2YgbmFtZSA9PT0gXCJzdHJpbmdcIikgbmFtZSA9IFN5bWJvbC5mb3IobmFtZSk7XG4gICAgaWYgKHR5cGVvZiBuYW1lICE9PSBcInN5bWJvbFwiKSB7XG4gICAgICBjb25zdCBtZXRhID0gUmVmbGVjdC5nZXRNZXRhZGF0YShcbiAgICAgICAgZ2V0SW5qZWN0S2V5KEluamVjdGFibGVzS2V5cy5JTkpFQ1RBQkxFKSxcbiAgICAgICAgbmFtZVxuICAgICAgKTtcbiAgICAgIG5hbWUgPSAobWV0YT8uc3ltYm9sIGFzIHN5bWJvbCkgfHwgU3ltYm9sLmZvcihuYW1lLnRvU3RyaW5nKCkpO1xuICAgIH1cbiAgICBpZiAoIW5hbWUpIHRocm93IG5ldyBFcnJvcihgSW5qZWN0YWJsZSAke25hbWV9IG5vdCBmb3VuZGApO1xuXG4gICAgaWYgKCEoKG5hbWUgYXMgc3ltYm9sKSBpbiB0aGlzLmNhY2hlKSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgY29uc3QgY2FjaGUgPSB0aGlzLmNhY2hlW25hbWVdO1xuICAgIGlmICghY2FjaGUub3B0aW9ucy5zaW5nbGV0b24gJiYgIWNhY2hlLmluc3RhbmNlKVxuICAgICAgcmV0dXJuIHRoaXMuYnVpbGQ8VD4obmFtZSwgLi4uYXJncyk7XG4gICAgcmV0dXJuIGNhY2hlLmluc3RhbmNlIHx8IHRoaXMuYnVpbGQ8VD4obmFtZSwgLi4uYXJncyk7XG4gIH1cbiAgLyoqXG4gICAqIEBpbmhlcml0RG9jXG4gICAqL1xuICByZWdpc3RlcjxUPihcbiAgICBvYmo6IEluamVjdGFibGU8VD4sXG4gICAgY2F0ZWdvcnk6IHN5bWJvbCB8IHVuZGVmaW5lZCxcbiAgICBvcHRpb25zOiBJbmplY3RhYmxlT3B0aW9uczxUPixcbiAgICBmb3JjZTogYm9vbGVhbiA9IGZhbHNlXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IGNhc3RPYmo6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBvYmogYXMgUmVjb3JkPHN0cmluZywgYW55PjtcblxuICAgIGNvbnN0IGNvbnN0cnVjdG9yID0gIWNhc3RPYmoubmFtZSAmJiBjYXN0T2JqLmNvbnN0cnVjdG9yO1xuICAgIGlmICh0eXBlb2YgY2FzdE9iaiAhPT0gXCJmdW5jdGlvblwiICYmICFjb25zdHJ1Y3RvcilcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEluamVjdGFibGUgcmVnaXN0ZXJpbmcgZmFpbGVkLiBNaXNzaW5nIENsYXNzIG5hbWUgb3IgY29uc3RydWN0b3JgXG4gICAgICApO1xuXG4gICAgY29uc3QgbmFtZSA9IGNhdGVnb3J5IHx8IFN5bWJvbC5mb3IoKG9iaiBhcyBhbnkpLnRvU3RyaW5nKCkpO1xuXG4gICAgaWYgKCF0aGlzLmNhY2hlW25hbWVdIHx8IGZvcmNlKVxuICAgICAgdGhpcy5jYWNoZVtuYW1lXSA9IHtcbiAgICAgICAgaW5zdGFuY2U6IG9wdGlvbnMuc2luZ2xldG9uICYmIGNvbnN0cnVjdG9yID8gb2JqIDogdW5kZWZpbmVkLFxuICAgICAgICBjb25zdHJ1Y3RvcjogIWNvbnN0cnVjdG9yID8gb2JqIDogKG9iaiBhcyBhbnkpLmNvbnN0cnVjdG9yLFxuICAgICAgICBvcHRpb25zOiBvcHRpb25zLFxuICAgICAgfTtcbiAgfVxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIGJ1aWxkPFQ+KG5hbWU6IHN5bWJvbCwgLi4uYXJnczogYW55W10pOiBUIHtcbiAgICBjb25zdCB7IGNvbnN0cnVjdG9yLCBvcHRpb25zIH0gPSB0aGlzLmNhY2hlW25hbWVdO1xuICAgIGxldCBpbnN0YW5jZTogVDtcbiAgICB0cnkge1xuICAgICAgaW5zdGFuY2UgPSBuZXcgY29uc3RydWN0b3IoLi4uYXJncyk7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgZmFpbGVkIHRvIGJ1aWxkICR7bmFtZS50b1N0cmluZygpfSB3aXRoIGFyZ3MgJHthcmdzfTogJHtlfWBcbiAgICAgICk7XG4gICAgfVxuICAgIGlmIChvcHRpb25zLnNpbmdsZXRvbikge1xuICAgICAgdGhpcy5jYWNoZVtuYW1lXS5pbnN0YW5jZSA9IGluc3RhbmNlO1xuICAgIH1cbiAgICBpZiAob3B0aW9ucy5jYWxsYmFjaykgaW5zdGFuY2UgPSBvcHRpb25zLmNhbGxiYWNrKGluc3RhbmNlLCAuLi5hcmdzKTtcbiAgICByZXR1cm4gaW5zdGFuY2U7XG4gIH1cbn1cbiIsImltcG9ydCB7XG4gIEluamVjdGFibGUsXG4gIEluamVjdGFibGVSZWdpc3RyeUltcCxcbiAgSW5qZWN0YWJsZXNSZWdpc3RyeSxcbn0gZnJvbSBcIi4vcmVnaXN0cnlcIjtcbmltcG9ydCB7IEluamVjdGFibGVPcHRpb25zIH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ2VudHJhbCByZWdpc3RyeSBmb3IgbWFuYWdpbmcgaW5qZWN0YWJsZSBkZXBlbmRlbmNpZXMuXG4gKiBAc3VtbWFyeSBTdGF0aWMgY2xhc3MgaG9sZGluZyB0aGUgYWNjZXNzIHRvIHRoZSBpbmplY3RhYmxlcyBmdW5jdGlvbnMuIFByb3ZpZGVzIG1ldGhvZHMgZm9yIHJlZ2lzdGVyaW5nLFxuICogcmV0cmlldmluZywgYW5kIGJ1aWxkaW5nIGluamVjdGFibGUgb2JqZWN0cy5cbiAqIEB0ZW1wbGF0ZSBUIFR5cGUgb2YgdGhlIGluamVjdGFibGUgb2JqZWN0XG4gKlxuICogQGNsYXNzIEluamVjdGFibGVzXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIERlZmluZSBhbiBpbmplY3RhYmxlIGNsYXNzXG4gKiBAaW5qZWN0YWJsZSgpXG4gKiBjbGFzcyBNeVNlcnZpY2Uge1xuICogICBkb1NvbWV0aGluZygpIHtcbiAqICAgICByZXR1cm4gJ0hlbGxvIFdvcmxkJztcbiAqICAgfVxuICogfVxuICpcbiAqIC8vIEluamVjdCB0aGUgc2VydmljZSBpbnRvIGFub3RoZXIgY2xhc3NcbiAqIGNsYXNzIE15Q29tcG9uZW50IHtcbiAqICAgQGluamVjdCgpXG4gKiAgIHByaXZhdGUgc2VydmljZSE6IE15U2VydmljZTtcbiAqXG4gKiAgIHVzZVNlcnZpY2UoKSB7XG4gKiAgICAgcmV0dXJuIHRoaXMuc2VydmljZS5kb1NvbWV0aGluZygpO1xuICogICB9XG4gKiB9XG4gKlxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDbGllbnRcbiAqICAgcGFydGljaXBhbnQgSW5qZWN0YWJsZXNcbiAqICAgcGFydGljaXBhbnQgUmVnaXN0cnlcbiAqXG4gKiAgIENsaWVudC0+PkluamVjdGFibGVzOiByZWdpc3RlcihNeVNlcnZpY2UpXG4gKiAgIEluamVjdGFibGVzLT4+UmVnaXN0cnk6IHJlZ2lzdGVyKE15U2VydmljZSlcbiAqICAgUmVnaXN0cnktLT4+SW5qZWN0YWJsZXM6IHZvaWRcbiAqXG4gKiAgIENsaWVudC0+PkluamVjdGFibGVzOiBnZXQoXCJNeVNlcnZpY2VcIilcbiAqICAgSW5qZWN0YWJsZXMtPj5SZWdpc3RyeTogZ2V0KFwiTXlTZXJ2aWNlXCIpXG4gKiAgIFJlZ2lzdHJ5LS0+PkluamVjdGFibGVzOiBNeVNlcnZpY2UgaW5zdGFuY2VcbiAqICAgSW5qZWN0YWJsZXMtLT4+Q2xpZW50OiBNeVNlcnZpY2UgaW5zdGFuY2VcbiAqL1xuZXhwb3J0IGNsYXNzIEluamVjdGFibGVzIHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBIb2xkcyB0aGUgYWN0aXZlIHJlZ2lzdHJ5IGltcGxlbWVudGF0aW9uIHVzZWQgYnkgdGhlIEluamVjdGFibGVzIGZhY2FkZS5cbiAgICogQHN1bW1hcnkgSW50ZXJuYWwgc3RhdGljIHJlZmVyZW5jZSB0aGF0IGNhbiBiZSBzd2FwcGVkIHZpYSBzZXRSZWdpc3RyeSB0byBjdXN0b21pemUgaG93IGluamVjdGFibGVzIGFyZSBzdG9yZWQgYW5kIHJldHJpZXZlZC5cbiAgICogQHR5cGUge0luamVjdGFibGVzUmVnaXN0cnkgfCB1bmRlZmluZWR9XG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBhY3RpbmdJbmplY3RhYmxlc1JlZ2lzdHJ5PzogSW5qZWN0YWJsZXNSZWdpc3RyeSA9IHVuZGVmaW5lZDtcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKCkge31cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEZldGNoZXMgYW4gaW5qZWN0YWJsZSBpbnN0YW5jZSBieSBpdHMgcmVnaXN0ZXJlZCBuYW1lLlxuICAgKiBAc3VtbWFyeSBSZXRyaWV2ZXMgdGhlIG5hbWVkIHtAbGluayBJbmplY3RhYmxlfSBmcm9tIHRoZSByZWdpc3RyeS4gSWYgdGhlIGluamVjdGFibGUgaXMgYSBzaW5nbGV0b24sXG4gICAqIHJldHVybnMgdGhlIGV4aXN0aW5nIGluc3RhbmNlLiBPdGhlcndpc2UsIGNyZWF0ZXMgYSBuZXcgaW5zdGFuY2UuXG4gICAqIEB0ZW1wbGF0ZSBUIFR5cGUgb2YgdGhlIGluamVjdGFibGUgb2JqZWN0IHRvIHJldHJpZXZlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIFRoZSByZWdpc3RlcmVkIG5hbWUgb2YgdGhlIGluamVjdGFibGUgdG8gcmV0cmlldmVcbiAgICogQHBhcmFtIHthbnlbXX0gYXJncyBDb25zdHJ1Y3RvciBhcmd1bWVudHMgdG8gcGFzcyB3aGVuIGluc3RhbnRpYXRpbmcgdGhlIGluamVjdGFibGVcbiAgICogQHJldHVybiB7SW5qZWN0YWJsZTxUPiB8IHVuZGVmaW5lZH0gVGhlIGluamVjdGFibGUgaW5zdGFuY2Ugb3IgdW5kZWZpbmVkIGlmIG5vdCBmb3VuZFxuICAgKi9cbiAgc3RhdGljIGdldDxUPihcbiAgICBuYW1lOiBzeW1ib2wgfCBzdHJpbmcgfCB7IG5ldyAoLi4uYXJnczogYW55W10pOiBUIH0sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogVCB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIEluamVjdGFibGVzLmdldFJlZ2lzdHJ5KCkuZ2V0KG5hbWUsIC4uLmFyZ3MpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBBZGRzIGEgY2xhc3Mgb3Igb2JqZWN0IHRvIHRoZSBpbmplY3RhYmxlIHJlZ2lzdHJ5LlxuICAgKiBAc3VtbWFyeSBSZWdpc3RlcnMgYW4gaW5qZWN0YWJsZSBjb25zdHJ1Y3RvciBvciBpbnN0YW5jZSB3aXRoIHRoZSByZWdpc3RyeSwgbWFraW5nIGl0IGF2YWlsYWJsZSBmb3IgaW5qZWN0aW9uLlxuICAgKiBAdGVtcGxhdGUgVCBUeXBlIG9mIHRoZSBpbmplY3RhYmxlIG9iamVjdCB0byByZWdpc3RlclxuICAgKiBAcGFyYW0ge0luamVjdGFibGU8VD59IGNvbnN0cnVjdG9yIFRoZSBjbGFzcyBjb25zdHJ1Y3RvciBvciBvYmplY3QgaW5zdGFuY2UgdG8gcmVnaXN0ZXJcbiAgICogQHBhcmFtIHthbnlbXX0gYXJncyBBZGRpdGlvbmFsIGFyZ3VtZW50cyBmb3IgcmVnaXN0cmF0aW9uIChjYXRlZ29yeSwgc2luZ2xldG9uIGZsYWcsIGV0Yy4pXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBzdGF0aWMgcmVnaXN0ZXI8VD4oY29uc3RydWN0b3I6IEluamVjdGFibGU8VD4sIC4uLmFyZ3M6IGFueVtdKTogdm9pZCB7XG4gICAgcmV0dXJuIEluamVjdGFibGVzLmdldFJlZ2lzdHJ5KCkucmVnaXN0ZXIoXG4gICAgICBjb25zdHJ1Y3RvcixcbiAgICAgIC4uLihhcmdzIGFzIFtzeW1ib2wsIEluamVjdGFibGVPcHRpb25zPFQ+XSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIGFuIGluamVjdGFibGUgY2xhc3MuXG4gICAqIEBzdW1tYXJ5IEluc3RhbnRpYXRlcyBhbiBpbmplY3RhYmxlIGNsYXNzIHVzaW5nIGl0cyBjb25zdHJ1Y3RvciBhbmQgdGhlIHByb3ZpZGVkIGFyZ3VtZW50cy5cbiAgICogQHRlbXBsYXRlIFQgVHlwZSBvZiB0aGUgb2JqZWN0IHRvIGJ1aWxkXG4gICAqIEBwYXJhbSB7c3ltYm9sfSBuYW1lIHN5bWJvbCByZWZlcmVuY2luZyB0aGUgaW5qZWN0YWJsZVxuICAgKiBAcGFyYW0ge2FueVtdfSBhcmdzIENvbnN0cnVjdG9yIGFyZ3VtZW50cyB0byBwYXNzIHdoZW4gaW5zdGFudGlhdGluZyB0aGUgaW5qZWN0YWJsZVxuICAgKiBAcmV0dXJuIHtUfSBUaGUgbmV3bHkgY3JlYXRlZCBpbnN0YW5jZVxuICAgKi9cbiAgc3RhdGljIGJ1aWxkPFQ+KG5hbWU6IHN5bWJvbCwgLi4uYXJnczogYW55W10pOiBUIHtcbiAgICByZXR1cm4gSW5qZWN0YWJsZXMuZ2V0UmVnaXN0cnkoKS5idWlsZChuYW1lLCAuLi5hcmdzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVwbGFjZXMgdGhlIGN1cnJlbnQgcmVnaXN0cnkgaW1wbGVtZW50YXRpb24uXG4gICAqIEBzdW1tYXJ5IFNldHMgYSBuZXcge0BsaW5rIEluamVjdGFibGVzUmVnaXN0cnl9IGltcGxlbWVudGF0aW9uLCBhbGxvd2luZyBmb3IgY3VzdG9tIHJlZ2lzdHJ5IGJlaGF2aW9yLlxuICAgKiBAcGFyYW0ge0luamVjdGFibGVzUmVnaXN0cnl9IG9wZXJhdGlvbnNSZWdpc3RyeSBUaGUgbmV3IGltcGxlbWVudGF0aW9uIG9mIFJlZ2lzdHJ5IHRvIHVzZVxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgc3RhdGljIHNldFJlZ2lzdHJ5KG9wZXJhdGlvbnNSZWdpc3RyeTogSW5qZWN0YWJsZXNSZWdpc3RyeSk6IHZvaWQge1xuICAgIEluamVjdGFibGVzLmFjdGluZ0luamVjdGFibGVzUmVnaXN0cnkgPSBvcGVyYXRpb25zUmVnaXN0cnk7XG4gIH1cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBQcm92aWRlcyBhY2Nlc3MgdG8gdGhlIGN1cnJlbnQgcmVnaXN0cnkgaW5zdGFuY2UuXG4gICAqIEBzdW1tYXJ5IFJldHVybnMgdGhlIGN1cnJlbnQge0BsaW5rIEluamVjdGFibGVzUmVnaXN0cnl9IG9yIGNyZWF0ZXMgYSBkZWZhdWx0IG9uZSBpZiBub25lIGV4aXN0cy5cbiAgICogQHJldHVybiB7SW5qZWN0YWJsZXNSZWdpc3RyeX0gVGhlIGN1cnJlbnQgcmVnaXN0cnkgaW5zdGFuY2VcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGdldFJlZ2lzdHJ5KCk6IEluamVjdGFibGVzUmVnaXN0cnkge1xuICAgIGlmICghSW5qZWN0YWJsZXMuYWN0aW5nSW5qZWN0YWJsZXNSZWdpc3RyeSlcbiAgICAgIEluamVjdGFibGVzLmFjdGluZ0luamVjdGFibGVzUmVnaXN0cnkgPSBuZXcgSW5qZWN0YWJsZVJlZ2lzdHJ5SW1wKCk7XG4gICAgcmV0dXJuIEluamVjdGFibGVzLmFjdGluZ0luamVjdGFibGVzUmVnaXN0cnk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENsZWFycyBhbGwgcmVnaXN0ZXJlZCBpbmplY3RhYmxlcy5cbiAgICogQHN1bW1hcnkgUmVzZXRzIHRoZSByZWdpc3RyeSB0byBhIGNsZWFuIHN0YXRlIGJ5IGNyZWF0aW5nIGEgbmV3IGVtcHR5IHJlZ2lzdHJ5IGluc3RhbmNlLlxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgc3RhdGljIHJlc2V0KCk6IHZvaWQge1xuICAgIEluamVjdGFibGVzLnNldFJlZ2lzdHJ5KG5ldyBJbmplY3RhYmxlUmVnaXN0cnlJbXAoKSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlbW92ZXMgc3BlY2lmaWMgaW5qZWN0YWJsZXMgZnJvbSB0aGUgcmVnaXN0cnkgYmFzZWQgb24gYSBwYXR0ZXJuLlxuICAgKiBAc3VtbWFyeSBTZWxlY3RpdmVseSByZXNldHMgdGhlIHJlZ2lzdHJ5IGJ5IHJlbW92aW5nIG9ubHkgdGhlIGluamVjdGFibGVzIHdob3NlIG5hbWVzIG1hdGNoIHRoZSBwcm92aWRlZCBwYXR0ZXJuLlxuICAgKiBAcGFyYW0ge3N0cmluZyB8IFJlZ0V4cH0gbWF0Y2ggQSBzdHJpbmcgb3IgcmVndWxhciBleHByZXNzaW9uIHBhdHRlcm4gdG8gbWF0Y2ggYWdhaW5zdCBpbmplY3RhYmxlIG5hbWVzXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBzdGF0aWMgc2VsZWN0aXZlUmVzZXQobWF0Y2g6IHN0cmluZyB8IFJlZ0V4cCk6IHZvaWQge1xuICAgIGNvbnN0IHJlZ2V4cCA9IHR5cGVvZiBtYXRjaCA9PT0gXCJzdHJpbmdcIiA/IG5ldyBSZWdFeHAobWF0Y2gpIDogbWF0Y2g7XG4gICAgKEluamVjdGFibGVzLmFjdGluZ0luamVjdGFibGVzUmVnaXN0cnkgYXMgYW55KVtcImNhY2hlXCJdID0gT2JqZWN0LmVudHJpZXMoXG4gICAgICAoSW5qZWN0YWJsZXMuYWN0aW5nSW5qZWN0YWJsZXNSZWdpc3RyeSBhcyBhbnkpW1wiY2FjaGVcIl1cbiAgICApLnJlZHVjZSgoYWNjdW06IFJlY29yZDxzdHJpbmcsIGFueT4sIFtrZXksIHZhbF0pID0+IHtcbiAgICAgIGlmICgha2V5Lm1hdGNoKHJlZ2V4cCkpIGFjY3VtW2tleV0gPSB2YWw7XG4gICAgICByZXR1cm4gYWNjdW07XG4gICAgfSwge30pO1xuICB9XG59XG4iLCJpbXBvcnQgeyBEZWZhdWx0SW5qZWN0YWJsZXNDb25maWcsIEluamVjdGFibGVzS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgSW5qZWN0YWJsZXMgfSBmcm9tIFwiLi9JbmplY3RhYmxlc1wiO1xuaW1wb3J0IHsgZ2V0SW5qZWN0S2V5IH0gZnJvbSBcIi4vdXRpbHNcIjtcbmltcG9ydCB7IEluamVjdGFibGVNZXRhZGF0YSwgSW5zdGFuY2VDYWxsYmFjayB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBEZWNvcmF0aW9uLCBNZXRhZGF0YSwgcHJvcCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdGlvblwiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDb25maWd1cmF0aW9uIG9wdGlvbnMgZm9yIHRoZSBAaW5qZWN0YWJsZSBkZWNvcmF0b3IuXG4gKiBAc3VtbWFyeSBDb250cm9scyBsaWZlY3ljbGUgKHNpbmdsZXRvbiB2cyBvbi1kZW1hbmQpIGFuZCBhbiBvcHRpb25hbCBpbnN0YW5jZSB0cmFuc2Zvcm1hdGlvbiBjYWxsYmFjayBleGVjdXRlZCBwb3N0LWNvbnN0cnVjdGlvbi5cbiAqIEB0ZW1wbGF0ZSBUIFRoZSBpbnN0YW5jZSB0eXBlIGFmZmVjdGVkIGJ5IHRoZSBjYWxsYmFjayB3aGVuIHByb3ZpZGVkLlxuICogQHByb3BlcnR5IHtib29sZWFufSBzaW5nbGV0b24gV2hlbiB0cnVlLCBhIHNpbmdsZSBpbnN0YW5jZSBpcyBzaGFyZWQgKHNpbmdsZXRvbikuIFdoZW4gZmFsc2UsIGluc3RhbmNlcyBhcmUgY3JlYXRlZCBvbiBkZW1hbmQuXG4gKiBAcHJvcGVydHkge0luc3RhbmNlQ2FsbGJhY2s8VD59IFtjYWxsYmFja10gT3B0aW9uYWwgaG9vayB0byB0cmFuc2Zvcm0gdGhlIGluc3RhbmNlIGFmdGVyIGl0IGlzIGNvbnN0cnVjdGVkLlxuICogQHR5cGVkZWYgSW5qZWN0YWJsZUNvbmZpZ1xuICogQG1lbWJlck9mIG1vZHVsZTppbmplY3RhYmxlLWRlY29yYXRvcnNcbiAqL1xuZXhwb3J0IHR5cGUgSW5qZWN0YWJsZUNvbmZpZyA9IHtcbiAgc2luZ2xldG9uOiBib29sZWFuO1xuICBjYWxsYmFjaz86IEluc3RhbmNlQ2FsbGJhY2s8YW55Pjtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBpbmplY3RhYmxlQmFzZURlY29yYXRvcihcbiAgY2F0ZWdvcnk/OiBzdHJpbmcgfCBDb25zdHJ1Y3RvciB8IFBhcnRpYWw8SW5qZWN0YWJsZUNvbmZpZz4sXG4gIGNmZz86IFBhcnRpYWw8SW5qZWN0YWJsZUNvbmZpZz5cbikge1xuICBjZmcgPVxuICAgIGNmZyB8fFxuICAgICh0eXBlb2YgY2F0ZWdvcnkgPT09IFwib2JqZWN0XCJcbiAgICAgID8gT2JqZWN0LmFzc2lnbihjYXRlZ29yeSBhcyBSZWNvcmQ8YW55LCBhbnk+LCBEZWZhdWx0SW5qZWN0YWJsZXNDb25maWcpXG4gICAgICA6IERlZmF1bHRJbmplY3RhYmxlc0NvbmZpZyk7XG4gIGNhdGVnb3J5ID1cbiAgICB0eXBlb2YgY2F0ZWdvcnkgPT09IFwib2JqZWN0XCJcbiAgICAgID8gdW5kZWZpbmVkXG4gICAgICA6IHR5cGVvZiBjYXRlZ29yeSA9PT0gXCJzdHJpbmdcIlxuICAgICAgICA/IGNhdGVnb3J5XG4gICAgICAgIDogdHlwZW9mIGNhdGVnb3J5ID09PSBcImZ1bmN0aW9uXCIgJiYgY2F0ZWdvcnkubmFtZVxuICAgICAgICAgID8gY2F0ZWdvcnlcbiAgICAgICAgICA6IHVuZGVmaW5lZDtcbiAgcmV0dXJuIGZ1bmN0aW9uIGluamVjdGFibGVJbm5lckRlY29yYXRvcihvcmlnaW5hbDogYW55KSB7XG4gICAgY29uc3Qgc3ltYm9sID0gU3ltYm9sLmZvcihjYXRlZ29yeSB8fCBvcmlnaW5hbC50b1N0cmluZygpKTtcbiAgICBjYXRlZ29yeSA9IGNhdGVnb3J5IHx8IG9yaWdpbmFsLm5hbWU7XG5cbiAgICBjb25zdCBtZXRhZGF0YTogSW5qZWN0YWJsZU1ldGFkYXRhID0ge1xuICAgICAgY2xhc3M6IGNhdGVnb3J5IGFzIHN0cmluZyxcbiAgICAgIHN5bWJvbDogc3ltYm9sLFxuICAgIH07XG5cbiAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKFxuICAgICAgZ2V0SW5qZWN0S2V5KEluamVjdGFibGVzS2V5cy5JTkpFQ1RBQkxFKSxcbiAgICAgIG1ldGFkYXRhLFxuICAgICAgb3JpZ2luYWxcbiAgICApO1xuICAgIC8vIHRoZSBuZXcgY29uc3RydWN0b3IgYmVoYXZpb3VyXG4gICAgY29uc3QgbmV3Q29uc3RydWN0b3I6IGFueSA9IGZ1bmN0aW9uICguLi5hcmdzOiBhbnlbXSkge1xuICAgICAgcmV0dXJuIEluamVjdGFibGVzLmdldDxhbnk+KHN5bWJvbCwgLi4uYXJncyk7XG4gICAgfTtcblxuICAgIC8vIGNvcHkgcHJvdG90eXBlIHNvIGluc3RhbmNlb2Ygb3BlcmF0b3Igc3RpbGwgd29ya3NcbiAgICBuZXdDb25zdHJ1Y3Rvci5wcm90b3R5cGUgPSBvcmlnaW5hbC5wcm90b3R5cGU7XG4gICAgLy8gbmV3Q29uc3RydWN0b3IuX19wcm90b19fID0gb3JpZ2luYWwuX19wcm90b19fO1xuICAgIC8vIFNldHMgdGhlIHByb3BlciBjb25zdHJ1Y3RvciBuYW1lIGZvciB0eXBlIHZlcmlmaWNhdGlvblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShuZXdDb25zdHJ1Y3RvciwgXCJuYW1lXCIsIHtcbiAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgdmFsdWU6IG9yaWdpbmFsLnByb3RvdHlwZS5jb25zdHJ1Y3Rvci5uYW1lLFxuICAgIH0pO1xuXG4gICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShcbiAgICAgIGdldEluamVjdEtleShJbmplY3RhYmxlc0tleXMuSU5KRUNUQUJMRSksXG4gICAgICBtZXRhZGF0YSxcbiAgICAgIG5ld0NvbnN0cnVjdG9yXG4gICAgKTtcblxuICAgIEluamVjdGFibGVzLnJlZ2lzdGVyKG9yaWdpbmFsLCBzeW1ib2wsIGNmZyk7XG4gICAgLy8gcmV0dXJuIG5ldyBjb25zdHJ1Y3RvciAod2lsbCBvdmVycmlkZSBvcmlnaW5hbClcbiAgICByZXR1cm4gbmV3Q29uc3RydWN0b3I7XG4gIH07XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEdlbmVyaWMgY29uc3RydWN0b3IgdHlwZSBmb3IgY2xhc3MtbGlrZSB2YWx1ZXMuXG4gKiBAc3VtbWFyeSBSZXByZXNlbnRzIGFueSBjbGFzcyB0aGF0IGNhbiBiZSBpbnN0YW50aWF0ZWQgd2l0aCBhcmJpdHJhcnkgYXJndW1lbnRzLCBwcm9kdWNpbmcgYW4gaW5zdGFuY2Ugb2YgdHlwZSBULlxuICogQHRlbXBsYXRlIFQgVGhlIGluc3RhbmNlIHR5cGUgY3JlYXRlZCBieSB0aGUgY29uc3RydWN0b3IuXG4gKiBAdHlwZWRlZiBDb25zdHJ1Y3RvclxuICogQGV4YW1wbGVcbiAqIC8vIFVzaW5nIENvbnN0cnVjdG9yIHRvIHR5cGUgYSBmYWN0b3J5XG4gKiBmdW5jdGlvbiBtYWtlPFQ+KEN0b3I6IENvbnN0cnVjdG9yPFQ+LCAuLi5hcmdzOiBhbnlbXSk6IFQge1xuICogICByZXR1cm4gbmV3IEN0b3IoLi4uYXJncyk7XG4gKiB9XG4gKiBAbWVtYmVyT2YgbW9kdWxlOmluamVjdGFibGUtZGVjb3JhdG9yc1xuICovXG5leHBvcnQgdHlwZSBDb25zdHJ1Y3RvcjxUID0gYW55PiA9IHsgbmV3ICguLi5hcmdzOiBhbnlbXSk6IFQgfTtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVjb3JhdG9yIHRoYXQgbWFya3MgYSBjbGFzcyBhcyBhdmFpbGFibGUgZm9yIGRlcGVuZGVuY3kgaW5qZWN0aW9uLlxuICogQHN1bW1hcnkgRGVmaW5lcyBhIGNsYXNzIGFzIGFuIGluamVjdGFibGUgdGhhdCBjYW4gYmUgcmV0cmlldmVkIGZyb20gdGhlIHJlZ2lzdHJ5LlxuICogV2hlbiBhcHBsaWVkIHRvIGEgY2xhc3MsIHJlcGxhY2VzIGl0cyBjb25zdHJ1Y3RvciB3aXRoIG9uZSB0aGF0IHJldHVybnMgYW4gaW5zdGFuY2UuXG4gKlxuICogQHJldHVybiB7ZnVuY3Rpb24oYW55KTogYW55fSBBIGRlY29yYXRvciBmdW5jdGlvbiB0aGF0IHRyYW5zZm9ybXMgdGhlIGNsYXNzIGludG8gYW4gaW5qZWN0YWJsZS5cbiAqXG4gKiBAZnVuY3Rpb24gaW5qZWN0YWJsZVxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5qZWN0YWJsZSgpOiAob3JpZ2luYWw6IGFueSkgPT4gYW55O1xuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVjb3JhdG9yIHRoYXQgbWFya3MgYSBjbGFzcyBhcyBhdmFpbGFibGUgZm9yIGRlcGVuZGVuY3kgaW5qZWN0aW9uLlxuICogQHN1bW1hcnkgRGVmaW5lcyBhIGNsYXNzIGFzIGFuIGluamVjdGFibGUgdGhhdCBjYW4gYmUgcmV0cmlldmVkIGZyb20gdGhlIHJlZ2lzdHJ5LlxuICogV2hlbiBhcHBsaWVkIHRvIGEgY2xhc3MsIHJlcGxhY2VzIGl0cyBjb25zdHJ1Y3RvciB3aXRoIG9uZSB0aGF0IHJldHVybnMgYW4gaW5zdGFuY2UuXG4gKlxuICogQHBhcmFtIHtzdHJpbmcgfCBDb25zdHJ1Y3Rvcn0gY2F0ZWdvcnkgRGVmYXVsdHMgdG8gdGhlIGNsYXNzIGNhdGVnb3J5LiBVc2VmdWwgd2hlbiBtaW5pZmljYXRpb24gb2NjdXJzIGFuZCBuYW1lcyBhcmUgY2hhbmdlZCxcbiAqIG9yIHdoZW4geW91IHdhbnQgdG8gdXBjYXN0IHRoZSBvYmplY3QgdG8gYSBkaWZmZXJlbnQgdHlwZS5cbiAqXG4gKiBAcmV0dXJuIHtmdW5jdGlvbihhbnkpOiBhbnl9IEEgZGVjb3JhdG9yIGZ1bmN0aW9uIHRoYXQgdHJhbnNmb3JtcyB0aGUgY2xhc3MgaW50byBhbiBpbmplY3RhYmxlLlxuICpcbiAqIEBmdW5jdGlvbiBpbmplY3RhYmxlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbmplY3RhYmxlKFxuICBjYXRlZ29yeTogc3RyaW5nIHwgQ29uc3RydWN0b3Jcbik6IChvcmlnaW5hbDogYW55KSA9PiBhbnk7XG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWNvcmF0b3IgdGhhdCBtYXJrcyBhIGNsYXNzIGFzIGF2YWlsYWJsZSBmb3IgZGVwZW5kZW5jeSBpbmplY3Rpb24uXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgY2xhc3MgYXMgYW4gaW5qZWN0YWJsZSB0aGF0IGNhbiBiZSByZXRyaWV2ZWQgZnJvbSB0aGUgcmVnaXN0cnkuXG4gKiBXaGVuIGFwcGxpZWQgdG8gYSBjbGFzcywgcmVwbGFjZXMgaXRzIGNvbnN0cnVjdG9yIHdpdGggb25lIHRoYXQgcmV0dXJucyBhbiBpbnN0YW5jZS5cbiAqXG4gKiBAcGFyYW0ge1BhcnRpYWw8SW5qZWN0YWJsZUNvbmZpZz59IGNmZz1EZWZhdWx0SW5qZWN0YWJsZUNvbmZpZyBBbGxvd3Mgb3ZlcnJpZGluZyB0aGUgZGVmYXVsdCBzaW5nbGV0b24gYmVoYXZpb3IgYW5kIGFkZGluZyBhIGNhbGxiYWNrIGZ1bmN0aW9uLlxuICpcbiAqIEByZXR1cm4ge2Z1bmN0aW9uKGFueSk6IGFueX0gQSBkZWNvcmF0b3IgZnVuY3Rpb24gdGhhdCB0cmFuc2Zvcm1zIHRoZSBjbGFzcyBpbnRvIGFuIGluamVjdGFibGUuXG4gKlxuICogQGZ1bmN0aW9uIGluamVjdGFibGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluamVjdGFibGUoXG4gIGNmZzogUGFydGlhbDxJbmplY3RhYmxlQ29uZmlnPlxuKTogKG9yaWdpbmFsOiBhbnkpID0+IGFueTtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVjb3JhdG9yIHRoYXQgbWFya3MgYSBjbGFzcyBhcyBhdmFpbGFibGUgZm9yIGRlcGVuZGVuY3kgaW5qZWN0aW9uLlxuICogQHN1bW1hcnkgRGVmaW5lcyBhIGNsYXNzIGFzIGFuIGluamVjdGFibGUgdGhhdCBjYW4gYmUgcmV0cmlldmVkIGZyb20gdGhlIHJlZ2lzdHJ5LlxuICogV2hlbiBhcHBsaWVkIHRvIGEgY2xhc3MsIHJlcGxhY2VzIGl0cyBjb25zdHJ1Y3RvciB3aXRoIG9uZSB0aGF0IHJldHVybnMgYW4gaW5zdGFuY2UuXG4gKlxuICogQHBhcmFtIGNhdGVnb3J5IERlZmF1bHRzIHRvIHRoZSBjbGFzcyBjYXRlZ29yeS4gVXNlZnVsIHdoZW4gbWluaWZpY2F0aW9uIG9jY3VycyBhbmQgbmFtZXMgYXJlIGNoYW5nZWQsXG4gKiBvciB3aGVuIHlvdSB3YW50IHRvIHVwY2FzdCB0aGUgb2JqZWN0IHRvIGEgZGlmZmVyZW50IHR5cGUuXG4gKiBAcGFyYW0ge1BhcnRpYWw8SW5qZWN0YWJsZUNvbmZpZz59IGNmZz1EZWZhdWx0SW5qZWN0YWJsZUNvbmZpZyBBbGxvd3Mgb3ZlcnJpZGluZyB0aGUgZGVmYXVsdCBzaW5nbGV0b24gYmVoYXZpb3IgYW5kIGFkZGluZyBhIGNhbGxiYWNrIGZ1bmN0aW9uLlxuICpcbiAqIEByZXR1cm4ge2Z1bmN0aW9uKGFueSk6IGFueX0gQSBkZWNvcmF0b3IgZnVuY3Rpb24gdGhhdCB0cmFuc2Zvcm1zIHRoZSBjbGFzcyBpbnRvIGFuIGluamVjdGFibGUuXG4gKlxuICogQGZ1bmN0aW9uIGluamVjdGFibGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluamVjdGFibGUoXG4gIGNhdGVnb3J5OiBzdHJpbmcgfCBDb25zdHJ1Y3RvcixcbiAgY2ZnOiBQYXJ0aWFsPEluamVjdGFibGVDb25maWc+XG4pOiAob3JpZ2luYWw6IGFueSkgPT4gYW55O1xuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVjb3JhdG9yIHRoYXQgbWFya3MgYSBjbGFzcyBhcyBhdmFpbGFibGUgZm9yIGRlcGVuZGVuY3kgaW5qZWN0aW9uLlxuICogQHN1bW1hcnkgRGVmaW5lcyBhIGNsYXNzIGFzIGFuIGluamVjdGFibGUgdGhhdCBjYW4gYmUgcmV0cmlldmVkIGZyb20gdGhlIHJlZ2lzdHJ5LlxuICogV2hlbiBhcHBsaWVkIHRvIGEgY2xhc3MsIHJlcGxhY2VzIGl0cyBjb25zdHJ1Y3RvciB3aXRoIG9uZSB0aGF0IHJldHVybnMgYW4gaW5zdGFuY2UuXG4gKlxuICogQHBhcmFtIHtzdHJpbmcgfCBDb25zdHJ1Y3Rvcn0gW2NhdGVnb3J5XSBEZWZhdWx0cyB0byB0aGUgY2xhc3MgY2F0ZWdvcnkuIFVzZWZ1bCB3aGVuIG1pbmlmaWNhdGlvbiBvY2N1cnMgYW5kIG5hbWVzIGFyZSBjaGFuZ2VkLFxuICogb3Igd2hlbiB5b3Ugd2FudCB0byB1cGNhc3QgdGhlIG9iamVjdCB0byBhIGRpZmZlcmVudCB0eXBlLlxuICogQHBhcmFtIHtQYXJ0aWFsPEluamVjdGFibGVDb25maWc+fSBbY2ZnPURlZmF1bHRJbmplY3RhYmxlQ29uZmlnXSBBbGxvd3Mgb3ZlcnJpZGluZyB0aGUgZGVmYXVsdCBzaW5nbGV0b24gYmVoYXZpb3IgYW5kIGFkZGluZyBhIGNhbGxiYWNrIGZ1bmN0aW9uLlxuICpcbiAqIEByZXR1cm4ge2Z1bmN0aW9uKGFueSk6IGFueX0gQSBkZWNvcmF0b3IgZnVuY3Rpb24gdGhhdCB0cmFuc2Zvcm1zIHRoZSBjbGFzcyBpbnRvIGFuIGluamVjdGFibGUuXG4gKlxuICogQGZ1bmN0aW9uIGluamVjdGFibGVcbiAqIEBjYXRlZ29yeSBDbGFzcyBEZWNvcmF0b3JzXG4gKlxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDbGllbnRcbiAqICAgcGFydGljaXBhbnQgRGVjb3JhdG9yXG4gKiAgIHBhcnRpY2lwYW50IEluamVjdGFibGVzXG4gKlxuICogICBDbGllbnQtPj5EZWNvcmF0b3I6IEBpbmplY3RhYmxlKClcbiAqICAgRGVjb3JhdG9yLT4+RGVjb3JhdG9yOiBDcmVhdGUgbmV3IGNvbnN0cnVjdG9yXG4gKlxuICogICBOb3RlIG92ZXIgRGVjb3JhdG9yOiBXaGVuIG5ldyBpbnN0YW5jZSByZXF1ZXN0ZWRcbiAqICAgRGVjb3JhdG9yLT4+SW5qZWN0YWJsZXM6IGdldChjYXRlZ29yeSlcbiAqICAgYWx0IEluc3RhbmNlIGV4aXN0c1xuICogICAgIEluamVjdGFibGVzLS0+PkRlY29yYXRvcjogUmV0dXJuIGV4aXN0aW5nIGluc3RhbmNlXG4gKiAgIGVsc2UgTm8gaW5zdGFuY2VcbiAqICAgICBEZWNvcmF0b3ItPj5JbmplY3RhYmxlczogcmVnaXN0ZXIob3JpZ2luYWwsIGNhdGVnb3J5KVxuICogICAgIERlY29yYXRvci0+PkluamVjdGFibGVzOiBnZXQoY2F0ZWdvcnkpXG4gKiAgICAgSW5qZWN0YWJsZXMtLT4+RGVjb3JhdG9yOiBSZXR1cm4gbmV3IGluc3RhbmNlXG4gKiAgICAgb3B0IEhhcyBjYWxsYmFja1xuICogICAgICAgRGVjb3JhdG9yLT4+RGVjb3JhdG9yOiBDYWxsIGluc3RhbmNlQ2FsbGJhY2tcbiAqICAgICBlbmRcbiAqICAgZW5kXG4gKiAgIERlY29yYXRvci0+PkRlY29yYXRvcjogRGVmaW5lIG1ldGFkYXRhXG4gKiAgIERlY29yYXRvci0tPj5DbGllbnQ6IFJldHVybiBpbnN0YW5jZVxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5qZWN0YWJsZShcbiAgY2F0ZWdvcnk/OiBzdHJpbmcgfCBDb25zdHJ1Y3RvciB8IFBhcnRpYWw8SW5qZWN0YWJsZUNvbmZpZz4sXG4gIGNmZz86IFBhcnRpYWw8SW5qZWN0YWJsZUNvbmZpZz5cbikge1xuICByZXR1cm4gRGVjb3JhdGlvbi5mb3IoSW5qZWN0YWJsZXNLZXlzLklOSkVDVEFCTEUpXG4gICAgLmRlZmluZSh7IGRlY29yYXRvcjogaW5qZWN0YWJsZUJhc2VEZWNvcmF0b3IsIGFyZ3M6IFtjYXRlZ29yeSwgY2ZnXSB9KVxuICAgIC5hcHBseSgpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDb252ZW5pZW5jZSBkZWNvcmF0b3IgdG8gcmVnaXN0ZXIgYW4gaW5qZWN0YWJsZSBhcyBhIHNpbmdsZXRvbi5cbiAqIEBzdW1tYXJ5IFdyYXBzIHtAbGluayBpbmplY3RhYmxlfSBmb3JjaW5nIHRoZSBzaW5nbGV0b24gbGlmZWN5Y2xlIHNvIG9ubHkgb25lIGluc3RhbmNlIGlzIGNyZWF0ZWQgYW5kIHJldXNlZC5cbiAqIEBwYXJhbSB7c3RyaW5nfENvbnN0cnVjdG9yfSBbY2F0ZWdvcnldIE9wdGlvbmFsIGV4cGxpY2l0IGNhdGVnb3J5L3N5bWJvbCBzb3VyY2U7IGRlZmF1bHRzIHRvIHRoZSBjbGFzcy5cbiAqIEBwYXJhbSB7T21pdDxJbmplY3RhYmxlQ29uZmlnLCBcInNpbmdsZXRvblwiPn0gW2NmZ10gQWRkaXRpb25hbCBpbmplY3RhYmxlIGNvbmZpZ3VyYXRpb24gZXhjbHVkaW5nIHRoZSBzaW5nbGV0b24gZmxhZy5cbiAqIEByZXR1cm4ge2Z1bmN0aW9uKGFueSk6IGFueX0gQSBjbGFzcyBkZWNvcmF0b3IgdGhhdCByZWdpc3RlcnMgdGhlIHRhcmdldCBhcyBhIHNpbmdsZXRvbiBpbmplY3RhYmxlLlxuICogQGZ1bmN0aW9uIHNpbmdsZXRvblxuICogQGNhdGVnb3J5IENsYXNzIERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNpbmdsZXRvbihcbiAgY2F0ZWdvcnk/OiBzdHJpbmcgfCBDb25zdHJ1Y3RvcixcbiAgY2ZnPzogT21pdDxJbmplY3RhYmxlQ29uZmlnLCBcInNpbmdsZXRvblwiPlxuKSB7XG4gIHJldHVybiBpbmplY3RhYmxlKFxuICAgIGNhdGVnb3J5IGFzIGFueSxcbiAgICBPYmplY3QuYXNzaWduKHt9LCBjZmcgfHwge30sIHsgc2luZ2xldG9uOiB0cnVlIH0pXG4gICk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENvbnZlbmllbmNlIGRlY29yYXRvciB0byByZWdpc3RlciBhbiBpbmplY3RhYmxlIGFzIG9uLWRlbWFuZCAobm9uLXNpbmdsZXRvbikuXG4gKiBAc3VtbWFyeSBXcmFwcyB7QGxpbmsgaW5qZWN0YWJsZX0gZm9yY2luZyBuZXcgaW5zdGFuY2VzIHRvIGJlIGNyZWF0ZWQgb24gZXZlcnkgaW5qZWN0aW9uIG9yIHJldHJpZXZhbC5cbiAqIEBwYXJhbSB7c3RyaW5nfENvbnN0cnVjdG9yfSBbY2F0ZWdvcnldIE9wdGlvbmFsIGV4cGxpY2l0IGNhdGVnb3J5L3N5bWJvbCBzb3VyY2U7IGRlZmF1bHRzIHRvIHRoZSBjbGFzcy5cbiAqIEBwYXJhbSB7T21pdDxJbmplY3RhYmxlQ29uZmlnLCBcInNpbmdsZXRvblwiPn0gW2NmZ10gQWRkaXRpb25hbCBpbmplY3RhYmxlIGNvbmZpZ3VyYXRpb24gZXhjbHVkaW5nIHRoZSBzaW5nbGV0b24gZmxhZy5cbiAqIEByZXR1cm4ge2Z1bmN0aW9uKGFueSk6IGFueX0gQSBjbGFzcyBkZWNvcmF0b3IgdGhhdCByZWdpc3RlcnMgdGhlIHRhcmdldCBhcyBhIG5vbi1zaW5nbGV0b24gaW5qZWN0YWJsZS5cbiAqIEBmdW5jdGlvbiBvbkRlbWFuZFxuICogQGNhdGVnb3J5IENsYXNzIERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9uRGVtYW5kKFxuICBjYXRlZ29yeT86IHN0cmluZyB8IENvbnN0cnVjdG9yLFxuICBjZmc/OiBPbWl0PEluamVjdGFibGVDb25maWcsIFwic2luZ2xldG9uXCI+XG4pIHtcbiAgcmV0dXJuIGluamVjdGFibGUoXG4gICAgY2F0ZWdvcnkgYXMgYW55LFxuICAgIE9iamVjdC5hc3NpZ24oe30sIGNmZyB8fCB7fSwgeyBzaW5nbGV0b246IGZhbHNlIH0pXG4gICk7XG59XG4vKipcbiAqIEBkZXNjcmlwdGlvbiBGdW5jdGlvbiB0eXBlIGZvciB0cmFuc2Zvcm1pbmcgaW5qZWN0YWJsZSBpbnN0YW5jZXMgYmVmb3JlIHRoZXkncmUgaW5qZWN0ZWQuXG4gKiBAc3VtbWFyeSBGdW5jdGlvbiB3aGljaCB0cmFuc2Zvcm1zIGEgY2FjaGVkIHtAbGluayBpbmplY3RhYmxlfSBpbnN0YW5jZSBiZWZvcmUgaXQncyBpbmplY3RlZCBpbnRvIGEgdGFyZ2V0IG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge2FueX0gaW5qZWN0YWJsZSBUaGUgaW5qZWN0YWJsZSBpbnN0YW5jZSB0byB0cmFuc2Zvcm1cbiAqIEBwYXJhbSB7YW55fSBvYmogVGhlIG9iamVjdCB0aGUgaW5qZWN0YWJsZSB3aWxsIGJlIGluamVjdGVkIG9uXG4gKiBAcmV0dXJuIHthbnl9IFRoZSB0cmFuc2Zvcm1lZCBpbmplY3RhYmxlIGluc3RhbmNlXG4gKlxuICogQHR5cGVkZWYge0Z1bmN0aW9ufSBJbnN0YW5jZVRyYW5zZm9ybWVyXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICogQG1lbWJlck9mIG1vZHVsZTppbmplY3RhYmxlLWRlY29yYXRvcnNcbiAqL1xuZXhwb3J0IHR5cGUgSW5zdGFuY2VUcmFuc2Zvcm1lciA9IChpbmplY3RhYmxlOiBhbnksIG9iajogYW55KSA9PiBhbnk7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE9wdGlvbnMgZm9yIHRoZSBwcm9wZXJ0eS1sZXZlbCBAaW5qZWN0IGRlY29yYXRvci5cbiAqIEBzdW1tYXJ5IEFsbG93cyBzcGVjaWZ5aW5nIGNvbnN0cnVjdG9yIGFyZ3VtZW50cyBhbmQgYW4gb3B0aW9uYWwgdHJhbnNmb3JtZXIgdG8gYmUgYXBwbGllZCB0byB0aGUgcmVzb2x2ZWQgaW5zdGFuY2UuXG4gKiBAcHJvcGVydHkge2FueVtdfSBbYXJnc10gT3B0aW9uYWwgY29uc3RydWN0b3IgYXJndW1lbnRzIHRvIHVzZSB3aGVuIGJ1aWxkaW5nIHRoZSBpbmplY3RhYmxlIGluc3RhbmNlLlxuICogQHByb3BlcnR5IHtJbnN0YW5jZVRyYW5zZm9ybWVyfSBbdHJhbnNmb3JtZXJdIE9wdGlvbmFsIGZ1bmN0aW9uIHRvIHRyYW5zZm9ybSB0aGUgaW5zdGFuY2UgYmVmb3JlIGFzc2lnbm1lbnQuXG4gKiBAdHlwZWRlZiBJbmplY3RPcHRpb25zXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmluamVjdGFibGUtZGVjb3JhdG9yc1xuICovXG5leHBvcnQgdHlwZSBJbmplY3RPcHRpb25zID0ge1xuICBhcmdzPzogYW55W107XG4gIHRyYW5zZm9ybWVyPzogSW5zdGFuY2VUcmFuc2Zvcm1lcjtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBpbmplY3RCYXNlRGVjb3JhdG9yKFxuICBjYXRlZ29yeT86IHN5bWJvbCB8IHN0cmluZyB8IENvbnN0cnVjdG9yIHwgUGFydGlhbDxJbmplY3RPcHRpb25zPixcbiAgY2ZnPzogUGFydGlhbDxJbmplY3RPcHRpb25zPlxuKSB7XG4gIHJldHVybiBmdW5jdGlvbiBpbmplY3RJbm5lckRlY29yYXRvcih0YXJnZXQ6IGFueSwgcHJvcGVydHlLZXk/OiBhbnkpIHtcbiAgICBjb25zdCBjb25maWc6IEluamVjdE9wdGlvbnMgPSAoXG4gICAgICBjZmcgfHwgdHlwZW9mIGNhdGVnb3J5ID09PSBcIm9iamVjdFwiID8gY2F0ZWdvcnkgOiB7fVxuICAgICkgYXMgSW5qZWN0T3B0aW9ucztcblxuICAgIGlmIChwcm9wZXJ0eUtleSkge1xuICAgICAgcHJvcCgpKHRhcmdldCwgcHJvcGVydHlLZXkpO1xuICAgIH1cblxuICAgIGNvbnN0IG5hbWU6IHN5bWJvbCB8IHN0cmluZyB8IENvbnN0cnVjdG9yIHwgdW5kZWZpbmVkID1cbiAgICAgICh0eXBlb2YgY2F0ZWdvcnkgIT09IFwib2JqZWN0XCIgJiZcbiAgICAgICAgKGNhdGVnb3J5IGFzIHN5bWJvbCB8IHN0cmluZyB8IENvbnN0cnVjdG9yKSkgfHxcbiAgICAgIE1ldGFkYXRhLnR5cGUodGFyZ2V0LmNvbnN0cnVjdG9yLCBwcm9wZXJ0eUtleSk7XG4gICAgaWYgKCFuYW1lKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENvdWxkIG5vdCBnZXQgVHlwZSBmcm9tIGRlY29yYXRvcmApO1xuICAgIH1cblxuICAgIC8vIHByb3AoKSh0YXJnZXQsIHByb3BlcnR5S2V5KTtcbiAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKFxuICAgICAgZ2V0SW5qZWN0S2V5KEluamVjdGFibGVzS2V5cy5JTkpFQ1QpLFxuICAgICAge1xuICAgICAgICBpbmplY3RhYmxlOiBuYW1lLFxuICAgICAgfSxcbiAgICAgIHRhcmdldCxcbiAgICAgIHByb3BlcnR5S2V5XG4gICAgKTtcblxuICAgIGNvbnN0IHZhbHVlcyA9IG5ldyBXZWFrTWFwKCk7XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eUtleSwge1xuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgZ2V0KHRoaXM6IGFueSkge1xuICAgICAgICBjb25zdCBkZXNjcmlwdG9yOiBQcm9wZXJ0eURlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKFxuICAgICAgICAgIHRhcmdldCxcbiAgICAgICAgICBwcm9wZXJ0eUtleVxuICAgICAgICApIGFzIFByb3BlcnR5RGVzY3JpcHRvcjtcbiAgICAgICAgaWYgKGRlc2NyaXB0b3IuY29uZmlndXJhYmxlKSB7XG4gICAgICAgICAgLy8gbGV0IC9vYmo6IGFueTtcbiAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgcHJvcGVydHlLZXksIHtcbiAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgICAgICAgZ2V0KHRoaXM6IGFueSkge1xuICAgICAgICAgICAgICBsZXQgb2JqID0gdmFsdWVzLmdldCh0aGlzKTtcbiAgICAgICAgICAgICAgaWYgKG9iaikgcmV0dXJuIG9iajtcbiAgICAgICAgICAgICAgb2JqID0gSW5qZWN0YWJsZXMuZ2V0KG5hbWUsIC4uLihjb25maWcuYXJncyB8fCBbXSkpO1xuICAgICAgICAgICAgICBpZiAoIW9iailcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgICBgQ291bGQgbm90IGdldCBJbmplY3RhYmxlICR7bmFtZS50b1N0cmluZygpfSB0byBpbmplY3QgaW4gJHt0YXJnZXQuY29uc3RydWN0b3IgPyB0YXJnZXQuY29uc3RydWN0b3IubmFtZSA6IHRhcmdldC5uYW1lfSdzICR7cHJvcGVydHlLZXl9YFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIGlmIChjb25maWcudHJhbnNmb3JtZXIpXG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgIG9iaiA9IGNvbmZpZy50cmFuc2Zvcm1lcihvYmosIHRhcmdldCk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHZhbHVlcy5zZXQodGhpcywgb2JqKTtcblxuICAgICAgICAgICAgICByZXR1cm4gb2JqO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICByZXR1cm4gdGhpc1twcm9wZXJ0eUtleV07XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSk7XG4gIH07XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFByb3BlcnR5IGRlY29yYXRvciB0aGF0IGluamVjdHMgYSBkZXBlbmRlbmN5IGludG8gYSBjbGFzcyBwcm9wZXJ0eS5cbiAqIEBzdW1tYXJ5IEFsbG93cyBmb3IgdGhlIGluamVjdGlvbiBvZiBhbiB7QGxpbmsgaW5qZWN0YWJsZX0gZGVjb3JhdGVkIGRlcGVuZGVuY3kgaW50byBhIGNsYXNzIHByb3BlcnR5LlxuICogVGhlIHByb3BlcnR5IG11c3QgYmUgdHlwZWQgZm9yIHRoZSByZXF1ZXN0ZWQgZGVwZW5kZW5jeS4gT25seSBjb25jcmV0ZSBjbGFzc2VzIGFyZSBzdXBwb3J0ZWQ7IGdlbmVyaWNzIGFyZSBub3QuXG4gKlxuICogQHJldHVybiB7ZnVuY3Rpb24oYW55LCBhbnkpOiB2b2lkfSBBIHByb3BlcnR5IGRlY29yYXRvciBmdW5jdGlvbiB0aGF0IHNldHMgdXAgdGhlIGRlcGVuZGVuY3kgaW5qZWN0aW9uLlxuICpcbiAqIEBmdW5jdGlvbiBpbmplY3RcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluamVjdCgpOiAodGFyZ2V0OiBhbnksIHByb3BlcnR5S2V5OiBhbnkpID0+IHZvaWQ7XG4vKipcbiAqIEBkZXNjcmlwdGlvbiBQcm9wZXJ0eSBkZWNvcmF0b3IgdGhhdCBpbmplY3RzIGEgZGVwZW5kZW5jeSBpbnRvIGEgY2xhc3MgcHJvcGVydHkuXG4gKiBAc3VtbWFyeSBBbGxvd3MgZm9yIHRoZSBpbmplY3Rpb24gb2YgYW4ge0BsaW5rIGluamVjdGFibGV9IGRlY29yYXRlZCBkZXBlbmRlbmN5IGludG8gYSBjbGFzcyBwcm9wZXJ0eS5cbiAqIFRoZSBwcm9wZXJ0eSBtdXN0IGJlIHR5cGVkIGZvciB0aGUgcmVxdWVzdGVkIGRlcGVuZGVuY3kuIE9ubHkgY29uY3JldGUgY2xhc3NlcyBhcmUgc3VwcG9ydGVkOyBnZW5lcmljcyBhcmUgbm90LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBjYXRlZ29yeSBEZWZhdWx0cyB0byB0aGUgY2xhc3MgbmFtZSBkZXJpdmVkIGZyb20gdGhlIHByb3BlcnR5IHR5cGUuIFVzZWZ1bCB3aGVuIG1pbmlmaWNhdGlvbiBvY2N1cnNcbiAqIGFuZCBuYW1lcyBhcmUgY2hhbmdlZCwgb3Igd2hlbiB5b3Ugd2FudCB0byB1cGNhc3QgdGhlIG9iamVjdCB0byBhIGRpZmZlcmVudCB0eXBlLlxuICogQHJldHVybiB7ZnVuY3Rpb24oYW55LCBhbnkpOiB2b2lkfSBBIHByb3BlcnR5IGRlY29yYXRvciBmdW5jdGlvbiB0aGF0IHNldHMgdXAgdGhlIGRlcGVuZGVuY3kgaW5qZWN0aW9uLlxuICpcbiAqIEBmdW5jdGlvbiBpbmplY3RcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluamVjdChcbiAgY2F0ZWdvcnk6IHN0cmluZyB8IENvbnN0cnVjdG9yXG4pOiAodGFyZ2V0OiBhbnksIHByb3BlcnR5S2V5OiBhbnkpID0+IHZvaWQ7XG4vKipcbiAqIEBkZXNjcmlwdGlvbiBQcm9wZXJ0eSBkZWNvcmF0b3IgdGhhdCBpbmplY3RzIGEgZGVwZW5kZW5jeSBpbnRvIGEgY2xhc3MgcHJvcGVydHkuXG4gKiBAc3VtbWFyeSBBbGxvd3MgZm9yIHRoZSBpbmplY3Rpb24gb2YgYW4ge0BsaW5rIGluamVjdGFibGV9IGRlY29yYXRlZCBkZXBlbmRlbmN5IGludG8gYSBjbGFzcyBwcm9wZXJ0eS5cbiAqIFRoZSBwcm9wZXJ0eSBtdXN0IGJlIHR5cGVkIGZvciB0aGUgcmVxdWVzdGVkIGRlcGVuZGVuY3kuIE9ubHkgY29uY3JldGUgY2xhc3NlcyBhcmUgc3VwcG9ydGVkOyBnZW5lcmljcyBhcmUgbm90LlxuICpcbiAqIEBwYXJhbSB7UGFydGlhbDxJbmplY3RPcHRpb25zPn0gW2NmZz17fV0gT3B0aW9uYWwgZnVuY3Rpb24gdG8gdHJhbnNmb3JtIHRoZSBpbmplY3RhYmxlIGluc3RhbmNlIGJlZm9yZSBpdCdzIGluamVjdGVkLCBvciBhcmd1bWVudHMgdG8gcGFzcyB0aGUgY29uc3RydWN0b3Igd2hlbiBpbmplY3Rpbmcgb25EZW1hbmRcbiAqIEByZXR1cm4ge2Z1bmN0aW9uKGFueSwgYW55KTogdm9pZH0gQSBwcm9wZXJ0eSBkZWNvcmF0b3IgZnVuY3Rpb24gdGhhdCBzZXRzIHVwIHRoZSBkZXBlbmRlbmN5IGluamVjdGlvbi5cbiAqXG4gKiBAZnVuY3Rpb24gaW5qZWN0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbmplY3QoXG4gIGNmZzogUGFydGlhbDxJbmplY3RPcHRpb25zPlxuKTogKHRhcmdldDogYW55LCBwcm9wZXJ0eUtleTogYW55KSA9PiB2b2lkO1xuLyoqXG4gKiBAZGVzY3JpcHRpb24gUHJvcGVydHkgZGVjb3JhdG9yIHRoYXQgaW5qZWN0cyBhIGRlcGVuZGVuY3kgaW50byBhIGNsYXNzIHByb3BlcnR5LlxuICogQHN1bW1hcnkgQWxsb3dzIGZvciB0aGUgaW5qZWN0aW9uIG9mIGFuIHtAbGluayBpbmplY3RhYmxlfSBkZWNvcmF0ZWQgZGVwZW5kZW5jeSBpbnRvIGEgY2xhc3MgcHJvcGVydHkuXG4gKiBUaGUgcHJvcGVydHkgbXVzdCBiZSB0eXBlZCBmb3IgdGhlIHJlcXVlc3RlZCBkZXBlbmRlbmN5LiBPbmx5IGNvbmNyZXRlIGNsYXNzZXMgYXJlIHN1cHBvcnRlZDsgZ2VuZXJpY3MgYXJlIG5vdC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gY2F0ZWdvcnkgRGVmYXVsdHMgdG8gdGhlIGNsYXNzIG5hbWUgZGVyaXZlZCBmcm9tIHRoZSBwcm9wZXJ0eSB0eXBlLiBVc2VmdWwgd2hlbiBtaW5pZmljYXRpb24gb2NjdXJzXG4gKiBhbmQgbmFtZXMgYXJlIGNoYW5nZWQsIG9yIHdoZW4geW91IHdhbnQgdG8gdXBjYXN0IHRoZSBvYmplY3QgdG8gYSBkaWZmZXJlbnQgdHlwZS5cbiAqIEBwYXJhbSB7UGFydGlhbDxJbmplY3RPcHRpb25zPn0gY2ZnPXt9IE9wdGlvbmFsIGZ1bmN0aW9uIHRvIHRyYW5zZm9ybSB0aGUgaW5qZWN0YWJsZSBpbnN0YW5jZSBiZWZvcmUgaXQncyBpbmplY3RlZCwgb3IgYXJndW1lbnRzIHRvIHBhc3MgdGhlIGNvbnN0cnVjdG9yIHdoZW4gaW5qZWN0aW5nIG9uRGVtYW5kXG4gKiBAcmV0dXJuIHtmdW5jdGlvbihhbnksIGFueSk6IHZvaWR9IEEgcHJvcGVydHkgZGVjb3JhdG9yIGZ1bmN0aW9uIHRoYXQgc2V0cyB1cCB0aGUgZGVwZW5kZW5jeSBpbmplY3Rpb24uXG4gKlxuICogQGZ1bmN0aW9uIGluamVjdFxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5qZWN0KFxuICBjYXRlZ29yeTogc3RyaW5nIHwgQ29uc3RydWN0b3IsXG4gIGNmZzogUGFydGlhbDxJbmplY3RPcHRpb25zPlxuKTogKHRhcmdldDogYW55LCBwcm9wZXJ0eUtleTogYW55KSA9PiB2b2lkO1xuLyoqXG4gKiBAZGVzY3JpcHRpb24gUHJvcGVydHkgZGVjb3JhdG9yIHRoYXQgaW5qZWN0cyBhIGRlcGVuZGVuY3kgaW50byBhIGNsYXNzIHByb3BlcnR5LlxuICogQHN1bW1hcnkgQWxsb3dzIGZvciB0aGUgaW5qZWN0aW9uIG9mIGFuIHtAbGluayBpbmplY3RhYmxlfSBkZWNvcmF0ZWQgZGVwZW5kZW5jeSBpbnRvIGEgY2xhc3MgcHJvcGVydHkuXG4gKiBUaGUgcHJvcGVydHkgbXVzdCBiZSB0eXBlZCBmb3IgdGhlIHJlcXVlc3RlZCBkZXBlbmRlbmN5LiBPbmx5IGNvbmNyZXRlIGNsYXNzZXMgYXJlIHN1cHBvcnRlZDsgZ2VuZXJpY3MgYXJlIG5vdC5cbiAqXG4gKiBJbmplY3RlZCBwcm9wZXJ0aWVzIHNob3VsZCBiZSBkZXNjcmliZWQgbGlrZSBzbzpcbiAqIDxwcmU+XG4gKiAgICAgY2xhc3MgQ2xhc3NOYW1lIHtcbiAqICAgICAgICAgLi4uXG4gKlxuICogICAgICAgICBAaW5qZWN0KClcbiAqICAgICAgICAgcHJvcGVydHlOYW1lITogSW5qZWN0YWJsZUNsYXNzO1xuICpcbiAqICAgICAgICAgLi4uXG4gKiAgICAgfVxuICogPC9wcmU+XG4gKlxuICogd2hlcmUgSW5qZWN0YWJsZUNsYXNzIGlzIHRoZSBjbGFzcyB5b3Ugd2FudCB0byBpbmplY3QuXG4gKiBOb3RpY2UgdGhlIHVzZSBvZiAnITonIHRvIGVuc3VyZSB0aGUgdHJhbnNwaWxlciB0aGUgcHJvcGVydHkgd2lsbCBiZSBzZXQgb3V0c2lkZSB0aGUgY29uc3RydWN0b3IgYnV0IHdpbGwgYWx3YXlzIGJlIGRlZmluZWQuXG4gKiBGb3IgcHJvamVjdHMgd2hlcmUgbWluaWZpY2F0aW9uIG9jY3VycywgeW91IHNob3VsZCB1c2UgdGhlIGNhdGVnb3J5IHBhcmFtIHRvIGVuc3VyZSB0aGUgbmFtZSBpcyB0aGUgc2FtZSB0aHJvdWdob3V0LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbY2F0ZWdvcnldIERlZmF1bHRzIHRvIHRoZSBjbGFzcyBuYW1lIGRlcml2ZWQgZnJvbSB0aGUgcHJvcGVydHkgdHlwZS4gVXNlZnVsIHdoZW4gbWluaWZpY2F0aW9uIG9jY3Vyc1xuICogYW5kIG5hbWVzIGFyZSBjaGFuZ2VkLCBvciB3aGVuIHlvdSB3YW50IHRvIHVwY2FzdCB0aGUgb2JqZWN0IHRvIGEgZGlmZmVyZW50IHR5cGUuXG4gKiBAcGFyYW0ge1BhcnRpYWw8SW5qZWN0T3B0aW9ucz59IFtjZmc9e31dIE9wdGlvbmFsIGZ1bmN0aW9uIHRvIHRyYW5zZm9ybSB0aGUgaW5qZWN0YWJsZSBpbnN0YW5jZSBiZWZvcmUgaXQncyBpbmplY3RlZCwgb3IgYXJndW1lbnRzIHRvIHBhc3MgdGhlIGNvbnN0cnVjdG9yIHdoZW4gaW5qZWN0aW5nIG9uRGVtYW5kXG4gKiBAcmV0dXJuIHtmdW5jdGlvbihhbnksIGFueSk6IHZvaWR9IEEgcHJvcGVydHkgZGVjb3JhdG9yIGZ1bmN0aW9uIHRoYXQgc2V0cyB1cCB0aGUgZGVwZW5kZW5jeSBpbmplY3Rpb24uXG4gKlxuICogQGZ1bmN0aW9uIGluamVjdFxuICogQGNhdGVnb3J5IFByb3BlcnR5IERlY29yYXRvcnNcbiAqXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICogICBwYXJ0aWNpcGFudCBEZWNvcmF0b3JcbiAqICAgcGFydGljaXBhbnQgSW5qZWN0YWJsZXNcbiAqXG4gKiAgIENsaWVudC0+PkRlY29yYXRvcjogQGluamVjdCgpXG4gKiAgIERlY29yYXRvci0+PkRlY29yYXRvcjogR2V0IHR5cGUgZnJvbSBwcm9wZXJ0eVxuICogICBEZWNvcmF0b3ItPj5EZWNvcmF0b3I6IERlZmluZSBtZXRhZGF0YVxuICogICBEZWNvcmF0b3ItPj5EZWNvcmF0b3I6IERlZmluZSBwcm9wZXJ0eSBnZXR0ZXJcbiAqXG4gKiAgIE5vdGUgb3ZlciBEZWNvcmF0b3I6IFdoZW4gcHJvcGVydHkgYWNjZXNzZWRcbiAqICAgQ2xpZW50LT4+RGVjb3JhdG9yOiBhY2Nlc3MgcHJvcGVydHlcbiAqICAgRGVjb3JhdG9yLT4+RGVjb3JhdG9yOiBDaGVjayBpZiBpbnN0YW5jZSBleGlzdHNcbiAqICAgYWx0IEluc3RhbmNlIGV4aXN0cyBpbiBXZWFrTWFwXG4gKiAgICAgRGVjb3JhdG9yLS0+PkNsaWVudDogUmV0dXJuIGNhY2hlZCBpbnN0YW5jZVxuICogICBlbHNlIE5vIGluc3RhbmNlXG4gKiAgICAgRGVjb3JhdG9yLT4+SW5qZWN0YWJsZXM6IGdldChuYW1lKVxuICogICAgIGFsdCBJbmplY3RhYmxlIGZvdW5kXG4gKiAgICAgICBJbmplY3RhYmxlcy0tPj5EZWNvcmF0b3I6IFJldHVybiBpbmplY3RhYmxlIGluc3RhbmNlXG4gKiAgICAgICBvcHQgSGFzIHRyYW5zZm9ybWVyXG4gKiAgICAgICAgIERlY29yYXRvci0+PkRlY29yYXRvcjogQ2FsbCB0cmFuc2Zvcm1lclxuICogICAgICAgZW5kXG4gKiAgICAgICBEZWNvcmF0b3ItPj5EZWNvcmF0b3I6IFN0b3JlIGluIFdlYWtNYXBcbiAqICAgICAgIERlY29yYXRvci0tPj5DbGllbnQ6IFJldHVybiBpbnN0YW5jZVxuICogICAgIGVsc2UgTm8gaW5qZWN0YWJsZVxuICogICAgICAgRGVjb3JhdG9yLS0+PkNsaWVudDogVGhyb3cgZXJyb3JcbiAqICAgICBlbmRcbiAqICAgZW5kXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbmplY3QoXG4gIGNhdGVnb3J5Pzogc3ltYm9sIHwgc3RyaW5nIHwgQ29uc3RydWN0b3IgfCBQYXJ0aWFsPEluamVjdE9wdGlvbnM+LFxuICBjZmc/OiBQYXJ0aWFsPEluamVjdE9wdGlvbnM+XG4pIHtcbiAgcmV0dXJuIERlY29yYXRpb24uZm9yKEluamVjdGFibGVzS2V5cy5JTkpFQ1QpXG4gICAgLmRlZmluZSh7IGRlY29yYXRvcjogaW5qZWN0QmFzZURlY29yYXRvciwgYXJnczogW2NhdGVnb3J5LCBjZmddIH0pXG4gICAgLmFwcGx5KCk7XG59XG4iLCIvKipcbiAqIEBkZXNjcmlwdGlvbiBBIGxpZ2h0d2VpZ2h0IGRlcGVuZGVuY3kgaW5qZWN0aW9uIGxpYnJhcnkgZm9yIFR5cGVTY3JpcHQgYXBwbGljYXRpb25zLlxuICogQHN1bW1hcnkgQWRkcyBhIHNpbXBsZSBJbmplY3RhYmxlcyBpbXBsZW1lbnRhdGlvbiB0byBjcmVhdGUgc2luZ2xldG9uIGluc3RhbmNlcyBvZiBhbiBvYmplY3RcbiAqIGFuZCBlYXNpbHkgaW5qZWN0IGl0IGludG8gb3RoZXIgb2JqZWN0cy4gUHJvdmlkZXMgZGVjb3JhdG9ycyBmb3IgbWFya2luZyBjbGFzc2VzIGFzIGluamVjdGFibGVcbiAqIGFuZCBmb3IgaW5qZWN0aW5nIGRlcGVuZGVuY2llcyBpbnRvIGNsYXNzIHByb3BlcnRpZXMuXG4gKlxuICogQG1vZHVsZSBpbmplY3RhYmxlLWRlY29yYXRvcnNcbiAqL1xuXG5pbXBvcnQgeyBNZXRhZGF0YSB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdGlvblwiO1xuXG5leHBvcnQgKiBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0luamVjdGFibGVzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9yZWdpc3RyeVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vdHlwZXNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3V0aWxzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEN1cnJlbnQgdmVyc2lvbiBvZiB0aGUgaW5qZWN0YWJsZS1kZWNvcmF0b3JzIGxpYnJhcnkuXG4gKiBAc3VtbWFyeSBEZWZpbmVkIG9uIGxpYnJhcnkgYnVpbGQuIEhvbGRzIHRoZSBsaWJyYXJ5J3MgY3VycmVudCB2ZXJzaW9uIHN0cmluZy5cbiAqIEBjb25zdCBWRVJTSU9OXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmluamVjdGFibGUtZGVjb3JhdG9yc1xuICovXG5leHBvcnQgY29uc3QgVkVSU0lPTiA9IFwiIyNWRVJTSU9OIyNcIjtcbmV4cG9ydCBjb25zdCBQQUNLQUdFX05BTUUgPSBcIiMjUEFDS0FHRV9OQU1FIyNcIjtcbk1ldGFkYXRhLnJlZ2lzdGVyTGlicmFyeShQQUNLQUdFX05BTUUsIFZFUlNJT04pO1xuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBRUE7Ozs7Ozs7O0FBUUc7QUFDVSxNQUFBLGVBQWUsR0FBRztBQUM3QixJQUFBLE9BQU8sRUFBRSxZQUFZO0FBQ3JCLElBQUEsVUFBVSxFQUFFLFlBQVk7QUFDeEIsSUFBQSxNQUFNLEVBQUUsUUFBUTs7QUFHbEI7Ozs7O0FBS0c7QUFDVSxNQUFBLHdCQUF3QixHQUFxQjtBQUN4RCxJQUFBLFNBQVMsRUFBRSxJQUFJOztBQUdqQjs7Ozs7QUFLRztBQUNJLE1BQU0sT0FBTyxHQUFHOztBQy9CdkI7Ozs7Ozs7QUFPRztB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