@cichol/logger 4.4.2 → 4.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dists/classes/logger.d.ts +32 -0
  2. package/dists/formatters/command-line.d.ts +2 -0
  3. package/dists/formatters/morgan.d.ts +7 -0
  4. package/dists/handlers/debug.d.ts +5 -0
  5. package/dists/handlers/error.d.ts +13 -0
  6. package/dists/handlers/fatal.d.ts +4 -0
  7. package/dists/handlers/http.d.ts +5 -0
  8. package/dists/handlers/index.d.ts +12 -0
  9. package/dists/handlers/info.d.ts +5 -0
  10. package/dists/handlers/notice.d.ts +5 -0
  11. package/dists/handlers/query.d.ts +13 -0
  12. package/dists/handlers/verbose.d.ts +5 -0
  13. package/dists/handlers/warning.d.ts +5 -0
  14. package/dists/helpers/color-scheme.d.ts +12 -0
  15. package/dists/helpers/constants.d.ts +18 -0
  16. package/dists/helpers/label-decorator.d.ts +2 -0
  17. package/dists/helpers/logging-level.d.ts +13 -0
  18. package/dists/index.cjs +543 -0
  19. package/dists/index.d.ts +1 -0
  20. package/dists/index.js +523 -0
  21. package/package.json +18 -11
  22. package/releases/cjs.js +0 -543
  23. package/releases/esm.js +0 -523
  24. /package/{types/classes/logger.d.ts → dists/classes/logger.d.cts} +0 -0
  25. /package/{types/formatters/command-line.d.ts → dists/formatters/command-line.d.cts} +0 -0
  26. /package/{types/formatters/morgan.d.ts → dists/formatters/morgan.d.cts} +0 -0
  27. /package/{types/handlers/debug.d.ts → dists/handlers/debug.d.cts} +0 -0
  28. /package/{types/handlers/error.d.ts → dists/handlers/error.d.cts} +0 -0
  29. /package/{types/handlers/fatal.d.ts → dists/handlers/fatal.d.cts} +0 -0
  30. /package/{types/handlers/http.d.ts → dists/handlers/http.d.cts} +0 -0
  31. /package/{types/handlers/index.d.ts → dists/handlers/index.d.cts} +0 -0
  32. /package/{types/handlers/info.d.ts → dists/handlers/info.d.cts} +0 -0
  33. /package/{types/handlers/notice.d.ts → dists/handlers/notice.d.cts} +0 -0
  34. /package/{types/handlers/query.d.ts → dists/handlers/query.d.cts} +0 -0
  35. /package/{types/handlers/verbose.d.ts → dists/handlers/verbose.d.cts} +0 -0
  36. /package/{types/handlers/warning.d.ts → dists/handlers/warning.d.cts} +0 -0
  37. /package/{types/helpers/color-scheme.d.ts → dists/helpers/color-scheme.d.cts} +0 -0
  38. /package/{types/helpers/constants.d.ts → dists/helpers/constants.d.cts} +0 -0
  39. /package/{types/helpers/label-decorator.d.ts → dists/helpers/label-decorator.d.cts} +0 -0
  40. /package/{types/helpers/logging-level.d.ts → dists/helpers/logging-level.d.cts} +0 -0
  41. /package/{types/index.d.ts → dists/index.d.cts} +0 -0
package/releases/esm.js DELETED
@@ -1,523 +0,0 @@
1
- import _Symbol from 'core-js-pure/stable/symbol/index.js';
2
- import _filterInstanceProperty from 'core-js-pure/stable/instance/filter.js';
3
- import _mapInstanceProperty from 'core-js-pure/stable/instance/map.js';
4
- import _trimInstanceProperty from 'core-js-pure/stable/instance/trim.js';
5
- import 'reflect-metadata';
6
- import { STATUS_CODES, IncomingMessage, ServerResponse } from 'http';
7
- import { PassThrough } from 'stream';
8
- import Promise$1 from 'bluebird';
9
- import lodash from 'lodash';
10
- import morgan from 'morgan';
11
- import * as winston from 'winston';
12
- import { format } from 'winston';
13
- import _findInstanceProperty from 'core-js-pure/stable/instance/find.js';
14
- import _Reflect$apply from 'core-js-pure/stable/reflect/apply.js';
15
- import chalk from 'chalk';
16
- import rTracer from 'cls-rtracer';
17
- import { DateTime } from 'luxon';
18
- import _Map from 'core-js-pure/stable/map/index.js';
19
- import process, { version, env } from 'process';
20
- import _Symbol$for from 'core-js-pure/stable/symbol/for.js';
21
- import _startsWithInstanceProperty from 'core-js-pure/stable/instance/starts-with.js';
22
- import _sliceInstanceProperty from 'core-js-pure/stable/instance/slice.js';
23
- import path from 'path';
24
- import highlight from 'cli-highlight';
25
- import prettyBytes from 'pretty-bytes';
26
- import prettyMs from 'pretty-ms';
27
- import cluster from 'cluster';
28
- import 'worker_threads';
29
-
30
- const LoggingLevel = {
31
- // Critical levels. (It will crash the process)
32
- Fatal: 0,
33
- Error: 1,
34
- // Warning levels. (It just report warning information, not crash the process)
35
- Warning: 2,
36
- // Regular level and aliases.
37
- Notice: 3,
38
- Info: 3,
39
- // Maybe sensitive levels. (In general, does not useful)
40
- Http: 4,
41
- Query: 4,
42
- // Loud levels.
43
- Verbose: 5,
44
- Debug: 5
45
- };
46
-
47
- // Constants.
48
- const colorizerMap = new _Map();
49
-
50
- // Helpers.
51
- function createScheme(options) {
52
- const nextIndex = colorizerMap.size;
53
- const colorizer = chalk.bgHex(options.background).hex(options.foreground);
54
- colorizerMap.set(nextIndex, colorizer);
55
- return nextIndex;
56
- }
57
-
58
- // Color definitions.
59
- const ColorValue = {
60
- // Basic colors.
61
- White: '#FFFFFF',
62
- Gray: '#808080',
63
- Black: '#000000',
64
- // Specialized colors.
65
- Critical: '#D63031',
66
- Warning: '#FDCB6E',
67
- Regular: '#0984E3',
68
- Http: '#6AB04C',
69
- Query: '#399AF3'
70
- };
71
- const ColorScheme = {
72
- Critical: createScheme({
73
- background: ColorValue.Critical,
74
- foreground: ColorValue.Black
75
- }),
76
- Warning: createScheme({
77
- background: ColorValue.Warning,
78
- foreground: ColorValue.Black
79
- }),
80
- Regular: createScheme({
81
- background: ColorValue.Regular,
82
- foreground: ColorValue.White
83
- }),
84
- Http: createScheme({
85
- background: ColorValue.Http,
86
- foreground: ColorValue.Black
87
- }),
88
- Query: createScheme({
89
- background: ColorValue.Query,
90
- foreground: ColorValue.Black
91
- }),
92
- Loud: createScheme({
93
- background: ColorValue.Black,
94
- foreground: ColorValue.Gray
95
- })
96
- };
97
- function getChalkOf(colorSet) {
98
- return colorizerMap.get(colorSet) ?? chalk;
99
- }
100
-
101
- /* eslint-enable no-use-before-define */
102
-
103
- // Node.js built-in APIs.
104
-
105
- // Constants.
106
- const {
107
- isTTY
108
- } = process.stdout;
109
- const isNotOnCLI = !isTTY;
110
- function decorateLabel(label, scheme) {
111
- if (isNotOnCLI) {
112
- return label;
113
- }
114
- const chalk = getChalkOf(scheme);
115
- const decoratedLabel = chalk.bold(` ${label} `);
116
- return decoratedLabel;
117
- }
118
-
119
- // Type definitions.
120
-
121
- // Constants.
122
- const rootPath = process.cwd();
123
- const conjunction = ` ${chalk.blue('──')} `;
124
- const splat = _Symbol$for('splat');
125
-
126
- // Handler metadata.
127
- const name$8 = 'error';
128
- const level$8 = LoggingLevel.Error;
129
- const label$8 = decorateLabel('ERROR', ColorScheme.Critical);
130
- function mapLocationOfErrorThrown(filename) {
131
- let target = path.relative(rootPath, filename);
132
- if (_startsWithInstanceProperty(target).call(target, 'node_modules')) {
133
- target = chalk.gray(target).replace(/node_modules[\\/]([^\\/]+)(.*)/, (matches, moduleName, trailing) => `node_modules${path.sep}${chalk.bold.underline(moduleName)}${chalk.gray(trailing)}` // eslint-disable-line max-len
134
- );
135
- } else {
136
- target = `${chalk.gray(path.dirname(target) + path.sep)}${chalk.bold.underline(path.basename(target))}`;
137
- }
138
- return target;
139
- }
140
- function handle$1(data) {
141
- var _context, _context2, _context3;
142
- const {
143
- [splat]: [error] = []
144
- } = data;
145
- if (!(error instanceof Error)) {
146
- return undefined;
147
- }
148
- const {
149
- name,
150
- message,
151
- stack: rawStack = ''
152
- } = error;
153
- const stack = _mapInstanceProperty(_context = _mapInstanceProperty(_context2 = _mapInstanceProperty(_context3 = _sliceInstanceProperty(rawStack).call(rawStack, name.length + message.length + 3).split('\n')).call(_context3, line => line.replace(/^\s+at /g, ''))).call(_context2, line => path.isAbsolute(line) ? `<anonymous>${conjunction}${mapLocationOfErrorThrown(line)}` : line)).call(_context, line => line.replace(/^(.+) \((.+)\)$/, (matches, contextName, rawLocation) => {
154
- let location;
155
- if (rawLocation === '<anonymous>') {
156
- location = chalk.gray(rawLocation);
157
- } else {
158
- const [filename, line, column] = rawLocation.split(':');
159
- if (path.isAbsolute(filename)) {
160
- const target = mapLocationOfErrorThrown(path.relative(rootPath, filename));
161
- const trailing = chalk.gray(`:${line}:${column}`);
162
- location = target + trailing;
163
- } else {
164
- location = chalk.gray(`https://github.com/${chalk.bold.underline('nodejs')}/node/blob/${version}/lib/${filename}#L${line}`); // eslint-disable-line max-len
165
- }
166
- }
167
- return `${contextName}${conjunction}${location}`;
168
- })).join('\n');
169
- const label = decorateLabel(name, ColorScheme.Critical);
170
- const payload = `${message}\n\n${stack}\n`;
171
- return {
172
- label,
173
- payload
174
- };
175
- }
176
-
177
- var ErrorHandler = /*#__PURE__*/Object.freeze({
178
- __proto__: null,
179
- default: handle$1,
180
- label: label$8,
181
- level: level$8,
182
- name: name$8
183
- });
184
-
185
- // Local helpers.
186
-
187
- // Handler metadata.
188
- const name$7 = 'fatal';
189
- const level$7 = LoggingLevel.Fatal;
190
- const label$7 = decorateLabel('FATAL', ColorScheme.Critical);
191
-
192
- var FatalHandler = /*#__PURE__*/Object.freeze({
193
- __proto__: null,
194
- default: handle$1,
195
- label: label$7,
196
- level: level$7,
197
- name: name$7
198
- });
199
-
200
- // Local helpers.
201
-
202
- // Handler metadata.
203
- const name$6 = 'warning';
204
- const level$6 = LoggingLevel.Warning;
205
- const label$6 = decorateLabel('WARNING', ColorScheme.Warning);
206
- var warning = null;
207
-
208
- var WarningHandler = /*#__PURE__*/Object.freeze({
209
- __proto__: null,
210
- default: warning,
211
- label: label$6,
212
- level: level$6,
213
- name: name$6
214
- });
215
-
216
- // Local helpers.
217
-
218
- // Handler metadata.
219
- const name$5 = 'notice';
220
- const level$5 = LoggingLevel.Notice;
221
- const label$5 = decorateLabel('NOTICE', ColorScheme.Regular);
222
- var notice = null;
223
-
224
- var NoticeHandler = /*#__PURE__*/Object.freeze({
225
- __proto__: null,
226
- default: notice,
227
- label: label$5,
228
- level: level$5,
229
- name: name$5
230
- });
231
-
232
- // Local helpers.
233
-
234
- // Handler metadata.
235
- const name$4 = 'info';
236
- const level$4 = LoggingLevel.Info;
237
- const label$4 = decorateLabel('INFO', ColorScheme.Regular);
238
- var info = null;
239
-
240
- var InfoHandler = /*#__PURE__*/Object.freeze({
241
- __proto__: null,
242
- default: info,
243
- label: label$4,
244
- level: level$4,
245
- name: name$4
246
- });
247
-
248
- // Local helpers.
249
-
250
- // Handler metadata.
251
- const name$3 = 'http';
252
- const level$3 = LoggingLevel.Http;
253
- const label$3 = decorateLabel('HTTP', ColorScheme.Http);
254
- var http = null;
255
-
256
- var HttpHandler = /*#__PURE__*/Object.freeze({
257
- __proto__: null,
258
- default: http,
259
- label: label$3,
260
- level: level$3,
261
- name: name$3
262
- });
263
-
264
- // Highlight.js
265
-
266
- // Type definitions.
267
-
268
- // Handler metadata.
269
- const name$2 = 'query';
270
- const level$2 = LoggingLevel.Query;
271
- const label$2 = decorateLabel('QUERY', ColorScheme.Query);
272
- function handle(data) {
273
- const payload = highlight(data.message, {
274
- language: 'sql'
275
- });
276
- return {
277
- label: label$2,
278
- payload
279
- };
280
- }
281
-
282
- var QueryHandler = /*#__PURE__*/Object.freeze({
283
- __proto__: null,
284
- default: handle,
285
- label: label$2,
286
- level: level$2,
287
- name: name$2
288
- });
289
-
290
- // Local helpers.
291
-
292
- // Handler metadata.
293
- const name$1 = 'verbose';
294
- const level$1 = LoggingLevel.Verbose;
295
- const label$1 = decorateLabel('VERBOSE', ColorScheme.Loud);
296
- var verbose = null;
297
-
298
- var VerboseHandler = /*#__PURE__*/Object.freeze({
299
- __proto__: null,
300
- default: verbose,
301
- label: label$1,
302
- level: level$1,
303
- name: name$1
304
- });
305
-
306
- // Local helpers.
307
-
308
- // Handler metadata.
309
- const name = 'debug';
310
- const level = LoggingLevel.Debug;
311
- const label = decorateLabel('DEBUG', ColorScheme.Loud);
312
- var debug = null;
313
-
314
- var DebugHandler = /*#__PURE__*/Object.freeze({
315
- __proto__: null,
316
- default: debug,
317
- label: label,
318
- level: level,
319
- name: name
320
- });
321
-
322
- // Handler implementations.
323
- const handlers = [FatalHandler, ErrorHandler, WarningHandler, NoticeHandler, InfoHandler, HttpHandler, QueryHandler, VerboseHandler, DebugHandler];
324
-
325
- var formatForCLI = format.printf(data => {
326
- const timestamp = chalk.gray(DateTime.now().toISO({
327
- includeOffset: true
328
- }));
329
- const handler = _findInstanceProperty(handlers).call(handlers, ({
330
- name
331
- }) => name === data.level);
332
- const fallback = {
333
- label: handler?.label,
334
- payload: data.message
335
- };
336
- const performHandle = handler?.default ?? (() => fallback);
337
-
338
- // Execute handler and then, get decorated payload.
339
- const {
340
- label,
341
- payload
342
- } = _Reflect$apply(performHandle, undefined, [data]) ?? fallback;
343
- let extraFingerprint;
344
- if (handler?.level === LoggingLevel.Http) {
345
- extraFingerprint = data.transactionId ? `(Transaction-ID = ${data.transactionId})` : `(Request-ID = ${rTracer.id()})`;
346
- }
347
- return `${label} ${timestamp}${extraFingerprint ? ` ${extraFingerprint}` : ''}\n${payload}`;
348
- });
349
-
350
- // Node.js built-in APIs.
351
-
352
- // Type definitions.
353
- const ExecutionMode = {
354
- DevelopmentMode: 'development',
355
- ProductionMode: 'production'
356
- };
357
- const ClusteringMode = {
358
- MasterProcess: 0,
359
- WorkerProcess: 1
360
- };
361
- // Exportings.
362
- const executionMode = env.NODE_ENV ?? ExecutionMode.DevelopmentMode;
363
- cluster.isPrimary ?? cluster.isMaster ? ClusteringMode.MasterProcess : ClusteringMode.WorkerProcess;
364
-
365
- // Node.js built-in APIs.
366
-
367
- // Type definitions.
368
-
369
- // Helpers.
370
- function decorateStatusCode(statusCode) {
371
- const groupOfCode = Math.floor(Number(statusCode) / 100) * 100;
372
- const baseMessage = `${statusCode} ${STATUS_CODES[statusCode]}`;
373
- switch (groupOfCode) {
374
- case 200:
375
- {
376
- return chalk.green(baseMessage);
377
- }
378
- case 300:
379
- {
380
- return chalk.magenta(baseMessage);
381
- }
382
- case 400:
383
- case 500:
384
- {
385
- return chalk.red(baseMessage);
386
- }
387
- default:
388
- {
389
- return chalk.gray(baseMessage);
390
- }
391
- }
392
- }
393
- function formatForMorgan(tokens, request, response) {
394
- function _(token, ...subArgs) {
395
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
396
- return tokens[token](request, response, ...subArgs);
397
- }
398
-
399
- // Raw values.
400
- const method = _('method');
401
- const URL = _('url');
402
- const httpVersion = `HTTP/${_('http-version')}`;
403
- const statusCode = Number(_('status'));
404
- const contentLength = Number(_('res', 'content-length') ?? -1);
405
- const responseTime = Number(_('response-time') ?? -1);
406
-
407
- // Decorated values.
408
- const $method = chalk.bold(method);
409
- const $version = chalk.rgb(98, 177, 255)(httpVersion);
410
- const $statusCode = decorateStatusCode(statusCode);
411
- const $contentLength = contentLength >= 0 ? prettyBytes(contentLength) : '? B';
412
- const $responseTime = responseTime >= 0 ? prettyMs(responseTime) : '';
413
-
414
- // Additional information.
415
- const metadata = `(${$contentLength}, ${$responseTime})`;
416
- return [`→ ${$method} ${URL} ${$version}`, `← ${$version} ${$statusCode} ${metadata}`].join('\n');
417
- }
418
- var formatForMorgan$1 = executionMode === ExecutionMode.DevelopmentMode ? formatForMorgan : morgan.combined;
419
-
420
- var _context, _context2;
421
-
422
- // Type definitions.
423
-
424
- // Transports.
425
- const {
426
- Console: ConsoleTransport
427
- } = winston.transports;
428
-
429
- // Keys in order to access private properties.
430
- const KeyOfInstance = _Symbol('@cichol/logger::classes/logger::Instance');
431
- const KeyOfPassport = _Symbol('@cichol/logger::classes/logger::Passport');
432
- class Logger {
433
- #logger = winston.createLogger({
434
- levels: _filterInstanceProperty(_context = _mapInstanceProperty(_context2 = lodash(handlers)).call(_context2, ({
435
- name,
436
- level
437
- }) => [name, level])).call(_context, ([, level]) => typeof level === 'number').fromPairs().value(),
438
- level: executionMode === ExecutionMode.ProductionMode ? 'http' : 'verbose',
439
- transports: [new ConsoleTransport({
440
- format: formatForCLI
441
- })],
442
- exitOnError: false
443
- });
444
- #morgan = morgan(formatForMorgan$1, {
445
- stream: new PassThrough({
446
- objectMode: true
447
- }).on('data', data => {
448
- this.log('http', _trimInstanceProperty(data).call(data));
449
- })
450
- });
451
- constructor(passport) {
452
- if (passport !== KeyOfPassport) {
453
- throw new ReferenceError('Logger class cannot be constructed in directly');
454
- }
455
- }
456
- static get instance() {
457
- if (this !== Logger) {
458
- throw new ReferenceError('Logger class is not inheritable');
459
- }
460
- if (Reflect.hasOwnMetadata(KeyOfInstance, Logger)) {
461
- return Reflect.getOwnMetadata(KeyOfInstance, Logger);
462
- }
463
- const instance = new Logger(KeyOfPassport);
464
- try {
465
- return instance;
466
- } finally {
467
- Reflect.defineMetadata(KeyOfInstance, instance, Logger);
468
- }
469
- }
470
-
471
- /**
472
- * Logging message with specific level.
473
- *
474
- * @param level
475
- * @param message
476
- * @param args Additional metadata.
477
- */
478
-
479
- /**
480
- * Logging HTTP I/O.
481
- *
482
- * @param request Node.js built-in `IncomingMessage` instance from `http` module.
483
- * @param response Node.js built-in `ServerResponse` instance from `http` module.
484
- */
485
-
486
- /**
487
- * Logging errors in detail.
488
- *
489
- * @param error
490
- */
491
-
492
- log(...args) {
493
- const logger = this.#logger;
494
- const morgan = this.#morgan;
495
- switch (true) {
496
- case args.length >= 2 && args[0] instanceof IncomingMessage && args[1] instanceof ServerResponse:
497
- {
498
- const [request, response] = args;
499
- return Promise$1.fromCallback(callback => morgan(request, response, callback));
500
- }
501
- case args.length >= 1 && args[0] instanceof Error:
502
- {
503
- const [error, ...data] = args;
504
-
505
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
506
- logger.log('error', error.message, error, ...data);
507
- return undefined;
508
- }
509
- default:
510
- {
511
- const [level, message, ...data] = args;
512
-
513
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
514
- logger.log(level, message, ...data);
515
- return undefined;
516
- }
517
- }
518
- }
519
- }
520
- var logger = Logger.instance;
521
-
522
- export { logger as default };
523
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXNtLmpzIiwic291cmNlcyI6WyIuLi9zb3VyY2VzL2hlbHBlcnMvbG9nZ2luZy1sZXZlbC50cyIsIi4uL3NvdXJjZXMvaGVscGVycy9jb2xvci1zY2hlbWUudHMiLCIuLi9zb3VyY2VzL2hlbHBlcnMvbGFiZWwtZGVjb3JhdG9yLnRzIiwiLi4vc291cmNlcy9oYW5kbGVycy9lcnJvci50cyIsIi4uL3NvdXJjZXMvaGFuZGxlcnMvZmF0YWwudHMiLCIuLi9zb3VyY2VzL2hhbmRsZXJzL3dhcm5pbmcudHMiLCIuLi9zb3VyY2VzL2hhbmRsZXJzL25vdGljZS50cyIsIi4uL3NvdXJjZXMvaGFuZGxlcnMvaW5mby50cyIsIi4uL3NvdXJjZXMvaGFuZGxlcnMvaHR0cC50cyIsIi4uL3NvdXJjZXMvaGFuZGxlcnMvcXVlcnkudHMiLCIuLi9zb3VyY2VzL2hhbmRsZXJzL3ZlcmJvc2UudHMiLCIuLi9zb3VyY2VzL2hhbmRsZXJzL2RlYnVnLnRzIiwiLi4vc291cmNlcy9oYW5kbGVycy9pbmRleC50cyIsIi4uL3NvdXJjZXMvZm9ybWF0dGVycy9jb21tYW5kLWxpbmUudHMiLCIuLi9zb3VyY2VzL2hlbHBlcnMvY29uc3RhbnRzLnRzIiwiLi4vc291cmNlcy9mb3JtYXR0ZXJzL21vcmdhbi50cyIsIi4uL3NvdXJjZXMvY2xhc3Nlcy9sb2dnZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgTG9nZ2luZ0xldmVsID0ge1xuICAgIC8vIENyaXRpY2FsIGxldmVscy4gKEl0IHdpbGwgY3Jhc2ggdGhlIHByb2Nlc3MpXG4gICAgRmF0YWw6IDAsXG4gICAgRXJyb3I6IDEsXG5cbiAgICAvLyBXYXJuaW5nIGxldmVscy4gKEl0IGp1c3QgcmVwb3J0IHdhcm5pbmcgaW5mb3JtYXRpb24sIG5vdCBjcmFzaCB0aGUgcHJvY2VzcylcbiAgICBXYXJuaW5nOiAyLFxuXG4gICAgLy8gUmVndWxhciBsZXZlbCBhbmQgYWxpYXNlcy5cbiAgICBOb3RpY2U6IDMsXG4gICAgSW5mbzogMyxcblxuICAgIC8vIE1heWJlIHNlbnNpdGl2ZSBsZXZlbHMuIChJbiBnZW5lcmFsLCBkb2VzIG5vdCB1c2VmdWwpXG4gICAgSHR0cDogNCxcbiAgICBRdWVyeTogNCxcblxuICAgIC8vIExvdWQgbGV2ZWxzLlxuICAgIFZlcmJvc2U6IDUsXG4gICAgRGVidWc6IDVcbn0gYXMgY29uc3Q7XG5cbnR5cGUgTG9nZ2luZ0xldmVsID0gdHlwZW9mIExvZ2dpbmdMZXZlbFtrZXlvZiB0eXBlb2YgTG9nZ2luZ0xldmVsXTtcblxuZXhwb3J0IGRlZmF1bHQgTG9nZ2luZ0xldmVsO1xuIiwiLyogZXNsaW50LWRpc2FibGUgbm8tdXNlLWJlZm9yZS1kZWZpbmUgKi9cblxuLy8gVGhpcmQtcGFydHkgbW9kdWxlcy5cbmltcG9ydCBjaGFsaywgeyB0eXBlIENoYWxrSW5zdGFuY2UgfSBmcm9tICdjaGFsayc7XG5cbi8vIENvbnN0YW50cy5cbmNvbnN0IGNvbG9yaXplck1hcCA9IG5ldyBNYXA8bnVtYmVyLCBDaGFsa0luc3RhbmNlPigpO1xuXG4vLyBIZWxwZXJzLlxuZnVuY3Rpb24gY3JlYXRlU2NoZW1lKG9wdGlvbnM6IHsgYmFja2dyb3VuZDogQ29sb3JWYWx1ZSwgZm9yZWdyb3VuZDogQ29sb3JWYWx1ZSB9KTogbnVtYmVyIHtcbiAgICBjb25zdCBuZXh0SW5kZXggPSBjb2xvcml6ZXJNYXAuc2l6ZTtcbiAgICBjb25zdCBjb2xvcml6ZXIgPSBjaGFsay5iZ0hleChvcHRpb25zLmJhY2tncm91bmQpLmhleChvcHRpb25zLmZvcmVncm91bmQpO1xuXG4gICAgY29sb3JpemVyTWFwLnNldChuZXh0SW5kZXgsIGNvbG9yaXplcik7XG5cbiAgICByZXR1cm4gbmV4dEluZGV4O1xufVxuXG4vLyBDb2xvciBkZWZpbml0aW9ucy5cbmNvbnN0IENvbG9yVmFsdWUgPSB7XG4gICAgLy8gQmFzaWMgY29sb3JzLlxuICAgIFdoaXRlOiAnI0ZGRkZGRicsXG4gICAgR3JheTogJyM4MDgwODAnLFxuICAgIEJsYWNrOiAnIzAwMDAwMCcsXG5cbiAgICAvLyBTcGVjaWFsaXplZCBjb2xvcnMuXG4gICAgQ3JpdGljYWw6ICcjRDYzMDMxJyxcbiAgICBXYXJuaW5nOiAnI0ZEQ0I2RScsXG4gICAgUmVndWxhcjogJyMwOTg0RTMnLFxuICAgIEh0dHA6ICcjNkFCMDRDJyxcbiAgICBRdWVyeTogJyMzOTlBRjMnXG59IGFzIGNvbnN0O1xuXG50eXBlIENvbG9yVmFsdWUgPSB0eXBlb2YgQ29sb3JWYWx1ZVtrZXlvZiB0eXBlb2YgQ29sb3JWYWx1ZV07XG5cbmNvbnN0IENvbG9yU2NoZW1lID0ge1xuICAgIENyaXRpY2FsOiBjcmVhdGVTY2hlbWUoe1xuICAgICAgICBiYWNrZ3JvdW5kOiBDb2xvclZhbHVlLkNyaXRpY2FsLFxuICAgICAgICBmb3JlZ3JvdW5kOiBDb2xvclZhbHVlLkJsYWNrXG4gICAgfSksXG5cbiAgICBXYXJuaW5nOiBjcmVhdGVTY2hlbWUoe1xuICAgICAgICBiYWNrZ3JvdW5kOiBDb2xvclZhbHVlLldhcm5pbmcsXG4gICAgICAgIGZvcmVncm91bmQ6IENvbG9yVmFsdWUuQmxhY2tcbiAgICB9KSxcblxuICAgIFJlZ3VsYXI6IGNyZWF0ZVNjaGVtZSh7XG4gICAgICAgIGJhY2tncm91bmQ6IENvbG9yVmFsdWUuUmVndWxhcixcbiAgICAgICAgZm9yZWdyb3VuZDogQ29sb3JWYWx1ZS5XaGl0ZVxuICAgIH0pLFxuXG4gICAgSHR0cDogY3JlYXRlU2NoZW1lKHtcbiAgICAgICAgYmFja2dyb3VuZDogQ29sb3JWYWx1ZS5IdHRwLFxuICAgICAgICBmb3JlZ3JvdW5kOiBDb2xvclZhbHVlLkJsYWNrXG4gICAgfSksXG5cbiAgICBRdWVyeTogY3JlYXRlU2NoZW1lKHtcbiAgICAgICAgYmFja2dyb3VuZDogQ29sb3JWYWx1ZS5RdWVyeSxcbiAgICAgICAgZm9yZWdyb3VuZDogQ29sb3JWYWx1ZS5CbGFja1xuICAgIH0pLFxuXG4gICAgTG91ZDogY3JlYXRlU2NoZW1lKHtcbiAgICAgICAgYmFja2dyb3VuZDogQ29sb3JWYWx1ZS5CbGFjayxcbiAgICAgICAgZm9yZWdyb3VuZDogQ29sb3JWYWx1ZS5HcmF5XG4gICAgfSlcbn0gYXMgY29uc3Q7XG5cbnR5cGUgQ29sb3JTY2hlbWUgPSB0eXBlb2YgQ29sb3JTY2hlbWVba2V5b2YgdHlwZW9mIENvbG9yU2NoZW1lXTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldENoYWxrT2YoY29sb3JTZXQ6IENvbG9yU2NoZW1lKTogQ2hhbGtJbnN0YW5jZSB7XG4gICAgcmV0dXJuIGNvbG9yaXplck1hcC5nZXQoY29sb3JTZXQpID8/IGNoYWxrO1xufVxuXG5leHBvcnQgZGVmYXVsdCBDb2xvclNjaGVtZTtcblxuLyogZXNsaW50LWVuYWJsZSBuby11c2UtYmVmb3JlLWRlZmluZSAqL1xuIiwiLy8gTm9kZS5qcyBidWlsdC1pbiBBUElzLlxuaW1wb3J0IHByb2Nlc3MgZnJvbSAncHJvY2Vzcyc7XG5cbi8vIExvY2FsIGhlbHBlcnMuXG5pbXBvcnQgQ29sb3JTY2hlbWUsIHsgZ2V0Q2hhbGtPZiB9IGZyb20gJy4vY29sb3Itc2NoZW1lJztcblxuLy8gQ29uc3RhbnRzLlxuY29uc3QgeyBpc1RUWSB9ID0gcHJvY2Vzcy5zdGRvdXQ7XG5jb25zdCBpc05vdE9uQ0xJID0gIWlzVFRZO1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBkZWNvcmF0ZUxhYmVsPFQgZXh0ZW5kcyBzdHJpbmc+KGxhYmVsOiBULCBzY2hlbWU6IENvbG9yU2NoZW1lKTogVCB7XG4gICAgaWYgKGlzTm90T25DTEkpIHtcbiAgICAgICAgcmV0dXJuIGxhYmVsO1xuICAgIH1cblxuICAgIGNvbnN0IGNoYWxrID0gZ2V0Q2hhbGtPZihzY2hlbWUpO1xuICAgIGNvbnN0IGRlY29yYXRlZExhYmVsID0gY2hhbGsuYm9sZChgICR7bGFiZWx9IGApO1xuXG4gICAgcmV0dXJuIGRlY29yYXRlZExhYmVsIGFzIFQ7XG59XG4iLCIvLyBOb2RlLmpzIGJ1aWx0LWluIEFQSXMuXG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCBwcm9jZXNzLCB7IHZlcnNpb24gfSBmcm9tICdwcm9jZXNzJztcblxuLy8gVGhpcmQtcGFydHkgbW9kdWxlcy5cbmltcG9ydCBjaGFsayBmcm9tICdjaGFsayc7XG5cbi8vIExvY2FsIGhlbHBlcnMuXG5pbXBvcnQgTG9nZ2luZ0xldmVsIGZyb20gJy4uL2hlbHBlcnMvbG9nZ2luZy1sZXZlbCc7XG5pbXBvcnQgQ29sb3JTY2hlbWUgZnJvbSAnLi4vaGVscGVycy9jb2xvci1zY2hlbWUnO1xuaW1wb3J0IGRlY29yYXRlTGFiZWwgZnJvbSAnLi4vaGVscGVycy9sYWJlbC1kZWNvcmF0b3InO1xuXG4vLyBUeXBlIGRlZmluaXRpb25zLlxudHlwZSBMb2dnaW5nRGF0YSA9IHsgbGV2ZWw6IHN0cmluZywgbWVzc2FnZTogc3RyaW5nIH0gJiBSZWNvcmQ8UHJvcGVydHlLZXksIGFueT47XG50eXBlIEhhbmRsZWREYXRhID0geyBsYWJlbDogc3RyaW5nLCBwYXlsb2FkOiBzdHJpbmcgfTtcblxuLy8gQ29uc3RhbnRzLlxuY29uc3Qgcm9vdFBhdGggPSBwcm9jZXNzLmN3ZCgpO1xuY29uc3QgY29uanVuY3Rpb24gPSBgICR7Y2hhbGsuYmx1ZSgn4pSA4pSAJyl9IGA7XG5jb25zdCBzcGxhdDogdW5pcXVlIHN5bWJvbCA9IFN5bWJvbC5mb3IoJ3NwbGF0Jyk7XG5cbi8vIEhhbmRsZXIgbWV0YWRhdGEuXG5leHBvcnQgY29uc3QgbmFtZSA9ICdlcnJvcic7XG5leHBvcnQgY29uc3QgbGV2ZWwgPSBMb2dnaW5nTGV2ZWwuRXJyb3I7XG5leHBvcnQgY29uc3QgbGFiZWwgPSBkZWNvcmF0ZUxhYmVsKCdFUlJPUicsIENvbG9yU2NoZW1lLkNyaXRpY2FsKTtcblxuZnVuY3Rpb24gbWFwTG9jYXRpb25PZkVycm9yVGhyb3duKGZpbGVuYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGxldCB0YXJnZXQgPSBwYXRoLnJlbGF0aXZlKHJvb3RQYXRoLCBmaWxlbmFtZSk7XG5cbiAgICBpZiAodGFyZ2V0LnN0YXJ0c1dpdGgoJ25vZGVfbW9kdWxlcycpKSB7XG4gICAgICAgIHRhcmdldCA9IGNoYWxrLmdyYXkodGFyZ2V0KS5yZXBsYWNlKFxuICAgICAgICAgICAgL25vZGVfbW9kdWxlc1tcXFxcL10oW15cXFxcL10rKSguKikvLFxuICAgICAgICAgICAgKG1hdGNoZXMsIG1vZHVsZU5hbWU6IHN0cmluZywgdHJhaWxpbmc6IHN0cmluZykgPT4gYG5vZGVfbW9kdWxlcyR7cGF0aC5zZXB9JHtjaGFsay5ib2xkLnVuZGVybGluZShtb2R1bGVOYW1lKX0ke2NoYWxrLmdyYXkodHJhaWxpbmcpfWAgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtbGVuXG4gICAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGFyZ2V0ID0gYCR7Y2hhbGsuZ3JheShwYXRoLmRpcm5hbWUodGFyZ2V0KSArIHBhdGguc2VwKX0ke2NoYWxrLmJvbGQudW5kZXJsaW5lKHBhdGguYmFzZW5hbWUodGFyZ2V0KSl9YDtcbiAgICB9XG5cbiAgICByZXR1cm4gdGFyZ2V0O1xufVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBoYW5kbGUoZGF0YTogTG9nZ2luZ0RhdGEpOiBIYW5kbGVkRGF0YSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgeyBbc3BsYXRdOiBbIGVycm9yIF0gPSBbXSB9ID0gZGF0YSBhcyBhbnk7XG5cbiAgICBpZiAoIShlcnJvciBpbnN0YW5jZW9mIEVycm9yKSkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGNvbnN0IHsgbmFtZSwgbWVzc2FnZSwgc3RhY2s6IHJhd1N0YWNrID0gJycgfSA9IGVycm9yO1xuXG4gICAgY29uc3Qgc3RhY2sgPSByYXdTdGFja1xuICAgICAgICAuc2xpY2UobmFtZS5sZW5ndGggKyBtZXNzYWdlLmxlbmd0aCArIDMpXG4gICAgICAgIC5zcGxpdCgnXFxuJylcbiAgICAgICAgLm1hcChsaW5lID0+IGxpbmUucmVwbGFjZSgvXlxccythdCAvZywgJycpKVxuICAgICAgICAubWFwKGxpbmUgPT4gKHBhdGguaXNBYnNvbHV0ZShsaW5lKSA/IGA8YW5vbnltb3VzPiR7Y29uanVuY3Rpb259JHttYXBMb2NhdGlvbk9mRXJyb3JUaHJvd24obGluZSl9YCA6IGxpbmUpKVxuICAgICAgICAubWFwKGxpbmUgPT4gbGluZS5yZXBsYWNlKC9eKC4rKSBcXCgoLispXFwpJC8sIChtYXRjaGVzLCBjb250ZXh0TmFtZTogc3RyaW5nLCByYXdMb2NhdGlvbjogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgICBsZXQgbG9jYXRpb247XG5cbiAgICAgICAgICAgIGlmIChyYXdMb2NhdGlvbiA9PT0gJzxhbm9ueW1vdXM+Jykge1xuICAgICAgICAgICAgICAgIGxvY2F0aW9uID0gY2hhbGsuZ3JheShyYXdMb2NhdGlvbik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IFsgZmlsZW5hbWUsIGxpbmUsIGNvbHVtbiBdID0gcmF3TG9jYXRpb24uc3BsaXQoJzonKTtcblxuICAgICAgICAgICAgICAgIGlmIChwYXRoLmlzQWJzb2x1dGUoZmlsZW5hbWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IG1hcExvY2F0aW9uT2ZFcnJvclRocm93bihwYXRoLnJlbGF0aXZlKHJvb3RQYXRoLCBmaWxlbmFtZSkpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB0cmFpbGluZyA9IGNoYWxrLmdyYXkoYDoke2xpbmV9OiR7Y29sdW1ufWApO1xuXG4gICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uID0gdGFyZ2V0ICsgdHJhaWxpbmc7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbG9jYXRpb24gPSBjaGFsay5ncmF5KGBodHRwczovL2dpdGh1Yi5jb20vJHtjaGFsay5ib2xkLnVuZGVybGluZSgnbm9kZWpzJyl9L25vZGUvYmxvYi8ke3ZlcnNpb259L2xpYi8ke2ZpbGVuYW1lfSNMJHtsaW5lfWApOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1sZW5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBgJHtjb250ZXh0TmFtZX0ke2Nvbmp1bmN0aW9ufSR7bG9jYXRpb259YDtcbiAgICAgICAgfSkpXG4gICAgICAgIC5qb2luKCdcXG4nKTtcblxuICAgIGNvbnN0IGxhYmVsID0gZGVjb3JhdGVMYWJlbChuYW1lLCBDb2xvclNjaGVtZS5Dcml0aWNhbCk7XG4gICAgY29uc3QgcGF5bG9hZCA9IGAke21lc3NhZ2V9XFxuXFxuJHtzdGFja31cXG5gO1xuXG4gICAgcmV0dXJuIHsgbGFiZWwsIHBheWxvYWQgfTtcbn1cbiIsIi8vIExvY2FsIGhlbHBlcnMuXG5pbXBvcnQgTG9nZ2luZ0xldmVsIGZyb20gJy4uL2hlbHBlcnMvbG9nZ2luZy1sZXZlbCc7XG5pbXBvcnQgQ29sb3JTY2hlbWUgZnJvbSAnLi4vaGVscGVycy9jb2xvci1zY2hlbWUnO1xuaW1wb3J0IGRlY29yYXRlTGFiZWwgZnJvbSAnLi4vaGVscGVycy9sYWJlbC1kZWNvcmF0b3InO1xuXG4vLyBIYW5kbGVyIG1ldGFkYXRhLlxuZXhwb3J0IGNvbnN0IG5hbWUgPSAnZmF0YWwnO1xuZXhwb3J0IGNvbnN0IGxldmVsID0gTG9nZ2luZ0xldmVsLkZhdGFsO1xuZXhwb3J0IGNvbnN0IGxhYmVsID0gZGVjb3JhdGVMYWJlbCgnRkFUQUwnLCBDb2xvclNjaGVtZS5Dcml0aWNhbCk7XG5cbmV4cG9ydCB7IGRlZmF1bHQgfSBmcm9tICcuL2Vycm9yJztcbiIsIi8vIExvY2FsIGhlbHBlcnMuXG5pbXBvcnQgTG9nZ2luZ0xldmVsIGZyb20gJy4uL2hlbHBlcnMvbG9nZ2luZy1sZXZlbCc7XG5pbXBvcnQgQ29sb3JTY2hlbWUgZnJvbSAnLi4vaGVscGVycy9jb2xvci1zY2hlbWUnO1xuaW1wb3J0IGRlY29yYXRlTGFiZWwgZnJvbSAnLi4vaGVscGVycy9sYWJlbC1kZWNvcmF0b3InO1xuXG4vLyBIYW5kbGVyIG1ldGFkYXRhLlxuZXhwb3J0IGNvbnN0IG5hbWUgPSAnd2FybmluZyc7XG5leHBvcnQgY29uc3QgbGV2ZWwgPSBMb2dnaW5nTGV2ZWwuV2FybmluZztcbmV4cG9ydCBjb25zdCBsYWJlbCA9IGRlY29yYXRlTGFiZWwoJ1dBUk5JTkcnLCBDb2xvclNjaGVtZS5XYXJuaW5nKTtcblxuZXhwb3J0IGRlZmF1bHQgbnVsbDtcbiIsIi8vIExvY2FsIGhlbHBlcnMuXG5pbXBvcnQgTG9nZ2luZ0xldmVsIGZyb20gJy4uL2hlbHBlcnMvbG9nZ2luZy1sZXZlbCc7XG5pbXBvcnQgQ29sb3JTY2hlbWUgZnJvbSAnLi4vaGVscGVycy9jb2xvci1zY2hlbWUnO1xuaW1wb3J0IGRlY29yYXRlTGFiZWwgZnJvbSAnLi4vaGVscGVycy9sYWJlbC1kZWNvcmF0b3InO1xuXG4vLyBIYW5kbGVyIG1ldGFkYXRhLlxuZXhwb3J0IGNvbnN0IG5hbWUgPSAnbm90aWNlJztcbmV4cG9ydCBjb25zdCBsZXZlbCA9IExvZ2dpbmdMZXZlbC5Ob3RpY2U7XG5leHBvcnQgY29uc3QgbGFiZWwgPSBkZWNvcmF0ZUxhYmVsKCdOT1RJQ0UnLCBDb2xvclNjaGVtZS5SZWd1bGFyKTtcblxuZXhwb3J0IGRlZmF1bHQgbnVsbDtcbiIsIi8vIExvY2FsIGhlbHBlcnMuXG5pbXBvcnQgTG9nZ2luZ0xldmVsIGZyb20gJy4uL2hlbHBlcnMvbG9nZ2luZy1sZXZlbCc7XG5pbXBvcnQgQ29sb3JTY2hlbWUgZnJvbSAnLi4vaGVscGVycy9jb2xvci1zY2hlbWUnO1xuaW1wb3J0IGRlY29yYXRlTGFiZWwgZnJvbSAnLi4vaGVscGVycy9sYWJlbC1kZWNvcmF0b3InO1xuXG4vLyBIYW5kbGVyIG1ldGFkYXRhLlxuZXhwb3J0IGNvbnN0IG5hbWUgPSAnaW5mbyc7XG5leHBvcnQgY29uc3QgbGV2ZWwgPSBMb2dnaW5nTGV2ZWwuSW5mbztcbmV4cG9ydCBjb25zdCBsYWJlbCA9IGRlY29yYXRlTGFiZWwoJ0lORk8nLCBDb2xvclNjaGVtZS5SZWd1bGFyKTtcblxuZXhwb3J0IGRlZmF1bHQgbnVsbDtcbiIsIi8vIExvY2FsIGhlbHBlcnMuXG5pbXBvcnQgTG9nZ2luZ0xldmVsIGZyb20gJy4uL2hlbHBlcnMvbG9nZ2luZy1sZXZlbCc7XG5pbXBvcnQgQ29sb3JTY2hlbWUgZnJvbSAnLi4vaGVscGVycy9jb2xvci1zY2hlbWUnO1xuaW1wb3J0IGRlY29yYXRlTGFiZWwgZnJvbSAnLi4vaGVscGVycy9sYWJlbC1kZWNvcmF0b3InO1xuXG4vLyBIYW5kbGVyIG1ldGFkYXRhLlxuZXhwb3J0IGNvbnN0IG5hbWUgPSAnaHR0cCc7XG5leHBvcnQgY29uc3QgbGV2ZWwgPSBMb2dnaW5nTGV2ZWwuSHR0cDtcbmV4cG9ydCBjb25zdCBsYWJlbCA9IGRlY29yYXRlTGFiZWwoJ0hUVFAnLCBDb2xvclNjaGVtZS5IdHRwKTtcblxuZXhwb3J0IGRlZmF1bHQgbnVsbDtcbiIsIi8vIEhpZ2hsaWdodC5qc1xuaW1wb3J0IGhpZ2hsaWdodCBmcm9tICdjbGktaGlnaGxpZ2h0JztcblxuLy8gTG9jYWwgaGVscGVycy5cbmltcG9ydCBMb2dnaW5nTGV2ZWwgZnJvbSAnLi4vaGVscGVycy9sb2dnaW5nLWxldmVsJztcbmltcG9ydCBDb2xvclNjaGVtZSBmcm9tICcuLi9oZWxwZXJzL2NvbG9yLXNjaGVtZSc7XG5pbXBvcnQgZGVjb3JhdGVMYWJlbCBmcm9tICcuLi9oZWxwZXJzL2xhYmVsLWRlY29yYXRvcic7XG5cbi8vIFR5cGUgZGVmaW5pdGlvbnMuXG50eXBlIExvZ2dpbmdEYXRhID0geyBsZXZlbDogc3RyaW5nLCBtZXNzYWdlOiBzdHJpbmcgfSAmIFJlY29yZDxQcm9wZXJ0eUtleSwgYW55PjtcbnR5cGUgSGFuZGxlZERhdGEgPSB7IGxhYmVsOiBzdHJpbmcsIHBheWxvYWQ6IHN0cmluZyB9O1xuXG4vLyBIYW5kbGVyIG1ldGFkYXRhLlxuZXhwb3J0IGNvbnN0IG5hbWUgPSAncXVlcnknO1xuZXhwb3J0IGNvbnN0IGxldmVsID0gTG9nZ2luZ0xldmVsLlF1ZXJ5O1xuZXhwb3J0IGNvbnN0IGxhYmVsID0gZGVjb3JhdGVMYWJlbCgnUVVFUlknLCBDb2xvclNjaGVtZS5RdWVyeSk7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGhhbmRsZShkYXRhOiBMb2dnaW5nRGF0YSk6IEhhbmRsZWREYXRhIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBwYXlsb2FkID0gaGlnaGxpZ2h0KGRhdGEubWVzc2FnZSwgeyBsYW5ndWFnZTogJ3NxbCcgfSk7XG5cbiAgICByZXR1cm4geyBsYWJlbCwgcGF5bG9hZCB9O1xufVxuIiwiLy8gTG9jYWwgaGVscGVycy5cbmltcG9ydCBMb2dnaW5nTGV2ZWwgZnJvbSAnLi4vaGVscGVycy9sb2dnaW5nLWxldmVsJztcbmltcG9ydCBDb2xvclNjaGVtZSBmcm9tICcuLi9oZWxwZXJzL2NvbG9yLXNjaGVtZSc7XG5pbXBvcnQgZGVjb3JhdGVMYWJlbCBmcm9tICcuLi9oZWxwZXJzL2xhYmVsLWRlY29yYXRvcic7XG5cbi8vIEhhbmRsZXIgbWV0YWRhdGEuXG5leHBvcnQgY29uc3QgbmFtZSA9ICd2ZXJib3NlJztcbmV4cG9ydCBjb25zdCBsZXZlbCA9IExvZ2dpbmdMZXZlbC5WZXJib3NlO1xuZXhwb3J0IGNvbnN0IGxhYmVsID0gZGVjb3JhdGVMYWJlbCgnVkVSQk9TRScsIENvbG9yU2NoZW1lLkxvdWQpO1xuXG5leHBvcnQgZGVmYXVsdCBudWxsO1xuIiwiLy8gTG9jYWwgaGVscGVycy5cbmltcG9ydCBMb2dnaW5nTGV2ZWwgZnJvbSAnLi4vaGVscGVycy9sb2dnaW5nLWxldmVsJztcbmltcG9ydCBDb2xvclNjaGVtZSBmcm9tICcuLi9oZWxwZXJzL2NvbG9yLXNjaGVtZSc7XG5pbXBvcnQgZGVjb3JhdGVMYWJlbCBmcm9tICcuLi9oZWxwZXJzL2xhYmVsLWRlY29yYXRvcic7XG5cbi8vIEhhbmRsZXIgbWV0YWRhdGEuXG5leHBvcnQgY29uc3QgbmFtZSA9ICdkZWJ1Zyc7XG5leHBvcnQgY29uc3QgbGV2ZWwgPSBMb2dnaW5nTGV2ZWwuRGVidWc7XG5leHBvcnQgY29uc3QgbGFiZWwgPSBkZWNvcmF0ZUxhYmVsKCdERUJVRycsIENvbG9yU2NoZW1lLkxvdWQpO1xuXG5leHBvcnQgZGVmYXVsdCBudWxsO1xuIiwiLy8gSGFuZGxlciBpbXBsZW1lbnRhdGlvbnMuXG5pbXBvcnQgKiBhcyBGYXRhbEhhbmRsZXIgZnJvbSAnLi9mYXRhbCc7XG5pbXBvcnQgKiBhcyBFcnJvckhhbmRsZXIgZnJvbSAnLi9lcnJvcic7XG5pbXBvcnQgKiBhcyBXYXJuaW5nSGFuZGxlciBmcm9tICcuL3dhcm5pbmcnO1xuaW1wb3J0ICogYXMgTm90aWNlSGFuZGxlciBmcm9tICcuL25vdGljZSc7XG5pbXBvcnQgKiBhcyBJbmZvSGFuZGxlciBmcm9tICcuL2luZm8nO1xuaW1wb3J0ICogYXMgSHR0cEhhbmRsZXIgZnJvbSAnLi9odHRwJztcbmltcG9ydCAqIGFzIFF1ZXJ5SGFuZGxlciBmcm9tICcuL3F1ZXJ5JztcbmltcG9ydCAqIGFzIFZlcmJvc2VIYW5kbGVyIGZyb20gJy4vdmVyYm9zZSc7XG5pbXBvcnQgKiBhcyBEZWJ1Z0hhbmRsZXIgZnJvbSAnLi9kZWJ1Zyc7XG5cbmNvbnN0IGhhbmRsZXJzID0gW1xuICAgIEZhdGFsSGFuZGxlcixcbiAgICBFcnJvckhhbmRsZXIsXG4gICAgV2FybmluZ0hhbmRsZXIsXG4gICAgTm90aWNlSGFuZGxlcixcbiAgICBJbmZvSGFuZGxlcixcbiAgICBIdHRwSGFuZGxlcixcbiAgICBRdWVyeUhhbmRsZXIsXG4gICAgVmVyYm9zZUhhbmRsZXIsXG4gICAgRGVidWdIYW5kbGVyXG5dO1xuXG5leHBvcnQgdHlwZSBMb2dnaW5nTGV2ZWxOYW1lID0gKHR5cGVvZiBoYW5kbGVycyBleHRlbmRzIChpbmZlciBUKVtdID8gVCA6IG5ldmVyKVsnbmFtZSddO1xuZXhwb3J0IGRlZmF1bHQgaGFuZGxlcnM7XG4iLCIvLyBUaGlyZC1wYXJ0eSBtb2R1bGVzLlxuaW1wb3J0IGNoYWxrIGZyb20gJ2NoYWxrJztcbmltcG9ydCByVHJhY2VyIGZyb20gJ2Nscy1ydHJhY2VyJztcbmltcG9ydCB7IERhdGVUaW1lIH0gZnJvbSAnbHV4b24nO1xuaW1wb3J0IHsgZm9ybWF0IH0gZnJvbSAnd2luc3Rvbic7XG5cbi8vIExvY2FsIGhlbHBlcnMuXG5pbXBvcnQgTG9nZ2luZ0xldmVsIGZyb20gJy4uL2hlbHBlcnMvbG9nZ2luZy1sZXZlbCc7XG5cbi8vIEhhbmRsZXIgaW1wbGVtZW50YXRpb25zLlxuaW1wb3J0IGhhbmRsZXJzIGZyb20gJy4uL2hhbmRsZXJzJztcblxuZXhwb3J0IGRlZmF1bHQgZm9ybWF0LnByaW50ZihkYXRhID0+IHtcbiAgICBjb25zdCB0aW1lc3RhbXAgPSBjaGFsay5ncmF5KERhdGVUaW1lLm5vdygpLnRvSVNPKHsgaW5jbHVkZU9mZnNldDogdHJ1ZSB9KSk7XG4gICAgY29uc3QgaGFuZGxlciA9IGhhbmRsZXJzLmZpbmQoKHsgbmFtZSB9KSA9PiBuYW1lID09PSBkYXRhLmxldmVsKTtcbiAgICBjb25zdCBmYWxsYmFjayA9IHsgbGFiZWw6IGhhbmRsZXI/LmxhYmVsLCBwYXlsb2FkOiBkYXRhLm1lc3NhZ2UgfTtcbiAgICBjb25zdCBwZXJmb3JtSGFuZGxlID0gaGFuZGxlcj8uZGVmYXVsdCA/PyAoKCk6IHR5cGVvZiBmYWxsYmFjayA9PiBmYWxsYmFjayk7XG5cbiAgICAvLyBFeGVjdXRlIGhhbmRsZXIgYW5kIHRoZW4sIGdldCBkZWNvcmF0ZWQgcGF5bG9hZC5cbiAgICBjb25zdCB7IGxhYmVsLCBwYXlsb2FkIH0gPSBSZWZsZWN0LmFwcGx5KHBlcmZvcm1IYW5kbGUsIHVuZGVmaW5lZCwgWyBkYXRhIF0pID8/IGZhbGxiYWNrO1xuXG4gICAgbGV0IGV4dHJhRmluZ2VycHJpbnQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIGlmIChoYW5kbGVyPy5sZXZlbCA9PT0gTG9nZ2luZ0xldmVsLkh0dHApIHtcbiAgICAgICAgZXh0cmFGaW5nZXJwcmludCA9IGRhdGEudHJhbnNhY3Rpb25JZFxuICAgICAgICAgICAgPyBgKFRyYW5zYWN0aW9uLUlEID0gJHtkYXRhLnRyYW5zYWN0aW9uSWQgYXMgc3RyaW5nfSlgXG4gICAgICAgICAgICA6IGAoUmVxdWVzdC1JRCA9ICR7clRyYWNlci5pZCgpIGFzIHN0cmluZ30pYDtcbiAgICB9XG5cbiAgICByZXR1cm4gYCR7bGFiZWwgYXMgc3RyaW5nfSAke3RpbWVzdGFtcH0ke2V4dHJhRmluZ2VycHJpbnQgPyBgICR7ZXh0cmFGaW5nZXJwcmludH1gIDogJyd9XFxuJHtwYXlsb2FkIGFzIHN0cmluZ31gO1xufSk7XG4iLCIvLyBOb2RlLmpzIGJ1aWx0LWluIEFQSXMuXG5pbXBvcnQgY2x1c3RlciBmcm9tICdjbHVzdGVyJztcbmltcG9ydCB7IGVudiBhcyBlbnZpcm9ubWVudHMgfSBmcm9tICdwcm9jZXNzJztcbmltcG9ydCB7IGlzTWFpblRocmVhZCB9IGZyb20gJ3dvcmtlcl90aHJlYWRzJztcblxuLy8gVHlwZSBkZWZpbml0aW9ucy5cbmV4cG9ydCBjb25zdCBFeGVjdXRpb25Nb2RlID0ge1xuICAgIERldmVsb3BtZW50TW9kZTogJ2RldmVsb3BtZW50JyxcbiAgICBQcm9kdWN0aW9uTW9kZTogJ3Byb2R1Y3Rpb24nXG59IGFzIGNvbnN0O1xuXG5leHBvcnQgY29uc3QgQ2x1c3RlcmluZ01vZGUgPSB7XG4gICAgTWFzdGVyUHJvY2VzczogMCxcbiAgICBXb3JrZXJQcm9jZXNzOiAxXG59IGFzIGNvbnN0O1xuXG5leHBvcnQgY29uc3QgVGhyZWFkaW5nTW9kZSA9IHtcbiAgICBNYWluVGhyZWFkOiAwLFxuICAgIFdvcmtlclRocmVhZDogMVxufSBhcyBjb25zdDtcblxuZXhwb3J0IHR5cGUgRXhlY3V0aW9uTW9kZSA9IHR5cGVvZiBFeGVjdXRpb25Nb2RlW2tleW9mIHR5cGVvZiBFeGVjdXRpb25Nb2RlXTtcbmV4cG9ydCB0eXBlIENsdXN0ZXJpbmdNb2RlID0gdHlwZW9mIENsdXN0ZXJpbmdNb2RlW2tleW9mIHR5cGVvZiBDbHVzdGVyaW5nTW9kZV07XG5leHBvcnQgdHlwZSBUaHJlYWRpbmdNb2RlID0gdHlwZW9mIFRocmVhZGluZ01vZGVba2V5b2YgdHlwZW9mIFRocmVhZGluZ01vZGVdO1xuXG4vLyBFeHBvcnRpbmdzLlxuZXhwb3J0IGNvbnN0IGV4ZWN1dGlvbk1vZGUgPSBlbnZpcm9ubWVudHMuTk9ERV9FTlYgYXMgRXhlY3V0aW9uTW9kZSA/PyBFeGVjdXRpb25Nb2RlLkRldmVsb3BtZW50TW9kZTtcblxuZXhwb3J0IGNvbnN0IGNsdXN0ZXJpbmdNb2RlOiBDbHVzdGVyaW5nTW9kZSA9IGNsdXN0ZXIuaXNQcmltYXJ5ID8/IGNsdXN0ZXIuaXNNYXN0ZXJcbiAgICA/IENsdXN0ZXJpbmdNb2RlLk1hc3RlclByb2Nlc3NcbiAgICA6IENsdXN0ZXJpbmdNb2RlLldvcmtlclByb2Nlc3M7XG5cbmV4cG9ydCBjb25zdCB0aHJlYWRpbmdNb2RlOiBUaHJlYWRpbmdNb2RlID0gaXNNYWluVGhyZWFkXG4gICAgPyBUaHJlYWRpbmdNb2RlLk1haW5UaHJlYWRcbiAgICA6IFRocmVhZGluZ01vZGUuV29ya2VyVGhyZWFkO1xuIiwiLy8gTm9kZS5qcyBidWlsdC1pbiBBUElzLlxuaW1wb3J0IHtcbiAgICBTVEFUVVNfQ09ERVMsXG4gICAgSW5jb21pbmdNZXNzYWdlIGFzIEh0dHBSZXF1ZXN0LFxuICAgIFNlcnZlclJlc3BvbnNlIGFzIEh0dHBSZXNwb25zZVxufSBmcm9tICdodHRwJztcblxuLy8gVGhpcmQtcGFydHkgbW9kdWxlcy5cbmltcG9ydCBjaGFsayBmcm9tICdjaGFsayc7XG5pbXBvcnQgbW9yZ2FuIGZyb20gJ21vcmdhbic7XG5pbXBvcnQgcHJldHR5Qnl0ZXMgZnJvbSAncHJldHR5LWJ5dGVzJztcbmltcG9ydCBwcmV0dHlNcyBmcm9tICdwcmV0dHktbXMnO1xuXG4vLyBMb2NhbCBoZWxwZXJzLlxuaW1wb3J0IHsgRXhlY3V0aW9uTW9kZSwgZXhlY3V0aW9uTW9kZSB9IGZyb20gJy4uL2hlbHBlcnMvY29uc3RhbnRzJztcblxuLy8gVHlwZSBkZWZpbml0aW9ucy5cbmRlY2xhcmUgbW9kdWxlICdtb3JnYW4nIHtcbiAgICBjb25zdCBjb21iaW5lZDogbW9yZ2FuLkZvcm1hdEZuO1xufVxuXG5pbnRlcmZhY2UgVG9rZW5JbmRleGVyIHtcbiAgICBbdG9rZW5OYW1lOiBzdHJpbmddOiAoXG4gICAgICAgIHJlcXVlc3Q6IEh0dHBSZXF1ZXN0LFxuICAgICAgICByZXNwb25zZTogSHR0cFJlc3BvbnNlLFxuICAgICAgICAuLi5hcmdzOiBhbnlbXVxuICAgICkgPT4gc3RyaW5nIHwgdW5kZWZpbmVkO1xufVxuXG4vLyBIZWxwZXJzLlxuZnVuY3Rpb24gZGVjb3JhdGVTdGF0dXNDb2RlKHN0YXR1c0NvZGU6IGtleW9mIHR5cGVvZiBTVEFUVVNfQ09ERVMpOiBzdHJpbmcge1xuICAgIGNvbnN0IGdyb3VwT2ZDb2RlID0gTWF0aC5mbG9vcihOdW1iZXIoc3RhdHVzQ29kZSkgLyAxMDApICogMTAwO1xuICAgIGNvbnN0IGJhc2VNZXNzYWdlID0gYCR7c3RhdHVzQ29kZX0gJHtTVEFUVVNfQ09ERVNbc3RhdHVzQ29kZV0gYXMgc3RyaW5nfWA7XG5cbiAgICBzd2l0Y2ggKGdyb3VwT2ZDb2RlKSB7XG4gICAgY2FzZSAyMDA6IHtcbiAgICAgICAgcmV0dXJuIGNoYWxrLmdyZWVuKGJhc2VNZXNzYWdlKTtcbiAgICB9XG5cbiAgICBjYXNlIDMwMDoge1xuICAgICAgICByZXR1cm4gY2hhbGsubWFnZW50YShiYXNlTWVzc2FnZSk7XG4gICAgfVxuICAgIGNhc2UgNDAwOlxuICAgIGNhc2UgNTAwOiB7XG4gICAgICAgIHJldHVybiBjaGFsay5yZWQoYmFzZU1lc3NhZ2UpO1xuICAgIH1cblxuICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgcmV0dXJuIGNoYWxrLmdyYXkoYmFzZU1lc3NhZ2UpO1xuICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIGZvcm1hdEZvck1vcmdhbih0b2tlbnM6IGFueSwgcmVxdWVzdDogSHR0cFJlcXVlc3QsIHJlc3BvbnNlOiBIdHRwUmVzcG9uc2UpOiBzdHJpbmcge1xuICAgIGZ1bmN0aW9uIF8odG9rZW46IHN0cmluZywgLi4uc3ViQXJnczogYW55W10pOiBzdHJpbmcgfCB2b2lkIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtYXJndW1lbnRcbiAgICAgICAgcmV0dXJuICh0b2tlbnMgYXMgVG9rZW5JbmRleGVyKVt0b2tlbl0ocmVxdWVzdCwgcmVzcG9uc2UsIC4uLnN1YkFyZ3MpO1xuICAgIH1cblxuICAgIC8vIFJhdyB2YWx1ZXMuXG4gICAgY29uc3QgbWV0aG9kID0gXygnbWV0aG9kJyk7XG4gICAgY29uc3QgVVJMID0gXygndXJsJyk7XG4gICAgY29uc3QgaHR0cFZlcnNpb24gPSBgSFRUUC8ke18oJ2h0dHAtdmVyc2lvbicpIGFzIHN0cmluZ31gO1xuICAgIGNvbnN0IHN0YXR1c0NvZGUgPSBOdW1iZXIoXygnc3RhdHVzJykpO1xuICAgIGNvbnN0IGNvbnRlbnRMZW5ndGggPSBOdW1iZXIoXygncmVzJywgJ2NvbnRlbnQtbGVuZ3RoJykgPz8gLTEpO1xuICAgIGNvbnN0IHJlc3BvbnNlVGltZSA9IE51bWJlcihfKCdyZXNwb25zZS10aW1lJykgPz8gLTEpO1xuXG4gICAgLy8gRGVjb3JhdGVkIHZhbHVlcy5cbiAgICBjb25zdCAkbWV0aG9kID0gY2hhbGsuYm9sZChtZXRob2QpO1xuICAgIGNvbnN0ICR2ZXJzaW9uID0gY2hhbGsucmdiKDk4LCAxNzcsIDI1NSkoaHR0cFZlcnNpb24pO1xuICAgIGNvbnN0ICRzdGF0dXNDb2RlID0gZGVjb3JhdGVTdGF0dXNDb2RlKHN0YXR1c0NvZGUpO1xuICAgIGNvbnN0ICRjb250ZW50TGVuZ3RoID0gY29udGVudExlbmd0aCA+PSAwID8gcHJldHR5Qnl0ZXMoY29udGVudExlbmd0aCkgOiAnPyBCJztcbiAgICBjb25zdCAkcmVzcG9uc2VUaW1lID0gcmVzcG9uc2VUaW1lID49IDAgPyBwcmV0dHlNcyhyZXNwb25zZVRpbWUpIDogJyc7XG5cbiAgICAvLyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uLlxuICAgIGNvbnN0IG1ldGFkYXRhID0gYCgkeyRjb250ZW50TGVuZ3RofSwgJHskcmVzcG9uc2VUaW1lfSlgO1xuXG4gICAgcmV0dXJuIFtcbiAgICAgICAgYOKGkiAkeyRtZXRob2R9ICR7VVJMIGFzIHN0cmluZ30gJHskdmVyc2lvbn1gLFxuICAgICAgICBg4oaQICR7JHZlcnNpb259ICR7JHN0YXR1c0NvZGV9ICR7bWV0YWRhdGF9YFxuICAgIF0uam9pbignXFxuJyk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGV4ZWN1dGlvbk1vZGUgPT09IEV4ZWN1dGlvbk1vZGUuRGV2ZWxvcG1lbnRNb2RlID8gZm9ybWF0Rm9yTW9yZ2FuIDogbW9yZ2FuLmNvbWJpbmVkO1xuIiwiaW1wb3J0ICdyZWZsZWN0LW1ldGFkYXRhJztcblxuLy8gTm9kZS5qcyBidWlsdC1pbiBBUElzLlxuaW1wb3J0IHsgSW5jb21pbmdNZXNzYWdlIGFzIEh0dHBSZXF1ZXN0LCBTZXJ2ZXJSZXNwb25zZSBhcyBIdHRwUmVzcG9uc2UgfSBmcm9tICdodHRwJztcbmltcG9ydCB7IFBhc3NUaHJvdWdoIH0gZnJvbSAnc3RyZWFtJztcblxuLy8gVGhpcmQtcGFydHkgbW9kdWxlcy5cbmltcG9ydCBQcm9taXNlIGZyb20gJ2JsdWViaXJkJztcbmltcG9ydCBsb2Rhc2ggZnJvbSAnbG9kYXNoJztcbmltcG9ydCBtb3JnYW4gZnJvbSAnbW9yZ2FuJztcbmltcG9ydCB0eXBlIHsgbGV2ZWwgYXMgTG9nZ2luZ0xldmVsIH0gZnJvbSAnd2luc3Rvbic7XG5pbXBvcnQgKiBhcyB3aW5zdG9uIGZyb20gJ3dpbnN0b24nO1xuaW1wb3J0IHsgTG9nZ2VyIGFzIEJhc2VMb2dnZXIgfSBmcm9tICd3aW5zdG9uJztcblxuLy8gRm9ybWF0dGVycy5cbmltcG9ydCBmb3JtYXRGb3JDTEkgZnJvbSAnLi4vZm9ybWF0dGVycy9jb21tYW5kLWxpbmUnO1xuaW1wb3J0IGZvcm1hdEZvck1vcmdhbiBmcm9tICcuLi9mb3JtYXR0ZXJzL21vcmdhbic7XG5cbi8vIExvY2FsIGhlbHBlcnMuXG5pbXBvcnQgeyBFeGVjdXRpb25Nb2RlLCBleGVjdXRpb25Nb2RlIH0gZnJvbSAnLi4vaGVscGVycy9jb25zdGFudHMnO1xuXG4vLyBIYW5kbGVyIGltcGxlbWVudGF0aW9ucy5cbmltcG9ydCB0eXBlIHsgTG9nZ2luZ0xldmVsTmFtZSB9IGZyb20gJy4uL2hhbmRsZXJzJztcbmltcG9ydCBoYW5kbGVycyBmcm9tICcuLi9oYW5kbGVycyc7XG5cbi8vIFR5cGUgZGVmaW5pdGlvbnMuXG50eXBlIE1vcmdhbiA9IChyZXE6IEh0dHBSZXF1ZXN0LCByZXM6IEh0dHBSZXNwb25zZSwgbmV4dDogKGVycm9yPzogRXJyb3IpID0+IHZvaWQpID0+IHZvaWQ7XG5cbi8vIFRyYW5zcG9ydHMuXG5jb25zdCB7IENvbnNvbGU6IENvbnNvbGVUcmFuc3BvcnQgfSA9IHdpbnN0b24udHJhbnNwb3J0cztcblxuLy8gS2V5cyBpbiBvcmRlciB0byBhY2Nlc3MgcHJpdmF0ZSBwcm9wZXJ0aWVzLlxuY29uc3QgS2V5T2ZJbnN0YW5jZTogdW5pcXVlIHN5bWJvbCA9IFN5bWJvbCgnQGNpY2hvbC9sb2dnZXI6OmNsYXNzZXMvbG9nZ2VyOjpJbnN0YW5jZScpO1xuY29uc3QgS2V5T2ZQYXNzcG9ydDogdW5pcXVlIHN5bWJvbCA9IFN5bWJvbCgnQGNpY2hvbC9sb2dnZXI6OmNsYXNzZXMvbG9nZ2VyOjpQYXNzcG9ydCcpO1xuXG5jbGFzcyBMb2dnZXIge1xuICAgICNsb2dnZXI6IEJhc2VMb2dnZXIgPSB3aW5zdG9uLmNyZWF0ZUxvZ2dlcih7XG4gICAgICAgIGxldmVsczogbG9kYXNoKGhhbmRsZXJzKVxuICAgICAgICAgICAgLm1hcCgoeyBuYW1lLCBsZXZlbCB9KSA9PiBbIG5hbWUsIGxldmVsIF0pXG4gICAgICAgICAgICAuZmlsdGVyKChbICwgbGV2ZWwgXSkgPT4gdHlwZW9mIGxldmVsID09PSAnbnVtYmVyJylcbiAgICAgICAgICAgIC5mcm9tUGFpcnMoKVxuICAgICAgICAgICAgLnZhbHVlKCksXG5cbiAgICAgICAgbGV2ZWw6IChleGVjdXRpb25Nb2RlID09PSBFeGVjdXRpb25Nb2RlLlByb2R1Y3Rpb25Nb2RlID8gJ2h0dHAnIDogJ3ZlcmJvc2UnKSBhcyB0eXBlb2YgTG9nZ2luZ0xldmVsLFxuXG4gICAgICAgIHRyYW5zcG9ydHM6IFtcbiAgICAgICAgICAgIG5ldyBDb25zb2xlVHJhbnNwb3J0KHsgZm9ybWF0OiBmb3JtYXRGb3JDTEkgfSlcbiAgICAgICAgXSxcblxuICAgICAgICBleGl0T25FcnJvcjogZmFsc2VcbiAgICB9KTtcblxuICAgICNtb3JnYW46IE1vcmdhbiA9IG1vcmdhbihmb3JtYXRGb3JNb3JnYW4sIHtcbiAgICAgICAgc3RyZWFtOiBuZXcgUGFzc1Rocm91Z2goeyBvYmplY3RNb2RlOiB0cnVlIH0pLm9uKCdkYXRhJywgKGRhdGE6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgdGhpcy5sb2coJ2h0dHAnLCBkYXRhLnRyaW0oKSk7XG4gICAgICAgIH0pXG4gICAgfSkgYXMgTW9yZ2FuO1xuXG4gICAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihwYXNzcG9ydDogdHlwZW9mIEtleU9mUGFzc3BvcnQpIHtcbiAgICAgICAgaWYgKHBhc3Nwb3J0ICE9PSBLZXlPZlBhc3Nwb3J0KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoJ0xvZ2dlciBjbGFzcyBjYW5ub3QgYmUgY29uc3RydWN0ZWQgaW4gZGlyZWN0bHknKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBzdGF0aWMgZ2V0IGluc3RhbmNlKCk6IExvZ2dlciB7XG4gICAgICAgIGlmICh0aGlzICE9PSBMb2dnZXIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcignTG9nZ2VyIGNsYXNzIGlzIG5vdCBpbmhlcml0YWJsZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKFJlZmxlY3QuaGFzT3duTWV0YWRhdGEoS2V5T2ZJbnN0YW5jZSwgTG9nZ2VyKSkge1xuICAgICAgICAgICAgcmV0dXJuIFJlZmxlY3QuZ2V0T3duTWV0YWRhdGEoS2V5T2ZJbnN0YW5jZSwgTG9nZ2VyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGluc3RhbmNlID0gbmV3IExvZ2dlcihLZXlPZlBhc3Nwb3J0KTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIGluc3RhbmNlO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShLZXlPZkluc3RhbmNlLCBpbnN0YW5jZSwgTG9nZ2VyKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIExvZ2dpbmcgbWVzc2FnZSB3aXRoIHNwZWNpZmljIGxldmVsLlxuICAgICAqXG4gICAgICogQHBhcmFtIGxldmVsXG4gICAgICogQHBhcmFtIG1lc3NhZ2VcbiAgICAgKiBAcGFyYW0gYXJncyBBZGRpdGlvbmFsIG1ldGFkYXRhLlxuICAgICAqL1xuICAgIHB1YmxpYyBsb2cobGV2ZWw6IExvZ2dpbmdMZXZlbE5hbWUsIG1lc3NhZ2U6IHN0cmluZywgLi4uYXJnczogYW55W10pOiB2b2lkO1xuXG4gICAgLyoqXG4gICAgICogTG9nZ2luZyBIVFRQIEkvTy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSByZXF1ZXN0IE5vZGUuanMgYnVpbHQtaW4gYEluY29taW5nTWVzc2FnZWAgaW5zdGFuY2UgZnJvbSBgaHR0cGAgbW9kdWxlLlxuICAgICAqIEBwYXJhbSByZXNwb25zZSBOb2RlLmpzIGJ1aWx0LWluIGBTZXJ2ZXJSZXNwb25zZWAgaW5zdGFuY2UgZnJvbSBgaHR0cGAgbW9kdWxlLlxuICAgICAqL1xuICAgIHB1YmxpYyBsb2cocmVxdWVzdDogSHR0cFJlcXVlc3QsIHJlc3BvbnNlOiBIdHRwUmVzcG9uc2UpOiBQcm9taXNlPHZvaWQ+O1xuXG4gICAgLyoqXG4gICAgICogTG9nZ2luZyBlcnJvcnMgaW4gZGV0YWlsLlxuICAgICAqXG4gICAgICogQHBhcmFtIGVycm9yXG4gICAgICovXG4gICAgcHVibGljIGxvZyhlcnJvcjogRXJyb3IpOiB2b2lkO1xuXG4gICAgcHVibGljIGxvZyguLi5hcmdzOiBhbnlbXSk6IHZvaWQgfCBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29uc3QgbG9nZ2VyID0gdGhpcy4jbG9nZ2VyO1xuICAgICAgICBjb25zdCBtb3JnYW4gPSB0aGlzLiNtb3JnYW47XG5cbiAgICAgICAgc3dpdGNoICh0cnVlKSB7XG4gICAgICAgIGNhc2UgKGFyZ3MubGVuZ3RoID49IDIgJiYgYXJnc1swXSBpbnN0YW5jZW9mIEh0dHBSZXF1ZXN0ICYmIGFyZ3NbMV0gaW5zdGFuY2VvZiBIdHRwUmVzcG9uc2UpOiB7XG4gICAgICAgICAgICBjb25zdCBbIHJlcXVlc3QsIHJlc3BvbnNlIF0gPSBhcmdzIGFzIFsgSHR0cFJlcXVlc3QsIEh0dHBSZXNwb25zZSBdO1xuXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5mcm9tQ2FsbGJhY2s8dm9pZD4oY2FsbGJhY2sgPT4gbW9yZ2FuKHJlcXVlc3QsIHJlc3BvbnNlLCBjYWxsYmFjaykpO1xuICAgICAgICB9XG5cbiAgICAgICAgY2FzZSAoYXJncy5sZW5ndGggPj0gMSAmJiBhcmdzWzBdIGluc3RhbmNlb2YgRXJyb3IpOiB7XG4gICAgICAgICAgICBjb25zdCBbIGVycm9yLCAuLi5kYXRhIF0gPSBhcmdzIGFzIFsgRXJyb3IsIC4uLmFueVtdIF07XG5cbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLWFyZ3VtZW50XG4gICAgICAgICAgICBsb2dnZXIubG9nKCdlcnJvcicsIGVycm9yLm1lc3NhZ2UsIGVycm9yLCAuLi5kYXRhKTtcblxuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgIGNvbnN0IFsgbGV2ZWwsIG1lc3NhZ2UsIC4uLmRhdGEgXSA9IGFyZ3MgYXMgWyB0eXBlb2YgTG9nZ2luZ0xldmVsLCBzdHJpbmcsIC4uLmFueVtdIF07XG5cbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLWFyZ3VtZW50XG4gICAgICAgICAgICBsb2dnZXIubG9nKGxldmVsLCBtZXNzYWdlLCAuLi5kYXRhKTtcblxuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBMb2dnZXIuaW5zdGFuY2U7XG4iXSwibmFtZXMiOlsiTG9nZ2luZ0xldmVsIiwiRmF0YWwiLCJFcnJvciIsIldhcm5pbmciLCJOb3RpY2UiLCJJbmZvIiwiSHR0cCIsIlF1ZXJ5IiwiVmVyYm9zZSIsIkRlYnVnIiwiY29sb3JpemVyTWFwIiwiX01hcCIsImNyZWF0ZVNjaGVtZSIsIm9wdGlvbnMiLCJuZXh0SW5kZXgiLCJzaXplIiwiY29sb3JpemVyIiwiY2hhbGsiLCJiZ0hleCIsImJhY2tncm91bmQiLCJoZXgiLCJmb3JlZ3JvdW5kIiwic2V0IiwiQ29sb3JWYWx1ZSIsIldoaXRlIiwiR3JheSIsIkJsYWNrIiwiQ3JpdGljYWwiLCJSZWd1bGFyIiwiQ29sb3JTY2hlbWUiLCJMb3VkIiwiZ2V0Q2hhbGtPZiIsImNvbG9yU2V0IiwiZ2V0IiwiaXNUVFkiLCJwcm9jZXNzIiwic3Rkb3V0IiwiaXNOb3RPbkNMSSIsImRlY29yYXRlTGFiZWwiLCJsYWJlbCIsInNjaGVtZSIsImRlY29yYXRlZExhYmVsIiwiYm9sZCIsInJvb3RQYXRoIiwiY3dkIiwiY29uanVuY3Rpb24iLCJibHVlIiwic3BsYXQiLCJfU3ltYm9sJGZvciIsIm5hbWUiLCJsZXZlbCIsIm1hcExvY2F0aW9uT2ZFcnJvclRocm93biIsImZpbGVuYW1lIiwidGFyZ2V0IiwicGF0aCIsInJlbGF0aXZlIiwiX3N0YXJ0c1dpdGhJbnN0YW5jZVByb3BlcnR5IiwiY2FsbCIsImdyYXkiLCJyZXBsYWNlIiwibWF0Y2hlcyIsIm1vZHVsZU5hbWUiLCJ0cmFpbGluZyIsInNlcCIsInVuZGVybGluZSIsImRpcm5hbWUiLCJiYXNlbmFtZSIsImhhbmRsZSIsImRhdGEiLCJfY29udGV4dCIsIl9jb250ZXh0MiIsIl9jb250ZXh0MyIsImVycm9yIiwidW5kZWZpbmVkIiwibWVzc2FnZSIsInN0YWNrIiwicmF3U3RhY2siLCJfbWFwSW5zdGFuY2VQcm9wZXJ0eSIsIl9zbGljZUluc3RhbmNlUHJvcGVydHkiLCJsZW5ndGgiLCJzcGxpdCIsImxpbmUiLCJpc0Fic29sdXRlIiwiY29udGV4dE5hbWUiLCJyYXdMb2NhdGlvbiIsImxvY2F0aW9uIiwiY29sdW1uIiwidmVyc2lvbiIsImpvaW4iLCJwYXlsb2FkIiwiaGlnaGxpZ2h0IiwibGFuZ3VhZ2UiLCJoYW5kbGVycyIsIkZhdGFsSGFuZGxlciIsIkVycm9ySGFuZGxlciIsIldhcm5pbmdIYW5kbGVyIiwiTm90aWNlSGFuZGxlciIsIkluZm9IYW5kbGVyIiwiSHR0cEhhbmRsZXIiLCJRdWVyeUhhbmRsZXIiLCJWZXJib3NlSGFuZGxlciIsIkRlYnVnSGFuZGxlciIsImZvcm1hdCIsInByaW50ZiIsInRpbWVzdGFtcCIsIkRhdGVUaW1lIiwibm93IiwidG9JU08iLCJpbmNsdWRlT2Zmc2V0IiwiaGFuZGxlciIsIl9maW5kSW5zdGFuY2VQcm9wZXJ0eSIsImZhbGxiYWNrIiwicGVyZm9ybUhhbmRsZSIsImRlZmF1bHQiLCJfUmVmbGVjdCRhcHBseSIsImV4dHJhRmluZ2VycHJpbnQiLCJ0cmFuc2FjdGlvbklkIiwiclRyYWNlciIsImlkIiwiRXhlY3V0aW9uTW9kZSIsIkRldmVsb3BtZW50TW9kZSIsIlByb2R1Y3Rpb25Nb2RlIiwiQ2x1c3RlcmluZ01vZGUiLCJNYXN0ZXJQcm9jZXNzIiwiV29ya2VyUHJvY2VzcyIsImV4ZWN1dGlvbk1vZGUiLCJlbnZpcm9ubWVudHMiLCJOT0RFX0VOViIsImNsdXN0ZXIiLCJpc1ByaW1hcnkiLCJpc01hc3RlciIsImRlY29yYXRlU3RhdHVzQ29kZSIsInN0YXR1c0NvZGUiLCJncm91cE9mQ29kZSIsIk1hdGgiLCJmbG9vciIsIk51bWJlciIsImJhc2VNZXNzYWdlIiwiU1RBVFVTX0NPREVTIiwiZ3JlZW4iLCJtYWdlbnRhIiwicmVkIiwiZm9ybWF0Rm9yTW9yZ2FuIiwidG9rZW5zIiwicmVxdWVzdCIsInJlc3BvbnNlIiwiXyIsInRva2VuIiwic3ViQXJncyIsIm1ldGhvZCIsIlVSTCIsImh0dHBWZXJzaW9uIiwiY29udGVudExlbmd0aCIsInJlc3BvbnNlVGltZSIsIiRtZXRob2QiLCIkdmVyc2lvbiIsInJnYiIsIiRzdGF0dXNDb2RlIiwiJGNvbnRlbnRMZW5ndGgiLCJwcmV0dHlCeXRlcyIsIiRyZXNwb25zZVRpbWUiLCJwcmV0dHlNcyIsIm1ldGFkYXRhIiwibW9yZ2FuIiwiY29tYmluZWQiLCJDb25zb2xlIiwiQ29uc29sZVRyYW5zcG9ydCIsIndpbnN0b24iLCJ0cmFuc3BvcnRzIiwiS2V5T2ZJbnN0YW5jZSIsIl9TeW1ib2wiLCJLZXlPZlBhc3Nwb3J0IiwiTG9nZ2VyIiwiY3JlYXRlTG9nZ2VyIiwibGV2ZWxzIiwiX2ZpbHRlckluc3RhbmNlUHJvcGVydHkiLCJsb2Rhc2giLCJmcm9tUGFpcnMiLCJ2YWx1ZSIsImZvcm1hdEZvckNMSSIsImV4aXRPbkVycm9yIiwic3RyZWFtIiwiUGFzc1Rocm91Z2giLCJvYmplY3RNb2RlIiwib24iLCJsb2ciLCJfdHJpbUluc3RhbmNlUHJvcGVydHkiLCJjb25zdHJ1Y3RvciIsInBhc3Nwb3J0IiwiUmVmZXJlbmNlRXJyb3IiLCJpbnN0YW5jZSIsIlJlZmxlY3QiLCJoYXNPd25NZXRhZGF0YSIsImdldE93bk1ldGFkYXRhIiwiZGVmaW5lTWV0YWRhdGEiLCJhcmdzIiwibG9nZ2VyIiwiSHR0cFJlcXVlc3QiLCJIdHRwUmVzcG9uc2UiLCJQcm9taXNlIiwiZnJvbUNhbGxiYWNrIiwiY2FsbGJhY2si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
File without changes