@decaf-ts/logging 0.3.12 → 0.3.13
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.
- package/dist/logging.cjs +534 -97
- package/dist/logging.esm.cjs +531 -98
- package/lib/LoggedClass.cjs +9 -12
- package/lib/LoggedClass.d.ts +6 -10
- package/lib/constants.cjs +40 -8
- package/lib/constants.d.ts +35 -7
- package/lib/decorators.cjs +114 -50
- package/lib/decorators.d.ts +58 -43
- package/lib/environment.cjs +65 -20
- package/lib/environment.d.ts +66 -22
- package/lib/esm/LoggedClass.d.ts +6 -10
- package/lib/esm/LoggedClass.js +9 -12
- package/lib/esm/constants.d.ts +35 -7
- package/lib/esm/constants.js +40 -8
- package/lib/esm/decorators.d.ts +58 -43
- package/lib/esm/decorators.js +113 -50
- package/lib/esm/environment.d.ts +66 -22
- package/lib/esm/environment.js +65 -20
- package/lib/esm/filters/LogFilter.d.ts +37 -0
- package/lib/esm/filters/LogFilter.js +30 -1
- package/lib/esm/filters/PatternFilter.d.ts +46 -0
- package/lib/esm/filters/PatternFilter.js +41 -1
- package/lib/esm/index.d.ts +7 -10
- package/lib/esm/index.js +8 -11
- package/lib/esm/logging.d.ts +14 -0
- package/lib/esm/logging.js +22 -1
- package/lib/esm/time.d.ts +149 -0
- package/lib/esm/time.js +212 -0
- package/lib/esm/types.d.ts +89 -51
- package/lib/esm/types.js +1 -1
- package/lib/filters/LogFilter.cjs +30 -1
- package/lib/filters/LogFilter.d.ts +37 -0
- package/lib/filters/PatternFilter.cjs +41 -1
- package/lib/filters/PatternFilter.d.ts +46 -0
- package/lib/index.cjs +8 -11
- package/lib/index.d.ts +7 -10
- package/lib/logging.cjs +22 -1
- package/lib/logging.d.ts +14 -0
- package/lib/time.cjs +217 -0
- package/lib/time.d.ts +149 -0
- package/lib/types.cjs +1 -1
- package/lib/types.d.ts +89 -51
- package/package.json +2 -2
package/dist/logging.cjs
CHANGED
|
@@ -4,12 +4,29 @@
|
|
|
4
4
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.logging = {}, global.styledStringBuilder, global.typedObjectAccumulator, global.tslib));
|
|
5
5
|
})(this, (function (exports, styledStringBuilder, typedObjectAccumulator, tslib) { 'use strict';
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* @description Global key used to store environment variables in browser contexts.
|
|
9
|
+
* @summary Enables the logging environment helpers to locate serialized environment configuration on `globalThis`.
|
|
10
|
+
* @const BrowserEnvKey
|
|
11
|
+
* @type {string}
|
|
12
|
+
* @memberOf module:Logging
|
|
13
|
+
*/
|
|
7
14
|
const BrowserEnvKey = "ENV";
|
|
8
15
|
/**
|
|
9
16
|
* @description Delimiter used for composing nested environment variable names.
|
|
10
17
|
* @summary Joins parent and child keys when mapping object paths to ENV strings.
|
|
18
|
+
* @const ENV_PATH_DELIMITER
|
|
19
|
+
* @type {string}
|
|
20
|
+
* @memberOf module:Logging
|
|
11
21
|
*/
|
|
12
22
|
const ENV_PATH_DELIMITER = "__";
|
|
23
|
+
/**
|
|
24
|
+
* @description Default prefix and suffix used for template placeholders.
|
|
25
|
+
* @summary Provides wrapper strings applied when interpolating messages with {@link patchPlaceholders}.
|
|
26
|
+
* @const DefaultPlaceholderWrappers
|
|
27
|
+
* @type {string[]}
|
|
28
|
+
* @memberOf module:Logging
|
|
29
|
+
*/
|
|
13
30
|
const DefaultPlaceholderWrappers = ["${", "}"];
|
|
14
31
|
/**
|
|
15
32
|
* @description Enum for log levels.
|
|
@@ -20,21 +37,24 @@
|
|
|
20
37
|
*/
|
|
21
38
|
exports.LogLevel = void 0;
|
|
22
39
|
(function (LogLevel) {
|
|
23
|
-
/**
|
|
40
|
+
/** @description Benchmark events that capture performance metrics. */
|
|
41
|
+
LogLevel["benchmark"] = "benchmark";
|
|
42
|
+
/** @description Error events that indicate failures requiring attention. */
|
|
24
43
|
LogLevel["error"] = "error";
|
|
25
|
-
/**
|
|
44
|
+
/** @description Informational events describing normal operation. */
|
|
26
45
|
LogLevel["info"] = "info";
|
|
27
|
-
/**
|
|
46
|
+
/** @description Verbose diagnostic information for detailed tracing. */
|
|
28
47
|
LogLevel["verbose"] = "verbose";
|
|
29
|
-
/** Debug or trace
|
|
48
|
+
/** @description Debug or trace details aimed at developers. */
|
|
30
49
|
LogLevel["debug"] = "debug";
|
|
31
|
-
/**
|
|
50
|
+
/** @description Extremely chatty or playful log entries. */
|
|
32
51
|
LogLevel["silly"] = "silly";
|
|
33
52
|
})(exports.LogLevel || (exports.LogLevel = {}));
|
|
34
53
|
/**
|
|
35
54
|
* @description Numeric values associated with log levels.
|
|
36
55
|
* @summary Provides a numeric representation of log levels for comparison and filtering.
|
|
37
|
-
* @
|
|
56
|
+
* @typedef {Object} NumericLogLevelsShape
|
|
57
|
+
* @property {number} benchmark - Numeric value for benchmark level (0).
|
|
38
58
|
* @property {number} error - Numeric value for error level (2).
|
|
39
59
|
* @property {number} info - Numeric value for info level (4).
|
|
40
60
|
* @property {number} verbose - Numeric value for verbose level (6).
|
|
@@ -42,7 +62,15 @@
|
|
|
42
62
|
* @property {number} silly - Numeric value for silly level (9).
|
|
43
63
|
* @memberOf module:Logging
|
|
44
64
|
*/
|
|
65
|
+
/**
|
|
66
|
+
* @description Numeric values associated with log levels.
|
|
67
|
+
* @summary Provides a numeric representation of log levels for comparison and filtering.
|
|
68
|
+
* @const NumericLogLevels
|
|
69
|
+
* @type {NumericLogLevelsShape}
|
|
70
|
+
* @memberOf module:Logging
|
|
71
|
+
*/
|
|
45
72
|
const NumericLogLevels = {
|
|
73
|
+
benchmark: 0,
|
|
46
74
|
error: 2,
|
|
47
75
|
info: 4,
|
|
48
76
|
verbose: 6,
|
|
@@ -65,7 +93,6 @@
|
|
|
65
93
|
/**
|
|
66
94
|
* @description Default theme for styling log output.
|
|
67
95
|
* @summary Defines the default color and style settings for various components of log messages.
|
|
68
|
-
* @const DefaultTheme
|
|
69
96
|
* @typedef {Theme} DefaultTheme
|
|
70
97
|
* @property {Object} class - Styling for class names.
|
|
71
98
|
* @property {number} class.fg - Foreground color code for class names (34).
|
|
@@ -85,6 +112,7 @@
|
|
|
85
112
|
* @property {Object} logLevel.verbose - Styling for verbose level logs (empty object).
|
|
86
113
|
* @property {Object} logLevel.debug - Styling for debug level logs.
|
|
87
114
|
* @property {number} logLevel.debug.fg - Foreground color code for debug level logs (33).
|
|
115
|
+
* @const DefaultTheme
|
|
88
116
|
* @memberOf module:Logging
|
|
89
117
|
*/
|
|
90
118
|
const DefaultTheme = {
|
|
@@ -105,6 +133,10 @@
|
|
|
105
133
|
},
|
|
106
134
|
method: {},
|
|
107
135
|
logLevel: {
|
|
136
|
+
benchmark: {
|
|
137
|
+
fg: 32,
|
|
138
|
+
style: ["bold"],
|
|
139
|
+
},
|
|
108
140
|
error: {
|
|
109
141
|
fg: 31,
|
|
110
142
|
style: ["bold"],
|
|
@@ -382,12 +414,31 @@
|
|
|
382
414
|
}
|
|
383
415
|
|
|
384
416
|
/**
|
|
385
|
-
* @
|
|
386
|
-
* @
|
|
417
|
+
* @description Environment accumulator that lazily reads from runtime sources.
|
|
418
|
+
* @summary Extends {@link ObjectAccumulator} to merge configuration objects while resolving values from Node or browser environment variables on demand.
|
|
387
419
|
* @template T
|
|
388
|
-
* @
|
|
389
|
-
* @
|
|
390
|
-
*
|
|
420
|
+
* @class Environment
|
|
421
|
+
* @example
|
|
422
|
+
* const Config = Environment.accumulate({ logging: { level: "info" } });
|
|
423
|
+
* console.log(Config.logging.level);
|
|
424
|
+
* console.log(String(Config.logging.level)); // => LOGGING__LEVEL key when serialized
|
|
425
|
+
* @mermaid
|
|
426
|
+
* sequenceDiagram
|
|
427
|
+
* participant Client
|
|
428
|
+
* participant Env as Environment
|
|
429
|
+
* participant Process as process.env
|
|
430
|
+
* participant Browser as globalThis.ENV
|
|
431
|
+
* Client->>Env: accumulate(partialConfig)
|
|
432
|
+
* Env->>Env: expand(values)
|
|
433
|
+
* Client->>Env: Config.logging.level
|
|
434
|
+
* alt Browser runtime
|
|
435
|
+
* Env->>Browser: lookup ENV key
|
|
436
|
+
* Browser-->>Env: resolved value
|
|
437
|
+
* else Node runtime
|
|
438
|
+
* Env->>Process: lookup ENV key
|
|
439
|
+
* Process-->>Env: resolved value
|
|
440
|
+
* end
|
|
441
|
+
* Env-->>Client: merged value
|
|
391
442
|
*/
|
|
392
443
|
class Environment extends typedObjectAccumulator.ObjectAccumulator {
|
|
393
444
|
/**
|
|
@@ -402,10 +453,10 @@
|
|
|
402
453
|
super();
|
|
403
454
|
}
|
|
404
455
|
/**
|
|
405
|
-
* @description Retrieves a value from the environment
|
|
406
|
-
* @summary
|
|
407
|
-
* @param {string} k -
|
|
408
|
-
* @return {unknown}
|
|
456
|
+
* @description Retrieves a value from the runtime environment.
|
|
457
|
+
* @summary Handles browser and Node.js environments by normalizing keys and parsing values.
|
|
458
|
+
* @param {string} k - Key to resolve from the environment.
|
|
459
|
+
* @return {unknown} Value resolved from the environment or `undefined` when absent.
|
|
409
460
|
*/
|
|
410
461
|
fromEnv(k) {
|
|
411
462
|
let env;
|
|
@@ -419,6 +470,12 @@
|
|
|
419
470
|
}
|
|
420
471
|
return this.parseEnvValue(env[k]);
|
|
421
472
|
}
|
|
473
|
+
/**
|
|
474
|
+
* @description Converts stringified environment values into native types.
|
|
475
|
+
* @summary Interprets booleans and numbers while leaving other types unchanged.
|
|
476
|
+
* @param {unknown} val - Raw value retrieved from the environment.
|
|
477
|
+
* @return {unknown} Parsed value converted to boolean, number, or left as-is.
|
|
478
|
+
*/
|
|
422
479
|
parseEnvValue(val) {
|
|
423
480
|
if (typeof val !== "string")
|
|
424
481
|
return val;
|
|
@@ -432,10 +489,10 @@
|
|
|
432
489
|
return val;
|
|
433
490
|
}
|
|
434
491
|
/**
|
|
435
|
-
* @description Expands an object into the environment
|
|
436
|
-
* @summary Defines properties
|
|
437
|
-
* @template V - Type of the object being expanded
|
|
438
|
-
* @param {V} value -
|
|
492
|
+
* @description Expands an object into the environment.
|
|
493
|
+
* @summary Defines lazy properties that first consult runtime variables before falling back to seeded values.
|
|
494
|
+
* @template V - Type of the object being expanded.
|
|
495
|
+
* @param {V} value - Object to expose through environment getters and setters.
|
|
439
496
|
* @return {void}
|
|
440
497
|
*/
|
|
441
498
|
expand(value) {
|
|
@@ -466,10 +523,10 @@
|
|
|
466
523
|
* @protected
|
|
467
524
|
* @static
|
|
468
525
|
* @description Retrieves or creates the singleton instance of the Environment class.
|
|
469
|
-
* @summary Ensures only one instance
|
|
526
|
+
* @summary Ensures only one {@link Environment} instance is created, wrapping it in a proxy to compose ENV keys on demand.
|
|
470
527
|
* @template E
|
|
471
|
-
* @param {...unknown[]} args - Arguments
|
|
472
|
-
* @return {E}
|
|
528
|
+
* @param {...unknown[]} args - Arguments forwarded to the factory when instantiating the singleton.
|
|
529
|
+
* @return {E} Singleton environment instance.
|
|
473
530
|
*/
|
|
474
531
|
static instance(...args) {
|
|
475
532
|
if (!Environment._instance) {
|
|
@@ -495,10 +552,11 @@
|
|
|
495
552
|
/**
|
|
496
553
|
* @static
|
|
497
554
|
* @description Accumulates the given value into the environment.
|
|
498
|
-
* @summary Adds new properties
|
|
555
|
+
* @summary Adds new properties, hiding raw descriptors to avoid leaking enumeration semantics.
|
|
556
|
+
* @template T
|
|
499
557
|
* @template V
|
|
500
|
-
* @param {V} value -
|
|
501
|
-
* @return {
|
|
558
|
+
* @param {V} value - Object to merge into the environment.
|
|
559
|
+
* @return {Environment} Updated environment reference.
|
|
502
560
|
*/
|
|
503
561
|
static accumulate(value) {
|
|
504
562
|
const instance = Environment.instance();
|
|
@@ -513,9 +571,22 @@
|
|
|
513
571
|
});
|
|
514
572
|
return instance.accumulate(value);
|
|
515
573
|
}
|
|
574
|
+
/**
|
|
575
|
+
* @description Retrieves a value using a dot-path key from the accumulated environment.
|
|
576
|
+
* @summary Delegates to the singleton instance to access stored configuration.
|
|
577
|
+
* @param {string} key - Key to resolve from the environment store.
|
|
578
|
+
* @return {unknown} Stored value corresponding to the provided key.
|
|
579
|
+
*/
|
|
516
580
|
static get(key) {
|
|
517
581
|
return Environment._instance.get(key);
|
|
518
582
|
}
|
|
583
|
+
/**
|
|
584
|
+
* @description Builds a proxy that composes environment keys for nested properties.
|
|
585
|
+
* @summary Allows chained property access to emit uppercase ENV identifiers while honoring existing runtime overrides.
|
|
586
|
+
* @param {any} current - Seed model segment used when projecting nested structures.
|
|
587
|
+
* @param {string[]} path - Accumulated path segments leading to the proxy.
|
|
588
|
+
* @return {any} Proxy that resolves environment values or composes additional proxies for deeper paths.
|
|
589
|
+
*/
|
|
519
590
|
static buildEnvProxy(current, path) {
|
|
520
591
|
const buildKey = (p) => p.map((seg) => toENVFormat(seg)).join(ENV_PATH_DELIMITER);
|
|
521
592
|
// Helper to read from the active environment given a composed key
|
|
@@ -584,6 +655,12 @@
|
|
|
584
655
|
.map((k) => (toEnv ? toENVFormat(k) : k));
|
|
585
656
|
}
|
|
586
657
|
}
|
|
658
|
+
/**
|
|
659
|
+
* @description Singleton environment instance seeded with default logging configuration.
|
|
660
|
+
* @summary Combines {@link DefaultLoggingConfig} with runtime environment variables to provide consistent logging defaults across platforms.
|
|
661
|
+
* @const LoggedEnvironment
|
|
662
|
+
* @memberOf module:Logging
|
|
663
|
+
*/
|
|
587
664
|
const LoggedEnvironment = Environment.accumulate(Object.assign({}, DefaultLoggingConfig, {
|
|
588
665
|
env: (isBrowser() && globalThis[BrowserEnvKey]
|
|
589
666
|
? globalThis[BrowserEnvKey]["NODE_ENV"]
|
|
@@ -758,6 +835,9 @@
|
|
|
758
835
|
return;
|
|
759
836
|
let method;
|
|
760
837
|
switch (level) {
|
|
838
|
+
case exports.LogLevel.benchmark:
|
|
839
|
+
method = console.log;
|
|
840
|
+
break;
|
|
761
841
|
case exports.LogLevel.info:
|
|
762
842
|
method = console.log;
|
|
763
843
|
break;
|
|
@@ -773,6 +853,15 @@
|
|
|
773
853
|
}
|
|
774
854
|
method(this.createLog(level, msg, error));
|
|
775
855
|
}
|
|
856
|
+
/**
|
|
857
|
+
* @description Logs a message at the benchmark level
|
|
858
|
+
* @summary Logs a message at the benchmark level if the current verbosity setting allows it
|
|
859
|
+
* @param {StringLike} msg - The message to be logged
|
|
860
|
+
* @return {void}
|
|
861
|
+
*/
|
|
862
|
+
benchmark(msg) {
|
|
863
|
+
this.log(exports.LogLevel.benchmark, msg);
|
|
864
|
+
}
|
|
776
865
|
/**
|
|
777
866
|
* @description Logs a message at the silly level
|
|
778
867
|
* @summary Logs a message at the silly level if the current verbosity setting allows it
|
|
@@ -974,6 +1063,15 @@
|
|
|
974
1063
|
static debug(msg) {
|
|
975
1064
|
return this.get().debug(msg);
|
|
976
1065
|
}
|
|
1066
|
+
/**
|
|
1067
|
+
* @description Logs a benchmark message.
|
|
1068
|
+
* @summary Delegates the benchmark logging to the global logger instance.
|
|
1069
|
+
*
|
|
1070
|
+
* @param msg - The message to be logged.
|
|
1071
|
+
*/
|
|
1072
|
+
static benchmark(msg) {
|
|
1073
|
+
return this.get().benchmark(msg);
|
|
1074
|
+
}
|
|
977
1075
|
/**
|
|
978
1076
|
* @description Logs a silly message.
|
|
979
1077
|
* @summary Delegates the debug logging to the global logger instance.
|
|
@@ -1129,12 +1227,8 @@
|
|
|
1129
1227
|
}
|
|
1130
1228
|
|
|
1131
1229
|
/**
|
|
1132
|
-
* @description Base class that provides a ready-to-use logger instance
|
|
1133
|
-
* @summary
|
|
1134
|
-
* into derived classes through a protected getter. Subclasses can directly access
|
|
1135
|
-
* this.log to emit messages without manually creating a logger. This promotes
|
|
1136
|
-
* consistent, context-aware logging across the codebase.
|
|
1137
|
-
* @param {void} [constructor] - No constructor arguments; subclasses may define their own
|
|
1230
|
+
* @description Base class that provides a ready-to-use logger instance.
|
|
1231
|
+
* @summary Supplies inheriting classes with a lazily created, context-aware {@link Logger} via the protected `log` getter, promoting consistent structured logging without manual wiring.
|
|
1138
1232
|
* @class LoggedClass
|
|
1139
1233
|
* @example
|
|
1140
1234
|
* class UserService extends LoggedClass {
|
|
@@ -1162,30 +1256,273 @@
|
|
|
1162
1256
|
*/
|
|
1163
1257
|
class LoggedClass {
|
|
1164
1258
|
/**
|
|
1165
|
-
* @description Lazily provides a context-aware logger for the current instance
|
|
1166
|
-
* @summary
|
|
1167
|
-
*
|
|
1168
|
-
* @return {Logger} A logger bound to the subclass context
|
|
1259
|
+
* @description Lazily provides a context-aware logger for the current instance.
|
|
1260
|
+
* @summary Calls {@link Logging.for} with the subclass instance to obtain a logger whose context matches the subclass name.
|
|
1261
|
+
* @return {Logger} Logger bound to the subclass context.
|
|
1169
1262
|
*/
|
|
1170
1263
|
get log() {
|
|
1171
|
-
|
|
1264
|
+
if (!this._log)
|
|
1265
|
+
this._log = Logging.for(this);
|
|
1266
|
+
return this._log;
|
|
1172
1267
|
}
|
|
1173
1268
|
constructor() { }
|
|
1174
1269
|
}
|
|
1175
1270
|
|
|
1271
|
+
/**
|
|
1272
|
+
* @description Base class for message filters that plug into the logging pipeline.
|
|
1273
|
+
* @summary Extends {@link LoggedClass} to supply a scoped logger and defines the contract required by {@link LoggingFilter} implementers that transform or drop log messages before emission.
|
|
1274
|
+
* @class LogFilter
|
|
1275
|
+
* @example
|
|
1276
|
+
* class RedactSecretsFilter extends LogFilter {
|
|
1277
|
+
* filter(config: LoggingConfig, message: string): string {
|
|
1278
|
+
* return message.replace(/secret/gi, "***");
|
|
1279
|
+
* }
|
|
1280
|
+
* }
|
|
1281
|
+
*
|
|
1282
|
+
* const filter = new RedactSecretsFilter();
|
|
1283
|
+
* filter.filter({ ...DefaultLoggingConfig, verbose: 0 }, "secret token");
|
|
1284
|
+
* @mermaid
|
|
1285
|
+
* sequenceDiagram
|
|
1286
|
+
* participant Logger
|
|
1287
|
+
* participant Filter as LogFilter
|
|
1288
|
+
* participant Impl as ConcreteFilter
|
|
1289
|
+
* participant Output
|
|
1290
|
+
* Logger->>Filter: filter(config, message, context)
|
|
1291
|
+
* Filter->>Impl: delegate to subclass implementation
|
|
1292
|
+
* Impl-->>Filter: transformed message
|
|
1293
|
+
* Filter-->>Output: return filtered message
|
|
1294
|
+
*/
|
|
1176
1295
|
class LogFilter extends LoggedClass {
|
|
1296
|
+
/**
|
|
1297
|
+
* @description Scoped logger that excludes other filters from the chain.
|
|
1298
|
+
* @summary Returns a child logger dedicated to the filter, preventing recursive filter invocation when emitting diagnostic messages.
|
|
1299
|
+
* @return {Logger} Context-aware logger for the filter instance.
|
|
1300
|
+
*/
|
|
1177
1301
|
get log() {
|
|
1178
1302
|
return super.log.for(this, { filters: [] });
|
|
1179
1303
|
}
|
|
1180
1304
|
}
|
|
1181
1305
|
|
|
1306
|
+
function safeNow() {
|
|
1307
|
+
// Prefer performance.now when available
|
|
1308
|
+
if (typeof globalThis !== "undefined" &&
|
|
1309
|
+
typeof globalThis.performance?.now === "function") {
|
|
1310
|
+
return () => globalThis.performance.now();
|
|
1311
|
+
}
|
|
1312
|
+
// Node: use process.hrtime.bigint for higher precision if available
|
|
1313
|
+
if (typeof process !== "undefined" &&
|
|
1314
|
+
typeof process.hrtime?.bigint === "function") {
|
|
1315
|
+
return () => {
|
|
1316
|
+
const ns = process.hrtime.bigint(); // nanoseconds
|
|
1317
|
+
return Number(ns) / 1_000_000; // to ms
|
|
1318
|
+
};
|
|
1319
|
+
}
|
|
1320
|
+
// Fallback
|
|
1321
|
+
return () => Date.now();
|
|
1322
|
+
}
|
|
1323
|
+
/**
|
|
1324
|
+
* @description High-resolution clock accessor returning milliseconds.
|
|
1325
|
+
* @summary Chooses the most precise timer available in the current runtime, preferring `performance.now` or `process.hrtime.bigint`.
|
|
1326
|
+
* @return {number} Milliseconds elapsed according to the best available clock.
|
|
1327
|
+
*/
|
|
1328
|
+
const now = safeNow();
|
|
1182
1329
|
/**
|
|
1183
|
-
* @description
|
|
1184
|
-
* @summary
|
|
1185
|
-
* @param {
|
|
1186
|
-
* @
|
|
1187
|
-
* @
|
|
1188
|
-
*
|
|
1330
|
+
* @description High-resolution stopwatch with pause, resume, and lap tracking.
|
|
1331
|
+
* @summary Tracks elapsed time using the highest precision timer available, supports pausing, resuming, and recording labeled laps for diagnostics and benchmarking.
|
|
1332
|
+
* @param {boolean} [autoStart=false] - When true, the stopwatch starts immediately upon construction.
|
|
1333
|
+
* @class StopWatch
|
|
1334
|
+
* @example
|
|
1335
|
+
* const sw = new StopWatch(true);
|
|
1336
|
+
* // ... work ...
|
|
1337
|
+
* const lap = sw.lap("phase 1");
|
|
1338
|
+
* sw.pause();
|
|
1339
|
+
* console.log(`Elapsed: ${lap.totalMs}ms`);
|
|
1340
|
+
* @mermaid
|
|
1341
|
+
* sequenceDiagram
|
|
1342
|
+
* participant Client
|
|
1343
|
+
* participant StopWatch
|
|
1344
|
+
* participant Clock as now()
|
|
1345
|
+
* Client->>StopWatch: start()
|
|
1346
|
+
* StopWatch->>Clock: now()
|
|
1347
|
+
* Clock-->>StopWatch: timestamp
|
|
1348
|
+
* Client->>StopWatch: lap()
|
|
1349
|
+
* StopWatch->>Clock: now()
|
|
1350
|
+
* Clock-->>StopWatch: timestamp
|
|
1351
|
+
* StopWatch-->>Client: Lap
|
|
1352
|
+
* Client->>StopWatch: pause()
|
|
1353
|
+
* StopWatch->>Clock: now()
|
|
1354
|
+
* Clock-->>StopWatch: timestamp
|
|
1355
|
+
*/
|
|
1356
|
+
class StopWatch {
|
|
1357
|
+
constructor(autoStart = false) {
|
|
1358
|
+
this._startMs = null;
|
|
1359
|
+
this._elapsedMs = 0;
|
|
1360
|
+
this._running = false;
|
|
1361
|
+
this._laps = [];
|
|
1362
|
+
this._lastLapTotalMs = 0;
|
|
1363
|
+
if (autoStart)
|
|
1364
|
+
this.start();
|
|
1365
|
+
}
|
|
1366
|
+
/**
|
|
1367
|
+
* @description Indicates whether the stopwatch is actively running.
|
|
1368
|
+
* @summary Returns `true` when timing is in progress and `false` when paused or stopped.
|
|
1369
|
+
* @return {boolean} Current running state.
|
|
1370
|
+
*/
|
|
1371
|
+
get running() {
|
|
1372
|
+
return this._running;
|
|
1373
|
+
}
|
|
1374
|
+
/**
|
|
1375
|
+
* @description Elapsed time captured by the stopwatch.
|
|
1376
|
+
* @summary Computes the total elapsed time in milliseconds, including the current session if running.
|
|
1377
|
+
* @return {number} Milliseconds elapsed since the stopwatch started.
|
|
1378
|
+
*/
|
|
1379
|
+
get elapsedMs() {
|
|
1380
|
+
if (!this._running || this._startMs == null)
|
|
1381
|
+
return this._elapsedMs;
|
|
1382
|
+
return this._elapsedMs + (now() - this._startMs);
|
|
1383
|
+
}
|
|
1384
|
+
/**
|
|
1385
|
+
* @description Starts timing if the stopwatch is not already running.
|
|
1386
|
+
* @summary Records the current timestamp and transitions the stopwatch into the running state.
|
|
1387
|
+
* @return {this} Fluent reference to the stopwatch.
|
|
1388
|
+
*/
|
|
1389
|
+
start() {
|
|
1390
|
+
if (!this._running) {
|
|
1391
|
+
this._running = true;
|
|
1392
|
+
this._startMs = now();
|
|
1393
|
+
}
|
|
1394
|
+
return this;
|
|
1395
|
+
}
|
|
1396
|
+
/**
|
|
1397
|
+
* @description Pauses timing and accumulates elapsed milliseconds.
|
|
1398
|
+
* @summary Captures the partial duration, updates the accumulator, and keeps the stopwatch ready to resume later.
|
|
1399
|
+
* @return {this} Fluent reference to the stopwatch.
|
|
1400
|
+
*/
|
|
1401
|
+
pause() {
|
|
1402
|
+
if (this._running && this._startMs != null) {
|
|
1403
|
+
this._elapsedMs += now() - this._startMs;
|
|
1404
|
+
this._startMs = null;
|
|
1405
|
+
this._running = false;
|
|
1406
|
+
}
|
|
1407
|
+
return this;
|
|
1408
|
+
}
|
|
1409
|
+
/**
|
|
1410
|
+
* @description Resumes timing after a pause.
|
|
1411
|
+
* @summary Captures a fresh start timestamp while keeping previous elapsed time intact.
|
|
1412
|
+
* @return {this} Fluent reference to the stopwatch.
|
|
1413
|
+
*/
|
|
1414
|
+
resume() {
|
|
1415
|
+
if (!this._running) {
|
|
1416
|
+
this._running = true;
|
|
1417
|
+
this._startMs = now();
|
|
1418
|
+
}
|
|
1419
|
+
return this;
|
|
1420
|
+
}
|
|
1421
|
+
/**
|
|
1422
|
+
* @description Stops timing and returns the total elapsed milliseconds.
|
|
1423
|
+
* @summary Invokes {@link StopWatch.pause} to consolidate elapsed time, leaving the stopwatch in a non-running state.
|
|
1424
|
+
* @return {number} Milliseconds accumulated across all runs.
|
|
1425
|
+
*/
|
|
1426
|
+
stop() {
|
|
1427
|
+
this.pause();
|
|
1428
|
+
return this._elapsedMs;
|
|
1429
|
+
}
|
|
1430
|
+
/**
|
|
1431
|
+
* @description Resets the stopwatch state while optionally continuing to run.
|
|
1432
|
+
* @summary Clears elapsed time and lap history, preserving whether the stopwatch should continue ticking.
|
|
1433
|
+
* @return {this} Fluent reference to the stopwatch.
|
|
1434
|
+
*/
|
|
1435
|
+
reset() {
|
|
1436
|
+
const wasRunning = this._running;
|
|
1437
|
+
this._startMs = wasRunning ? now() : null;
|
|
1438
|
+
this._elapsedMs = 0;
|
|
1439
|
+
this._laps = [];
|
|
1440
|
+
this._lastLapTotalMs = 0;
|
|
1441
|
+
return this;
|
|
1442
|
+
}
|
|
1443
|
+
/**
|
|
1444
|
+
* @description Records a lap split since the stopwatch started or since the previous lap.
|
|
1445
|
+
* @summary Stores the lap metadata, updates cumulative tracking, and returns the newly created {@link Lap}.
|
|
1446
|
+
* @param {string} [label] - Optional label describing the lap.
|
|
1447
|
+
* @return {Lap} Lap snapshot capturing incremental and cumulative timings.
|
|
1448
|
+
*/
|
|
1449
|
+
lap(label) {
|
|
1450
|
+
const total = this.elapsedMs;
|
|
1451
|
+
const ms = total - this._lastLapTotalMs;
|
|
1452
|
+
const lap = {
|
|
1453
|
+
index: this._laps.length,
|
|
1454
|
+
label,
|
|
1455
|
+
ms,
|
|
1456
|
+
totalMs: total,
|
|
1457
|
+
};
|
|
1458
|
+
this._laps.push(lap);
|
|
1459
|
+
this._lastLapTotalMs = total;
|
|
1460
|
+
return lap;
|
|
1461
|
+
}
|
|
1462
|
+
/**
|
|
1463
|
+
* @description Retrieves the recorded lap history.
|
|
1464
|
+
* @summary Returns the internal lap array as a read-only view to prevent external mutation.
|
|
1465
|
+
* @return {Lap[]} Laps captured by the stopwatch.
|
|
1466
|
+
*/
|
|
1467
|
+
get laps() {
|
|
1468
|
+
return this._laps;
|
|
1469
|
+
}
|
|
1470
|
+
/**
|
|
1471
|
+
* @description Formats the elapsed time in a human-readable representation.
|
|
1472
|
+
* @summary Uses {@link formatMs} to produce an `hh:mm:ss.mmm` string for display and logging.
|
|
1473
|
+
* @return {string} Elapsed time formatted for presentation.
|
|
1474
|
+
*/
|
|
1475
|
+
toString() {
|
|
1476
|
+
return formatMs(this.elapsedMs);
|
|
1477
|
+
}
|
|
1478
|
+
/**
|
|
1479
|
+
* @description Serializes the stopwatch state.
|
|
1480
|
+
* @summary Provides a JSON-friendly snapshot including running state, elapsed time, and lap details.
|
|
1481
|
+
* @return {{running: boolean, elapsedMs: number, laps: Lap[]}} Serializable stopwatch representation.
|
|
1482
|
+
*/
|
|
1483
|
+
toJSON() {
|
|
1484
|
+
return {
|
|
1485
|
+
running: this._running,
|
|
1486
|
+
elapsedMs: this.elapsedMs,
|
|
1487
|
+
laps: this._laps.slice(),
|
|
1488
|
+
};
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
/**
|
|
1492
|
+
* @description Formats milliseconds into `hh:mm:ss.mmm`.
|
|
1493
|
+
* @summary Breaks the duration into hours, minutes, seconds, and milliseconds, returning a zero-padded string.
|
|
1494
|
+
* @param {number} ms - Milliseconds to format.
|
|
1495
|
+
* @return {string} Formatted duration string.
|
|
1496
|
+
* @function formatMs
|
|
1497
|
+
* @memberOf module:Logging
|
|
1498
|
+
* @mermaid
|
|
1499
|
+
* sequenceDiagram
|
|
1500
|
+
* participant Caller
|
|
1501
|
+
* participant Formatter as formatMs
|
|
1502
|
+
* Caller->>Formatter: formatMs(ms)
|
|
1503
|
+
* Formatter->>Formatter: derive hours/minutes/seconds
|
|
1504
|
+
* Formatter->>Formatter: pad segments
|
|
1505
|
+
* Formatter-->>Caller: hh:mm:ss.mmm
|
|
1506
|
+
*/
|
|
1507
|
+
function formatMs(ms) {
|
|
1508
|
+
const sign = ms < 0 ? "-" : "";
|
|
1509
|
+
const abs = Math.abs(ms);
|
|
1510
|
+
const hours = Math.floor(abs / 3_600_000);
|
|
1511
|
+
const minutes = Math.floor((abs % 3_600_000) / 60_000);
|
|
1512
|
+
const seconds = Math.floor((abs % 60_000) / 1000);
|
|
1513
|
+
const millis = Math.floor(abs % 1000);
|
|
1514
|
+
const pad = (n, w) => n.toString().padStart(w, "0");
|
|
1515
|
+
return `${sign}${pad(hours, 2)}:${pad(minutes, 2)}:${pad(seconds, 2)}.${pad(millis, 3)}`;
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1518
|
+
/**
|
|
1519
|
+
* @description Method decorator for logging function calls.
|
|
1520
|
+
* @summary Wraps class methods to automatically log entry, exit, timing, and optional custom messages at a configurable {@link LogLevel}.
|
|
1521
|
+
* @param {LogLevel} level - Log level applied to the generated log statements (defaults to `LogLevel.info`).
|
|
1522
|
+
* @param {number} [verbosity=0] - Verbosity threshold required for the entry log to appear.
|
|
1523
|
+
* @param {ArgFormatFunction} [entryMessage] - Formatter invoked with the original method arguments to describe the invocation.
|
|
1524
|
+
* @param {ReturnFormatFunction} [exitMessage] - Optional formatter that describes the outcome or failure of the call.
|
|
1525
|
+
* @return {function(any, any, PropertyDescriptor): void} Method decorator proxy that injects logging behavior.
|
|
1189
1526
|
* @function log
|
|
1190
1527
|
* @mermaid
|
|
1191
1528
|
* sequenceDiagram
|
|
@@ -1210,93 +1547,153 @@
|
|
|
1210
1547
|
* end
|
|
1211
1548
|
* @category Method Decorators
|
|
1212
1549
|
*/
|
|
1213
|
-
function log(level = exports.LogLevel.info,
|
|
1214
|
-
return function (target, propertyKey, descriptor) {
|
|
1215
|
-
if (!descriptor)
|
|
1550
|
+
function log(level = exports.LogLevel.info, verbosity = 0, entryMessage = (...args) => `called with ${args}`, exitMessage) {
|
|
1551
|
+
return function log(target, propertyKey, descriptor) {
|
|
1552
|
+
if (!descriptor || typeof descriptor === "number")
|
|
1216
1553
|
throw new Error(`Logging decoration only applies to methods`);
|
|
1217
|
-
const logger =
|
|
1554
|
+
const logger = target instanceof LoggedClass
|
|
1555
|
+
? target["log"].for(target[propertyKey])
|
|
1556
|
+
: Logging.for(target).for(target[propertyKey]);
|
|
1218
1557
|
const method = logger[level].bind(logger);
|
|
1219
1558
|
const originalMethod = descriptor.value;
|
|
1220
1559
|
descriptor.value = new Proxy(originalMethod, {
|
|
1221
1560
|
apply(fn, thisArg, args) {
|
|
1222
|
-
method(
|
|
1223
|
-
|
|
1561
|
+
method(entryMessage(...args), verbosity);
|
|
1562
|
+
try {
|
|
1563
|
+
const result = Reflect.apply(fn, thisArg, args);
|
|
1564
|
+
if (result instanceof Promise) {
|
|
1565
|
+
return result
|
|
1566
|
+
.then((r) => {
|
|
1567
|
+
if (exitMessage)
|
|
1568
|
+
method(exitMessage(undefined, r));
|
|
1569
|
+
return r;
|
|
1570
|
+
})
|
|
1571
|
+
.catch((e) => {
|
|
1572
|
+
if (exitMessage)
|
|
1573
|
+
logger.error(exitMessage(e));
|
|
1574
|
+
throw e;
|
|
1575
|
+
});
|
|
1576
|
+
}
|
|
1577
|
+
if (exitMessage)
|
|
1578
|
+
method(exitMessage(undefined, result));
|
|
1579
|
+
return result;
|
|
1580
|
+
}
|
|
1581
|
+
catch (err) {
|
|
1582
|
+
if (exitMessage)
|
|
1583
|
+
logger.error(exitMessage(err));
|
|
1584
|
+
throw err;
|
|
1585
|
+
}
|
|
1586
|
+
},
|
|
1587
|
+
});
|
|
1588
|
+
return descriptor;
|
|
1589
|
+
};
|
|
1590
|
+
}
|
|
1591
|
+
/**
|
|
1592
|
+
* @description Method decorator that records execution time at the benchmark level.
|
|
1593
|
+
* @summary Wraps the target method to emit {@link Logger.benchmark} entries capturing completion time or failure latency.
|
|
1594
|
+
* @return {function(any, any, PropertyDescriptor): void} Method decorator proxy that benchmarks the original implementation.
|
|
1595
|
+
* @function benchmark
|
|
1596
|
+
* @mermaid
|
|
1597
|
+
* sequenceDiagram
|
|
1598
|
+
* participant Caller
|
|
1599
|
+
* participant Decorator as benchmark
|
|
1600
|
+
* participant Method as Original Method
|
|
1601
|
+
* Caller->>Decorator: invoke()
|
|
1602
|
+
* Decorator->>Method: Reflect.apply(...)
|
|
1603
|
+
* alt Promise result
|
|
1604
|
+
* Method-->>Decorator: Promise
|
|
1605
|
+
* Decorator->>Decorator: attach then()
|
|
1606
|
+
* Decorator->>Decorator: log completion duration
|
|
1607
|
+
* else Synchronous result
|
|
1608
|
+
* Method-->>Decorator: value
|
|
1609
|
+
* Decorator->>Decorator: log completion duration
|
|
1610
|
+
* end
|
|
1611
|
+
* Decorator-->>Caller: return result
|
|
1612
|
+
* @category Method Decorators
|
|
1613
|
+
*/
|
|
1614
|
+
function benchmark() {
|
|
1615
|
+
return function benchmark(target, propertyKey, descriptor) {
|
|
1616
|
+
if (!descriptor || typeof descriptor === "number")
|
|
1617
|
+
throw new Error(`benchmark decoration only applies to methods`);
|
|
1618
|
+
const logger = target instanceof LoggedClass
|
|
1619
|
+
? target["log"].for(target[propertyKey])
|
|
1620
|
+
: Logging.for(target).for(target[propertyKey]);
|
|
1621
|
+
const originalMethod = descriptor.value;
|
|
1622
|
+
descriptor.value = new Proxy(originalMethod, {
|
|
1623
|
+
apply(fn, thisArg, args) {
|
|
1624
|
+
const start = now();
|
|
1224
1625
|
try {
|
|
1225
1626
|
const result = Reflect.apply(fn, thisArg, args);
|
|
1226
1627
|
if (result instanceof Promise) {
|
|
1227
1628
|
return result.then((r) => {
|
|
1228
|
-
|
|
1229
|
-
method(`completed in ${Date.now() - start}ms`, verbosity);
|
|
1629
|
+
logger.benchmark(`completed in ${now() - start}ms`);
|
|
1230
1630
|
return r;
|
|
1231
1631
|
});
|
|
1232
1632
|
}
|
|
1233
|
-
|
|
1234
|
-
method(`completed in ${Date.now() - start}ms`, verbosity);
|
|
1633
|
+
logger.benchmark(`completed in ${now() - start}ms`);
|
|
1235
1634
|
return result;
|
|
1236
1635
|
}
|
|
1237
1636
|
catch (err) {
|
|
1238
|
-
|
|
1239
|
-
method(`failed in ${Date.now() - start}ms`, verbosity);
|
|
1637
|
+
logger.benchmark(`failed in ${now() - start}ms`);
|
|
1240
1638
|
throw err;
|
|
1241
1639
|
}
|
|
1242
1640
|
},
|
|
1243
1641
|
});
|
|
1642
|
+
return descriptor;
|
|
1244
1643
|
};
|
|
1245
1644
|
}
|
|
1246
1645
|
/**
|
|
1247
|
-
* @description Method decorator for logging function calls with debug level
|
|
1248
|
-
* @summary Convenience wrapper around
|
|
1249
|
-
* @
|
|
1250
|
-
* @return {Function} A method decorator that wraps the original method with debug logging
|
|
1646
|
+
* @description Method decorator for logging function calls with debug level.
|
|
1647
|
+
* @summary Convenience wrapper around {@link log} that logs using `LogLevel.debug`.
|
|
1648
|
+
* @return {function(any, any, PropertyDescriptor): void} Debug-level logging decorator.
|
|
1251
1649
|
* @function debug
|
|
1252
1650
|
* @category Method Decorators
|
|
1253
1651
|
*/
|
|
1254
|
-
function debug(
|
|
1255
|
-
return log(exports.LogLevel.debug,
|
|
1652
|
+
function debug() {
|
|
1653
|
+
return log(exports.LogLevel.debug, 0, (...args) => `called with ${args}`, (e, result) => e
|
|
1654
|
+
? `Failed with: ${e}`
|
|
1655
|
+
: result
|
|
1656
|
+
? `Completed with ${JSON.stringify(result)}`
|
|
1657
|
+
: "completed");
|
|
1256
1658
|
}
|
|
1257
1659
|
/**
|
|
1258
|
-
* @description Method decorator for logging function calls with info level
|
|
1259
|
-
* @summary Convenience wrapper around
|
|
1260
|
-
* @
|
|
1261
|
-
* @return {Function} A method decorator that wraps the original method with info logging
|
|
1660
|
+
* @description Method decorator for logging function calls with info level.
|
|
1661
|
+
* @summary Convenience wrapper around {@link log} that logs using `LogLevel.info`.
|
|
1662
|
+
* @return {function(any, any, PropertyDescriptor): void} Info-level logging decorator.
|
|
1262
1663
|
* @function info
|
|
1263
1664
|
* @category Method Decorators
|
|
1264
1665
|
*/
|
|
1265
|
-
function info(
|
|
1266
|
-
return log(exports.LogLevel.info
|
|
1666
|
+
function info() {
|
|
1667
|
+
return log(exports.LogLevel.info);
|
|
1267
1668
|
}
|
|
1268
1669
|
/**
|
|
1269
|
-
* @description Method decorator for logging function calls with silly level
|
|
1270
|
-
* @summary Convenience wrapper around
|
|
1271
|
-
* @
|
|
1272
|
-
* @return {Function} A method decorator that wraps the original method with silly logging
|
|
1670
|
+
* @description Method decorator for logging function calls with silly level.
|
|
1671
|
+
* @summary Convenience wrapper around {@link log} that logs using `LogLevel.silly`.
|
|
1672
|
+
* @return {function(any, any, PropertyDescriptor): void} Silly-level logging decorator.
|
|
1273
1673
|
* @function silly
|
|
1274
1674
|
* @category Method Decorators
|
|
1275
1675
|
*/
|
|
1276
|
-
function silly(
|
|
1277
|
-
return log(exports.LogLevel.silly
|
|
1676
|
+
function silly() {
|
|
1677
|
+
return log(exports.LogLevel.silly);
|
|
1278
1678
|
}
|
|
1279
1679
|
/**
|
|
1280
|
-
* @description Method decorator for logging function calls with verbose level
|
|
1281
|
-
* @summary Convenience wrapper around
|
|
1282
|
-
* @param {number} verbosity -
|
|
1283
|
-
* @
|
|
1284
|
-
* @return {Function} A method decorator that wraps the original method with verbose logging
|
|
1680
|
+
* @description Method decorator for logging function calls with verbose level.
|
|
1681
|
+
* @summary Convenience wrapper around {@link log} that logs using `LogLevel.verbose` with configurable verbosity and optional benchmarking.
|
|
1682
|
+
* @param {number|boolean} verbosity - Verbosity level for log filtering or flag to enable benchmarking.
|
|
1683
|
+
* @return {function(any, any,PropertyDescriptor): void} Verbose logging decorator.
|
|
1285
1684
|
* @function verbose
|
|
1286
1685
|
* @category Method Decorators
|
|
1287
1686
|
*/
|
|
1288
|
-
function verbose(verbosity = 0
|
|
1289
|
-
if (
|
|
1290
|
-
benchmark = verbosity;
|
|
1687
|
+
function verbose(verbosity = 0) {
|
|
1688
|
+
if (!verbosity) {
|
|
1291
1689
|
verbosity = 0;
|
|
1292
1690
|
}
|
|
1293
|
-
return log(exports.LogLevel.verbose,
|
|
1691
|
+
return log(exports.LogLevel.verbose, verbosity);
|
|
1294
1692
|
}
|
|
1295
1693
|
/**
|
|
1296
|
-
* @description Creates a decorator that makes a method non-configurable
|
|
1297
|
-
* @summary
|
|
1298
|
-
*
|
|
1299
|
-
* @return {Function} A decorator function that can be applied to methods
|
|
1694
|
+
* @description Creates a decorator that makes a method non-configurable.
|
|
1695
|
+
* @summary Prevents overriding by marking the method descriptor as non-configurable, throwing if applied to non-method targets.
|
|
1696
|
+
* @return {function(object, any, PropertyDescriptor): PropertyDescriptor|undefined} Decorator that hardens the method descriptor.
|
|
1300
1697
|
* @function final
|
|
1301
1698
|
* @category Method Decorators
|
|
1302
1699
|
*/
|
|
@@ -1311,17 +1708,57 @@
|
|
|
1311
1708
|
};
|
|
1312
1709
|
}
|
|
1313
1710
|
|
|
1711
|
+
/**
|
|
1712
|
+
* @description Filter that patches log messages using regular expressions.
|
|
1713
|
+
* @summary Applies a configured {@link RegExp} and replacement strategy to redact, mask, or restructure log payloads before they are emitted.
|
|
1714
|
+
* @param {RegExp} regexp - Expression used to detect sensitive or formatted text.
|
|
1715
|
+
* @param {string|ReplacementFunction} replacement - Replacement string or callback invoked for each match.
|
|
1716
|
+
* @class PatternFilter
|
|
1717
|
+
* @example
|
|
1718
|
+
* const filter = new PatternFilter(/token=[^&]+/g, "token=***");
|
|
1719
|
+
* const sanitized = filter.filter(config, "token=123&user=tom", []);
|
|
1720
|
+
* // sanitized === "token=***&user=tom"
|
|
1721
|
+
* @mermaid
|
|
1722
|
+
* sequenceDiagram
|
|
1723
|
+
* participant Logger
|
|
1724
|
+
* participant Filter as PatternFilter
|
|
1725
|
+
* participant RegExp
|
|
1726
|
+
* Logger->>Filter: filter(config, message, context)
|
|
1727
|
+
* Filter->>RegExp: execute match()
|
|
1728
|
+
* alt match found
|
|
1729
|
+
* RegExp-->>Filter: captures
|
|
1730
|
+
* Filter->>RegExp: replace(message, replacement)
|
|
1731
|
+
* RegExp-->>Filter: transformed message
|
|
1732
|
+
* else no match
|
|
1733
|
+
* RegExp-->>Filter: null
|
|
1734
|
+
* end
|
|
1735
|
+
* Filter-->>Logger: sanitized message
|
|
1736
|
+
*/
|
|
1314
1737
|
class PatternFilter extends LogFilter {
|
|
1315
1738
|
constructor(regexp, replacement) {
|
|
1316
1739
|
super();
|
|
1317
1740
|
this.regexp = regexp;
|
|
1318
1741
|
this.replacement = replacement;
|
|
1319
1742
|
}
|
|
1743
|
+
/**
|
|
1744
|
+
* @description Ensures deterministic RegExp matching.
|
|
1745
|
+
* @summary Runs the configured expression, then resets its state so repeated invocations behave consistently.
|
|
1746
|
+
* @param {string} message - Message to test for matches.
|
|
1747
|
+
* @return {RegExpExecArray|null} Match result or null when no match is found.
|
|
1748
|
+
*/
|
|
1320
1749
|
match(message) {
|
|
1321
1750
|
const match = this.regexp.exec(message);
|
|
1322
1751
|
this.regexp.lastIndex = 0;
|
|
1323
1752
|
return match;
|
|
1324
1753
|
}
|
|
1754
|
+
/**
|
|
1755
|
+
* @description Applies the replacement strategy to the incoming message.
|
|
1756
|
+
* @summary Executes {@link PatternFilter.match} and, when a match is found, replaces every occurrence using the configured replacement handler.
|
|
1757
|
+
* @param {LoggingConfig} config - Active logging configuration (unused but part of the filter contract).
|
|
1758
|
+
* @param {string} message - Message to be sanitized.
|
|
1759
|
+
* @param {string[]} context - Context entries associated with the log event.
|
|
1760
|
+
* @return {string} Sanitized log message.
|
|
1761
|
+
*/
|
|
1325
1762
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1326
1763
|
filter(config, message, context) {
|
|
1327
1764
|
const log = this.log.for(this.filter);
|
|
@@ -1345,22 +1782,18 @@
|
|
|
1345
1782
|
], PatternFilter.prototype, "match", null);
|
|
1346
1783
|
|
|
1347
1784
|
/**
|
|
1348
|
-
* @description
|
|
1349
|
-
* @summary
|
|
1350
|
-
* - Core classes like {@link Logging} and {@link MiniLogger}
|
|
1351
|
-
* - Decorators such as {@link log} for instrumenting methods
|
|
1352
|
-
* - Configuration and constants like {@link LogLevel} and {@link DefaultLoggingConfig}
|
|
1353
|
-
* - Type definitions including {@link Logger} and {@link LoggingConfig}
|
|
1354
|
-
* These exports enable consistent, context-aware, and optionally themed logging across projects.
|
|
1785
|
+
* @description Comprehensive logging toolkit for browser and Node environments.
|
|
1786
|
+
* @summary Exposes {@link Logging} and {@link MiniLogger} for runtime logging, decorators such as {@link log} for method instrumentation, and utilities like {@link PatternFilter}, {@link StopWatch}, and {@link LoggedEnvironment} to build configurable, theme-aware log pipelines.
|
|
1355
1787
|
* @module Logging
|
|
1356
1788
|
*/
|
|
1357
1789
|
/**
|
|
1358
|
-
* @description Current package version string
|
|
1359
|
-
* @summary Stores the
|
|
1790
|
+
* @description Current package version string.
|
|
1791
|
+
* @summary Stores the package version for diagnostics and compatibility checks.
|
|
1360
1792
|
* @const VERSION
|
|
1793
|
+
* @type {string}
|
|
1361
1794
|
* @memberOf module:Logging
|
|
1362
1795
|
*/
|
|
1363
|
-
const VERSION = "0.3.
|
|
1796
|
+
const VERSION = "0.3.12";
|
|
1364
1797
|
|
|
1365
1798
|
exports.BrowserEnvKey = BrowserEnvKey;
|
|
1366
1799
|
exports.DefaultLoggingConfig = DefaultLoggingConfig;
|
|
@@ -1375,13 +1808,17 @@
|
|
|
1375
1808
|
exports.MiniLogger = MiniLogger;
|
|
1376
1809
|
exports.NumericLogLevels = NumericLogLevels;
|
|
1377
1810
|
exports.PatternFilter = PatternFilter;
|
|
1811
|
+
exports.StopWatch = StopWatch;
|
|
1378
1812
|
exports.VERSION = VERSION;
|
|
1813
|
+
exports.benchmark = benchmark;
|
|
1379
1814
|
exports.debug = debug;
|
|
1380
1815
|
exports.escapeRegExp = escapeRegExp;
|
|
1381
1816
|
exports.final = final;
|
|
1817
|
+
exports.formatMs = formatMs;
|
|
1382
1818
|
exports.info = info;
|
|
1383
1819
|
exports.isBrowser = isBrowser;
|
|
1384
1820
|
exports.log = log;
|
|
1821
|
+
exports.now = now;
|
|
1385
1822
|
exports.padEnd = padEnd;
|
|
1386
1823
|
exports.patchPlaceholders = patchPlaceholders;
|
|
1387
1824
|
exports.patchString = patchString;
|
|
@@ -1396,4 +1833,4 @@
|
|
|
1396
1833
|
exports.verbose = verbose;
|
|
1397
1834
|
|
|
1398
1835
|
}));
|
|
1399
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2luZy5janMiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb25zdGFudHMudHMiLCIuLi9zcmMvdGV4dC50cyIsIi4uL3NyYy93ZWIudHMiLCIuLi9zcmMvZW52aXJvbm1lbnQudHMiLCIuLi9zcmMvbG9nZ2luZy50cyIsIi4uL3NyYy9Mb2dnZWRDbGFzcy50cyIsIi4uL3NyYy9maWx0ZXJzL0xvZ0ZpbHRlci50cyIsIi4uL3NyYy9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL2ZpbHRlcnMvUGF0dGVybkZpbHRlci50cyIsIi4uL3NyYy9pbmRleC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBMb2dnaW5nQ29uZmlnLCBUaGVtZSB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbmV4cG9ydCBjb25zdCBCcm93c2VyRW52S2V5ID0gXCJFTlZcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVsaW1pdGVyIHVzZWQgZm9yIGNvbXBvc2luZyBuZXN0ZWQgZW52aXJvbm1lbnQgdmFyaWFibGUgbmFtZXMuXG4gKiBAc3VtbWFyeSBKb2lucyBwYXJlbnQgYW5kIGNoaWxkIGtleXMgd2hlbiBtYXBwaW5nIG9iamVjdCBwYXRocyB0byBFTlYgc3RyaW5ncy5cbiAqL1xuZXhwb3J0IGNvbnN0IEVOVl9QQVRIX0RFTElNSVRFUiA9IFwiX19cIjtcblxuZXhwb3J0IGNvbnN0IERlZmF1bHRQbGFjZWhvbGRlcldyYXBwZXJzID0gW1wiJHtcIiwgXCJ9XCJdO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBFbnVtIGZvciBsb2cgbGV2ZWxzLlxuICogQHN1bW1hcnkgRGVmaW5lcyBkaWZmZXJlbnQgbGV2ZWxzIG9mIGxvZ2dpbmcgZm9yIHRoZSBhcHBsaWNhdGlvbi5cbiAqIEBlbnVtIHtzdHJpbmd9XG4gKiBAcmVhZG9ubHlcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgZW51bSBMb2dMZXZlbCB7XG4gIC8qKiBFcnJvciBldmVudHMgdGhhdCBhcmUgbGlrZWx5IHRvIGNhdXNlIHByb2JsZW1zLiAqL1xuICBlcnJvciA9IFwiZXJyb3JcIixcbiAgLyoqIFJvdXRpbmUgaW5mb3JtYXRpb24sIHN1Y2ggYXMgb25nb2luZyBzdGF0dXMgb3IgcGVyZm9ybWFuY2UuICovXG4gIGluZm8gPSBcImluZm9cIixcbiAgLyoqIEFkZGl0aW9uYWwgcmVsZXZhbnQgaW5mb3JtYXRpb24uICovXG4gIHZlcmJvc2UgPSBcInZlcmJvc2VcIixcbiAgLyoqIERlYnVnIG9yIHRyYWNlIGluZm9ybWF0aW9uLiAqL1xuICBkZWJ1ZyA9IFwiZGVidWdcIixcbiAgLyoqIHdheSB0b28gdmVyYm9zZSBvciBzaWxseSBpbmZvcm1hdGlvbi4gKi9cbiAgc2lsbHkgPSBcInNpbGx5XCIsXG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE51bWVyaWMgdmFsdWVzIGFzc29jaWF0ZWQgd2l0aCBsb2cgbGV2ZWxzLlxuICogQHN1bW1hcnkgUHJvdmlkZXMgYSBudW1lcmljIHJlcHJlc2VudGF0aW9uIG9mIGxvZyBsZXZlbHMgZm9yIGNvbXBhcmlzb24gYW5kIGZpbHRlcmluZy5cbiAqIEBjb25zdCBOdW1lcmljTG9nTGV2ZWxzXG4gKiBAcHJvcGVydHkge251bWJlcn0gZXJyb3IgLSBOdW1lcmljIHZhbHVlIGZvciBlcnJvciBsZXZlbCAoMikuXG4gKiBAcHJvcGVydHkge251bWJlcn0gaW5mbyAtIE51bWVyaWMgdmFsdWUgZm9yIGluZm8gbGV2ZWwgKDQpLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IHZlcmJvc2UgLSBOdW1lcmljIHZhbHVlIGZvciB2ZXJib3NlIGxldmVsICg2KS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBkZWJ1ZyAtIE51bWVyaWMgdmFsdWUgZm9yIGRlYnVnIGxldmVsICg3KS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBzaWxseSAtIE51bWVyaWMgdmFsdWUgZm9yIHNpbGx5IGxldmVsICg5KS5cbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgY29uc3QgTnVtZXJpY0xvZ0xldmVscyA9IHtcbiAgZXJyb3I6IDIsXG4gIGluZm86IDQsXG4gIHZlcmJvc2U6IDYsXG4gIGRlYnVnOiA3LFxuICBzaWxseTogOSxcbn07XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEVudW0gZm9yIGxvZ2dpbmcgb3V0cHV0IG1vZGVzLlxuICogQHN1bW1hcnkgRGVmaW5lcyBkaWZmZXJlbnQgb3V0cHV0IGZvcm1hdHMgZm9yIGxvZyBtZXNzYWdlcy5cbiAqIEBlbnVtIHtzdHJpbmd9XG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGVudW0gTG9nZ2luZ01vZGUge1xuICAvKiogUmF3IHRleHQgZm9ybWF0IGZvciBodW1hbiByZWFkYWJpbGl0eSAqL1xuICBSQVcgPSBcInJhd1wiLFxuICAvKiogSlNPTiBmb3JtYXQgZm9yIG1hY2hpbmUgcGFyc2luZyAqL1xuICBKU09OID0gXCJqc29uXCIsXG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlZmF1bHQgdGhlbWUgZm9yIHN0eWxpbmcgbG9nIG91dHB1dC5cbiAqIEBzdW1tYXJ5IERlZmluZXMgdGhlIGRlZmF1bHQgY29sb3IgYW5kIHN0eWxlIHNldHRpbmdzIGZvciB2YXJpb3VzIGNvbXBvbmVudHMgb2YgbG9nIG1lc3NhZ2VzLlxuICogQGNvbnN0IERlZmF1bHRUaGVtZVxuICogQHR5cGVkZWYge1RoZW1lfSBEZWZhdWx0VGhlbWVcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBjbGFzcyAtIFN0eWxpbmcgZm9yIGNsYXNzIG5hbWVzLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IGNsYXNzLmZnIC0gRm9yZWdyb3VuZCBjb2xvciBjb2RlIGZvciBjbGFzcyBuYW1lcyAoMzQpLlxuICogQHByb3BlcnR5IHtPYmplY3R9IGlkIC0gU3R5bGluZyBmb3IgaWRlbnRpZmllcnMuXG4gKiBAcHJvcGVydHkge251bWJlcn0gaWQuZmcgLSBGb3JlZ3JvdW5kIGNvbG9yIGNvZGUgZm9yIGlkZW50aWZpZXJzICgzNikuXG4gKiBAcHJvcGVydHkge09iamVjdH0gc3RhY2sgLSBTdHlsaW5nIGZvciBzdGFjayB0cmFjZXMgKGVtcHR5IG9iamVjdCkuXG4gKiBAcHJvcGVydHkge09iamVjdH0gdGltZXN0YW1wIC0gU3R5bGluZyBmb3IgdGltZXN0YW1wcyAoZW1wdHkgb2JqZWN0KS5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBtZXNzYWdlIC0gU3R5bGluZyBmb3IgZGlmZmVyZW50IHR5cGVzIG9mIG1lc3NhZ2VzLlxuICogQHByb3BlcnR5IHtPYmplY3R9IG1lc3NhZ2UuZXJyb3IgLSBTdHlsaW5nIGZvciBlcnJvciBtZXNzYWdlcy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBtZXNzYWdlLmVycm9yLmZnIC0gRm9yZWdyb3VuZCBjb2xvciBjb2RlIGZvciBlcnJvciBtZXNzYWdlcyAoMzEpLlxuICogQHByb3BlcnR5IHtPYmplY3R9IG1ldGhvZCAtIFN0eWxpbmcgZm9yIG1ldGhvZCBuYW1lcyAoZW1wdHkgb2JqZWN0KS5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBsb2dMZXZlbCAtIFN0eWxpbmcgZm9yIGRpZmZlcmVudCBsb2cgbGV2ZWxzLlxuICogQHByb3BlcnR5IHtPYmplY3R9IGxvZ0xldmVsLmVycm9yIC0gU3R5bGluZyBmb3IgZXJyb3IgbGV2ZWwgbG9ncy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBsb2dMZXZlbC5lcnJvci5mZyAtIEZvcmVncm91bmQgY29sb3IgY29kZSBmb3IgZXJyb3IgbGV2ZWwgbG9ncyAoMzEpLlxuICogQHByb3BlcnR5IHtzdHJpbmdbXX0gbG9nTGV2ZWwuZXJyb3Iuc3R5bGUgLSBTdHlsZSBhdHRyaWJ1dGVzIGZvciBlcnJvciBsZXZlbCBsb2dzIChbXCJib2xkXCJdKS5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBsb2dMZXZlbC5pbmZvIC0gU3R5bGluZyBmb3IgaW5mbyBsZXZlbCBsb2dzIChlbXB0eSBvYmplY3QpLlxuICogQHByb3BlcnR5IHtPYmplY3R9IGxvZ0xldmVsLnZlcmJvc2UgLSBTdHlsaW5nIGZvciB2ZXJib3NlIGxldmVsIGxvZ3MgKGVtcHR5IG9iamVjdCkuXG4gKiBAcHJvcGVydHkge09iamVjdH0gbG9nTGV2ZWwuZGVidWcgLSBTdHlsaW5nIGZvciBkZWJ1ZyBsZXZlbCBsb2dzLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IGxvZ0xldmVsLmRlYnVnLmZnIC0gRm9yZWdyb3VuZCBjb2xvciBjb2RlIGZvciBkZWJ1ZyBsZXZlbCBsb2dzICgzMykuXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGNvbnN0IERlZmF1bHRUaGVtZTogVGhlbWUgPSB7XG4gIGFwcDoge30sXG4gIHNlcGFyYXRvcjoge30sXG4gIGNsYXNzOiB7XG4gICAgZmc6IDM0LFxuICB9LFxuICBpZDoge1xuICAgIGZnOiAzNixcbiAgfSxcbiAgc3RhY2s6IHt9LFxuICB0aW1lc3RhbXA6IHt9LFxuICBtZXNzYWdlOiB7XG4gICAgZXJyb3I6IHtcbiAgICAgIGZnOiAzMSxcbiAgICB9LFxuICB9LFxuICBtZXRob2Q6IHt9LFxuICBsb2dMZXZlbDoge1xuICAgIGVycm9yOiB7XG4gICAgICBmZzogMzEsXG4gICAgICBzdHlsZTogW1wiYm9sZFwiXSxcbiAgICB9LFxuICAgIGluZm86IHtcbiAgICAgIGZnOiAzNCxcbiAgICAgIHN0eWxlOiBbXCJib2xkXCJdLFxuICAgIH0sXG4gICAgdmVyYm9zZToge1xuICAgICAgZmc6IDM0LFxuICAgICAgc3R5bGU6IFtcImJvbGRcIl0sXG4gICAgfSxcbiAgICBkZWJ1Zzoge1xuICAgICAgZmc6IDMzLFxuICAgICAgc3R5bGU6IFtcImJvbGRcIl0sXG4gICAgfSxcbiAgfSxcbn07XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlZmF1bHQgY29uZmlndXJhdGlvbiBmb3IgbG9nZ2luZy5cbiAqIEBzdW1tYXJ5IERlZmluZXMgdGhlIGRlZmF1bHQgc2V0dGluZ3MgZm9yIHRoZSBsb2dnaW5nIHN5c3RlbSwgaW5jbHVkaW5nIHZlcmJvc2l0eSwgbG9nIGxldmVsLCBzdHlsaW5nLCBhbmQgdGltZXN0YW1wIGZvcm1hdC5cbiAqIEBjb25zdCBEZWZhdWx0TG9nZ2luZ0NvbmZpZ1xuICogQHR5cGVkZWYge0xvZ2dpbmdDb25maWd9IERlZmF1bHRMb2dnaW5nQ29uZmlnXG4gKiBAcHJvcGVydHkge251bWJlcn0gdmVyYm9zZSAtIFZlcmJvc2l0eSBsZXZlbCAoMCkuXG4gKiBAcHJvcGVydHkge0xvZ0xldmVsfSBsZXZlbCAtIERlZmF1bHQgbG9nIGxldmVsIChMb2dMZXZlbC5pbmZvKS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gbG9nTGV2ZWwgLSBXaGV0aGVyIHRvIGRpc3BsYXkgbG9nIGxldmVsIGluIG91dHB1dCAodHJ1ZSkuXG4gKiBAcHJvcGVydHkge0xvZ2dpbmdNb2RlfSBtb2RlIC0gT3V0cHV0IGZvcm1hdCBtb2RlIChMb2dnaW5nTW9kZS5SQVcpLlxuICogQHByb3BlcnR5IHtib29sZWFufSBzdHlsZSAtIFdoZXRoZXIgdG8gYXBwbHkgc3R5bGluZyB0byBsb2cgb3V0cHV0IChmYWxzZSkuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gc2VwYXJhdG9yIC0gU2VwYXJhdG9yIGJldHdlZW4gbG9nIGNvbXBvbmVudHMgKFwiIC0gXCIpLlxuICogQHByb3BlcnR5IHtib29sZWFufSB0aW1lc3RhbXAgLSBXaGV0aGVyIHRvIGluY2x1ZGUgdGltZXN0YW1wcyBpbiBsb2cgbWVzc2FnZXMgKHRydWUpLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHRpbWVzdGFtcEZvcm1hdCAtIEZvcm1hdCBmb3IgdGltZXN0YW1wcyAoXCJISDptbTpzcy5TU1NcIikuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IGNvbnRleHQgLSBXaGV0aGVyIHRvIGluY2x1ZGUgY29udGV4dCBpbmZvcm1hdGlvbiBpbiBsb2cgbWVzc2FnZXMgKHRydWUpLlxuICogQHByb3BlcnR5IHtUaGVtZX0gdGhlbWUgLSBUaGUgdGhlbWUgdG8gdXNlIGZvciBzdHlsaW5nIGxvZyBtZXNzYWdlcyAoRGVmYXVsdFRoZW1lKS5cbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgY29uc3QgRGVmYXVsdExvZ2dpbmdDb25maWc6IExvZ2dpbmdDb25maWcgPSB7XG4gIGVudjogXCJkZXZlbG9wbWVudFwiLFxuICB2ZXJib3NlOiAwLFxuICBsZXZlbDogTG9nTGV2ZWwuaW5mbyxcbiAgbG9nTGV2ZWw6IHRydWUsXG4gIHN0eWxlOiBmYWxzZSxcbiAgY29udGV4dFNlcGFyYXRvcjogXCIuXCIsXG4gIHNlcGFyYXRvcjogXCItXCIsXG4gIHRpbWVzdGFtcDogdHJ1ZSxcbiAgdGltZXN0YW1wRm9ybWF0OiBcIkhIOm1tOnNzLlNTU1wiLFxuICBjb250ZXh0OiB0cnVlLFxuICBmb3JtYXQ6IExvZ2dpbmdNb2RlLlJBVyxcbiAgcGF0dGVybjpcbiAgICBcIntsZXZlbH0gW3t0aW1lc3RhbXB9XSB7YXBwfSB7Y29udGV4dH0ge3NlcGFyYXRvcn0ge21lc3NhZ2V9IHtzdGFja31cIixcbiAgdGhlbWU6IERlZmF1bHRUaGVtZSxcbn07XG4iLCJpbXBvcnQgeyBEZWZhdWx0UGxhY2Vob2xkZXJXcmFwcGVycyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBQYWRzIHRoZSBlbmQgb2YgYSBzdHJpbmcgd2l0aCBhIHNwZWNpZmllZCBjaGFyYWN0ZXIuXG4gKiBAc3VtbWFyeSBFeHRlbmRzIHRoZSBpbnB1dCBzdHJpbmcgdG8gYSBzcGVjaWZpZWQgbGVuZ3RoIGJ5IGFkZGluZyBhIHBhZGRpbmcgY2hhcmFjdGVyIHRvIHRoZSBlbmQuXG4gKiBJZiB0aGUgaW5wdXQgc3RyaW5nIGlzIGFscmVhZHkgbG9uZ2VyIHRoYW4gdGhlIHNwZWNpZmllZCBsZW5ndGgsIGl0IGlzIHJldHVybmVkIHVuY2hhbmdlZC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyIC0gVGhlIGlucHV0IHN0cmluZyB0byBiZSBwYWRkZWQuXG4gKiBAcGFyYW0ge251bWJlcn0gbGVuZ3RoIC0gVGhlIGRlc2lyZWQgdG90YWwgbGVuZ3RoIG9mIHRoZSByZXN1bHRpbmcgc3RyaW5nLlxuICogQHBhcmFtIHtzdHJpbmd9IFtjaGFyPVwiIFwiXSAtIFRoZSBjaGFyYWN0ZXIgdG8gdXNlIGZvciBwYWRkaW5nLiBEZWZhdWx0cyB0byBhIHNwYWNlLlxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgcGFkZGVkIHN0cmluZy5cbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGFkZGluZyBjaGFyYWN0ZXIgaXMgbm90IGV4YWN0bHkgb25lIGNoYXJhY3RlciBsb25nLlxuICpcbiAqIEBmdW5jdGlvbiBwYWRFbmRcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhZEVuZChcbiAgc3RyOiBzdHJpbmcsXG4gIGxlbmd0aDogbnVtYmVyLFxuICBjaGFyOiBzdHJpbmcgPSBcIiBcIlxuKTogc3RyaW5nIHtcbiAgaWYgKGNoYXIubGVuZ3RoICE9PSAxKVxuICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgY2hhcmFjdGVyIGxlbmd0aCBmb3IgcGFkZGluZy4gbXVzdCBiZSBvbmUhXCIpO1xuICByZXR1cm4gc3RyLnBhZEVuZChsZW5ndGgsIGNoYXIpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBSZXBsYWNlcyBwbGFjZWhvbGRlcnMgaW4gYSBzdHJpbmcgd2l0aCBwcm92aWRlZCB2YWx1ZXMuXG4gKiBAc3VtbWFyeSBJbnRlcnBvbGF0ZXMgYSBzdHJpbmcgYnkgcmVwbGFjaW5nIHBsYWNlaG9sZGVycyBvZiB0aGUgZm9ybSAke3ZhcmlhYmxlTmFtZX1cbiAqIHdpdGggY29ycmVzcG9uZGluZyB2YWx1ZXMgZnJvbSB0aGUgcHJvdmlkZWQgb2JqZWN0LiBJZiBhIHBsYWNlaG9sZGVyIGRvZXNuJ3QgaGF2ZVxuICogYSBjb3JyZXNwb25kaW5nIHZhbHVlLCBpdCBpcyBsZWZ0IHVuY2hhbmdlZCBpbiB0aGUgc3RyaW5nLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBpbnB1dCAtIFRoZSBpbnB1dCBzdHJpbmcgY29udGFpbmluZyBwbGFjZWhvbGRlcnMgdG8gYmUgcmVwbGFjZWQuXG4gKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIG51bWJlciB8IHN0cmluZz59IHZhbHVlcyAtIEFuIG9iamVjdCBjb250YWluaW5nIGtleS12YWx1ZSBwYWlycyBmb3IgcmVwbGFjZW1lbnQuXG4gKiBAcGFyYW0gcHJlZml4XG4gKiBAcGFyYW0gc3VmZml4XG4gKiBAcGFyYW0gZmxhZ3NcbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGludGVycG9sYXRlZCBzdHJpbmcgd2l0aCBwbGFjZWhvbGRlcnMgcmVwbGFjZWQgYnkgdGhlaXIgY29ycmVzcG9uZGluZyB2YWx1ZXMuXG4gKlxuICogQGZ1bmN0aW9uIHBhdGNoUGxhY2Vob2xkZXJzXG4gKlxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDYWxsZXJcbiAqICAgcGFydGljaXBhbnQgcGF0Y2hTdHJpbmdcbiAqICAgcGFydGljaXBhbnQgU3RyaW5nLnJlcGxhY2VcbiAqICAgQ2FsbGVyLT4+cGF0Y2hTdHJpbmc6IENhbGwgd2l0aCBpbnB1dCBhbmQgdmFsdWVzXG4gKiAgIHBhdGNoU3RyaW5nLT4+U3RyaW5nLnJlcGxhY2U6IENhbGwgd2l0aCByZWdleCBhbmQgcmVwbGFjZW1lbnQgZnVuY3Rpb25cbiAqICAgU3RyaW5nLnJlcGxhY2UtPj5wYXRjaFN0cmluZzogUmV0dXJuIHJlcGxhY2VkIHN0cmluZ1xuICogICBwYXRjaFN0cmluZy0tPj5DYWxsZXI6IFJldHVybiBwYXRjaGVkIHN0cmluZ1xuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gcGF0Y2hQbGFjZWhvbGRlcnMoXG4gIGlucHV0OiBzdHJpbmcsXG4gIHZhbHVlczogUmVjb3JkPHN0cmluZywgbnVtYmVyIHwgc3RyaW5nPixcbiAgcHJlZml4OiBzdHJpbmcgPSBEZWZhdWx0UGxhY2Vob2xkZXJXcmFwcGVyc1swXSxcbiAgc3VmZml4OiBzdHJpbmcgPSBEZWZhdWx0UGxhY2Vob2xkZXJXcmFwcGVyc1sxXSxcbiAgZmxhZ3M6IHN0cmluZyA9IFwiZ1wiXG4pOiBzdHJpbmcge1xuICBjb25zdCBwbGFjZWhvbGRlcnMgPSBPYmplY3QuZW50cmllcyh2YWx1ZXMpLnJlZHVjZShcbiAgICAoYWNjOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LCBba2V5LCB2YWxdKSA9PiB7XG4gICAgICBhY2NbYCR7cHJlZml4fSR7a2V5fSR7c3VmZml4fWBdID0gdmFsO1xuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LFxuICAgIHt9XG4gICk7XG4gIHJldHVybiBwYXRjaFN0cmluZyhpbnB1dCwgcGxhY2Vob2xkZXJzLCBmbGFncyk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFJlcGxhY2VzIG9jY3VycmVuY2VzIG9mIGtleXMgd2l0aCB0aGVpciBjb3JyZXNwb25kaW5nIHZhbHVlcyBpbiBhIHN0cmluZy5cbiAqIEBzdW1tYXJ5IEl0ZXJhdGVzIHRocm91Z2ggYSBzZXQgb2Yga2V5LXZhbHVlIHBhaXJzIGFuZCByZXBsYWNlcyBhbGwgb2NjdXJyZW5jZXMgb2YgZWFjaCBrZXlcbiAqIGluIHRoZSBpbnB1dCBzdHJpbmcgd2l0aCBpdHMgY29ycmVzcG9uZGluZyB2YWx1ZS4gU3VwcG9ydHMgcmVndWxhciBleHByZXNzaW9uIGZsYWdzIGZvciBjdXN0b21pemVkIHJlcGxhY2VtZW50LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBpbnB1dCAtIFRoZSBpbnB1dCBzdHJpbmcgaW4gd2hpY2ggcmVwbGFjZW1lbnRzIHdpbGwgYmUgbWFkZS5cbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgbnVtYmVyIHwgc3RyaW5nPn0gdmFsdWVzIC0gQW4gb2JqZWN0IGNvbnRhaW5pbmcga2V5LXZhbHVlIHBhaXJzIGZvciByZXBsYWNlbWVudC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbZmxhZ3M9XCJnXCJdIC0gUmVndWxhciBleHByZXNzaW9uIGZsYWdzIHRvIGNvbnRyb2wgdGhlIHJlcGxhY2VtZW50IGJlaGF2aW9yLlxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgc3RyaW5nIHdpdGggYWxsIHNwZWNpZmllZCByZXBsYWNlbWVudHMgYXBwbGllZC5cbiAqXG4gKiBAZnVuY3Rpb24gcGF0Y2hTdHJpbmdcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhdGNoU3RyaW5nKFxuICBpbnB1dDogc3RyaW5nLFxuICB2YWx1ZXM6IFJlY29yZDxzdHJpbmcsIG51bWJlciB8IHN0cmluZz4sXG4gIGZsYWdzOiBzdHJpbmcgPSBcImdcIlxuKTogc3RyaW5nIHtcbiAgT2JqZWN0LmVudHJpZXModmFsdWVzKS5mb3JFYWNoKChba2V5LCB2YWxdKSA9PiB7XG4gICAgY29uc3QgcmVnZXhwID0gbmV3IFJlZ0V4cChlc2NhcGVSZWdFeHAoa2V5KSwgZmxhZ3MpO1xuICAgIGlucHV0ID0gaW5wdXQucmVwbGFjZShyZWdleHAsIHZhbCBhcyBzdHJpbmcpO1xuICB9KTtcbiAgcmV0dXJuIGlucHV0O1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDb252ZXJ0cyBhIHN0cmluZyB0byBjYW1lbENhc2UuXG4gKiBAc3VtbWFyeSBUcmFuc2Zvcm1zIHRoZSBpbnB1dCBzdHJpbmcgaW50byBjYW1lbENhc2UgZm9ybWF0LCB3aGVyZSB3b3JkcyBhcmUgam9pbmVkIHdpdGhvdXQgc3BhY2VzXG4gKiBhbmQgZWFjaCB3b3JkIGFmdGVyIHRoZSBmaXJzdCBzdGFydHMgd2l0aCBhIGNhcGl0YWwgbGV0dGVyLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gVGhlIGlucHV0IHN0cmluZyB0byBiZSBjb252ZXJ0ZWQuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBpbnB1dCBzdHJpbmcgY29udmVydGVkIHRvIGNhbWVsQ2FzZS5cbiAqXG4gKiBAZnVuY3Rpb24gdG9DYW1lbENhc2VcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvQ2FtZWxDYXNlKHRleHQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiB0ZXh0XG4gICAgLnJlcGxhY2UoLyg/Ol5cXHd8W0EtWl18XFxiXFx3KS9nLCAod29yZCwgaW5kZXgpID0+XG4gICAgICBpbmRleCA9PT0gMCA/IHdvcmQudG9Mb3dlckNhc2UoKSA6IHdvcmQudG9VcHBlckNhc2UoKVxuICAgIClcbiAgICAucmVwbGFjZSgvXFxzKy9nLCBcIlwiKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ29udmVydHMgYSBzdHJpbmcgdG8gRU5WSVJPTk1FTlRfVkFSSUFCTEUgZm9ybWF0LlxuICogQHN1bW1hcnkgVHJhbnNmb3JtcyB0aGUgaW5wdXQgc3RyaW5nIGludG8gdXBwZXJjYXNlIHdpdGggd29yZHMgc2VwYXJhdGVkIGJ5IHVuZGVyc2NvcmVzLFxuICogdHlwaWNhbGx5IHVzZWQgZm9yIGVudmlyb25tZW50IHZhcmlhYmxlIG5hbWVzLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gVGhlIGlucHV0IHN0cmluZyB0byBiZSBjb252ZXJ0ZWQuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBpbnB1dCBzdHJpbmcgY29udmVydGVkIHRvIEVOVklST05NRU5UX1ZBUklBQkxFIGZvcm1hdC5cbiAqXG4gKiBAZnVuY3Rpb24gdG9FTlZGb3JtYXRcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvRU5WRm9ybWF0KHRleHQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiB0b1NuYWtlQ2FzZSh0ZXh0KS50b1VwcGVyQ2FzZSgpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDb252ZXJ0cyBhIHN0cmluZyB0byBzbmFrZV9jYXNlLlxuICogQHN1bW1hcnkgVHJhbnNmb3JtcyB0aGUgaW5wdXQgc3RyaW5nIGludG8gbG93ZXJjYXNlIHdpdGggd29yZHMgc2VwYXJhdGVkIGJ5IHVuZGVyc2NvcmVzLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gVGhlIGlucHV0IHN0cmluZyB0byBiZSBjb252ZXJ0ZWQuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBpbnB1dCBzdHJpbmcgY29udmVydGVkIHRvIHNuYWtlX2Nhc2UuXG4gKlxuICogQGZ1bmN0aW9uIHRvU25ha2VDYXNlXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b1NuYWtlQ2FzZSh0ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gdGV4dFxuICAgIC5yZXBsYWNlKC8oW2Etel0pKFtBLVpdKS9nLCBcIiQxXyQyXCIpXG4gICAgLnJlcGxhY2UoL1tcXHMtXSsvZywgXCJfXCIpXG4gICAgLnRvTG93ZXJDYXNlKCk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENvbnZlcnRzIGEgc3RyaW5nIHRvIGtlYmFiLWNhc2UuXG4gKiBAc3VtbWFyeSBUcmFuc2Zvcm1zIHRoZSBpbnB1dCBzdHJpbmcgaW50byBsb3dlcmNhc2Ugd2l0aCB3b3JkcyBzZXBhcmF0ZWQgYnkgaHlwaGVucy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIFRoZSBpbnB1dCBzdHJpbmcgdG8gYmUgY29udmVydGVkLlxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgaW5wdXQgc3RyaW5nIGNvbnZlcnRlZCB0byBrZWJhYi1jYXNlLlxuICpcbiAqIEBmdW5jdGlvbiB0b0tlYmFiQ2FzZVxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gdG9LZWJhYkNhc2UodGV4dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHRleHRcbiAgICAucmVwbGFjZSgvKFthLXpdKShbQS1aXSkvZywgXCIkMS0kMlwiKVxuICAgIC5yZXBsYWNlKC9bXFxzX10rL2csIFwiLVwiKVxuICAgIC50b0xvd2VyQ2FzZSgpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDb252ZXJ0cyBhIHN0cmluZyB0byBQYXNjYWxDYXNlLlxuICogQHN1bW1hcnkgVHJhbnNmb3JtcyB0aGUgaW5wdXQgc3RyaW5nIGludG8gUGFzY2FsQ2FzZSBmb3JtYXQsIHdoZXJlIHdvcmRzIGFyZSBqb2luZWQgd2l0aG91dCBzcGFjZXNcbiAqIGFuZCBlYWNoIHdvcmQgc3RhcnRzIHdpdGggYSBjYXBpdGFsIGxldHRlci5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIFRoZSBpbnB1dCBzdHJpbmcgdG8gYmUgY29udmVydGVkLlxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgaW5wdXQgc3RyaW5nIGNvbnZlcnRlZCB0byBQYXNjYWxDYXNlLlxuICpcbiAqIEBmdW5jdGlvbiB0b1Bhc2NhbENhc2VcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvUGFzY2FsQ2FzZSh0ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gdGV4dFxuICAgIC5yZXBsYWNlKC8oPzpeXFx3fFtBLVpdfFxcYlxcdykvZywgKHdvcmQpID0+IHdvcmQudG9VcHBlckNhc2UoKSlcbiAgICAucmVwbGFjZSgvXFxzKy9nLCBcIlwiKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRXNjYXBlcyBzcGVjaWFsIGNoYXJhY3RlcnMgaW4gYSBzdHJpbmcgZm9yIHVzZSBpbiBhIHJlZ3VsYXIgZXhwcmVzc2lvbi5cbiAqIEBzdW1tYXJ5IEFkZHMgYmFja3NsYXNoZXMgYmVmb3JlIGNoYXJhY3RlcnMgdGhhdCBoYXZlIHNwZWNpYWwgbWVhbmluZyBpbiByZWd1bGFyIGV4cHJlc3Npb25zLFxuICogYWxsb3dpbmcgdGhlIHN0cmluZyB0byBiZSB1c2VkIGFzIGEgbGl0ZXJhbCBtYXRjaCBpbiBhIFJlZ0V4cC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIC0gVGhlIHN0cmluZyB0byBlc2NhcGUgZm9yIHJlZ3VsYXIgZXhwcmVzc2lvbiB1c2UuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBlc2NhcGVkIHN0cmluZyBzYWZlIGZvciB1c2UgaW4gcmVndWxhciBleHByZXNzaW9ucy5cbiAqXG4gKiBAZnVuY3Rpb24gZXNjYXBlUmVnRXhwXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlc2NhcGVSZWdFeHAoc3RyaW5nOiBzdHJpbmcpIHtcbiAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKC9bLiorP14ke30oKXxbXFxdXFxcXF0vZywgXCJcXFxcJCZcIik7IC8vICQmIG1lYW5zIHRoZSB3aG9sZSBtYXRjaGVkIHN0cmluZ1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IFV0aWwgZnVuY3Rpb24gdG8gcHJvdmlkZSBzdHJpbmcgZm9ybWF0IGZ1bmN0aW9uYWxpdHkgc2ltaWxhciB0byBDIydzIHN0cmluZy5mb3JtYXRcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nXG4gKiBAcGFyYW0ge0FycmF5PHN0cmluZyB8IG51bWJlcj4gfCBSZWNvcmQ8c3RyaW5nLCBhbnk+fSBbYXJnc10gcmVwbGFjZW1lbnRzIG1hZGUgYnkgb3JkZXIgb2YgYXBwZWFyYW5jZSAocmVwbGFjZW1lbnQwIHdpbCByZXBsYWNlIHswfSBhbmQgc28gb24pXG4gKiBAcmV0dXJuIHtzdHJpbmd9IGZvcm1hdHRlZCBzdHJpbmdcbiAqXG4gKiBAZnVuY3Rpb24gc2ZcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gc2YoXG4gIHN0cmluZzogc3RyaW5nLFxuICAuLi5hcmdzOiAoc3RyaW5nIHwgbnVtYmVyIHwgUmVjb3JkPHN0cmluZywgYW55PilbXVxuKSB7XG4gIGlmIChhcmdzLmxlbmd0aCA+IDEpIHtcbiAgICBpZiAoXG4gICAgICAhYXJncy5ldmVyeSgoYXJnKSA9PiB0eXBlb2YgYXJnID09PSBcInN0cmluZ1wiIHx8IHR5cGVvZiBhcmcgPT09IFwibnVtYmVyXCIpXG4gICAgKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgT25seSBzdHJpbmcgYW5kIG51bWJlciBhcmd1bWVudHMgYXJlIHN1cHBvcnRlZCBmb3IgbXVsdGlwbGUgcmVwbGFjZW1lbnRzLmBcbiAgICAgICk7XG4gIH1cblxuICBpZiAoYXJncy5sZW5ndGggPT09IDEgJiYgdHlwZW9mIGFyZ3NbMF0gPT09IFwib2JqZWN0XCIpIHtcbiAgICBjb25zdCBvYmogPSBhcmdzWzBdIGFzIFJlY29yZDxzdHJpbmcsIGFueT47XG4gICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKG9iaikucmVkdWNlKChhY2MsIFtrZXksIHZhbF0pID0+IHtcbiAgICAgIHJldHVybiBhY2MucmVwbGFjZShuZXcgUmVnRXhwKGBcXFxceyR7a2V5fVxcXFx9YCwgXCJnXCIpLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB2YWw7XG4gICAgICB9KTtcbiAgICB9LCBzdHJpbmcpO1xuICB9XG5cbiAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKC97KFxcZCspfS9nLCBmdW5jdGlvbiAobWF0Y2gsIG51bWJlcikge1xuICAgIHJldHVybiB0eXBlb2YgYXJnc1tudW1iZXJdICE9PSBcInVuZGVmaW5lZFwiXG4gICAgICA/IGFyZ3NbbnVtYmVyXS50b1N0cmluZygpXG4gICAgICA6IFwidW5kZWZpbmVkXCI7XG4gIH0pO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IFV0aWwgZnVuY3Rpb24gdG8gcHJvdmlkZSBzdHJpbmcgZm9ybWF0IGZ1bmN0aW9uYWxpdHkgc2ltaWxhciB0byBDIydzIHN0cmluZy5mb3JtYXRcbiAqXG4gKiBAc2VlIHNmXG4gKlxuICogQGRlcHJlY2F0ZWRcbiAqIEBmdW5jdGlvbiBzdHJpbmdGb3JtYXRcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgY29uc3Qgc3RyaW5nRm9ybWF0ID0gc2Y7XG4iLCIvKipcbiAqIEBkZXNjcmlwdGlvbiBEZXRlcm1pbmVzIGlmIHRoZSBjdXJyZW50IGVudmlyb25tZW50IGlzIGEgYnJvd3NlciBieSBjaGVja2luZyB0aGUgcHJvdG90eXBlIGNoYWluIG9mIHRoZSBnbG9iYWwgb2JqZWN0LlxuICogQHN1bW1hcnkgQ2hlY2tzIGlmIHRoZSBjb2RlIGlzIHJ1bm5pbmcgaW4gYSBicm93c2VyIGVudmlyb25tZW50LlxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgZW52aXJvbm1lbnQgaXMgYSBicm93c2VyLCBmYWxzZSBvdGhlcndpc2UuXG4gKiBAZnVuY3Rpb24gaXNCcm93c2VyXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQnJvd3NlcigpOiBib29sZWFuIHtcbiAgcmV0dXJuIChcbiAgICBPYmplY3QuZ2V0UHJvdG90eXBlT2YoT2JqZWN0LmdldFByb3RvdHlwZU9mKGdsb2JhbFRoaXMpKSAhPT1cbiAgICBPYmplY3QucHJvdG90eXBlXG4gICk7XG59XG4iLCJpbXBvcnQgeyBPYmplY3RBY2N1bXVsYXRvciB9IGZyb20gXCJ0eXBlZC1vYmplY3QtYWNjdW11bGF0b3JcIjtcbmltcG9ydCB7IHRvRU5WRm9ybWF0IH0gZnJvbSBcIi4vdGV4dFwiO1xuaW1wb3J0IHsgaXNCcm93c2VyIH0gZnJvbSBcIi4vd2ViXCI7XG5pbXBvcnQge1xuICBCcm93c2VyRW52S2V5LFxuICBEZWZhdWx0TG9nZ2luZ0NvbmZpZyxcbiAgRU5WX1BBVEhfREVMSU1JVEVSLFxufSBmcm9tIFwiLi9jb25zdGFudHNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRmFjdG9yeSB0eXBlIGZvciBjcmVhdGluZyBFbnZpcm9ubWVudCBpbnN0YW5jZXMuXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgZnVuY3Rpb24gdHlwZSB0aGF0IGNyZWF0ZXMgYW5kIHJldHVybnMgRW52aXJvbm1lbnQgaW5zdGFuY2VzLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIC0gVGhlIHR5cGUgb2Ygb2JqZWN0IHRoZSBFbnZpcm9ubWVudCB3aWxsIGFjY3VtdWxhdGUuXG4gKiBAdGVtcGxhdGUgRSAtIFRoZSBzcGVjaWZpYyBFbnZpcm9ubWVudCB0eXBlIHRvIGJlIGNyZWF0ZWQsIGV4dGVuZGluZyBFbnZpcm9ubWVudDxUPi5cbiAqIEB0eXBlZGVmIHtmdW5jdGlvbiguLi51bmtub3duW10pOiBFfSBFbnZpcm9ubWVudEZhY3RvcnlcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgdHlwZSBFbnZpcm9ubWVudEZhY3Rvcnk8VCBleHRlbmRzIG9iamVjdCwgRSBleHRlbmRzIEVudmlyb25tZW50PFQ+PiA9IChcbiAgLi4uYXJnczogdW5rbm93bltdXG4pID0+IEU7XG5cbi8qKlxuICogQGNsYXNzIEVudmlyb25tZW50XG4gKiBAZXh0ZW5kcyB7T2JqZWN0QWNjdW11bGF0b3I8VD59XG4gKiBAdGVtcGxhdGUgVFxuICogQGRlc2NyaXB0aW9uIEEgY2xhc3MgcmVwcmVzZW50aW5nIGFuIGVudmlyb25tZW50IHdpdGggYWNjdW11bGF0aW9uIGNhcGFiaWxpdGllcy5cbiAqIEBzdW1tYXJ5IE1hbmFnZXMgZW52aXJvbm1lbnQtcmVsYXRlZCBkYXRhIGFuZCBwcm92aWRlcyBtZXRob2RzIGZvciBhY2N1bXVsYXRpb24gYW5kIGtleSByZXRyaWV2YWwuXG4gKiBAcGFyYW0ge1R9IFtpbml0aWFsRGF0YV0gLSBUaGUgaW5pdGlhbCBkYXRhIHRvIHBvcHVsYXRlIHRoZSBlbnZpcm9ubWVudCB3aXRoLlxuICovXG5leHBvcnQgY2xhc3MgRW52aXJvbm1lbnQ8VCBleHRlbmRzIG9iamVjdD4gZXh0ZW5kcyBPYmplY3RBY2N1bXVsYXRvcjxUPiB7XG4gIC8qKlxuICAgKiBAc3RhdGljXG4gICAqIEBwcm90ZWN0ZWRcbiAgICogQGRlc2NyaXB0aW9uIEEgZmFjdG9yeSBmdW5jdGlvbiBmb3IgY3JlYXRpbmcgRW52aXJvbm1lbnQgaW5zdGFuY2VzLlxuICAgKiBAc3VtbWFyeSBEZWZpbmVzIGhvdyBuZXcgaW5zdGFuY2VzIG9mIHRoZSBFbnZpcm9ubWVudCBjbGFzcyBzaG91bGQgYmUgY3JlYXRlZC5cbiAgICogQHJldHVybiB7RW52aXJvbm1lbnQ8YW55Pn0gQSBuZXcgaW5zdGFuY2Ugb2YgdGhlIEVudmlyb25tZW50IGNsYXNzLlxuICAgKi9cbiAgcHJvdGVjdGVkIHN0YXRpYyBmYWN0b3J5OiBFbnZpcm9ubWVudEZhY3Rvcnk8YW55LCBhbnk+ID1cbiAgICAoKTogRW52aXJvbm1lbnQ8YW55PiA9PiBuZXcgRW52aXJvbm1lbnQoKTtcblxuICAvKipcbiAgICogQHN0YXRpY1xuICAgKiBAcHJpdmF0ZVxuICAgKiBAZGVzY3JpcHRpb24gVGhlIHNpbmdsZXRvbiBpbnN0YW5jZSBvZiB0aGUgRW52aXJvbm1lbnQgY2xhc3MuXG4gICAqIEB0eXBlIHtFbnZpcm9ubWVudDxhbnk+fVxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgX2luc3RhbmNlOiBFbnZpcm9ubWVudDxhbnk+O1xuXG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgYSB2YWx1ZSBmcm9tIHRoZSBlbnZpcm9ubWVudFxuICAgKiBAc3VtbWFyeSBHZXRzIGEgdmFsdWUgZnJvbSB0aGUgZW52aXJvbm1lbnQgdmFyaWFibGVzLCBoYW5kbGluZyBicm93c2VyIGFuZCBOb2RlLmpzIGVudmlyb25tZW50cyBkaWZmZXJlbnRseVxuICAgKiBAcGFyYW0ge3N0cmluZ30gayAtIFRoZSBrZXkgdG8gcmV0cmlldmUgZnJvbSB0aGUgZW52aXJvbm1lbnRcbiAgICogQHJldHVybiB7dW5rbm93bn0gVGhlIHZhbHVlIGZyb20gdGhlIGVudmlyb25tZW50LCBvciB1bmRlZmluZWQgaWYgbm90IGZvdW5kXG4gICAqL1xuICBwcm90ZWN0ZWQgZnJvbUVudihrOiBzdHJpbmcpIHtcbiAgICBsZXQgZW52OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICBpZiAoaXNCcm93c2VyKCkpIHtcbiAgICAgIGVudiA9XG4gICAgICAgIChcbiAgICAgICAgICBnbG9iYWxUaGlzIGFzIHR5cGVvZiBnbG9iYWxUaGlzICYge1xuICAgICAgICAgICAgW0Jyb3dzZXJFbnZLZXldOiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuICAgICAgICAgIH1cbiAgICAgICAgKVtCcm93c2VyRW52S2V5XSB8fCB7fTtcbiAgICB9IGVsc2Uge1xuICAgICAgZW52ID0gZ2xvYmFsVGhpcy5wcm9jZXNzLmVudjtcbiAgICAgIGsgPSB0b0VOVkZvcm1hdChrKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMucGFyc2VFbnZWYWx1ZShlbnZba10pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHBhcnNlRW52VmFsdWUodmFsOiB1bmtub3duKSB7XG4gICAgaWYgKHR5cGVvZiB2YWwgIT09IFwic3RyaW5nXCIpIHJldHVybiB2YWw7XG4gICAgaWYgKHZhbCA9PT0gXCJ0cnVlXCIpIHJldHVybiB0cnVlO1xuICAgIGlmICh2YWwgPT09IFwiZmFsc2VcIikgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IHJlc3VsdCA9IHBhcnNlRmxvYXQodmFsKTtcbiAgICBpZiAoIWlzTmFOKHJlc3VsdCkpIHJldHVybiByZXN1bHQ7XG4gICAgcmV0dXJuIHZhbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRXhwYW5kcyBhbiBvYmplY3QgaW50byB0aGUgZW52aXJvbm1lbnRcbiAgICogQHN1bW1hcnkgRGVmaW5lcyBwcm9wZXJ0aWVzIG9uIHRoZSBlbnZpcm9ubWVudCBvYmplY3QgdGhhdCBjYW4gYmUgYWNjZXNzZWQgYXMgZ2V0dGVycyBhbmQgc2V0dGVyc1xuICAgKiBAdGVtcGxhdGUgViAtIFR5cGUgb2YgdGhlIG9iamVjdCBiZWluZyBleHBhbmRlZFxuICAgKiBAcGFyYW0ge1Z9IHZhbHVlIC0gVGhlIG9iamVjdCB0byBleHBhbmQgaW50byB0aGUgZW52aXJvbm1lbnRcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIHByb3RlY3RlZCBvdmVycmlkZSBleHBhbmQ8ViBleHRlbmRzIG9iamVjdD4odmFsdWU6IFYpOiB2b2lkIHtcbiAgICBPYmplY3QuZW50cmllcyh2YWx1ZSkuZm9yRWFjaCgoW2ssIHZdKSA9PiB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgaywge1xuICAgICAgICBnZXQ6ICgpID0+IHtcbiAgICAgICAgICBjb25zdCBmcm9tRW52ID0gdGhpcy5mcm9tRW52KGspO1xuICAgICAgICAgIGlmICh0eXBlb2YgZnJvbUVudiAhPT0gXCJ1bmRlZmluZWRcIikgcmV0dXJuIGZyb21FbnY7XG4gICAgICAgICAgaWYgKHYgJiYgdHlwZW9mIHYgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgIHJldHVybiBFbnZpcm9ubWVudC5idWlsZEVudlByb3h5KHYgYXMgYW55LCBba10pO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBJZiB0aGUgbW9kZWwgcHJvdmlkZXMgYW4gZW1wdHkgc3RyaW5nLCBleHBvc2UgYSBwcm94eSB0aGF0IGNvbXBvc2VzIEVOViBrZXlzXG4gICAgICAgICAgaWYgKHYgPT09IFwiXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBFbnZpcm9ubWVudC5idWlsZEVudlByb3h5KHVuZGVmaW5lZCwgW2tdKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHY7XG4gICAgICAgIH0sXG4gICAgICAgIHNldDogKHZhbDogVltrZXlvZiBWXSkgPT4ge1xuICAgICAgICAgIHYgPSB2YWw7XG4gICAgICAgIH0sXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm90ZWN0ZWRcbiAgICogQHN0YXRpY1xuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIG9yIGNyZWF0ZXMgdGhlIHNpbmdsZXRvbiBpbnN0YW5jZSBvZiB0aGUgRW52aXJvbm1lbnQgY2xhc3MuXG4gICAqIEBzdW1tYXJ5IEVuc3VyZXMgb25seSBvbmUgaW5zdGFuY2Ugb2YgdGhlIEVudmlyb25tZW50IGNsYXNzIGV4aXN0cy5cbiAgICogQHRlbXBsYXRlIEVcbiAgICogQHBhcmFtIHsuLi51bmtub3duW119IGFyZ3MgLSBBcmd1bWVudHMgdG8gcGFzcyB0byB0aGUgZmFjdG9yeSBmdW5jdGlvbiBpZiBhIG5ldyBpbnN0YW5jZSBpcyBjcmVhdGVkLlxuICAgKiBAcmV0dXJuIHtFfSBUaGUgc2luZ2xldG9uIGluc3RhbmNlIG9mIHRoZSBFbnZpcm9ubWVudCBjbGFzcy5cbiAgICovXG4gIHByb3RlY3RlZCBzdGF0aWMgaW5zdGFuY2U8RSBleHRlbmRzIEVudmlyb25tZW50PGFueT4+KC4uLmFyZ3M6IHVua25vd25bXSk6IEUge1xuICAgIGlmICghRW52aXJvbm1lbnQuX2luc3RhbmNlKSB7XG4gICAgICBjb25zdCBiYXNlID0gRW52aXJvbm1lbnQuZmFjdG9yeSguLi5hcmdzKSBhcyBFO1xuICAgICAgY29uc3QgcHJveGllZCA9IG5ldyBQcm94eShiYXNlIGFzIGFueSwge1xuICAgICAgICBnZXQodGFyZ2V0LCBwcm9wLCByZWNlaXZlcikge1xuICAgICAgICAgIGNvbnN0IHZhbHVlID0gUmVmbGVjdC5nZXQodGFyZ2V0LCBwcm9wLCByZWNlaXZlcik7XG4gICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJ1bmRlZmluZWRcIikgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgIGlmICh0eXBlb2YgcHJvcCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgLy8gQXZvaWQgaW50ZXJmZXJpbmcgd2l0aCBsb2dnaW5nIGNvbmZpZyBsb29rdXBzIGZvciBvcHRpb25hbCBmaWVsZHMgbGlrZSAnYXBwJ1xuICAgICAgICAgICAgaWYgKHByb3AgPT09IFwiYXBwXCIpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICByZXR1cm4gRW52aXJvbm1lbnQuYnVpbGRFbnZQcm94eSh1bmRlZmluZWQsIFtwcm9wXSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgRW52aXJvbm1lbnQuX2luc3RhbmNlID0gcHJveGllZCBhcyBhbnk7XG4gICAgfVxuICAgIHJldHVybiBFbnZpcm9ubWVudC5faW5zdGFuY2UgYXMgRTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3RhdGljXG4gICAqIEBkZXNjcmlwdGlvbiBBY2N1bXVsYXRlcyB0aGUgZ2l2ZW4gdmFsdWUgaW50byB0aGUgZW52aXJvbm1lbnQuXG4gICAqIEBzdW1tYXJ5IEFkZHMgbmV3IHByb3BlcnRpZXMgdG8gdGhlIGVudmlyb25tZW50IGZyb20gdGhlIHByb3ZpZGVkIG9iamVjdC5cbiAgICogQHRlbXBsYXRlIFZcbiAgICogQHBhcmFtIHtWfSB2YWx1ZSAtIFRoZSBvYmplY3QgdG8gYWNjdW11bGF0ZSBpbnRvIHRoZSBlbnZpcm9ubWVudC5cbiAgICogQHJldHVybiB7Vn0gVGhlIHVwZGF0ZWQgZW52aXJvbm1lbnQgaW5zdGFuY2UuXG4gICAqL1xuICBzdGF0aWMgYWNjdW11bGF0ZTxWIGV4dGVuZHMgb2JqZWN0PihcbiAgICB2YWx1ZTogVlxuICApOiB0eXBlb2YgRW52aXJvbm1lbnQuX2luc3RhbmNlICZcbiAgICBWICZcbiAgICBPYmplY3RBY2N1bXVsYXRvcjx0eXBlb2YgRW52aXJvbm1lbnQuX2luc3RhbmNlICYgVj4ge1xuICAgIGNvbnN0IGluc3RhbmNlID0gRW52aXJvbm1lbnQuaW5zdGFuY2UoKTtcbiAgICBPYmplY3Qua2V5cyhpbnN0YW5jZSBhcyBhbnkpLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgY29uc3QgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoaW5zdGFuY2UgYXMgYW55LCBrZXkpO1xuICAgICAgaWYgKGRlc2MgJiYgZGVzYy5jb25maWd1cmFibGUgJiYgZGVzYy5lbnVtZXJhYmxlKSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShpbnN0YW5jZSBhcyBhbnksIGtleSwge1xuICAgICAgICAgIC4uLmRlc2MsXG4gICAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBpbnN0YW5jZS5hY2N1bXVsYXRlKHZhbHVlKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXQoa2V5OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gRW52aXJvbm1lbnQuX2luc3RhbmNlLmdldChrZXkpO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgYnVpbGRFbnZQcm94eShjdXJyZW50OiBhbnksIHBhdGg6IHN0cmluZ1tdKTogYW55IHtcbiAgICBjb25zdCBidWlsZEtleSA9IChwOiBzdHJpbmdbXSkgPT5cbiAgICAgIHAubWFwKChzZWcpID0+IHRvRU5WRm9ybWF0KHNlZykpLmpvaW4oRU5WX1BBVEhfREVMSU1JVEVSKTtcblxuICAgIC8vIEhlbHBlciB0byByZWFkIGZyb20gdGhlIGFjdGl2ZSBlbnZpcm9ubWVudCBnaXZlbiBhIGNvbXBvc2VkIGtleVxuICAgIGNvbnN0IHJlYWRFbnYgPSAoa2V5OiBzdHJpbmcpOiB1bmtub3duID0+IHtcbiAgICAgIGlmIChpc0Jyb3dzZXIoKSkge1xuICAgICAgICBjb25zdCBlbnYgPSAoXG4gICAgICAgICAgZ2xvYmFsVGhpcyBhcyB0eXBlb2YgZ2xvYmFsVGhpcyAmIHtcbiAgICAgICAgICAgIFtCcm93c2VyRW52S2V5XT86IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgICAgICAgIH1cbiAgICAgICAgKVtCcm93c2VyRW52S2V5XTtcbiAgICAgICAgcmV0dXJuIGVudiA/IGVudltrZXldIDogdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIChnbG9iYWxUaGlzIGFzIGFueSk/LnByb2Nlc3M/LmVudj8uW2tleV07XG4gICAgfTtcblxuICAgIGNvbnN0IGhhbmRsZXI6IFByb3h5SGFuZGxlcjxhbnk+ID0ge1xuICAgICAgZ2V0KF90YXJnZXQsIHByb3A6IHN0cmluZyB8IHN5bWJvbCkge1xuICAgICAgICBpZiAocHJvcCA9PT0gU3ltYm9sLnRvUHJpbWl0aXZlKSB7XG4gICAgICAgICAgcmV0dXJuICgpID0+IGJ1aWxkS2V5KHBhdGgpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9wID09PSBcInRvU3RyaW5nXCIpIHtcbiAgICAgICAgICByZXR1cm4gKCkgPT4gYnVpbGRLZXkocGF0aCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb3AgPT09IFwidmFsdWVPZlwiKSB7XG4gICAgICAgICAgcmV0dXJuICgpID0+IGJ1aWxkS2V5KHBhdGgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgcHJvcCA9PT0gXCJzeW1ib2xcIikgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgICAgICBjb25zdCBuZXh0TW9kZWwgPVxuICAgICAgICAgIGN1cnJlbnQgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGN1cnJlbnQsIHByb3ApXG4gICAgICAgICAgICA/IChjdXJyZW50IGFzIGFueSlbcHJvcF1cbiAgICAgICAgICAgIDogdW5kZWZpbmVkO1xuICAgICAgICBjb25zdCBuZXh0UGF0aCA9IFsuLi5wYXRoLCBwcm9wXTtcbiAgICAgICAgY29uc3QgY29tcG9zZWRLZXkgPSBidWlsZEtleShuZXh0UGF0aCk7XG5cbiAgICAgICAgLy8gSWYgYW4gRU5WIHZhbHVlIGV4aXN0cyBmb3IgdGhpcyBwYXRoLCByZXR1cm4gaXQgZGlyZWN0bHlcbiAgICAgICAgY29uc3QgZW52VmFsdWUgPSByZWFkRW52KGNvbXBvc2VkS2V5KTtcbiAgICAgICAgaWYgKHR5cGVvZiBlbnZWYWx1ZSAhPT0gXCJ1bmRlZmluZWRcIikgcmV0dXJuIGVudlZhbHVlO1xuXG4gICAgICAgIC8vIE90aGVyd2lzZSwgaWYgdGhlIG1vZGVsIGhhcyBhbiBvYmplY3QgYXQgdGhpcyBwYXRoLCBrZWVwIGRyaWxsaW5nIHdpdGggYSBwcm94eVxuICAgICAgICBjb25zdCBpc05leHRPYmplY3QgPSBuZXh0TW9kZWwgJiYgdHlwZW9mIG5leHRNb2RlbCA9PT0gXCJvYmplY3RcIjtcbiAgICAgICAgaWYgKGlzTmV4dE9iamVjdCkgcmV0dXJuIEVudmlyb25tZW50LmJ1aWxkRW52UHJveHkobmV4dE1vZGVsLCBuZXh0UGF0aCk7XG5cbiAgICAgICAgLy8gQWx3YXlzIHJldHVybiBhIHByb3h5IGZvciBmdXJ0aGVyIHBhdGggY29tcG9zaXRpb24gd2hlbiBubyBFTlYgdmFsdWU7XG4gICAgICAgIC8vIGRvIG5vdCBzdXJmYWNlIHByaW1pdGl2ZSBtb2RlbCBkZWZhdWx0cyBoZXJlICh0aGlzIEFQSSBpcyBmb3Iga2V5IGNvbXBvc2l0aW9uKS5cbiAgICAgICAgcmV0dXJuIEVudmlyb25tZW50LmJ1aWxkRW52UHJveHkodW5kZWZpbmVkLCBuZXh0UGF0aCk7XG4gICAgICB9LFxuICAgICAgb3duS2V5cygpIHtcbiAgICAgICAgcmV0dXJuIGN1cnJlbnQgPyBSZWZsZWN0Lm93bktleXMoY3VycmVudCkgOiBbXTtcbiAgICAgIH0sXG4gICAgICBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoX3QsIHApIHtcbiAgICAgICAgaWYgKCFjdXJyZW50KSByZXR1cm4gdW5kZWZpbmVkIGFzIGFueTtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChjdXJyZW50LCBwKSkge1xuICAgICAgICAgIHJldHVybiB7IGVudW1lcmFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IGFzIFByb3BlcnR5RGVzY3JpcHRvcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkIGFzIGFueTtcbiAgICAgIH0sXG4gICAgfTtcblxuICAgIGNvbnN0IHRhcmdldCA9IHt9IGFzIGFueTtcbiAgICByZXR1cm4gbmV3IFByb3h5KHRhcmdldCwgaGFuZGxlcik7XG4gIH1cblxuICAvKipcbiAgICogQHN0YXRpY1xuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIHRoZSBrZXlzIG9mIHRoZSBlbnZpcm9ubWVudCwgb3B0aW9uYWxseSBjb252ZXJ0aW5nIHRoZW0gdG8gRU5WIGZvcm1hdC5cbiAgICogQHN1bW1hcnkgR2V0cyBhbGwga2V5cyBpbiB0aGUgZW52aXJvbm1lbnQsIHdpdGggYW4gb3B0aW9uIHRvIGZvcm1hdCB0aGVtIGZvciBlbnZpcm9ubWVudCB2YXJpYWJsZXMuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW3RvRW52PXRydWVdIC0gV2hldGhlciB0byBjb252ZXJ0IHRoZSBrZXlzIHRvIEVOViBmb3JtYXQuXG4gICAqIEByZXR1cm4ge3N0cmluZ1tdfSBBbiBhcnJheSBvZiBrZXlzIGZyb20gdGhlIGVudmlyb25tZW50LlxuICAgKi9cbiAgc3RhdGljIGtleXModG9FbnY6IGJvb2xlYW4gPSB0cnVlKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBFbnZpcm9ubWVudC5pbnN0YW5jZSgpXG4gICAgICAua2V5cygpXG4gICAgICAubWFwKChrKSA9PiAodG9FbnYgPyB0b0VOVkZvcm1hdChrKSA6IGspKTtcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgTG9nZ2VkRW52aXJvbm1lbnQgPSBFbnZpcm9ubWVudC5hY2N1bXVsYXRlKFxuICBPYmplY3QuYXNzaWduKHt9LCBEZWZhdWx0TG9nZ2luZ0NvbmZpZywge1xuICAgIGVudjpcbiAgICAgIChpc0Jyb3dzZXIoKSAmJiAoZ2xvYmFsVGhpcyBhcyBhbnkpW0Jyb3dzZXJFbnZLZXldXG4gICAgICAgID8gKGdsb2JhbFRoaXMgYXMgYW55KVtCcm93c2VyRW52S2V5XVtcIk5PREVfRU5WXCJdXG4gICAgICAgIDogKGdsb2JhbFRoaXMgYXMgYW55KS5wcm9jZXNzLmVudltcIk5PREVfRU5WXCJdKSB8fCBcImRldmVsb3BtZW50XCIsXG4gIH0pXG4pO1xuIiwiaW1wb3J0IHtcbiAgTG9nZ2VyRmFjdG9yeSxcbiAgTG9nZ2luZ0NvbmZpZyxcbiAgTG9nZ2luZ0NvbnRleHQsXG4gIFN0cmluZ0xpa2UsXG4gIFRoZW1lLFxuICBUaGVtZU9wdGlvbixcbiAgVGhlbWVPcHRpb25CeUxvZ0xldmVsLFxuICBMb2dnZXIsXG59IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBDb2xvcml6ZU9wdGlvbnMsIHN0eWxlLCBTdHlsZWRTdHJpbmcgfSBmcm9tIFwic3R5bGVkLXN0cmluZy1idWlsZGVyXCI7XG5pbXBvcnQgeyBEZWZhdWx0VGhlbWUsIExvZ0xldmVsLCBOdW1lcmljTG9nTGV2ZWxzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBzZiB9IGZyb20gXCIuL3RleHRcIjtcbmltcG9ydCB7IExvZ2dlZEVudmlyb25tZW50IH0gZnJvbSBcIi4vZW52aXJvbm1lbnRcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQSBtaW5pbWFsIGxvZ2dlciBpbXBsZW1lbnRhdGlvbi5cbiAqIEBzdW1tYXJ5IE1pbmlMb2dnZXIgaXMgYSBsaWdodHdlaWdodCBsb2dnaW5nIGNsYXNzIHRoYXQgaW1wbGVtZW50cyB0aGUgTG9nZ2VyIGludGVyZmFjZS5cbiAqIEl0IHByb3ZpZGVzIGJhc2ljIGxvZ2dpbmcgZnVuY3Rpb25hbGl0eSB3aXRoIHN1cHBvcnQgZm9yIGRpZmZlcmVudCBsb2cgbGV2ZWxzLCB2ZXJib3NpdHksXG4gKiBjb250ZXh0LWF3YXJlIGxvZ2dpbmcsIGFuZCBjdXN0b21pemFibGUgZm9ybWF0dGluZy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjb250ZXh0IC0gVGhlIGNvbnRleHQgKHR5cGljYWxseSBjbGFzcyBuYW1lKSB0aGlzIGxvZ2dlciBpcyBhc3NvY2lhdGVkIHdpdGhcbiAqIEBwYXJhbSB7UGFydGlhbDxMb2dnaW5nQ29uZmlnPn0gY29uZiAtIE9wdGlvbmFsIGNvbmZpZ3VyYXRpb24gdG8gb3ZlcnJpZGUgZ2xvYmFsIHNldHRpbmdzXG4gKiBAY2xhc3MgTWluaUxvZ2dlclxuICogQGV4YW1wbGVcbiAqIC8vIENyZWF0ZSBhIG5ldyBsb2dnZXIgZm9yIGEgY2xhc3NcbiAqIGNvbnN0IGxvZ2dlciA9IG5ldyBNaW5pTG9nZ2VyKCdNeUNsYXNzJyk7XG4gKlxuICogLy8gTG9nIG1lc3NhZ2VzIGF0IGRpZmZlcmVudCBsZXZlbHNcbiAqIGxvZ2dlci5pbmZvKCdUaGlzIGlzIGFuIGluZm8gbWVzc2FnZScpO1xuICogbG9nZ2VyLmRlYnVnKCdUaGlzIGlzIGEgZGVidWcgbWVzc2FnZScpO1xuICogbG9nZ2VyLmVycm9yKCdTb21ldGhpbmcgd2VudCB3cm9uZycpO1xuICpcbiAqIC8vIENyZWF0ZSBhIGNoaWxkIGxvZ2dlciBmb3IgYSBzcGVjaWZpYyBtZXRob2RcbiAqIGNvbnN0IG1ldGhvZExvZ2dlciA9IGxvZ2dlci5mb3IoJ215TWV0aG9kJyk7XG4gKiBtZXRob2RMb2dnZXIudmVyYm9zZSgnRGV0YWlsZWQgaW5mb3JtYXRpb24nLCAyKTtcbiAqXG4gKiAvLyBMb2cgd2l0aCBjdXN0b20gY29uZmlndXJhdGlvblxuICogbG9nZ2VyLmZvcignc3BlY2lhbE1ldGhvZCcsIHsgc3R5bGU6IHRydWUgfSkuaW5mbygnU3R5bGVkIG1lc3NhZ2UnKTtcbiAqL1xuZXhwb3J0IGNsYXNzIE1pbmlMb2dnZXIgaW1wbGVtZW50cyBMb2dnZXIge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcm90ZWN0ZWQgY29udGV4dDogc3RyaW5nLFxuICAgIHByb3RlY3RlZCBjb25mPzogUGFydGlhbDxMb2dnaW5nQ29uZmlnPlxuICApIHt9XG5cbiAgcHJvdGVjdGVkIGNvbmZpZyhcbiAgICBrZXk6IGtleW9mIExvZ2dpbmdDb25maWdcbiAgKTogTG9nZ2luZ0NvbmZpZ1trZXlvZiBMb2dnaW5nQ29uZmlnXSB7XG4gICAgaWYgKHRoaXMuY29uZiAmJiBrZXkgaW4gdGhpcy5jb25mKSByZXR1cm4gdGhpcy5jb25mW2tleV07XG4gICAgcmV0dXJuIExvZ2dpbmcuZ2V0Q29uZmlnKClba2V5XTtcbiAgfVxuXG4gIGZvcihtZXRob2Q6IHN0cmluZyB8ICgoLi4uYXJnczogYW55W10pID0+IGFueSkpOiBMb2dnZXI7XG4gIGZvcihjb25maWc6IFBhcnRpYWw8TG9nZ2luZ0NvbmZpZz4pOiBMb2dnZXI7XG4gIGZvcihcbiAgICBtZXRob2Q6IHN0cmluZyB8ICgoLi4uYXJnczogYW55W10pID0+IGFueSkgfCBQYXJ0aWFsPExvZ2dpbmdDb25maWc+LFxuICAgIGNvbmZpZzogUGFydGlhbDxMb2dnaW5nQ29uZmlnPixcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBMb2dnZXI7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIGNoaWxkIGxvZ2dlciBmb3IgYSBzcGVjaWZpYyBtZXRob2Qgb3IgY29udGV4dFxuICAgKiBAc3VtbWFyeSBSZXR1cm5zIGEgbmV3IGxvZ2dlciBpbnN0YW5jZSB3aXRoIHRoZSBjdXJyZW50IGNvbnRleHQgZXh0ZW5kZWQgYnkgdGhlIHNwZWNpZmllZCBtZXRob2QgbmFtZVxuICAgKiBAcGFyYW0ge3N0cmluZyB8IEZ1bmN0aW9ufSBtZXRob2QgLSBUaGUgbWV0aG9kIG5hbWUgb3IgZnVuY3Rpb24gdG8gY3JlYXRlIGEgbG9nZ2VyIGZvclxuICAgKiBAcGFyYW0ge1BhcnRpYWw8TG9nZ2luZ0NvbmZpZz59IGNvbmZpZyAtIE9wdGlvbmFsIGNvbmZpZ3VyYXRpb24gdG8gb3ZlcnJpZGUgc2V0dGluZ3NcbiAgICogQHBhcmFtIHsuLi5hbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIGxvZ2dlciBmYWN0b3J5XG4gICAqIEByZXR1cm4ge0xvZ2dlcn0gQSBuZXcgbG9nZ2VyIGluc3RhbmNlIGZvciB0aGUgc3BlY2lmaWVkIG1ldGhvZFxuICAgKi9cbiAgZm9yKFxuICAgIG1ldGhvZD86IHN0cmluZyB8ICgoLi4uYXJnczogYW55W10pID0+IGFueSkgfCBQYXJ0aWFsPExvZ2dpbmdDb25maWc+LFxuICAgIGNvbmZpZz86IFBhcnRpYWw8TG9nZ2luZ0NvbmZpZz4sXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IExvZ2dlciB7XG4gICAgaWYgKCFjb25maWcgJiYgdHlwZW9mIG1ldGhvZCA9PT0gXCJvYmplY3RcIikge1xuICAgICAgY29uZmlnID0gbWV0aG9kO1xuICAgICAgbWV0aG9kID0gdW5kZWZpbmVkO1xuICAgIH0gZWxzZSB7XG4gICAgICBtZXRob2QgPSBtZXRob2RcbiAgICAgICAgPyB0eXBlb2YgbWV0aG9kID09PSBcInN0cmluZ1wiXG4gICAgICAgICAgPyBtZXRob2RcbiAgICAgICAgICA6IChtZXRob2QgYXMgYW55KS5uYW1lXG4gICAgICAgIDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgUHJveHkodGhpcywge1xuICAgICAgZ2V0OiAodGFyZ2V0OiB0eXBlb2YgdGhpcywgcDogc3RyaW5nIHwgc3ltYm9sLCByZWNlaXZlcjogYW55KSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IFJlZmxlY3QuZ2V0KHRhcmdldCwgcCwgcmVjZWl2ZXIpO1xuICAgICAgICBpZiAocCA9PT0gXCJjb25maWdcIikge1xuICAgICAgICAgIHJldHVybiBuZXcgUHJveHkodGhpcy5jb25maWcsIHtcbiAgICAgICAgICAgIGdldDogKHRhcmdldDogdHlwZW9mIHRoaXMuY29uZmlnLCBwOiBzdHJpbmcgfCBzeW1ib2wpID0+IHtcbiAgICAgICAgICAgICAgaWYgKGNvbmZpZyAmJiBwIGluIGNvbmZpZylcbiAgICAgICAgICAgICAgICByZXR1cm4gY29uZmlnW3AgYXMga2V5b2YgTG9nZ2luZ0NvbmZpZ107XG4gICAgICAgICAgICAgIHJldHVybiBSZWZsZWN0LmdldCh0YXJnZXQsIHAsIHJlY2VpdmVyKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHAgPT09IFwiY29udGV4dFwiICYmIG1ldGhvZCkge1xuICAgICAgICAgIHJldHVybiBbcmVzdWx0LCBtZXRob2RdLmpvaW4oXCIuXCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgZm9ybWF0dGVkIGxvZyBzdHJpbmdcbiAgICogQHN1bW1hcnkgR2VuZXJhdGVzIGEgbG9nIHN0cmluZyB3aXRoIHRpbWVzdGFtcCwgY29sb3JlZCBsb2cgbGV2ZWwsIGNvbnRleHQsIGFuZCBtZXNzYWdlXG4gICAqIEBwYXJhbSB7TG9nTGV2ZWx9IGxldmVsIC0gVGhlIGxvZyBsZXZlbCBmb3IgdGhpcyBtZXNzYWdlXG4gICAqIEBwYXJhbSB7U3RyaW5nTGlrZSB8IEVycm9yfSBtZXNzYWdlIC0gVGhlIG1lc3NhZ2UgdG8gbG9nIG9yIGFuIEVycm9yIG9iamVjdFxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2Vycm9yXSAtIE9wdGlvbmFsIGVycm9yIHRvIGV4dHJhY3Qgc3RhY2sgdHJhY2UgdG8gaW5jbHVkZSBpbiB0aGUgbG9nXG4gICAqIEByZXR1cm4ge3N0cmluZ30gQSBmb3JtYXR0ZWQgbG9nIHN0cmluZyB3aXRoIGFsbCBjb21wb25lbnRzXG4gICAqL1xuICBwcm90ZWN0ZWQgY3JlYXRlTG9nKFxuICAgIGxldmVsOiBMb2dMZXZlbCxcbiAgICBtZXNzYWdlOiBTdHJpbmdMaWtlIHwgRXJyb3IsXG4gICAgZXJyb3I/OiBFcnJvclxuICApOiBzdHJpbmcge1xuICAgIGNvbnN0IGxvZzogUmVjb3JkPFxuICAgICAgfCBcInRpbWVzdGFtcFwiXG4gICAgICB8IFwibGV2ZWxcIlxuICAgICAgfCBcImNvbnRleHRcIlxuICAgICAgfCBcImNvcnJlbGF0aW9uSWRcIlxuICAgICAgfCBcIm1lc3NhZ2VcIlxuICAgICAgfCBcInNlcGFyYXRvclwiXG4gICAgICB8IFwic3RhY2tcIlxuICAgICAgfCBcImFwcFwiLFxuICAgICAgc3RyaW5nXG4gICAgPiA9IHt9IGFzIGFueTtcbiAgICBjb25zdCBzdHlsZSA9IHRoaXMuY29uZmlnKFwic3R5bGVcIik7XG4gICAgY29uc3Qgc2VwYXJhdG9yID0gdGhpcy5jb25maWcoXCJzZXBhcmF0b3JcIik7XG4gICAgY29uc3QgYXBwID0gdGhpcy5jb25maWcoXCJhcHBcIik7XG4gICAgaWYgKGFwcClcbiAgICAgIGxvZy5hcHAgPSBzdHlsZVxuICAgICAgICA/IExvZ2dpbmcudGhlbWUoYXBwIGFzIHN0cmluZywgXCJhcHBcIiwgbGV2ZWwpXG4gICAgICAgIDogKGFwcCBhcyBzdHJpbmcpO1xuXG4gICAgaWYgKHNlcGFyYXRvcilcbiAgICAgIGxvZy5zZXBhcmF0b3IgPSBzdHlsZVxuICAgICAgICA/IExvZ2dpbmcudGhlbWUoc2VwYXJhdG9yIGFzIHN0cmluZywgXCJzZXBhcmF0b3JcIiwgbGV2ZWwpXG4gICAgICAgIDogKHNlcGFyYXRvciBhcyBzdHJpbmcpO1xuXG4gICAgaWYgKHRoaXMuY29uZmlnKFwidGltZXN0YW1wXCIpKSB7XG4gICAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpO1xuICAgICAgY29uc3QgdGltZXN0YW1wID0gc3R5bGUgPyBMb2dnaW5nLnRoZW1lKGRhdGUsIFwidGltZXN0YW1wXCIsIGxldmVsKSA6IGRhdGU7XG4gICAgICBsb2cudGltZXN0YW1wID0gdGltZXN0YW1wO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbmZpZyhcImxvZ0xldmVsXCIpKSB7XG4gICAgICBjb25zdCBsdmw6IHN0cmluZyA9IHN0eWxlXG4gICAgICAgID8gTG9nZ2luZy50aGVtZShsZXZlbCwgXCJsb2dMZXZlbFwiLCBsZXZlbClcbiAgICAgICAgOiBsZXZlbDtcbiAgICAgIGxvZy5sZXZlbCA9IGx2bC50b1VwcGVyQ2FzZSgpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbmZpZyhcImNvbnRleHRcIikpIHtcbiAgICAgIGNvbnN0IGNvbnRleHQ6IHN0cmluZyA9IHN0eWxlXG4gICAgICAgID8gTG9nZ2luZy50aGVtZSh0aGlzLmNvbnRleHQsIFwiY2xhc3NcIiwgbGV2ZWwpXG4gICAgICAgIDogdGhpcy5jb250ZXh0O1xuICAgICAgbG9nLmNvbnRleHQgPSBjb250ZXh0O1xuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbmZpZyhcImNvcnJlbGF0aW9uSWRcIikpIHtcbiAgICAgIHtcbiAgICAgICAgY29uc3QgaWQ6IHN0cmluZyA9IHN0eWxlXG4gICAgICAgICAgPyBMb2dnaW5nLnRoZW1lKHRoaXMuY29uZmlnKFwiY29ycmVsYXRpb25JZFwiKSEudG9TdHJpbmcoKSwgXCJpZFwiLCBsZXZlbClcbiAgICAgICAgICA6IHRoaXMuY29uZmlnKFwiY29ycmVsYXRpb25JZFwiKSEudG9TdHJpbmcoKTtcbiAgICAgICAgbG9nLmNvcnJlbGF0aW9uSWQgPSBpZDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBtc2c6IHN0cmluZyA9IHN0eWxlXG4gICAgICA/IExvZ2dpbmcudGhlbWUoXG4gICAgICAgICAgdHlwZW9mIG1lc3NhZ2UgPT09IFwic3RyaW5nXCIgPyBtZXNzYWdlIDogKG1lc3NhZ2UgYXMgRXJyb3IpLm1lc3NhZ2UsXG4gICAgICAgICAgXCJtZXNzYWdlXCIsXG4gICAgICAgICAgbGV2ZWxcbiAgICAgICAgKVxuICAgICAgOiB0eXBlb2YgbWVzc2FnZSA9PT0gXCJzdHJpbmdcIlxuICAgICAgICA/IG1lc3NhZ2VcbiAgICAgICAgOiAobWVzc2FnZSBhcyBFcnJvcikubWVzc2FnZTtcbiAgICBsb2cubWVzc2FnZSA9IG1zZztcbiAgICBpZiAoZXJyb3IgfHwgbWVzc2FnZSBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICBjb25zdCBzdGFjayA9IHN0eWxlXG4gICAgICAgID8gTG9nZ2luZy50aGVtZShcbiAgICAgICAgICAgIChlcnJvcj8uc3RhY2sgfHwgKG1lc3NhZ2UgYXMgRXJyb3IpLnN0YWNrKSBhcyBzdHJpbmcsXG4gICAgICAgICAgICBcInN0YWNrXCIsXG4gICAgICAgICAgICBsZXZlbFxuICAgICAgICAgIClcbiAgICAgICAgOiBlcnJvcj8uc3RhY2sgfHwgXCJcIjtcbiAgICAgIGxvZy5zdGFjayA9IGAgfCAkeyhlcnJvciB8fCAobWVzc2FnZSBhcyBFcnJvcikpLm1lc3NhZ2V9IC0gU3RhY2sgdHJhY2U6XFxuJHtzdGFja31gO1xuICAgIH1cblxuICAgIHN3aXRjaCAodGhpcy5jb25maWcoXCJmb3JtYXRcIikpIHtcbiAgICAgIGNhc2UgXCJqc29uXCI6XG4gICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShsb2cpO1xuICAgICAgY2FzZSBcInJhd1wiOlxuICAgICAgICByZXR1cm4gKHRoaXMuY29uZmlnKFwicGF0dGVyblwiKSBhcyBzdHJpbmcpXG4gICAgICAgICAgLnNwbGl0KFwiIFwiKVxuICAgICAgICAgIC5tYXAoKHMpID0+IHtcbiAgICAgICAgICAgIGlmICghcy5tYXRjaCgvXFx7Lio/fS9nKSkgcmV0dXJuIHM7XG4gICAgICAgICAgICBjb25zdCBmb3JtYXR0ZWRTID0gc2YocywgbG9nKTtcbiAgICAgICAgICAgIGlmIChmb3JtYXR0ZWRTICE9PSBzKSByZXR1cm4gZm9ybWF0dGVkUztcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAuZmlsdGVyKChzKSA9PiBzKVxuICAgICAgICAgIC5qb2luKFwiIFwiKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgbG9nZ2luZyBmb3JtYXQ6ICR7dGhpcy5jb25maWcoXCJmb3JtYXRcIil9YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMb2dzIGEgbWVzc2FnZSB3aXRoIHRoZSBzcGVjaWZpZWQgbG9nIGxldmVsXG4gICAqIEBzdW1tYXJ5IENoZWNrcyBpZiB0aGUgbWVzc2FnZSBzaG91bGQgYmUgbG9nZ2VkIGJhc2VkIG9uIHRoZSBjdXJyZW50IGxvZyBsZXZlbCxcbiAgICogdGhlbiB1c2VzIHRoZSBhcHByb3ByaWF0ZSBjb25zb2xlIG1ldGhvZCB0byBvdXRwdXQgdGhlIGZvcm1hdHRlZCBsb2dcbiAgICogQHBhcmFtIHtMb2dMZXZlbH0gbGV2ZWwgLSBUaGUgbG9nIGxldmVsIG9mIHRoZSBtZXNzYWdlXG4gICAqIEBwYXJhbSB7U3RyaW5nTGlrZSB8IEVycm9yfSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWQgb3IgYW4gRXJyb3Igb2JqZWN0XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbZXJyb3JdIC0gT3B0aW9uYWwgc3RhY2sgdHJhY2UgdG8gaW5jbHVkZSBpbiB0aGUgbG9nXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBwcm90ZWN0ZWQgbG9nKGxldmVsOiBMb2dMZXZlbCwgbXNnOiBTdHJpbmdMaWtlIHwgRXJyb3IsIGVycm9yPzogRXJyb3IpOiB2b2lkIHtcbiAgICBjb25zdCBjb25mTHZsID0gdGhpcy5jb25maWcoXCJsZXZlbFwiKSBhcyBMb2dMZXZlbDtcbiAgICBpZiAoTnVtZXJpY0xvZ0xldmVsc1tjb25mTHZsXSA8IE51bWVyaWNMb2dMZXZlbHNbbGV2ZWxdKSByZXR1cm47XG4gICAgbGV0IG1ldGhvZDtcbiAgICBzd2l0Y2ggKGxldmVsKSB7XG4gICAgICBjYXNlIExvZ0xldmVsLmluZm86XG4gICAgICAgIG1ldGhvZCA9IGNvbnNvbGUubG9nO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgTG9nTGV2ZWwudmVyYm9zZTpcbiAgICAgIGNhc2UgTG9nTGV2ZWwuZGVidWc6XG4gICAgICAgIG1ldGhvZCA9IGNvbnNvbGUuZGVidWc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBMb2dMZXZlbC5lcnJvcjpcbiAgICAgICAgbWV0aG9kID0gY29uc29sZS5lcnJvcjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGxvZyBsZXZlbFwiKTtcbiAgICB9XG4gICAgbWV0aG9kKHRoaXMuY3JlYXRlTG9nKGxldmVsLCBtc2csIGVycm9yKSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYSBtZXNzYWdlIGF0IHRoZSBzaWxseSBsZXZlbFxuICAgKiBAc3VtbWFyeSBMb2dzIGEgbWVzc2FnZSBhdCB0aGUgc2lsbHkgbGV2ZWwgaWYgdGhlIGN1cnJlbnQgdmVyYm9zaXR5IHNldHRpbmcgYWxsb3dzIGl0XG4gICAqIEBwYXJhbSB7U3RyaW5nTGlrZX0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbdmVyYm9zaXR5PTBdIC0gVGhlIHZlcmJvc2l0eSBsZXZlbCBvZiB0aGUgbWVzc2FnZVxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgc2lsbHkobXNnOiBTdHJpbmdMaWtlLCB2ZXJib3NpdHk6IG51bWJlciA9IDApOiB2b2lkIHtcbiAgICBpZiAoKHRoaXMuY29uZmlnKFwidmVyYm9zZVwiKSBhcyBudW1iZXIpID49IHZlcmJvc2l0eSlcbiAgICAgIHRoaXMubG9nKExvZ0xldmVsLnZlcmJvc2UsIG1zZyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYSBtZXNzYWdlIGF0IHRoZSB2ZXJib3NlIGxldmVsXG4gICAqIEBzdW1tYXJ5IExvZ3MgYSBtZXNzYWdlIGF0IHRoZSB2ZXJib3NlIGxldmVsIGlmIHRoZSBjdXJyZW50IHZlcmJvc2l0eSBzZXR0aW5nIGFsbG93cyBpdFxuICAgKiBAcGFyYW0ge1N0cmluZ0xpa2V9IG1zZyAtIFRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZFxuICAgKiBAcGFyYW0ge251bWJlcn0gW3ZlcmJvc2l0eT0wXSAtIFRoZSB2ZXJib3NpdHkgbGV2ZWwgb2YgdGhlIG1lc3NhZ2VcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIHZlcmJvc2UobXNnOiBTdHJpbmdMaWtlLCB2ZXJib3NpdHk6IG51bWJlciA9IDApOiB2b2lkIHtcbiAgICBpZiAoKHRoaXMuY29uZmlnKFwidmVyYm9zZVwiKSBhcyBudW1iZXIpID49IHZlcmJvc2l0eSlcbiAgICAgIHRoaXMubG9nKExvZ0xldmVsLnZlcmJvc2UsIG1zZyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYSBtZXNzYWdlIGF0IHRoZSBpbmZvIGxldmVsXG4gICAqIEBzdW1tYXJ5IExvZ3MgYSBtZXNzYWdlIGF0IHRoZSBpbmZvIGxldmVsIGZvciBnZW5lcmFsIGFwcGxpY2F0aW9uIGluZm9ybWF0aW9uXG4gICAqIEBwYXJhbSB7U3RyaW5nTGlrZX0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBpbmZvKG1zZzogU3RyaW5nTGlrZSk6IHZvaWQge1xuICAgIHRoaXMubG9nKExvZ0xldmVsLmluZm8sIG1zZyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYSBtZXNzYWdlIGF0IHRoZSBkZWJ1ZyBsZXZlbFxuICAgKiBAc3VtbWFyeSBMb2dzIGEgbWVzc2FnZSBhdCB0aGUgZGVidWcgbGV2ZWwgZm9yIGRldGFpbGVkIHRyb3VibGVzaG9vdGluZyBpbmZvcm1hdGlvblxuICAgKiBAcGFyYW0ge1N0cmluZ0xpa2V9IG1zZyAtIFRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZFxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgZGVidWcobXNnOiBTdHJpbmdMaWtlKTogdm9pZCB7XG4gICAgdGhpcy5sb2coTG9nTGV2ZWwuZGVidWcsIG1zZyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYSBtZXNzYWdlIGF0IHRoZSBlcnJvciBsZXZlbFxuICAgKiBAc3VtbWFyeSBMb2dzIGEgbWVzc2FnZSBhdCB0aGUgZXJyb3IgbGV2ZWwgZm9yIGVycm9ycyBhbmQgZXhjZXB0aW9uc1xuICAgKiBAcGFyYW0ge1N0cmluZ0xpa2UgfCBFcnJvcn0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkIG9yIGFuIEVycm9yIG9iamVjdFxuICAgKiBAcGFyYW0gZVxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgZXJyb3IobXNnOiBTdHJpbmdMaWtlIHwgRXJyb3IsIGU/OiBFcnJvcik6IHZvaWQge1xuICAgIHRoaXMubG9nKExvZ0xldmVsLmVycm9yLCBtc2csIGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBVcGRhdGVzIHRoZSBsb2dnZXIgY29uZmlndXJhdGlvblxuICAgKiBAc3VtbWFyeSBNZXJnZXMgdGhlIHByb3ZpZGVkIGNvbmZpZ3VyYXRpb24gd2l0aCB0aGUgZXhpc3RpbmcgY29uZmlndXJhdGlvblxuICAgKiBAcGFyYW0ge1BhcnRpYWw8TG9nZ2luZ0NvbmZpZz59IGNvbmZpZyAtIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gYXBwbHlcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIHNldENvbmZpZyhjb25maWc6IFBhcnRpYWw8TG9nZ2luZ0NvbmZpZz4pOiB2b2lkIHtcbiAgICB0aGlzLmNvbmYgPSB7IC4uLih0aGlzLmNvbmYgfHwge30pLCAuLi5jb25maWcgfTtcbiAgfVxufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBBIHN0YXRpYyBjbGFzcyBmb3IgbWFuYWdpbmcgbG9nZ2luZyBvcGVyYXRpb25zXG4gKiBAc3VtbWFyeSBUaGUgTG9nZ2luZyBjbGFzcyBwcm92aWRlcyBhIGNlbnRyYWxpemVkIGxvZ2dpbmcgbWVjaGFuaXNtIHdpdGggc3VwcG9ydCBmb3JcbiAqIGRpZmZlcmVudCBsb2cgbGV2ZWxzLCB2ZXJib3NpdHksIGFuZCBzdHlsaW5nLiBJdCB1c2VzIGEgc2luZ2xldG9uIHBhdHRlcm4gdG8gbWFpbnRhaW4gYSBnbG9iYWxcbiAqIGxvZ2dlciBpbnN0YW5jZSBhbmQgYWxsb3dzIGNyZWF0aW5nIHNwZWNpZmljIGxvZ2dlcnMgZm9yIGRpZmZlcmVudCBjbGFzc2VzIGFuZCBtZXRob2RzLlxuICogQGNsYXNzIExvZ2dpbmdcbiAqIEBleGFtcGxlXG4gKiAvLyBTZXQgZ2xvYmFsIGNvbmZpZ3VyYXRpb25cbiAqIExvZ2dpbmcuc2V0Q29uZmlnKHsgbGV2ZWw6IExvZ0xldmVsLmRlYnVnLCBzdHlsZTogdHJ1ZSB9KTtcbiAqXG4gKiAvLyBHZXQgYSBsb2dnZXIgZm9yIGEgc3BlY2lmaWMgY2xhc3NcbiAqIGNvbnN0IGxvZ2dlciA9IExvZ2dpbmcuZm9yKCdNeUNsYXNzJyk7XG4gKlxuICogLy8gTG9nIG1lc3NhZ2VzIGF0IGRpZmZlcmVudCBsZXZlbHNcbiAqIGxvZ2dlci5pbmZvKCdBcHBsaWNhdGlvbiBzdGFydGVkJyk7XG4gKiBsb2dnZXIuZGVidWcoJ1Byb2Nlc3NpbmcgZGF0YS4uLicpO1xuICpcbiAqIC8vIExvZyB3aXRoIGNvbnRleHRcbiAqIGNvbnN0IG1ldGhvZExvZ2dlciA9IExvZ2dpbmcuZm9yKCdNeUNsYXNzLm15TWV0aG9kJyk7XG4gKiBtZXRob2RMb2dnZXIudmVyYm9zZSgnRGV0YWlsZWQgb3BlcmF0aW9uIGluZm9ybWF0aW9uJywgMSk7XG4gKlxuICogLy8gTG9nIGVycm9yc1xuICogdHJ5IHtcbiAqICAgLy8gc29tZSBvcGVyYXRpb25cbiAqIH0gY2F0Y2ggKGVycm9yKSB7XG4gKiAgIGxvZ2dlci5lcnJvcihlcnJvcik7XG4gKiB9XG4gKiBAbWVybWFpZFxuICogY2xhc3NEaWFncmFtXG4gKiAgIGNsYXNzIExvZ2dlciB7XG4gKiAgICAgPDxpbnRlcmZhY2U+PlxuICogICAgICtmb3IobWV0aG9kLCBjb25maWcsIC4uLmFyZ3MpXG4gKiAgICAgK3NpbGx5KG1zZywgdmVyYm9zaXR5KVxuICogICAgICt2ZXJib3NlKG1zZywgdmVyYm9zaXR5KVxuICogICAgICtpbmZvKG1zZylcbiAqICAgICArZGVidWcobXNnKVxuICogICAgICtlcnJvcihtc2cpXG4gKiAgICAgK3NldENvbmZpZyhjb25maWcpXG4gKiAgIH1cbiAqXG4gKiAgIGNsYXNzIExvZ2dpbmcge1xuICogICAgIC1nbG9iYWw6IExvZ2dlclxuICogICAgIC1fZmFjdG9yeTogTG9nZ2VyRmFjdG9yeVxuICogICAgIC1fY29uZmlnOiBMb2dnaW5nQ29uZmlnXG4gKiAgICAgK3NldEZhY3RvcnkoZmFjdG9yeSlcbiAqICAgICArc2V0Q29uZmlnKGNvbmZpZylcbiAqICAgICArZ2V0Q29uZmlnKClcbiAqICAgICArZ2V0KClcbiAqICAgICArdmVyYm9zZShtc2csIHZlcmJvc2l0eSlcbiAqICAgICAraW5mbyhtc2cpXG4gKiAgICAgK2RlYnVnKG1zZylcbiAqICAgICArc2lsbHkobXNnKVxuICogICAgICtlcnJvcihtc2cpXG4gKiAgICAgK2ZvcihvYmplY3QsIGNvbmZpZywgLi4uYXJncylcbiAqICAgICArYmVjYXVzZShyZWFzb24sIGlkKVxuICogICAgICt0aGVtZSh0ZXh0LCB0eXBlLCBsb2dnZXJMZXZlbCwgdGVtcGxhdGUpXG4gKiAgIH1cbiAqXG4gKiAgIGNsYXNzIE1pbmlMb2dnZXIge1xuICogICAgICtjb25zdHJ1Y3Rvcihjb250ZXh0LCBjb25mPylcbiAqICAgfVxuICpcbiAqICAgTG9nZ2luZyAuLj4gTG9nZ2VyIDogY3JlYXRlc1xuICogICBMb2dnaW5nIC4uPiBNaW5pTG9nZ2VyIDogY3JlYXRlcyBieSBkZWZhdWx0XG4gKi9cbmV4cG9ydCBjbGFzcyBMb2dnaW5nIHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgZ2xvYmFsIGxvZ2dlciBpbnN0YW5jZVxuICAgKiBAc3VtbWFyeSBBIHNpbmdsZXRvbiBpbnN0YW5jZSBvZiBMb2dnZXIgdXNlZCBmb3IgZ2xvYmFsIGxvZ2dpbmdcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGdsb2JhbD86IExvZ2dlcjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEZhY3RvcnkgZnVuY3Rpb24gZm9yIGNyZWF0aW5nIGxvZ2dlciBpbnN0YW5jZXNcbiAgICogQHN1bW1hcnkgQSBmdW5jdGlvbiB0aGF0IGNyZWF0ZXMgbmV3IExvZ2dlciBpbnN0YW5jZXMuIEJ5IGRlZmF1bHQsIGl0IGNyZWF0ZXMgYSBNaW5pTG9nZ2VyLlxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgX2ZhY3Rvcnk6IExvZ2dlckZhY3RvcnkgPSAoXG4gICAgb2JqZWN0OiBzdHJpbmcsXG4gICAgY29uZmlnPzogUGFydGlhbDxMb2dnaW5nQ29uZmlnPlxuICApID0+IHtcbiAgICByZXR1cm4gbmV3IE1pbmlMb2dnZXIob2JqZWN0LCBjb25maWcpO1xuICB9O1xuXG4gIHByaXZhdGUgc3RhdGljIF9jb25maWc6IHR5cGVvZiBMb2dnZWRFbnZpcm9ubWVudCA9IExvZ2dlZEVudmlyb25tZW50O1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoKSB7fVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgZmFjdG9yeSBmdW5jdGlvbiBmb3IgY3JlYXRpbmcgbG9nZ2VyIGluc3RhbmNlc1xuICAgKiBAc3VtbWFyeSBBbGxvd3MgY3VzdG9taXppbmcgaG93IGxvZ2dlciBpbnN0YW5jZXMgYXJlIGNyZWF0ZWRcbiAgICogQHBhcmFtIHtMb2dnZXJGYWN0b3J5fSBmYWN0b3J5IC0gVGhlIGZhY3RvcnkgZnVuY3Rpb24gdG8gdXNlIGZvciBjcmVhdGluZyBsb2dnZXJzXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBzdGF0aWMgc2V0RmFjdG9yeShmYWN0b3J5OiBMb2dnZXJGYWN0b3J5KSB7XG4gICAgTG9nZ2luZy5fZmFjdG9yeSA9IGZhY3Rvcnk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFVwZGF0ZXMgdGhlIGdsb2JhbCBsb2dnaW5nIGNvbmZpZ3VyYXRpb25cbiAgICogQHN1bW1hcnkgQWxsb3dzIHVwZGF0aW5nIHRoZSBnbG9iYWwgbG9nZ2luZyBjb25maWd1cmF0aW9uIHdpdGggbmV3IHNldHRpbmdzXG4gICAqIEBwYXJhbSB7UGFydGlhbDxMb2dnaW5nQ29uZmlnPn0gY29uZmlnIC0gVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byBhcHBseVxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgc3RhdGljIHNldENvbmZpZyhjb25maWc6IFBhcnRpYWw8TG9nZ2luZ0NvbmZpZz4pOiB2b2lkIHtcbiAgICBPYmplY3QuZW50cmllcyhjb25maWcpLmZvckVhY2goKFtrLCB2XSkgPT4ge1xuICAgICAgKHRoaXMuX2NvbmZpZyBhcyBhbnkpW2tdID0gdiBhcyBhbnk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEdldHMgYSBjb3B5IG9mIHRoZSBjdXJyZW50IGdsb2JhbCBsb2dnaW5nIGNvbmZpZ3VyYXRpb25cbiAgICogQHN1bW1hcnkgUmV0dXJucyBhIGNvcHkgb2YgdGhlIGN1cnJlbnQgZ2xvYmFsIGxvZ2dpbmcgY29uZmlndXJhdGlvblxuICAgKiBAcmV0dXJuIHtMb2dnaW5nQ29uZmlnfSBBIGNvcHkgb2YgdGhlIGN1cnJlbnQgY29uZmlndXJhdGlvblxuICAgKi9cbiAgc3RhdGljIGdldENvbmZpZygpOiB0eXBlb2YgTG9nZ2VkRW52aXJvbm1lbnQge1xuICAgIHJldHVybiB0aGlzLl9jb25maWc7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBvciBjcmVhdGVzIHRoZSBnbG9iYWwgbG9nZ2VyIGluc3RhbmNlLlxuICAgKiBAc3VtbWFyeSBSZXR1cm5zIHRoZSBleGlzdGluZyBnbG9iYWwgbG9nZ2VyIG9yIGNyZWF0ZXMgYSBuZXcgb25lIGlmIGl0IGRvZXNuJ3QgZXhpc3QuXG4gICAqXG4gICAqIEByZXR1cm4gVGhlIGdsb2JhbCBWZXJib3NpdHlMb2dnZXIgaW5zdGFuY2UuXG4gICAqL1xuICBzdGF0aWMgZ2V0KCk6IExvZ2dlciB7XG4gICAgdGhpcy5nbG9iYWwgPSB0aGlzLmdsb2JhbCA/IHRoaXMuZ2xvYmFsIDogdGhpcy5fZmFjdG9yeShcIkxvZ2dpbmdcIik7XG4gICAgcmV0dXJuIHRoaXMuZ2xvYmFsO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMb2dzIGEgdmVyYm9zZSBtZXNzYWdlLlxuICAgKiBAc3VtbWFyeSBEZWxlZ2F0ZXMgdGhlIHZlcmJvc2UgbG9nZ2luZyB0byB0aGUgZ2xvYmFsIGxvZ2dlciBpbnN0YW5jZS5cbiAgICpcbiAgICogQHBhcmFtIG1zZyAtIFRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZC5cbiAgICogQHBhcmFtIHZlcmJvc2l0eSAtIFRoZSB2ZXJib3NpdHkgbGV2ZWwgb2YgdGhlIG1lc3NhZ2UgKGRlZmF1bHQ6IDApLlxuICAgKi9cbiAgc3RhdGljIHZlcmJvc2UobXNnOiBTdHJpbmdMaWtlLCB2ZXJib3NpdHk6IG51bWJlciA9IDApOiB2b2lkIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoKS52ZXJib3NlKG1zZywgdmVyYm9zaXR5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhbiBpbmZvIG1lc3NhZ2UuXG4gICAqIEBzdW1tYXJ5IERlbGVnYXRlcyB0aGUgaW5mbyBsb2dnaW5nIHRvIHRoZSBnbG9iYWwgbG9nZ2VyIGluc3RhbmNlLlxuICAgKlxuICAgKiBAcGFyYW0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkLlxuICAgKi9cbiAgc3RhdGljIGluZm8obXNnOiBTdHJpbmdMaWtlKTogdm9pZCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KCkuaW5mbyhtc2cpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMb2dzIGEgZGVidWcgbWVzc2FnZS5cbiAgICogQHN1bW1hcnkgRGVsZWdhdGVzIHRoZSBkZWJ1ZyBsb2dnaW5nIHRvIHRoZSBnbG9iYWwgbG9nZ2VyIGluc3RhbmNlLlxuICAgKlxuICAgKiBAcGFyYW0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkLlxuICAgKi9cbiAgc3RhdGljIGRlYnVnKG1zZzogU3RyaW5nTGlrZSk6IHZvaWQge1xuICAgIHJldHVybiB0aGlzLmdldCgpLmRlYnVnKG1zZyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYSBzaWxseSBtZXNzYWdlLlxuICAgKiBAc3VtbWFyeSBEZWxlZ2F0ZXMgdGhlIGRlYnVnIGxvZ2dpbmcgdG8gdGhlIGdsb2JhbCBsb2dnZXIgaW5zdGFuY2UuXG4gICAqXG4gICAqIEBwYXJhbSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWQuXG4gICAqL1xuICBzdGF0aWMgc2lsbHkobXNnOiBTdHJpbmdMaWtlKTogdm9pZCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KCkuc2lsbHkobXNnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhbiBlcnJvciBtZXNzYWdlLlxuICAgKiBAc3VtbWFyeSBEZWxlZ2F0ZXMgdGhlIGVycm9yIGxvZ2dpbmcgdG8gdGhlIGdsb2JhbCBsb2dnZXIgaW5zdGFuY2UuXG4gICAqXG4gICAqIEBwYXJhbSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWQuXG4gICAqIEBwYXJhbSBlXG4gICAqL1xuICBzdGF0aWMgZXJyb3IobXNnOiBTdHJpbmdMaWtlLCBlPzogRXJyb3IpOiB2b2lkIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoKS5lcnJvcihtc2csIGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgbG9nZ2VyIGZvciBhIHNwZWNpZmljIG9iamVjdCBvciBjb250ZXh0XG4gICAqIEBzdW1tYXJ5IENyZWF0ZXMgYSBuZXcgbG9nZ2VyIGluc3RhbmNlIGZvciB0aGUgZ2l2ZW4gb2JqZWN0IG9yIGNvbnRleHQgdXNpbmcgdGhlIGZhY3RvcnkgZnVuY3Rpb25cbiAgICogQHBhcmFtIHtMb2dnaW5nQ29udGV4dH0gb2JqZWN0IC0gVGhlIG9iamVjdCwgY2xhc3MsIG9yIGNvbnRleHQgdG8gY3JlYXRlIGEgbG9nZ2VyIGZvclxuICAgKiBAcGFyYW0ge1BhcnRpYWw8TG9nZ2luZ0NvbmZpZz59IFtjb25maWddIC0gT3B0aW9uYWwgY29uZmlndXJhdGlvbiB0byBvdmVycmlkZSBnbG9iYWwgc2V0dGluZ3NcbiAgICogQHBhcmFtIHsuLi5hbnl9IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBsb2dnZXIgZmFjdG9yeVxuICAgKiBAcmV0dXJuIHtMb2dnZXJ9IEEgbmV3IGxvZ2dlciBpbnN0YW5jZSBmb3IgdGhlIHNwZWNpZmllZCBvYmplY3Qgb3IgY29udGV4dFxuICAgKi9cbiAgc3RhdGljIGZvcihcbiAgICBvYmplY3Q6IExvZ2dpbmdDb250ZXh0LFxuICAgIGNvbmZpZz86IFBhcnRpYWw8TG9nZ2luZ0NvbmZpZz4sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogTG9nZ2VyIHtcbiAgICBvYmplY3QgPVxuICAgICAgdHlwZW9mIG9iamVjdCA9PT0gXCJzdHJpbmdcIlxuICAgICAgICA/IG9iamVjdFxuICAgICAgICA6IG9iamVjdC5jb25zdHJ1Y3RvclxuICAgICAgICAgID8gb2JqZWN0LmNvbnN0cnVjdG9yLm5hbWVcbiAgICAgICAgICA6IG9iamVjdC5uYW1lO1xuICAgIHJldHVybiB0aGlzLl9mYWN0b3J5KG9iamVjdCwgY29uZmlnLCAuLi5hcmdzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIGxvZ2dlciBmb3IgYSBzcGVjaWZpYyByZWFzb24gb3IgY29ycmVsYXRpb24gY29udGV4dFxuICAgKiBAc3VtbWFyeSBVdGlsaXR5IHRvIHF1aWNrbHkgY3JlYXRlIGEgbG9nZ2VyIGxhYmVsZWQgd2l0aCBhIGZyZWUtZm9ybSByZWFzb24gYW5kIG9wdGlvbmFsIGlkZW50aWZpZXJcbiAgICogc28gdGhhdCBhZC1ob2Mgb3BlcmF0aW9ucyBjYW4gYmUgdHJhY2VkIHdpdGhvdXQgdHlpbmcgdGhlIGxvZ2dlciB0byBhIGNsYXNzIG9yIG1ldGhvZCBuYW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcmVhc29uIC0gQSB0ZXh0dWFsIHJlYXNvbiBvciBjb250ZXh0IGxhYmVsIGZvciB0aGlzIGxvZ2dlciBpbnN0YW5jZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2lkXSAtIE9wdGlvbmFsIGlkZW50aWZpZXIgdG8gaGVscCBjb3JyZWxhdGUgcmVsYXRlZCBsb2cgZW50cmllc1xuICAgKiBAcmV0dXJuIHtMb2dnZXJ9IEEgbmV3IGxvZ2dlciBpbnN0YW5jZSBsYWJlbGVkIHdpdGggdGhlIHByb3ZpZGVkIHJlYXNvbiBhbmQgaWRcbiAgICovXG4gIHN0YXRpYyBiZWNhdXNlKHJlYXNvbjogc3RyaW5nLCBpZD86IHN0cmluZyk6IExvZ2dlciB7XG4gICAgcmV0dXJuIHRoaXMuX2ZhY3RvcnkocmVhc29uLCB0aGlzLl9jb25maWcsIGlkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQXBwbGllcyB0aGVtZSBzdHlsaW5nIHRvIHRleHRcbiAgICogQHN1bW1hcnkgQXBwbGllcyBzdHlsaW5nIChjb2xvcnMsIGZvcm1hdHRpbmcpIHRvIHRleHQgYmFzZWQgb24gdGhlIHRoZW1lIGNvbmZpZ3VyYXRpb25cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRleHQgLSBUaGUgdGV4dCB0byBzdHlsZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSAtIFRoZSB0eXBlIG9mIGVsZW1lbnQgdG8gc3R5bGUgKGUuZy4sIFwiY2xhc3NcIiwgXCJtZXNzYWdlXCIsIFwibG9nTGV2ZWxcIilcbiAgICogQHBhcmFtIHtMb2dMZXZlbH0gbG9nZ2VyTGV2ZWwgLSBUaGUgbG9nIGxldmVsIHRvIHVzZSBmb3Igc3R5bGluZ1xuICAgKiBAcGFyYW0ge1RoZW1lfSBbdGVtcGxhdGU9RGVmYXVsdFRoZW1lXSAtIFRoZSB0aGVtZSB0byB1c2UgZm9yIHN0eWxpbmdcbiAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgc3R5bGVkIHRleHRcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQ2FsbGVyXG4gICAqICAgcGFydGljaXBhbnQgVGhlbWUgYXMgTG9nZ2luZy50aGVtZVxuICAgKiAgIHBhcnRpY2lwYW50IEFwcGx5IGFzIGFwcGx5IGZ1bmN0aW9uXG4gICAqICAgcGFydGljaXBhbnQgU3R5bGUgYXMgc3R5bGVkLXN0cmluZy1idWlsZGVyXG4gICAqXG4gICAqICAgQ2FsbGVyLT4+VGhlbWU6IHRoZW1lKHRleHQsIHR5cGUsIGxvZ2dlckxldmVsKVxuICAgKiAgIFRoZW1lLT4+VGhlbWU6IENoZWNrIGlmIHN0eWxpbmcgaXMgZW5hYmxlZFxuICAgKiAgIGFsdCBzdHlsaW5nIGRpc2FibGVkXG4gICAqICAgICBUaGVtZS0tPj5DYWxsZXI6IHJldHVybiBvcmlnaW5hbCB0ZXh0XG4gICAqICAgZWxzZSBzdHlsaW5nIGVuYWJsZWRcbiAgICogICAgIFRoZW1lLT4+VGhlbWU6IEdldCB0aGVtZSBmb3IgdHlwZVxuICAgKiAgICAgYWx0IHRoZW1lIG5vdCBmb3VuZFxuICAgKiAgICAgICBUaGVtZS0tPj5DYWxsZXI6IHJldHVybiBvcmlnaW5hbCB0ZXh0XG4gICAqICAgICBlbHNlIHRoZW1lIGZvdW5kXG4gICAqICAgICAgIFRoZW1lLT4+VGhlbWU6IERldGVybWluZSBhY3R1YWwgdGhlbWUgYmFzZWQgb24gbG9nIGxldmVsXG4gICAqICAgICAgIFRoZW1lLT4+QXBwbHk6IEFwcGx5IGVhY2ggc3R5bGUgcHJvcGVydHlcbiAgICogICAgICAgQXBwbHktPj5TdHlsZTogQXBwbHkgY29sb3JzIGFuZCBmb3JtYXR0aW5nXG4gICAqICAgICAgIFN0eWxlLS0+PkFwcGx5OiBSZXR1cm4gc3R5bGVkIHRleHRcbiAgICogICAgICAgQXBwbHktLT4+VGhlbWU6IFJldHVybiBzdHlsZWQgdGV4dFxuICAgKiAgICAgICBUaGVtZS0tPj5DYWxsZXI6IFJldHVybiBmaW5hbCBzdHlsZWQgdGV4dFxuICAgKiAgICAgZW5kXG4gICAqICAgZW5kXG4gICAqL1xuICBzdGF0aWMgdGhlbWUoXG4gICAgdGV4dDogc3RyaW5nLFxuICAgIHR5cGU6IGtleW9mIFRoZW1lIHwga2V5b2YgTG9nTGV2ZWwsXG4gICAgbG9nZ2VyTGV2ZWw6IExvZ0xldmVsLFxuICAgIHRlbXBsYXRlOiBUaGVtZSA9IERlZmF1bHRUaGVtZVxuICApIHtcbiAgICBpZiAoIXRoaXMuX2NvbmZpZy5zdHlsZSkgcmV0dXJuIHRleHQ7XG4gICAgY29uc3QgbG9nZ2VyID0gTG9nZ2luZy5nZXQoKS5mb3IodGhpcy50aGVtZSk7XG5cbiAgICBmdW5jdGlvbiBhcHBseShcbiAgICAgIHR4dDogc3RyaW5nLFxuICAgICAgb3B0aW9uOiBrZXlvZiBUaGVtZU9wdGlvbixcbiAgICAgIHZhbHVlOiBudW1iZXIgfCBbbnVtYmVyXSB8IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSB8IG51bWJlcltdIHwgc3RyaW5nW11cbiAgICApOiBzdHJpbmcge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgdDogc3RyaW5nIHwgU3R5bGVkU3RyaW5nID0gdHh0O1xuICAgICAgICBsZXQgYyA9IHN0eWxlKHQpO1xuXG4gICAgICAgIGZ1bmN0aW9uIGFwcGx5Q29sb3IoXG4gICAgICAgICAgdmFsOiBudW1iZXIgfCBbbnVtYmVyXSB8IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgICAgICAgICBpc0JnID0gZmFsc2VcbiAgICAgICAgKTogU3R5bGVkU3RyaW5nIHtcbiAgICAgICAgICBsZXQgZjpcbiAgICAgICAgICAgIHwgdHlwZW9mIGMuYmFja2dyb3VuZFxuICAgICAgICAgICAgfCB0eXBlb2YgYy5mb3JlZ3JvdW5kXG4gICAgICAgICAgICB8IHR5cGVvZiBjLnJnYlxuICAgICAgICAgICAgfCB0eXBlb2YgYy5jb2xvcjI1NiA9IGlzQmcgPyBjLmJhY2tncm91bmQgOiBjLmZvcmVncm91bmQ7XG4gICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHZhbCkpIHtcbiAgICAgICAgICAgIHJldHVybiAoZiBhcyB0eXBlb2YgYy5iYWNrZ3JvdW5kIHwgdHlwZW9mIGMuZm9yZWdyb3VuZCkuY2FsbChcbiAgICAgICAgICAgICAgYyxcbiAgICAgICAgICAgICAgdmFsdWUgYXMgbnVtYmVyXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBzd2l0Y2ggKHZhbC5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgICAgZiA9IGlzQmcgPyBjLmJnQ29sb3IyNTYgOiBjLmNvbG9yMjU2O1xuICAgICAgICAgICAgICByZXR1cm4gKGYgYXMgdHlwZW9mIGMuYmdDb2xvcjI1NiB8IHR5cGVvZiBjLmNvbG9yMjU2KSh2YWxbMF0pO1xuICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICBmID0gaXNCZyA/IGMuYmdSZ2IgOiBjLnJnYjtcbiAgICAgICAgICAgICAgcmV0dXJuIGMucmdiKHZhbFswXSwgdmFsWzFdLCB2YWxbMl0pO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGBOb3QgYSB2YWxpZCBjb2xvciBvcHRpb246ICR7b3B0aW9ufWApO1xuICAgICAgICAgICAgICByZXR1cm4gc3R5bGUodCBhcyBzdHJpbmcpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGFwcGx5U3R5bGUodjogbnVtYmVyIHwgc3RyaW5nKTogdm9pZCB7XG4gICAgICAgICAgaWYgKHR5cGVvZiB2ID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICBjID0gYy5zdHlsZSh2KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYyA9IGNbdiBhcyBrZXlvZiBDb2xvcml6ZU9wdGlvbnNdIGFzIFN0eWxlZFN0cmluZztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBzd2l0Y2ggKG9wdGlvbikge1xuICAgICAgICAgIGNhc2UgXCJiZ1wiOlxuICAgICAgICAgIGNhc2UgXCJmZ1wiOlxuICAgICAgICAgICAgcmV0dXJuIGFwcGx5Q29sb3IodmFsdWUgYXMgbnVtYmVyKS50ZXh0O1xuICAgICAgICAgIGNhc2UgXCJzdHlsZVwiOlxuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICAgIHZhbHVlLmZvckVhY2goYXBwbHlTdHlsZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBhcHBseVN0eWxlKHZhbHVlIGFzIG51bWJlciB8IHN0cmluZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gYy50ZXh0O1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoYE5vdCBhIHZhbGlkIHRoZW1lIG9wdGlvbjogJHtvcHRpb259YCk7XG4gICAgICAgICAgICByZXR1cm4gdDtcbiAgICAgICAgfVxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICAgIGxvZ2dlci5lcnJvcihgRXJyb3IgYXBwbHlpbmcgc3R5bGU6ICR7b3B0aW9ufSB3aXRoIHZhbHVlICR7dmFsdWV9YCk7XG4gICAgICAgIHJldHVybiB0eHQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgaW5kaXZpZHVhbFRoZW1lID0gdGVtcGxhdGVbdHlwZSBhcyBrZXlvZiBUaGVtZV07XG4gICAgaWYgKCFpbmRpdmlkdWFsVGhlbWUgfHwgIU9iamVjdC5rZXlzKGluZGl2aWR1YWxUaGVtZSkubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gdGV4dDtcbiAgICB9XG5cbiAgICBsZXQgYWN0dWFsVGhlbWU6IFRoZW1lT3B0aW9uID0gaW5kaXZpZHVhbFRoZW1lIGFzIFRoZW1lT3B0aW9uO1xuXG4gICAgY29uc3QgbG9nTGV2ZWxzID0gT2JqZWN0LmFzc2lnbih7fSwgTG9nTGV2ZWwpO1xuICAgIGlmIChPYmplY3Qua2V5cyhpbmRpdmlkdWFsVGhlbWUpWzBdIGluIGxvZ0xldmVscylcbiAgICAgIGFjdHVhbFRoZW1lID1cbiAgICAgICAgKGluZGl2aWR1YWxUaGVtZSBhcyBUaGVtZU9wdGlvbkJ5TG9nTGV2ZWwpW2xvZ2dlckxldmVsXSB8fCB7fTtcblxuICAgIHJldHVybiBPYmplY3Qua2V5cyhhY3R1YWxUaGVtZSkucmVkdWNlKChhY2M6IHN0cmluZywga2V5OiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IHZhbCA9IChhY3R1YWxUaGVtZSBhcyBUaGVtZU9wdGlvbilba2V5IGFzIGtleW9mIFRoZW1lT3B0aW9uXTtcbiAgICAgIGlmICh2YWwpXG4gICAgICAgIHJldHVybiBhcHBseShcbiAgICAgICAgICBhY2MsXG4gICAgICAgICAga2V5IGFzIGtleW9mIFRoZW1lT3B0aW9uLFxuICAgICAgICAgIHZhbCBhc1xuICAgICAgICAgICAgfCBudW1iZXJcbiAgICAgICAgICAgIHwgW251bWJlcl1cbiAgICAgICAgICAgIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXJdXG4gICAgICAgICAgICB8IG51bWJlcltdXG4gICAgICAgICAgICB8IHN0cmluZ1tdXG4gICAgICAgICk7XG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sIHRleHQpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBMb2dnaW5nIH0gZnJvbSBcIi4vbG9nZ2luZ1wiO1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQmFzZSBjbGFzcyB0aGF0IHByb3ZpZGVzIGEgcmVhZHktdG8tdXNlIGxvZ2dlciBpbnN0YW5jZVxuICogQHN1bW1hcnkgTG9nZ2VkQ2xhc3MgaXMgYSBjb252ZW5pZW5jZSBhYnN0cmFjdCBjbGFzcyB0aGF0IGluamVjdHMgYSB0eXBlLXNhZmUgbG9nZ2VyXG4gKiBpbnRvIGRlcml2ZWQgY2xhc3NlcyB0aHJvdWdoIGEgcHJvdGVjdGVkIGdldHRlci4gU3ViY2xhc3NlcyBjYW4gZGlyZWN0bHkgYWNjZXNzXG4gKiB0aGlzLmxvZyB0byBlbWl0IG1lc3NhZ2VzIHdpdGhvdXQgbWFudWFsbHkgY3JlYXRpbmcgYSBsb2dnZXIuIFRoaXMgcHJvbW90ZXNcbiAqIGNvbnNpc3RlbnQsIGNvbnRleHQtYXdhcmUgbG9nZ2luZyBhY3Jvc3MgdGhlIGNvZGViYXNlLlxuICogQHBhcmFtIHt2b2lkfSBbY29uc3RydWN0b3JdIC0gTm8gY29uc3RydWN0b3IgYXJndW1lbnRzOyBzdWJjbGFzc2VzIG1heSBkZWZpbmUgdGhlaXIgb3duXG4gKiBAY2xhc3MgTG9nZ2VkQ2xhc3NcbiAqIEBleGFtcGxlXG4gKiBjbGFzcyBVc2VyU2VydmljZSBleHRlbmRzIExvZ2dlZENsYXNzIHtcbiAqICAgY3JlYXRlKHVzZXI6IFVzZXIpIHtcbiAqICAgICB0aGlzLmxvZy5pbmZvKGBDcmVhdGluZyB1c2VyICR7dXNlci5pZH1gKTtcbiAqICAgfVxuICogfVxuICpcbiAqIGNvbnN0IHN2YyA9IG5ldyBVc2VyU2VydmljZSgpO1xuICogc3ZjLmNyZWF0ZSh7IGlkOiBcIjQyXCIgfSk7XG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICogICBwYXJ0aWNpcGFudCBJbnN0YW5jZSBhcyBTdWJjbGFzcyBJbnN0YW5jZVxuICogICBwYXJ0aWNpcGFudCBHZXR0ZXIgYXMgTG9nZ2VkQ2xhc3MubG9nXG4gKiAgIHBhcnRpY2lwYW50IExvZ2dpbmcgYXMgTG9nZ2luZ1xuICogICBwYXJ0aWNpcGFudCBMb2dnZXIgYXMgTG9nZ2VyXG4gKlxuICogICBDbGllbnQtPj5JbnN0YW5jZTogY2FsbCBzb21lTWV0aG9kKClcbiAqICAgSW5zdGFuY2UtPj5HZXR0ZXI6IGFjY2VzcyB0aGlzLmxvZ1xuICogICBHZXR0ZXItPj5Mb2dnaW5nOiBMb2dnaW5nLmZvcih0aGlzKVxuICogICBMb2dnaW5nLS0+PkdldHRlcjogcmV0dXJuIExvZ2dlclxuICogICBHZXR0ZXItLT4+SW5zdGFuY2U6IHJldHVybiBMb2dnZXJcbiAqICAgSW5zdGFuY2UtPj5Mb2dnZXI6IGluZm8vZGVidWcvZXJyb3IoLi4uKVxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgTG9nZ2VkQ2xhc3Mge1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExhemlseSBwcm92aWRlcyBhIGNvbnRleHQtYXdhcmUgbG9nZ2VyIGZvciB0aGUgY3VycmVudCBpbnN0YW5jZVxuICAgKiBAc3VtbWFyeSBVc2VzIExvZ2dpbmcuZm9yKHRoaXMpIHRvIGNyZWF0ZSBhIGxvZ2dlciB3aG9zZSBjb250ZXh0IGlzIHRoZVxuICAgKiBzdWJjbGFzcyBuYW1lLCBhbGxvd2luZyB1bmlmb3JtIGFuZCBzdHJ1Y3R1cmVkIGxvZ3MgZnJvbSBhbnkgaW5oZXJpdGluZyBjbGFzcy5cbiAgICogQHJldHVybiB7TG9nZ2VyfSBBIGxvZ2dlciBib3VuZCB0byB0aGUgc3ViY2xhc3MgY29udGV4dFxuICAgKi9cbiAgcHJvdGVjdGVkIGdldCBsb2coKTogTG9nZ2VyIHtcbiAgICByZXR1cm4gTG9nZ2luZy5mb3IodGhpcyBhcyBhbnkpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKCkge31cbn1cbiIsImltcG9ydCB7IExvZ2dlciwgTG9nZ2luZ0NvbmZpZywgTG9nZ2luZ0ZpbHRlciB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgTG9nZ2VkQ2xhc3MgfSBmcm9tIFwiLi4vTG9nZ2VkQ2xhc3NcIjtcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIExvZ0ZpbHRlciBleHRlbmRzIExvZ2dlZENsYXNzIGltcGxlbWVudHMgTG9nZ2luZ0ZpbHRlciB7XG4gIG92ZXJyaWRlIGdldCBsb2coKTogTG9nZ2VyIHtcbiAgICByZXR1cm4gc3VwZXIubG9nLmZvcih0aGlzIGFzIGFueSwgeyBmaWx0ZXJzOiBbXSB9KTtcbiAgfVxuXG4gIGFic3RyYWN0IGZpbHRlcihcbiAgICBjb25maWc6IExvZ2dpbmdDb25maWcsXG4gICAgbWVzc2FnZTogc3RyaW5nLFxuICAgIGNvbnRleHQ6IHN0cmluZ1tdXG4gICk6IHN0cmluZztcbn1cbiIsImltcG9ydCB7IExvZ0xldmVsIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBMb2dnaW5nIH0gZnJvbSBcIi4vbG9nZ2luZ1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBNZXRob2QgZGVjb3JhdG9yIGZvciBsb2dnaW5nIGZ1bmN0aW9uIGNhbGxzXG4gKiBAc3VtbWFyeSBDcmVhdGVzIGEgZGVjb3JhdG9yIHRoYXQgbG9ncyBtZXRob2QgY2FsbHMgd2l0aCBzcGVjaWZpZWQgbGV2ZWwsIGJlbmNobWFya2luZywgYW5kIHZlcmJvc2l0eVxuICogQHBhcmFtIHtMb2dMZXZlbH0gbGV2ZWwgLSBUaGUgbG9nIGxldmVsIHRvIHVzZSAoZGVmYXVsdDogTG9nTGV2ZWwuaW5mbylcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2JlbmNobWFyaz1mYWxzZV0gLSBXaGV0aGVyIHRvIGxvZyBleGVjdXRpb24gdGltZSAoZGVmYXVsdDogZmFsc2UpXG4gKiBAcGFyYW0ge251bWJlcn0gW3ZlcmJvc2l0eT0wXSAtIFRoZSB2ZXJib3NpdHkgbGV2ZWwgZm9yIHRoZSBsb2cgbWVzc2FnZXMgKGRlZmF1bHQ6IDApXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBtZXRob2QgZGVjb3JhdG9yIHRoYXQgd3JhcHMgdGhlIG9yaWdpbmFsIG1ldGhvZCB3aXRoIGxvZ2dpbmdcbiAqIEBmdW5jdGlvbiBsb2dcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2xpZW50XG4gKiAgIHBhcnRpY2lwYW50IERlY29yYXRvciBhcyBsb2cgZGVjb3JhdG9yXG4gKiAgIHBhcnRpY2lwYW50IE1ldGhvZCBhcyBPcmlnaW5hbCBNZXRob2RcbiAqICAgcGFydGljaXBhbnQgTG9nZ2VyIGFzIExvZ2dpbmcgaW5zdGFuY2VcbiAqXG4gKiAgIENsaWVudC0+PkRlY29yYXRvcjogY2FsbCBkZWNvcmF0ZWQgbWV0aG9kXG4gKiAgIERlY29yYXRvci0+PkxvZ2dlcjogbG9nIG1ldGhvZCBjYWxsXG4gKiAgIERlY29yYXRvci0+Pk1ldGhvZDogY2FsbCBvcmlnaW5hbCBtZXRob2RcbiAqICAgYWx0IHJlc3VsdCBpcyBQcm9taXNlXG4gKiAgICAgTWV0aG9kLS0+PkRlY29yYXRvcjogcmV0dXJuIFByb21pc2VcbiAqICAgICBEZWNvcmF0b3ItPj5EZWNvcmF0b3I6IGF0dGFjaCB0aGVuIGhhbmRsZXJcbiAqICAgICBOb3RlIG92ZXIgRGVjb3JhdG9yOiBQcm9taXNlIHJlc29sdmVzXG4gKiAgICAgRGVjb3JhdG9yLT4+TG9nZ2VyOiBsb2cgYmVuY2htYXJrIChpZiBlbmFibGVkKVxuICogICAgIERlY29yYXRvci0tPj5DbGllbnQ6IHJldHVybiByZXN1bHRcbiAqICAgZWxzZSByZXN1bHQgaXMgbm90IFByb21pc2VcbiAqICAgICBNZXRob2QtLT4+RGVjb3JhdG9yOiByZXR1cm4gcmVzdWx0XG4gKiAgICAgRGVjb3JhdG9yLT4+TG9nZ2VyOiBsb2cgYmVuY2htYXJrIChpZiBlbmFibGVkKVxuICogICAgIERlY29yYXRvci0tPj5DbGllbnQ6IHJldHVybiByZXN1bHRcbiAqICAgZW5kXG4gKiBAY2F0ZWdvcnkgTWV0aG9kIERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxvZyhcbiAgbGV2ZWw6IExvZ0xldmVsID0gTG9nTGV2ZWwuaW5mbyxcbiAgYmVuY2htYXJrOiBib29sZWFuID0gZmFsc2UsXG4gIHZlcmJvc2l0eSA9IDBcbikge1xuICByZXR1cm4gZnVuY3Rpb24gKFxuICAgIHRhcmdldDogYW55LFxuICAgIHByb3BlcnR5S2V5PzogYW55LFxuICAgIGRlc2NyaXB0b3I/OiBQcm9wZXJ0eURlc2NyaXB0b3JcbiAgKSB7XG4gICAgaWYgKCFkZXNjcmlwdG9yKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBMb2dnaW5nIGRlY29yYXRpb24gb25seSBhcHBsaWVzIHRvIG1ldGhvZHNgKTtcbiAgICBjb25zdCBsb2dnZXIgPSBMb2dnaW5nLmZvcih0YXJnZXQpLmZvcih0YXJnZXRbcHJvcGVydHlLZXldKTtcbiAgICBjb25zdCBtZXRob2QgPSBsb2dnZXJbbGV2ZWxdLmJpbmQobG9nZ2VyKSBhcyBhbnk7XG4gICAgY29uc3Qgb3JpZ2luYWxNZXRob2QgPSBkZXNjcmlwdG9yLnZhbHVlO1xuXG4gICAgZGVzY3JpcHRvci52YWx1ZSA9IG5ldyBQcm94eShvcmlnaW5hbE1ldGhvZCwge1xuICAgICAgYXBwbHkoZm4sIHRoaXNBcmcsIGFyZ3M6IGFueVtdKSB7XG4gICAgICAgIG1ldGhvZChgY2FsbGVkIHdpdGggJHthcmdzfWAsIHZlcmJvc2l0eSk7XG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBSZWZsZWN0LmFwcGx5KGZuLCB0aGlzQXJnLCBhcmdzKTtcbiAgICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC50aGVuKChyOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgaWYgKGJlbmNobWFyaylcbiAgICAgICAgICAgICAgICBtZXRob2QoYGNvbXBsZXRlZCBpbiAke0RhdGUubm93KCkgLSBzdGFydH1tc2AsIHZlcmJvc2l0eSk7XG4gICAgICAgICAgICAgIHJldHVybiByO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChiZW5jaG1hcmspXG4gICAgICAgICAgICBtZXRob2QoYGNvbXBsZXRlZCBpbiAke0RhdGUubm93KCkgLSBzdGFydH1tc2AsIHZlcmJvc2l0eSk7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgaWYgKGJlbmNobWFyaykgbWV0aG9kKGBmYWlsZWQgaW4gJHtEYXRlLm5vdygpIC0gc3RhcnR9bXNgLCB2ZXJib3NpdHkpO1xuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9KTtcbiAgfTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gTWV0aG9kIGRlY29yYXRvciBmb3IgbG9nZ2luZyBmdW5jdGlvbiBjYWxscyB3aXRoIGRlYnVnIGxldmVsXG4gKiBAc3VtbWFyeSBDb252ZW5pZW5jZSB3cmFwcGVyIGFyb3VuZCB0aGUgbG9nIGRlY29yYXRvciB0aGF0IHVzZXMgTG9nTGV2ZWwuZGVidWdcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2JlbmNobWFyaz1mYWxzZV0gLSBXaGV0aGVyIHRvIGxvZyBleGVjdXRpb24gdGltZSAoZGVmYXVsdDogZmFsc2UpXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBtZXRob2QgZGVjb3JhdG9yIHRoYXQgd3JhcHMgdGhlIG9yaWdpbmFsIG1ldGhvZCB3aXRoIGRlYnVnIGxvZ2dpbmdcbiAqIEBmdW5jdGlvbiBkZWJ1Z1xuICogQGNhdGVnb3J5IE1ldGhvZCBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWJ1ZyhiZW5jaG1hcms6IGJvb2xlYW4gPSBmYWxzZSkge1xuICByZXR1cm4gbG9nKExvZ0xldmVsLmRlYnVnLCBiZW5jaG1hcmspO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBNZXRob2QgZGVjb3JhdG9yIGZvciBsb2dnaW5nIGZ1bmN0aW9uIGNhbGxzIHdpdGggaW5mbyBsZXZlbFxuICogQHN1bW1hcnkgQ29udmVuaWVuY2Ugd3JhcHBlciBhcm91bmQgdGhlIGxvZyBkZWNvcmF0b3IgdGhhdCB1c2VzIExvZ0xldmVsLmluZm9cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2JlbmNobWFyaz1mYWxzZV0gLSBXaGV0aGVyIHRvIGxvZyBleGVjdXRpb24gdGltZSAoZGVmYXVsdDogZmFsc2UpXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBtZXRob2QgZGVjb3JhdG9yIHRoYXQgd3JhcHMgdGhlIG9yaWdpbmFsIG1ldGhvZCB3aXRoIGluZm8gbG9nZ2luZ1xuICogQGZ1bmN0aW9uIGluZm9cbiAqIEBjYXRlZ29yeSBNZXRob2QgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gaW5mbyhiZW5jaG1hcms6IGJvb2xlYW4gPSBmYWxzZSkge1xuICByZXR1cm4gbG9nKExvZ0xldmVsLmluZm8sIGJlbmNobWFyayk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE1ldGhvZCBkZWNvcmF0b3IgZm9yIGxvZ2dpbmcgZnVuY3Rpb24gY2FsbHMgd2l0aCBzaWxseSBsZXZlbFxuICogQHN1bW1hcnkgQ29udmVuaWVuY2Ugd3JhcHBlciBhcm91bmQgdGhlIGxvZyBkZWNvcmF0b3IgdGhhdCB1c2VzIExvZ0xldmVsLnNpbGx5XG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtiZW5jaG1hcms9ZmFsc2VdIC0gV2hldGhlciB0byBsb2cgZXhlY3V0aW9uIHRpbWUgKGRlZmF1bHQ6IGZhbHNlKVxuICogQHJldHVybiB7RnVuY3Rpb259IEEgbWV0aG9kIGRlY29yYXRvciB0aGF0IHdyYXBzIHRoZSBvcmlnaW5hbCBtZXRob2Qgd2l0aCBzaWxseSBsb2dnaW5nXG4gKiBAZnVuY3Rpb24gc2lsbHlcbiAqIEBjYXRlZ29yeSBNZXRob2QgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gc2lsbHkoYmVuY2htYXJrOiBib29sZWFuID0gZmFsc2UpIHtcbiAgcmV0dXJuIGxvZyhMb2dMZXZlbC5zaWxseSwgYmVuY2htYXJrKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gTWV0aG9kIGRlY29yYXRvciBmb3IgbG9nZ2luZyBmdW5jdGlvbiBjYWxscyB3aXRoIHZlcmJvc2UgbGV2ZWxcbiAqIEBzdW1tYXJ5IENvbnZlbmllbmNlIHdyYXBwZXIgYXJvdW5kIHRoZSBsb2cgZGVjb3JhdG9yIHRoYXQgdXNlcyBMb2dMZXZlbC52ZXJib3NlIHdpdGggY29uZmlndXJhYmxlIHZlcmJvc2l0eVxuICogQHJldHVybiB7RnVuY3Rpb259IEEgbWV0aG9kIGRlY29yYXRvciB0aGF0IHdyYXBzIHRoZSBvcmlnaW5hbCBtZXRob2Qgd2l0aCB2ZXJib3NlIGxvZ2dpbmdcbiAqIEBmdW5jdGlvbiB2ZXJib3NlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZXJib3NlKCk6IChcbiAgdGFyZ2V0OiBhbnksXG4gIHByb3BlcnR5S2V5PzogYW55LFxuICBkZXNjcmlwdG9yPzogYW55XG4pID0+IHZvaWQ7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE1ldGhvZCBkZWNvcmF0b3IgZm9yIGxvZ2dpbmcgZnVuY3Rpb24gY2FsbHMgd2l0aCB2ZXJib3NlIGxldmVsXG4gKiBAc3VtbWFyeSBDb252ZW5pZW5jZSB3cmFwcGVyIGFyb3VuZCB0aGUgbG9nIGRlY29yYXRvciB0aGF0IHVzZXMgTG9nTGV2ZWwudmVyYm9zZSB3aXRoIGNvbmZpZ3VyYWJsZSB2ZXJib3NpdHlcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gYmVuY2htYXJrIC0gV2hldGhlciB0byBsb2cgZXhlY3V0aW9uIHRpbWVcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIG1ldGhvZCBkZWNvcmF0b3IgdGhhdCB3cmFwcyB0aGUgb3JpZ2luYWwgbWV0aG9kIHdpdGggdmVyYm9zZSBsb2dnaW5nXG4gKiBAZnVuY3Rpb24gdmVyYm9zZVxuICovXG5leHBvcnQgZnVuY3Rpb24gdmVyYm9zZShcbiAgYmVuY2htYXJrOiBib29sZWFuXG4pOiAodGFyZ2V0OiBhbnksIHByb3BlcnR5S2V5PzogYW55LCBkZXNjcmlwdG9yPzogYW55KSA9PiB2b2lkO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBNZXRob2QgZGVjb3JhdG9yIGZvciBsb2dnaW5nIGZ1bmN0aW9uIGNhbGxzIHdpdGggdmVyYm9zZSBsZXZlbFxuICogQHN1bW1hcnkgQ29udmVuaWVuY2Ugd3JhcHBlciBhcm91bmQgdGhlIGxvZyBkZWNvcmF0b3IgdGhhdCB1c2VzIExvZ0xldmVsLnZlcmJvc2Ugd2l0aCBjb25maWd1cmFibGUgdmVyYm9zaXR5XG4gKiBAcGFyYW0ge251bWJlcn0gdmVyYm9zaXR5IC0gVGhlIHZlcmJvc2l0eSBsZXZlbCBmb3IgdGhlIGxvZyBtZXNzYWdlcyAoZGVmYXVsdDogMClcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIG1ldGhvZCBkZWNvcmF0b3IgdGhhdCB3cmFwcyB0aGUgb3JpZ2luYWwgbWV0aG9kIHdpdGggdmVyYm9zZSBsb2dnaW5nXG4gKiBAZnVuY3Rpb24gdmVyYm9zZVxuICogQGNhdGVnb3J5IE1ldGhvZCBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZXJib3NlKFxuICB2ZXJib3NpdHk6IG51bWJlciB8IGJvb2xlYW5cbik6ICh0YXJnZXQ6IGFueSwgcHJvcGVydHlLZXk/OiBhbnksIGRlc2NyaXB0b3I/OiBhbnkpID0+IHZvaWQ7XG4vKipcbiAqIEBkZXNjcmlwdGlvbiBNZXRob2QgZGVjb3JhdG9yIGZvciBsb2dnaW5nIGZ1bmN0aW9uIGNhbGxzIHdpdGggdmVyYm9zZSBsZXZlbFxuICogQHN1bW1hcnkgQ29udmVuaWVuY2Ugd3JhcHBlciBhcm91bmQgdGhlIGxvZyBkZWNvcmF0b3IgdGhhdCB1c2VzIExvZ0xldmVsLnZlcmJvc2Ugd2l0aCBjb25maWd1cmFibGUgdmVyYm9zaXR5XG4gKiBAcGFyYW0ge251bWJlcn0gdmVyYm9zaXR5IC0gVGhlIHZlcmJvc2l0eSBsZXZlbCBmb3IgdGhlIGxvZyBtZXNzYWdlcyAoZGVmYXVsdDogMClcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2JlbmNobWFyaz1mYWxzZV0gLSBXaGV0aGVyIHRvIGxvZyBleGVjdXRpb24gdGltZSAoZGVmYXVsdDogZmFsc2UpXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBtZXRob2QgZGVjb3JhdG9yIHRoYXQgd3JhcHMgdGhlIG9yaWdpbmFsIG1ldGhvZCB3aXRoIHZlcmJvc2UgbG9nZ2luZ1xuICogQGZ1bmN0aW9uIHZlcmJvc2VcbiAqIEBjYXRlZ29yeSBNZXRob2QgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gdmVyYm9zZSh2ZXJib3NpdHk6IG51bWJlciB8IGJvb2xlYW4gPSAwLCBiZW5jaG1hcms/OiBib29sZWFuKSB7XG4gIGlmICh0eXBlb2YgdmVyYm9zaXR5ID09PSBcImJvb2xlYW5cIikge1xuICAgIGJlbmNobWFyayA9IHZlcmJvc2l0eTtcbiAgICB2ZXJib3NpdHkgPSAwO1xuICB9XG4gIHJldHVybiBsb2coTG9nTGV2ZWwudmVyYm9zZSwgYmVuY2htYXJrLCB2ZXJib3NpdHkpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgZGVjb3JhdG9yIHRoYXQgbWFrZXMgYSBtZXRob2Qgbm9uLWNvbmZpZ3VyYWJsZVxuICogQHN1bW1hcnkgVGhpcyBkZWNvcmF0b3IgcHJldmVudHMgYSBtZXRob2QgZnJvbSBiZWluZyBvdmVycmlkZGVuIGJ5IG1ha2luZyBpdCBub24tY29uZmlndXJhYmxlLlxuICogSXQgdGhyb3dzIGFuIGVycm9yIGlmIHVzZWQgb24gYW55dGhpbmcgb3RoZXIgdGhhbiBhIG1ldGhvZC5cbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIGRlY29yYXRvciBmdW5jdGlvbiB0aGF0IGNhbiBiZSBhcHBsaWVkIHRvIG1ldGhvZHNcbiAqIEBmdW5jdGlvbiBmaW5hbFxuICogQGNhdGVnb3J5IE1ldGhvZCBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5hbCgpIHtcbiAgcmV0dXJuIChcbiAgICB0YXJnZXQ6IG9iamVjdCxcbiAgICBwcm9wZXJ0eUtleT86IGFueSxcbiAgICBkZXNjcmlwdG9yPzogUHJvcGVydHlEZXNjcmlwdG9yXG4gICkgPT4ge1xuICAgIGlmICghZGVzY3JpcHRvcilcbiAgICAgIHRocm93IG5ldyBFcnJvcihcImZpbmFsIGRlY29yYXRvciBjYW4gb25seSBiZSB1c2VkIG9uIG1ldGhvZHNcIik7XG4gICAgaWYgKGRlc2NyaXB0b3I/LmNvbmZpZ3VyYWJsZSkge1xuICAgICAgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIGRlc2NyaXB0b3I7XG4gIH07XG59XG4iLCJpbXBvcnQgeyBMb2dGaWx0ZXIgfSBmcm9tIFwiLi9Mb2dGaWx0ZXJcIjtcbmltcG9ydCB7IExvZ2dpbmdDb25maWcgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IGZpbmFsIH0gZnJvbSBcIi4uL2RlY29yYXRvcnNcIjtcblxuZXhwb3J0IHR5cGUgUmVwbGFjZW1lbnRGdW5jdGlvbiA9IChzdWJzdHJpbmc6IHN0cmluZywgLi4uYXJnczogYW55W10pID0+IHN0cmluZztcblxuZXhwb3J0IGNsYXNzIFBhdHRlcm5GaWx0ZXIgZXh0ZW5kcyBMb2dGaWx0ZXIge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgcmVnZXhwOiBSZWdFeHAsXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IHJlcGxhY2VtZW50OiBzdHJpbmcgfCBSZXBsYWNlbWVudEZ1bmN0aW9uXG4gICkge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICBAZmluYWwoKVxuICBwcm90ZWN0ZWQgbWF0Y2gobWVzc2FnZTogc3RyaW5nKSB7XG4gICAgY29uc3QgbWF0Y2ggPSB0aGlzLnJlZ2V4cC5leGVjKG1lc3NhZ2UpO1xuICAgIHRoaXMucmVnZXhwLmxhc3RJbmRleCA9IDA7XG4gICAgcmV0dXJuIG1hdGNoO1xuICB9XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBmaWx0ZXIoY29uZmlnOiBMb2dnaW5nQ29uZmlnLCBtZXNzYWdlOiBzdHJpbmcsIGNvbnRleHQ6IHN0cmluZ1tdKTogc3RyaW5nIHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5maWx0ZXIpO1xuICAgIGNvbnN0IG1hdGNoID0gdGhpcy5tYXRjaChtZXNzYWdlKTtcbiAgICBpZiAoIW1hdGNoKSByZXR1cm4gbWVzc2FnZTtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIG1lc3NhZ2UucmVwbGFjZSh0aGlzLnJlZ2V4cCwgdGhpcy5yZXBsYWNlbWVudCBhcyBhbnkpO1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIGxvZy5lcnJvcihgUGF0dGVybkZpbHRlciByZXBsYWNlbWVudCBlcnJvcjogJHtlfWApO1xuICAgIH1cbiAgICByZXR1cm4gXCJcIjtcbiAgfVxufVxuIiwiZXhwb3J0ICogZnJvbSBcIi4vZmlsdGVyc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9lbnZpcm9ubWVudFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vTG9nZ2VkQ2xhc3NcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2xvZ2dpbmdcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3RleHRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3R5cGVzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi93ZWJcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQSBsb2dnaW5nIG1vZHVsZSBmb3IgVHlwZVNjcmlwdCBhcHBsaWNhdGlvbnNcbiAqIEBzdW1tYXJ5IFByb3ZpZGVzIGEgY29tcHJlaGVuc2l2ZSwgZmxleGlibGUgbG9nZ2luZyBzb2x1dGlvbi4gVGhpcyBtb2R1bGUgZXhwb3NlczpcbiAqIC0gQ29yZSBjbGFzc2VzIGxpa2Uge0BsaW5rIExvZ2dpbmd9IGFuZCB7QGxpbmsgTWluaUxvZ2dlcn1cbiAqIC0gRGVjb3JhdG9ycyBzdWNoIGFzIHtAbGluayBsb2d9IGZvciBpbnN0cnVtZW50aW5nIG1ldGhvZHNcbiAqIC0gQ29uZmlndXJhdGlvbiBhbmQgY29uc3RhbnRzIGxpa2Uge0BsaW5rIExvZ0xldmVsfSBhbmQge0BsaW5rIERlZmF1bHRMb2dnaW5nQ29uZmlnfVxuICogLSBUeXBlIGRlZmluaXRpb25zIGluY2x1ZGluZyB7QGxpbmsgTG9nZ2VyfSBhbmQge0BsaW5rIExvZ2dpbmdDb25maWd9XG4gKiBUaGVzZSBleHBvcnRzIGVuYWJsZSBjb25zaXN0ZW50LCBjb250ZXh0LWF3YXJlLCBhbmQgb3B0aW9uYWxseSB0aGVtZWQgbG9nZ2luZyBhY3Jvc3MgcHJvamVjdHMuXG4gKiBAbW9kdWxlIExvZ2dpbmdcbiAqL1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDdXJyZW50IHBhY2thZ2UgdmVyc2lvbiBzdHJpbmdcbiAqIEBzdW1tYXJ5IFN0b3JlcyB0aGUgY3VycmVudCBwYWNrYWdlIHZlcnNpb24sIHVzZWQgZm9yIHZlcnNpb24gdHJhY2tpbmcgYW5kIGNvbXBhdGliaWxpdHkgY2hlY2tzXG4gKiBAY29uc3QgVkVSU0lPTlxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBjb25zdCBWRVJTSU9OID0gXCIjI1ZFUlNJT04jI1wiO1xuIl0sIm5hbWVzIjpbIkxvZ0xldmVsIiwiTG9nZ2luZ01vZGUiLCJPYmplY3RBY2N1bXVsYXRvciIsInN0eWxlIiwiX19kZWNvcmF0ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBRU8sVUFBTSxhQUFhLEdBQUc7SUFFN0I7OztJQUdHO0FBQ0ksVUFBTSxrQkFBa0IsR0FBRztVQUVyQiwwQkFBMEIsR0FBRyxDQUFDLElBQUksRUFBRSxHQUFHO0lBRXBEOzs7Ozs7SUFNRztBQUNTQTtJQUFaLENBQUEsVUFBWSxRQUFRLEVBQUE7O0lBRWxCLElBQUEsUUFBQSxDQUFBLE9BQUEsQ0FBQSxHQUFBLE9BQWU7O0lBRWYsSUFBQSxRQUFBLENBQUEsTUFBQSxDQUFBLEdBQUEsTUFBYTs7SUFFYixJQUFBLFFBQUEsQ0FBQSxTQUFBLENBQUEsR0FBQSxTQUFtQjs7SUFFbkIsSUFBQSxRQUFBLENBQUEsT0FBQSxDQUFBLEdBQUEsT0FBZTs7SUFFZixJQUFBLFFBQUEsQ0FBQSxPQUFBLENBQUEsR0FBQSxPQUFlO0lBQ2pCLENBQUMsRUFYV0EsZ0JBQVEsS0FBUkEsZ0JBQVEsR0FXbkIsRUFBQSxDQUFBLENBQUE7SUFFRDs7Ozs7Ozs7OztJQVVHO0FBQ1UsVUFBQSxnQkFBZ0IsR0FBRztJQUM5QixJQUFBLEtBQUssRUFBRSxDQUFDO0lB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
|
|
1836
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2luZy5janMiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb25zdGFudHMudHMiLCIuLi9zcmMvdGV4dC50cyIsIi4uL3NyYy93ZWIudHMiLCIuLi9zcmMvZW52aXJvbm1lbnQudHMiLCIuLi9zcmMvbG9nZ2luZy50cyIsIi4uL3NyYy9Mb2dnZWRDbGFzcy50cyIsIi4uL3NyYy9maWx0ZXJzL0xvZ0ZpbHRlci50cyIsIi4uL3NyYy90aW1lLnRzIiwiLi4vc3JjL2RlY29yYXRvcnMudHMiLCIuLi9zcmMvZmlsdGVycy9QYXR0ZXJuRmlsdGVyLnRzIiwiLi4vc3JjL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IExvZ2dpbmdDb25maWcsIFRoZW1lIH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gR2xvYmFsIGtleSB1c2VkIHRvIHN0b3JlIGVudmlyb25tZW50IHZhcmlhYmxlcyBpbiBicm93c2VyIGNvbnRleHRzLlxuICogQHN1bW1hcnkgRW5hYmxlcyB0aGUgbG9nZ2luZyBlbnZpcm9ubWVudCBoZWxwZXJzIHRvIGxvY2F0ZSBzZXJpYWxpemVkIGVudmlyb25tZW50IGNvbmZpZ3VyYXRpb24gb24gYGdsb2JhbFRoaXNgLlxuICogQGNvbnN0IEJyb3dzZXJFbnZLZXlcbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGNvbnN0IEJyb3dzZXJFbnZLZXkgPSBcIkVOVlwiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWxpbWl0ZXIgdXNlZCBmb3IgY29tcG9zaW5nIG5lc3RlZCBlbnZpcm9ubWVudCB2YXJpYWJsZSBuYW1lcy5cbiAqIEBzdW1tYXJ5IEpvaW5zIHBhcmVudCBhbmQgY2hpbGQga2V5cyB3aGVuIG1hcHBpbmcgb2JqZWN0IHBhdGhzIHRvIEVOViBzdHJpbmdzLlxuICogQGNvbnN0IEVOVl9QQVRIX0RFTElNSVRFUlxuICogQHR5cGUge3N0cmluZ31cbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgY29uc3QgRU5WX1BBVEhfREVMSU1JVEVSID0gXCJfX1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWZhdWx0IHByZWZpeCBhbmQgc3VmZml4IHVzZWQgZm9yIHRlbXBsYXRlIHBsYWNlaG9sZGVycy5cbiAqIEBzdW1tYXJ5IFByb3ZpZGVzIHdyYXBwZXIgc3RyaW5ncyBhcHBsaWVkIHdoZW4gaW50ZXJwb2xhdGluZyBtZXNzYWdlcyB3aXRoIHtAbGluayBwYXRjaFBsYWNlaG9sZGVyc30uXG4gKiBAY29uc3QgRGVmYXVsdFBsYWNlaG9sZGVyV3JhcHBlcnNcbiAqIEB0eXBlIHtzdHJpbmdbXX1cbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgY29uc3QgRGVmYXVsdFBsYWNlaG9sZGVyV3JhcHBlcnMgPSBbXCIke1wiLCBcIn1cIl07XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEVudW0gZm9yIGxvZyBsZXZlbHMuXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGRpZmZlcmVudCBsZXZlbHMgb2YgbG9nZ2luZyBmb3IgdGhlIGFwcGxpY2F0aW9uLlxuICogQGVudW0ge3N0cmluZ31cbiAqIEByZWFkb25seVxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBlbnVtIExvZ0xldmVsIHtcbiAgLyoqIEBkZXNjcmlwdGlvbiBCZW5jaG1hcmsgZXZlbnRzIHRoYXQgY2FwdHVyZSBwZXJmb3JtYW5jZSBtZXRyaWNzLiAqL1xuICBiZW5jaG1hcmsgPSBcImJlbmNobWFya1wiLFxuICAvKiogQGRlc2NyaXB0aW9uIEVycm9yIGV2ZW50cyB0aGF0IGluZGljYXRlIGZhaWx1cmVzIHJlcXVpcmluZyBhdHRlbnRpb24uICovXG4gIGVycm9yID0gXCJlcnJvclwiLFxuICAvKiogQGRlc2NyaXB0aW9uIEluZm9ybWF0aW9uYWwgZXZlbnRzIGRlc2NyaWJpbmcgbm9ybWFsIG9wZXJhdGlvbi4gKi9cbiAgaW5mbyA9IFwiaW5mb1wiLFxuICAvKiogQGRlc2NyaXB0aW9uIFZlcmJvc2UgZGlhZ25vc3RpYyBpbmZvcm1hdGlvbiBmb3IgZGV0YWlsZWQgdHJhY2luZy4gKi9cbiAgdmVyYm9zZSA9IFwidmVyYm9zZVwiLFxuICAvKiogQGRlc2NyaXB0aW9uIERlYnVnIG9yIHRyYWNlIGRldGFpbHMgYWltZWQgYXQgZGV2ZWxvcGVycy4gKi9cbiAgZGVidWcgPSBcImRlYnVnXCIsXG4gIC8qKiBAZGVzY3JpcHRpb24gRXh0cmVtZWx5IGNoYXR0eSBvciBwbGF5ZnVsIGxvZyBlbnRyaWVzLiAqL1xuICBzaWxseSA9IFwic2lsbHlcIixcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gTnVtZXJpYyB2YWx1ZXMgYXNzb2NpYXRlZCB3aXRoIGxvZyBsZXZlbHMuXG4gKiBAc3VtbWFyeSBQcm92aWRlcyBhIG51bWVyaWMgcmVwcmVzZW50YXRpb24gb2YgbG9nIGxldmVscyBmb3IgY29tcGFyaXNvbiBhbmQgZmlsdGVyaW5nLlxuICogQHR5cGVkZWYge09iamVjdH0gTnVtZXJpY0xvZ0xldmVsc1NoYXBlXG4gKiBAcHJvcGVydHkge251bWJlcn0gYmVuY2htYXJrIC0gTnVtZXJpYyB2YWx1ZSBmb3IgYmVuY2htYXJrIGxldmVsICgwKS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBlcnJvciAtIE51bWVyaWMgdmFsdWUgZm9yIGVycm9yIGxldmVsICgyKS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBpbmZvIC0gTnVtZXJpYyB2YWx1ZSBmb3IgaW5mbyBsZXZlbCAoNCkuXG4gKiBAcHJvcGVydHkge251bWJlcn0gdmVyYm9zZSAtIE51bWVyaWMgdmFsdWUgZm9yIHZlcmJvc2UgbGV2ZWwgKDYpLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IGRlYnVnIC0gTnVtZXJpYyB2YWx1ZSBmb3IgZGVidWcgbGV2ZWwgKDcpLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IHNpbGx5IC0gTnVtZXJpYyB2YWx1ZSBmb3Igc2lsbHkgbGV2ZWwgKDkpLlxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbi8qKlxuICogQGRlc2NyaXB0aW9uIE51bWVyaWMgdmFsdWVzIGFzc29jaWF0ZWQgd2l0aCBsb2cgbGV2ZWxzLlxuICogQHN1bW1hcnkgUHJvdmlkZXMgYSBudW1lcmljIHJlcHJlc2VudGF0aW9uIG9mIGxvZyBsZXZlbHMgZm9yIGNvbXBhcmlzb24gYW5kIGZpbHRlcmluZy5cbiAqIEBjb25zdCBOdW1lcmljTG9nTGV2ZWxzXG4gKiBAdHlwZSB7TnVtZXJpY0xvZ0xldmVsc1NoYXBlfVxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBjb25zdCBOdW1lcmljTG9nTGV2ZWxzID0ge1xuICBiZW5jaG1hcms6IDAsXG4gIGVycm9yOiAyLFxuICBpbmZvOiA0LFxuICB2ZXJib3NlOiA2LFxuICBkZWJ1ZzogNyxcbiAgc2lsbHk6IDksXG59O1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBFbnVtIGZvciBsb2dnaW5nIG91dHB1dCBtb2Rlcy5cbiAqIEBzdW1tYXJ5IERlZmluZXMgZGlmZmVyZW50IG91dHB1dCBmb3JtYXRzIGZvciBsb2cgbWVzc2FnZXMuXG4gKiBAZW51bSB7c3RyaW5nfVxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBlbnVtIExvZ2dpbmdNb2RlIHtcbiAgLyoqIFJhdyB0ZXh0IGZvcm1hdCBmb3IgaHVtYW4gcmVhZGFiaWxpdHkgKi9cbiAgUkFXID0gXCJyYXdcIixcbiAgLyoqIEpTT04gZm9ybWF0IGZvciBtYWNoaW5lIHBhcnNpbmcgKi9cbiAgSlNPTiA9IFwianNvblwiLFxufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWZhdWx0IHRoZW1lIGZvciBzdHlsaW5nIGxvZyBvdXRwdXQuXG4gKiBAc3VtbWFyeSBEZWZpbmVzIHRoZSBkZWZhdWx0IGNvbG9yIGFuZCBzdHlsZSBzZXR0aW5ncyBmb3IgdmFyaW91cyBjb21wb25lbnRzIG9mIGxvZyBtZXNzYWdlcy5cbiAqIEB0eXBlZGVmIHtUaGVtZX0gRGVmYXVsdFRoZW1lXG4gKiBAcHJvcGVydHkge09iamVjdH0gY2xhc3MgLSBTdHlsaW5nIGZvciBjbGFzcyBuYW1lcy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBjbGFzcy5mZyAtIEZvcmVncm91bmQgY29sb3IgY29kZSBmb3IgY2xhc3MgbmFtZXMgKDM0KS5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBpZCAtIFN0eWxpbmcgZm9yIGlkZW50aWZpZXJzLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IGlkLmZnIC0gRm9yZWdyb3VuZCBjb2xvciBjb2RlIGZvciBpZGVudGlmaWVycyAoMzYpLlxuICogQHByb3BlcnR5IHtPYmplY3R9IHN0YWNrIC0gU3R5bGluZyBmb3Igc3RhY2sgdHJhY2VzIChlbXB0eSBvYmplY3QpLlxuICogQHByb3BlcnR5IHtPYmplY3R9IHRpbWVzdGFtcCAtIFN0eWxpbmcgZm9yIHRpbWVzdGFtcHMgKGVtcHR5IG9iamVjdCkuXG4gKiBAcHJvcGVydHkge09iamVjdH0gbWVzc2FnZSAtIFN0eWxpbmcgZm9yIGRpZmZlcmVudCB0eXBlcyBvZiBtZXNzYWdlcy5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBtZXNzYWdlLmVycm9yIC0gU3R5bGluZyBmb3IgZXJyb3IgbWVzc2FnZXMuXG4gKiBAcHJvcGVydHkge251bWJlcn0gbWVzc2FnZS5lcnJvci5mZyAtIEZvcmVncm91bmQgY29sb3IgY29kZSBmb3IgZXJyb3IgbWVzc2FnZXMgKDMxKS5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBtZXRob2QgLSBTdHlsaW5nIGZvciBtZXRob2QgbmFtZXMgKGVtcHR5IG9iamVjdCkuXG4gKiBAcHJvcGVydHkge09iamVjdH0gbG9nTGV2ZWwgLSBTdHlsaW5nIGZvciBkaWZmZXJlbnQgbG9nIGxldmVscy5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBsb2dMZXZlbC5lcnJvciAtIFN0eWxpbmcgZm9yIGVycm9yIGxldmVsIGxvZ3MuXG4gKiBAcHJvcGVydHkge251bWJlcn0gbG9nTGV2ZWwuZXJyb3IuZmcgLSBGb3JlZ3JvdW5kIGNvbG9yIGNvZGUgZm9yIGVycm9yIGxldmVsIGxvZ3MgKDMxKS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nW119IGxvZ0xldmVsLmVycm9yLnN0eWxlIC0gU3R5bGUgYXR0cmlidXRlcyBmb3IgZXJyb3IgbGV2ZWwgbG9ncyAoW1wiYm9sZFwiXSkuXG4gKiBAcHJvcGVydHkge09iamVjdH0gbG9nTGV2ZWwuaW5mbyAtIFN0eWxpbmcgZm9yIGluZm8gbGV2ZWwgbG9ncyAoZW1wdHkgb2JqZWN0KS5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBsb2dMZXZlbC52ZXJib3NlIC0gU3R5bGluZyBmb3IgdmVyYm9zZSBsZXZlbCBsb2dzIChlbXB0eSBvYmplY3QpLlxuICogQHByb3BlcnR5IHtPYmplY3R9IGxvZ0xldmVsLmRlYnVnIC0gU3R5bGluZyBmb3IgZGVidWcgbGV2ZWwgbG9ncy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBsb2dMZXZlbC5kZWJ1Zy5mZyAtIEZvcmVncm91bmQgY29sb3IgY29kZSBmb3IgZGVidWcgbGV2ZWwgbG9ncyAoMzMpLlxuICogQGNvbnN0IERlZmF1bHRUaGVtZVxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBjb25zdCBEZWZhdWx0VGhlbWU6IFRoZW1lID0ge1xuICBhcHA6IHt9LFxuICBzZXBhcmF0b3I6IHt9LFxuICBjbGFzczoge1xuICAgIGZnOiAzNCxcbiAgfSxcbiAgaWQ6IHtcbiAgICBmZzogMzYsXG4gIH0sXG4gIHN0YWNrOiB7fSxcbiAgdGltZXN0YW1wOiB7fSxcbiAgbWVzc2FnZToge1xuICAgIGVycm9yOiB7XG4gICAgICBmZzogMzEsXG4gICAgfSxcbiAgfSxcbiAgbWV0aG9kOiB7fSxcbiAgbG9nTGV2ZWw6IHtcbiAgICBiZW5jaG1hcms6IHtcbiAgICAgIGZnOiAzMixcbiAgICAgIHN0eWxlOiBbXCJib2xkXCJdLFxuICAgIH0sXG4gICAgZXJyb3I6IHtcbiAgICAgIGZnOiAzMSxcbiAgICAgIHN0eWxlOiBbXCJib2xkXCJdLFxuICAgIH0sXG4gICAgaW5mbzoge1xuICAgICAgZmc6IDM0LFxuICAgICAgc3R5bGU6IFtcImJvbGRcIl0sXG4gICAgfSxcbiAgICB2ZXJib3NlOiB7XG4gICAgICBmZzogMzQsXG4gICAgICBzdHlsZTogW1wiYm9sZFwiXSxcbiAgICB9LFxuICAgIGRlYnVnOiB7XG4gICAgICBmZzogMzMsXG4gICAgICBzdHlsZTogW1wiYm9sZFwiXSxcbiAgICB9LFxuICB9LFxufTtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVmYXVsdCBjb25maWd1cmF0aW9uIGZvciBsb2dnaW5nLlxuICogQHN1bW1hcnkgRGVmaW5lcyB0aGUgZGVmYXVsdCBzZXR0aW5ncyBmb3IgdGhlIGxvZ2dpbmcgc3lzdGVtLCBpbmNsdWRpbmcgdmVyYm9zaXR5LCBsb2cgbGV2ZWwsIHN0eWxpbmcsIGFuZCB0aW1lc3RhbXAgZm9ybWF0LlxuICogQGNvbnN0IERlZmF1bHRMb2dnaW5nQ29uZmlnXG4gKiBAdHlwZWRlZiB7TG9nZ2luZ0NvbmZpZ30gRGVmYXVsdExvZ2dpbmdDb25maWdcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSB2ZXJib3NlIC0gVmVyYm9zaXR5IGxldmVsICgwKS5cbiAqIEBwcm9wZXJ0eSB7TG9nTGV2ZWx9IGxldmVsIC0gRGVmYXVsdCBsb2cgbGV2ZWwgKExvZ0xldmVsLmluZm8pLlxuICogQHByb3BlcnR5IHtib29sZWFufSBsb2dMZXZlbCAtIFdoZXRoZXIgdG8gZGlzcGxheSBsb2cgbGV2ZWwgaW4gb3V0cHV0ICh0cnVlKS5cbiAqIEBwcm9wZXJ0eSB7TG9nZ2luZ01vZGV9IG1vZGUgLSBPdXRwdXQgZm9ybWF0IG1vZGUgKExvZ2dpbmdNb2RlLlJBVykuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IHN0eWxlIC0gV2hldGhlciB0byBhcHBseSBzdHlsaW5nIHRvIGxvZyBvdXRwdXQgKGZhbHNlKS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzZXBhcmF0b3IgLSBTZXBhcmF0b3IgYmV0d2VlbiBsb2cgY29tcG9uZW50cyAoXCIgLSBcIikuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IHRpbWVzdGFtcCAtIFdoZXRoZXIgdG8gaW5jbHVkZSB0aW1lc3RhbXBzIGluIGxvZyBtZXNzYWdlcyAodHJ1ZSkuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gdGltZXN0YW1wRm9ybWF0IC0gRm9ybWF0IGZvciB0aW1lc3RhbXBzIChcIkhIOm1tOnNzLlNTU1wiKS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gY29udGV4dCAtIFdoZXRoZXIgdG8gaW5jbHVkZSBjb250ZXh0IGluZm9ybWF0aW9uIGluIGxvZyBtZXNzYWdlcyAodHJ1ZSkuXG4gKiBAcHJvcGVydHkge1RoZW1lfSB0aGVtZSAtIFRoZSB0aGVtZSB0byB1c2UgZm9yIHN0eWxpbmcgbG9nIG1lc3NhZ2VzIChEZWZhdWx0VGhlbWUpLlxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBjb25zdCBEZWZhdWx0TG9nZ2luZ0NvbmZpZzogTG9nZ2luZ0NvbmZpZyA9IHtcbiAgZW52OiBcImRldmVsb3BtZW50XCIsXG4gIHZlcmJvc2U6IDAsXG4gIGxldmVsOiBMb2dMZXZlbC5pbmZvLFxuICBsb2dMZXZlbDogdHJ1ZSxcbiAgc3R5bGU6IGZhbHNlLFxuICBjb250ZXh0U2VwYXJhdG9yOiBcIi5cIixcbiAgc2VwYXJhdG9yOiBcIi1cIixcbiAgdGltZXN0YW1wOiB0cnVlLFxuICB0aW1lc3RhbXBGb3JtYXQ6IFwiSEg6bW06c3MuU1NTXCIsXG4gIGNvbnRleHQ6IHRydWUsXG4gIGZvcm1hdDogTG9nZ2luZ01vZGUuUkFXLFxuICBwYXR0ZXJuOlxuICAgIFwie2xldmVsfSBbe3RpbWVzdGFtcH1dIHthcHB9IHtjb250ZXh0fSB7c2VwYXJhdG9yfSB7bWVzc2FnZX0ge3N0YWNrfVwiLFxuICB0aGVtZTogRGVmYXVsdFRoZW1lLFxufTtcbiIsImltcG9ydCB7IERlZmF1bHRQbGFjZWhvbGRlcldyYXBwZXJzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFBhZHMgdGhlIGVuZCBvZiBhIHN0cmluZyB3aXRoIGEgc3BlY2lmaWVkIGNoYXJhY3Rlci5cbiAqIEBzdW1tYXJ5IEV4dGVuZHMgdGhlIGlucHV0IHN0cmluZyB0byBhIHNwZWNpZmllZCBsZW5ndGggYnkgYWRkaW5nIGEgcGFkZGluZyBjaGFyYWN0ZXIgdG8gdGhlIGVuZC5cbiAqIElmIHRoZSBpbnB1dCBzdHJpbmcgaXMgYWxyZWFkeSBsb25nZXIgdGhhbiB0aGUgc3BlY2lmaWVkIGxlbmd0aCwgaXQgaXMgcmV0dXJuZWQgdW5jaGFuZ2VkLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgLSBUaGUgaW5wdXQgc3RyaW5nIHRvIGJlIHBhZGRlZC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBsZW5ndGggLSBUaGUgZGVzaXJlZCB0b3RhbCBsZW5ndGggb2YgdGhlIHJlc3VsdGluZyBzdHJpbmcuXG4gKiBAcGFyYW0ge3N0cmluZ30gW2NoYXI9XCIgXCJdIC0gVGhlIGNoYXJhY3RlciB0byB1c2UgZm9yIHBhZGRpbmcuIERlZmF1bHRzIHRvIGEgc3BhY2UuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBwYWRkZWQgc3RyaW5nLlxuICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYWRkaW5nIGNoYXJhY3RlciBpcyBub3QgZXhhY3RseSBvbmUgY2hhcmFjdGVyIGxvbmcuXG4gKlxuICogQGZ1bmN0aW9uIHBhZEVuZFxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gcGFkRW5kKFxuICBzdHI6IHN0cmluZyxcbiAgbGVuZ3RoOiBudW1iZXIsXG4gIGNoYXI6IHN0cmluZyA9IFwiIFwiXG4pOiBzdHJpbmcge1xuICBpZiAoY2hhci5sZW5ndGggIT09IDEpXG4gICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBjaGFyYWN0ZXIgbGVuZ3RoIGZvciBwYWRkaW5nLiBtdXN0IGJlIG9uZSFcIik7XG4gIHJldHVybiBzdHIucGFkRW5kKGxlbmd0aCwgY2hhcik7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFJlcGxhY2VzIHBsYWNlaG9sZGVycyBpbiBhIHN0cmluZyB3aXRoIHByb3ZpZGVkIHZhbHVlcy5cbiAqIEBzdW1tYXJ5IEludGVycG9sYXRlcyBhIHN0cmluZyBieSByZXBsYWNpbmcgcGxhY2Vob2xkZXJzIG9mIHRoZSBmb3JtICR7dmFyaWFibGVOYW1lfVxuICogd2l0aCBjb3JyZXNwb25kaW5nIHZhbHVlcyBmcm9tIHRoZSBwcm92aWRlZCBvYmplY3QuIElmIGEgcGxhY2Vob2xkZXIgZG9lc24ndCBoYXZlXG4gKiBhIGNvcnJlc3BvbmRpbmcgdmFsdWUsIGl0IGlzIGxlZnQgdW5jaGFuZ2VkIGluIHRoZSBzdHJpbmcuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGlucHV0IC0gVGhlIGlucHV0IHN0cmluZyBjb250YWluaW5nIHBsYWNlaG9sZGVycyB0byBiZSByZXBsYWNlZC5cbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgbnVtYmVyIHwgc3RyaW5nPn0gdmFsdWVzIC0gQW4gb2JqZWN0IGNvbnRhaW5pbmcga2V5LXZhbHVlIHBhaXJzIGZvciByZXBsYWNlbWVudC5cbiAqIEBwYXJhbSBwcmVmaXhcbiAqIEBwYXJhbSBzdWZmaXhcbiAqIEBwYXJhbSBmbGFnc1xuICogQHJldHVybiB7c3RyaW5nfSBUaGUgaW50ZXJwb2xhdGVkIHN0cmluZyB3aXRoIHBsYWNlaG9sZGVycyByZXBsYWNlZCBieSB0aGVpciBjb3JyZXNwb25kaW5nIHZhbHVlcy5cbiAqXG4gKiBAZnVuY3Rpb24gcGF0Y2hQbGFjZWhvbGRlcnNcbiAqXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IENhbGxlclxuICogICBwYXJ0aWNpcGFudCBwYXRjaFN0cmluZ1xuICogICBwYXJ0aWNpcGFudCBTdHJpbmcucmVwbGFjZVxuICogICBDYWxsZXItPj5wYXRjaFN0cmluZzogQ2FsbCB3aXRoIGlucHV0IGFuZCB2YWx1ZXNcbiAqICAgcGF0Y2hTdHJpbmctPj5TdHJpbmcucmVwbGFjZTogQ2FsbCB3aXRoIHJlZ2V4IGFuZCByZXBsYWNlbWVudCBmdW5jdGlvblxuICogICBTdHJpbmcucmVwbGFjZS0+PnBhdGNoU3RyaW5nOiBSZXR1cm4gcmVwbGFjZWQgc3RyaW5nXG4gKiAgIHBhdGNoU3RyaW5nLS0+PkNhbGxlcjogUmV0dXJuIHBhdGNoZWQgc3RyaW5nXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXRjaFBsYWNlaG9sZGVycyhcbiAgaW5wdXQ6IHN0cmluZyxcbiAgdmFsdWVzOiBSZWNvcmQ8c3RyaW5nLCBudW1iZXIgfCBzdHJpbmc+LFxuICBwcmVmaXg6IHN0cmluZyA9IERlZmF1bHRQbGFjZWhvbGRlcldyYXBwZXJzWzBdLFxuICBzdWZmaXg6IHN0cmluZyA9IERlZmF1bHRQbGFjZWhvbGRlcldyYXBwZXJzWzFdLFxuICBmbGFnczogc3RyaW5nID0gXCJnXCJcbik6IHN0cmluZyB7XG4gIGNvbnN0IHBsYWNlaG9sZGVycyA9IE9iamVjdC5lbnRyaWVzKHZhbHVlcykucmVkdWNlKFxuICAgIChhY2M6IFJlY29yZDxzdHJpbmcsIGFueT4sIFtrZXksIHZhbF0pID0+IHtcbiAgICAgIGFjY1tgJHtwcmVmaXh9JHtrZXl9JHtzdWZmaXh9YF0gPSB2YWw7XG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sXG4gICAge31cbiAgKTtcbiAgcmV0dXJuIHBhdGNoU3RyaW5nKGlucHV0LCBwbGFjZWhvbGRlcnMsIGZsYWdzKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUmVwbGFjZXMgb2NjdXJyZW5jZXMgb2Yga2V5cyB3aXRoIHRoZWlyIGNvcnJlc3BvbmRpbmcgdmFsdWVzIGluIGEgc3RyaW5nLlxuICogQHN1bW1hcnkgSXRlcmF0ZXMgdGhyb3VnaCBhIHNldCBvZiBrZXktdmFsdWUgcGFpcnMgYW5kIHJlcGxhY2VzIGFsbCBvY2N1cnJlbmNlcyBvZiBlYWNoIGtleVxuICogaW4gdGhlIGlucHV0IHN0cmluZyB3aXRoIGl0cyBjb3JyZXNwb25kaW5nIHZhbHVlLiBTdXBwb3J0cyByZWd1bGFyIGV4cHJlc3Npb24gZmxhZ3MgZm9yIGN1c3RvbWl6ZWQgcmVwbGFjZW1lbnQuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGlucHV0IC0gVGhlIGlucHV0IHN0cmluZyBpbiB3aGljaCByZXBsYWNlbWVudHMgd2lsbCBiZSBtYWRlLlxuICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBudW1iZXIgfCBzdHJpbmc+fSB2YWx1ZXMgLSBBbiBvYmplY3QgY29udGFpbmluZyBrZXktdmFsdWUgcGFpcnMgZm9yIHJlcGxhY2VtZW50LlxuICogQHBhcmFtIHtzdHJpbmd9IFtmbGFncz1cImdcIl0gLSBSZWd1bGFyIGV4cHJlc3Npb24gZmxhZ3MgdG8gY29udHJvbCB0aGUgcmVwbGFjZW1lbnQgYmVoYXZpb3IuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBzdHJpbmcgd2l0aCBhbGwgc3BlY2lmaWVkIHJlcGxhY2VtZW50cyBhcHBsaWVkLlxuICpcbiAqIEBmdW5jdGlvbiBwYXRjaFN0cmluZ1xuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gcGF0Y2hTdHJpbmcoXG4gIGlucHV0OiBzdHJpbmcsXG4gIHZhbHVlczogUmVjb3JkPHN0cmluZywgbnVtYmVyIHwgc3RyaW5nPixcbiAgZmxhZ3M6IHN0cmluZyA9IFwiZ1wiXG4pOiBzdHJpbmcge1xuICBPYmplY3QuZW50cmllcyh2YWx1ZXMpLmZvckVhY2goKFtrZXksIHZhbF0pID0+IHtcbiAgICBjb25zdCByZWdleHAgPSBuZXcgUmVnRXhwKGVzY2FwZVJlZ0V4cChrZXkpLCBmbGFncyk7XG4gICAgaW5wdXQgPSBpbnB1dC5yZXBsYWNlKHJlZ2V4cCwgdmFsIGFzIHN0cmluZyk7XG4gIH0pO1xuICByZXR1cm4gaW5wdXQ7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENvbnZlcnRzIGEgc3RyaW5nIHRvIGNhbWVsQ2FzZS5cbiAqIEBzdW1tYXJ5IFRyYW5zZm9ybXMgdGhlIGlucHV0IHN0cmluZyBpbnRvIGNhbWVsQ2FzZSBmb3JtYXQsIHdoZXJlIHdvcmRzIGFyZSBqb2luZWQgd2l0aG91dCBzcGFjZXNcbiAqIGFuZCBlYWNoIHdvcmQgYWZ0ZXIgdGhlIGZpcnN0IHN0YXJ0cyB3aXRoIGEgY2FwaXRhbCBsZXR0ZXIuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHRleHQgLSBUaGUgaW5wdXQgc3RyaW5nIHRvIGJlIGNvbnZlcnRlZC5cbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGlucHV0IHN0cmluZyBjb252ZXJ0ZWQgdG8gY2FtZWxDYXNlLlxuICpcbiAqIEBmdW5jdGlvbiB0b0NhbWVsQ2FzZVxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gdG9DYW1lbENhc2UodGV4dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHRleHRcbiAgICAucmVwbGFjZSgvKD86Xlxcd3xbQS1aXXxcXGJcXHcpL2csICh3b3JkLCBpbmRleCkgPT5cbiAgICAgIGluZGV4ID09PSAwID8gd29yZC50b0xvd2VyQ2FzZSgpIDogd29yZC50b1VwcGVyQ2FzZSgpXG4gICAgKVxuICAgIC5yZXBsYWNlKC9cXHMrL2csIFwiXCIpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDb252ZXJ0cyBhIHN0cmluZyB0byBFTlZJUk9OTUVOVF9WQVJJQUJMRSBmb3JtYXQuXG4gKiBAc3VtbWFyeSBUcmFuc2Zvcm1zIHRoZSBpbnB1dCBzdHJpbmcgaW50byB1cHBlcmNhc2Ugd2l0aCB3b3JkcyBzZXBhcmF0ZWQgYnkgdW5kZXJzY29yZXMsXG4gKiB0eXBpY2FsbHkgdXNlZCBmb3IgZW52aXJvbm1lbnQgdmFyaWFibGUgbmFtZXMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHRleHQgLSBUaGUgaW5wdXQgc3RyaW5nIHRvIGJlIGNvbnZlcnRlZC5cbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGlucHV0IHN0cmluZyBjb252ZXJ0ZWQgdG8gRU5WSVJPTk1FTlRfVkFSSUFCTEUgZm9ybWF0LlxuICpcbiAqIEBmdW5jdGlvbiB0b0VOVkZvcm1hdFxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gdG9FTlZGb3JtYXQodGV4dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHRvU25ha2VDYXNlKHRleHQpLnRvVXBwZXJDYXNlKCk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENvbnZlcnRzIGEgc3RyaW5nIHRvIHNuYWtlX2Nhc2UuXG4gKiBAc3VtbWFyeSBUcmFuc2Zvcm1zIHRoZSBpbnB1dCBzdHJpbmcgaW50byBsb3dlcmNhc2Ugd2l0aCB3b3JkcyBzZXBhcmF0ZWQgYnkgdW5kZXJzY29yZXMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHRleHQgLSBUaGUgaW5wdXQgc3RyaW5nIHRvIGJlIGNvbnZlcnRlZC5cbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGlucHV0IHN0cmluZyBjb252ZXJ0ZWQgdG8gc25ha2VfY2FzZS5cbiAqXG4gKiBAZnVuY3Rpb24gdG9TbmFrZUNhc2VcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvU25ha2VDYXNlKHRleHQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiB0ZXh0XG4gICAgLnJlcGxhY2UoLyhbYS16XSkoW0EtWl0pL2csIFwiJDFfJDJcIilcbiAgICAucmVwbGFjZSgvW1xccy1dKy9nLCBcIl9cIilcbiAgICAudG9Mb3dlckNhc2UoKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ29udmVydHMgYSBzdHJpbmcgdG8ga2ViYWItY2FzZS5cbiAqIEBzdW1tYXJ5IFRyYW5zZm9ybXMgdGhlIGlucHV0IHN0cmluZyBpbnRvIGxvd2VyY2FzZSB3aXRoIHdvcmRzIHNlcGFyYXRlZCBieSBoeXBoZW5zLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gVGhlIGlucHV0IHN0cmluZyB0byBiZSBjb252ZXJ0ZWQuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBpbnB1dCBzdHJpbmcgY29udmVydGVkIHRvIGtlYmFiLWNhc2UuXG4gKlxuICogQGZ1bmN0aW9uIHRvS2ViYWJDYXNlXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b0tlYmFiQ2FzZSh0ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gdGV4dFxuICAgIC5yZXBsYWNlKC8oW2Etel0pKFtBLVpdKS9nLCBcIiQxLSQyXCIpXG4gICAgLnJlcGxhY2UoL1tcXHNfXSsvZywgXCItXCIpXG4gICAgLnRvTG93ZXJDYXNlKCk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENvbnZlcnRzIGEgc3RyaW5nIHRvIFBhc2NhbENhc2UuXG4gKiBAc3VtbWFyeSBUcmFuc2Zvcm1zIHRoZSBpbnB1dCBzdHJpbmcgaW50byBQYXNjYWxDYXNlIGZvcm1hdCwgd2hlcmUgd29yZHMgYXJlIGpvaW5lZCB3aXRob3V0IHNwYWNlc1xuICogYW5kIGVhY2ggd29yZCBzdGFydHMgd2l0aCBhIGNhcGl0YWwgbGV0dGVyLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gVGhlIGlucHV0IHN0cmluZyB0byBiZSBjb252ZXJ0ZWQuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBpbnB1dCBzdHJpbmcgY29udmVydGVkIHRvIFBhc2NhbENhc2UuXG4gKlxuICogQGZ1bmN0aW9uIHRvUGFzY2FsQ2FzZVxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gdG9QYXNjYWxDYXNlKHRleHQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiB0ZXh0XG4gICAgLnJlcGxhY2UoLyg/Ol5cXHd8W0EtWl18XFxiXFx3KS9nLCAod29yZCkgPT4gd29yZC50b1VwcGVyQ2FzZSgpKVxuICAgIC5yZXBsYWNlKC9cXHMrL2csIFwiXCIpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBFc2NhcGVzIHNwZWNpYWwgY2hhcmFjdGVycyBpbiBhIHN0cmluZyBmb3IgdXNlIGluIGEgcmVndWxhciBleHByZXNzaW9uLlxuICogQHN1bW1hcnkgQWRkcyBiYWNrc2xhc2hlcyBiZWZvcmUgY2hhcmFjdGVycyB0aGF0IGhhdmUgc3BlY2lhbCBtZWFuaW5nIGluIHJlZ3VsYXIgZXhwcmVzc2lvbnMsXG4gKiBhbGxvd2luZyB0aGUgc3RyaW5nIHRvIGJlIHVzZWQgYXMgYSBsaXRlcmFsIG1hdGNoIGluIGEgUmVnRXhwLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgLSBUaGUgc3RyaW5nIHRvIGVzY2FwZSBmb3IgcmVndWxhciBleHByZXNzaW9uIHVzZS5cbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGVzY2FwZWQgc3RyaW5nIHNhZmUgZm9yIHVzZSBpbiByZWd1bGFyIGV4cHJlc3Npb25zLlxuICpcbiAqIEBmdW5jdGlvbiBlc2NhcGVSZWdFeHBcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVzY2FwZVJlZ0V4cChzdHJpbmc6IHN0cmluZykge1xuICByZXR1cm4gc3RyaW5nLnJlcGxhY2UoL1suKis/XiR7fSgpfFtcXF1cXFxcXS9nLCBcIlxcXFwkJlwiKTsgLy8gJCYgbWVhbnMgdGhlIHdob2xlIG1hdGNoZWQgc3RyaW5nXG59XG5cbi8qKlxuICogQHN1bW1hcnkgVXRpbCBmdW5jdGlvbiB0byBwcm92aWRlIHN0cmluZyBmb3JtYXQgZnVuY3Rpb25hbGl0eSBzaW1pbGFyIHRvIEMjJ3Mgc3RyaW5nLmZvcm1hdFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmdcbiAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nIHwgbnVtYmVyPiB8IFJlY29yZDxzdHJpbmcsIGFueT59IFthcmdzXSByZXBsYWNlbWVudHMgbWFkZSBieSBvcmRlciBvZiBhcHBlYXJhbmNlIChyZXBsYWNlbWVudDAgd2lsIHJlcGxhY2UgezB9IGFuZCBzbyBvbilcbiAqIEByZXR1cm4ge3N0cmluZ30gZm9ybWF0dGVkIHN0cmluZ1xuICpcbiAqIEBmdW5jdGlvbiBzZlxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZihcbiAgc3RyaW5nOiBzdHJpbmcsXG4gIC4uLmFyZ3M6IChzdHJpbmcgfCBudW1iZXIgfCBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtdXG4pIHtcbiAgaWYgKGFyZ3MubGVuZ3RoID4gMSkge1xuICAgIGlmIChcbiAgICAgICFhcmdzLmV2ZXJ5KChhcmcpID0+IHR5cGVvZiBhcmcgPT09IFwic3RyaW5nXCIgfHwgdHlwZW9mIGFyZyA9PT0gXCJudW1iZXJcIilcbiAgICApXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBPbmx5IHN0cmluZyBhbmQgbnVtYmVyIGFyZ3VtZW50cyBhcmUgc3VwcG9ydGVkIGZvciBtdWx0aXBsZSByZXBsYWNlbWVudHMuYFxuICAgICAgKTtcbiAgfVxuXG4gIGlmIChhcmdzLmxlbmd0aCA9PT0gMSAmJiB0eXBlb2YgYXJnc1swXSA9PT0gXCJvYmplY3RcIikge1xuICAgIGNvbnN0IG9iaiA9IGFyZ3NbMF0gYXMgUmVjb3JkPHN0cmluZywgYW55PjtcbiAgICByZXR1cm4gT2JqZWN0LmVudHJpZXMob2JqKS5yZWR1Y2UoKGFjYywgW2tleSwgdmFsXSkgPT4ge1xuICAgICAgcmV0dXJuIGFjYy5yZXBsYWNlKG5ldyBSZWdFeHAoYFxcXFx7JHtrZXl9XFxcXH1gLCBcImdcIiksIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHZhbDtcbiAgICAgIH0pO1xuICAgIH0sIHN0cmluZyk7XG4gIH1cblxuICByZXR1cm4gc3RyaW5nLnJlcGxhY2UoL3soXFxkKyl9L2csIGZ1bmN0aW9uIChtYXRjaCwgbnVtYmVyKSB7XG4gICAgcmV0dXJuIHR5cGVvZiBhcmdzW251bWJlcl0gIT09IFwidW5kZWZpbmVkXCJcbiAgICAgID8gYXJnc1tudW1iZXJdLnRvU3RyaW5nKClcbiAgICAgIDogXCJ1bmRlZmluZWRcIjtcbiAgfSk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgVXRpbCBmdW5jdGlvbiB0byBwcm92aWRlIHN0cmluZyBmb3JtYXQgZnVuY3Rpb25hbGl0eSBzaW1pbGFyIHRvIEMjJ3Mgc3RyaW5nLmZvcm1hdFxuICpcbiAqIEBzZWUgc2ZcbiAqXG4gKiBAZGVwcmVjYXRlZFxuICogQGZ1bmN0aW9uIHN0cmluZ0Zvcm1hdFxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBjb25zdCBzdHJpbmdGb3JtYXQgPSBzZjtcbiIsIi8qKlxuICogQGRlc2NyaXB0aW9uIERldGVybWluZXMgaWYgdGhlIGN1cnJlbnQgZW52aXJvbm1lbnQgaXMgYSBicm93c2VyIGJ5IGNoZWNraW5nIHRoZSBwcm90b3R5cGUgY2hhaW4gb2YgdGhlIGdsb2JhbCBvYmplY3QuXG4gKiBAc3VtbWFyeSBDaGVja3MgaWYgdGhlIGNvZGUgaXMgcnVubmluZyBpbiBhIGJyb3dzZXIgZW52aXJvbm1lbnQuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIHRoZSBlbnZpcm9ubWVudCBpcyBhIGJyb3dzZXIsIGZhbHNlIG90aGVyd2lzZS5cbiAqIEBmdW5jdGlvbiBpc0Jyb3dzZXJcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gaXNCcm93c2VyKCk6IGJvb2xlYW4ge1xuICByZXR1cm4gKFxuICAgIE9iamVjdC5nZXRQcm90b3R5cGVPZihPYmplY3QuZ2V0UHJvdG90eXBlT2YoZ2xvYmFsVGhpcykpICE9PVxuICAgIE9iamVjdC5wcm90b3R5cGVcbiAgKTtcbn1cbiIsImltcG9ydCB7IE9iamVjdEFjY3VtdWxhdG9yIH0gZnJvbSBcInR5cGVkLW9iamVjdC1hY2N1bXVsYXRvclwiO1xuaW1wb3J0IHsgdG9FTlZGb3JtYXQgfSBmcm9tIFwiLi90ZXh0XCI7XG5pbXBvcnQgeyBpc0Jyb3dzZXIgfSBmcm9tIFwiLi93ZWJcIjtcbmltcG9ydCB7XG4gIEJyb3dzZXJFbnZLZXksXG4gIERlZmF1bHRMb2dnaW5nQ29uZmlnLFxuICBFTlZfUEFUSF9ERUxJTUlURVIsXG59IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBGYWN0b3J5IHR5cGUgZm9yIGNyZWF0aW5nIEVudmlyb25tZW50IGluc3RhbmNlcy5cbiAqIEBzdW1tYXJ5IERlc2NyaWJlcyBmYWN0b3JpZXMgdGhhdCBjb25zdHJ1Y3Qge0BsaW5rIEVudmlyb25tZW50fSBkZXJpdmF0aXZlcyB3aXRoIGN1c3RvbSBpbml0aWFsaXphdGlvbi5cbiAqIEB0ZW1wbGF0ZSBUIC0gVGhlIHR5cGUgb2Ygb2JqZWN0IHRoZSBFbnZpcm9ubWVudCB3aWxsIGFjY3VtdWxhdGUuXG4gKiBAdGVtcGxhdGUgRSAtIFRoZSBzcGVjaWZpYyBFbnZpcm9ubWVudCB0eXBlIHRvIGJlIGNyZWF0ZWQsIGV4dGVuZGluZyBFbnZpcm9ubWVudDxUPi5cbiAqIEB0eXBlZGVmIHtmdW5jdGlvbih1bmtub3duW10pOiBFfSBFbnZpcm9ubWVudEZhY3RvcnlcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TG9nZ2luZ1xuICovXG5leHBvcnQgdHlwZSBFbnZpcm9ubWVudEZhY3Rvcnk8VCBleHRlbmRzIG9iamVjdCwgRSBleHRlbmRzIEVudmlyb25tZW50PFQ+PiA9IChcbiAgLi4uYXJnczogdW5rbm93bltdXG4pID0+IEU7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEVudmlyb25tZW50IGFjY3VtdWxhdG9yIHRoYXQgbGF6aWx5IHJlYWRzIGZyb20gcnVudGltZSBzb3VyY2VzLlxuICogQHN1bW1hcnkgRXh0ZW5kcyB7QGxpbmsgT2JqZWN0QWNjdW11bGF0b3J9IHRvIG1lcmdlIGNvbmZpZ3VyYXRpb24gb2JqZWN0cyB3aGlsZSByZXNvbHZpbmcgdmFsdWVzIGZyb20gTm9kZSBvciBicm93c2VyIGVudmlyb25tZW50IHZhcmlhYmxlcyBvbiBkZW1hbmQuXG4gKiBAdGVtcGxhdGUgVFxuICogQGNsYXNzIEVudmlyb25tZW50XG4gKiBAZXhhbXBsZVxuICogY29uc3QgQ29uZmlnID0gRW52aXJvbm1lbnQuYWNjdW11bGF0ZSh7IGxvZ2dpbmc6IHsgbGV2ZWw6IFwiaW5mb1wiIH0gfSk7XG4gKiBjb25zb2xlLmxvZyhDb25maWcubG9nZ2luZy5sZXZlbCk7XG4gKiBjb25zb2xlLmxvZyhTdHJpbmcoQ29uZmlnLmxvZ2dpbmcubGV2ZWwpKTsgLy8gPT4gTE9HR0lOR19fTEVWRUwga2V5IHdoZW4gc2VyaWFsaXplZFxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDbGllbnRcbiAqICAgcGFydGljaXBhbnQgRW52IGFzIEVudmlyb25tZW50XG4gKiAgIHBhcnRpY2lwYW50IFByb2Nlc3MgYXMgcHJvY2Vzcy5lbnZcbiAqICAgcGFydGljaXBhbnQgQnJvd3NlciBhcyBnbG9iYWxUaGlzLkVOVlxuICogICBDbGllbnQtPj5FbnY6IGFjY3VtdWxhdGUocGFydGlhbENvbmZpZylcbiAqICAgRW52LT4+RW52OiBleHBhbmQodmFsdWVzKVxuICogICBDbGllbnQtPj5FbnY6IENvbmZpZy5sb2dnaW5nLmxldmVsXG4gKiAgIGFsdCBCcm93c2VyIHJ1bnRpbWVcbiAqICAgICBFbnYtPj5Ccm93c2VyOiBsb29rdXAgRU5WIGtleVxuICogICAgIEJyb3dzZXItLT4+RW52OiByZXNvbHZlZCB2YWx1ZVxuICogICBlbHNlIE5vZGUgcnVudGltZVxuICogICAgIEVudi0+PlByb2Nlc3M6IGxvb2t1cCBFTlYga2V5XG4gKiAgICAgUHJvY2Vzcy0tPj5FbnY6IHJlc29sdmVkIHZhbHVlXG4gKiAgIGVuZFxuICogICBFbnYtLT4+Q2xpZW50OiBtZXJnZWQgdmFsdWVcbiAqL1xuZXhwb3J0IGNsYXNzIEVudmlyb25tZW50PFQgZXh0ZW5kcyBvYmplY3Q+IGV4dGVuZHMgT2JqZWN0QWNjdW11bGF0b3I8VD4ge1xuICAvKipcbiAgICogQHN0YXRpY1xuICAgKiBAcHJvdGVjdGVkXG4gICAqIEBkZXNjcmlwdGlvbiBBIGZhY3RvcnkgZnVuY3Rpb24gZm9yIGNyZWF0aW5nIEVudmlyb25tZW50IGluc3RhbmNlcy5cbiAgICogQHN1bW1hcnkgRGVmaW5lcyBob3cgbmV3IGluc3RhbmNlcyBvZiB0aGUgRW52aXJvbm1lbnQgY2xhc3Mgc2hvdWxkIGJlIGNyZWF0ZWQuXG4gICAqIEByZXR1cm4ge0Vudmlyb25tZW50PGFueT59IEEgbmV3IGluc3RhbmNlIG9mIHRoZSBFbnZpcm9ubWVudCBjbGFzcy5cbiAgICovXG4gIHByb3RlY3RlZCBzdGF0aWMgZmFjdG9yeTogRW52aXJvbm1lbnRGYWN0b3J5PGFueSwgYW55PiA9XG4gICAgKCk6IEVudmlyb25tZW50PGFueT4gPT4gbmV3IEVudmlyb25tZW50KCk7XG5cbiAgLyoqXG4gICAqIEBzdGF0aWNcbiAgICogQHByaXZhdGVcbiAgICogQGRlc2NyaXB0aW9uIFRoZSBzaW5nbGV0b24gaW5zdGFuY2Ugb2YgdGhlIEVudmlyb25tZW50IGNsYXNzLlxuICAgKiBAdHlwZSB7RW52aXJvbm1lbnQ8YW55Pn1cbiAgICovXG4gIHByaXZhdGUgc3RhdGljIF9pbnN0YW5jZTogRW52aXJvbm1lbnQ8YW55PjtcblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIGEgdmFsdWUgZnJvbSB0aGUgcnVudGltZSBlbnZpcm9ubWVudC5cbiAgICogQHN1bW1hcnkgSGFuZGxlcyBicm93c2VyIGFuZCBOb2RlLmpzIGVudmlyb25tZW50cyBieSBub3JtYWxpemluZyBrZXlzIGFuZCBwYXJzaW5nIHZhbHVlcy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGsgLSBLZXkgdG8gcmVzb2x2ZSBmcm9tIHRoZSBlbnZpcm9ubWVudC5cbiAgICogQHJldHVybiB7dW5rbm93bn0gVmFsdWUgcmVzb2x2ZWQgZnJvbSB0aGUgZW52aXJvbm1lbnQgb3IgYHVuZGVmaW5lZGAgd2hlbiBhYnNlbnQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZnJvbUVudihrOiBzdHJpbmcpIHtcbiAgICBsZXQgZW52OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICBpZiAoaXNCcm93c2VyKCkpIHtcbiAgICAgIGVudiA9XG4gICAgICAgIChcbiAgICAgICAgICBnbG9iYWxUaGlzIGFzIHR5cGVvZiBnbG9iYWxUaGlzICYge1xuICAgICAgICAgICAgW0Jyb3dzZXJFbnZLZXldOiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuICAgICAgICAgIH1cbiAgICAgICAgKVtCcm93c2VyRW52S2V5XSB8fCB7fTtcbiAgICB9IGVsc2Uge1xuICAgICAgZW52ID0gZ2xvYmFsVGhpcy5wcm9jZXNzLmVudjtcbiAgICAgIGsgPSB0b0VOVkZvcm1hdChrKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMucGFyc2VFbnZWYWx1ZShlbnZba10pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDb252ZXJ0cyBzdHJpbmdpZmllZCBlbnZpcm9ubWVudCB2YWx1ZXMgaW50byBuYXRpdmUgdHlwZXMuXG4gICAqIEBzdW1tYXJ5IEludGVycHJldHMgYm9vbGVhbnMgYW5kIG51bWJlcnMgd2hpbGUgbGVhdmluZyBvdGhlciB0eXBlcyB1bmNoYW5nZWQuXG4gICAqIEBwYXJhbSB7dW5rbm93bn0gdmFsIC0gUmF3IHZhbHVlIHJldHJpZXZlZCBmcm9tIHRoZSBlbnZpcm9ubWVudC5cbiAgICogQHJldHVybiB7dW5rbm93bn0gUGFyc2VkIHZhbHVlIGNvbnZlcnRlZCB0byBib29sZWFuLCBudW1iZXIsIG9yIGxlZnQgYXMtaXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgcGFyc2VFbnZWYWx1ZSh2YWw6IHVua25vd24pIHtcbiAgICBpZiAodHlwZW9mIHZhbCAhPT0gXCJzdHJpbmdcIikgcmV0dXJuIHZhbDtcbiAgICBpZiAodmFsID09PSBcInRydWVcIikgcmV0dXJuIHRydWU7XG4gICAgaWYgKHZhbCA9PT0gXCJmYWxzZVwiKSByZXR1cm4gZmFsc2U7XG4gICAgY29uc3QgcmVzdWx0ID0gcGFyc2VGbG9hdCh2YWwpO1xuICAgIGlmICghaXNOYU4ocmVzdWx0KSkgcmV0dXJuIHJlc3VsdDtcbiAgICByZXR1cm4gdmFsO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBFeHBhbmRzIGFuIG9iamVjdCBpbnRvIHRoZSBlbnZpcm9ubWVudC5cbiAgICogQHN1bW1hcnkgRGVmaW5lcyBsYXp5IHByb3BlcnRpZXMgdGhhdCBmaXJzdCBjb25zdWx0IHJ1bnRpbWUgdmFyaWFibGVzIGJlZm9yZSBmYWxsaW5nIGJhY2sgdG8gc2VlZGVkIHZhbHVlcy5cbiAgICogQHRlbXBsYXRlIFYgLSBUeXBlIG9mIHRoZSBvYmplY3QgYmVpbmcgZXhwYW5kZWQuXG4gICAqIEBwYXJhbSB7Vn0gdmFsdWUgLSBPYmplY3QgdG8gZXhwb3NlIHRocm91Z2ggZW52aXJvbm1lbnQgZ2V0dGVycyBhbmQgc2V0dGVycy5cbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIHByb3RlY3RlZCBvdmVycmlkZSBleHBhbmQ8ViBleHRlbmRzIG9iamVjdD4odmFsdWU6IFYpOiB2b2lkIHtcbiAgICBPYmplY3QuZW50cmllcyh2YWx1ZSkuZm9yRWFjaCgoW2ssIHZdKSA9PiB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgaywge1xuICAgICAgICBnZXQ6ICgpID0+IHtcbiAgICAgICAgICBjb25zdCBmcm9tRW52ID0gdGhpcy5mcm9tRW52KGspO1xuICAgICAgICAgIGlmICh0eXBlb2YgZnJvbUVudiAhPT0gXCJ1bmRlZmluZWRcIikgcmV0dXJuIGZyb21FbnY7XG4gICAgICAgICAgaWYgKHYgJiYgdHlwZW9mIHYgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgIHJldHVybiBFbnZpcm9ubWVudC5idWlsZEVudlByb3h5KHYgYXMgYW55LCBba10pO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBJZiB0aGUgbW9kZWwgcHJvdmlkZXMgYW4gZW1wdHkgc3RyaW5nLCBleHBvc2UgYSBwcm94eSB0aGF0IGNvbXBvc2VzIEVOViBrZXlzXG4gICAgICAgICAgaWYgKHYgPT09IFwiXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBFbnZpcm9ubWVudC5idWlsZEVudlByb3h5KHVuZGVmaW5lZCwgW2tdKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHY7XG4gICAgICAgIH0sXG4gICAgICAgIHNldDogKHZhbDogVltrZXlvZiBWXSkgPT4ge1xuICAgICAgICAgIHYgPSB2YWw7XG4gICAgICAgIH0sXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm90ZWN0ZWRcbiAgICogQHN0YXRpY1xuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIG9yIGNyZWF0ZXMgdGhlIHNpbmdsZXRvbiBpbnN0YW5jZSBvZiB0aGUgRW52aXJvbm1lbnQgY2xhc3MuXG4gICAqIEBzdW1tYXJ5IEVuc3VyZXMgb25seSBvbmUge0BsaW5rIEVudmlyb25tZW50fSBpbnN0YW5jZSBpcyBjcmVhdGVkLCB3cmFwcGluZyBpdCBpbiBhIHByb3h5IHRvIGNvbXBvc2UgRU5WIGtleXMgb24gZGVtYW5kLlxuICAgKiBAdGVtcGxhdGUgRVxuICAgKiBAcGFyYW0gey4uLnVua25vd25bXX0gYXJncyAtIEFyZ3VtZW50cyBmb3J3YXJkZWQgdG8gdGhlIGZhY3Rvcnkgd2hlbiBpbnN0YW50aWF0aW5nIHRoZSBzaW5nbGV0b24uXG4gICAqIEByZXR1cm4ge0V9IFNpbmdsZXRvbiBlbnZpcm9ubWVudCBpbnN0YW5jZS5cbiAgICovXG4gIHByb3RlY3RlZCBzdGF0aWMgaW5zdGFuY2U8RSBleHRlbmRzIEVudmlyb25tZW50PGFueT4+KC4uLmFyZ3M6IHVua25vd25bXSk6IEUge1xuICAgIGlmICghRW52aXJvbm1lbnQuX2luc3RhbmNlKSB7XG4gICAgICBjb25zdCBiYXNlID0gRW52aXJvbm1lbnQuZmFjdG9yeSguLi5hcmdzKSBhcyBFO1xuICAgICAgY29uc3QgcHJveGllZCA9IG5ldyBQcm94eShiYXNlIGFzIGFueSwge1xuICAgICAgICBnZXQodGFyZ2V0LCBwcm9wLCByZWNlaXZlcikge1xuICAgICAgICAgIGNvbnN0IHZhbHVlID0gUmVmbGVjdC5nZXQodGFyZ2V0LCBwcm9wLCByZWNlaXZlcik7XG4gICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJ1bmRlZmluZWRcIikgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgIGlmICh0eXBlb2YgcHJvcCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgLy8gQXZvaWQgaW50ZXJmZXJpbmcgd2l0aCBsb2dnaW5nIGNvbmZpZyBsb29rdXBzIGZvciBvcHRpb25hbCBmaWVsZHMgbGlrZSAnYXBwJ1xuICAgICAgICAgICAgaWYgKHByb3AgPT09IFwiYXBwXCIpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICByZXR1cm4gRW52aXJvbm1lbnQuYnVpbGRFbnZQcm94eSh1bmRlZmluZWQsIFtwcm9wXSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgRW52aXJvbm1lbnQuX2luc3RhbmNlID0gcHJveGllZCBhcyBhbnk7XG4gICAgfVxuICAgIHJldHVybiBFbnZpcm9ubWVudC5faW5zdGFuY2UgYXMgRTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3RhdGljXG4gICAqIEBkZXNjcmlwdGlvbiBBY2N1bXVsYXRlcyB0aGUgZ2l2ZW4gdmFsdWUgaW50byB0aGUgZW52aXJvbm1lbnQuXG4gICAqIEBzdW1tYXJ5IEFkZHMgbmV3IHByb3BlcnRpZXMsIGhpZGluZyByYXcgZGVzY3JpcHRvcnMgdG8gYXZvaWQgbGVha2luZyBlbnVtZXJhdGlvbiBzZW1hbnRpY3MuXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqIEB0ZW1wbGF0ZSBWXG4gICAqIEBwYXJhbSB7Vn0gdmFsdWUgLSBPYmplY3QgdG8gbWVyZ2UgaW50byB0aGUgZW52aXJvbm1lbnQuXG4gICAqIEByZXR1cm4ge0Vudmlyb25tZW50fSBVcGRhdGVkIGVudmlyb25tZW50IHJlZmVyZW5jZS5cbiAgICovXG4gIHN0YXRpYyBhY2N1bXVsYXRlPFYgZXh0ZW5kcyBvYmplY3Q+KFxuICAgIHZhbHVlOiBWXG4gICk6IHR5cGVvZiBFbnZpcm9ubWVudC5faW5zdGFuY2UgJlxuICAgIFYgJlxuICAgIE9iamVjdEFjY3VtdWxhdG9yPHR5cGVvZiBFbnZpcm9ubWVudC5faW5zdGFuY2UgJiBWPiB7XG4gICAgY29uc3QgaW5zdGFuY2UgPSBFbnZpcm9ubWVudC5pbnN0YW5jZSgpO1xuICAgIE9iamVjdC5rZXlzKGluc3RhbmNlIGFzIGFueSkuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICBjb25zdCBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihpbnN0YW5jZSBhcyBhbnksIGtleSk7XG4gICAgICBpZiAoZGVzYyAmJiBkZXNjLmNvbmZpZ3VyYWJsZSAmJiBkZXNjLmVudW1lcmFibGUpIHtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGluc3RhbmNlIGFzIGFueSwga2V5LCB7XG4gICAgICAgICAgLi4uZGVzYyxcbiAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGluc3RhbmNlLmFjY3VtdWxhdGUodmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgYSB2YWx1ZSB1c2luZyBhIGRvdC1wYXRoIGtleSBmcm9tIHRoZSBhY2N1bXVsYXRlZCBlbnZpcm9ubWVudC5cbiAgICogQHN1bW1hcnkgRGVsZWdhdGVzIHRvIHRoZSBzaW5nbGV0b24gaW5zdGFuY2UgdG8gYWNjZXNzIHN0b3JlZCBjb25maWd1cmF0aW9uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IC0gS2V5IHRvIHJlc29sdmUgZnJvbSB0aGUgZW52aXJvbm1lbnQgc3RvcmUuXG4gICAqIEByZXR1cm4ge3Vua25vd259IFN0b3JlZCB2YWx1ZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBwcm92aWRlZCBrZXkuXG4gICAqL1xuICBzdGF0aWMgZ2V0KGtleTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIEVudmlyb25tZW50Ll9pbnN0YW5jZS5nZXQoa2V5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQnVpbGRzIGEgcHJveHkgdGhhdCBjb21wb3NlcyBlbnZpcm9ubWVudCBrZXlzIGZvciBuZXN0ZWQgcHJvcGVydGllcy5cbiAgICogQHN1bW1hcnkgQWxsb3dzIGNoYWluZWQgcHJvcGVydHkgYWNjZXNzIHRvIGVtaXQgdXBwZXJjYXNlIEVOViBpZGVudGlmaWVycyB3aGlsZSBob25vcmluZyBleGlzdGluZyBydW50aW1lIG92ZXJyaWRlcy5cbiAgICogQHBhcmFtIHthbnl9IGN1cnJlbnQgLSBTZWVkIG1vZGVsIHNlZ21lbnQgdXNlZCB3aGVuIHByb2plY3RpbmcgbmVzdGVkIHN0cnVjdHVyZXMuXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IHBhdGggLSBBY2N1bXVsYXRlZCBwYXRoIHNlZ21lbnRzIGxlYWRpbmcgdG8gdGhlIHByb3h5LlxuICAgKiBAcmV0dXJuIHthbnl9IFByb3h5IHRoYXQgcmVzb2x2ZXMgZW52aXJvbm1lbnQgdmFsdWVzIG9yIGNvbXBvc2VzIGFkZGl0aW9uYWwgcHJveGllcyBmb3IgZGVlcGVyIHBhdGhzLlxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgYnVpbGRFbnZQcm94eShjdXJyZW50OiBhbnksIHBhdGg6IHN0cmluZ1tdKTogYW55IHtcbiAgICBjb25zdCBidWlsZEtleSA9IChwOiBzdHJpbmdbXSkgPT5cbiAgICAgIHAubWFwKChzZWcpID0+IHRvRU5WRm9ybWF0KHNlZykpLmpvaW4oRU5WX1BBVEhfREVMSU1JVEVSKTtcblxuICAgIC8vIEhlbHBlciB0byByZWFkIGZyb20gdGhlIGFjdGl2ZSBlbnZpcm9ubWVudCBnaXZlbiBhIGNvbXBvc2VkIGtleVxuICAgIGNvbnN0IHJlYWRFbnYgPSAoa2V5OiBzdHJpbmcpOiB1bmtub3duID0+IHtcbiAgICAgIGlmIChpc0Jyb3dzZXIoKSkge1xuICAgICAgICBjb25zdCBlbnYgPSAoXG4gICAgICAgICAgZ2xvYmFsVGhpcyBhcyB0eXBlb2YgZ2xvYmFsVGhpcyAmIHtcbiAgICAgICAgICAgIFtCcm93c2VyRW52S2V5XT86IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgICAgICAgIH1cbiAgICAgICAgKVtCcm93c2VyRW52S2V5XTtcbiAgICAgICAgcmV0dXJuIGVudiA/IGVudltrZXldIDogdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIChnbG9iYWxUaGlzIGFzIGFueSk/LnByb2Nlc3M/LmVudj8uW2tleV07XG4gICAgfTtcblxuICAgIGNvbnN0IGhhbmRsZXI6IFByb3h5SGFuZGxlcjxhbnk+ID0ge1xuICAgICAgZ2V0KF90YXJnZXQsIHByb3A6IHN0cmluZyB8IHN5bWJvbCkge1xuICAgICAgICBpZiAocHJvcCA9PT0gU3ltYm9sLnRvUHJpbWl0aXZlKSB7XG4gICAgICAgICAgcmV0dXJuICgpID0+IGJ1aWxkS2V5KHBhdGgpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9wID09PSBcInRvU3RyaW5nXCIpIHtcbiAgICAgICAgICByZXR1cm4gKCkgPT4gYnVpbGRLZXkocGF0aCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb3AgPT09IFwidmFsdWVPZlwiKSB7XG4gICAgICAgICAgcmV0dXJuICgpID0+IGJ1aWxkS2V5KHBhdGgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgcHJvcCA9PT0gXCJzeW1ib2xcIikgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgICAgICBjb25zdCBuZXh0TW9kZWwgPVxuICAgICAgICAgIGN1cnJlbnQgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGN1cnJlbnQsIHByb3ApXG4gICAgICAgICAgICA/IChjdXJyZW50IGFzIGFueSlbcHJvcF1cbiAgICAgICAgICAgIDogdW5kZWZpbmVkO1xuICAgICAgICBjb25zdCBuZXh0UGF0aCA9IFsuLi5wYXRoLCBwcm9wXTtcbiAgICAgICAgY29uc3QgY29tcG9zZWRLZXkgPSBidWlsZEtleShuZXh0UGF0aCk7XG5cbiAgICAgICAgLy8gSWYgYW4gRU5WIHZhbHVlIGV4aXN0cyBmb3IgdGhpcyBwYXRoLCByZXR1cm4gaXQgZGlyZWN0bHlcbiAgICAgICAgY29uc3QgZW52VmFsdWUgPSByZWFkRW52KGNvbXBvc2VkS2V5KTtcbiAgICAgICAgaWYgKHR5cGVvZiBlbnZWYWx1ZSAhPT0gXCJ1bmRlZmluZWRcIikgcmV0dXJuIGVudlZhbHVlO1xuXG4gICAgICAgIC8vIE90aGVyd2lzZSwgaWYgdGhlIG1vZGVsIGhhcyBhbiBvYmplY3QgYXQgdGhpcyBwYXRoLCBrZWVwIGRyaWxsaW5nIHdpdGggYSBwcm94eVxuICAgICAgICBjb25zdCBpc05leHRPYmplY3QgPSBuZXh0TW9kZWwgJiYgdHlwZW9mIG5leHRNb2RlbCA9PT0gXCJvYmplY3RcIjtcbiAgICAgICAgaWYgKGlzTmV4dE9iamVjdCkgcmV0dXJuIEVudmlyb25tZW50LmJ1aWxkRW52UHJveHkobmV4dE1vZGVsLCBuZXh0UGF0aCk7XG5cbiAgICAgICAgLy8gQWx3YXlzIHJldHVybiBhIHByb3h5IGZvciBmdXJ0aGVyIHBhdGggY29tcG9zaXRpb24gd2hlbiBubyBFTlYgdmFsdWU7XG4gICAgICAgIC8vIGRvIG5vdCBzdXJmYWNlIHByaW1pdGl2ZSBtb2RlbCBkZWZhdWx0cyBoZXJlICh0aGlzIEFQSSBpcyBmb3Iga2V5IGNvbXBvc2l0aW9uKS5cbiAgICAgICAgcmV0dXJuIEVudmlyb25tZW50LmJ1aWxkRW52UHJveHkodW5kZWZpbmVkLCBuZXh0UGF0aCk7XG4gICAgICB9LFxuICAgICAgb3duS2V5cygpIHtcbiAgICAgICAgcmV0dXJuIGN1cnJlbnQgPyBSZWZsZWN0Lm93bktleXMoY3VycmVudCkgOiBbXTtcbiAgICAgIH0sXG4gICAgICBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoX3QsIHApIHtcbiAgICAgICAgaWYgKCFjdXJyZW50KSByZXR1cm4gdW5kZWZpbmVkIGFzIGFueTtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChjdXJyZW50LCBwKSkge1xuICAgICAgICAgIHJldHVybiB7IGVudW1lcmFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IGFzIFByb3BlcnR5RGVzY3JpcHRvcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkIGFzIGFueTtcbiAgICAgIH0sXG4gICAgfTtcblxuICAgIGNvbnN0IHRhcmdldCA9IHt9IGFzIGFueTtcbiAgICByZXR1cm4gbmV3IFByb3h5KHRhcmdldCwgaGFuZGxlcik7XG4gIH1cblxuICAvKipcbiAgICogQHN0YXRpY1xuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIHRoZSBrZXlzIG9mIHRoZSBlbnZpcm9ubWVudCwgb3B0aW9uYWxseSBjb252ZXJ0aW5nIHRoZW0gdG8gRU5WIGZvcm1hdC5cbiAgICogQHN1bW1hcnkgR2V0cyBhbGwga2V5cyBpbiB0aGUgZW52aXJvbm1lbnQsIHdpdGggYW4gb3B0aW9uIHRvIGZvcm1hdCB0aGVtIGZvciBlbnZpcm9ubWVudCB2YXJpYWJsZXMuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW3RvRW52PXRydWVdIC0gV2hldGhlciB0byBjb252ZXJ0IHRoZSBrZXlzIHRvIEVOViBmb3JtYXQuXG4gICAqIEByZXR1cm4ge3N0cmluZ1tdfSBBbiBhcnJheSBvZiBrZXlzIGZyb20gdGhlIGVudmlyb25tZW50LlxuICAgKi9cbiAgc3RhdGljIGtleXModG9FbnY6IGJvb2xlYW4gPSB0cnVlKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBFbnZpcm9ubWVudC5pbnN0YW5jZSgpXG4gICAgICAua2V5cygpXG4gICAgICAubWFwKChrKSA9PiAodG9FbnYgPyB0b0VOVkZvcm1hdChrKSA6IGspKTtcbiAgfVxufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBTaW5nbGV0b24gZW52aXJvbm1lbnQgaW5zdGFuY2Ugc2VlZGVkIHdpdGggZGVmYXVsdCBsb2dnaW5nIGNvbmZpZ3VyYXRpb24uXG4gKiBAc3VtbWFyeSBDb21iaW5lcyB7QGxpbmsgRGVmYXVsdExvZ2dpbmdDb25maWd9IHdpdGggcnVudGltZSBlbnZpcm9ubWVudCB2YXJpYWJsZXMgdG8gcHJvdmlkZSBjb25zaXN0ZW50IGxvZ2dpbmcgZGVmYXVsdHMgYWNyb3NzIHBsYXRmb3Jtcy5cbiAqIEBjb25zdCBMb2dnZWRFbnZpcm9ubWVudFxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBjb25zdCBMb2dnZWRFbnZpcm9ubWVudCA9IEVudmlyb25tZW50LmFjY3VtdWxhdGUoXG4gIE9iamVjdC5hc3NpZ24oe30sIERlZmF1bHRMb2dnaW5nQ29uZmlnLCB7XG4gICAgZW52OlxuICAgICAgKGlzQnJvd3NlcigpICYmIChnbG9iYWxUaGlzIGFzIGFueSlbQnJvd3NlckVudktleV1cbiAgICAgICAgPyAoZ2xvYmFsVGhpcyBhcyBhbnkpW0Jyb3dzZXJFbnZLZXldW1wiTk9ERV9FTlZcIl1cbiAgICAgICAgOiAoZ2xvYmFsVGhpcyBhcyBhbnkpLnByb2Nlc3MuZW52W1wiTk9ERV9FTlZcIl0pIHx8IFwiZGV2ZWxvcG1lbnRcIixcbiAgfSlcbik7XG4iLCJpbXBvcnQge1xuICBMb2dnZXJGYWN0b3J5LFxuICBMb2dnaW5nQ29uZmlnLFxuICBMb2dnaW5nQ29udGV4dCxcbiAgU3RyaW5nTGlrZSxcbiAgVGhlbWUsXG4gIFRoZW1lT3B0aW9uLFxuICBUaGVtZU9wdGlvbkJ5TG9nTGV2ZWwsXG4gIExvZ2dlcixcbn0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IENvbG9yaXplT3B0aW9ucywgc3R5bGUsIFN0eWxlZFN0cmluZyB9IGZyb20gXCJzdHlsZWQtc3RyaW5nLWJ1aWxkZXJcIjtcbmltcG9ydCB7IERlZmF1bHRUaGVtZSwgTG9nTGV2ZWwsIE51bWVyaWNMb2dMZXZlbHMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHNmIH0gZnJvbSBcIi4vdGV4dFwiO1xuaW1wb3J0IHsgTG9nZ2VkRW52aXJvbm1lbnQgfSBmcm9tIFwiLi9lbnZpcm9ubWVudFwiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBBIG1pbmltYWwgbG9nZ2VyIGltcGxlbWVudGF0aW9uLlxuICogQHN1bW1hcnkgTWluaUxvZ2dlciBpcyBhIGxpZ2h0d2VpZ2h0IGxvZ2dpbmcgY2xhc3MgdGhhdCBpbXBsZW1lbnRzIHRoZSBMb2dnZXIgaW50ZXJmYWNlLlxuICogSXQgcHJvdmlkZXMgYmFzaWMgbG9nZ2luZyBmdW5jdGlvbmFsaXR5IHdpdGggc3VwcG9ydCBmb3IgZGlmZmVyZW50IGxvZyBsZXZlbHMsIHZlcmJvc2l0eSxcbiAqIGNvbnRleHQtYXdhcmUgbG9nZ2luZywgYW5kIGN1c3RvbWl6YWJsZSBmb3JtYXR0aW5nLlxuICogQHBhcmFtIHtzdHJpbmd9IGNvbnRleHQgLSBUaGUgY29udGV4dCAodHlwaWNhbGx5IGNsYXNzIG5hbWUpIHRoaXMgbG9nZ2VyIGlzIGFzc29jaWF0ZWQgd2l0aFxuICogQHBhcmFtIHtQYXJ0aWFsPExvZ2dpbmdDb25maWc+fSBjb25mIC0gT3B0aW9uYWwgY29uZmlndXJhdGlvbiB0byBvdmVycmlkZSBnbG9iYWwgc2V0dGluZ3NcbiAqIEBjbGFzcyBNaW5pTG9nZ2VyXG4gKiBAZXhhbXBsZVxuICogLy8gQ3JlYXRlIGEgbmV3IGxvZ2dlciBmb3IgYSBjbGFzc1xuICogY29uc3QgbG9nZ2VyID0gbmV3IE1pbmlMb2dnZXIoJ015Q2xhc3MnKTtcbiAqXG4gKiAvLyBMb2cgbWVzc2FnZXMgYXQgZGlmZmVyZW50IGxldmVsc1xuICogbG9nZ2VyLmluZm8oJ1RoaXMgaXMgYW4gaW5mbyBtZXNzYWdlJyk7XG4gKiBsb2dnZXIuZGVidWcoJ1RoaXMgaXMgYSBkZWJ1ZyBtZXNzYWdlJyk7XG4gKiBsb2dnZXIuZXJyb3IoJ1NvbWV0aGluZyB3ZW50IHdyb25nJyk7XG4gKlxuICogLy8gQ3JlYXRlIGEgY2hpbGQgbG9nZ2VyIGZvciBhIHNwZWNpZmljIG1ldGhvZFxuICogY29uc3QgbWV0aG9kTG9nZ2VyID0gbG9nZ2VyLmZvcignbXlNZXRob2QnKTtcbiAqIG1ldGhvZExvZ2dlci52ZXJib3NlKCdEZXRhaWxlZCBpbmZvcm1hdGlvbicsIDIpO1xuICpcbiAqIC8vIExvZyB3aXRoIGN1c3RvbSBjb25maWd1cmF0aW9uXG4gKiBsb2dnZXIuZm9yKCdzcGVjaWFsTWV0aG9kJywgeyBzdHlsZTogdHJ1ZSB9KS5pbmZvKCdTdHlsZWQgbWVzc2FnZScpO1xuICovXG5leHBvcnQgY2xhc3MgTWluaUxvZ2dlciBpbXBsZW1lbnRzIExvZ2dlciB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByb3RlY3RlZCBjb250ZXh0OiBzdHJpbmcsXG4gICAgcHJvdGVjdGVkIGNvbmY/OiBQYXJ0aWFsPExvZ2dpbmdDb25maWc+XG4gICkge31cblxuICBwcm90ZWN0ZWQgY29uZmlnKFxuICAgIGtleToga2V5b2YgTG9nZ2luZ0NvbmZpZ1xuICApOiBMb2dnaW5nQ29uZmlnW2tleW9mIExvZ2dpbmdDb25maWddIHtcbiAgICBpZiAodGhpcy5jb25mICYmIGtleSBpbiB0aGlzLmNvbmYpIHJldHVybiB0aGlzLmNvbmZba2V5XTtcbiAgICByZXR1cm4gTG9nZ2luZy5nZXRDb25maWcoKVtrZXldO1xuICB9XG5cbiAgZm9yKG1ldGhvZDogc3RyaW5nIHwgKCguLi5hcmdzOiBhbnlbXSkgPT4gYW55KSk6IExvZ2dlcjtcbiAgZm9yKGNvbmZpZzogUGFydGlhbDxMb2dnaW5nQ29uZmlnPik6IExvZ2dlcjtcbiAgZm9yKFxuICAgIG1ldGhvZDogc3RyaW5nIHwgKCguLi5hcmdzOiBhbnlbXSkgPT4gYW55KSB8IFBhcnRpYWw8TG9nZ2luZ0NvbmZpZz4sXG4gICAgY29uZmlnOiBQYXJ0aWFsPExvZ2dpbmdDb25maWc+LFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IExvZ2dlcjtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgY2hpbGQgbG9nZ2VyIGZvciBhIHNwZWNpZmljIG1ldGhvZCBvciBjb250ZXh0XG4gICAqIEBzdW1tYXJ5IFJldHVybnMgYSBuZXcgbG9nZ2VyIGluc3RhbmNlIHdpdGggdGhlIGN1cnJlbnQgY29udGV4dCBleHRlbmRlZCBieSB0aGUgc3BlY2lmaWVkIG1ldGhvZCBuYW1lXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgRnVuY3Rpb259IG1ldGhvZCAtIFRoZSBtZXRob2QgbmFtZSBvciBmdW5jdGlvbiB0byBjcmVhdGUgYSBsb2dnZXIgZm9yXG4gICAqIEBwYXJhbSB7UGFydGlhbDxMb2dnaW5nQ29uZmlnPn0gY29uZmlnIC0gT3B0aW9uYWwgY29uZmlndXJhdGlvbiB0byBvdmVycmlkZSBzZXR0aW5nc1xuICAgKiBAcGFyYW0gey4uLmFueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHMgdG8gcGFzcyB0byB0aGUgbG9nZ2VyIGZhY3RvcnlcbiAgICogQHJldHVybiB7TG9nZ2VyfSBBIG5ldyBsb2dnZXIgaW5zdGFuY2UgZm9yIHRoZSBzcGVjaWZpZWQgbWV0aG9kXG4gICAqL1xuICBmb3IoXG4gICAgbWV0aG9kPzogc3RyaW5nIHwgKCguLi5hcmdzOiBhbnlbXSkgPT4gYW55KSB8IFBhcnRpYWw8TG9nZ2luZ0NvbmZpZz4sXG4gICAgY29uZmlnPzogUGFydGlhbDxMb2dnaW5nQ29uZmlnPixcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogTG9nZ2VyIHtcbiAgICBpZiAoIWNvbmZpZyAmJiB0eXBlb2YgbWV0aG9kID09PSBcIm9iamVjdFwiKSB7XG4gICAgICBjb25maWcgPSBtZXRob2Q7XG4gICAgICBtZXRob2QgPSB1bmRlZmluZWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIG1ldGhvZCA9IG1ldGhvZFxuICAgICAgICA/IHR5cGVvZiBtZXRob2QgPT09IFwic3RyaW5nXCJcbiAgICAgICAgICA/IG1ldGhvZFxuICAgICAgICAgIDogKG1ldGhvZCBhcyBhbnkpLm5hbWVcbiAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBQcm94eSh0aGlzLCB7XG4gICAgICBnZXQ6ICh0YXJnZXQ6IHR5cGVvZiB0aGlzLCBwOiBzdHJpbmcgfCBzeW1ib2wsIHJlY2VpdmVyOiBhbnkpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gUmVmbGVjdC5nZXQodGFyZ2V0LCBwLCByZWNlaXZlcik7XG4gICAgICAgIGlmIChwID09PSBcImNvbmZpZ1wiKSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyBQcm94eSh0aGlzLmNvbmZpZywge1xuICAgICAgICAgICAgZ2V0OiAodGFyZ2V0OiB0eXBlb2YgdGhpcy5jb25maWcsIHA6IHN0cmluZyB8IHN5bWJvbCkgPT4ge1xuICAgICAgICAgICAgICBpZiAoY29uZmlnICYmIHAgaW4gY29uZmlnKVxuICAgICAgICAgICAgICAgIHJldHVybiBjb25maWdbcCBhcyBrZXlvZiBMb2dnaW5nQ29uZmlnXTtcbiAgICAgICAgICAgICAgcmV0dXJuIFJlZmxlY3QuZ2V0KHRhcmdldCwgcCwgcmVjZWl2ZXIpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocCA9PT0gXCJjb250ZXh0XCIgJiYgbWV0aG9kKSB7XG4gICAgICAgICAgcmV0dXJuIFtyZXN1bHQsIG1ldGhvZF0uam9pbihcIi5cIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBmb3JtYXR0ZWQgbG9nIHN0cmluZ1xuICAgKiBAc3VtbWFyeSBHZW5lcmF0ZXMgYSBsb2cgc3RyaW5nIHdpdGggdGltZXN0YW1wLCBjb2xvcmVkIGxvZyBsZXZlbCwgY29udGV4dCwgYW5kIG1lc3NhZ2VcbiAgICogQHBhcmFtIHtMb2dMZXZlbH0gbGV2ZWwgLSBUaGUgbG9nIGxldmVsIGZvciB0aGlzIG1lc3NhZ2VcbiAgICogQHBhcmFtIHtTdHJpbmdMaWtlIHwgRXJyb3J9IG1lc3NhZ2UgLSBUaGUgbWVzc2FnZSB0byBsb2cgb3IgYW4gRXJyb3Igb2JqZWN0XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbZXJyb3JdIC0gT3B0aW9uYWwgZXJyb3IgdG8gZXh0cmFjdCBzdGFjayB0cmFjZSB0byBpbmNsdWRlIGluIHRoZSBsb2dcbiAgICogQHJldHVybiB7c3RyaW5nfSBBIGZvcm1hdHRlZCBsb2cgc3RyaW5nIHdpdGggYWxsIGNvbXBvbmVudHNcbiAgICovXG4gIHByb3RlY3RlZCBjcmVhdGVMb2coXG4gICAgbGV2ZWw6IExvZ0xldmVsLFxuICAgIG1lc3NhZ2U6IFN0cmluZ0xpa2UgfCBFcnJvcixcbiAgICBlcnJvcj86IEVycm9yXG4gICk6IHN0cmluZyB7XG4gICAgY29uc3QgbG9nOiBSZWNvcmQ8XG4gICAgICB8IFwidGltZXN0YW1wXCJcbiAgICAgIHwgXCJsZXZlbFwiXG4gICAgICB8IFwiY29udGV4dFwiXG4gICAgICB8IFwiY29ycmVsYXRpb25JZFwiXG4gICAgICB8IFwibWVzc2FnZVwiXG4gICAgICB8IFwic2VwYXJhdG9yXCJcbiAgICAgIHwgXCJzdGFja1wiXG4gICAgICB8IFwiYXBwXCIsXG4gICAgICBzdHJpbmdcbiAgICA+ID0ge30gYXMgYW55O1xuICAgIGNvbnN0IHN0eWxlID0gdGhpcy5jb25maWcoXCJzdHlsZVwiKTtcbiAgICBjb25zdCBzZXBhcmF0b3IgPSB0aGlzLmNvbmZpZyhcInNlcGFyYXRvclwiKTtcbiAgICBjb25zdCBhcHAgPSB0aGlzLmNvbmZpZyhcImFwcFwiKTtcbiAgICBpZiAoYXBwKVxuICAgICAgbG9nLmFwcCA9IHN0eWxlXG4gICAgICAgID8gTG9nZ2luZy50aGVtZShhcHAgYXMgc3RyaW5nLCBcImFwcFwiLCBsZXZlbClcbiAgICAgICAgOiAoYXBwIGFzIHN0cmluZyk7XG5cbiAgICBpZiAoc2VwYXJhdG9yKVxuICAgICAgbG9nLnNlcGFyYXRvciA9IHN0eWxlXG4gICAgICAgID8gTG9nZ2luZy50aGVtZShzZXBhcmF0b3IgYXMgc3RyaW5nLCBcInNlcGFyYXRvclwiLCBsZXZlbClcbiAgICAgICAgOiAoc2VwYXJhdG9yIGFzIHN0cmluZyk7XG5cbiAgICBpZiAodGhpcy5jb25maWcoXCJ0aW1lc3RhbXBcIikpIHtcbiAgICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCk7XG4gICAgICBjb25zdCB0aW1lc3RhbXAgPSBzdHlsZSA/IExvZ2dpbmcudGhlbWUoZGF0ZSwgXCJ0aW1lc3RhbXBcIiwgbGV2ZWwpIDogZGF0ZTtcbiAgICAgIGxvZy50aW1lc3RhbXAgPSB0aW1lc3RhbXA7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY29uZmlnKFwibG9nTGV2ZWxcIikpIHtcbiAgICAgIGNvbnN0IGx2bDogc3RyaW5nID0gc3R5bGVcbiAgICAgICAgPyBMb2dnaW5nLnRoZW1lKGxldmVsLCBcImxvZ0xldmVsXCIsIGxldmVsKVxuICAgICAgICA6IGxldmVsO1xuICAgICAgbG9nLmxldmVsID0gbHZsLnRvVXBwZXJDYXNlKCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY29uZmlnKFwiY29udGV4dFwiKSkge1xuICAgICAgY29uc3QgY29udGV4dDogc3RyaW5nID0gc3R5bGVcbiAgICAgICAgPyBMb2dnaW5nLnRoZW1lKHRoaXMuY29udGV4dCwgXCJjbGFzc1wiLCBsZXZlbClcbiAgICAgICAgOiB0aGlzLmNvbnRleHQ7XG4gICAgICBsb2cuY29udGV4dCA9IGNvbnRleHQ7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY29uZmlnKFwiY29ycmVsYXRpb25JZFwiKSkge1xuICAgICAge1xuICAgICAgICBjb25zdCBpZDogc3RyaW5nID0gc3R5bGVcbiAgICAgICAgICA/IExvZ2dpbmcudGhlbWUodGhpcy5jb25maWcoXCJjb3JyZWxhdGlvbklkXCIpIS50b1N0cmluZygpLCBcImlkXCIsIGxldmVsKVxuICAgICAgICAgIDogdGhpcy5jb25maWcoXCJjb3JyZWxhdGlvbklkXCIpIS50b1N0cmluZygpO1xuICAgICAgICBsb2cuY29ycmVsYXRpb25JZCA9IGlkO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IG1zZzogc3RyaW5nID0gc3R5bGVcbiAgICAgID8gTG9nZ2luZy50aGVtZShcbiAgICAgICAgICB0eXBlb2YgbWVzc2FnZSA9PT0gXCJzdHJpbmdcIiA/IG1lc3NhZ2UgOiAobWVzc2FnZSBhcyBFcnJvcikubWVzc2FnZSxcbiAgICAgICAgICBcIm1lc3NhZ2VcIixcbiAgICAgICAgICBsZXZlbFxuICAgICAgICApXG4gICAgICA6IHR5cGVvZiBtZXNzYWdlID09PSBcInN0cmluZ1wiXG4gICAgICAgID8gbWVzc2FnZVxuICAgICAgICA6IChtZXNzYWdlIGFzIEVycm9yKS5tZXNzYWdlO1xuICAgIGxvZy5tZXNzYWdlID0gbXNnO1xuICAgIGlmIChlcnJvciB8fCBtZXNzYWdlIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIGNvbnN0IHN0YWNrID0gc3R5bGVcbiAgICAgICAgPyBMb2dnaW5nLnRoZW1lKFxuICAgICAgICAgICAgKGVycm9yPy5zdGFjayB8fCAobWVzc2FnZSBhcyBFcnJvcikuc3RhY2spIGFzIHN0cmluZyxcbiAgICAgICAgICAgIFwic3RhY2tcIixcbiAgICAgICAgICAgIGxldmVsXG4gICAgICAgICAgKVxuICAgICAgICA6IGVycm9yPy5zdGFjayB8fCBcIlwiO1xuICAgICAgbG9nLnN0YWNrID0gYCB8ICR7KGVycm9yIHx8IChtZXNzYWdlIGFzIEVycm9yKSkubWVzc2FnZX0gLSBTdGFjayB0cmFjZTpcXG4ke3N0YWNrfWA7XG4gICAgfVxuXG4gICAgc3dpdGNoICh0aGlzLmNvbmZpZyhcImZvcm1hdFwiKSkge1xuICAgICAgY2FzZSBcImpzb25cIjpcbiAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGxvZyk7XG4gICAgICBjYXNlIFwicmF3XCI6XG4gICAgICAgIHJldHVybiAodGhpcy5jb25maWcoXCJwYXR0ZXJuXCIpIGFzIHN0cmluZylcbiAgICAgICAgICAuc3BsaXQoXCIgXCIpXG4gICAgICAgICAgLm1hcCgocykgPT4ge1xuICAgICAgICAgICAgaWYgKCFzLm1hdGNoKC9cXHsuKj99L2cpKSByZXR1cm4gcztcbiAgICAgICAgICAgIGNvbnN0IGZvcm1hdHRlZFMgPSBzZihzLCBsb2cpO1xuICAgICAgICAgICAgaWYgKGZvcm1hdHRlZFMgIT09IHMpIHJldHVybiBmb3JtYXR0ZWRTO1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5maWx0ZXIoKHMpID0+IHMpXG4gICAgICAgICAgLmpvaW4oXCIgXCIpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBsb2dnaW5nIGZvcm1hdDogJHt0aGlzLmNvbmZpZyhcImZvcm1hdFwiKX1gKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYSBtZXNzYWdlIHdpdGggdGhlIHNwZWNpZmllZCBsb2cgbGV2ZWxcbiAgICogQHN1bW1hcnkgQ2hlY2tzIGlmIHRoZSBtZXNzYWdlIHNob3VsZCBiZSBsb2dnZWQgYmFzZWQgb24gdGhlIGN1cnJlbnQgbG9nIGxldmVsLFxuICAgKiB0aGVuIHVzZXMgdGhlIGFwcHJvcHJpYXRlIGNvbnNvbGUgbWV0aG9kIHRvIG91dHB1dCB0aGUgZm9ybWF0dGVkIGxvZ1xuICAgKiBAcGFyYW0ge0xvZ0xldmVsfSBsZXZlbCAtIFRoZSBsb2cgbGV2ZWwgb2YgdGhlIG1lc3NhZ2VcbiAgICogQHBhcmFtIHtTdHJpbmdMaWtlIHwgRXJyb3J9IG1zZyAtIFRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZCBvciBhbiBFcnJvciBvYmplY3RcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtlcnJvcl0gLSBPcHRpb25hbCBzdGFjayB0cmFjZSB0byBpbmNsdWRlIGluIHRoZSBsb2dcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIHByb3RlY3RlZCBsb2cobGV2ZWw6IExvZ0xldmVsLCBtc2c6IFN0cmluZ0xpa2UgfCBFcnJvciwgZXJyb3I/OiBFcnJvcik6IHZvaWQge1xuICAgIGNvbnN0IGNvbmZMdmwgPSB0aGlzLmNvbmZpZyhcImxldmVsXCIpIGFzIExvZ0xldmVsO1xuICAgIGlmIChOdW1lcmljTG9nTGV2ZWxzW2NvbmZMdmxdIDwgTnVtZXJpY0xvZ0xldmVsc1tsZXZlbF0pIHJldHVybjtcbiAgICBsZXQgbWV0aG9kO1xuICAgIHN3aXRjaCAobGV2ZWwpIHtcbiAgICAgIGNhc2UgTG9nTGV2ZWwuYmVuY2htYXJrOlxuICAgICAgICBtZXRob2QgPSBjb25zb2xlLmxvZztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIExvZ0xldmVsLmluZm86XG4gICAgICAgIG1ldGhvZCA9IGNvbnNvbGUubG9nO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgTG9nTGV2ZWwudmVyYm9zZTpcbiAgICAgIGNhc2UgTG9nTGV2ZWwuZGVidWc6XG4gICAgICAgIG1ldGhvZCA9IGNvbnNvbGUuZGVidWc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBMb2dMZXZlbC5lcnJvcjpcbiAgICAgICAgbWV0aG9kID0gY29uc29sZS5lcnJvcjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGxvZyBsZXZlbFwiKTtcbiAgICB9XG4gICAgbWV0aG9kKHRoaXMuY3JlYXRlTG9nKGxldmVsLCBtc2csIGVycm9yKSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYSBtZXNzYWdlIGF0IHRoZSBiZW5jaG1hcmsgbGV2ZWxcbiAgICogQHN1bW1hcnkgTG9ncyBhIG1lc3NhZ2UgYXQgdGhlIGJlbmNobWFyayBsZXZlbCBpZiB0aGUgY3VycmVudCB2ZXJib3NpdHkgc2V0dGluZyBhbGxvd3MgaXRcbiAgICogQHBhcmFtIHtTdHJpbmdMaWtlfSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWRcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIGJlbmNobWFyayhtc2c6IFN0cmluZ0xpa2UpOiB2b2lkIHtcbiAgICB0aGlzLmxvZyhMb2dMZXZlbC5iZW5jaG1hcmssIG1zZyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYSBtZXNzYWdlIGF0IHRoZSBzaWxseSBsZXZlbFxuICAgKiBAc3VtbWFyeSBMb2dzIGEgbWVzc2FnZSBhdCB0aGUgc2lsbHkgbGV2ZWwgaWYgdGhlIGN1cnJlbnQgdmVyYm9zaXR5IHNldHRpbmcgYWxsb3dzIGl0XG4gICAqIEBwYXJhbSB7U3RyaW5nTGlrZX0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbdmVyYm9zaXR5PTBdIC0gVGhlIHZlcmJvc2l0eSBsZXZlbCBvZiB0aGUgbWVzc2FnZVxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgc2lsbHkobXNnOiBTdHJpbmdMaWtlLCB2ZXJib3NpdHk6IG51bWJlciA9IDApOiB2b2lkIHtcbiAgICBpZiAoKHRoaXMuY29uZmlnKFwidmVyYm9zZVwiKSBhcyBudW1iZXIpID49IHZlcmJvc2l0eSlcbiAgICAgIHRoaXMubG9nKExvZ0xldmVsLnZlcmJvc2UsIG1zZyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYSBtZXNzYWdlIGF0IHRoZSB2ZXJib3NlIGxldmVsXG4gICAqIEBzdW1tYXJ5IExvZ3MgYSBtZXNzYWdlIGF0IHRoZSB2ZXJib3NlIGxldmVsIGlmIHRoZSBjdXJyZW50IHZlcmJvc2l0eSBzZXR0aW5nIGFsbG93cyBpdFxuICAgKiBAcGFyYW0ge1N0cmluZ0xpa2V9IG1zZyAtIFRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZFxuICAgKiBAcGFyYW0ge251bWJlcn0gW3ZlcmJvc2l0eT0wXSAtIFRoZSB2ZXJib3NpdHkgbGV2ZWwgb2YgdGhlIG1lc3NhZ2VcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIHZlcmJvc2UobXNnOiBTdHJpbmdMaWtlLCB2ZXJib3NpdHk6IG51bWJlciA9IDApOiB2b2lkIHtcbiAgICBpZiAoKHRoaXMuY29uZmlnKFwidmVyYm9zZVwiKSBhcyBudW1iZXIpID49IHZlcmJvc2l0eSlcbiAgICAgIHRoaXMubG9nKExvZ0xldmVsLnZlcmJvc2UsIG1zZyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYSBtZXNzYWdlIGF0IHRoZSBpbmZvIGxldmVsXG4gICAqIEBzdW1tYXJ5IExvZ3MgYSBtZXNzYWdlIGF0IHRoZSBpbmZvIGxldmVsIGZvciBnZW5lcmFsIGFwcGxpY2F0aW9uIGluZm9ybWF0aW9uXG4gICAqIEBwYXJhbSB7U3RyaW5nTGlrZX0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBpbmZvKG1zZzogU3RyaW5nTGlrZSk6IHZvaWQge1xuICAgIHRoaXMubG9nKExvZ0xldmVsLmluZm8sIG1zZyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYSBtZXNzYWdlIGF0IHRoZSBkZWJ1ZyBsZXZlbFxuICAgKiBAc3VtbWFyeSBMb2dzIGEgbWVzc2FnZSBhdCB0aGUgZGVidWcgbGV2ZWwgZm9yIGRldGFpbGVkIHRyb3VibGVzaG9vdGluZyBpbmZvcm1hdGlvblxuICAgKiBAcGFyYW0ge1N0cmluZ0xpa2V9IG1zZyAtIFRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZFxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgZGVidWcobXNnOiBTdHJpbmdMaWtlKTogdm9pZCB7XG4gICAgdGhpcy5sb2coTG9nTGV2ZWwuZGVidWcsIG1zZyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYSBtZXNzYWdlIGF0IHRoZSBlcnJvciBsZXZlbFxuICAgKiBAc3VtbWFyeSBMb2dzIGEgbWVzc2FnZSBhdCB0aGUgZXJyb3IgbGV2ZWwgZm9yIGVycm9ycyBhbmQgZXhjZXB0aW9uc1xuICAgKiBAcGFyYW0ge1N0cmluZ0xpa2UgfCBFcnJvcn0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkIG9yIGFuIEVycm9yIG9iamVjdFxuICAgKiBAcGFyYW0gZVxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgZXJyb3IobXNnOiBTdHJpbmdMaWtlIHwgRXJyb3IsIGU/OiBFcnJvcik6IHZvaWQge1xuICAgIHRoaXMubG9nKExvZ0xldmVsLmVycm9yLCBtc2csIGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBVcGRhdGVzIHRoZSBsb2dnZXIgY29uZmlndXJhdGlvblxuICAgKiBAc3VtbWFyeSBNZXJnZXMgdGhlIHByb3ZpZGVkIGNvbmZpZ3VyYXRpb24gd2l0aCB0aGUgZXhpc3RpbmcgY29uZmlndXJhdGlvblxuICAgKiBAcGFyYW0ge1BhcnRpYWw8TG9nZ2luZ0NvbmZpZz59IGNvbmZpZyAtIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gYXBwbHlcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIHNldENvbmZpZyhjb25maWc6IFBhcnRpYWw8TG9nZ2luZ0NvbmZpZz4pOiB2b2lkIHtcbiAgICB0aGlzLmNvbmYgPSB7IC4uLih0aGlzLmNvbmYgfHwge30pLCAuLi5jb25maWcgfTtcbiAgfVxufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBBIHN0YXRpYyBjbGFzcyBmb3IgbWFuYWdpbmcgbG9nZ2luZyBvcGVyYXRpb25zXG4gKiBAc3VtbWFyeSBUaGUgTG9nZ2luZyBjbGFzcyBwcm92aWRlcyBhIGNlbnRyYWxpemVkIGxvZ2dpbmcgbWVjaGFuaXNtIHdpdGggc3VwcG9ydCBmb3JcbiAqIGRpZmZlcmVudCBsb2cgbGV2ZWxzLCB2ZXJib3NpdHksIGFuZCBzdHlsaW5nLiBJdCB1c2VzIGEgc2luZ2xldG9uIHBhdHRlcm4gdG8gbWFpbnRhaW4gYSBnbG9iYWxcbiAqIGxvZ2dlciBpbnN0YW5jZSBhbmQgYWxsb3dzIGNyZWF0aW5nIHNwZWNpZmljIGxvZ2dlcnMgZm9yIGRpZmZlcmVudCBjbGFzc2VzIGFuZCBtZXRob2RzLlxuICogQGNsYXNzIExvZ2dpbmdcbiAqIEBleGFtcGxlXG4gKiAvLyBTZXQgZ2xvYmFsIGNvbmZpZ3VyYXRpb25cbiAqIExvZ2dpbmcuc2V0Q29uZmlnKHsgbGV2ZWw6IExvZ0xldmVsLmRlYnVnLCBzdHlsZTogdHJ1ZSB9KTtcbiAqXG4gKiAvLyBHZXQgYSBsb2dnZXIgZm9yIGEgc3BlY2lmaWMgY2xhc3NcbiAqIGNvbnN0IGxvZ2dlciA9IExvZ2dpbmcuZm9yKCdNeUNsYXNzJyk7XG4gKlxuICogLy8gTG9nIG1lc3NhZ2VzIGF0IGRpZmZlcmVudCBsZXZlbHNcbiAqIGxvZ2dlci5pbmZvKCdBcHBsaWNhdGlvbiBzdGFydGVkJyk7XG4gKiBsb2dnZXIuZGVidWcoJ1Byb2Nlc3NpbmcgZGF0YS4uLicpO1xuICpcbiAqIC8vIExvZyB3aXRoIGNvbnRleHRcbiAqIGNvbnN0IG1ldGhvZExvZ2dlciA9IExvZ2dpbmcuZm9yKCdNeUNsYXNzLm15TWV0aG9kJyk7XG4gKiBtZXRob2RMb2dnZXIudmVyYm9zZSgnRGV0YWlsZWQgb3BlcmF0aW9uIGluZm9ybWF0aW9uJywgMSk7XG4gKlxuICogLy8gTG9nIGVycm9yc1xuICogdHJ5IHtcbiAqICAgLy8gc29tZSBvcGVyYXRpb25cbiAqIH0gY2F0Y2ggKGVycm9yKSB7XG4gKiAgIGxvZ2dlci5lcnJvcihlcnJvcik7XG4gKiB9XG4gKiBAbWVybWFpZFxuICogY2xhc3NEaWFncmFtXG4gKiAgIGNsYXNzIExvZ2dlciB7XG4gKiAgICAgPDxpbnRlcmZhY2U+PlxuICogICAgICtmb3IobWV0aG9kLCBjb25maWcsIC4uLmFyZ3MpXG4gKiAgICAgK3NpbGx5KG1zZywgdmVyYm9zaXR5KVxuICogICAgICt2ZXJib3NlKG1zZywgdmVyYm9zaXR5KVxuICogICAgICtpbmZvKG1zZylcbiAqICAgICArZGVidWcobXNnKVxuICogICAgICtlcnJvcihtc2cpXG4gKiAgICAgK3NldENvbmZpZyhjb25maWcpXG4gKiAgIH1cbiAqXG4gKiAgIGNsYXNzIExvZ2dpbmcge1xuICogICAgIC1nbG9iYWw6IExvZ2dlclxuICogICAgIC1fZmFjdG9yeTogTG9nZ2VyRmFjdG9yeVxuICogICAgIC1fY29uZmlnOiBMb2dnaW5nQ29uZmlnXG4gKiAgICAgK3NldEZhY3RvcnkoZmFjdG9yeSlcbiAqICAgICArc2V0Q29uZmlnKGNvbmZpZylcbiAqICAgICArZ2V0Q29uZmlnKClcbiAqICAgICArZ2V0KClcbiAqICAgICArdmVyYm9zZShtc2csIHZlcmJvc2l0eSlcbiAqICAgICAraW5mbyhtc2cpXG4gKiAgICAgK2RlYnVnKG1zZylcbiAqICAgICArc2lsbHkobXNnKVxuICogICAgICtlcnJvcihtc2cpXG4gKiAgICAgK2ZvcihvYmplY3QsIGNvbmZpZywgLi4uYXJncylcbiAqICAgICArYmVjYXVzZShyZWFzb24sIGlkKVxuICogICAgICt0aGVtZSh0ZXh0LCB0eXBlLCBsb2dnZXJMZXZlbCwgdGVtcGxhdGUpXG4gKiAgIH1cbiAqXG4gKiAgIGNsYXNzIE1pbmlMb2dnZXIge1xuICogICAgICtjb25zdHJ1Y3Rvcihjb250ZXh0LCBjb25mPylcbiAqICAgfVxuICpcbiAqICAgTG9nZ2luZyAuLj4gTG9nZ2VyIDogY3JlYXRlc1xuICogICBMb2dnaW5nIC4uPiBNaW5pTG9nZ2VyIDogY3JlYXRlcyBieSBkZWZhdWx0XG4gKi9cbmV4cG9ydCBjbGFzcyBMb2dnaW5nIHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgZ2xvYmFsIGxvZ2dlciBpbnN0YW5jZVxuICAgKiBAc3VtbWFyeSBBIHNpbmdsZXRvbiBpbnN0YW5jZSBvZiBMb2dnZXIgdXNlZCBmb3IgZ2xvYmFsIGxvZ2dpbmdcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGdsb2JhbD86IExvZ2dlcjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEZhY3RvcnkgZnVuY3Rpb24gZm9yIGNyZWF0aW5nIGxvZ2dlciBpbnN0YW5jZXNcbiAgICogQHN1bW1hcnkgQSBmdW5jdGlvbiB0aGF0IGNyZWF0ZXMgbmV3IExvZ2dlciBpbnN0YW5jZXMuIEJ5IGRlZmF1bHQsIGl0IGNyZWF0ZXMgYSBNaW5pTG9nZ2VyLlxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgX2ZhY3Rvcnk6IExvZ2dlckZhY3RvcnkgPSAoXG4gICAgb2JqZWN0OiBzdHJpbmcsXG4gICAgY29uZmlnPzogUGFydGlhbDxMb2dnaW5nQ29uZmlnPlxuICApID0+IHtcbiAgICByZXR1cm4gbmV3IE1pbmlMb2dnZXIob2JqZWN0LCBjb25maWcpO1xuICB9O1xuXG4gIHByaXZhdGUgc3RhdGljIF9jb25maWc6IHR5cGVvZiBMb2dnZWRFbnZpcm9ubWVudCA9IExvZ2dlZEVudmlyb25tZW50O1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoKSB7fVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgZmFjdG9yeSBmdW5jdGlvbiBmb3IgY3JlYXRpbmcgbG9nZ2VyIGluc3RhbmNlc1xuICAgKiBAc3VtbWFyeSBBbGxvd3MgY3VzdG9taXppbmcgaG93IGxvZ2dlciBpbnN0YW5jZXMgYXJlIGNyZWF0ZWRcbiAgICogQHBhcmFtIHtMb2dnZXJGYWN0b3J5fSBmYWN0b3J5IC0gVGhlIGZhY3RvcnkgZnVuY3Rpb24gdG8gdXNlIGZvciBjcmVhdGluZyBsb2dnZXJzXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBzdGF0aWMgc2V0RmFjdG9yeShmYWN0b3J5OiBMb2dnZXJGYWN0b3J5KSB7XG4gICAgTG9nZ2luZy5fZmFjdG9yeSA9IGZhY3Rvcnk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFVwZGF0ZXMgdGhlIGdsb2JhbCBsb2dnaW5nIGNvbmZpZ3VyYXRpb25cbiAgICogQHN1bW1hcnkgQWxsb3dzIHVwZGF0aW5nIHRoZSBnbG9iYWwgbG9nZ2luZyBjb25maWd1cmF0aW9uIHdpdGggbmV3IHNldHRpbmdzXG4gICAqIEBwYXJhbSB7UGFydGlhbDxMb2dnaW5nQ29uZmlnPn0gY29uZmlnIC0gVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byBhcHBseVxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgc3RhdGljIHNldENvbmZpZyhjb25maWc6IFBhcnRpYWw8TG9nZ2luZ0NvbmZpZz4pOiB2b2lkIHtcbiAgICBPYmplY3QuZW50cmllcyhjb25maWcpLmZvckVhY2goKFtrLCB2XSkgPT4ge1xuICAgICAgKHRoaXMuX2NvbmZpZyBhcyBhbnkpW2tdID0gdiBhcyBhbnk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEdldHMgYSBjb3B5IG9mIHRoZSBjdXJyZW50IGdsb2JhbCBsb2dnaW5nIGNvbmZpZ3VyYXRpb25cbiAgICogQHN1bW1hcnkgUmV0dXJucyBhIGNvcHkgb2YgdGhlIGN1cnJlbnQgZ2xvYmFsIGxvZ2dpbmcgY29uZmlndXJhdGlvblxuICAgKiBAcmV0dXJuIHtMb2dnaW5nQ29uZmlnfSBBIGNvcHkgb2YgdGhlIGN1cnJlbnQgY29uZmlndXJhdGlvblxuICAgKi9cbiAgc3RhdGljIGdldENvbmZpZygpOiB0eXBlb2YgTG9nZ2VkRW52aXJvbm1lbnQge1xuICAgIHJldHVybiB0aGlzLl9jb25maWc7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBvciBjcmVhdGVzIHRoZSBnbG9iYWwgbG9nZ2VyIGluc3RhbmNlLlxuICAgKiBAc3VtbWFyeSBSZXR1cm5zIHRoZSBleGlzdGluZyBnbG9iYWwgbG9nZ2VyIG9yIGNyZWF0ZXMgYSBuZXcgb25lIGlmIGl0IGRvZXNuJ3QgZXhpc3QuXG4gICAqXG4gICAqIEByZXR1cm4gVGhlIGdsb2JhbCBWZXJib3NpdHlMb2dnZXIgaW5zdGFuY2UuXG4gICAqL1xuICBzdGF0aWMgZ2V0KCk6IExvZ2dlciB7XG4gICAgdGhpcy5nbG9iYWwgPSB0aGlzLmdsb2JhbCA/IHRoaXMuZ2xvYmFsIDogdGhpcy5fZmFjdG9yeShcIkxvZ2dpbmdcIik7XG4gICAgcmV0dXJuIHRoaXMuZ2xvYmFsO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMb2dzIGEgdmVyYm9zZSBtZXNzYWdlLlxuICAgKiBAc3VtbWFyeSBEZWxlZ2F0ZXMgdGhlIHZlcmJvc2UgbG9nZ2luZyB0byB0aGUgZ2xvYmFsIGxvZ2dlciBpbnN0YW5jZS5cbiAgICpcbiAgICogQHBhcmFtIG1zZyAtIFRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZC5cbiAgICogQHBhcmFtIHZlcmJvc2l0eSAtIFRoZSB2ZXJib3NpdHkgbGV2ZWwgb2YgdGhlIG1lc3NhZ2UgKGRlZmF1bHQ6IDApLlxuICAgKi9cbiAgc3RhdGljIHZlcmJvc2UobXNnOiBTdHJpbmdMaWtlLCB2ZXJib3NpdHk6IG51bWJlciA9IDApOiB2b2lkIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoKS52ZXJib3NlKG1zZywgdmVyYm9zaXR5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhbiBpbmZvIG1lc3NhZ2UuXG4gICAqIEBzdW1tYXJ5IERlbGVnYXRlcyB0aGUgaW5mbyBsb2dnaW5nIHRvIHRoZSBnbG9iYWwgbG9nZ2VyIGluc3RhbmNlLlxuICAgKlxuICAgKiBAcGFyYW0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkLlxuICAgKi9cbiAgc3RhdGljIGluZm8obXNnOiBTdHJpbmdMaWtlKTogdm9pZCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KCkuaW5mbyhtc2cpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMb2dzIGEgZGVidWcgbWVzc2FnZS5cbiAgICogQHN1bW1hcnkgRGVsZWdhdGVzIHRoZSBkZWJ1ZyBsb2dnaW5nIHRvIHRoZSBnbG9iYWwgbG9nZ2VyIGluc3RhbmNlLlxuICAgKlxuICAgKiBAcGFyYW0gbXNnIC0gVGhlIG1lc3NhZ2UgdG8gYmUgbG9nZ2VkLlxuICAgKi9cbiAgc3RhdGljIGRlYnVnKG1zZzogU3RyaW5nTGlrZSk6IHZvaWQge1xuICAgIHJldHVybiB0aGlzLmdldCgpLmRlYnVnKG1zZyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYSBiZW5jaG1hcmsgbWVzc2FnZS5cbiAgICogQHN1bW1hcnkgRGVsZWdhdGVzIHRoZSBiZW5jaG1hcmsgbG9nZ2luZyB0byB0aGUgZ2xvYmFsIGxvZ2dlciBpbnN0YW5jZS5cbiAgICpcbiAgICogQHBhcmFtIG1zZyAtIFRoZSBtZXNzYWdlIHRvIGJlIGxvZ2dlZC5cbiAgICovXG4gIHN0YXRpYyBiZW5jaG1hcmsobXNnOiBTdHJpbmdMaWtlKTogdm9pZCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KCkuYmVuY2htYXJrKG1zZyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3MgYSBzaWxseSBtZXNzYWdlLlxuICAgKiBAc3VtbWFyeSBEZWxlZ2F0ZXMgdGhlIGRlYnVnIGxvZ2dpbmcgdG8gdGhlIGdsb2JhbCBsb2dnZXIgaW5zdGFuY2UuXG4gICAqXG4gICAqIEBwYXJhbSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWQuXG4gICAqL1xuICBzdGF0aWMgc2lsbHkobXNnOiBTdHJpbmdMaWtlKTogdm9pZCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KCkuc2lsbHkobXNnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBhbiBlcnJvciBtZXNzYWdlLlxuICAgKiBAc3VtbWFyeSBEZWxlZ2F0ZXMgdGhlIGVycm9yIGxvZ2dpbmcgdG8gdGhlIGdsb2JhbCBsb2dnZXIgaW5zdGFuY2UuXG4gICAqXG4gICAqIEBwYXJhbSBtc2cgLSBUaGUgbWVzc2FnZSB0byBiZSBsb2dnZWQuXG4gICAqIEBwYXJhbSBlXG4gICAqL1xuICBzdGF0aWMgZXJyb3IobXNnOiBTdHJpbmdMaWtlLCBlPzogRXJyb3IpOiB2b2lkIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoKS5lcnJvcihtc2csIGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgbG9nZ2VyIGZvciBhIHNwZWNpZmljIG9iamVjdCBvciBjb250ZXh0XG4gICAqIEBzdW1tYXJ5IENyZWF0ZXMgYSBuZXcgbG9nZ2VyIGluc3RhbmNlIGZvciB0aGUgZ2l2ZW4gb2JqZWN0IG9yIGNvbnRleHQgdXNpbmcgdGhlIGZhY3RvcnkgZnVuY3Rpb25cbiAgICogQHBhcmFtIHtMb2dnaW5nQ29udGV4dH0gb2JqZWN0IC0gVGhlIG9iamVjdCwgY2xhc3MsIG9yIGNvbnRleHQgdG8gY3JlYXRlIGEgbG9nZ2VyIGZvclxuICAgKiBAcGFyYW0ge1BhcnRpYWw8TG9nZ2luZ0NvbmZpZz59IFtjb25maWddIC0gT3B0aW9uYWwgY29uZmlndXJhdGlvbiB0byBvdmVycmlkZSBnbG9iYWwgc2V0dGluZ3NcbiAgICogQHBhcmFtIHsuLi5hbnl9IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBsb2dnZXIgZmFjdG9yeVxuICAgKiBAcmV0dXJuIHtMb2dnZXJ9IEEgbmV3IGxvZ2dlciBpbnN0YW5jZSBmb3IgdGhlIHNwZWNpZmllZCBvYmplY3Qgb3IgY29udGV4dFxuICAgKi9cbiAgc3RhdGljIGZvcihcbiAgICBvYmplY3Q6IExvZ2dpbmdDb250ZXh0LFxuICAgIGNvbmZpZz86IFBhcnRpYWw8TG9nZ2luZ0NvbmZpZz4sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogTG9nZ2VyIHtcbiAgICBvYmplY3QgPVxuICAgICAgdHlwZW9mIG9iamVjdCA9PT0gXCJzdHJpbmdcIlxuICAgICAgICA/IG9iamVjdFxuICAgICAgICA6IG9iamVjdC5jb25zdHJ1Y3RvclxuICAgICAgICAgID8gb2JqZWN0LmNvbnN0cnVjdG9yLm5hbWVcbiAgICAgICAgICA6IG9iamVjdC5uYW1lO1xuICAgIHJldHVybiB0aGlzLl9mYWN0b3J5KG9iamVjdCwgY29uZmlnLCAuLi5hcmdzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIGxvZ2dlciBmb3IgYSBzcGVjaWZpYyByZWFzb24gb3IgY29ycmVsYXRpb24gY29udGV4dFxuICAgKiBAc3VtbWFyeSBVdGlsaXR5IHRvIHF1aWNrbHkgY3JlYXRlIGEgbG9nZ2VyIGxhYmVsZWQgd2l0aCBhIGZyZWUtZm9ybSByZWFzb24gYW5kIG9wdGlvbmFsIGlkZW50aWZpZXJcbiAgICogc28gdGhhdCBhZC1ob2Mgb3BlcmF0aW9ucyBjYW4gYmUgdHJhY2VkIHdpdGhvdXQgdHlpbmcgdGhlIGxvZ2dlciB0byBhIGNsYXNzIG9yIG1ldGhvZCBuYW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcmVhc29uIC0gQSB0ZXh0dWFsIHJlYXNvbiBvciBjb250ZXh0IGxhYmVsIGZvciB0aGlzIGxvZ2dlciBpbnN0YW5jZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2lkXSAtIE9wdGlvbmFsIGlkZW50aWZpZXIgdG8gaGVscCBjb3JyZWxhdGUgcmVsYXRlZCBsb2cgZW50cmllc1xuICAgKiBAcmV0dXJuIHtMb2dnZXJ9IEEgbmV3IGxvZ2dlciBpbnN0YW5jZSBsYWJlbGVkIHdpdGggdGhlIHByb3ZpZGVkIHJlYXNvbiBhbmQgaWRcbiAgICovXG4gIHN0YXRpYyBiZWNhdXNlKHJlYXNvbjogc3RyaW5nLCBpZD86IHN0cmluZyk6IExvZ2dlciB7XG4gICAgcmV0dXJuIHRoaXMuX2ZhY3RvcnkocmVhc29uLCB0aGlzLl9jb25maWcsIGlkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQXBwbGllcyB0aGVtZSBzdHlsaW5nIHRvIHRleHRcbiAgICogQHN1bW1hcnkgQXBwbGllcyBzdHlsaW5nIChjb2xvcnMsIGZvcm1hdHRpbmcpIHRvIHRleHQgYmFzZWQgb24gdGhlIHRoZW1lIGNvbmZpZ3VyYXRpb25cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRleHQgLSBUaGUgdGV4dCB0byBzdHlsZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSAtIFRoZSB0eXBlIG9mIGVsZW1lbnQgdG8gc3R5bGUgKGUuZy4sIFwiY2xhc3NcIiwgXCJtZXNzYWdlXCIsIFwibG9nTGV2ZWxcIilcbiAgICogQHBhcmFtIHtMb2dMZXZlbH0gbG9nZ2VyTGV2ZWwgLSBUaGUgbG9nIGxldmVsIHRvIHVzZSBmb3Igc3R5bGluZ1xuICAgKiBAcGFyYW0ge1RoZW1lfSBbdGVtcGxhdGU9RGVmYXVsdFRoZW1lXSAtIFRoZSB0aGVtZSB0byB1c2UgZm9yIHN0eWxpbmdcbiAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgc3R5bGVkIHRleHRcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQ2FsbGVyXG4gICAqICAgcGFydGljaXBhbnQgVGhlbWUgYXMgTG9nZ2luZy50aGVtZVxuICAgKiAgIHBhcnRpY2lwYW50IEFwcGx5IGFzIGFwcGx5IGZ1bmN0aW9uXG4gICAqICAgcGFydGljaXBhbnQgU3R5bGUgYXMgc3R5bGVkLXN0cmluZy1idWlsZGVyXG4gICAqXG4gICAqICAgQ2FsbGVyLT4+VGhlbWU6IHRoZW1lKHRleHQsIHR5cGUsIGxvZ2dlckxldmVsKVxuICAgKiAgIFRoZW1lLT4+VGhlbWU6IENoZWNrIGlmIHN0eWxpbmcgaXMgZW5hYmxlZFxuICAgKiAgIGFsdCBzdHlsaW5nIGRpc2FibGVkXG4gICAqICAgICBUaGVtZS0tPj5DYWxsZXI6IHJldHVybiBvcmlnaW5hbCB0ZXh0XG4gICAqICAgZWxzZSBzdHlsaW5nIGVuYWJsZWRcbiAgICogICAgIFRoZW1lLT4+VGhlbWU6IEdldCB0aGVtZSBmb3IgdHlwZVxuICAgKiAgICAgYWx0IHRoZW1lIG5vdCBmb3VuZFxuICAgKiAgICAgICBUaGVtZS0tPj5DYWxsZXI6IHJldHVybiBvcmlnaW5hbCB0ZXh0XG4gICAqICAgICBlbHNlIHRoZW1lIGZvdW5kXG4gICAqICAgICAgIFRoZW1lLT4+VGhlbWU6IERldGVybWluZSBhY3R1YWwgdGhlbWUgYmFzZWQgb24gbG9nIGxldmVsXG4gICAqICAgICAgIFRoZW1lLT4+QXBwbHk6IEFwcGx5IGVhY2ggc3R5bGUgcHJvcGVydHlcbiAgICogICAgICAgQXBwbHktPj5TdHlsZTogQXBwbHkgY29sb3JzIGFuZCBmb3JtYXR0aW5nXG4gICAqICAgICAgIFN0eWxlLS0+PkFwcGx5OiBSZXR1cm4gc3R5bGVkIHRleHRcbiAgICogICAgICAgQXBwbHktLT4+VGhlbWU6IFJldHVybiBzdHlsZWQgdGV4dFxuICAgKiAgICAgICBUaGVtZS0tPj5DYWxsZXI6IFJldHVybiBmaW5hbCBzdHlsZWQgdGV4dFxuICAgKiAgICAgZW5kXG4gICAqICAgZW5kXG4gICAqL1xuICBzdGF0aWMgdGhlbWUoXG4gICAgdGV4dDogc3RyaW5nLFxuICAgIHR5cGU6IGtleW9mIFRoZW1lIHwga2V5b2YgTG9nTGV2ZWwsXG4gICAgbG9nZ2VyTGV2ZWw6IExvZ0xldmVsLFxuICAgIHRlbXBsYXRlOiBUaGVtZSA9IERlZmF1bHRUaGVtZVxuICApIHtcbiAgICBpZiAoIXRoaXMuX2NvbmZpZy5zdHlsZSkgcmV0dXJuIHRleHQ7XG4gICAgY29uc3QgbG9nZ2VyID0gTG9nZ2luZy5nZXQoKS5mb3IodGhpcy50aGVtZSk7XG5cbiAgICBmdW5jdGlvbiBhcHBseShcbiAgICAgIHR4dDogc3RyaW5nLFxuICAgICAgb3B0aW9uOiBrZXlvZiBUaGVtZU9wdGlvbixcbiAgICAgIHZhbHVlOiBudW1iZXIgfCBbbnVtYmVyXSB8IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSB8IG51bWJlcltdIHwgc3RyaW5nW11cbiAgICApOiBzdHJpbmcge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgdDogc3RyaW5nIHwgU3R5bGVkU3RyaW5nID0gdHh0O1xuICAgICAgICBsZXQgYyA9IHN0eWxlKHQpO1xuXG4gICAgICAgIGZ1bmN0aW9uIGFwcGx5Q29sb3IoXG4gICAgICAgICAgdmFsOiBudW1iZXIgfCBbbnVtYmVyXSB8IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgICAgICAgICBpc0JnID0gZmFsc2VcbiAgICAgICAgKTogU3R5bGVkU3RyaW5nIHtcbiAgICAgICAgICBsZXQgZjpcbiAgICAgICAgICAgIHwgdHlwZW9mIGMuYmFja2dyb3VuZFxuICAgICAgICAgICAgfCB0eXBlb2YgYy5mb3JlZ3JvdW5kXG4gICAgICAgICAgICB8IHR5cGVvZiBjLnJnYlxuICAgICAgICAgICAgfCB0eXBlb2YgYy5jb2xvcjI1NiA9IGlzQmcgPyBjLmJhY2tncm91bmQgOiBjLmZvcmVncm91bmQ7XG4gICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHZhbCkpIHtcbiAgICAgICAgICAgIHJldHVybiAoZiBhcyB0eXBlb2YgYy5iYWNrZ3JvdW5kIHwgdHlwZW9mIGMuZm9yZWdyb3VuZCkuY2FsbChcbiAgICAgICAgICAgICAgYyxcbiAgICAgICAgICAgICAgdmFsdWUgYXMgbnVtYmVyXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBzd2l0Y2ggKHZhbC5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgICAgZiA9IGlzQmcgPyBjLmJnQ29sb3IyNTYgOiBjLmNvbG9yMjU2O1xuICAgICAgICAgICAgICByZXR1cm4gKGYgYXMgdHlwZW9mIGMuYmdDb2xvcjI1NiB8IHR5cGVvZiBjLmNvbG9yMjU2KSh2YWxbMF0pO1xuICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICBmID0gaXNCZyA/IGMuYmdSZ2IgOiBjLnJnYjtcbiAgICAgICAgICAgICAgcmV0dXJuIGMucmdiKHZhbFswXSwgdmFsWzFdLCB2YWxbMl0pO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGBOb3QgYSB2YWxpZCBjb2xvciBvcHRpb246ICR7b3B0aW9ufWApO1xuICAgICAgICAgICAgICByZXR1cm4gc3R5bGUodCBhcyBzdHJpbmcpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGFwcGx5U3R5bGUodjogbnVtYmVyIHwgc3RyaW5nKTogdm9pZCB7XG4gICAgICAgICAgaWYgKHR5cGVvZiB2ID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICBjID0gYy5zdHlsZSh2KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYyA9IGNbdiBhcyBrZXlvZiBDb2xvcml6ZU9wdGlvbnNdIGFzIFN0eWxlZFN0cmluZztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBzd2l0Y2ggKG9wdGlvbikge1xuICAgICAgICAgIGNhc2UgXCJiZ1wiOlxuICAgICAgICAgIGNhc2UgXCJmZ1wiOlxuICAgICAgICAgICAgcmV0dXJuIGFwcGx5Q29sb3IodmFsdWUgYXMgbnVtYmVyKS50ZXh0O1xuICAgICAgICAgIGNhc2UgXCJzdHlsZVwiOlxuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICAgIHZhbHVlLmZvckVhY2goYXBwbHlTdHlsZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBhcHBseVN0eWxlKHZhbHVlIGFzIG51bWJlciB8IHN0cmluZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gYy50ZXh0O1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoYE5vdCBhIHZhbGlkIHRoZW1lIG9wdGlvbjogJHtvcHRpb259YCk7XG4gICAgICAgICAgICByZXR1cm4gdDtcbiAgICAgICAgfVxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICAgIGxvZ2dlci5lcnJvcihgRXJyb3IgYXBwbHlpbmcgc3R5bGU6ICR7b3B0aW9ufSB3aXRoIHZhbHVlICR7dmFsdWV9YCk7XG4gICAgICAgIHJldHVybiB0eHQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgaW5kaXZpZHVhbFRoZW1lID0gdGVtcGxhdGVbdHlwZSBhcyBrZXlvZiBUaGVtZV07XG4gICAgaWYgKCFpbmRpdmlkdWFsVGhlbWUgfHwgIU9iamVjdC5rZXlzKGluZGl2aWR1YWxUaGVtZSkubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gdGV4dDtcbiAgICB9XG5cbiAgICBsZXQgYWN0dWFsVGhlbWU6IFRoZW1lT3B0aW9uID0gaW5kaXZpZHVhbFRoZW1lIGFzIFRoZW1lT3B0aW9uO1xuXG4gICAgY29uc3QgbG9nTGV2ZWxzID0gT2JqZWN0LmFzc2lnbih7fSwgTG9nTGV2ZWwpO1xuICAgIGlmIChPYmplY3Qua2V5cyhpbmRpdmlkdWFsVGhlbWUpWzBdIGluIGxvZ0xldmVscylcbiAgICAgIGFjdHVhbFRoZW1lID1cbiAgICAgICAgKGluZGl2aWR1YWxUaGVtZSBhcyBUaGVtZU9wdGlvbkJ5TG9nTGV2ZWwpW2xvZ2dlckxldmVsXSB8fCB7fTtcblxuICAgIHJldHVybiBPYmplY3Qua2V5cyhhY3R1YWxUaGVtZSkucmVkdWNlKChhY2M6IHN0cmluZywga2V5OiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IHZhbCA9IChhY3R1YWxUaGVtZSBhcyBUaGVtZU9wdGlvbilba2V5IGFzIGtleW9mIFRoZW1lT3B0aW9uXTtcbiAgICAgIGlmICh2YWwpXG4gICAgICAgIHJldHVybiBhcHBseShcbiAgICAgICAgICBhY2MsXG4gICAgICAgICAga2V5IGFzIGtleW9mIFRoZW1lT3B0aW9uLFxuICAgICAgICAgIHZhbCBhc1xuICAgICAgICAgICAgfCBudW1iZXJcbiAgICAgICAgICAgIHwgW251bWJlcl1cbiAgICAgICAgICAgIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXJdXG4gICAgICAgICAgICB8IG51bWJlcltdXG4gICAgICAgICAgICB8IHN0cmluZ1tdXG4gICAgICAgICk7XG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sIHRleHQpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBMb2dnaW5nIH0gZnJvbSBcIi4vbG9nZ2luZ1wiO1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQmFzZSBjbGFzcyB0aGF0IHByb3ZpZGVzIGEgcmVhZHktdG8tdXNlIGxvZ2dlciBpbnN0YW5jZS5cbiAqIEBzdW1tYXJ5IFN1cHBsaWVzIGluaGVyaXRpbmcgY2xhc3NlcyB3aXRoIGEgbGF6aWx5IGNyZWF0ZWQsIGNvbnRleHQtYXdhcmUge0BsaW5rIExvZ2dlcn0gdmlhIHRoZSBwcm90ZWN0ZWQgYGxvZ2AgZ2V0dGVyLCBwcm9tb3RpbmcgY29uc2lzdGVudCBzdHJ1Y3R1cmVkIGxvZ2dpbmcgd2l0aG91dCBtYW51YWwgd2lyaW5nLlxuICogQGNsYXNzIExvZ2dlZENsYXNzXG4gKiBAZXhhbXBsZVxuICogY2xhc3MgVXNlclNlcnZpY2UgZXh0ZW5kcyBMb2dnZWRDbGFzcyB7XG4gKiAgIGNyZWF0ZSh1c2VyOiBVc2VyKSB7XG4gKiAgICAgdGhpcy5sb2cuaW5mbyhgQ3JlYXRpbmcgdXNlciAke3VzZXIuaWR9YCk7XG4gKiAgIH1cbiAqIH1cbiAqXG4gKiBjb25zdCBzdmMgPSBuZXcgVXNlclNlcnZpY2UoKTtcbiAqIHN2Yy5jcmVhdGUoeyBpZDogXCI0MlwiIH0pO1xuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDbGllbnRcbiAqICAgcGFydGljaXBhbnQgSW5zdGFuY2UgYXMgU3ViY2xhc3MgSW5zdGFuY2VcbiAqICAgcGFydGljaXBhbnQgR2V0dGVyIGFzIExvZ2dlZENsYXNzLmxvZ1xuICogICBwYXJ0aWNpcGFudCBMb2dnaW5nIGFzIExvZ2dpbmdcbiAqICAgcGFydGljaXBhbnQgTG9nZ2VyIGFzIExvZ2dlclxuICpcbiAqICAgQ2xpZW50LT4+SW5zdGFuY2U6IGNhbGwgc29tZU1ldGhvZCgpXG4gKiAgIEluc3RhbmNlLT4+R2V0dGVyOiBhY2Nlc3MgdGhpcy5sb2dcbiAqICAgR2V0dGVyLT4+TG9nZ2luZzogTG9nZ2luZy5mb3IodGhpcylcbiAqICAgTG9nZ2luZy0tPj5HZXR0ZXI6IHJldHVybiBMb2dnZXJcbiAqICAgR2V0dGVyLS0+Pkluc3RhbmNlOiByZXR1cm4gTG9nZ2VyXG4gKiAgIEluc3RhbmNlLT4+TG9nZ2VyOiBpbmZvL2RlYnVnL2Vycm9yKC4uLilcbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIExvZ2dlZENsYXNzIHtcbiAgcHJpdmF0ZSBfbG9nPzogTG9nZ2VyO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTGF6aWx5IHByb3ZpZGVzIGEgY29udGV4dC1hd2FyZSBsb2dnZXIgZm9yIHRoZSBjdXJyZW50IGluc3RhbmNlLlxuICAgKiBAc3VtbWFyeSBDYWxscyB7QGxpbmsgTG9nZ2luZy5mb3J9IHdpdGggdGhlIHN1YmNsYXNzIGluc3RhbmNlIHRvIG9idGFpbiBhIGxvZ2dlciB3aG9zZSBjb250ZXh0IG1hdGNoZXMgdGhlIHN1YmNsYXNzIG5hbWUuXG4gICAqIEByZXR1cm4ge0xvZ2dlcn0gTG9nZ2VyIGJvdW5kIHRvIHRoZSBzdWJjbGFzcyBjb250ZXh0LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldCBsb2coKTogTG9nZ2VyIHtcbiAgICBpZiAoIXRoaXMuX2xvZykgdGhpcy5fbG9nID0gTG9nZ2luZy5mb3IodGhpcyBhcyBhbnkpO1xuICAgIHJldHVybiB0aGlzLl9sb2c7XG4gIH1cblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoKSB7fVxufVxuIiwiaW1wb3J0IHsgTG9nZ2VyLCBMb2dnaW5nQ29uZmlnLCBMb2dnaW5nRmlsdGVyIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBMb2dnZWRDbGFzcyB9IGZyb20gXCIuLi9Mb2dnZWRDbGFzc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBCYXNlIGNsYXNzIGZvciBtZXNzYWdlIGZpbHRlcnMgdGhhdCBwbHVnIGludG8gdGhlIGxvZ2dpbmcgcGlwZWxpbmUuXG4gKiBAc3VtbWFyeSBFeHRlbmRzIHtAbGluayBMb2dnZWRDbGFzc30gdG8gc3VwcGx5IGEgc2NvcGVkIGxvZ2dlciBhbmQgZGVmaW5lcyB0aGUgY29udHJhY3QgcmVxdWlyZWQgYnkge0BsaW5rIExvZ2dpbmdGaWx0ZXJ9IGltcGxlbWVudGVycyB0aGF0IHRyYW5zZm9ybSBvciBkcm9wIGxvZyBtZXNzYWdlcyBiZWZvcmUgZW1pc3Npb24uXG4gKiBAY2xhc3MgTG9nRmlsdGVyXG4gKiBAZXhhbXBsZVxuICogY2xhc3MgUmVkYWN0U2VjcmV0c0ZpbHRlciBleHRlbmRzIExvZ0ZpbHRlciB7XG4gKiAgIGZpbHRlcihjb25maWc6IExvZ2dpbmdDb25maWcsIG1lc3NhZ2U6IHN0cmluZyk6IHN0cmluZyB7XG4gKiAgICAgcmV0dXJuIG1lc3NhZ2UucmVwbGFjZSgvc2VjcmV0L2dpLCBcIioqKlwiKTtcbiAqICAgfVxuICogfVxuICpcbiAqIGNvbnN0IGZpbHRlciA9IG5ldyBSZWRhY3RTZWNyZXRzRmlsdGVyKCk7XG4gKiBmaWx0ZXIuZmlsdGVyKHsgLi4uRGVmYXVsdExvZ2dpbmdDb25maWcsIHZlcmJvc2U6IDAgfSwgXCJzZWNyZXQgdG9rZW5cIik7XG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IExvZ2dlclxuICogICBwYXJ0aWNpcGFudCBGaWx0ZXIgYXMgTG9nRmlsdGVyXG4gKiAgIHBhcnRpY2lwYW50IEltcGwgYXMgQ29uY3JldGVGaWx0ZXJcbiAqICAgcGFydGljaXBhbnQgT3V0cHV0XG4gKiAgIExvZ2dlci0+PkZpbHRlcjogZmlsdGVyKGNvbmZpZywgbWVzc2FnZSwgY29udGV4dClcbiAqICAgRmlsdGVyLT4+SW1wbDogZGVsZWdhdGUgdG8gc3ViY2xhc3MgaW1wbGVtZW50YXRpb25cbiAqICAgSW1wbC0tPj5GaWx0ZXI6IHRyYW5zZm9ybWVkIG1lc3NhZ2VcbiAqICAgRmlsdGVyLS0+Pk91dHB1dDogcmV0dXJuIGZpbHRlcmVkIG1lc3NhZ2VcbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIExvZ0ZpbHRlciBleHRlbmRzIExvZ2dlZENsYXNzIGltcGxlbWVudHMgTG9nZ2luZ0ZpbHRlciB7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2NvcGVkIGxvZ2dlciB0aGF0IGV4Y2x1ZGVzIG90aGVyIGZpbHRlcnMgZnJvbSB0aGUgY2hhaW4uXG4gICAqIEBzdW1tYXJ5IFJldHVybnMgYSBjaGlsZCBsb2dnZXIgZGVkaWNhdGVkIHRvIHRoZSBmaWx0ZXIsIHByZXZlbnRpbmcgcmVjdXJzaXZlIGZpbHRlciBpbnZvY2F0aW9uIHdoZW4gZW1pdHRpbmcgZGlhZ25vc3RpYyBtZXNzYWdlcy5cbiAgICogQHJldHVybiB7TG9nZ2VyfSBDb250ZXh0LWF3YXJlIGxvZ2dlciBmb3IgdGhlIGZpbHRlciBpbnN0YW5jZS5cbiAgICovXG4gIG92ZXJyaWRlIGdldCBsb2coKTogTG9nZ2VyIHtcbiAgICByZXR1cm4gc3VwZXIubG9nLmZvcih0aGlzIGFzIGFueSwgeyBmaWx0ZXJzOiBbXSB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVHJhbnNmb3JtIG9yIHN1cHByZXNzIGEgbG9nIG1lc3NhZ2UuXG4gICAqIEBzdW1tYXJ5IEluc3BlY3QgdGhlIHByb3ZpZGVkIG1lc3NhZ2UgYW5kIGNvbnRleHQgdG8gcHJvZHVjZSB0aGUgdmFsdWUgdGhhdCB3aWxsIGJlIGZvcndhcmRlZCB0byBzdWJzZXF1ZW50IGZpbHRlcnMgb3IgZW1pdHRlcnMuXG4gICAqIEBwYXJhbSB7TG9nZ2luZ0NvbmZpZ30gY29uZmlnIC0gQWN0aXZlIGxvZ2dpbmcgY29uZmlndXJhdGlvbi5cbiAgICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgLSBPcmlnaW5hbCBsb2cgbWVzc2FnZSBwYXlsb2FkLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBjb250ZXh0IC0gQ29udGV4dCB2YWx1ZXMgYXR0YWNoZWQgdG8gdGhlIG1lc3NhZ2UuXG4gICAqIEByZXR1cm4ge3N0cmluZ30gRmlsdGVyZWQgbWVzc2FnZSB0byBwYXNzIHRvIGRvd25zdHJlYW0gcHJvY2Vzc2luZy5cbiAgICovXG4gIGFic3RyYWN0IGZpbHRlcihcbiAgICBjb25maWc6IExvZ2dpbmdDb25maWcsXG4gICAgbWVzc2FnZTogc3RyaW5nLFxuICAgIGNvbnRleHQ6IHN0cmluZ1tdXG4gICk6IHN0cmluZztcbn1cbiIsIi8qKlxuICogQGRlc2NyaXB0aW9uIFNuYXBzaG90IG9mIGEgcmVjb3JkZWQgbGFwIGludGVydmFsLlxuICogQHN1bW1hcnkgQ2FwdHVyZXMgdGhlIGxhcCBpbmRleCwgb3B0aW9uYWwgbGFiZWwsIGVsYXBzZWQgbWlsbGlzZWNvbmRzIGZvciB0aGUgbGFwLCBhbmQgY3VtdWxhdGl2ZSBlbGFwc2VkIHRpbWUgc2luY2UgdGhlIHN0b3B3YXRjaCBzdGFydGVkLlxuICogQHR5cGVkZWYge09iamVjdH0gTGFwXG4gKiBAcHJvcGVydHkge251bWJlcn0gaW5kZXggLSBaZXJvLWJhc2VkIGxhcCBvcmRlci5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbbGFiZWxdIC0gT3B0aW9uYWwgbGFiZWwgZGVzY3JpYmluZyB0aGUgbGFwLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IG1zIC0gRHVyYXRpb24gb2YgdGhlIGxhcCBpbiBtaWxsaXNlY29uZHMuXG4gKiBAcHJvcGVydHkge251bWJlcn0gdG90YWxNcyAtIFRvdGFsIGVsYXBzZWQgdGltZSB3aGVuIHRoZSBsYXAgd2FzIHJlY29yZGVkLlxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCB0eXBlIExhcCA9IHtcbiAgaW5kZXg6IG51bWJlcjtcbiAgbGFiZWw/OiBzdHJpbmc7XG4gIC8qKiBEdXJhdGlvbiBvZiB0aGlzIGxhcCBpbiBtaWxsaXNlY29uZHMgKi9cbiAgbXM6IG51bWJlcjtcbiAgLyoqIEN1bXVsYXRpdmUgdGltZSB1cCB0byB0aGlzIGxhcCBpbiBtaWxsaXNlY29uZHMgKi9cbiAgdG90YWxNczogbnVtYmVyO1xufTtcblxudHlwZSBOb3dGbiA9ICgpID0+IG51bWJlcjsgLy8gbWlsbGlzZWNvbmRzXG5cbmZ1bmN0aW9uIHNhZmVOb3coKTogTm93Rm4ge1xuICAvLyBQcmVmZXIgcGVyZm9ybWFuY2Uubm93IHdoZW4gYXZhaWxhYmxlXG4gIGlmIChcbiAgICB0eXBlb2YgZ2xvYmFsVGhpcyAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgIHR5cGVvZiBnbG9iYWxUaGlzLnBlcmZvcm1hbmNlPy5ub3cgPT09IFwiZnVuY3Rpb25cIlxuICApIHtcbiAgICByZXR1cm4gKCkgPT4gZ2xvYmFsVGhpcy5wZXJmb3JtYW5jZS5ub3coKTtcbiAgfVxuICAvLyBOb2RlOiB1c2UgcHJvY2Vzcy5ocnRpbWUuYmlnaW50IGZvciBoaWdoZXIgcHJlY2lzaW9uIGlmIGF2YWlsYWJsZVxuICBpZiAoXG4gICAgdHlwZW9mIHByb2Nlc3MgIT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICB0eXBlb2YgKHByb2Nlc3MgYXMgYW55KS5ocnRpbWU/LmJpZ2ludCA9PT0gXCJmdW5jdGlvblwiXG4gICkge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBjb25zdCBucyA9IChwcm9jZXNzIGFzIGFueSkuaHJ0aW1lLmJpZ2ludCgpIGFzIGJpZ2ludDsgLy8gbmFub3NlY29uZHNcbiAgICAgIHJldHVybiBOdW1iZXIobnMpIC8gMV8wMDBfMDAwOyAvLyB0byBtc1xuICAgIH07XG4gIH1cbiAgLy8gRmFsbGJhY2tcbiAgcmV0dXJuICgpID0+IERhdGUubm93KCk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEhpZ2gtcmVzb2x1dGlvbiBjbG9jayBhY2Nlc3NvciByZXR1cm5pbmcgbWlsbGlzZWNvbmRzLlxuICogQHN1bW1hcnkgQ2hvb3NlcyB0aGUgbW9zdCBwcmVjaXNlIHRpbWVyIGF2YWlsYWJsZSBpbiB0aGUgY3VycmVudCBydW50aW1lLCBwcmVmZXJyaW5nIGBwZXJmb3JtYW5jZS5ub3dgIG9yIGBwcm9jZXNzLmhydGltZS5iaWdpbnRgLlxuICogQHJldHVybiB7bnVtYmVyfSBNaWxsaXNlY29uZHMgZWxhcHNlZCBhY2NvcmRpbmcgdG8gdGhlIGJlc3QgYXZhaWxhYmxlIGNsb2NrLlxuICovXG5leHBvcnQgY29uc3Qgbm93ID0gc2FmZU5vdygpO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBIaWdoLXJlc29sdXRpb24gc3RvcHdhdGNoIHdpdGggcGF1c2UsIHJlc3VtZSwgYW5kIGxhcCB0cmFja2luZy5cbiAqIEBzdW1tYXJ5IFRyYWNrcyBlbGFwc2VkIHRpbWUgdXNpbmcgdGhlIGhpZ2hlc3QgcHJlY2lzaW9uIHRpbWVyIGF2YWlsYWJsZSwgc3VwcG9ydHMgcGF1c2luZywgcmVzdW1pbmcsIGFuZCByZWNvcmRpbmcgbGFiZWxlZCBsYXBzIGZvciBkaWFnbm9zdGljcyBhbmQgYmVuY2htYXJraW5nLlxuICogQHBhcmFtIHtib29sZWFufSBbYXV0b1N0YXJ0PWZhbHNlXSAtIFdoZW4gdHJ1ZSwgdGhlIHN0b3B3YXRjaCBzdGFydHMgaW1tZWRpYXRlbHkgdXBvbiBjb25zdHJ1Y3Rpb24uXG4gKiBAY2xhc3MgU3RvcFdhdGNoXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgc3cgPSBuZXcgU3RvcFdhdGNoKHRydWUpO1xuICogLy8gLi4uIHdvcmsgLi4uXG4gKiBjb25zdCBsYXAgPSBzdy5sYXAoXCJwaGFzZSAxXCIpO1xuICogc3cucGF1c2UoKTtcbiAqIGNvbnNvbGUubG9nKGBFbGFwc2VkOiAke2xhcC50b3RhbE1zfW1zYCk7XG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICogICBwYXJ0aWNpcGFudCBTdG9wV2F0Y2hcbiAqICAgcGFydGljaXBhbnQgQ2xvY2sgYXMgbm93KClcbiAqICAgQ2xpZW50LT4+U3RvcFdhdGNoOiBzdGFydCgpXG4gKiAgIFN0b3BXYXRjaC0+PkNsb2NrOiBub3coKVxuICogICBDbG9jay0tPj5TdG9wV2F0Y2g6IHRpbWVzdGFtcFxuICogICBDbGllbnQtPj5TdG9wV2F0Y2g6IGxhcCgpXG4gKiAgIFN0b3BXYXRjaC0+PkNsb2NrOiBub3coKVxuICogICBDbG9jay0tPj5TdG9wV2F0Y2g6IHRpbWVzdGFtcFxuICogICBTdG9wV2F0Y2gtLT4+Q2xpZW50OiBMYXBcbiAqICAgQ2xpZW50LT4+U3RvcFdhdGNoOiBwYXVzZSgpXG4gKiAgIFN0b3BXYXRjaC0+PkNsb2NrOiBub3coKVxuICogICBDbG9jay0tPj5TdG9wV2F0Y2g6IHRpbWVzdGFtcFxuICovXG5leHBvcnQgY2xhc3MgU3RvcFdhdGNoIHtcbiAgcHJpdmF0ZSBfc3RhcnRNczogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgX2VsYXBzZWRNcyA9IDA7XG4gIHByaXZhdGUgX3J1bm5pbmcgPSBmYWxzZTtcbiAgcHJpdmF0ZSBfbGFwczogTGFwW10gPSBbXTtcbiAgcHJpdmF0ZSBfbGFzdExhcFRvdGFsTXMgPSAwO1xuXG4gIGNvbnN0cnVjdG9yKGF1dG9TdGFydCA9IGZhbHNlKSB7XG4gICAgaWYgKGF1dG9TdGFydCkgdGhpcy5zdGFydCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgc3RvcHdhdGNoIGlzIGFjdGl2ZWx5IHJ1bm5pbmcuXG4gICAqIEBzdW1tYXJ5IFJldHVybnMgYHRydWVgIHdoZW4gdGltaW5nIGlzIGluIHByb2dyZXNzIGFuZCBgZmFsc2VgIHdoZW4gcGF1c2VkIG9yIHN0b3BwZWQuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IEN1cnJlbnQgcnVubmluZyBzdGF0ZS5cbiAgICovXG4gIGdldCBydW5uaW5nKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9ydW5uaW5nO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBFbGFwc2VkIHRpbWUgY2FwdHVyZWQgYnkgdGhlIHN0b3B3YXRjaC5cbiAgICogQHN1bW1hcnkgQ29tcHV0ZXMgdGhlIHRvdGFsIGVsYXBzZWQgdGltZSBpbiBtaWxsaXNlY29uZHMsIGluY2x1ZGluZyB0aGUgY3VycmVudCBzZXNzaW9uIGlmIHJ1bm5pbmcuXG4gICAqIEByZXR1cm4ge251bWJlcn0gTWlsbGlzZWNvbmRzIGVsYXBzZWQgc2luY2UgdGhlIHN0b3B3YXRjaCBzdGFydGVkLlxuICAgKi9cbiAgZ2V0IGVsYXBzZWRNcygpOiBudW1iZXIge1xuICAgIGlmICghdGhpcy5fcnVubmluZyB8fCB0aGlzLl9zdGFydE1zID09IG51bGwpIHJldHVybiB0aGlzLl9lbGFwc2VkTXM7XG4gICAgcmV0dXJuIHRoaXMuX2VsYXBzZWRNcyArIChub3coKSAtIHRoaXMuX3N0YXJ0TXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTdGFydHMgdGltaW5nIGlmIHRoZSBzdG9wd2F0Y2ggaXMgbm90IGFscmVhZHkgcnVubmluZy5cbiAgICogQHN1bW1hcnkgUmVjb3JkcyB0aGUgY3VycmVudCB0aW1lc3RhbXAgYW5kIHRyYW5zaXRpb25zIHRoZSBzdG9wd2F0Y2ggaW50byB0aGUgcnVubmluZyBzdGF0ZS5cbiAgICogQHJldHVybiB7dGhpc30gRmx1ZW50IHJlZmVyZW5jZSB0byB0aGUgc3RvcHdhdGNoLlxuICAgKi9cbiAgc3RhcnQoKTogdGhpcyB7XG4gICAgaWYgKCF0aGlzLl9ydW5uaW5nKSB7XG4gICAgICB0aGlzLl9ydW5uaW5nID0gdHJ1ZTtcbiAgICAgIHRoaXMuX3N0YXJ0TXMgPSBub3coKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFBhdXNlcyB0aW1pbmcgYW5kIGFjY3VtdWxhdGVzIGVsYXBzZWQgbWlsbGlzZWNvbmRzLlxuICAgKiBAc3VtbWFyeSBDYXB0dXJlcyB0aGUgcGFydGlhbCBkdXJhdGlvbiwgdXBkYXRlcyB0aGUgYWNjdW11bGF0b3IsIGFuZCBrZWVwcyB0aGUgc3RvcHdhdGNoIHJlYWR5IHRvIHJlc3VtZSBsYXRlci5cbiAgICogQHJldHVybiB7dGhpc30gRmx1ZW50IHJlZmVyZW5jZSB0byB0aGUgc3RvcHdhdGNoLlxuICAgKi9cbiAgcGF1c2UoKTogdGhpcyB7XG4gICAgaWYgKHRoaXMuX3J1bm5pbmcgJiYgdGhpcy5fc3RhcnRNcyAhPSBudWxsKSB7XG4gICAgICB0aGlzLl9lbGFwc2VkTXMgKz0gbm93KCkgLSB0aGlzLl9zdGFydE1zO1xuICAgICAgdGhpcy5fc3RhcnRNcyA9IG51bGw7XG4gICAgICB0aGlzLl9ydW5uaW5nID0gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXN1bWVzIHRpbWluZyBhZnRlciBhIHBhdXNlLlxuICAgKiBAc3VtbWFyeSBDYXB0dXJlcyBhIGZyZXNoIHN0YXJ0IHRpbWVzdGFtcCB3aGlsZSBrZWVwaW5nIHByZXZpb3VzIGVsYXBzZWQgdGltZSBpbnRhY3QuXG4gICAqIEByZXR1cm4ge3RoaXN9IEZsdWVudCByZWZlcmVuY2UgdG8gdGhlIHN0b3B3YXRjaC5cbiAgICovXG4gIHJlc3VtZSgpOiB0aGlzIHtcbiAgICBpZiAoIXRoaXMuX3J1bm5pbmcpIHtcbiAgICAgIHRoaXMuX3J1bm5pbmcgPSB0cnVlO1xuICAgICAgdGhpcy5fc3RhcnRNcyA9IG5vdygpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU3RvcHMgdGltaW5nIGFuZCByZXR1cm5zIHRoZSB0b3RhbCBlbGFwc2VkIG1pbGxpc2Vjb25kcy5cbiAgICogQHN1bW1hcnkgSW52b2tlcyB7QGxpbmsgU3RvcFdhdGNoLnBhdXNlfSB0byBjb25zb2xpZGF0ZSBlbGFwc2VkIHRpbWUsIGxlYXZpbmcgdGhlIHN0b3B3YXRjaCBpbiBhIG5vbi1ydW5uaW5nIHN0YXRlLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IE1pbGxpc2Vjb25kcyBhY2N1bXVsYXRlZCBhY3Jvc3MgYWxsIHJ1bnMuXG4gICAqL1xuICBzdG9wKCk6IG51bWJlciB7XG4gICAgdGhpcy5wYXVzZSgpO1xuICAgIHJldHVybiB0aGlzLl9lbGFwc2VkTXM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlc2V0cyB0aGUgc3RvcHdhdGNoIHN0YXRlIHdoaWxlIG9wdGlvbmFsbHkgY29udGludWluZyB0byBydW4uXG4gICAqIEBzdW1tYXJ5IENsZWFycyBlbGFwc2VkIHRpbWUgYW5kIGxhcCBoaXN0b3J5LCBwcmVzZXJ2aW5nIHdoZXRoZXIgdGhlIHN0b3B3YXRjaCBzaG91bGQgY29udGludWUgdGlja2luZy5cbiAgICogQHJldHVybiB7dGhpc30gRmx1ZW50IHJlZmVyZW5jZSB0byB0aGUgc3RvcHdhdGNoLlxuICAgKi9cbiAgcmVzZXQoKTogdGhpcyB7XG4gICAgY29uc3Qgd2FzUnVubmluZyA9IHRoaXMuX3J1bm5pbmc7XG4gICAgdGhpcy5fc3RhcnRNcyA9IHdhc1J1bm5pbmcgPyBub3coKSA6IG51bGw7XG4gICAgdGhpcy5fZWxhcHNlZE1zID0gMDtcbiAgICB0aGlzLl9sYXBzID0gW107XG4gICAgdGhpcy5fbGFzdExhcFRvdGFsTXMgPSAwO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZWNvcmRzIGEgbGFwIHNwbGl0IHNpbmNlIHRoZSBzdG9wd2F0Y2ggc3RhcnRlZCBvciBzaW5jZSB0aGUgcHJldmlvdXMgbGFwLlxuICAgKiBAc3VtbWFyeSBTdG9yZXMgdGhlIGxhcCBtZXRhZGF0YSwgdXBkYXRlcyBjdW11bGF0aXZlIHRyYWNraW5nLCBhbmQgcmV0dXJucyB0aGUgbmV3bHkgY3JlYXRlZCB7QGxpbmsgTGFwfS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtsYWJlbF0gLSBPcHRpb25hbCBsYWJlbCBkZXNjcmliaW5nIHRoZSBsYXAuXG4gICAqIEByZXR1cm4ge0xhcH0gTGFwIHNuYXBzaG90IGNhcHR1cmluZyBpbmNyZW1lbnRhbCBhbmQgY3VtdWxhdGl2ZSB0aW1pbmdzLlxuICAgKi9cbiAgbGFwKGxhYmVsPzogc3RyaW5nKTogTGFwIHtcbiAgICBjb25zdCB0b3RhbCA9IHRoaXMuZWxhcHNlZE1zO1xuICAgIGNvbnN0IG1zID0gdG90YWwgLSB0aGlzLl9sYXN0TGFwVG90YWxNcztcbiAgICBjb25zdCBsYXA6IExhcCA9IHtcbiAgICAgIGluZGV4OiB0aGlzLl9sYXBzLmxlbmd0aCxcbiAgICAgIGxhYmVsLFxuICAgICAgbXMsXG4gICAgICB0b3RhbE1zOiB0b3RhbCxcbiAgICB9O1xuICAgIHRoaXMuX2xhcHMucHVzaChsYXApO1xuICAgIHRoaXMuX2xhc3RMYXBUb3RhbE1zID0gdG90YWw7XG4gICAgcmV0dXJuIGxhcDtcbiAgfVxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyB0aGUgcmVjb3JkZWQgbGFwIGhpc3RvcnkuXG4gICAqIEBzdW1tYXJ5IFJldHVybnMgdGhlIGludGVybmFsIGxhcCBhcnJheSBhcyBhIHJlYWQtb25seSB2aWV3IHRvIHByZXZlbnQgZXh0ZXJuYWwgbXV0YXRpb24uXG4gICAqIEByZXR1cm4ge0xhcFtdfSBMYXBzIGNhcHR1cmVkIGJ5IHRoZSBzdG9wd2F0Y2guXG4gICAqL1xuICBnZXQgbGFwcygpOiByZWFkb25seSBMYXBbXSB7XG4gICAgcmV0dXJuIHRoaXMuX2xhcHM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEZvcm1hdHMgdGhlIGVsYXBzZWQgdGltZSBpbiBhIGh1bWFuLXJlYWRhYmxlIHJlcHJlc2VudGF0aW9uLlxuICAgKiBAc3VtbWFyeSBVc2VzIHtAbGluayBmb3JtYXRNc30gdG8gcHJvZHVjZSBhbiBgaGg6bW06c3MubW1tYCBzdHJpbmcgZm9yIGRpc3BsYXkgYW5kIGxvZ2dpbmcuXG4gICAqIEByZXR1cm4ge3N0cmluZ30gRWxhcHNlZCB0aW1lIGZvcm1hdHRlZCBmb3IgcHJlc2VudGF0aW9uLlxuICAgKi9cbiAgdG9TdHJpbmcoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gZm9ybWF0TXModGhpcy5lbGFwc2VkTXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXJpYWxpemVzIHRoZSBzdG9wd2F0Y2ggc3RhdGUuXG4gICAqIEBzdW1tYXJ5IFByb3ZpZGVzIGEgSlNPTi1mcmllbmRseSBzbmFwc2hvdCBpbmNsdWRpbmcgcnVubmluZyBzdGF0ZSwgZWxhcHNlZCB0aW1lLCBhbmQgbGFwIGRldGFpbHMuXG4gICAqIEByZXR1cm4ge3tydW5uaW5nOiBib29sZWFuLCBlbGFwc2VkTXM6IG51bWJlciwgbGFwczogTGFwW119fSBTZXJpYWxpemFibGUgc3RvcHdhdGNoIHJlcHJlc2VudGF0aW9uLlxuICAgKi9cbiAgdG9KU09OKCkge1xuICAgIHJldHVybiB7XG4gICAgICBydW5uaW5nOiB0aGlzLl9ydW5uaW5nLFxuICAgICAgZWxhcHNlZE1zOiB0aGlzLmVsYXBzZWRNcyxcbiAgICAgIGxhcHM6IHRoaXMuX2xhcHMuc2xpY2UoKSxcbiAgICB9O1xuICB9XG59XG4vKipcbiAqIEBkZXNjcmlwdGlvbiBGb3JtYXRzIG1pbGxpc2Vjb25kcyBpbnRvIGBoaDptbTpzcy5tbW1gLlxuICogQHN1bW1hcnkgQnJlYWtzIHRoZSBkdXJhdGlvbiBpbnRvIGhvdXJzLCBtaW51dGVzLCBzZWNvbmRzLCBhbmQgbWlsbGlzZWNvbmRzLCByZXR1cm5pbmcgYSB6ZXJvLXBhZGRlZCBzdHJpbmcuXG4gKiBAcGFyYW0ge251bWJlcn0gbXMgLSBNaWxsaXNlY29uZHMgdG8gZm9ybWF0LlxuICogQHJldHVybiB7c3RyaW5nfSBGb3JtYXR0ZWQgZHVyYXRpb24gc3RyaW5nLlxuICogQGZ1bmN0aW9uIGZvcm1hdE1zXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2FsbGVyXG4gKiAgIHBhcnRpY2lwYW50IEZvcm1hdHRlciBhcyBmb3JtYXRNc1xuICogICBDYWxsZXItPj5Gb3JtYXR0ZXI6IGZvcm1hdE1zKG1zKVxuICogICBGb3JtYXR0ZXItPj5Gb3JtYXR0ZXI6IGRlcml2ZSBob3Vycy9taW51dGVzL3NlY29uZHNcbiAqICAgRm9ybWF0dGVyLT4+Rm9ybWF0dGVyOiBwYWQgc2VnbWVudHNcbiAqICAgRm9ybWF0dGVyLS0+PkNhbGxlcjogaGg6bW06c3MubW1tXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmb3JtYXRNcyhtczogbnVtYmVyKTogc3RyaW5nIHtcbiAgY29uc3Qgc2lnbiA9IG1zIDwgMCA/IFwiLVwiIDogXCJcIjtcbiAgY29uc3QgYWJzID0gTWF0aC5hYnMobXMpO1xuICBjb25zdCBob3VycyA9IE1hdGguZmxvb3IoYWJzIC8gM182MDBfMDAwKTtcbiAgY29uc3QgbWludXRlcyA9IE1hdGguZmxvb3IoKGFicyAlIDNfNjAwXzAwMCkgLyA2MF8wMDApO1xuICBjb25zdCBzZWNvbmRzID0gTWF0aC5mbG9vcigoYWJzICUgNjBfMDAwKSAvIDEwMDApO1xuICBjb25zdCBtaWxsaXMgPSBNYXRoLmZsb29yKGFicyAlIDEwMDApO1xuICBjb25zdCBwYWQgPSAobjogbnVtYmVyLCB3OiBudW1iZXIpID0+IG4udG9TdHJpbmcoKS5wYWRTdGFydCh3LCBcIjBcIik7XG4gIHJldHVybiBgJHtzaWdufSR7cGFkKGhvdXJzLCAyKX06JHtwYWQobWludXRlcywgMil9OiR7cGFkKHNlY29uZHMsIDIpfS4ke3BhZChtaWxsaXMsIDMpfWA7XG59XG4iLCJpbXBvcnQgeyBMb2dMZXZlbCB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgTG9nZ2luZyB9IGZyb20gXCIuL2xvZ2dpbmdcIjtcbmltcG9ydCB7IG5vdyB9IGZyb20gXCIuL3RpbWVcIjtcbmltcG9ydCB7IExvZ2dlZENsYXNzIH0gZnJvbSBcIi4vTG9nZ2VkQ2xhc3NcIjtcbmltcG9ydCB7IExvZ2dlciB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbmV4cG9ydCB0eXBlIEFyZ0Zvcm1hdEZ1bmN0aW9uID0gKC4uLmFyZ3M6IGFueVtdKSA9PiBzdHJpbmc7XG5leHBvcnQgdHlwZSBSZXR1cm5Gb3JtYXRGdW5jdGlvbiA9IChlPzogRXJyb3IsIHJlc3VsdD86IGFueSkgPT4gc3RyaW5nO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBNZXRob2QgZGVjb3JhdG9yIGZvciBsb2dnaW5nIGZ1bmN0aW9uIGNhbGxzLlxuICogQHN1bW1hcnkgV3JhcHMgY2xhc3MgbWV0aG9kcyB0byBhdXRvbWF0aWNhbGx5IGxvZyBlbnRyeSwgZXhpdCwgdGltaW5nLCBhbmQgb3B0aW9uYWwgY3VzdG9tIG1lc3NhZ2VzIGF0IGEgY29uZmlndXJhYmxlIHtAbGluayBMb2dMZXZlbH0uXG4gKiBAcGFyYW0ge0xvZ0xldmVsfSBsZXZlbCAtIExvZyBsZXZlbCBhcHBsaWVkIHRvIHRoZSBnZW5lcmF0ZWQgbG9nIHN0YXRlbWVudHMgKGRlZmF1bHRzIHRvIGBMb2dMZXZlbC5pbmZvYCkuXG4gKiBAcGFyYW0ge251bWJlcn0gW3ZlcmJvc2l0eT0wXSAtIFZlcmJvc2l0eSB0aHJlc2hvbGQgcmVxdWlyZWQgZm9yIHRoZSBlbnRyeSBsb2cgdG8gYXBwZWFyLlxuICogQHBhcmFtIHtBcmdGb3JtYXRGdW5jdGlvbn0gW2VudHJ5TWVzc2FnZV0gLSBGb3JtYXR0ZXIgaW52b2tlZCB3aXRoIHRoZSBvcmlnaW5hbCBtZXRob2QgYXJndW1lbnRzIHRvIGRlc2NyaWJlIHRoZSBpbnZvY2F0aW9uLlxuICogQHBhcmFtIHtSZXR1cm5Gb3JtYXRGdW5jdGlvbn0gW2V4aXRNZXNzYWdlXSAtIE9wdGlvbmFsIGZvcm1hdHRlciB0aGF0IGRlc2NyaWJlcyB0aGUgb3V0Y29tZSBvciBmYWlsdXJlIG9mIHRoZSBjYWxsLlxuICogQHJldHVybiB7ZnVuY3Rpb24oYW55LCBhbnksIFByb3BlcnR5RGVzY3JpcHRvcik6IHZvaWR9IE1ldGhvZCBkZWNvcmF0b3IgcHJveHkgdGhhdCBpbmplY3RzIGxvZ2dpbmcgYmVoYXZpb3IuXG4gKiBAZnVuY3Rpb24gbG9nXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICogICBwYXJ0aWNpcGFudCBEZWNvcmF0b3IgYXMgbG9nIGRlY29yYXRvclxuICogICBwYXJ0aWNpcGFudCBNZXRob2QgYXMgT3JpZ2luYWwgTWV0aG9kXG4gKiAgIHBhcnRpY2lwYW50IExvZ2dlciBhcyBMb2dnaW5nIGluc3RhbmNlXG4gKlxuICogICBDbGllbnQtPj5EZWNvcmF0b3I6IGNhbGwgZGVjb3JhdGVkIG1ldGhvZFxuICogICBEZWNvcmF0b3ItPj5Mb2dnZXI6IGxvZyBtZXRob2QgY2FsbFxuICogICBEZWNvcmF0b3ItPj5NZXRob2Q6IGNhbGwgb3JpZ2luYWwgbWV0aG9kXG4gKiAgIGFsdCByZXN1bHQgaXMgUHJvbWlzZVxuICogICAgIE1ldGhvZC0tPj5EZWNvcmF0b3I6IHJldHVybiBQcm9taXNlXG4gKiAgICAgRGVjb3JhdG9yLT4+RGVjb3JhdG9yOiBhdHRhY2ggdGhlbiBoYW5kbGVyXG4gKiAgICAgTm90ZSBvdmVyIERlY29yYXRvcjogUHJvbWlzZSByZXNvbHZlc1xuICogICAgIERlY29yYXRvci0+PkxvZ2dlcjogbG9nIGJlbmNobWFyayAoaWYgZW5hYmxlZClcbiAqICAgICBEZWNvcmF0b3ItLT4+Q2xpZW50OiByZXR1cm4gcmVzdWx0XG4gKiAgIGVsc2UgcmVzdWx0IGlzIG5vdCBQcm9taXNlXG4gKiAgICAgTWV0aG9kLS0+PkRlY29yYXRvcjogcmV0dXJuIHJlc3VsdFxuICogICAgIERlY29yYXRvci0+PkxvZ2dlcjogbG9nIGJlbmNobWFyayAoaWYgZW5hYmxlZClcbiAqICAgICBEZWNvcmF0b3ItLT4+Q2xpZW50OiByZXR1cm4gcmVzdWx0XG4gKiAgIGVuZFxuICogQGNhdGVnb3J5IE1ldGhvZCBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsb2coXG4gIGxldmVsOiBMb2dMZXZlbCA9IExvZ0xldmVsLmluZm8sXG4gIHZlcmJvc2l0eSA9IDAsXG4gIGVudHJ5TWVzc2FnZTogQXJnRm9ybWF0RnVuY3Rpb24gPSAoLi4uYXJnczogYW55W10pID0+IGBjYWxsZWQgd2l0aCAke2FyZ3N9YCxcbiAgZXhpdE1lc3NhZ2U/OiBSZXR1cm5Gb3JtYXRGdW5jdGlvblxuKSB7XG4gIHJldHVybiBmdW5jdGlvbiBsb2codGFyZ2V0OiBhbnksIHByb3BlcnR5S2V5PzogYW55LCBkZXNjcmlwdG9yPzogYW55KSB7XG4gICAgaWYgKCFkZXNjcmlwdG9yIHx8IHR5cGVvZiBkZXNjcmlwdG9yID09PSBcIm51bWJlclwiKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBMb2dnaW5nIGRlY29yYXRpb24gb25seSBhcHBsaWVzIHRvIG1ldGhvZHNgKTtcbiAgICBjb25zdCBsb2dnZXI6IExvZ2dlciA9XG4gICAgICB0YXJnZXQgaW5zdGFuY2VvZiBMb2dnZWRDbGFzc1xuICAgICAgICA/IHRhcmdldFtcImxvZ1wiXS5mb3IodGFyZ2V0W3Byb3BlcnR5S2V5IGFzIGtleW9mIHR5cGVvZiB0YXJnZXRdKVxuICAgICAgICA6IExvZ2dpbmcuZm9yKHRhcmdldCkuZm9yKHRhcmdldFtwcm9wZXJ0eUtleV0pO1xuICAgIGNvbnN0IG1ldGhvZCA9IGxvZ2dlcltsZXZlbF0uYmluZChsb2dnZXIpIGFzIGFueTtcbiAgICBjb25zdCBvcmlnaW5hbE1ldGhvZCA9IGRlc2NyaXB0b3IudmFsdWU7XG5cbiAgICBkZXNjcmlwdG9yLnZhbHVlID0gbmV3IFByb3h5KG9yaWdpbmFsTWV0aG9kLCB7XG4gICAgICBhcHBseShmbiwgdGhpc0FyZywgYXJnczogYW55W10pIHtcbiAgICAgICAgbWV0aG9kKGVudHJ5TWVzc2FnZSguLi5hcmdzKSwgdmVyYm9zaXR5KTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBSZWZsZWN0LmFwcGx5KGZuLCB0aGlzQXJnLCBhcmdzKTtcbiAgICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdFxuICAgICAgICAgICAgICAudGhlbigocjogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGV4aXRNZXNzYWdlKSBtZXRob2QoZXhpdE1lc3NhZ2UodW5kZWZpbmVkLCByKSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHI7XG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgIC5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChleGl0TWVzc2FnZSkgbG9nZ2VyLmVycm9yKGV4aXRNZXNzYWdlKGUgYXMgRXJyb3IpKTtcbiAgICAgICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGV4aXRNZXNzYWdlKSBtZXRob2QoZXhpdE1lc3NhZ2UodW5kZWZpbmVkLCByZXN1bHQpKTtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9IGNhdGNoIChlcnI6IHVua25vd24pIHtcbiAgICAgICAgICBpZiAoZXhpdE1lc3NhZ2UpIGxvZ2dlci5lcnJvcihleGl0TWVzc2FnZShlcnIgYXMgRXJyb3IpKTtcbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSk7XG4gICAgcmV0dXJuIGRlc2NyaXB0b3I7XG4gIH07XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE1ldGhvZCBkZWNvcmF0b3IgdGhhdCByZWNvcmRzIGV4ZWN1dGlvbiB0aW1lIGF0IHRoZSBiZW5jaG1hcmsgbGV2ZWwuXG4gKiBAc3VtbWFyeSBXcmFwcyB0aGUgdGFyZ2V0IG1ldGhvZCB0byBlbWl0IHtAbGluayBMb2dnZXIuYmVuY2htYXJrfSBlbnRyaWVzIGNhcHR1cmluZyBjb21wbGV0aW9uIHRpbWUgb3IgZmFpbHVyZSBsYXRlbmN5LlxuICogQHJldHVybiB7ZnVuY3Rpb24oYW55LCBhbnksICBQcm9wZXJ0eURlc2NyaXB0b3IpOiB2b2lkfSBNZXRob2QgZGVjb3JhdG9yIHByb3h5IHRoYXQgYmVuY2htYXJrcyB0aGUgb3JpZ2luYWwgaW1wbGVtZW50YXRpb24uXG4gKiBAZnVuY3Rpb24gYmVuY2htYXJrXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IENhbGxlclxuICogICBwYXJ0aWNpcGFudCBEZWNvcmF0b3IgYXMgYmVuY2htYXJrXG4gKiAgIHBhcnRpY2lwYW50IE1ldGhvZCBhcyBPcmlnaW5hbCBNZXRob2RcbiAqICAgQ2FsbGVyLT4+RGVjb3JhdG9yOiBpbnZva2UoKVxuICogICBEZWNvcmF0b3ItPj5NZXRob2Q6IFJlZmxlY3QuYXBwbHkoLi4uKVxuICogICBhbHQgUHJvbWlzZSByZXN1bHRcbiAqICAgICBNZXRob2QtLT4+RGVjb3JhdG9yOiBQcm9taXNlXG4gKiAgICAgRGVjb3JhdG9yLT4+RGVjb3JhdG9yOiBhdHRhY2ggdGhlbigpXG4gKiAgICAgRGVjb3JhdG9yLT4+RGVjb3JhdG9yOiBsb2cgY29tcGxldGlvbiBkdXJhdGlvblxuICogICBlbHNlIFN5bmNocm9ub3VzIHJlc3VsdFxuICogICAgIE1ldGhvZC0tPj5EZWNvcmF0b3I6IHZhbHVlXG4gKiAgICAgRGVjb3JhdG9yLT4+RGVjb3JhdG9yOiBsb2cgY29tcGxldGlvbiBkdXJhdGlvblxuICogICBlbmRcbiAqICAgRGVjb3JhdG9yLS0+PkNhbGxlcjogcmV0dXJuIHJlc3VsdFxuICogQGNhdGVnb3J5IE1ldGhvZCBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBiZW5jaG1hcmsoKSB7XG4gIHJldHVybiBmdW5jdGlvbiBiZW5jaG1hcmsodGFyZ2V0OiBhbnksIHByb3BlcnR5S2V5PzogYW55LCBkZXNjcmlwdG9yPzogYW55KSB7XG4gICAgaWYgKCFkZXNjcmlwdG9yIHx8IHR5cGVvZiBkZXNjcmlwdG9yID09PSBcIm51bWJlclwiKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBiZW5jaG1hcmsgZGVjb3JhdGlvbiBvbmx5IGFwcGxpZXMgdG8gbWV0aG9kc2ApO1xuICAgIGNvbnN0IGxvZ2dlcjogTG9nZ2VyID1cbiAgICAgIHRhcmdldCBpbnN0YW5jZW9mIExvZ2dlZENsYXNzXG4gICAgICAgID8gdGFyZ2V0W1wibG9nXCJdLmZvcih0YXJnZXRbcHJvcGVydHlLZXkgYXMga2V5b2YgdHlwZW9mIHRhcmdldF0pXG4gICAgICAgIDogTG9nZ2luZy5mb3IodGFyZ2V0KS5mb3IodGFyZ2V0W3Byb3BlcnR5S2V5XSk7XG4gICAgY29uc3Qgb3JpZ2luYWxNZXRob2QgPSBkZXNjcmlwdG9yLnZhbHVlO1xuXG4gICAgZGVzY3JpcHRvci52YWx1ZSA9IG5ldyBQcm94eShvcmlnaW5hbE1ldGhvZCwge1xuICAgICAgYXBwbHkoZm4sIHRoaXNBcmcsIGFyZ3M6IGFueVtdKSB7XG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gbm93KCk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gUmVmbGVjdC5hcHBseShmbiwgdGhpc0FyZywgYXJncyk7XG4gICAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQudGhlbigocjogYW55KSA9PiB7XG4gICAgICAgICAgICAgIGxvZ2dlci5iZW5jaG1hcmsoYGNvbXBsZXRlZCBpbiAke25vdygpIC0gc3RhcnR9bXNgKTtcbiAgICAgICAgICAgICAgcmV0dXJuIHI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgbG9nZ2VyLmJlbmNobWFyayhgY29tcGxldGVkIGluICR7bm93KCkgLSBzdGFydH1tc2ApO1xuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH0gY2F0Y2ggKGVycjogdW5rbm93bikge1xuICAgICAgICAgIGxvZ2dlci5iZW5jaG1hcmsoYGZhaWxlZCBpbiAke25vdygpIC0gc3RhcnR9bXNgKTtcbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICByZXR1cm4gZGVzY3JpcHRvcjtcbiAgfTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gTWV0aG9kIGRlY29yYXRvciBmb3IgbG9nZ2luZyBmdW5jdGlvbiBjYWxscyB3aXRoIGRlYnVnIGxldmVsLlxuICogQHN1bW1hcnkgQ29udmVuaWVuY2Ugd3JhcHBlciBhcm91bmQge0BsaW5rIGxvZ30gdGhhdCBsb2dzIHVzaW5nIGBMb2dMZXZlbC5kZWJ1Z2AuXG4gKiBAcmV0dXJuIHtmdW5jdGlvbihhbnksIGFueSwgUHJvcGVydHlEZXNjcmlwdG9yKTogdm9pZH0gRGVidWctbGV2ZWwgbG9nZ2luZyBkZWNvcmF0b3IuXG4gKiBAZnVuY3Rpb24gZGVidWdcbiAqIEBjYXRlZ29yeSBNZXRob2QgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZGVidWcoKSB7XG4gIHJldHVybiBsb2coXG4gICAgTG9nTGV2ZWwuZGVidWcsXG4gICAgMCxcbiAgICAoLi4uYXJnczogYW55W10pID0+IGBjYWxsZWQgd2l0aCAke2FyZ3N9YCxcbiAgICAoZT86IEVycm9yLCByZXN1bHQ/OiBhbnkpID0+XG4gICAgICBlXG4gICAgICAgID8gYEZhaWxlZCB3aXRoOiAke2V9YFxuICAgICAgICA6IHJlc3VsdFxuICAgICAgICAgID8gYENvbXBsZXRlZCB3aXRoICR7SlNPTi5zdHJpbmdpZnkocmVzdWx0KX1gXG4gICAgICAgICAgOiBcImNvbXBsZXRlZFwiXG4gICk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE1ldGhvZCBkZWNvcmF0b3IgZm9yIGxvZ2dpbmcgZnVuY3Rpb24gY2FsbHMgd2l0aCBpbmZvIGxldmVsLlxuICogQHN1bW1hcnkgQ29udmVuaWVuY2Ugd3JhcHBlciBhcm91bmQge0BsaW5rIGxvZ30gdGhhdCBsb2dzIHVzaW5nIGBMb2dMZXZlbC5pbmZvYC5cbiAqIEByZXR1cm4ge2Z1bmN0aW9uKGFueSwgYW55LCBQcm9wZXJ0eURlc2NyaXB0b3IpOiB2b2lkfSBJbmZvLWxldmVsIGxvZ2dpbmcgZGVjb3JhdG9yLlxuICogQGZ1bmN0aW9uIGluZm9cbiAqIEBjYXRlZ29yeSBNZXRob2QgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gaW5mbygpIHtcbiAgcmV0dXJuIGxvZyhMb2dMZXZlbC5pbmZvKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gTWV0aG9kIGRlY29yYXRvciBmb3IgbG9nZ2luZyBmdW5jdGlvbiBjYWxscyB3aXRoIHNpbGx5IGxldmVsLlxuICogQHN1bW1hcnkgQ29udmVuaWVuY2Ugd3JhcHBlciBhcm91bmQge0BsaW5rIGxvZ30gdGhhdCBsb2dzIHVzaW5nIGBMb2dMZXZlbC5zaWxseWAuXG4gKiBAcmV0dXJuIHtmdW5jdGlvbihhbnksIGFueSwgUHJvcGVydHlEZXNjcmlwdG9yKTogdm9pZH0gU2lsbHktbGV2ZWwgbG9nZ2luZyBkZWNvcmF0b3IuXG4gKiBAZnVuY3Rpb24gc2lsbHlcbiAqIEBjYXRlZ29yeSBNZXRob2QgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gc2lsbHkoKSB7XG4gIHJldHVybiBsb2coTG9nTGV2ZWwuc2lsbHkpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBNZXRob2QgZGVjb3JhdG9yIGZvciBsb2dnaW5nIGZ1bmN0aW9uIGNhbGxzIHdpdGggdmVyYm9zZSBsZXZlbC5cbiAqIEBzdW1tYXJ5IENvbnZlbmllbmNlIHdyYXBwZXIgYXJvdW5kIHtAbGluayBsb2d9IHRoYXQgbG9ncyB1c2luZyBgTG9nTGV2ZWwudmVyYm9zZWAgd2l0aCBjb25maWd1cmFibGUgdmVyYm9zaXR5LlxuICogQHJldHVybiB7ZnVuY3Rpb24oYW55LCBhbnksIFByb3BlcnR5RGVzY3JpcHRvcik6IHZvaWR9IFZlcmJvc2UgbG9nZ2luZyBkZWNvcmF0b3IuXG4gKiBAZnVuY3Rpb24gdmVyYm9zZVxuICogQGNhdGVnb3J5IE1ldGhvZCBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZXJib3NlKCk6IChcbiAgdGFyZ2V0OiBhbnksXG4gIHByb3BlcnR5S2V5PzogYW55LFxuICBkZXNjcmlwdG9yPzogYW55XG4pID0+IHZvaWQ7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE1ldGhvZCBkZWNvcmF0b3IgZm9yIGxvZ2dpbmcgZnVuY3Rpb24gY2FsbHMgd2l0aCB2ZXJib3NlIGxldmVsLlxuICogQHN1bW1hcnkgQ29udmVuaWVuY2Ugd3JhcHBlciBhcm91bmQge0BsaW5rIGxvZ30gdGhhdCBsb2dzIHVzaW5nIGBMb2dMZXZlbC52ZXJib3NlYCB3aGlsZSB0b2dnbGluZyBiZW5jaG1hcmtpbmcuXG4gKiBAcmV0dXJuIHtmdW5jdGlvbihhbnksIFByb3BlcnR5RGVzY3JpcHRvcik6IHZvaWR9IFZlcmJvc2UgbG9nZ2luZyBkZWNvcmF0b3IuXG4gKiBAZnVuY3Rpb24gdmVyYm9zZVxuICogQGNhdGVnb3J5IE1ldGhvZCBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZXJib3NlKCk6IChcbiAgdGFyZ2V0OiBhbnksXG4gIHByb3BlcnR5S2V5PzogYW55LFxuICBkZXNjcmlwdG9yPzogYW55XG4pID0+IHZvaWQ7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE1ldGhvZCBkZWNvcmF0b3IgZm9yIGxvZ2dpbmcgZnVuY3Rpb24gY2FsbHMgd2l0aCB2ZXJib3NlIGxldmVsLlxuICogQHN1bW1hcnkgQ29udmVuaWVuY2Ugd3JhcHBlciBhcm91bmQge0BsaW5rIGxvZ30gdGhhdCBsb2dzIHVzaW5nIGBMb2dMZXZlbC52ZXJib3NlYCB3aXRoIGNvbmZpZ3VyYWJsZSB2ZXJib3NpdHkgYW5kIG9wdGlvbmFsIGJlbmNobWFya2luZy5cbiAqIEBwYXJhbSB7bnVtYmVyfGJvb2xlYW59IHZlcmJvc2l0eSAtIFZlcmJvc2l0eSBsZXZlbCBmb3IgbG9nIGZpbHRlcmluZyBvciBmbGFnIHRvIGVuYWJsZSBiZW5jaG1hcmtpbmcuXG4gKiBAcmV0dXJuIHtmdW5jdGlvbihhbnksIGFueSxQcm9wZXJ0eURlc2NyaXB0b3IpOiB2b2lkfSBWZXJib3NlIGxvZ2dpbmcgZGVjb3JhdG9yLlxuICogQGZ1bmN0aW9uIHZlcmJvc2VcbiAqIEBjYXRlZ29yeSBNZXRob2QgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gdmVyYm9zZSh2ZXJib3NpdHk6IG51bWJlciB8IGJvb2xlYW4gPSAwKSB7XG4gIGlmICghdmVyYm9zaXR5KSB7XG4gICAgdmVyYm9zaXR5ID0gMDtcbiAgfVxuICByZXR1cm4gbG9nKExvZ0xldmVsLnZlcmJvc2UsIHZlcmJvc2l0eSBhcyBudW1iZXIpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgZGVjb3JhdG9yIHRoYXQgbWFrZXMgYSBtZXRob2Qgbm9uLWNvbmZpZ3VyYWJsZS5cbiAqIEBzdW1tYXJ5IFByZXZlbnRzIG92ZXJyaWRpbmcgYnkgbWFya2luZyB0aGUgbWV0aG9kIGRlc2NyaXB0b3IgYXMgbm9uLWNvbmZpZ3VyYWJsZSwgdGhyb3dpbmcgaWYgYXBwbGllZCB0byBub24tbWV0aG9kIHRhcmdldHMuXG4gKiBAcmV0dXJuIHtmdW5jdGlvbihvYmplY3QsIGFueSwgUHJvcGVydHlEZXNjcmlwdG9yKTogUHJvcGVydHlEZXNjcmlwdG9yfHVuZGVmaW5lZH0gRGVjb3JhdG9yIHRoYXQgaGFyZGVucyB0aGUgbWV0aG9kIGRlc2NyaXB0b3IuXG4gKiBAZnVuY3Rpb24gZmluYWxcbiAqIEBjYXRlZ29yeSBNZXRob2QgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZmluYWwoKSB7XG4gIHJldHVybiAodGFyZ2V0OiBvYmplY3QsIHByb3BlcnR5S2V5PzogYW55LCBkZXNjcmlwdG9yPzogYW55KSA9PiB7XG4gICAgaWYgKCFkZXNjcmlwdG9yKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiZmluYWwgZGVjb3JhdG9yIGNhbiBvbmx5IGJlIHVzZWQgb24gbWV0aG9kc1wiKTtcbiAgICBpZiAoZGVzY3JpcHRvcj8uY29uZmlndXJhYmxlKSB7XG4gICAgICBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gZGVzY3JpcHRvcjtcbiAgfTtcbn1cbiIsImltcG9ydCB7IExvZ0ZpbHRlciB9IGZyb20gXCIuL0xvZ0ZpbHRlclwiO1xuaW1wb3J0IHsgTG9nZ2luZ0NvbmZpZyB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgZmluYWwgfSBmcm9tIFwiLi4vZGVjb3JhdG9yc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBSZXBsYWNlbWVudCBjYWxsYmFjayB1c2VkIHRvIHRyYW5zZm9ybSBSZWdFeHAgbWF0Y2hlcy5cbiAqIEBzdW1tYXJ5IFJlY2VpdmVzIHRoZSBtYXRjaGVkIHN1YnN0cmluZyBhbmQgYWRkaXRpb25hbCBjYXB0dXJlIGFyZ3VtZW50cywgcmV0dXJuaW5nIHRoZSByZXBsYWNlbWVudCB0ZXh0IHRoYXQgd2lsbCBiZSBpbmplY3RlZCBpbnRvIHRoZSBsb2cgbWVzc2FnZS5cbiAqIEB0eXBlZGVmIHtmdW5jdGlvbihzdHJpbmcsIGFueVtdKTogc3RyaW5nfSBSZXBsYWNlbWVudEZ1bmN0aW9uXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkxvZ2dpbmdcbiAqL1xuZXhwb3J0IHR5cGUgUmVwbGFjZW1lbnRGdW5jdGlvbiA9IChzdWJzdHJpbmc6IHN0cmluZywgLi4uYXJnczogYW55W10pID0+IHN0cmluZztcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRmlsdGVyIHRoYXQgcGF0Y2hlcyBsb2cgbWVzc2FnZXMgdXNpbmcgcmVndWxhciBleHByZXNzaW9ucy5cbiAqIEBzdW1tYXJ5IEFwcGxpZXMgYSBjb25maWd1cmVkIHtAbGluayBSZWdFeHB9IGFuZCByZXBsYWNlbWVudCBzdHJhdGVneSB0byByZWRhY3QsIG1hc2ssIG9yIHJlc3RydWN0dXJlIGxvZyBwYXlsb2FkcyBiZWZvcmUgdGhleSBhcmUgZW1pdHRlZC5cbiAqIEBwYXJhbSB7UmVnRXhwfSByZWdleHAgLSBFeHByZXNzaW9uIHVzZWQgdG8gZGV0ZWN0IHNlbnNpdGl2ZSBvciBmb3JtYXR0ZWQgdGV4dC5cbiAqIEBwYXJhbSB7c3RyaW5nfFJlcGxhY2VtZW50RnVuY3Rpb259IHJlcGxhY2VtZW50IC0gUmVwbGFjZW1lbnQgc3RyaW5nIG9yIGNhbGxiYWNrIGludm9rZWQgZm9yIGVhY2ggbWF0Y2guXG4gKiBAY2xhc3MgUGF0dGVybkZpbHRlclxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGZpbHRlciA9IG5ldyBQYXR0ZXJuRmlsdGVyKC90b2tlbj1bXiZdKy9nLCBcInRva2VuPSoqKlwiKTtcbiAqIGNvbnN0IHNhbml0aXplZCA9IGZpbHRlci5maWx0ZXIoY29uZmlnLCBcInRva2VuPTEyMyZ1c2VyPXRvbVwiLCBbXSk7XG4gKiAvLyBzYW5pdGl6ZWQgPT09IFwidG9rZW49KioqJnVzZXI9dG9tXCJcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgTG9nZ2VyXG4gKiAgIHBhcnRpY2lwYW50IEZpbHRlciBhcyBQYXR0ZXJuRmlsdGVyXG4gKiAgIHBhcnRpY2lwYW50IFJlZ0V4cFxuICogICBMb2dnZXItPj5GaWx0ZXI6IGZpbHRlcihjb25maWcsIG1lc3NhZ2UsIGNvbnRleHQpXG4gKiAgIEZpbHRlci0+PlJlZ0V4cDogZXhlY3V0ZSBtYXRjaCgpXG4gKiAgIGFsdCBtYXRjaCBmb3VuZFxuICogICAgIFJlZ0V4cC0tPj5GaWx0ZXI6IGNhcHR1cmVzXG4gKiAgICAgRmlsdGVyLT4+UmVnRXhwOiByZXBsYWNlKG1lc3NhZ2UsIHJlcGxhY2VtZW50KVxuICogICAgIFJlZ0V4cC0tPj5GaWx0ZXI6IHRyYW5zZm9ybWVkIG1lc3NhZ2VcbiAqICAgZWxzZSBubyBtYXRjaFxuICogICAgIFJlZ0V4cC0tPj5GaWx0ZXI6IG51bGxcbiAqICAgZW5kXG4gKiAgIEZpbHRlci0tPj5Mb2dnZXI6IHNhbml0aXplZCBtZXNzYWdlXG4gKi9cbmV4cG9ydCBjbGFzcyBQYXR0ZXJuRmlsdGVyIGV4dGVuZHMgTG9nRmlsdGVyIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IHJlZ2V4cDogUmVnRXhwLFxuICAgIHByb3RlY3RlZCByZWFkb25seSByZXBsYWNlbWVudDogc3RyaW5nIHwgUmVwbGFjZW1lbnRGdW5jdGlvblxuICApIHtcbiAgICBzdXBlcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBFbnN1cmVzIGRldGVybWluaXN0aWMgUmVnRXhwIG1hdGNoaW5nLlxuICAgKiBAc3VtbWFyeSBSdW5zIHRoZSBjb25maWd1cmVkIGV4cHJlc3Npb24sIHRoZW4gcmVzZXRzIGl0cyBzdGF0ZSBzbyByZXBlYXRlZCBpbnZvY2F0aW9ucyBiZWhhdmUgY29uc2lzdGVudGx5LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSAtIE1lc3NhZ2UgdG8gdGVzdCBmb3IgbWF0Y2hlcy5cbiAgICogQHJldHVybiB7UmVnRXhwRXhlY0FycmF5fG51bGx9IE1hdGNoIHJlc3VsdCBvciBudWxsIHdoZW4gbm8gbWF0Y2ggaXMgZm91bmQuXG4gICAqL1xuICBAZmluYWwoKVxuICBwcm90ZWN0ZWQgbWF0Y2gobWVzc2FnZTogc3RyaW5nKSB7XG4gICAgY29uc3QgbWF0Y2ggPSB0aGlzLnJlZ2V4cC5leGVjKG1lc3NhZ2UpO1xuICAgIHRoaXMucmVnZXhwLmxhc3RJbmRleCA9IDA7XG4gICAgcmV0dXJuIG1hdGNoO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBBcHBsaWVzIHRoZSByZXBsYWNlbWVudCBzdHJhdGVneSB0byB0aGUgaW5jb21pbmcgbWVzc2FnZS5cbiAgICogQHN1bW1hcnkgRXhlY3V0ZXMge0BsaW5rIFBhdHRlcm5GaWx0ZXIubWF0Y2h9IGFuZCwgd2hlbiBhIG1hdGNoIGlzIGZvdW5kLCByZXBsYWNlcyBldmVyeSBvY2N1cnJlbmNlIHVzaW5nIHRoZSBjb25maWd1cmVkIHJlcGxhY2VtZW50IGhhbmRsZXIuXG4gICAqIEBwYXJhbSB7TG9nZ2luZ0NvbmZpZ30gY29uZmlnIC0gQWN0aXZlIGxvZ2dpbmcgY29uZmlndXJhdGlvbiAodW51c2VkIGJ1dCBwYXJ0IG9mIHRoZSBmaWx0ZXIgY29udHJhY3QpLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSAtIE1lc3NhZ2UgdG8gYmUgc2FuaXRpemVkLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBjb250ZXh0IC0gQ29udGV4dCBlbnRyaWVzIGFzc29jaWF0ZWQgd2l0aCB0aGUgbG9nIGV2ZW50LlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IFNhbml0aXplZCBsb2cgbWVzc2FnZS5cbiAgICovXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgZmlsdGVyKGNvbmZpZzogTG9nZ2luZ0NvbmZpZywgbWVzc2FnZTogc3RyaW5nLCBjb250ZXh0OiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gICAgY29uc3QgbG9nID0gdGhpcy5sb2cuZm9yKHRoaXMuZmlsdGVyKTtcbiAgICBjb25zdCBtYXRjaCA9IHRoaXMubWF0Y2gobWVzc2FnZSk7XG4gICAgaWYgKCFtYXRjaCkgcmV0dXJuIG1lc3NhZ2U7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBtZXNzYWdlLnJlcGxhY2UodGhpcy5yZWdleHAsIHRoaXMucmVwbGFjZW1lbnQgYXMgYW55KTtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICBsb2cuZXJyb3IoYFBhdHRlcm5GaWx0ZXIgcmVwbGFjZW1lbnQgZXJyb3I6ICR7ZX1gKTtcbiAgICB9XG4gICAgcmV0dXJuIFwiXCI7XG4gIH1cbn1cbiIsImV4cG9ydCAqIGZyb20gXCIuL2ZpbHRlcnNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbnN0YW50c1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vZW52aXJvbm1lbnRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0xvZ2dlZENsYXNzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9sb2dnaW5nXCI7XG5leHBvcnQgKiBmcm9tIFwiLi90ZXh0XCI7XG5leHBvcnQgKiBmcm9tIFwiLi90aW1lXCI7XG5leHBvcnQgKiBmcm9tIFwiLi90eXBlc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vd2ViXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENvbXByZWhlbnNpdmUgbG9nZ2luZyB0b29sa2l0IGZvciBicm93c2VyIGFuZCBOb2RlIGVudmlyb25tZW50cy5cbiAqIEBzdW1tYXJ5IEV4cG9zZXMge0BsaW5rIExvZ2dpbmd9IGFuZCB7QGxpbmsgTWluaUxvZ2dlcn0gZm9yIHJ1bnRpbWUgbG9nZ2luZywgZGVjb3JhdG9ycyBzdWNoIGFzIHtAbGluayBsb2d9IGZvciBtZXRob2QgaW5zdHJ1bWVudGF0aW9uLCBhbmQgdXRpbGl0aWVzIGxpa2Uge0BsaW5rIFBhdHRlcm5GaWx0ZXJ9LCB7QGxpbmsgU3RvcFdhdGNofSwgYW5kIHtAbGluayBMb2dnZWRFbnZpcm9ubWVudH0gdG8gYnVpbGQgY29uZmlndXJhYmxlLCB0aGVtZS1hd2FyZSBsb2cgcGlwZWxpbmVzLlxuICogQG1vZHVsZSBMb2dnaW5nXG4gKi9cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ3VycmVudCBwYWNrYWdlIHZlcnNpb24gc3RyaW5nLlxuICogQHN1bW1hcnkgU3RvcmVzIHRoZSBwYWNrYWdlIHZlcnNpb24gZm9yIGRpYWdub3N0aWNzIGFuZCBjb21wYXRpYmlsaXR5IGNoZWNrcy5cbiAqIEBjb25zdCBWRVJTSU9OXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQG1lbWJlck9mIG1vZHVsZTpMb2dnaW5nXG4gKi9cbmV4cG9ydCBjb25zdCBWRVJTSU9OID0gXCIjI1ZFUlNJT04jI1wiO1xuIl0sIm5hbWVzIjpbIkxvZ0xldmVsIiwiTG9nZ2luZ01vZGUiLCJPYmplY3RBY2N1bXVsYXRvciIsInN0eWxlIiwiX19kZWNvcmF0ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0lBRUE7Ozs7OztJQU1HO0FBQ0ksVUFBTSxhQUFhLEdBQUc7SUFFN0I7Ozs7OztJQU1HO0FBQ0ksVUFBTSxrQkFBa0IsR0FBRztJQUVsQzs7Ozs7O0lBTUc7VUFDVSwwQkFBMEIsR0FBRyxDQUFDLElBQUksRUFBRSxHQUFHO0lBRXBEOzs7Ozs7SUFNRztBQUNTQTtJQUFaLENBQUEsVUFBWSxRQUFRLEVBQUE7O0lBRWxCLElBQUEsUUFBQSxDQUFBLFdBQUEsQ0FBQSxHQUFBLFdBQXVCOztJQUV2QixJQUFBLFFBQUEsQ0FBQSxPQUFBLENBQUEsR0FBQSxPQUFlOztJQUVmLElBQUEsUUFBQSxDQUFBLE1BQUEsQ0FBQSxHQUFBLE1BQWE7O0lBRWIsSUFBQSxRQUFBLENBQUEsU0FBQSxDQUFBLEdBQUEsU0FBbUI7O0lBRW5CLElBQUEsUUFBQSxDQUFBLE9BQUEsQ0FBQSxHQUFBLE9BQWU7O0lBRWYsSUFBQSxRQUFBLENBQUEsT0FBQSxDQUFBLEdBQUEsT0FBZTtJQUNqQixDQUFDLEVBYldBLGdCQUFRLEtBQVJBLGdCQUFRLEdBYW5CLEVBQUEsQ0FBQSxDQUFBO0lBRUQ7Ozs7Ozs7Ozs7O0lBV0c7SUFDSDs7Ozs7O0lBTUc7QUFDVSxVQUFBLGdCQUFnQixHQUFHO0lBQzlCLElBQUEsU0FBUyxFQUFFLENBQUM7SUFDWixJQUFBLEtBQUssRUFBRSxDQUFDO0lBQ1IsSUFBQSxJQUFJLEVBQUUsQ0FBQztJQUNQLElBQUEsT0FBTyxFQUFFLENBQUM7SUFDVixJQUFBLEtBQUssRUFBRSxDQUFDO0lBQ1IsSUFBQSxLQUFLLEVBQUUsQ0FBQzs7SUFHVjs7Ozs7SUFLRztB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
|