@dbx-tools/shared-core 0.6.130 → 0.6.131
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/README.md +4 -3
- package/lib/src/log.d.ts +15 -25
- package/lib/src/log.js +24 -103
- package/package.json +2 -11
- package/src/log.ts +25 -104
package/README.md
CHANGED
|
@@ -390,9 +390,10 @@ if (log.isLevelEnabled("debug")) {
|
|
|
390
390
|
}
|
|
391
391
|
```
|
|
392
392
|
|
|
393
|
-
`log.logger()`
|
|
394
|
-
honors `LOG_LEVEL` per call, so
|
|
395
|
-
without paying formatting cost
|
|
393
|
+
`log.logger()` is dependency-free and uses the platform console in browsers or
|
|
394
|
+
formatted stderr output on server runtimes. It honors `LOG_LEVEL` per call, so
|
|
395
|
+
debug statements can stay in production code without paying formatting cost
|
|
396
|
+
when disabled.
|
|
396
397
|
|
|
397
398
|
## Modules
|
|
398
399
|
|
package/lib/src/log.d.ts
CHANGED
|
@@ -2,20 +2,12 @@
|
|
|
2
2
|
* Tagged, leveled logging for every runtime - the one logger the whole
|
|
3
3
|
* monorepo shares.
|
|
4
4
|
*
|
|
5
|
-
* {@link logger} resolves a tagged {@link Logger}
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* the
|
|
11
|
-
*
|
|
12
|
-
* Sink selection chains two factories with nullish coalescing (first match
|
|
13
|
-
* wins):
|
|
14
|
-
*
|
|
15
|
-
* 1. {@link createConsolaLoggerFactory} when consola resolves and
|
|
16
|
-
* `LOG_CONSOLA_DISABLED` is not truthy.
|
|
17
|
-
* 2. {@link createConsoleLoggerFactory} everywhere else (also the sync
|
|
18
|
-
* bootstrap before that promise settles).
|
|
5
|
+
* {@link logger} resolves a tagged {@link Logger} through a synchronous console
|
|
6
|
+
* sink, then upgrades its server-side formatter when `node:util` resolves.
|
|
7
|
+
* Keeping the sink dependency-free prevents browser bundlers from retaining an
|
|
8
|
+
* optional bare import that downstream apps would still have to install.
|
|
9
|
+
* {@link LogLevel} filtering runs through {@link shouldEmit} in per-level
|
|
10
|
+
* wrappers around the platform console or stderr sink.
|
|
19
11
|
*
|
|
20
12
|
* The console fallback writes formatted lines to `process.stderr` when it is
|
|
21
13
|
* available (Bun `inspect` per argument when `LOG_BUN_CONSOLE_DISABLED` is
|
|
@@ -24,14 +16,13 @@
|
|
|
24
16
|
* the `LEVEL` text prefix (devtools show severity) and keep only the `[name]`
|
|
25
17
|
* tag.
|
|
26
18
|
*
|
|
27
|
-
* Env toggles: `LOG_LEVEL` (read per call)
|
|
28
|
-
*
|
|
19
|
+
* Env toggles: `LOG_LEVEL` (read per call) and `LOG_BUN_CONSOLE_DISABLED`
|
|
20
|
+
* (read once during factory init).
|
|
29
21
|
*
|
|
30
22
|
* Browser-safe: `process` / `Bun` / `window` / `document` are all reached
|
|
31
|
-
* through `globalThis` and guarded,
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* Consola is an optional peer; the module loads fine without it.
|
|
23
|
+
* through `globalThis` and guarded, and `node:util` is imported ONLY on a host
|
|
24
|
+
* that has `process.stderr` - never in a browser, where the specifier is
|
|
25
|
+
* unresolvable - so the module works in any runtime.
|
|
35
26
|
*
|
|
36
27
|
* @module
|
|
37
28
|
*/
|
|
@@ -51,9 +42,9 @@ export type LogLevel = (typeof LOG_LEVELS)[number];
|
|
|
51
42
|
export type Logger = {
|
|
52
43
|
[K in LogLevel]: (...args: any[]) => void;
|
|
53
44
|
} & {
|
|
54
|
-
/** Success message
|
|
45
|
+
/** Success message emitted at `info` level. */
|
|
55
46
|
success: (...args: any[]) => void;
|
|
56
|
-
/** Start / in-progress message
|
|
47
|
+
/** Start / in-progress message emitted at `info` level. */
|
|
57
48
|
start: (...args: any[]) => void;
|
|
58
49
|
};
|
|
59
50
|
/**
|
|
@@ -72,9 +63,8 @@ export declare function isLevelEnabled(level: LogLevel): boolean;
|
|
|
72
63
|
*
|
|
73
64
|
* The tag is `[name]` when `loggerName` is a non-empty string, a
|
|
74
65
|
* {@link NameLike} with `name`, or a file / URL path (the basename without
|
|
75
|
-
* extension is used).
|
|
76
|
-
*
|
|
77
|
-
* alone in browsers via {@link createFormatter}.
|
|
66
|
+
* extension is used). The console sink prepends `LEVEL [name]` on Node/Bun
|
|
67
|
+
* hosts or `[name]` alone in browsers via {@link createFormatter}.
|
|
78
68
|
*
|
|
79
69
|
* Calls below `process.env.LOG_LEVEL` are dropped by {@link shouldEmit} before
|
|
80
70
|
* the sink formats or writes the line.
|
package/lib/src/log.js
CHANGED
|
@@ -2,20 +2,12 @@
|
|
|
2
2
|
* Tagged, leveled logging for every runtime - the one logger the whole
|
|
3
3
|
* monorepo shares.
|
|
4
4
|
*
|
|
5
|
-
* {@link logger} resolves a tagged {@link Logger}
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* the
|
|
11
|
-
*
|
|
12
|
-
* Sink selection chains two factories with nullish coalescing (first match
|
|
13
|
-
* wins):
|
|
14
|
-
*
|
|
15
|
-
* 1. {@link createConsolaLoggerFactory} when consola resolves and
|
|
16
|
-
* `LOG_CONSOLA_DISABLED` is not truthy.
|
|
17
|
-
* 2. {@link createConsoleLoggerFactory} everywhere else (also the sync
|
|
18
|
-
* bootstrap before that promise settles).
|
|
5
|
+
* {@link logger} resolves a tagged {@link Logger} through a synchronous console
|
|
6
|
+
* sink, then upgrades its server-side formatter when `node:util` resolves.
|
|
7
|
+
* Keeping the sink dependency-free prevents browser bundlers from retaining an
|
|
8
|
+
* optional bare import that downstream apps would still have to install.
|
|
9
|
+
* {@link LogLevel} filtering runs through {@link shouldEmit} in per-level
|
|
10
|
+
* wrappers around the platform console or stderr sink.
|
|
19
11
|
*
|
|
20
12
|
* The console fallback writes formatted lines to `process.stderr` when it is
|
|
21
13
|
* available (Bun `inspect` per argument when `LOG_BUN_CONSOLE_DISABLED` is
|
|
@@ -24,14 +16,13 @@
|
|
|
24
16
|
* the `LEVEL` text prefix (devtools show severity) and keep only the `[name]`
|
|
25
17
|
* tag.
|
|
26
18
|
*
|
|
27
|
-
* Env toggles: `LOG_LEVEL` (read per call)
|
|
28
|
-
*
|
|
19
|
+
* Env toggles: `LOG_LEVEL` (read per call) and `LOG_BUN_CONSOLE_DISABLED`
|
|
20
|
+
* (read once during factory init).
|
|
29
21
|
*
|
|
30
22
|
* Browser-safe: `process` / `Bun` / `window` / `document` are all reached
|
|
31
|
-
* through `globalThis` and guarded,
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* Consola is an optional peer; the module loads fine without it.
|
|
23
|
+
* through `globalThis` and guarded, and `node:util` is imported ONLY on a host
|
|
24
|
+
* that has `process.stderr` - never in a browser, where the specifier is
|
|
25
|
+
* unresolvable - so the module works in any runtime.
|
|
35
26
|
*
|
|
36
27
|
* @module
|
|
37
28
|
*/
|
|
@@ -49,9 +40,8 @@ const globalProcess = globalThis.process;
|
|
|
49
40
|
const globalBun = globalThis.Bun;
|
|
50
41
|
/**
|
|
51
42
|
* Node `process.stderr` when writable, else `undefined` (stable for the
|
|
52
|
-
* process). Typed loosely (`any`) because it is handed to
|
|
53
|
-
*
|
|
54
|
-
* `.write`, neither of which our structural {@link ProcessLike} shape satisfies
|
|
43
|
+
* process). Typed loosely (`any`) because it is handed to the console sink's
|
|
44
|
+
* `.write`, which our structural {@link ProcessLike} shape does not satisfy
|
|
55
45
|
* nominally.
|
|
56
46
|
*/
|
|
57
47
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -77,70 +67,6 @@ const LOG_LEVEL_COLORS = Object.fromEntries(LOG_LEVELS.map((level) => {
|
|
|
77
67
|
}));
|
|
78
68
|
const LOG_LEVEL_COLOR_RESET = "\x1b[0m";
|
|
79
69
|
const DEFAULT_LEVEL = "info";
|
|
80
|
-
/**
|
|
81
|
-
* Consola-backed {@link LoggerFactory}, or `undefined` when consola is
|
|
82
|
-
* disabled, fails to import, or throws during setup.
|
|
83
|
-
*
|
|
84
|
-
* Builds one `createConsola` instance (badge off, level `verbose`) whose
|
|
85
|
-
* reporter calls {@link shouldEmit} on `logObj.type` before delegating to
|
|
86
|
-
* consola's default reporters. In Node, when `globalProcessStdErr` is set,
|
|
87
|
-
* recognized {@link LogLevel} types are redirected to stderr for that write.
|
|
88
|
-
* Tags use `withTag` (rendered `[name]`, not merged into args).
|
|
89
|
-
*
|
|
90
|
-
* Memoized: the dynamic `consola` import, env checks, and `createConsola`
|
|
91
|
-
* setup (plus the import/throw fallback) run once; later calls share the one
|
|
92
|
-
* resolved factory (or the one resolved `undefined`). A rejection is evicted
|
|
93
|
-
* by {@link memoize} so a later call retries.
|
|
94
|
-
*/
|
|
95
|
-
const createConsolaLoggerFactory = memoize(async () => {
|
|
96
|
-
const consolaDisabled = toBoolean(globalProcess?.env?.LOG_CONSOLA_DISABLED);
|
|
97
|
-
if (!consolaDisabled) {
|
|
98
|
-
try {
|
|
99
|
-
const { consola, createConsola, LogLevels } = await import(/* @vite-ignore */ "consola");
|
|
100
|
-
const defaultOptions = consola.options;
|
|
101
|
-
const createConsolaOptions = {
|
|
102
|
-
...consola.options,
|
|
103
|
-
defaults: { badge: false },
|
|
104
|
-
// `LOG_LEVEL` is enforced in {@link shouldEmit}; keep consola permissive
|
|
105
|
-
// so a threshold change after import is not blocked by its own filter.
|
|
106
|
-
level: LogLevels.verbose,
|
|
107
|
-
reporters: [
|
|
108
|
-
{
|
|
109
|
-
log: (logObj, ctx) => {
|
|
110
|
-
const logLevel = parseLogLevel(logObj.type);
|
|
111
|
-
if (!shouldEmit(logLevel, true))
|
|
112
|
-
return;
|
|
113
|
-
const ctxStdout = ctx.options.stdout;
|
|
114
|
-
try {
|
|
115
|
-
if (globalProcessStdErr !== undefined && logLevel !== undefined) {
|
|
116
|
-
ctx.options.stdout = globalProcessStdErr;
|
|
117
|
-
}
|
|
118
|
-
defaultOptions.reporters.forEach((reporter) => reporter.log(logObj, ctx));
|
|
119
|
-
}
|
|
120
|
-
finally {
|
|
121
|
-
ctx.options.stdout = ctxStdout;
|
|
122
|
-
}
|
|
123
|
-
},
|
|
124
|
-
},
|
|
125
|
-
],
|
|
126
|
-
};
|
|
127
|
-
const consolaLogger = createConsola(createConsolaOptions);
|
|
128
|
-
return (name) => {
|
|
129
|
-
return name ? consolaLogger.withTag(name) : consolaLogger;
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
catch (error) {
|
|
133
|
-
// consola is an OPTIONAL peer - not having it installed is the EXPECTED
|
|
134
|
-
// path (the module degrades to the console fallback), so this is not an
|
|
135
|
-
// error. Note it only at debug level, and without a stack trace (the
|
|
136
|
-
// message, not `console.trace`, so a missing optional dep stays quiet).
|
|
137
|
-
if (isLevelEnabled("debug")) {
|
|
138
|
-
console.debug("consola not available; using console fallback:", String(error));
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
return undefined;
|
|
143
|
-
});
|
|
144
70
|
/**
|
|
145
71
|
* Console {@link LoggerFactory}; always succeeds.
|
|
146
72
|
*
|
|
@@ -232,7 +158,7 @@ function consoleLoggerFactory(globalProcessStdErr, utils) {
|
|
|
232
158
|
};
|
|
233
159
|
return [level, emitter];
|
|
234
160
|
}));
|
|
235
|
-
//
|
|
161
|
+
// Convenience levels share the info sink.
|
|
236
162
|
logger.success = logger.info;
|
|
237
163
|
logger.start = logger.info;
|
|
238
164
|
return logger;
|
|
@@ -241,18 +167,16 @@ function consoleLoggerFactory(globalProcessStdErr, utils) {
|
|
|
241
167
|
return (name) => (name ? factory(name) : defaultFactory());
|
|
242
168
|
}
|
|
243
169
|
/**
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
* one in-flight promise and one settled result.
|
|
170
|
+
* Full console sink with optional `node:util` inspection. Memoized so
|
|
171
|
+
* concurrent and repeat callers share one in-flight promise and settled result.
|
|
247
172
|
*/
|
|
248
173
|
const resolveFactory = memoize(async () => {
|
|
249
|
-
return
|
|
174
|
+
return createConsoleLoggerFactory(globalProcessStdErr);
|
|
250
175
|
});
|
|
251
176
|
/**
|
|
252
177
|
* Active factory starts as a sync console sink (no `await`, so this module
|
|
253
178
|
* finishes evaluating immediately) and swaps to {@link resolveFactory}'s
|
|
254
|
-
* result when
|
|
255
|
-
* ready before the first interesting log line.
|
|
179
|
+
* result when server-side argument inspection is ready.
|
|
256
180
|
*/
|
|
257
181
|
let activeFactory = consoleLoggerFactory(globalProcessStdErr);
|
|
258
182
|
void resolveFactory().then((factory) => {
|
|
@@ -262,8 +186,8 @@ void resolveFactory().then((factory) => {
|
|
|
262
186
|
});
|
|
263
187
|
/**
|
|
264
188
|
* Build a logger that rebinds when {@link activeFactory} upgrades. Callers that
|
|
265
|
-
* capture `const log = logger("x")` at module scope still get
|
|
266
|
-
* arrives, without every call site waiting on a promise.
|
|
189
|
+
* capture `const log = logger("x")` at module scope still get the upgraded
|
|
190
|
+
* formatter once it arrives, without every call site waiting on a promise.
|
|
267
191
|
*/
|
|
268
192
|
function createLogger(name) {
|
|
269
193
|
let bound;
|
|
@@ -345,9 +269,7 @@ function activeLevel() {
|
|
|
345
269
|
* Whether `raw` meets the current `LOG_LEVEL` threshold.
|
|
346
270
|
*
|
|
347
271
|
* Parses `raw` as a {@link LogLevel}; when parsing fails, returns
|
|
348
|
-
* `defaultResult` if supplied, otherwise `false`.
|
|
349
|
-
* lines where unknown `logObj.type` values should pass through when
|
|
350
|
-
* `defaultResult` is `true`.
|
|
272
|
+
* `defaultResult` if supplied, otherwise `false`.
|
|
351
273
|
*/
|
|
352
274
|
function shouldEmit(raw, defaultResult) {
|
|
353
275
|
const level = parseLogLevel(raw);
|
|
@@ -389,9 +311,8 @@ function extractLoggerName(loggerName) {
|
|
|
389
311
|
*
|
|
390
312
|
* The tag is `[name]` when `loggerName` is a non-empty string, a
|
|
391
313
|
* {@link NameLike} with `name`, or a file / URL path (the basename without
|
|
392
|
-
* extension is used).
|
|
393
|
-
*
|
|
394
|
-
* alone in browsers via {@link createFormatter}.
|
|
314
|
+
* extension is used). The console sink prepends `LEVEL [name]` on Node/Bun
|
|
315
|
+
* hosts or `[name]` alone in browsers via {@link createFormatter}.
|
|
395
316
|
*
|
|
396
317
|
* Calls below `process.env.LOG_LEVEL` are dropped by {@link shouldEmit} before
|
|
397
318
|
* the sink formats or writes the line.
|
|
@@ -407,4 +328,4 @@ export function logger(loggerName) {
|
|
|
407
328
|
const name = extractLoggerName(loggerName);
|
|
408
329
|
return createLogger(name);
|
|
409
330
|
}
|
|
410
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2xvZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0NHOzs7Ozs7Ozs7QUFFSCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3hDLE9BQU8sRUFBaUIsU0FBUyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBY3ZELE1BQU0sYUFBYSxHQUFJLFVBQXdDLENBQUMsT0FBTyxDQUFDO0FBQ3hFLE1BQU0sU0FBUyxHQUFJLFVBQWdDLENBQUMsR0FBRyxDQUFDO0FBRXhEOzs7Ozs7R0FNRztBQUNILDhEQUE4RDtBQUM5RCxNQUFNLG1CQUFtQixHQUN2QixhQUFhLElBQUksT0FBTyxhQUFhLENBQUMsTUFBTSxFQUFFLEtBQUssS0FBSyxVQUFVO0lBQ2hFLENBQUMsQ0FBQyxhQUFhLENBQUMsTUFBTTtJQUN0QixDQUFDLENBQUMsU0FBUyxDQUFDO0FBRWhCLE1BQU0sVUFBVSxHQUFHLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFVLENBQUM7QUFDL0QsTUFBTSxjQUFjLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FDdkMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQ3JCLENBQUM7QUFDOUIsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLENBQUMsV0FBVyxDQUN6QyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7SUFDdkIsSUFBSSxLQUFLLEdBQUcsVUFBVSxDQUFDLENBQUMsT0FBTztJQUMvQixRQUFRLEtBQUssRUFBRSxDQUFDO1FBQ2QsS0FBSyxNQUFNO1lBQ1QsS0FBSyxHQUFHLFVBQVUsQ0FBQyxDQUFDLE9BQU87WUFDM0IsTUFBTTtR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QU0sVUFBVSxjQUFjLENBQUMsS0FBZTtJQUM1QyxPQUFPLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUMzQixDQUFDO0FBRUQsTUFBTSxpQkFBaUIsR0FBRyx3REFBd0QsQ0FBQztBQUVuRjs7Ozs7R0FLRztBQUNILFNBQVMsaUJBQWlCLENBQUMsVUFBeUM7SUFDbEUsSUFBSSxDQUFDLFVBQVU7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUNsQyxJQUFJLE9BQU8sVUFBVSxLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQ25DLE1BQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUNsRCxPQUFPLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLFVBQVUsQ0FBQztJQUNsQyxDQUFDO0lBQ0QsT0FBTyxpQkFBaUIsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDNUMsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FrQkc7QUFDSCxNQUFNLFVBQVUsTUFBTSxDQUFDLFVBQXlDO0lBQzlELE1BQU0sSUFBSSxHQUFHLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQzNDLE9BQU8sWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQzVCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFRhZ2dlZCwgbGV2ZWxlZCBsb2dnaW5nIGZvciBldmVyeSBydW50aW1lIC0gdGhlIG9uZSBsb2dnZXIgdGhlIHdob2xlXG4gKiBtb25vcmVwbyBzaGFyZXMuXG4gKlxuICoge0BsaW5rIGxvZ2dlcn0gcmVzb2x2ZXMgYSB0YWdnZWQge0BsaW5rIExvZ2dlcn0gdmlhIGEge0BsaW5rIExvZ2dlckZhY3Rvcnl9LlxuICogVGhlIGZhY3Rvcnkgc3RhcnRzIGFzIGEgc3luY2hyb25vdXMgY29uc29sZSBzaW5rIHNvIHRoaXMgbW9kdWxlIG5ldmVyIHVzZXNcbiAqIHRvcC1sZXZlbCBgYXdhaXRgICh0aGF0IGxlZnQgaW1wb3J0ZXJzIHdpdGggYSBudWxsIG5hbWVzcGFjZSBtaWQtbG9hZCBpblxuICogYnJvd3NlciBidW5kbGVzKS4gQSBtZW1vaXplZCBhc3luYyBjaGFpbiB0aGVuIHVwZ3JhZGVzIHRvIGNvbnNvbGEgd2hlbiBpdFxuICogaXMgYXZhaWxhYmxlLiB7QGxpbmsgTG9nTGV2ZWx9IGZpbHRlcmluZyBydW5zIHRocm91Z2gge0BsaW5rIHNob3VsZEVtaXR9IGluXG4gKiB0aGUgY29uc29sYSByZXBvcnRlciBvciBpbiBwZXItbGV2ZWwgd3JhcHBlcnMgb24gdGhlIGBjb25zb2xlYCBmYWxsYmFja3MuXG4gKlxuICogU2luayBzZWxlY3Rpb24gY2hhaW5zIHR3byBmYWN0b3JpZXMgd2l0aCBudWxsaXNoIGNvYWxlc2NpbmcgKGZpcnN0IG1hdGNoXG4gKiB3aW5zKTpcbiAqXG4gKiAxLiB7QGxpbmsgY3JlYXRlQ29uc29sYUxvZ2dlckZhY3Rvcnl9IHdoZW4gY29uc29sYSByZXNvbHZlcyBhbmRcbiAqICAgIGBMT0dfQ09OU09MQV9ESVNBQkxFRGAgaXMgbm90IHRydXRoeS5cbiAqIDIuIHtAbGluayBjcmVhdGVDb25zb2xlTG9nZ2VyRmFjdG9yeX0gZXZlcnl3aGVyZSBlbHNlIChhbHNvIHRoZSBzeW5jXG4gKiAgICBib290c3RyYXAgYmVmb3JlIHRoYXQgcHJvbWlzZSBzZXR0bGVzKS5cbiAqXG4gKiBUaGUgY29uc29sZSBmYWxsYmFjayB3cml0ZXMgZm9ybWF0dGVkIGxpbmVzIHRvIGBwcm9jZXNzLnN0ZGVycmAgd2hlbiBpdCBpc1xuICogYXZhaWxhYmxlIChCdW4gYGluc3BlY3RgIHBlciBhcmd1bWVudCB3aGVuIGBMT0dfQlVOX0NPTlNPTEVfRElTQUJMRURgIGlzXG4gKiB1bnNldCwgb3RoZXJ3aXNlIGBub2RlOnV0aWxgIGBmb3JtYXRXaXRoT3B0aW9uc2ApLCBvciBkZWxlZ2F0ZXMgdG8gZ2xvYmFsXG4gKiBgY29uc29sZS4qYCB3aGVuIHN0ZGVyciBvciBgbm9kZTp1dGlsYCBpcyB1bmF2YWlsYWJsZS4gQnJvd3NlciBob3N0cyBvbWl0XG4gKiB0aGUgYExFVkVMYCB0ZXh0IHByZWZpeCAoZGV2dG9vbHMgc2hvdyBzZXZlcml0eSkgYW5kIGtlZXAgb25seSB0aGUgYFtuYW1lXWBcbiAqIHRhZy5cbiAqXG4gKiBFbnYgdG9nZ2xlczogYExPR19MRVZFTGAgKHJlYWQgcGVyIGNhbGwpLCBgTE9HX0NPTlNPTEFfRElTQUJMRURgIC9cbiAqIGBMT0dfQlVOX0NPTlNPTEVfRElTQUJMRURgIChyZWFkIG9uY2UgZHVyaW5nIGZhY3RvcnkgaW5pdCkuXG4gKlxuICogQnJvd3Nlci1zYWZlOiBgcHJvY2Vzc2AgLyBgQnVuYCAvIGB3aW5kb3dgIC8gYGRvY3VtZW50YCBhcmUgYWxsIHJlYWNoZWRcbiAqIHRocm91Z2ggYGdsb2JhbFRoaXNgIGFuZCBndWFyZGVkLCBjb25zb2xhIGxvYWRzIGxhemlseSwgYW5kIGBub2RlOnV0aWxgIGlzXG4gKiBpbXBvcnRlZCBPTkxZIG9uIGEgaG9zdCB0aGF0IGhhcyBgcHJvY2Vzcy5zdGRlcnJgIC0gbmV2ZXIgaW4gYSBicm93c2VyLFxuICogd2hlcmUgdGhlIHNwZWNpZmllciBpcyB1bnJlc29sdmFibGUgLSBzbyB0aGUgbW9kdWxlIHdvcmtzIGluIGFueSBydW50aW1lLlxuICogQ29uc29sYSBpcyBhbiBvcHRpb25hbCBwZWVyOyB0aGUgbW9kdWxlIGxvYWRzIGZpbmUgd2l0aG91dCBpdC5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgbWVtb2l6ZSB9IGZyb20gXCIuL2Z1bmN0aW9uLnRzXCI7XG5pbXBvcnQgeyB0eXBlIE5hbWVMaWtlLCB0b0Jvb2xlYW4gfSBmcm9tIFwiLi9vYmplY3QudHNcIjtcblxuLyoqIGBwcm9jZXNzYC1zaGFwZWQgdmlldyBvZmYgYGdsb2JhbFRoaXNgLCBzbyBubyBub2RlIHR5cGVzIGFyZSBuZWVkZWQuICovXG5pbnRlcmZhY2UgUHJvY2Vzc0xpa2Uge1xuICBlbnY/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+O1xuICBzdGRlcnI/OiB7IHdyaXRlPzogKGNodW5rOiBzdHJpbmcpID0+IHZvaWQ7IGlzVFRZPzogdW5rbm93biB9O1xufVxuXG4vKiogYEJ1bmAtc2hhcGVkIHZpZXcgb2ZmIGBnbG9iYWxUaGlzYCwgc28gbm8gYEB0eXBlcy9idW5gIGlzIG5lZWRlZC4gKi9cbmludGVyZmFjZSBCdW5MaWtlIHtcbiAgZW52PzogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPjtcbiAgaW5zcGVjdD86ICh2YWx1ZTogdW5rbm93biwgb3B0aW9ucz86IHsgY29sb3JzPzogYm9vbGVhbjsgZGVwdGg/OiBudW1iZXIgfSkgPT4gc3RyaW5nO1xufVxuXG5jb25zdCBnbG9iYWxQcm9jZXNzID0gKGdsb2JhbFRoaXMgYXMgeyBwcm9jZXNzPzogUHJvY2Vzc0xpa2UgfSkucHJvY2VzcztcbmNvbnN0IGdsb2JhbEJ1biA9IChnbG9iYWxUaGlzIGFzIHsgQnVuPzogQnVuTGlrZSB9KS5CdW47XG5cbi8qKlxuICogTm9kZSBgcHJvY2Vzcy5zdGRlcnJgIHdoZW4gd3JpdGFibGUsIGVsc2UgYHVuZGVmaW5lZGAgKHN0YWJsZSBmb3IgdGhlXG4gKiBwcm9jZXNzKS4gVHlwZWQgbG9vc2VseSAoYGFueWApIGJlY2F1c2UgaXQgaXMgaGFuZGVkIHRvIGNvbnNvbGEnc1xuICogYGN0eC5vcHRpb25zLnN0ZG91dGAgKGEgYFdyaXRlU3RyZWFtYCkgYW5kIHRvIHRoZSBjb25zb2xlIGZhbGxiYWNrJ3NcbiAqIGAud3JpdGVgLCBuZWl0aGVyIG9mIHdoaWNoIG91ciBzdHJ1Y3R1cmFsIHtAbGluayBQcm9jZXNzTGlrZX0gc2hhcGUgc2F0aXNmaWVzXG4gKiBub21pbmFsbHkuXG4gKi9cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG5jb25zdCBnbG9iYWxQcm9jZXNzU3RkRXJyOiBhbnkgPVxuICBnbG9iYWxQcm9jZXNzICYmIHR5cGVvZiBnbG9iYWxQcm9jZXNzLnN0ZGVycj8ud3JpdGUgPT09IFwiZnVuY3Rpb25cIlxuICAgID8gZ2xvYmFsUHJvY2Vzcy5zdGRlcnJcbiAgICA6IHVuZGVmaW5lZDtcblxuY29uc3QgTE9HX0xFVkVMUyA9IFtcImRlYnVnXCIsIFwiaW5mb1wiLCBcIndhcm5cIiwgXCJlcnJvclwiXSBhcyBjb25zdDtcbmNvbnN0IExPR19MRVZFTF9SQU5LID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuICBMT0dfTEVWRUxTLm1hcCgobGV2ZWwsIGluZGV4KSA9PiBbbGV2ZWwsIGluZGV4XSksXG4pIGFzIFJlY29yZDxMb2dMZXZlbCwgbnVtYmVyPjtcbmNvbnN0IExPR19MRVZFTF9DT0xPUlMgPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gIExPR19MRVZFTFMubWFwKChsZXZlbCkgPT4ge1xuICAgIGxldCBjb2xvciA9IFwiXFx4MWJbOTBtXCI7IC8vIGdyYXlcbiAgICBzd2l0Y2ggKGxldmVsKSB7XG4gICAgICBjYXNlIFwiaW5mb1wiOlxuICAgICAgICBjb2xvciA9IFwiXFx4MWJbMzRtXCI7IC8vIGJsdWVcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwid2FyblwiOlxuICAgICAgICBjb2xvciA9IFwiXFx4MWJbMzNtXCI7IC8vIHllbGxvd1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCJlcnJvclwiOlxuICAgICAgICBjb2xvciA9IFwiXFx4MWJbMzFtXCI7IC8vIHJlZFxuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIFtsZXZlbCwgY29sb3JdO1xuICB9KSxcbikgYXMgUmVjb3JkPExvZ0xldmVsLCBzdHJpbmc+O1xuY29uc3QgTE9HX0xFVkVMX0NPTE9SX1JFU0VUID0gXCJcXHgxYlswbVwiO1xuY29uc3QgREVGQVVMVF9MRVZFTDogTG9nTGV2ZWwgPSBcImluZm9cIjtcblxuLyoqXG4gKiBTdXBwb3J0ZWQgc2V2ZXJpdGllcywgbG93ZXN0IHRvIGhpZ2hlc3Q6IGBkZWJ1Z2AsIGBpbmZvYCwgYHdhcm5gLCBgZXJyb3JgLlxuICogQSBjYWxsIGJlbG93IHRoZSBhY3RpdmUgdGhyZXNob2xkIGlzIGRpc2NhcmRlZCBiZWZvcmUgYW55IHN0cmluZyB3b3JrIG9yXG4gKiBzaW5rIEkvTy5cbiAqXG4gKiBUaGUgdGhyZXNob2xkIGNvbWVzIGZyb20gYHByb2Nlc3MuZW52LkxPR19MRVZFTGAgb24gZXZlcnkgY2FsbFxuICogKGNhc2UtaW5zZW5zaXRpdmUsIGRlZmF1bHQgYGluZm9gIHdoZW4gdW5zZXQsIGVtcHR5LCBvciB1bmtub3duKSBzbyB0ZXN0XG4gKiBydW5uZXJzIGFuZCBlbWJlZGRlcnMgY2FuIGNoYW5nZSB2ZXJib3NpdHkgYWZ0ZXIgaW1wb3J0IHdpdGhvdXQgcmVzdGFydGluZ1xuICogdGhlIHByb2Nlc3MuXG4gKi9cbmV4cG9ydCB0eXBlIExvZ0xldmVsID0gKHR5cGVvZiBMT0dfTEVWRUxTKVtudW1iZXJdO1xuXG5leHBvcnQgdHlwZSBMb2dnZXIgPSB7XG4gIFtLIGluIExvZ0xldmVsXTogKC4uLmFyZ3M6IGFueVtdKSA9PiB2b2lkO1xufSAmIHtcbiAgLyoqIFN1Y2Nlc3MgbWVzc2FnZSAoY29uc29sYSBgc3VjY2Vzc2A7IGZhbGxzIGJhY2sgdG8gYGluZm9gLWxldmVsIG91dHB1dCkuICovXG4gIHN1Y2Nlc3M6ICguLi5hcmdzOiBhbnlbXSkgPT4gdm9pZDtcbiAgLyoqIFN0YXJ0IC8gaW4tcHJvZ3Jlc3MgbWVzc2FnZSAoY29uc29sYSBgc3RhcnRgOyBmYWxscyBiYWNrIHRvIGBpbmZvYC1sZXZlbCBvdXRwdXQpLiAqL1xuICBzdGFydDogKC4uLmFyZ3M6IGFueVtdKSA9PiB2b2lkO1xufTtcblxuLyoqIGAobmFtZT8pID0+IExvZ2dlcmAgc2luayBjb25zdHJ1Y3RvciByZXR1cm5lZCBieSB0aGUgaW5pdC10aW1lIGZhY3RvcnkgY2hhaW4uICovXG50eXBlIExvZ2dlckZhY3RvcnkgPSAobmFtZT86IHN0cmluZykgPT4gTG9nZ2VyO1xuXG4vKipcbiAqIENvbnNvbGEtYmFja2VkIHtAbGluayBMb2dnZXJGYWN0b3J5fSwgb3IgYHVuZGVmaW5lZGAgd2hlbiBjb25zb2xhIGlzXG4gKiBkaXNhYmxlZCwgZmFpbHMgdG8gaW1wb3J0LCBvciB0aHJvd3MgZHVyaW5nIHNldHVwLlxuICpcbiAqIEJ1aWxkcyBvbmUgYGNyZWF0ZUNvbnNvbGFgIGluc3RhbmNlIChiYWRnZSBvZmYsIGxldmVsIGB2ZXJib3NlYCkgd2hvc2VcbiAqIHJlcG9ydGVyIGNhbGxzIHtAbGluayBzaG91bGRFbWl0fSBvbiBgbG9nT2JqLnR5cGVgIGJlZm9yZSBkZWxlZ2F0aW5nIHRvXG4gKiBjb25zb2xhJ3MgZGVmYXVsdCByZXBvcnRlcnMuIEluIE5vZGUsIHdoZW4gYGdsb2JhbFByb2Nlc3NTdGRFcnJgIGlzIHNldCxcbiAqIHJlY29nbml6ZWQge0BsaW5rIExvZ0xldmVsfSB0eXBlcyBhcmUgcmVkaXJlY3RlZCB0byBzdGRlcnIgZm9yIHRoYXQgd3JpdGUuXG4gKiBUYWdzIHVzZSBgd2l0aFRhZ2AgKHJlbmRlcmVkIGBbbmFtZV1gLCBub3QgbWVyZ2VkIGludG8gYXJncykuXG4gKlxuICogTWVtb2l6ZWQ6IHRoZSBkeW5hbWljIGBjb25zb2xhYCBpbXBvcnQsIGVudiBjaGVja3MsIGFuZCBgY3JlYXRlQ29uc29sYWBcbiAqIHNldHVwIChwbHVzIHRoZSBpbXBvcnQvdGhyb3cgZmFsbGJhY2spIHJ1biBvbmNlOyBsYXRlciBjYWxscyBzaGFyZSB0aGUgb25lXG4gKiByZXNvbHZlZCBmYWN0b3J5IChvciB0aGUgb25lIHJlc29sdmVkIGB1bmRlZmluZWRgKS4gQSByZWplY3Rpb24gaXMgZXZpY3RlZFxuICogYnkge0BsaW5rIG1lbW9pemV9IHNvIGEgbGF0ZXIgY2FsbCByZXRyaWVzLlxuICovXG5jb25zdCBjcmVhdGVDb25zb2xhTG9nZ2VyRmFjdG9yeSA9IG1lbW9pemUoYXN5bmMgKCk6IFByb21pc2U8TG9nZ2VyRmFjdG9yeSB8IHVuZGVmaW5lZD4gPT4ge1xuICBjb25zdCBjb25zb2xhRGlzYWJsZWQgPSB0b0Jvb2xlYW4oZ2xvYmFsUHJvY2Vzcz8uZW52Py5MT0dfQ09OU09MQV9ESVNBQkxFRCk7XG4gIGlmICghY29uc29sYURpc2FibGVkKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHsgY29uc29sYSwgY3JlYXRlQ29uc29sYSwgTG9nTGV2ZWxzIH0gPSBhd2FpdCBpbXBvcnQoLyogQHZpdGUtaWdub3JlICovIFwiY29uc29sYVwiKTtcbiAgICAgIGNvbnN0IGRlZmF1bHRPcHRpb25zID0gY29uc29sYS5vcHRpb25zO1xuICAgICAgY29uc3QgY3JlYXRlQ29uc29sYU9wdGlvbnMgPSB7XG4gICAgICAgIC4uLmNvbnNvbGEub3B0aW9ucyxcbiAgICAgICAgZGVmYXVsdHM6IHsgYmFkZ2U6IGZhbHNlIH0sXG4gICAgICAgIC8vIGBMT0dfTEVWRUxgIGlzIGVuZm9yY2VkIGluIHtAbGluayBzaG91bGRFbWl0fTsga2VlcCBjb25zb2xhIHBlcm1pc3NpdmVcbiAgICAgICAgLy8gc28gYSB0aHJlc2hvbGQgY2hhbmdlIGFmdGVyIGltcG9ydCBpcyBub3QgYmxvY2tlZCBieSBpdHMgb3duIGZpbHRlci5cbiAgICAgICAgbGV2ZWw6IExvZ0xldmVscy52ZXJib3NlLFxuICAgICAgICByZXBvcnRlcnM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBsb2c6IChsb2dPYmosIGN0eCkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCBsb2dMZXZlbCA9IHBhcnNlTG9nTGV2ZWwobG9nT2JqLnR5cGUpO1xuICAgICAgICAgICAgICBpZiAoIXNob3VsZEVtaXQobG9nTGV2ZWwsIHRydWUpKSByZXR1cm47XG4gICAgICAgICAgICAgIGNvbnN0IGN0eFN0ZG91dCA9IGN0eC5vcHRpb25zLnN0ZG91dDtcbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBpZiAoZ2xvYmFsUHJvY2Vzc1N0ZEVyciAhPT0gdW5kZWZpbmVkICYmIGxvZ0xldmVsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgIGN0eC5vcHRpb25zLnN0ZG91dCA9IGdsb2JhbFByb2Nlc3NTdGRFcnI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlZmF1bHRPcHRpb25zLnJlcG9ydGVycy5mb3JFYWNoKChyZXBvcnRlcikgPT4gcmVwb3J0ZXIubG9nKGxvZ09iaiwgY3R4KSk7XG4gICAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgICAgY3R4Lm9wdGlvbnMuc3Rkb3V0ID0gY3R4U3Rkb3V0O1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9IGFzIE5vbk51bGxhYmxlPFBhcmFtZXRlcnM8dHlwZW9mIGNyZWF0ZUNvbnNvbGE+WzBdPjtcbiAgICAgIGNvbnN0IGNvbnNvbGFMb2dnZXIgPSBjcmVhdGVDb25zb2xhKGNyZWF0ZUNvbnNvbGFPcHRpb25zKTtcbiAgICAgIHJldHVybiAobmFtZT86IHN0cmluZykgPT4ge1xuICAgICAgICByZXR1cm4gbmFtZSA/IGNvbnNvbGFMb2dnZXIud2l0aFRhZyhuYW1lKSA6IGNvbnNvbGFMb2dnZXI7XG4gICAgICB9O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBjb25zb2xhIGlzIGFuIE9QVElPTkFMIHBlZXIgLSBub3QgaGF2aW5nIGl0IGluc3RhbGxlZCBpcyB0aGUgRVhQRUNURURcbiAgICAgIC8vIHBhdGggKHRoZSBtb2R1bGUgZGVncmFkZXMgdG8gdGhlIGNvbnNvbGUgZmFsbGJhY2spLCBzbyB0aGlzIGlzIG5vdCBhblxuICAgICAgLy8gZXJyb3IuIE5vdGUgaXQgb25seSBhdCBkZWJ1ZyBsZXZlbCwgYW5kIHdpdGhvdXQgYSBzdGFjayB0cmFjZSAodGhlXG4gICAgICAvLyBtZXNzYWdlLCBub3QgYGNvbnNvbGUudHJhY2VgLCBzbyBhIG1pc3Npbmcgb3B0aW9uYWwgZGVwIHN0YXlzIHF1aWV0KS5cbiAgICAgIGlmIChpc0xldmVsRW5hYmxlZChcImRlYnVnXCIpKSB7XG4gICAgICAgIGNvbnNvbGUuZGVidWcoXCJjb25zb2xhIG5vdCBhdmFpbGFibGU7IHVzaW5nIGNvbnNvbGUgZmFsbGJhY2s6XCIsIFN0cmluZyhlcnJvcikpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufSk7XG5cbi8qKlxuICogQ29uc29sZSB7QGxpbmsgTG9nZ2VyRmFjdG9yeX07IGFsd2F5cyBzdWNjZWVkcy5cbiAqXG4gKiBXaGVuIGBwcm9jZXNzLnN0ZGVycmAgaXMgYXZhaWxhYmxlLCBmb3JtYXRzIGVhY2ggbGluZSBhbmQgd3JpdGVzIG9ubHkgdG9cbiAqIHN0ZGVyci4gQnVuIGBpbnNwZWN0YCBmb3JtYXRzIGVhY2ggYXJndW1lbnQgd2hlbiBlbmFibGVkOyBvdGhlcndpc2VcbiAqIGB1dGlsLmluc3BlY3RgIHdoZW4gYG5vZGU6dXRpbGAgbG9hZHMsIG9yIGEgYEpTT04uc3RyaW5naWZ5YCBmYWxsYmFjayB3aGVuXG4gKiBpdCBkb2VzIG5vdC4gV2hlbiBzdGRlcnIgaXMgdW5hdmFpbGFibGUgKGV2ZXJ5IGJyb3dzZXIpLCBiaW5kc1xuICoge0BsaW5rIGNyZWF0ZUZvcm1hdHRlcn0gcHJlZml4ZXMgaW50byBnbG9iYWwgYGNvbnNvbGUuKmAgY2FsbHMgYW5kIHNraXBzIHRoZVxuICogYG5vZGU6dXRpbGAgaW1wb3J0IGVudGlyZWx5LlxuICovXG5hc3luYyBmdW5jdGlvbiBjcmVhdGVDb25zb2xlTG9nZ2VyRmFjdG9yeShnbG9iYWxQcm9jZXNzU3RkRXJyOiBhbnkpOiBQcm9taXNlPExvZ2dlckZhY3Rvcnk+IHtcbiAgLy8gSW5kaXJlY3Qgc3BlY2lmaWVyIHNvIHRoaXMgYnJvd3Nlci1zYWZlIG1vZHVsZSBkb2Vzbid0IHN0YXRpY2FsbHkgcHVsbCBpblxuICAvLyBub2RlIHR5cGVzOiBgbm9kZTp1dGlsYCBpcyBvcHRpb25hbCAodGhlIEpTT04gZmFsbGJhY2sgY292ZXJzIGl0cyBhYnNlbmNlKS5cbiAgY29uc3Qgbm9kZVV0aWwgPSBcIm5vZGU6dXRpbFwiO1xuICAvLyBHYXRlZCwgbm90IGp1c3QgY2F1Z2h0OiB0aGUgaW5kaXJlY3Qgc3BlY2lmaWVyIGRlZmVhdHMgYnVuZGxlciBhbmFseXNpcyBieVxuICAvLyBkZXNpZ24sIHNvIGEgY2xpZW50IGJ1aWxkIGVtaXRzIGEgbGl0ZXJhbCBgaW1wb3J0KFwibm9kZTp1dGlsXCIpYCB0aGF0IG5vXG4gIC8vIGJyb3dzZXIgY2FuIHJlc29sdmUsIGFuZCB0aGUgY2F1Z2h0IHJlamVjdGlvbiBzdGlsbCBzdXJmYWNlZCBhcyBhIGNvbnNvbGVcbiAgLy8gZXJyb3IuIGB1dGlsc2Agb25seSBmZWVkcyB0aGUgc3RkZXJyIGJyYW5jaCBvZiB0aGUgZW1pdHRlciBiZWxvdywgc28gbm9cbiAgLy8gc3RkZXJyIG1lYW5zIHRoZSBpbXBvcnQgaGFzIG5vdGhpbmcgdG8gc2VydmUgYW5kIGlzIHNraXBwZWQgb3V0cmlnaHQuXG4gIGNvbnN0IHV0aWxzOiB7IGluc3BlY3Q/OiBhbnkgfSB8IHVuZGVmaW5lZCA9XG4gICAgZ2xvYmFsUHJvY2Vzc1N0ZEVyciA9PT0gdW5kZWZpbmVkXG4gICAgICA/IHVuZGVmaW5lZFxuICAgICAgOiBhd2FpdCBpbXBvcnQoLyogQHZpdGUtaWdub3JlICovIG5vZGVVdGlsKS5jYXRjaCgoKSA9PiB1bmRlZmluZWQpO1xuICByZXR1cm4gY29uc29sZUxvZ2dlckZhY3RvcnkoZ2xvYmFsUHJvY2Vzc1N0ZEVyciwgdXRpbHMpO1xufVxuXG4vKipcbiAqIFRoZSBzeW5jaHJvbm91cyBjb3JlIG9mIHtAbGluayBjcmVhdGVDb25zb2xlTG9nZ2VyRmFjdG9yeX0sIHNwbGl0IG91dCBzbyB0aGVcbiAqIHNhbWUgZW1pdHRlciBhbHNvIHNlcnZlcyBhcyB0aGUgYm9vdHN0cmFwIHNpbmsgYmVmb3JlIGFueSBhc3luYyBmYWN0b3J5IGhhc1xuICogcmVzb2x2ZWQuIGB1dGlsc2AgaXMgYG5vZGU6dXRpbGAgd2hlbiBpdCBsb2FkZWQ7IHdpdGhvdXQgaXQsIG9iamVjdCBhcmd1bWVudHNcbiAqIGZvcm1hdCB0aHJvdWdoIHRoZSBgSlNPTi5zdHJpbmdpZnlgIGZhbGxiYWNrLlxuICovXG5mdW5jdGlvbiBjb25zb2xlTG9nZ2VyRmFjdG9yeShcbiAgZ2xvYmFsUHJvY2Vzc1N0ZEVycjogYW55LFxuICB1dGlscz86IHsgaW5zcGVjdD86IGFueSB9IHwgdW5kZWZpbmVkLFxuKTogTG9nZ2VyRmFjdG9yeSB7XG4gIGNvbnN0IGJ1bkluc3BlY3QgPVxuICAgIGdsb2JhbEJ1biAhPT0gdW5kZWZpbmVkICYmICF0b0Jvb2xlYW4oZ2xvYmFsQnVuLmVudj8uTE9HX0JVTl9DT05TT0xFX0RJU0FCTEVEKVxuICAgICAgPyBnbG9iYWxCdW4uaW5zcGVjdFxuICAgICAgOiB1bmRlZmluZWQ7XG4gIGNvbnN0IHJlc2V0Q29sb3JzUHJlZml4ID0gYnVuSW5zcGVjdCAhPT0gdW5kZWZpbmVkO1xuXG4gIGNvbnN0IGluc3BlY3QgPSAoYXJnOiBhbnksIGNvbG9ycz86IGJvb2xlYW4pID0+IHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShhcmcpIHx8ICh0eXBlb2YgYXJnID09PSBcIm9iamVjdFwiICYmIGFyZyAhPT0gbnVsbCkpIHtcbiAgICAgIGlmIChidW5JbnNwZWN0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGJ1bkluc3BlY3QoYXJnLCB7XG4gICAgICAgICAgY29sb3JzOiBjb2xvcnMsXG4gICAgICAgICAgZGVwdGg6IHV0aWxzPy5pbnNwZWN0Py5kZWZhdWx0T3B0aW9ucz8uZGVwdGggPz8gdW5kZWZpbmVkLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAodXRpbHMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gdXRpbHMuaW5zcGVjdChhcmcsIHtcbiAgICAgICAgICAuLi51dGlscz8uaW5zcGVjdD8uZGVmYXVsdE9wdGlvbnMsXG4gICAgICAgICAgY29sb3JzOiBmYWxzZSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBzZWVuID0gbmV3IFdlYWtTZXQoKTtcbiAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGFyZywgKF8sIHZhbHVlKSA9PiB7XG4gICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIiAmJiB2YWx1ZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKHNlZW4uaGFzKHZhbHVlKSkgcmV0dXJuIFwiW0NpcmN1bGFyXVwiO1xuICAgICAgICAgICAgc2Vlbi5hZGQodmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gU3RyaW5nKGFyZyk7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IGZhY3RvcnkgPSAobmFtZT86IHN0cmluZykgPT4ge1xuICAgIGNvbnN0IHByZWZpeEZvcm1hdHRlciA9IGNyZWF0ZUZvcm1hdHRlcihuYW1lLCBnbG9iYWxQcm9jZXNzU3RkRXJyLCByZXNldENvbG9yc1ByZWZpeCk7XG4gICAgY29uc3QgbG9nZ2VyID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgTE9HX0xFVkVMUy5tYXAoKGxldmVsKSA9PiB7XG4gICAgICAgIGNvbnN0IHsgcHJlZml4LCBjb2xvcnMsIHJlc2V0Q29sb3JzIH0gPSBwcmVmaXhGb3JtYXR0ZXIobGV2ZWwpO1xuICAgICAgICBjb25zdCBlbWl0dGVyID0gKC4uLmFyZ3M6IGFueVtdKSA9PiB7XG4gICAgICAgICAgaWYgKCFzaG91bGRFbWl0KGxldmVsLCB0cnVlKSkgcmV0dXJuO1xuICAgICAgICAgIGlmIChnbG9iYWxQcm9jZXNzU3RkRXJyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGNvbnN0IG1lc3NhZ2VQYXJ0cyA9IHByZWZpeCA/IFtwcmVmaXhdIDogW107XG4gICAgICAgICAgICBtZXNzYWdlUGFydHMucHVzaCguLi5hcmdzLm1hcCgoYXJnKSA9PiBpbnNwZWN0KGFyZywgY29sb3JzKSkpO1xuICAgICAgICAgICAgaWYgKHJlc2V0Q29sb3JzKSBtZXNzYWdlUGFydHMucHVzaChMT0dfTEVWRUxfQ09MT1JfUkVTRVQpO1xuICAgICAgICAgICAgZ2xvYmFsUHJvY2Vzc1N0ZEVyci53cml0ZShtZXNzYWdlUGFydHMuam9pbihcIiBcIikgKyBcIlxcblwiKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGV0IGxldmVsRm4gPSBjb25zb2xlW2xldmVsXTtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgbGV2ZWxGbiAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICAgIGxldmVsRm4gPSBjb25zb2xlLmxvZztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwcmVmaXgpIGxldmVsRm4gPSBsZXZlbEZuLmJpbmQoY29uc29sZSwgcHJlZml4KTtcbiAgICAgICAgICAgIGxldmVsRm4oLi4uYXJncyk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gW2xldmVsLCBlbWl0dGVyXTtcbiAgICAgIH0pLFxuICAgICkgYXMgTG9nZ2VyO1xuICAgIC8vIGNvbnNvbGEgc3VnYXIgdGhlIGNvbnNvbGUgZmFsbGJhY2sgZG9lc24ndCBoYXZlIG5hdGl2ZWx5IC0gcm91dGUgdG8gaW5mby5cbiAgICBsb2dnZXIuc3VjY2VzcyA9IGxvZ2dlci5pbmZvO1xuICAgIGxvZ2dlci5zdGFydCA9IGxvZ2dlci5pbmZvO1xuICAgIHJldHVybiBsb2dnZXI7XG4gIH07XG4gIGNvbnN0IGRlZmF1bHRGYWN0b3J5ID0gbWVtb2l6ZShmYWN0b3J5KTtcbiAgcmV0dXJuIChuYW1lPzogc3RyaW5nKSA9PiAobmFtZSA/IGZhY3RvcnkobmFtZSkgOiBkZWZhdWx0RmFjdG9yeSgpKTtcbn1cblxuLyoqXG4gKiBQcmVmZXJyZWQgZmFjdG9yeTogY29uc29sYSB3aGVuIGl0IGxvYWRzLCBlbHNlIHRoZSBmdWxsIGNvbnNvbGUgc2luayAod2l0aFxuICogb3B0aW9uYWwgYG5vZGU6dXRpbGAgaW5zcGVjdCkuIE1lbW9pemVkIHNvIGNvbmN1cnJlbnQgLyByZXBlYXQgY2FsbGVycyBzaGFyZVxuICogb25lIGluLWZsaWdodCBwcm9taXNlIGFuZCBvbmUgc2V0dGxlZCByZXN1bHQuXG4gKi9cbmNvbnN0IHJlc29sdmVGYWN0b3J5ID0gbWVtb2l6ZShhc3luYyAoKTogUHJvbWlzZTxMb2dnZXJGYWN0b3J5PiA9PiB7XG4gIHJldHVybiAoXG4gICAgKGF3YWl0IGNyZWF0ZUNvbnNvbGFMb2dnZXJGYWN0b3J5KCkpID8/IChhd2FpdCBjcmVhdGVDb25zb2xlTG9nZ2VyRmFjdG9yeShnbG9iYWxQcm9jZXNzU3RkRXJyKSlcbiAgKTtcbn0pO1xuXG4vKipcbiAqIEFjdGl2ZSBmYWN0b3J5IHN0YXJ0cyBhcyBhIHN5bmMgY29uc29sZSBzaW5rIChubyBgYXdhaXRgLCBzbyB0aGlzIG1vZHVsZVxuICogZmluaXNoZXMgZXZhbHVhdGluZyBpbW1lZGlhdGVseSkgYW5kIHN3YXBzIHRvIHtAbGluayByZXNvbHZlRmFjdG9yeX0nc1xuICogcmVzdWx0IHdoZW4gdGhhdCBsYW5kcy4gS2ljayB0aGUgcmVzb2x2ZSBvZmYgYXQgbG9hZCBzbyBjb25zb2xhIGlzIHVzdWFsbHlcbiAqIHJlYWR5IGJlZm9yZSB0aGUgZmlyc3QgaW50ZXJlc3RpbmcgbG9nIGxpbmUuXG4gKi9cbmxldCBhY3RpdmVGYWN0b3J5OiBMb2dnZXJGYWN0b3J5ID0gY29uc29sZUxvZ2dlckZhY3RvcnkoZ2xvYmFsUHJvY2Vzc1N0ZEVycik7XG52b2lkIHJlc29sdmVGYWN0b3J5KCkudGhlbihcbiAgKGZhY3RvcnkpID0+IHtcbiAgICBhY3RpdmVGYWN0b3J5ID0gZmFjdG9yeTtcbiAgfSxcbiAgKCkgPT4ge1xuICAgIC8vIEtlZXAgdGhlIHN5bmMgY29uc29sZSBzaW5rOyBuZXZlciBsZWF2ZSBpbXBvcnRlcnMgd2l0aG91dCBhIGZhY3RvcnkuXG4gIH0sXG4pO1xuXG4vKipcbiAqIEJ1aWxkIGEgbG9nZ2VyIHRoYXQgcmViaW5kcyB3aGVuIHtAbGluayBhY3RpdmVGYWN0b3J5fSB1cGdyYWRlcy4gQ2FsbGVycyB0aGF0XG4gKiBjYXB0dXJlIGBjb25zdCBsb2cgPSBsb2dnZXIoXCJ4XCIpYCBhdCBtb2R1bGUgc2NvcGUgc3RpbGwgZ2V0IGNvbnNvbGEgb25jZSBpdFxuICogYXJyaXZlcywgd2l0aG91dCBldmVyeSBjYWxsIHNpdGUgd2FpdGluZyBvbiBhIHByb21pc2UuXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUxvZ2dlcihuYW1lPzogc3RyaW5nKTogTG9nZ2VyIHtcbiAgbGV0IGJvdW5kOiB7IGZhY3Rvcnk6IExvZ2dlckZhY3Rvcnk7IGxvZ2dlcjogTG9nZ2VyIH0gfCB1bmRlZmluZWQ7XG4gIGNvbnN0IHNpbmsgPSAoKTogTG9nZ2VyID0+IHtcbiAgICBpZiAoYm91bmQ/LmZhY3RvcnkgIT09IGFjdGl2ZUZhY3RvcnkpIHtcbiAgICAgIGJvdW5kID0geyBmYWN0b3J5OiBhY3RpdmVGYWN0b3J5LCBsb2dnZXI6IGFjdGl2ZUZhY3RvcnkobmFtZSkgfTtcbiAgICB9XG4gICAgcmV0dXJuIGJvdW5kLmxvZ2dlcjtcbiAgfTtcbiAgcmV0dXJuIE9iamVjdC5mcm9tRW50cmllcyhcbiAgICBbLi4uTE9HX0xFVkVMUywgXCJzdWNjZXNzXCIsIFwic3RhcnRcIl0ubWFwKChsZXZlbCkgPT4gW1xuICAgICAgbGV2ZWwsXG4gICAgICAoLi4uYXJnczogYW55W10pID0+IHNpbmsoKVtsZXZlbCBhcyBrZXlvZiBMb2dnZXJdKC4uLmFyZ3MpLFxuICAgIF0pLFxuICApIGFzIExvZ2dlcjtcbn1cblxuLyoqXG4gKiBCdWlsZCBhIGxpbmUgcHJlZml4IG9mIGBMRVZFTCBbbmFtZV1gIG9uIE5vZGUvQnVuIGhvc3RzLCBvciBgW25hbWVdYCBhbG9uZVxuICogaW4gYnJvd3NlcnMgKGVpdGhlciBwYXJ0IG9taXR0ZWQgd2hlbiBhYnNlbnQpLiBBcHBsaWVzIHBlci1sZXZlbCBBTlNJIGNvbG9yXG4gKiB3aGVuIGBzdHJlYW1TdXBwb3J0c0NvbG9yYCBpcyB0cnVlIGZvciB0aGUgZ2l2ZW4gc3RkZXJyIHN0cmVhbS5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlRm9ybWF0dGVyKFxuICBuYW1lOiBhbnksXG4gIHN0cmVhbTogYW55LFxuICByZXNldENvbG9yc1ByZWZpeD86IGJvb2xlYW4sXG4pOiAobGV2ZWw/OiBMb2dMZXZlbCkgPT4geyBwcmVmaXg6IHN0cmluZzsgY29sb3JzOiBib29sZWFuOyByZXNldENvbG9yczogYm9vbGVhbiB9IHtcbiAgY29uc3QgZ2xvYiA9IGdsb2JhbFRoaXMgYXMgeyB3aW5kb3c/OiB1bmtub3duOyBkb2N1bWVudD86IHVua25vd24gfTtcbiAgY29uc3QgaXNCcm93c2VyID0gZ2xvYi53aW5kb3cgIT09IHVuZGVmaW5lZCAmJiBnbG9iLmRvY3VtZW50ICE9PSB1bmRlZmluZWQ7XG4gIGNvbnN0IHN1cHBvcnRzQ29sb3IgPSAhaXNCcm93c2VyID8gc3RyZWFtU3VwcG9ydHNDb2xvcihzdHJlYW0pIDogZmFsc2U7XG4gIGNvbnN0IG5hbWVQcmVmaXggPSBuYW1lID8gXCJbXCIgKyBuYW1lICsgXCJdXCIgOiB1bmRlZmluZWQ7XG4gIHJldHVybiAobGV2ZWw/OiBMb2dMZXZlbCkgPT4ge1xuICAgIGNvbnN0IGNvbG9yID0gc3VwcG9ydHNDb2xvciAmJiBsZXZlbCAhPT0gdW5kZWZpbmVkID8gTE9HX0xFVkVMX0NPTE9SU1tsZXZlbF0gOiB1bmRlZmluZWQ7XG4gICAgbGV0IHByZWZpeCA9IFshaXNCcm93c2VyICYmIGxldmVsID8gbGV2ZWwudG9VcHBlckNhc2UoKSA6IHVuZGVmaW5lZCwgbmFtZVByZWZpeF1cbiAgICAgIC5maWx0ZXIoQm9vbGVhbilcbiAgICAgIC5qb2luKFwiIFwiKTtcbiAgICBsZXQgcmVzZXRDb2xvcnMgPSBmYWxzZTtcbiAgICBpZiAoY29sb3IpIHtcbiAgICAgIGNvbnN0IGFwcGx5UmVzZXRDb2xvcnNQcmVmaXggPSByZXNldENvbG9yc1ByZWZpeCB8fCBcImluZm9cIiA9PT0gbGV2ZWw7XG4gICAgICBpZiAoIWFwcGx5UmVzZXRDb2xvcnNQcmVmaXgpIHJlc2V0Q29sb3JzID0gdHJ1ZTtcbiAgICAgIHByZWZpeCA9IGFwcGx5UmVzZXRDb2xvcnNQcmVmaXggPyBjb2xvciArIHByZWZpeCArIExPR19MRVZFTF9DT0xPUl9SRVNFVCA6IGNvbG9yICsgcHJlZml4O1xuICAgIH1cbiAgICByZXR1cm4geyBwcmVmaXgsIGNvbG9yczogY29sb3IgPyB0cnVlIDogZmFsc2UsIHJlc2V0Q29sb3JzIH07XG4gIH07XG59XG5cbi8qKiBUcnVlIHdoZW4gYHN0cmVhbWAgaXMgYSBUVFkgYW5kIHRoZSB0ZXJtaW5hbCBpcyBub3QgYGR1bWJgLiAqL1xuZnVuY3Rpb24gc3RyZWFtU3VwcG9ydHNDb2xvcihzdHJlYW0/OiB1bmtub3duKTogYm9vbGVhbiB7XG4gIGlmIChnbG9iYWxQcm9jZXNzID09PSB1bmRlZmluZWQgfHwgdHlwZW9mIHN0cmVhbSAhPT0gXCJvYmplY3RcIiB8fCBzdHJlYW0gPT09IG51bGwpIHJldHVybiBmYWxzZTtcbiAgY29uc3QgeyBpc1RUWSB9ID0gc3RyZWFtIGFzIHsgaXNUVFk/OiB1bmtub3duIH07XG4gIGlmIChpc1RUWSAhPT0gdHJ1ZSkgcmV0dXJuIGZhbHNlO1xuICBjb25zdCB0ZXJtID0gZ2xvYmFsUHJvY2Vzcy5lbnY/LlRFUk0/LnRvTG93ZXJDYXNlKCk7XG4gIGlmIChcImR1bWJcIiA9PSB0ZXJtKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiB0cnVlO1xufVxuXG4vKiogUGFyc2UgYSByYXcgdmFsdWUgYXMge0BsaW5rIExvZ0xldmVsfSAodHJpbW1lZCwgY2FzZS1pbnNlbnNpdGl2ZSkuICovXG5mdW5jdGlvbiBwYXJzZUxvZ0xldmVsKHJhdzogdW5rbm93bik6IExvZ0xldmVsIHwgdW5kZWZpbmVkIHtcbiAgaWYgKHJhdyA9PT0gdW5kZWZpbmVkIHx8IHJhdyA9PT0gbnVsbCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgbGV0IHRleHQgPSB0eXBlb2YgcmF3ID09PSBcInN0cmluZ1wiID8gcmF3IDogU3RyaW5nKHJhdyk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgMjsgaSsrKSB7XG4gICAgaWYgKGkgPiAwKSB7XG4gICAgICBjb25zdCBub3JtYWxpemVkID0gdGV4dC50cmltKCkudG9Mb3dlckNhc2UoKTtcbiAgICAgIGlmICh0ZXh0ID09PSBub3JtYWxpemVkKSBicmVhaztcbiAgICAgIHRleHQgPSBub3JtYWxpemVkO1xuICAgIH1cbiAgICBpZiAoIXRleHQpIHtcbiAgICAgIGJyZWFrO1xuICAgIH0gZWxzZSBpZiAodGV4dCBpbiBMT0dfTEVWRUxfUkFOSykge1xuICAgICAgcmV0dXJuIHRleHQgYXMgTG9nTGV2ZWw7XG4gICAgfVxuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKiBBY3RpdmUgdGhyZXNob2xkIGZyb20gYHByb2Nlc3MuZW52LkxPR19MRVZFTGAsIGRlZmF1bHQge0BsaW5rIERFRkFVTFRfTEVWRUx9LiAqL1xuZnVuY3Rpb24gYWN0aXZlTGV2ZWwoKTogTG9nTGV2ZWwge1xuICByZXR1cm4gcGFyc2VMb2dMZXZlbChnbG9iYWxQcm9jZXNzPy5lbnY/LkxPR19MRVZFTCkgPz8gREVGQVVMVF9MRVZFTDtcbn1cblxuLyoqXG4gKiBXaGV0aGVyIGByYXdgIG1lZXRzIHRoZSBjdXJyZW50IGBMT0dfTEVWRUxgIHRocmVzaG9sZC5cbiAqXG4gKiBQYXJzZXMgYHJhd2AgYXMgYSB7QGxpbmsgTG9nTGV2ZWx9OyB3aGVuIHBhcnNpbmcgZmFpbHMsIHJldHVybnNcbiAqIGBkZWZhdWx0UmVzdWx0YCBpZiBzdXBwbGllZCwgb3RoZXJ3aXNlIGBmYWxzZWAuIFVzZWQgZm9yIGNvbnNvbGEgcmVwb3J0ZXJcbiAqIGxpbmVzIHdoZXJlIHVua25vd24gYGxvZ09iai50eXBlYCB2YWx1ZXMgc2hvdWxkIHBhc3MgdGhyb3VnaCB3aGVuXG4gKiBgZGVmYXVsdFJlc3VsdGAgaXMgYHRydWVgLlxuICovXG5mdW5jdGlvbiBzaG91bGRFbWl0KHJhdzogdW5rbm93biwgZGVmYXVsdFJlc3VsdD86IGJvb2xlYW4pOiBib29sZWFuIHtcbiAgY29uc3QgbGV2ZWwgPSBwYXJzZUxvZ0xldmVsKHJhdyk7XG4gIGlmIChsZXZlbCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gZGVmYXVsdFJlc3VsdCA/PyBmYWxzZTtcbiAgcmV0dXJuIExPR19MRVZFTF9SQU5LW2xldmVsXSA+PSBMT0dfTEVWRUxfUkFOS1thY3RpdmVMZXZlbCgpXTtcbn1cblxuLyoqXG4gKiBXaGV0aGVyIGEgY2FsbCBhdCBgbGV2ZWxgIHdvdWxkIGJlIGVtaXR0ZWQgYXQgdGhlIGN1cnJlbnRcbiAqIGBwcm9jZXNzLmVudi5MT0dfTEVWRUxgIHRocmVzaG9sZC4gVXNlIGJlZm9yZSBidWlsZGluZyBleHBlbnNpdmUgZGVidWdcbiAqIHBheWxvYWRzLlxuICpcbiAqIEBleGFtcGxlXG4gKiBpZiAoaXNMZXZlbEVuYWJsZWQoXCJkZWJ1Z1wiKSkge1xuICogICBsb2cuZGVidWcoXCJtb3VudHM6cmVzb2x2ZXJcIiwgeyBjb250cmlidXRpb246IGF3YWl0IGhlYXZ5U25hcHNob3QoKSB9KTtcbiAqIH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzTGV2ZWxFbmFibGVkKGxldmVsOiBMb2dMZXZlbCk6IGJvb2xlYW4ge1xuICByZXR1cm4gc2hvdWxkRW1pdChsZXZlbCk7XG59XG5cbmNvbnN0IExPR0dFUl9OQU1FX1JFR0VYID0gL14oPzpbYS16XVthLXowLTkrLi1dKjpcXC9cXC8pPy4qXFwvKFteLy5dKykoPzpcXC5bXi9dKyk/JC9pO1xuXG4vKipcbiAqIERlcml2ZSB0aGUgdGFnIHN0cmluZyBmcm9tIGEgbG9nZ2VyIG5hbWUsIHBsdWdpbiwgb3IgcGF0aC4gU2xhc2gtIGFuZFxuICogVVJMLXNoYXBlZCBzdHJpbmdzIHVzZSB0aGUgbGFzdCBwYXRoIHNlZ21lbnQgKGV4dGVuc2lvbiBzdHJpcHBlZCk7IHBsYWluXG4gKiBzdHJpbmdzIHBhc3MgdGhyb3VnaCB1bmNoYW5nZWQuIEVtcHR5IG9yIG1pc3NpbmcgbmFtZXMgLT4gYHVuZGVmaW5lZGBcbiAqICh1bnRhZ2dlZCBzaW5rKS5cbiAqL1xuZnVuY3Rpb24gZXh0cmFjdExvZ2dlck5hbWUobG9nZ2VyTmFtZTogTmFtZUxpa2UgfCBzdHJpbmcgfCB1bmRlZmluZWQpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBpZiAoIWxvZ2dlck5hbWUpIHJldHVybiB1bmRlZmluZWQ7XG4gIGlmICh0eXBlb2YgbG9nZ2VyTmFtZSA9PT0gXCJzdHJpbmdcIikge1xuICAgIGNvbnN0IG1hdGNoID0gbG9nZ2VyTmFtZS5tYXRjaChMT0dHRVJfTkFNRV9SRUdFWCk7XG4gICAgcmV0dXJuIG1hdGNoPy5bMV0gPz8gbG9nZ2VyTmFtZTtcbiAgfVxuICByZXR1cm4gZXh0cmFjdExvZ2dlck5hbWUobG9nZ2VyTmFtZS5uYW1lKTtcbn1cblxuLyoqXG4gKiBCdWlsZCBhIHRhZ2dlZCBsb2dnZXIgZm9yIGEgcGx1Z2luIG9yIG1vZHVsZS5cbiAqXG4gKiBUaGUgdGFnIGlzIGBbbmFtZV1gIHdoZW4gYGxvZ2dlck5hbWVgIGlzIGEgbm9uLWVtcHR5IHN0cmluZywgYVxuICoge0BsaW5rIE5hbWVMaWtlfSB3aXRoIGBuYW1lYCwgb3IgYSBmaWxlIC8gVVJMIHBhdGggKHRoZSBiYXNlbmFtZSB3aXRob3V0XG4gKiBleHRlbnNpb24gaXMgdXNlZCkuIENvbnNvbGEgYXBwbGllcyB0aGUgdGFnIHZpYSBgd2l0aFRhZ2AgKHJlbmRlci10aW1lKS5cbiAqIFRoZSBgY29uc29sZWAgZmFsbGJhY2tzIHByZXBlbmQgYExFVkVMIFtuYW1lXWAgb24gTm9kZS9CdW4gaG9zdHMgb3IgYFtuYW1lXWBcbiAqIGFsb25lIGluIGJyb3dzZXJzIHZpYSB7QGxpbmsgY3JlYXRlRm9ybWF0dGVyfS5cbiAqXG4gKiBDYWxscyBiZWxvdyBgcHJvY2Vzcy5lbnYuTE9HX0xFVkVMYCBhcmUgZHJvcHBlZCBieSB7QGxpbmsgc2hvdWxkRW1pdH0gYmVmb3JlXG4gKiB0aGUgc2luayBmb3JtYXRzIG9yIHdyaXRlcyB0aGUgbGluZS5cbiAqXG4gKiBAZXhhbXBsZVxuICogaW1wb3J0IHsgbG9nIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbiAqXG4gKiBjb25zdCBsb2dnZXIgPSBsb2cubG9nZ2VyKFwiZ2VuaWUvY2hhdFwiKTtcbiAqIGxvZ2dlci5pbmZvKFwic3RhcnRpbmdcIik7XG4gKiBsb2dnZXIud2FybihcIm1pc3Npbmcgb3B0aW9uYWwgY29uZmlnXCIsIHsgcmVhc29uOiBcIm5vIGVudiB2YXJcIiB9KTtcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxvZ2dlcihsb2dnZXJOYW1lOiBOYW1lTGlrZSB8IHN0cmluZyB8IHVuZGVmaW5lZCk6IExvZ2dlciB7XG4gIGNvbnN0IG5hbWUgPSBleHRyYWN0TG9nZ2VyTmFtZShsb2dnZXJOYW1lKTtcbiAgcmV0dXJuIGNyZWF0ZUxvZ2dlcihuYW1lKTtcbn1cbiJdfQ==
|
|
331
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2xvZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMkJHOzs7Ozs7Ozs7QUFFSCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3hDLE9BQU8sRUFBaUIsU0FBUyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBY3ZELE1BQU0sYUFBYSxHQUFJLFVBQXdDLENBQUMsT0FBTyxDQUFDO0FBQ3hFLE1BQU0sU0FBUyxHQUFJLFVBQWdDLENBQUMsR0FBRyxDQUFDO0FBRXhEOzs7OztHQUtHO0FBQ0gsOERBQThEO0FBQzlELE1BQU0sbUJBQW1CLEdBQ3ZCLGFBQWEsSUFBSSxPQUFPLGFBQWEsQ0FBQyxNQUFNLEVBQUUsS0FBSyxLQUFLLFVBQVU7SUFDaEUsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxNQUFNO0lBQ3RCLENBQUMsQ0FBQyxTQUFTLENBQUM7QUFFaEIsTUFBTSxVQUFVLEdBQUcsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQVUsQ0FBQztBQUMvRCxNQUFNLGNBQWMsR0FBRyxNQUFNLENBQUMsV0FBVyxDQUN2QyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FDckIsQ0FBQztBQUM5QixNQUFNLGdCQUFnQixHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQ3pDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtJQUN2QixJQUFJLEtBQUssR0FBRyxVQUFVLENBQUMsQ0FBQyxPQUFPO0lBQy9CLFFBQVEsS0FBSyxFQUFFLENBQUM7UUFDZCxLQUFLLE1BQU07WUFDVCxLQUFLLEdBQUcsVUFBVSxDQUFDLENBQUMsT0FBTztZQUMzQixNQUFNO1FBQ1IsS0FBSyxN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YUFBdUI7SUFDdkQsTUFBTSxLQUFLLEdBQUcsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2pDLElBQUksS0FBSyxLQUFLLFNBQVM7UUFBRSxPQUFPLGFBQWEsSUFBSSxLQUFLLENBQUM7SUFDdkQsT0FBTyxjQUFjLENBQUMsS0FBSyxDQUFDLElBQUksY0FBYyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7QUFDaEUsQ0FBQztBQUVEOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sVUFBVSxjQUFjLENBQUMsS0FBZTtJQUM1QyxPQUFPLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUMzQixDQUFDO0FBRUQsTUFBTSxpQkFBaUIsR0FBRyx3REFBd0QsQ0FBQztBQUVuRjs7Ozs7R0FLRztBQUNILFNBQVMsaUJBQWlCLENBQUMsVUFBeUM7SUFDbEUsSUFBSSxDQUFDLFVBQVU7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUNsQyxJQUFJLE9BQU8sVUFBVSxLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQ25DLE1BQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUNsRCxPQUFPLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLFVBQVUsQ0FBQztJQUNsQyxDQUFDO0lBQ0QsT0FBTyxpQkFBaUIsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDNUMsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUNILE1BQU0sVUFBVSxNQUFNLENBQUMsVUFBeUM7SUFDOUQsTUFBTSxJQUFJLEdBQUcsaUJBQWlCLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDM0MsT0FBTyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDNUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVGFnZ2VkLCBsZXZlbGVkIGxvZ2dpbmcgZm9yIGV2ZXJ5IHJ1bnRpbWUgLSB0aGUgb25lIGxvZ2dlciB0aGUgd2hvbGVcbiAqIG1vbm9yZXBvIHNoYXJlcy5cbiAqXG4gKiB7QGxpbmsgbG9nZ2VyfSByZXNvbHZlcyBhIHRhZ2dlZCB7QGxpbmsgTG9nZ2VyfSB0aHJvdWdoIGEgc3luY2hyb25vdXMgY29uc29sZVxuICogc2luaywgdGhlbiB1cGdyYWRlcyBpdHMgc2VydmVyLXNpZGUgZm9ybWF0dGVyIHdoZW4gYG5vZGU6dXRpbGAgcmVzb2x2ZXMuXG4gKiBLZWVwaW5nIHRoZSBzaW5rIGRlcGVuZGVuY3ktZnJlZSBwcmV2ZW50cyBicm93c2VyIGJ1bmRsZXJzIGZyb20gcmV0YWluaW5nIGFuXG4gKiBvcHRpb25hbCBiYXJlIGltcG9ydCB0aGF0IGRvd25zdHJlYW0gYXBwcyB3b3VsZCBzdGlsbCBoYXZlIHRvIGluc3RhbGwuXG4gKiB7QGxpbmsgTG9nTGV2ZWx9IGZpbHRlcmluZyBydW5zIHRocm91Z2gge0BsaW5rIHNob3VsZEVtaXR9IGluIHBlci1sZXZlbFxuICogd3JhcHBlcnMgYXJvdW5kIHRoZSBwbGF0Zm9ybSBjb25zb2xlIG9yIHN0ZGVyciBzaW5rLlxuICpcbiAqIFRoZSBjb25zb2xlIGZhbGxiYWNrIHdyaXRlcyBmb3JtYXR0ZWQgbGluZXMgdG8gYHByb2Nlc3Muc3RkZXJyYCB3aGVuIGl0IGlzXG4gKiBhdmFpbGFibGUgKEJ1biBgaW5zcGVjdGAgcGVyIGFyZ3VtZW50IHdoZW4gYExPR19CVU5fQ09OU09MRV9ESVNBQkxFRGAgaXNcbiAqIHVuc2V0LCBvdGhlcndpc2UgYG5vZGU6dXRpbGAgYGZvcm1hdFdpdGhPcHRpb25zYCksIG9yIGRlbGVnYXRlcyB0byBnbG9iYWxcbiAqIGBjb25zb2xlLipgIHdoZW4gc3RkZXJyIG9yIGBub2RlOnV0aWxgIGlzIHVuYXZhaWxhYmxlLiBCcm93c2VyIGhvc3RzIG9taXRcbiAqIHRoZSBgTEVWRUxgIHRleHQgcHJlZml4IChkZXZ0b29scyBzaG93IHNldmVyaXR5KSBhbmQga2VlcCBvbmx5IHRoZSBgW25hbWVdYFxuICogdGFnLlxuICpcbiAqIEVudiB0b2dnbGVzOiBgTE9HX0xFVkVMYCAocmVhZCBwZXIgY2FsbCkgYW5kIGBMT0dfQlVOX0NPTlNPTEVfRElTQUJMRURgXG4gKiAocmVhZCBvbmNlIGR1cmluZyBmYWN0b3J5IGluaXQpLlxuICpcbiAqIEJyb3dzZXItc2FmZTogYHByb2Nlc3NgIC8gYEJ1bmAgLyBgd2luZG93YCAvIGBkb2N1bWVudGAgYXJlIGFsbCByZWFjaGVkXG4gKiB0aHJvdWdoIGBnbG9iYWxUaGlzYCBhbmQgZ3VhcmRlZCwgYW5kIGBub2RlOnV0aWxgIGlzIGltcG9ydGVkIE9OTFkgb24gYSBob3N0XG4gKiB0aGF0IGhhcyBgcHJvY2Vzcy5zdGRlcnJgIC0gbmV2ZXIgaW4gYSBicm93c2VyLCB3aGVyZSB0aGUgc3BlY2lmaWVyIGlzXG4gKiB1bnJlc29sdmFibGUgLSBzbyB0aGUgbW9kdWxlIHdvcmtzIGluIGFueSBydW50aW1lLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBtZW1vaXplIH0gZnJvbSBcIi4vZnVuY3Rpb24udHNcIjtcbmltcG9ydCB7IHR5cGUgTmFtZUxpa2UsIHRvQm9vbGVhbiB9IGZyb20gXCIuL29iamVjdC50c1wiO1xuXG4vKiogYHByb2Nlc3NgLXNoYXBlZCB2aWV3IG9mZiBgZ2xvYmFsVGhpc2AsIHNvIG5vIG5vZGUgdHlwZXMgYXJlIG5lZWRlZC4gKi9cbmludGVyZmFjZSBQcm9jZXNzTGlrZSB7XG4gIGVudj86IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD47XG4gIHN0ZGVycj86IHsgd3JpdGU/OiAoY2h1bms6IHN0cmluZykgPT4gdm9pZDsgaXNUVFk/OiB1bmtub3duIH07XG59XG5cbi8qKiBgQnVuYC1zaGFwZWQgdmlldyBvZmYgYGdsb2JhbFRoaXNgLCBzbyBubyBgQHR5cGVzL2J1bmAgaXMgbmVlZGVkLiAqL1xuaW50ZXJmYWNlIEJ1bkxpa2Uge1xuICBlbnY/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+O1xuICBpbnNwZWN0PzogKHZhbHVlOiB1bmtub3duLCBvcHRpb25zPzogeyBjb2xvcnM/OiBib29sZWFuOyBkZXB0aD86IG51bWJlciB9KSA9PiBzdHJpbmc7XG59XG5cbmNvbnN0IGdsb2JhbFByb2Nlc3MgPSAoZ2xvYmFsVGhpcyBhcyB7IHByb2Nlc3M/OiBQcm9jZXNzTGlrZSB9KS5wcm9jZXNzO1xuY29uc3QgZ2xvYmFsQnVuID0gKGdsb2JhbFRoaXMgYXMgeyBCdW4/OiBCdW5MaWtlIH0pLkJ1bjtcblxuLyoqXG4gKiBOb2RlIGBwcm9jZXNzLnN0ZGVycmAgd2hlbiB3cml0YWJsZSwgZWxzZSBgdW5kZWZpbmVkYCAoc3RhYmxlIGZvciB0aGVcbiAqIHByb2Nlc3MpLiBUeXBlZCBsb29zZWx5IChgYW55YCkgYmVjYXVzZSBpdCBpcyBoYW5kZWQgdG8gdGhlIGNvbnNvbGUgc2luaydzXG4gKiBgLndyaXRlYCwgd2hpY2ggb3VyIHN0cnVjdHVyYWwge0BsaW5rIFByb2Nlc3NMaWtlfSBzaGFwZSBkb2VzIG5vdCBzYXRpc2Z5XG4gKiBub21pbmFsbHkuXG4gKi9cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG5jb25zdCBnbG9iYWxQcm9jZXNzU3RkRXJyOiBhbnkgPVxuICBnbG9iYWxQcm9jZXNzICYmIHR5cGVvZiBnbG9iYWxQcm9jZXNzLnN0ZGVycj8ud3JpdGUgPT09IFwiZnVuY3Rpb25cIlxuICAgID8gZ2xvYmFsUHJvY2Vzcy5zdGRlcnJcbiAgICA6IHVuZGVmaW5lZDtcblxuY29uc3QgTE9HX0xFVkVMUyA9IFtcImRlYnVnXCIsIFwiaW5mb1wiLCBcIndhcm5cIiwgXCJlcnJvclwiXSBhcyBjb25zdDtcbmNvbnN0IExPR19MRVZFTF9SQU5LID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuICBMT0dfTEVWRUxTLm1hcCgobGV2ZWwsIGluZGV4KSA9PiBbbGV2ZWwsIGluZGV4XSksXG4pIGFzIFJlY29yZDxMb2dMZXZlbCwgbnVtYmVyPjtcbmNvbnN0IExPR19MRVZFTF9DT0xPUlMgPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gIExPR19MRVZFTFMubWFwKChsZXZlbCkgPT4ge1xuICAgIGxldCBjb2xvciA9IFwiXFx4MWJbOTBtXCI7IC8vIGdyYXlcbiAgICBzd2l0Y2ggKGxldmVsKSB7XG4gICAgICBjYXNlIFwiaW5mb1wiOlxuICAgICAgICBjb2xvciA9IFwiXFx4MWJbMzRtXCI7IC8vIGJsdWVcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwid2FyblwiOlxuICAgICAgICBjb2xvciA9IFwiXFx4MWJbMzNtXCI7IC8vIHllbGxvd1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCJlcnJvclwiOlxuICAgICAgICBjb2xvciA9IFwiXFx4MWJbMzFtXCI7IC8vIHJlZFxuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIFtsZXZlbCwgY29sb3JdO1xuICB9KSxcbikgYXMgUmVjb3JkPExvZ0xldmVsLCBzdHJpbmc+O1xuY29uc3QgTE9HX0xFVkVMX0NPTE9SX1JFU0VUID0gXCJcXHgxYlswbVwiO1xuY29uc3QgREVGQVVMVF9MRVZFTDogTG9nTGV2ZWwgPSBcImluZm9cIjtcblxuLyoqXG4gKiBTdXBwb3J0ZWQgc2V2ZXJpdGllcywgbG93ZXN0IHRvIGhpZ2hlc3Q6IGBkZWJ1Z2AsIGBpbmZvYCwgYHdhcm5gLCBgZXJyb3JgLlxuICogQSBjYWxsIGJlbG93IHRoZSBhY3RpdmUgdGhyZXNob2xkIGlzIGRpc2NhcmRlZCBiZWZvcmUgYW55IHN0cmluZyB3b3JrIG9yXG4gKiBzaW5rIEkvTy5cbiAqXG4gKiBUaGUgdGhyZXNob2xkIGNvbWVzIGZyb20gYHByb2Nlc3MuZW52LkxPR19MRVZFTGAgb24gZXZlcnkgY2FsbFxuICogKGNhc2UtaW5zZW5zaXRpdmUsIGRlZmF1bHQgYGluZm9gIHdoZW4gdW5zZXQsIGVtcHR5LCBvciB1bmtub3duKSBzbyB0ZXN0XG4gKiBydW5uZXJzIGFuZCBlbWJlZGRlcnMgY2FuIGNoYW5nZSB2ZXJib3NpdHkgYWZ0ZXIgaW1wb3J0IHdpdGhvdXQgcmVzdGFydGluZ1xuICogdGhlIHByb2Nlc3MuXG4gKi9cbmV4cG9ydCB0eXBlIExvZ0xldmVsID0gKHR5cGVvZiBMT0dfTEVWRUxTKVtudW1iZXJdO1xuXG5leHBvcnQgdHlwZSBMb2dnZXIgPSB7XG4gIFtLIGluIExvZ0xldmVsXTogKC4uLmFyZ3M6IGFueVtdKSA9PiB2b2lkO1xufSAmIHtcbiAgLyoqIFN1Y2Nlc3MgbWVzc2FnZSBlbWl0dGVkIGF0IGBpbmZvYCBsZXZlbC4gKi9cbiAgc3VjY2VzczogKC4uLmFyZ3M6IGFueVtdKSA9PiB2b2lkO1xuICAvKiogU3RhcnQgLyBpbi1wcm9ncmVzcyBtZXNzYWdlIGVtaXR0ZWQgYXQgYGluZm9gIGxldmVsLiAqL1xuICBzdGFydDogKC4uLmFyZ3M6IGFueVtdKSA9PiB2b2lkO1xufTtcblxuLyoqIGAobmFtZT8pID0+IExvZ2dlcmAgc2luayBjb25zdHJ1Y3RvciByZXR1cm5lZCBieSB0aGUgaW5pdC10aW1lIGZhY3RvcnkgY2hhaW4uICovXG50eXBlIExvZ2dlckZhY3RvcnkgPSAobmFtZT86IHN0cmluZykgPT4gTG9nZ2VyO1xuXG4vKipcbiAqIENvbnNvbGUge0BsaW5rIExvZ2dlckZhY3Rvcnl9OyBhbHdheXMgc3VjY2VlZHMuXG4gKlxuICogV2hlbiBgcHJvY2Vzcy5zdGRlcnJgIGlzIGF2YWlsYWJsZSwgZm9ybWF0cyBlYWNoIGxpbmUgYW5kIHdyaXRlcyBvbmx5IHRvXG4gKiBzdGRlcnIuIEJ1biBgaW5zcGVjdGAgZm9ybWF0cyBlYWNoIGFyZ3VtZW50IHdoZW4gZW5hYmxlZDsgb3RoZXJ3aXNlXG4gKiBgdXRpbC5pbnNwZWN0YCB3aGVuIGBub2RlOnV0aWxgIGxvYWRzLCBvciBhIGBKU09OLnN0cmluZ2lmeWAgZmFsbGJhY2sgd2hlblxuICogaXQgZG9lcyBub3QuIFdoZW4gc3RkZXJyIGlzIHVuYXZhaWxhYmxlIChldmVyeSBicm93c2VyKSwgYmluZHNcbiAqIHtAbGluayBjcmVhdGVGb3JtYXR0ZXJ9IHByZWZpeGVzIGludG8gZ2xvYmFsIGBjb25zb2xlLipgIGNhbGxzIGFuZCBza2lwcyB0aGVcbiAqIGBub2RlOnV0aWxgIGltcG9ydCBlbnRpcmVseS5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gY3JlYXRlQ29uc29sZUxvZ2dlckZhY3RvcnkoZ2xvYmFsUHJvY2Vzc1N0ZEVycjogYW55KTogUHJvbWlzZTxMb2dnZXJGYWN0b3J5PiB7XG4gIC8vIEluZGlyZWN0IHNwZWNpZmllciBzbyB0aGlzIGJyb3dzZXItc2FmZSBtb2R1bGUgZG9lc24ndCBzdGF0aWNhbGx5IHB1bGwgaW5cbiAgLy8gbm9kZSB0eXBlczogYG5vZGU6dXRpbGAgaXMgb3B0aW9uYWwgKHRoZSBKU09OIGZhbGxiYWNrIGNvdmVycyBpdHMgYWJzZW5jZSkuXG4gIGNvbnN0IG5vZGVVdGlsID0gXCJub2RlOnV0aWxcIjtcbiAgLy8gR2F0ZWQsIG5vdCBqdXN0IGNhdWdodDogdGhlIGluZGlyZWN0IHNwZWNpZmllciBkZWZlYXRzIGJ1bmRsZXIgYW5hbHlzaXMgYnlcbiAgLy8gZGVzaWduLCBzbyBhIGNsaWVudCBidWlsZCBlbWl0cyBhIGxpdGVyYWwgYGltcG9ydChcIm5vZGU6dXRpbFwiKWAgdGhhdCBub1xuICAvLyBicm93c2VyIGNhbiByZXNvbHZlLCBhbmQgdGhlIGNhdWdodCByZWplY3Rpb24gc3RpbGwgc3VyZmFjZWQgYXMgYSBjb25zb2xlXG4gIC8vIGVycm9yLiBgdXRpbHNgIG9ubHkgZmVlZHMgdGhlIHN0ZGVyciBicmFuY2ggb2YgdGhlIGVtaXR0ZXIgYmVsb3csIHNvIG5vXG4gIC8vIHN0ZGVyciBtZWFucyB0aGUgaW1wb3J0IGhhcyBub3RoaW5nIHRvIHNlcnZlIGFuZCBpcyBza2lwcGVkIG91dHJpZ2h0LlxuICBjb25zdCB1dGlsczogeyBpbnNwZWN0PzogYW55IH0gfCB1bmRlZmluZWQgPVxuICAgIGdsb2JhbFByb2Nlc3NTdGRFcnIgPT09IHVuZGVmaW5lZFxuICAgICAgPyB1bmRlZmluZWRcbiAgICAgIDogYXdhaXQgaW1wb3J0KC8qIEB2aXRlLWlnbm9yZSAqLyBub2RlVXRpbCkuY2F0Y2goKCkgPT4gdW5kZWZpbmVkKTtcbiAgcmV0dXJuIGNvbnNvbGVMb2dnZXJGYWN0b3J5KGdsb2JhbFByb2Nlc3NTdGRFcnIsIHV0aWxzKTtcbn1cblxuLyoqXG4gKiBUaGUgc3luY2hyb25vdXMgY29yZSBvZiB7QGxpbmsgY3JlYXRlQ29uc29sZUxvZ2dlckZhY3Rvcnl9LCBzcGxpdCBvdXQgc28gdGhlXG4gKiBzYW1lIGVtaXR0ZXIgYWxzbyBzZXJ2ZXMgYXMgdGhlIGJvb3RzdHJhcCBzaW5rIGJlZm9yZSBhbnkgYXN5bmMgZmFjdG9yeSBoYXNcbiAqIHJlc29sdmVkLiBgdXRpbHNgIGlzIGBub2RlOnV0aWxgIHdoZW4gaXQgbG9hZGVkOyB3aXRob3V0IGl0LCBvYmplY3QgYXJndW1lbnRzXG4gKiBmb3JtYXQgdGhyb3VnaCB0aGUgYEpTT04uc3RyaW5naWZ5YCBmYWxsYmFjay5cbiAqL1xuZnVuY3Rpb24gY29uc29sZUxvZ2dlckZhY3RvcnkoXG4gIGdsb2JhbFByb2Nlc3NTdGRFcnI6IGFueSxcbiAgdXRpbHM/OiB7IGluc3BlY3Q/OiBhbnkgfSB8IHVuZGVmaW5lZCxcbik6IExvZ2dlckZhY3Rvcnkge1xuICBjb25zdCBidW5JbnNwZWN0ID1cbiAgICBnbG9iYWxCdW4gIT09IHVuZGVmaW5lZCAmJiAhdG9Cb29sZWFuKGdsb2JhbEJ1bi5lbnY/LkxPR19CVU5fQ09OU09MRV9ESVNBQkxFRClcbiAgICAgID8gZ2xvYmFsQnVuLmluc3BlY3RcbiAgICAgIDogdW5kZWZpbmVkO1xuICBjb25zdCByZXNldENvbG9yc1ByZWZpeCA9IGJ1bkluc3BlY3QgIT09IHVuZGVmaW5lZDtcblxuICBjb25zdCBpbnNwZWN0ID0gKGFyZzogYW55LCBjb2xvcnM/OiBib29sZWFuKSA9PiB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoYXJnKSB8fCAodHlwZW9mIGFyZyA9PT0gXCJvYmplY3RcIiAmJiBhcmcgIT09IG51bGwpKSB7XG4gICAgICBpZiAoYnVuSW5zcGVjdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBidW5JbnNwZWN0KGFyZywge1xuICAgICAgICAgIGNvbG9yczogY29sb3JzLFxuICAgICAgICAgIGRlcHRoOiB1dGlscz8uaW5zcGVjdD8uZGVmYXVsdE9wdGlvbnM/LmRlcHRoID8/IHVuZGVmaW5lZCxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKHV0aWxzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIHV0aWxzLmluc3BlY3QoYXJnLCB7XG4gICAgICAgICAgLi4udXRpbHM/Lmluc3BlY3Q/LmRlZmF1bHRPcHRpb25zLFxuICAgICAgICAgIGNvbG9yczogZmFsc2UsXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3Qgc2VlbiA9IG5ldyBXZWFrU2V0KCk7XG4gICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShhcmcsIChfLCB2YWx1ZSkgPT4ge1xuICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiYgdmFsdWUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGlmIChzZWVuLmhhcyh2YWx1ZSkpIHJldHVybiBcIltDaXJjdWxhcl1cIjtcbiAgICAgICAgICAgIHNlZW4uYWRkKHZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIFN0cmluZyhhcmcpO1xuICAgIH1cbiAgfTtcblxuICBjb25zdCBmYWN0b3J5ID0gKG5hbWU/OiBzdHJpbmcpID0+IHtcbiAgICBjb25zdCBwcmVmaXhGb3JtYXR0ZXIgPSBjcmVhdGVGb3JtYXR0ZXIobmFtZSwgZ2xvYmFsUHJvY2Vzc1N0ZEVyciwgcmVzZXRDb2xvcnNQcmVmaXgpO1xuICAgIGNvbnN0IGxvZ2dlciA9IE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgIExPR19MRVZFTFMubWFwKChsZXZlbCkgPT4ge1xuICAgICAgICBjb25zdCB7IHByZWZpeCwgY29sb3JzLCByZXNldENvbG9ycyB9ID0gcHJlZml4Rm9ybWF0dGVyKGxldmVsKTtcbiAgICAgICAgY29uc3QgZW1pdHRlciA9ICguLi5hcmdzOiBhbnlbXSkgPT4ge1xuICAgICAgICAgIGlmICghc2hvdWxkRW1pdChsZXZlbCwgdHJ1ZSkpIHJldHVybjtcbiAgICAgICAgICBpZiAoZ2xvYmFsUHJvY2Vzc1N0ZEVyciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBjb25zdCBtZXNzYWdlUGFydHMgPSBwcmVmaXggPyBbcHJlZml4XSA6IFtdO1xuICAgICAgICAgICAgbWVzc2FnZVBhcnRzLnB1c2goLi4uYXJncy5tYXAoKGFyZykgPT4gaW5zcGVjdChhcmcsIGNvbG9ycykpKTtcbiAgICAgICAgICAgIGlmIChyZXNldENvbG9ycykgbWVzc2FnZVBhcnRzLnB1c2goTE9HX0xFVkVMX0NPTE9SX1JFU0VUKTtcbiAgICAgICAgICAgIGdsb2JhbFByb2Nlc3NTdGRFcnIud3JpdGUobWVzc2FnZVBhcnRzLmpvaW4oXCIgXCIpICsgXCJcXG5cIik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxldCBsZXZlbEZuID0gY29uc29sZVtsZXZlbF07XG4gICAgICAgICAgICBpZiAodHlwZW9mIGxldmVsRm4gIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICBsZXZlbEZuID0gY29uc29sZS5sb2c7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocHJlZml4KSBsZXZlbEZuID0gbGV2ZWxGbi5iaW5kKGNvbnNvbGUsIHByZWZpeCk7XG4gICAgICAgICAgICBsZXZlbEZuKC4uLmFyZ3MpO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIFtsZXZlbCwgZW1pdHRlcl07XG4gICAgICB9KSxcbiAgICApIGFzIExvZ2dlcjtcbiAgICAvLyBDb252ZW5pZW5jZSBsZXZlbHMgc2hhcmUgdGhlIGluZm8gc2luay5cbiAgICBsb2dnZXIuc3VjY2VzcyA9IGxvZ2dlci5pbmZvO1xuICAgIGxvZ2dlci5zdGFydCA9IGxvZ2dlci5pbmZvO1xuICAgIHJldHVybiBsb2dnZXI7XG4gIH07XG4gIGNvbnN0IGRlZmF1bHRGYWN0b3J5ID0gbWVtb2l6ZShmYWN0b3J5KTtcbiAgcmV0dXJuIChuYW1lPzogc3RyaW5nKSA9PiAobmFtZSA/IGZhY3RvcnkobmFtZSkgOiBkZWZhdWx0RmFjdG9yeSgpKTtcbn1cblxuLyoqXG4gKiBGdWxsIGNvbnNvbGUgc2luayB3aXRoIG9wdGlvbmFsIGBub2RlOnV0aWxgIGluc3BlY3Rpb24uIE1lbW9pemVkIHNvXG4gKiBjb25jdXJyZW50IGFuZCByZXBlYXQgY2FsbGVycyBzaGFyZSBvbmUgaW4tZmxpZ2h0IHByb21pc2UgYW5kIHNldHRsZWQgcmVzdWx0LlxuICovXG5jb25zdCByZXNvbHZlRmFjdG9yeSA9IG1lbW9pemUoYXN5bmMgKCk6IFByb21pc2U8TG9nZ2VyRmFjdG9yeT4gPT4ge1xuICByZXR1cm4gY3JlYXRlQ29uc29sZUxvZ2dlckZhY3RvcnkoZ2xvYmFsUHJvY2Vzc1N0ZEVycik7XG59KTtcblxuLyoqXG4gKiBBY3RpdmUgZmFjdG9yeSBzdGFydHMgYXMgYSBzeW5jIGNvbnNvbGUgc2luayAobm8gYGF3YWl0YCwgc28gdGhpcyBtb2R1bGVcbiAqIGZpbmlzaGVzIGV2YWx1YXRpbmcgaW1tZWRpYXRlbHkpIGFuZCBzd2FwcyB0byB7QGxpbmsgcmVzb2x2ZUZhY3Rvcnl9J3NcbiAqIHJlc3VsdCB3aGVuIHNlcnZlci1zaWRlIGFyZ3VtZW50IGluc3BlY3Rpb24gaXMgcmVhZHkuXG4gKi9cbmxldCBhY3RpdmVGYWN0b3J5OiBMb2dnZXJGYWN0b3J5ID0gY29uc29sZUxvZ2dlckZhY3RvcnkoZ2xvYmFsUHJvY2Vzc1N0ZEVycik7XG52b2lkIHJlc29sdmVGYWN0b3J5KCkudGhlbihcbiAgKGZhY3RvcnkpID0+IHtcbiAgICBhY3RpdmVGYWN0b3J5ID0gZmFjdG9yeTtcbiAgfSxcbiAgKCkgPT4ge1xuICAgIC8vIEtlZXAgdGhlIHN5bmMgY29uc29sZSBzaW5rOyBuZXZlciBsZWF2ZSBpbXBvcnRlcnMgd2l0aG91dCBhIGZhY3RvcnkuXG4gIH0sXG4pO1xuXG4vKipcbiAqIEJ1aWxkIGEgbG9nZ2VyIHRoYXQgcmViaW5kcyB3aGVuIHtAbGluayBhY3RpdmVGYWN0b3J5fSB1cGdyYWRlcy4gQ2FsbGVycyB0aGF0XG4gKiBjYXB0dXJlIGBjb25zdCBsb2cgPSBsb2dnZXIoXCJ4XCIpYCBhdCBtb2R1bGUgc2NvcGUgc3RpbGwgZ2V0IHRoZSB1cGdyYWRlZFxuICogZm9ybWF0dGVyIG9uY2UgaXQgYXJyaXZlcywgd2l0aG91dCBldmVyeSBjYWxsIHNpdGUgd2FpdGluZyBvbiBhIHByb21pc2UuXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUxvZ2dlcihuYW1lPzogc3RyaW5nKTogTG9nZ2VyIHtcbiAgbGV0IGJvdW5kOiB7IGZhY3Rvcnk6IExvZ2dlckZhY3Rvcnk7IGxvZ2dlcjogTG9nZ2VyIH0gfCB1bmRlZmluZWQ7XG4gIGNvbnN0IHNpbmsgPSAoKTogTG9nZ2VyID0+IHtcbiAgICBpZiAoYm91bmQ/LmZhY3RvcnkgIT09IGFjdGl2ZUZhY3RvcnkpIHtcbiAgICAgIGJvdW5kID0geyBmYWN0b3J5OiBhY3RpdmVGYWN0b3J5LCBsb2dnZXI6IGFjdGl2ZUZhY3RvcnkobmFtZSkgfTtcbiAgICB9XG4gICAgcmV0dXJuIGJvdW5kLmxvZ2dlcjtcbiAgfTtcbiAgcmV0dXJuIE9iamVjdC5mcm9tRW50cmllcyhcbiAgICBbLi4uTE9HX0xFVkVMUywgXCJzdWNjZXNzXCIsIFwic3RhcnRcIl0ubWFwKChsZXZlbCkgPT4gW1xuICAgICAgbGV2ZWwsXG4gICAgICAoLi4uYXJnczogYW55W10pID0+IHNpbmsoKVtsZXZlbCBhcyBrZXlvZiBMb2dnZXJdKC4uLmFyZ3MpLFxuICAgIF0pLFxuICApIGFzIExvZ2dlcjtcbn1cblxuLyoqXG4gKiBCdWlsZCBhIGxpbmUgcHJlZml4IG9mIGBMRVZFTCBbbmFtZV1gIG9uIE5vZGUvQnVuIGhvc3RzLCBvciBgW25hbWVdYCBhbG9uZVxuICogaW4gYnJvd3NlcnMgKGVpdGhlciBwYXJ0IG9taXR0ZWQgd2hlbiBhYnNlbnQpLiBBcHBsaWVzIHBlci1sZXZlbCBBTlNJIGNvbG9yXG4gKiB3aGVuIGBzdHJlYW1TdXBwb3J0c0NvbG9yYCBpcyB0cnVlIGZvciB0aGUgZ2l2ZW4gc3RkZXJyIHN0cmVhbS5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlRm9ybWF0dGVyKFxuICBuYW1lOiBhbnksXG4gIHN0cmVhbTogYW55LFxuICByZXNldENvbG9yc1ByZWZpeD86IGJvb2xlYW4sXG4pOiAobGV2ZWw/OiBMb2dMZXZlbCkgPT4geyBwcmVmaXg6IHN0cmluZzsgY29sb3JzOiBib29sZWFuOyByZXNldENvbG9yczogYm9vbGVhbiB9IHtcbiAgY29uc3QgZ2xvYiA9IGdsb2JhbFRoaXMgYXMgeyB3aW5kb3c/OiB1bmtub3duOyBkb2N1bWVudD86IHVua25vd24gfTtcbiAgY29uc3QgaXNCcm93c2VyID0gZ2xvYi53aW5kb3cgIT09IHVuZGVmaW5lZCAmJiBnbG9iLmRvY3VtZW50ICE9PSB1bmRlZmluZWQ7XG4gIGNvbnN0IHN1cHBvcnRzQ29sb3IgPSAhaXNCcm93c2VyID8gc3RyZWFtU3VwcG9ydHNDb2xvcihzdHJlYW0pIDogZmFsc2U7XG4gIGNvbnN0IG5hbWVQcmVmaXggPSBuYW1lID8gXCJbXCIgKyBuYW1lICsgXCJdXCIgOiB1bmRlZmluZWQ7XG4gIHJldHVybiAobGV2ZWw/OiBMb2dMZXZlbCkgPT4ge1xuICAgIGNvbnN0IGNvbG9yID0gc3VwcG9ydHNDb2xvciAmJiBsZXZlbCAhPT0gdW5kZWZpbmVkID8gTE9HX0xFVkVMX0NPTE9SU1tsZXZlbF0gOiB1bmRlZmluZWQ7XG4gICAgbGV0IHByZWZpeCA9IFshaXNCcm93c2VyICYmIGxldmVsID8gbGV2ZWwudG9VcHBlckNhc2UoKSA6IHVuZGVmaW5lZCwgbmFtZVByZWZpeF1cbiAgICAgIC5maWx0ZXIoQm9vbGVhbilcbiAgICAgIC5qb2luKFwiIFwiKTtcbiAgICBsZXQgcmVzZXRDb2xvcnMgPSBmYWxzZTtcbiAgICBpZiAoY29sb3IpIHtcbiAgICAgIGNvbnN0IGFwcGx5UmVzZXRDb2xvcnNQcmVmaXggPSByZXNldENvbG9yc1ByZWZpeCB8fCBcImluZm9cIiA9PT0gbGV2ZWw7XG4gICAgICBpZiAoIWFwcGx5UmVzZXRDb2xvcnNQcmVmaXgpIHJlc2V0Q29sb3JzID0gdHJ1ZTtcbiAgICAgIHByZWZpeCA9IGFwcGx5UmVzZXRDb2xvcnNQcmVmaXggPyBjb2xvciArIHByZWZpeCArIExPR19MRVZFTF9DT0xPUl9SRVNFVCA6IGNvbG9yICsgcHJlZml4O1xuICAgIH1cbiAgICByZXR1cm4geyBwcmVmaXgsIGNvbG9yczogY29sb3IgPyB0cnVlIDogZmFsc2UsIHJlc2V0Q29sb3JzIH07XG4gIH07XG59XG5cbi8qKiBUcnVlIHdoZW4gYHN0cmVhbWAgaXMgYSBUVFkgYW5kIHRoZSB0ZXJtaW5hbCBpcyBub3QgYGR1bWJgLiAqL1xuZnVuY3Rpb24gc3RyZWFtU3VwcG9ydHNDb2xvcihzdHJlYW0/OiB1bmtub3duKTogYm9vbGVhbiB7XG4gIGlmIChnbG9iYWxQcm9jZXNzID09PSB1bmRlZmluZWQgfHwgdHlwZW9mIHN0cmVhbSAhPT0gXCJvYmplY3RcIiB8fCBzdHJlYW0gPT09IG51bGwpIHJldHVybiBmYWxzZTtcbiAgY29uc3QgeyBpc1RUWSB9ID0gc3RyZWFtIGFzIHsgaXNUVFk/OiB1bmtub3duIH07XG4gIGlmIChpc1RUWSAhPT0gdHJ1ZSkgcmV0dXJuIGZhbHNlO1xuICBjb25zdCB0ZXJtID0gZ2xvYmFsUHJvY2Vzcy5lbnY/LlRFUk0/LnRvTG93ZXJDYXNlKCk7XG4gIGlmIChcImR1bWJcIiA9PSB0ZXJtKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiB0cnVlO1xufVxuXG4vKiogUGFyc2UgYSByYXcgdmFsdWUgYXMge0BsaW5rIExvZ0xldmVsfSAodHJpbW1lZCwgY2FzZS1pbnNlbnNpdGl2ZSkuICovXG5mdW5jdGlvbiBwYXJzZUxvZ0xldmVsKHJhdzogdW5rbm93bik6IExvZ0xldmVsIHwgdW5kZWZpbmVkIHtcbiAgaWYgKHJhdyA9PT0gdW5kZWZpbmVkIHx8IHJhdyA9PT0gbnVsbCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgbGV0IHRleHQgPSB0eXBlb2YgcmF3ID09PSBcInN0cmluZ1wiID8gcmF3IDogU3RyaW5nKHJhdyk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgMjsgaSsrKSB7XG4gICAgaWYgKGkgPiAwKSB7XG4gICAgICBjb25zdCBub3JtYWxpemVkID0gdGV4dC50cmltKCkudG9Mb3dlckNhc2UoKTtcbiAgICAgIGlmICh0ZXh0ID09PSBub3JtYWxpemVkKSBicmVhaztcbiAgICAgIHRleHQgPSBub3JtYWxpemVkO1xuICAgIH1cbiAgICBpZiAoIXRleHQpIHtcbiAgICAgIGJyZWFrO1xuICAgIH0gZWxzZSBpZiAodGV4dCBpbiBMT0dfTEVWRUxfUkFOSykge1xuICAgICAgcmV0dXJuIHRleHQgYXMgTG9nTGV2ZWw7XG4gICAgfVxuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKiBBY3RpdmUgdGhyZXNob2xkIGZyb20gYHByb2Nlc3MuZW52LkxPR19MRVZFTGAsIGRlZmF1bHQge0BsaW5rIERFRkFVTFRfTEVWRUx9LiAqL1xuZnVuY3Rpb24gYWN0aXZlTGV2ZWwoKTogTG9nTGV2ZWwge1xuICByZXR1cm4gcGFyc2VMb2dMZXZlbChnbG9iYWxQcm9jZXNzPy5lbnY/LkxPR19MRVZFTCkgPz8gREVGQVVMVF9MRVZFTDtcbn1cblxuLyoqXG4gKiBXaGV0aGVyIGByYXdgIG1lZXRzIHRoZSBjdXJyZW50IGBMT0dfTEVWRUxgIHRocmVzaG9sZC5cbiAqXG4gKiBQYXJzZXMgYHJhd2AgYXMgYSB7QGxpbmsgTG9nTGV2ZWx9OyB3aGVuIHBhcnNpbmcgZmFpbHMsIHJldHVybnNcbiAqIGBkZWZhdWx0UmVzdWx0YCBpZiBzdXBwbGllZCwgb3RoZXJ3aXNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIHNob3VsZEVtaXQocmF3OiB1bmtub3duLCBkZWZhdWx0UmVzdWx0PzogYm9vbGVhbik6IGJvb2xlYW4ge1xuICBjb25zdCBsZXZlbCA9IHBhcnNlTG9nTGV2ZWwocmF3KTtcbiAgaWYgKGxldmVsID09PSB1bmRlZmluZWQpIHJldHVybiBkZWZhdWx0UmVzdWx0ID8/IGZhbHNlO1xuICByZXR1cm4gTE9HX0xFVkVMX1JBTktbbGV2ZWxdID49IExPR19MRVZFTF9SQU5LW2FjdGl2ZUxldmVsKCldO1xufVxuXG4vKipcbiAqIFdoZXRoZXIgYSBjYWxsIGF0IGBsZXZlbGAgd291bGQgYmUgZW1pdHRlZCBhdCB0aGUgY3VycmVudFxuICogYHByb2Nlc3MuZW52LkxPR19MRVZFTGAgdGhyZXNob2xkLiBVc2UgYmVmb3JlIGJ1aWxkaW5nIGV4cGVuc2l2ZSBkZWJ1Z1xuICogcGF5bG9hZHMuXG4gKlxuICogQGV4YW1wbGVcbiAqIGlmIChpc0xldmVsRW5hYmxlZChcImRlYnVnXCIpKSB7XG4gKiAgIGxvZy5kZWJ1ZyhcIm1vdW50czpyZXNvbHZlclwiLCB7IGNvbnRyaWJ1dGlvbjogYXdhaXQgaGVhdnlTbmFwc2hvdCgpIH0pO1xuICogfVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNMZXZlbEVuYWJsZWQobGV2ZWw6IExvZ0xldmVsKTogYm9vbGVhbiB7XG4gIHJldHVybiBzaG91bGRFbWl0KGxldmVsKTtcbn1cblxuY29uc3QgTE9HR0VSX05BTUVfUkVHRVggPSAvXig/OlthLXpdW2EtejAtOSsuLV0qOlxcL1xcLyk/LipcXC8oW14vLl0rKSg/OlxcLlteL10rKT8kL2k7XG5cbi8qKlxuICogRGVyaXZlIHRoZSB0YWcgc3RyaW5nIGZyb20gYSBsb2dnZXIgbmFtZSwgcGx1Z2luLCBvciBwYXRoLiBTbGFzaC0gYW5kXG4gKiBVUkwtc2hhcGVkIHN0cmluZ3MgdXNlIHRoZSBsYXN0IHBhdGggc2VnbWVudCAoZXh0ZW5zaW9uIHN0cmlwcGVkKTsgcGxhaW5cbiAqIHN0cmluZ3MgcGFzcyB0aHJvdWdoIHVuY2hhbmdlZC4gRW1wdHkgb3IgbWlzc2luZyBuYW1lcyAtPiBgdW5kZWZpbmVkYFxuICogKHVudGFnZ2VkIHNpbmspLlxuICovXG5mdW5jdGlvbiBleHRyYWN0TG9nZ2VyTmFtZShsb2dnZXJOYW1lOiBOYW1lTGlrZSB8IHN0cmluZyB8IHVuZGVmaW5lZCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmICghbG9nZ2VyTmFtZSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgaWYgKHR5cGVvZiBsb2dnZXJOYW1lID09PSBcInN0cmluZ1wiKSB7XG4gICAgY29uc3QgbWF0Y2ggPSBsb2dnZXJOYW1lLm1hdGNoKExPR0dFUl9OQU1FX1JFR0VYKTtcbiAgICByZXR1cm4gbWF0Y2g/LlsxXSA/PyBsb2dnZXJOYW1lO1xuICB9XG4gIHJldHVybiBleHRyYWN0TG9nZ2VyTmFtZShsb2dnZXJOYW1lLm5hbWUpO1xufVxuXG4vKipcbiAqIEJ1aWxkIGEgdGFnZ2VkIGxvZ2dlciBmb3IgYSBwbHVnaW4gb3IgbW9kdWxlLlxuICpcbiAqIFRoZSB0YWcgaXMgYFtuYW1lXWAgd2hlbiBgbG9nZ2VyTmFtZWAgaXMgYSBub24tZW1wdHkgc3RyaW5nLCBhXG4gKiB7QGxpbmsgTmFtZUxpa2V9IHdpdGggYG5hbWVgLCBvciBhIGZpbGUgLyBVUkwgcGF0aCAodGhlIGJhc2VuYW1lIHdpdGhvdXRcbiAqIGV4dGVuc2lvbiBpcyB1c2VkKS4gVGhlIGNvbnNvbGUgc2luayBwcmVwZW5kcyBgTEVWRUwgW25hbWVdYCBvbiBOb2RlL0J1blxuICogaG9zdHMgb3IgYFtuYW1lXWAgYWxvbmUgaW4gYnJvd3NlcnMgdmlhIHtAbGluayBjcmVhdGVGb3JtYXR0ZXJ9LlxuICpcbiAqIENhbGxzIGJlbG93IGBwcm9jZXNzLmVudi5MT0dfTEVWRUxgIGFyZSBkcm9wcGVkIGJ5IHtAbGluayBzaG91bGRFbWl0fSBiZWZvcmVcbiAqIHRoZSBzaW5rIGZvcm1hdHMgb3Igd3JpdGVzIHRoZSBsaW5lLlxuICpcbiAqIEBleGFtcGxlXG4gKiBpbXBvcnQgeyBsb2cgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuICpcbiAqIGNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJnZW5pZS9jaGF0XCIpO1xuICogbG9nZ2VyLmluZm8oXCJzdGFydGluZ1wiKTtcbiAqIGxvZ2dlci53YXJuKFwibWlzc2luZyBvcHRpb25hbCBjb25maWdcIiwgeyByZWFzb246IFwibm8gZW52IHZhclwiIH0pO1xuICovXG5leHBvcnQgZnVuY3Rpb24gbG9nZ2VyKGxvZ2dlck5hbWU6IE5hbWVMaWtlIHwgc3RyaW5nIHwgdW5kZWZpbmVkKTogTG9nZ2VyIHtcbiAgY29uc3QgbmFtZSA9IGV4dHJhY3RMb2dnZXJOYW1lKGxvZ2dlck5hbWUpO1xuICByZXR1cm4gY3JlYXRlTG9nZ2VyKG5hbWUpO1xufVxuIl19
|
package/package.json
CHANGED
|
@@ -18,15 +18,11 @@
|
|
|
18
18
|
"projen": "projen"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
|
-
"@dbx-tools/test-polyglot": "0.6.
|
|
21
|
+
"@dbx-tools/test-polyglot": "0.6.131",
|
|
22
22
|
"@types/bun": "^1.3.14",
|
|
23
23
|
"@types/node": "^24.6.0",
|
|
24
|
-
"consola": "^3.4.2",
|
|
25
24
|
"typescript": "^5.9.3"
|
|
26
25
|
},
|
|
27
|
-
"peerDependencies": {
|
|
28
|
-
"consola": "^3.4.2"
|
|
29
|
-
},
|
|
30
26
|
"dependencies": {
|
|
31
27
|
"zod": "4.3.6"
|
|
32
28
|
},
|
|
@@ -44,7 +40,7 @@
|
|
|
44
40
|
"./package.json": "./package.json"
|
|
45
41
|
}
|
|
46
42
|
},
|
|
47
|
-
"version": "0.6.
|
|
43
|
+
"version": "0.6.131",
|
|
48
44
|
"types": "./lib/index.d.ts",
|
|
49
45
|
"type": "module",
|
|
50
46
|
"exports": {
|
|
@@ -59,11 +55,6 @@
|
|
|
59
55
|
"src",
|
|
60
56
|
"lib"
|
|
61
57
|
],
|
|
62
|
-
"peerDependenciesMeta": {
|
|
63
|
-
"consola": {
|
|
64
|
-
"optional": true
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
58
|
"dbxToolsConfig": {
|
|
68
59
|
"tags": [
|
|
69
60
|
"shared"
|
package/src/log.ts
CHANGED
|
@@ -2,20 +2,12 @@
|
|
|
2
2
|
* Tagged, leveled logging for every runtime - the one logger the whole
|
|
3
3
|
* monorepo shares.
|
|
4
4
|
*
|
|
5
|
-
* {@link logger} resolves a tagged {@link Logger}
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* the
|
|
11
|
-
*
|
|
12
|
-
* Sink selection chains two factories with nullish coalescing (first match
|
|
13
|
-
* wins):
|
|
14
|
-
*
|
|
15
|
-
* 1. {@link createConsolaLoggerFactory} when consola resolves and
|
|
16
|
-
* `LOG_CONSOLA_DISABLED` is not truthy.
|
|
17
|
-
* 2. {@link createConsoleLoggerFactory} everywhere else (also the sync
|
|
18
|
-
* bootstrap before that promise settles).
|
|
5
|
+
* {@link logger} resolves a tagged {@link Logger} through a synchronous console
|
|
6
|
+
* sink, then upgrades its server-side formatter when `node:util` resolves.
|
|
7
|
+
* Keeping the sink dependency-free prevents browser bundlers from retaining an
|
|
8
|
+
* optional bare import that downstream apps would still have to install.
|
|
9
|
+
* {@link LogLevel} filtering runs through {@link shouldEmit} in per-level
|
|
10
|
+
* wrappers around the platform console or stderr sink.
|
|
19
11
|
*
|
|
20
12
|
* The console fallback writes formatted lines to `process.stderr` when it is
|
|
21
13
|
* available (Bun `inspect` per argument when `LOG_BUN_CONSOLE_DISABLED` is
|
|
@@ -24,14 +16,13 @@
|
|
|
24
16
|
* the `LEVEL` text prefix (devtools show severity) and keep only the `[name]`
|
|
25
17
|
* tag.
|
|
26
18
|
*
|
|
27
|
-
* Env toggles: `LOG_LEVEL` (read per call)
|
|
28
|
-
*
|
|
19
|
+
* Env toggles: `LOG_LEVEL` (read per call) and `LOG_BUN_CONSOLE_DISABLED`
|
|
20
|
+
* (read once during factory init).
|
|
29
21
|
*
|
|
30
22
|
* Browser-safe: `process` / `Bun` / `window` / `document` are all reached
|
|
31
|
-
* through `globalThis` and guarded,
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* Consola is an optional peer; the module loads fine without it.
|
|
23
|
+
* through `globalThis` and guarded, and `node:util` is imported ONLY on a host
|
|
24
|
+
* that has `process.stderr` - never in a browser, where the specifier is
|
|
25
|
+
* unresolvable - so the module works in any runtime.
|
|
35
26
|
*
|
|
36
27
|
* @module
|
|
37
28
|
*/
|
|
@@ -56,9 +47,8 @@ const globalBun = (globalThis as { Bun?: BunLike }).Bun;
|
|
|
56
47
|
|
|
57
48
|
/**
|
|
58
49
|
* Node `process.stderr` when writable, else `undefined` (stable for the
|
|
59
|
-
* process). Typed loosely (`any`) because it is handed to
|
|
60
|
-
*
|
|
61
|
-
* `.write`, neither of which our structural {@link ProcessLike} shape satisfies
|
|
50
|
+
* process). Typed loosely (`any`) because it is handed to the console sink's
|
|
51
|
+
* `.write`, which our structural {@link ProcessLike} shape does not satisfy
|
|
62
52
|
* nominally.
|
|
63
53
|
*/
|
|
64
54
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -106,77 +96,15 @@ export type LogLevel = (typeof LOG_LEVELS)[number];
|
|
|
106
96
|
export type Logger = {
|
|
107
97
|
[K in LogLevel]: (...args: any[]) => void;
|
|
108
98
|
} & {
|
|
109
|
-
/** Success message
|
|
99
|
+
/** Success message emitted at `info` level. */
|
|
110
100
|
success: (...args: any[]) => void;
|
|
111
|
-
/** Start / in-progress message
|
|
101
|
+
/** Start / in-progress message emitted at `info` level. */
|
|
112
102
|
start: (...args: any[]) => void;
|
|
113
103
|
};
|
|
114
104
|
|
|
115
105
|
/** `(name?) => Logger` sink constructor returned by the init-time factory chain. */
|
|
116
106
|
type LoggerFactory = (name?: string) => Logger;
|
|
117
107
|
|
|
118
|
-
/**
|
|
119
|
-
* Consola-backed {@link LoggerFactory}, or `undefined` when consola is
|
|
120
|
-
* disabled, fails to import, or throws during setup.
|
|
121
|
-
*
|
|
122
|
-
* Builds one `createConsola` instance (badge off, level `verbose`) whose
|
|
123
|
-
* reporter calls {@link shouldEmit} on `logObj.type` before delegating to
|
|
124
|
-
* consola's default reporters. In Node, when `globalProcessStdErr` is set,
|
|
125
|
-
* recognized {@link LogLevel} types are redirected to stderr for that write.
|
|
126
|
-
* Tags use `withTag` (rendered `[name]`, not merged into args).
|
|
127
|
-
*
|
|
128
|
-
* Memoized: the dynamic `consola` import, env checks, and `createConsola`
|
|
129
|
-
* setup (plus the import/throw fallback) run once; later calls share the one
|
|
130
|
-
* resolved factory (or the one resolved `undefined`). A rejection is evicted
|
|
131
|
-
* by {@link memoize} so a later call retries.
|
|
132
|
-
*/
|
|
133
|
-
const createConsolaLoggerFactory = memoize(async (): Promise<LoggerFactory | undefined> => {
|
|
134
|
-
const consolaDisabled = toBoolean(globalProcess?.env?.LOG_CONSOLA_DISABLED);
|
|
135
|
-
if (!consolaDisabled) {
|
|
136
|
-
try {
|
|
137
|
-
const { consola, createConsola, LogLevels } = await import(/* @vite-ignore */ "consola");
|
|
138
|
-
const defaultOptions = consola.options;
|
|
139
|
-
const createConsolaOptions = {
|
|
140
|
-
...consola.options,
|
|
141
|
-
defaults: { badge: false },
|
|
142
|
-
// `LOG_LEVEL` is enforced in {@link shouldEmit}; keep consola permissive
|
|
143
|
-
// so a threshold change after import is not blocked by its own filter.
|
|
144
|
-
level: LogLevels.verbose,
|
|
145
|
-
reporters: [
|
|
146
|
-
{
|
|
147
|
-
log: (logObj, ctx) => {
|
|
148
|
-
const logLevel = parseLogLevel(logObj.type);
|
|
149
|
-
if (!shouldEmit(logLevel, true)) return;
|
|
150
|
-
const ctxStdout = ctx.options.stdout;
|
|
151
|
-
try {
|
|
152
|
-
if (globalProcessStdErr !== undefined && logLevel !== undefined) {
|
|
153
|
-
ctx.options.stdout = globalProcessStdErr;
|
|
154
|
-
}
|
|
155
|
-
defaultOptions.reporters.forEach((reporter) => reporter.log(logObj, ctx));
|
|
156
|
-
} finally {
|
|
157
|
-
ctx.options.stdout = ctxStdout;
|
|
158
|
-
}
|
|
159
|
-
},
|
|
160
|
-
},
|
|
161
|
-
],
|
|
162
|
-
} as NonNullable<Parameters<typeof createConsola>[0]>;
|
|
163
|
-
const consolaLogger = createConsola(createConsolaOptions);
|
|
164
|
-
return (name?: string) => {
|
|
165
|
-
return name ? consolaLogger.withTag(name) : consolaLogger;
|
|
166
|
-
};
|
|
167
|
-
} catch (error) {
|
|
168
|
-
// consola is an OPTIONAL peer - not having it installed is the EXPECTED
|
|
169
|
-
// path (the module degrades to the console fallback), so this is not an
|
|
170
|
-
// error. Note it only at debug level, and without a stack trace (the
|
|
171
|
-
// message, not `console.trace`, so a missing optional dep stays quiet).
|
|
172
|
-
if (isLevelEnabled("debug")) {
|
|
173
|
-
console.debug("consola not available; using console fallback:", String(error));
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
return undefined;
|
|
178
|
-
});
|
|
179
|
-
|
|
180
108
|
/**
|
|
181
109
|
* Console {@link LoggerFactory}; always succeeds.
|
|
182
110
|
*
|
|
@@ -270,7 +198,7 @@ function consoleLoggerFactory(
|
|
|
270
198
|
return [level, emitter];
|
|
271
199
|
}),
|
|
272
200
|
) as Logger;
|
|
273
|
-
//
|
|
201
|
+
// Convenience levels share the info sink.
|
|
274
202
|
logger.success = logger.info;
|
|
275
203
|
logger.start = logger.info;
|
|
276
204
|
return logger;
|
|
@@ -280,21 +208,17 @@ function consoleLoggerFactory(
|
|
|
280
208
|
}
|
|
281
209
|
|
|
282
210
|
/**
|
|
283
|
-
*
|
|
284
|
-
*
|
|
285
|
-
* one in-flight promise and one settled result.
|
|
211
|
+
* Full console sink with optional `node:util` inspection. Memoized so
|
|
212
|
+
* concurrent and repeat callers share one in-flight promise and settled result.
|
|
286
213
|
*/
|
|
287
214
|
const resolveFactory = memoize(async (): Promise<LoggerFactory> => {
|
|
288
|
-
return (
|
|
289
|
-
(await createConsolaLoggerFactory()) ?? (await createConsoleLoggerFactory(globalProcessStdErr))
|
|
290
|
-
);
|
|
215
|
+
return createConsoleLoggerFactory(globalProcessStdErr);
|
|
291
216
|
});
|
|
292
217
|
|
|
293
218
|
/**
|
|
294
219
|
* Active factory starts as a sync console sink (no `await`, so this module
|
|
295
220
|
* finishes evaluating immediately) and swaps to {@link resolveFactory}'s
|
|
296
|
-
* result when
|
|
297
|
-
* ready before the first interesting log line.
|
|
221
|
+
* result when server-side argument inspection is ready.
|
|
298
222
|
*/
|
|
299
223
|
let activeFactory: LoggerFactory = consoleLoggerFactory(globalProcessStdErr);
|
|
300
224
|
void resolveFactory().then(
|
|
@@ -308,8 +232,8 @@ void resolveFactory().then(
|
|
|
308
232
|
|
|
309
233
|
/**
|
|
310
234
|
* Build a logger that rebinds when {@link activeFactory} upgrades. Callers that
|
|
311
|
-
* capture `const log = logger("x")` at module scope still get
|
|
312
|
-
* arrives, without every call site waiting on a promise.
|
|
235
|
+
* capture `const log = logger("x")` at module scope still get the upgraded
|
|
236
|
+
* formatter once it arrives, without every call site waiting on a promise.
|
|
313
237
|
*/
|
|
314
238
|
function createLogger(name?: string): Logger {
|
|
315
239
|
let bound: { factory: LoggerFactory; logger: Logger } | undefined;
|
|
@@ -396,9 +320,7 @@ function activeLevel(): LogLevel {
|
|
|
396
320
|
* Whether `raw` meets the current `LOG_LEVEL` threshold.
|
|
397
321
|
*
|
|
398
322
|
* Parses `raw` as a {@link LogLevel}; when parsing fails, returns
|
|
399
|
-
* `defaultResult` if supplied, otherwise `false`.
|
|
400
|
-
* lines where unknown `logObj.type` values should pass through when
|
|
401
|
-
* `defaultResult` is `true`.
|
|
323
|
+
* `defaultResult` if supplied, otherwise `false`.
|
|
402
324
|
*/
|
|
403
325
|
function shouldEmit(raw: unknown, defaultResult?: boolean): boolean {
|
|
404
326
|
const level = parseLogLevel(raw);
|
|
@@ -442,9 +364,8 @@ function extractLoggerName(loggerName: NameLike | string | undefined): string |
|
|
|
442
364
|
*
|
|
443
365
|
* The tag is `[name]` when `loggerName` is a non-empty string, a
|
|
444
366
|
* {@link NameLike} with `name`, or a file / URL path (the basename without
|
|
445
|
-
* extension is used).
|
|
446
|
-
*
|
|
447
|
-
* alone in browsers via {@link createFormatter}.
|
|
367
|
+
* extension is used). The console sink prepends `LEVEL [name]` on Node/Bun
|
|
368
|
+
* hosts or `[name]` alone in browsers via {@link createFormatter}.
|
|
448
369
|
*
|
|
449
370
|
* Calls below `process.env.LOG_LEVEL` are dropped by {@link shouldEmit} before
|
|
450
371
|
* the sink formats or writes the line.
|