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