@nlabs/lex 1.56.1 → 1.57.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.
@@ -31,9 +31,7 @@ const defaultExit = (code)=>{
31
31
  };
32
32
  export const getTestFilePatterns = (testPathPattern)=>{
33
33
  const defaultPatterns = [
34
- '**/*.test.*',
35
- '**/*.spec.*',
36
- '**/*.integration.*'
34
+ '**/*.test.{ts,tsx,js,jsx}'
37
35
  ];
38
36
  if (!testPathPattern) {
39
37
  return defaultPatterns;
@@ -42,6 +40,9 @@ export const getTestFilePatterns = (testPathPattern)=>{
42
40
  testPathPattern
43
41
  ];
44
42
  };
43
+ export const getE2ETestFilePatterns = ()=>[
44
+ '**/*.e2e.{ts,tsx,js,jsx}'
45
+ ];
45
46
  const findUncoveredSourceFiles = ()=>{
46
47
  const sourceFiles = globSync('src/**/*.{ts,tsx,js,jsx}', {
47
48
  cwd: process.cwd(),
@@ -53,7 +54,7 @@ const findUncoveredSourceFiles = ()=>{
53
54
  '**/*.spec.*'
54
55
  ]
55
56
  });
56
- const testFiles = globSync('**/*.{test,spec}.{ts,tsx,js,jsx}', {
57
+ const testFiles = globSync('**/*.test.{ts,tsx,js,jsx}', {
57
58
  cwd: process.cwd(),
58
59
  ignore: [
59
60
  '**/node_modules/**',
@@ -87,10 +88,12 @@ export const test = async (options, args, filesOrCallback, callbackParam)=>{
87
88
  files = filesOrCallback;
88
89
  callback = callbackParam || defaultExit;
89
90
  }
90
- const { analyze = false, aiAnalyze = false, aiDebug = false, aiGenerate = false, bail, changedFilesWithAncestor, changedSince, ci, clearCache, cliName = 'Lex', collectCoverageFrom, colors, config, debug = false, debugTests = false, detectOpenHandles, environment, env, errorOnDeprecated, expand, forceExit, generate = false, json, lastCommit, listTests, logHeapUsage, maxWorkers, noStackTrace, notify, onlyChanged, outputFile, passWithNoTests, quiet, removeCache, runInBand, setup, showConfig, silent, testLocationInResults, testNamePattern, testPathPattern, update, useStderr, verbose, watch, watchAll } = options;
91
+ const { analyze = false, aiAnalyze = false, aiDebug = false, aiGenerate = false, bail, changedFilesWithAncestor, changedSince, ci, clearCache, cliName = 'Lex', collectCoverageFrom, colors, config, debug = false, debugTests = false, detectOpenHandles, e2e = false, e2eConfig, environment, env, errorOnDeprecated, expand, forceExit, generate = false, json, lastCommit, listTests, logHeapUsage, maxWorkers, noStackTrace, notify, onlyChanged, outputFile, passWithNoTests, quiet, removeCache, runInBand, setup, showConfig, silent, testLocationInResults, testNamePattern, testPathPattern, unit = false, update, useStderr, verbose, watch, watchAll } = options;
91
92
  const useGenerate = generate || aiGenerate;
92
93
  const useAnalyze = analyze || aiAnalyze;
93
94
  const useDebug = debugTests || aiDebug;
95
+ const runE2E = e2e;
96
+ const runUnit = unit || !runE2E;
94
97
  log(`${cliName} testing...`, 'info', quiet);
95
98
  const spinner = createSpinner(quiet);
96
99
  await LexConfig.parseConfig(options);
@@ -128,88 +131,6 @@ export const test = async (options, args, filesOrCallback, callbackParam)=>{
128
131
  }
129
132
  }
130
133
  }
131
- const projectVitestBin = pathResolve(process.cwd(), 'node_modules/.bin/vitest');
132
- let vitestPath;
133
- if (existsSync(projectVitestBin)) {
134
- vitestPath = projectVitestBin;
135
- } else {
136
- vitestPath = resolveBinaryPath('vitest');
137
- }
138
- if (!vitestPath) {
139
- log(`\n${cliName} Error: Vitest binary not found in Lex's node_modules or monorepo root`, 'error', quiet);
140
- log('Please reinstall Lex or check your installation.', 'info', quiet);
141
- return 1;
142
- }
143
- let vitestConfigFile;
144
- let projectVitestConfig = null;
145
- if (config) {
146
- vitestConfigFile = config;
147
- } else {
148
- const projectVitestConfigPaths = [
149
- pathResolve(process.cwd(), 'vitest.config.ts'),
150
- pathResolve(process.cwd(), 'vitest.config.mts'),
151
- pathResolve(process.cwd(), 'vitest.config.js'),
152
- pathResolve(process.cwd(), 'vitest.config.mjs'),
153
- pathResolve(process.cwd(), 'vitest.config.cjs')
154
- ];
155
- const existingConfigPath = projectVitestConfigPaths.find((configPath)=>existsSync(configPath));
156
- if (existingConfigPath) {
157
- vitestConfigFile = existingConfigPath;
158
- if (debug) {
159
- log(`Using project Vitest config file: ${vitestConfigFile}`, 'info', quiet);
160
- }
161
- } else {
162
- // No Vitest config file exists in the project
163
- // Check if there's a Vitest config in lex.config.cjs
164
- projectVitestConfig = LexConfig.config.vitest || null;
165
- const lexDir = LexConfig.getLexDir();
166
- const lexVitestConfig = pathResolve(lexDir, 'vitest.config.mjs');
167
- if (debug) {
168
- log(`Looking for Vitest config at: ${lexVitestConfig}`, 'info', quiet);
169
- log(`File exists: ${existsSync(lexVitestConfig)}`, 'info', quiet);
170
- }
171
- if (existsSync(lexVitestConfig)) {
172
- vitestConfigFile = lexVitestConfig;
173
- if (projectVitestConfig && Object.keys(projectVitestConfig).length > 0) {
174
- if (debug) {
175
- log(`Using Lex Vitest config with project Vitest config from lex.config.cjs: ${vitestConfigFile}`, 'info', quiet);
176
- }
177
- } else if (debug) {
178
- log(`Using Lex Vitest config (no project Vitest config found): ${vitestConfigFile}`, 'info', quiet);
179
- }
180
- } else {
181
- if (debug) {
182
- log('No Vitest config found in project or Lex', 'warn', quiet);
183
- }
184
- }
185
- }
186
- }
187
- if (showConfig) {
188
- if (vitestConfigFile) {
189
- const resolvedConfig = await import(vitestConfigFile);
190
- log(JSON.stringify(resolvedConfig.default ?? resolvedConfig, null, 2), 'info', quiet);
191
- } else {
192
- log(JSON.stringify({
193
- test: projectVitestConfig ?? {}
194
- }, null, 2), 'info', quiet);
195
- }
196
- callback(0);
197
- return 0;
198
- }
199
- const vitestSetupFile = setup || pathResolve(process.cwd(), 'vitest.setup.js');
200
- const vitestArgs = [];
201
- const vitestOptions = [];
202
- const reporters = new Set();
203
- const filters = [];
204
- const watchMode = Boolean(watch || watchAll);
205
- const listMode = Boolean(listTests);
206
- if (listMode) {
207
- vitestArgs.push('list');
208
- } else if (watchMode) {
209
- vitestArgs.push('watch');
210
- } else {
211
- vitestArgs.push('run');
212
- }
213
134
  const isESM = detectESM(process.cwd());
214
135
  let nodeOptions = process.env.NODE_OPTIONS || '';
215
136
  if (isESM) {
@@ -218,152 +139,230 @@ export const test = async (options, args, filesOrCallback, callbackParam)=>{
218
139
  }
219
140
  log('ESM project detected, using --experimental-vm-modules in NODE_OPTIONS', 'info', quiet);
220
141
  }
221
- if (vitestConfigFile) {
222
- vitestOptions.push('--config', vitestConfigFile);
223
- }
224
- if (bail) {
225
- vitestOptions.push('--bail', '1');
226
- }
227
- if (changedFilesWithAncestor) {
228
- vitestOptions.push('--changed');
229
- }
230
- if (changedSince) {
231
- vitestOptions.push('--changed', changedSince);
232
- }
233
- if (ci) {
234
- vitestOptions.push('--run');
235
- }
236
- if (collectCoverageFrom) {
237
- vitestOptions.push('--coverage', '--coverage.include', collectCoverageFrom);
238
- }
239
- if (debug) {
240
- vitestOptions.push('--inspect');
241
- }
242
- if (detectOpenHandles) {
243
- reporters.add('hanging-process');
244
- }
245
- const environmentName = environment || env;
246
- if (environmentName) {
247
- vitestOptions.push('--environment', environmentName);
248
- }
249
- if (errorOnDeprecated) {
250
- log('Vitest does not support --errorOnDeprecated; option ignored.', 'warn', quiet);
251
- }
252
- if (expand) {
253
- vitestOptions.push('--expandSnapshotDiff');
254
- }
255
- if (forceExit) {
256
- log('Vitest does not support --forceExit; option ignored.', 'warn', quiet);
257
- }
258
- if (lastCommit) {
259
- vitestOptions.push('--changed');
260
- }
261
- if (logHeapUsage) {
262
- vitestOptions.push('--logHeapUsage');
263
- }
264
- if (maxWorkers) {
265
- vitestOptions.push('--maxWorkers', maxWorkers);
266
- }
267
- if (noStackTrace) {
268
- log('Vitest does not support --noStackTrace; option ignored.', 'warn', quiet);
269
- }
270
- if (notify) {
271
- log('Vitest does not support --notify; option ignored.', 'warn', quiet);
272
- }
273
- if (onlyChanged) {
274
- vitestOptions.push('--changed');
275
- }
276
142
  let tempOutputFile = outputFile;
277
- const shouldWriteJson = json || useAnalyze || useDebug || Boolean(outputFile);
278
- if (shouldWriteJson) {
279
- tempOutputFile = outputFile || '.lex-test-results.json';
280
- vitestOptions.push('--outputFile', tempOutputFile);
281
- reporters.add('json');
282
- }
283
- if (passWithNoTests) {
284
- vitestOptions.push('--passWithNoTests');
285
- }
286
- if (runInBand) {
287
- vitestOptions.push('--no-file-parallelism', '--maxWorkers', '1');
288
- }
289
- if (silent) {
290
- vitestOptions.push('--silent');
291
- }
292
- if (testLocationInResults) {
293
- vitestOptions.push('--includeTaskLocation');
294
- }
295
- if (testNamePattern) {
296
- vitestOptions.push('--testNamePattern', testNamePattern);
297
- }
298
- if (testPathPattern) {
299
- filters.push(testPathPattern);
300
- }
301
- if (useStderr) {
302
- log('Vitest does not support --useStderr; option ignored.', 'warn', quiet);
303
- }
304
- if (verbose) {
305
- reporters.add('verbose');
306
- }
307
- if (removeCache || clearCache) {
308
- vitestOptions.push('--clearCache');
309
- }
310
- if (update) {
311
- vitestOptions.push('--update');
312
- }
313
- if (watch) {
314
- filters.push(watch);
315
- }
316
- if (args) {
317
- vitestOptions.push(...args);
318
- }
319
- if (files && files.length > 0) {
320
- filters.push(...files);
321
- }
322
- if (reporters.size > 0) {
323
- const reporterList = Array.from(reporters);
324
- if (reporterList.includes('json') && !reporterList.includes('verbose')) {
325
- // Keep console output while writing JSON results.
326
- reporterList.unshift('default');
327
- }
328
- reporterList.forEach((reporter)=>vitestOptions.push('--reporter', reporter));
329
- }
330
- const finalArgs = [
331
- ...vitestArgs,
332
- ...vitestOptions,
333
- ...filters
334
- ];
335
- if (debug) {
336
- log(`Vitest options: ${finalArgs.join(' ')}`, 'info', quiet);
337
- log(`NODE_OPTIONS: ${nodeOptions}`, 'info', quiet);
338
- }
339
143
  try {
340
- const env = {
144
+ const processEnv = {
341
145
  ...process.env,
342
146
  NODE_OPTIONS: nodeOptions
343
147
  };
344
148
  if (colors) {
345
- env.FORCE_COLOR = '1';
149
+ processEnv.FORCE_COLOR = '1';
346
150
  }
347
151
  if (ci) {
348
- env.CI = 'true';
349
- }
350
- if (vitestSetupFile && existsSync(vitestSetupFile)) {
351
- env.LEX_VITEST_SETUP = vitestSetupFile;
152
+ processEnv.CI = 'true';
352
153
  }
353
- await execa(vitestPath, finalArgs, {
354
- encoding: 'utf8',
355
- env,
356
- stdio: 'inherit'
357
- });
358
- spinner.succeed('Testing completed!');
359
- if (useAnalyze) {
360
- spinner.start('AI is analyzing test coverage and suggesting improvements...');
361
- try {
362
- const testResults = processTestResults(tempOutputFile);
363
- const filePatterns = getTestFilePatterns(testPathPattern);
364
- await aiFunction({
365
- context: true,
366
- prompt: `Analyze these Vitest test results and suggest test coverage improvements:
154
+ if (runUnit) {
155
+ const projectVitestBin = pathResolve(process.cwd(), 'node_modules/.bin/vitest');
156
+ let vitestPath;
157
+ if (existsSync(projectVitestBin)) {
158
+ vitestPath = projectVitestBin;
159
+ } else {
160
+ vitestPath = resolveBinaryPath('vitest');
161
+ }
162
+ if (!vitestPath) {
163
+ log(`\n${cliName} Error: Vitest binary not found in Lex's node_modules or monorepo root`, 'error', quiet);
164
+ log('Please reinstall Lex or check your installation.', 'info', quiet);
165
+ callback(1);
166
+ return 1;
167
+ }
168
+ let vitestConfigFile;
169
+ let projectVitestConfig = null;
170
+ if (config) {
171
+ vitestConfigFile = config;
172
+ } else {
173
+ const projectVitestConfigPaths = [
174
+ pathResolve(process.cwd(), 'vitest.config.ts'),
175
+ pathResolve(process.cwd(), 'vitest.config.mts'),
176
+ pathResolve(process.cwd(), 'vitest.config.js'),
177
+ pathResolve(process.cwd(), 'vitest.config.mjs'),
178
+ pathResolve(process.cwd(), 'vitest.config.cjs')
179
+ ];
180
+ const existingConfigPath = projectVitestConfigPaths.find((configPath)=>existsSync(configPath));
181
+ if (existingConfigPath) {
182
+ vitestConfigFile = existingConfigPath;
183
+ if (debug) {
184
+ log(`Using project Vitest config file: ${vitestConfigFile}`, 'info', quiet);
185
+ }
186
+ } else {
187
+ projectVitestConfig = LexConfig.config.vitest || null;
188
+ const lexDir = LexConfig.getLexDir();
189
+ const lexVitestConfig = pathResolve(lexDir, 'vitest.config.mjs');
190
+ if (debug) {
191
+ log(`Looking for Vitest config at: ${lexVitestConfig}`, 'info', quiet);
192
+ log(`File exists: ${existsSync(lexVitestConfig)}`, 'info', quiet);
193
+ }
194
+ if (existsSync(lexVitestConfig)) {
195
+ vitestConfigFile = lexVitestConfig;
196
+ if (projectVitestConfig && Object.keys(projectVitestConfig).length > 0) {
197
+ if (debug) {
198
+ log(`Using Lex Vitest config with project Vitest config from lex.config.cjs: ${vitestConfigFile}`, 'info', quiet);
199
+ }
200
+ } else if (debug) {
201
+ log(`Using Lex Vitest config (no project Vitest config found): ${vitestConfigFile}`, 'info', quiet);
202
+ }
203
+ } else if (debug) {
204
+ log('No Vitest config found in project or Lex', 'warn', quiet);
205
+ }
206
+ }
207
+ }
208
+ if (showConfig) {
209
+ if (vitestConfigFile) {
210
+ const resolvedConfig = await import(vitestConfigFile);
211
+ log(JSON.stringify(resolvedConfig.default ?? resolvedConfig, null, 2), 'info', quiet);
212
+ } else {
213
+ log(JSON.stringify({
214
+ test: projectVitestConfig ?? {}
215
+ }, null, 2), 'info', quiet);
216
+ }
217
+ callback(0);
218
+ return 0;
219
+ }
220
+ const vitestSetupFile = setup || pathResolve(process.cwd(), 'vitest.setup.js');
221
+ const vitestArgs = [];
222
+ const vitestOptions = [];
223
+ const reporters = new Set();
224
+ const filters = [];
225
+ const watchMode = Boolean(watch || watchAll);
226
+ const listMode = Boolean(listTests);
227
+ if (listMode) {
228
+ vitestArgs.push('list');
229
+ } else if (watchMode) {
230
+ vitestArgs.push('watch');
231
+ } else {
232
+ vitestArgs.push('run');
233
+ }
234
+ if (vitestConfigFile) {
235
+ vitestOptions.push('--config', vitestConfigFile);
236
+ }
237
+ if (bail) {
238
+ vitestOptions.push('--bail', '1');
239
+ }
240
+ if (changedFilesWithAncestor) {
241
+ vitestOptions.push('--changed');
242
+ }
243
+ if (changedSince) {
244
+ vitestOptions.push('--changed', changedSince);
245
+ }
246
+ if (ci) {
247
+ vitestOptions.push('--run');
248
+ }
249
+ if (collectCoverageFrom) {
250
+ vitestOptions.push('--coverage', '--coverage.include', collectCoverageFrom);
251
+ }
252
+ if (debug) {
253
+ vitestOptions.push('--inspect');
254
+ }
255
+ if (detectOpenHandles) {
256
+ reporters.add('hanging-process');
257
+ }
258
+ const environmentName = environment || env;
259
+ if (environmentName) {
260
+ vitestOptions.push('--environment', environmentName);
261
+ }
262
+ if (errorOnDeprecated) {
263
+ log('Vitest does not support --errorOnDeprecated; option ignored.', 'warn', quiet);
264
+ }
265
+ if (expand) {
266
+ vitestOptions.push('--expandSnapshotDiff');
267
+ }
268
+ if (forceExit) {
269
+ log('Vitest does not support --forceExit; option ignored.', 'warn', quiet);
270
+ }
271
+ if (lastCommit) {
272
+ vitestOptions.push('--changed');
273
+ }
274
+ if (logHeapUsage) {
275
+ vitestOptions.push('--logHeapUsage');
276
+ }
277
+ if (maxWorkers) {
278
+ vitestOptions.push('--maxWorkers', maxWorkers);
279
+ }
280
+ if (noStackTrace) {
281
+ log('Vitest does not support --noStackTrace; option ignored.', 'warn', quiet);
282
+ }
283
+ if (notify) {
284
+ log('Vitest does not support --notify; option ignored.', 'warn', quiet);
285
+ }
286
+ if (onlyChanged) {
287
+ vitestOptions.push('--changed');
288
+ }
289
+ const shouldWriteJson = json || useAnalyze || useDebug || Boolean(outputFile);
290
+ if (shouldWriteJson) {
291
+ tempOutputFile = outputFile || '.lex-test-results.json';
292
+ vitestOptions.push('--outputFile', tempOutputFile);
293
+ reporters.add('json');
294
+ }
295
+ if (passWithNoTests) {
296
+ vitestOptions.push('--passWithNoTests');
297
+ }
298
+ if (runInBand) {
299
+ vitestOptions.push('--no-file-parallelism', '--maxWorkers', '1');
300
+ }
301
+ if (silent) {
302
+ vitestOptions.push('--silent');
303
+ }
304
+ if (testLocationInResults) {
305
+ vitestOptions.push('--includeTaskLocation');
306
+ }
307
+ if (testNamePattern) {
308
+ vitestOptions.push('--testNamePattern', testNamePattern);
309
+ }
310
+ if (testPathPattern) {
311
+ filters.push(testPathPattern);
312
+ }
313
+ if (useStderr) {
314
+ log('Vitest does not support --useStderr; option ignored.', 'warn', quiet);
315
+ }
316
+ if (verbose) {
317
+ reporters.add('verbose');
318
+ }
319
+ if (removeCache || clearCache) {
320
+ vitestOptions.push('--clearCache');
321
+ }
322
+ if (update) {
323
+ vitestOptions.push('--update');
324
+ }
325
+ if (watch) {
326
+ filters.push(watch);
327
+ }
328
+ if (args) {
329
+ vitestOptions.push(...args);
330
+ }
331
+ if (files && files.length > 0) {
332
+ filters.push(...files.filter((file)=>!/\.e2e\./.test(file)));
333
+ }
334
+ if (reporters.size > 0) {
335
+ const reporterList = Array.from(reporters);
336
+ if (reporterList.includes('json') && !reporterList.includes('verbose')) {
337
+ reporterList.unshift('default');
338
+ }
339
+ reporterList.forEach((reporter)=>vitestOptions.push('--reporter', reporter));
340
+ }
341
+ const finalArgs = [
342
+ ...vitestArgs,
343
+ ...vitestOptions,
344
+ ...filters
345
+ ];
346
+ if (debug) {
347
+ log(`Vitest options: ${finalArgs.join(' ')}`, 'info', quiet);
348
+ log(`NODE_OPTIONS: ${nodeOptions}`, 'info', quiet);
349
+ }
350
+ if (vitestSetupFile && existsSync(vitestSetupFile)) {
351
+ processEnv.LEX_VITEST_SETUP = vitestSetupFile;
352
+ }
353
+ await execa(vitestPath, finalArgs, {
354
+ encoding: 'utf8',
355
+ env: processEnv,
356
+ stdio: 'inherit'
357
+ });
358
+ if (useAnalyze) {
359
+ spinner.start('AI is analyzing test coverage and suggesting improvements...');
360
+ try {
361
+ const testResults = processTestResults(tempOutputFile);
362
+ const filePatterns = getTestFilePatterns(testPathPattern);
363
+ await aiFunction({
364
+ context: true,
365
+ prompt: `Analyze these Vitest test results and suggest test coverage improvements:
367
366
 
368
367
  ${JSON.stringify(testResults, null, 2)}
369
368
 
@@ -374,24 +373,91 @@ Please provide:
374
373
  2. Suggestions for improving test cases
375
374
  3. Recommendations for additional integration test scenarios
376
375
  4. Best practices for increasing test effectiveness`,
377
- quiet,
378
- task: 'optimize'
379
- });
380
- spinner.succeed('AI test analysis complete');
381
- } catch (aiError) {
382
- spinner.fail('Could not generate AI test analysis');
383
- if (!quiet) {
384
- // eslint-disable-next-line no-console
385
- console.error('AI analysis error:', aiError);
376
+ quiet,
377
+ task: 'optimize'
378
+ });
379
+ spinner.succeed('AI test analysis complete');
380
+ } catch (aiError) {
381
+ spinner.fail('Could not generate AI test analysis');
382
+ if (!quiet) {
383
+ // eslint-disable-next-line no-console
384
+ console.error('AI analysis error:', aiError);
385
+ }
386
386
  }
387
387
  }
388
388
  }
389
+ if (runE2E) {
390
+ const projectPlaywrightBin = pathResolve(process.cwd(), 'node_modules/.bin/playwright');
391
+ let playwrightPath;
392
+ if (existsSync(projectPlaywrightBin)) {
393
+ playwrightPath = projectPlaywrightBin;
394
+ } else {
395
+ playwrightPath = resolveBinaryPath('playwright');
396
+ }
397
+ if (!playwrightPath) {
398
+ log(`\n${cliName} Error: Playwright binary not found in Lex's node_modules or monorepo root`, 'error', quiet);
399
+ log('Please install @playwright/test to run E2E tests.', 'info', quiet);
400
+ callback(1);
401
+ return 1;
402
+ }
403
+ const e2eConfigPaths = [
404
+ pathResolve(process.cwd(), 'playwright.config.ts'),
405
+ pathResolve(process.cwd(), 'playwright.config.mts'),
406
+ pathResolve(process.cwd(), 'playwright.config.js'),
407
+ pathResolve(process.cwd(), 'playwright.config.mjs'),
408
+ pathResolve(process.cwd(), 'playwright.config.cjs')
409
+ ];
410
+ const playwrightConfigFile = e2eConfig || e2eConfigPaths.find((configPath)=>existsSync(configPath));
411
+ const playwrightArgs = [
412
+ 'test'
413
+ ];
414
+ if (playwrightConfigFile) {
415
+ playwrightArgs.push('--config', playwrightConfigFile);
416
+ }
417
+ if (listTests) {
418
+ playwrightArgs.push('--list');
419
+ }
420
+ if (passWithNoTests) {
421
+ playwrightArgs.push('--pass-with-no-tests');
422
+ }
423
+ if (testNamePattern) {
424
+ playwrightArgs.push('--grep', testNamePattern);
425
+ }
426
+ if (maxWorkers) {
427
+ playwrightArgs.push('--workers', maxWorkers);
428
+ }
429
+ if (runInBand) {
430
+ playwrightArgs.push('--workers', '1');
431
+ }
432
+ if (update) {
433
+ playwrightArgs.push('--update-snapshots');
434
+ }
435
+ if (testPathPattern) {
436
+ playwrightArgs.push(testPathPattern);
437
+ }
438
+ if (files && files.length > 0) {
439
+ playwrightArgs.push(...files.filter((file)=>/\.e2e\./.test(file)));
440
+ }
441
+ if (debug) {
442
+ log(`Playwright options: ${playwrightArgs.join(' ')}`, 'info', quiet);
443
+ }
444
+ if (useGenerate || useAnalyze || useDebug) {
445
+ log('AI test helpers currently apply to Vitest unit test runs only; skipping them for Playwright E2E.', 'warn', quiet);
446
+ }
447
+ await execa(playwrightPath, playwrightArgs, {
448
+ encoding: 'utf8',
449
+ env: processEnv,
450
+ stdio: 'inherit'
451
+ });
452
+ }
453
+ spinner.succeed('Testing completed!');
389
454
  callback(0);
390
455
  return 0;
391
456
  } catch (error) {
392
- log(`\n${cliName} Error: Check for unit test errors and/or coverage.`, 'error', quiet);
457
+ const errorMessage = error instanceof Error ? error.message : String(error);
458
+ log(`\n${cliName} Error: Check for test failures and coverage issues.`, 'error', quiet);
393
459
  spinner.fail('Testing failed!');
394
- if (useDebug) {
460
+ if (useDebug && runUnit) {
395
461
  spinner.start('AI is analyzing test failures...');
396
462
  try {
397
463
  const testResults = processTestResults(tempOutputFile);
@@ -399,7 +465,7 @@ Please provide:
399
465
  context: true,
400
466
  prompt: `Debug these failed Vitest tests and suggest fixes:
401
467
 
402
- ${JSON.stringify(error.message, null, 2)}
468
+ ${JSON.stringify(errorMessage, null, 2)}
403
469
 
404
470
  Test results: ${JSON.stringify(testResults, null, 2)}
405
471
 
@@ -419,6 +485,8 @@ Please provide:
419
485
  console.error('AI debugging error:', aiError);
420
486
  }
421
487
  }
488
+ } else if (useDebug && runE2E) {
489
+ log('AI debugging assistance currently supports Vitest unit runs only.', 'warn', quiet);
422
490
  }
423
491
  callback(1);
424
492
  return 1;
@@ -426,4 +494,4 @@ Please provide:
426
494
  };
427
495
  export default test;
428
496
 
429
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21tYW5kcy90ZXN0L3Rlc3QudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTgtUHJlc2VudCwgTml0cm9nZW4gTGFicywgSW5jLlxuICogQ29weXJpZ2h0cyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSB0aGUgYWNjb21wYW55aW5nIExJQ0VOU0UgZmlsZSBmb3IgdGVybXMuXG4gKi9cbmltcG9ydCB7ZXhlY2F9IGZyb20gJ2V4ZWNhJztcbmltcG9ydCB7ZXhpc3RzU3luYywgcmVhZEZpbGVTeW5jfSBmcm9tICdmcyc7XG5pbXBvcnQge3N5bmMgYXMgZ2xvYlN5bmN9IGZyb20gJ2dsb2InO1xuaW1wb3J0IHtyZXNvbHZlIGFzIHBhdGhSZXNvbHZlfSBmcm9tICdwYXRoJztcblxuaW1wb3J0IHtMZXhDb25maWcsIGdldFR5cGVTY3JpcHRDb25maWdQYXRofSBmcm9tICcuLi8uLi9MZXhDb25maWcuanMnO1xuaW1wb3J0IHtjcmVhdGVTcGlubmVyfSBmcm9tICcuLi8uLi91dGlscy9hcHAuanMnO1xuaW1wb3J0IHtyZXNvbHZlQmluYXJ5UGF0aH0gZnJvbSAnLi4vLi4vdXRpbHMvZmlsZS5qcyc7XG5pbXBvcnQge2xvZ30gZnJvbSAnLi4vLi4vdXRpbHMvbG9nLmpzJztcbmltcG9ydCB7YWlGdW5jdGlvbn0gZnJvbSAnLi4vYWkvYWkuanMnO1xuXG5jb25zdCBkZXRlY3RFU00gPSAoY3dkOiBzdHJpbmcpOiBib29sZWFuID0+IHtcbiAgY29uc3QgcGFja2FnZUpzb25QYXRoID0gcGF0aFJlc29sdmUoY3dkLCAncGFja2FnZS5qc29uJyk7XG5cbiAgaWYoZXhpc3RzU3luYyhwYWNrYWdlSnNvblBhdGgpKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBhY2thZ2VKc29uQ29udGVudCA9IHJlYWRGaWxlU3luYyhwYWNrYWdlSnNvblBhdGgsICd1dGY4Jyk7XG4gICAgICBjb25zdCBwYWNrYWdlSnNvbiA9IEpTT04ucGFyc2UocGFja2FnZUpzb25Db250ZW50KTtcbiAgICAgIHJldHVybiBwYWNrYWdlSnNvbi50eXBlID09PSAnbW9kdWxlJztcbiAgICB9IGNhdGNoKF9lcnJvcikge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVzdE9wdGlvbnMge1xuICByZWFkb25seSBhbmFseXplPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgYWlEZWJ1Zz86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGFpR2VuZXJhdGU/OiBib29sZWFuO1xuICByZWFkb25seSBhaUFuYWx5emU/OiBib29sZWFuO1xuICByZWFkb25seSBiYWlsPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgY2hhbmdlZEZpbGVzV2l0aEFuY2VzdG9yPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgY2hhbmdlZFNpbmNlPzogc3RyaW5nO1xuICByZWFkb25seSBjaT86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGNsZWFyQ2FjaGU/OiBib29sZWFuO1xuICByZWFkb25seSBjbGlOYW1lPzogc3RyaW5nO1xuICByZWFkb25seSBjb2xsZWN0Q292ZXJhZ2VGcm9tPzogc3RyaW5nO1xuICByZWFkb25seSBjb2xvcnM/OiBib29sZWFuO1xuICByZWFkb25seSBjb25maWc/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGRlYnVnPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgZGVidWdUZXN0cz86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGRldGVjdE9wZW5IYW5kbGVzPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgZW52aXJvbm1lbnQ/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGVudj86IHN0cmluZztcbiAgcmVhZG9ubHkgZXJyb3JPbkRlcHJlY2F0ZWQ/OiBib29sZWFuO1xuICByZWFkb25seSBleHBhbmQ/OiBib29sZWFuO1xuICByZWFkb25seSBmb3JjZUV4aXQ/OiBib29sZWFuO1xuICByZWFkb25seSBnZW5lcmF0ZT86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGpzb24/OiBib29sZWFuO1xuICByZWFkb25seSBsYXN0Q29tbWl0PzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgbGlzdFRlc3RzPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgbG9nSGVhcFVzYWdlPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgbWF4V29ya2Vycz86IHN0cmluZztcbiAgcmVhZG9ubHkgbm9TdGFja1RyYWNlPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgbm90aWZ5PzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgb25seUNoYW5nZWQ/OiBib29sZWFuO1xuICByZWFkb25seSBvdXRwdXRGaWxlPzogc3RyaW5nO1xuICByZWFkb25seSBwYXNzV2l0aE5vVGVzdHM/OiBib29sZWFuO1xuICByZWFkb25seSBxdWlldD86IGJvb2xlYW47XG4gIHJlYWRvbmx5IHJlbW92ZUNhY2hlPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgcnVuSW5CYW5kPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgc2V0dXA/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHNob3dDb25maWc/OiBib29sZWFuO1xuICByZWFkb25seSBzaWxlbnQ/OiBib29sZWFuO1xuICByZWFkb25seSB0ZXN0TG9jYXRpb25JblJlc3VsdHM/OiBib29sZWFuO1xuICByZWFkb25seSB0ZXN0TmFtZVBhdHRlcm4/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHRlc3RQYXRoUGF0dGVybj86IHN0cmluZztcbiAgcmVhZG9ubHkgdXBkYXRlPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgdXNlU3RkZXJyPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgdmVyYm9zZT86IGJvb2xlYW47XG4gIHJlYWRvbmx5IHdhdGNoPzogc3RyaW5nO1xuICByZWFkb25seSB3YXRjaEFsbD86IGJvb2xlYW47XG59XG5cbmV4cG9ydCB0eXBlIFRlc3RDYWxsYmFjayA9IHR5cGVvZiBwcm9jZXNzLmV4aXQ7XG5cbmNvbnN0IGRlZmF1bHRFeGl0ID0gKChjb2RlPzogbnVtYmVyKSA9PiB7XG4gIGlmKHByb2Nlc3MuZW52LlZJVEVTVCB8fCBwcm9jZXNzLmVudi5WSVRFU1RfV09SS0VSX0lEIHx8IHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAndGVzdCcpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkIGFzIG5ldmVyO1xuICB9XG5cbiAgcHJvY2Vzcy5leGl0KGNvZGUpO1xufSkgYXMgdHlwZW9mIHByb2Nlc3MuZXhpdDtcblxuZXhwb3J0IGNvbnN0IGdldFRlc3RGaWxlUGF0dGVybnMgPSAodGVzdFBhdGhQYXR0ZXJuPzogc3RyaW5nKTogc3RyaW5nW10gPT4ge1xuICBjb25zdCBkZWZhdWx0UGF0dGVybnMgPSBbJyoqLyoudGVzdC4qJywgJyoqLyouc3BlYy4qJywgJyoqLyouaW50ZWdyYXRpb24uKiddO1xuXG4gIGlmKCF0ZXN0UGF0aFBhdHRlcm4pIHtcbiAgICByZXR1cm4gZGVmYXVsdFBhdHRlcm5zO1xuICB9XG5cbiAgcmV0dXJuIFt0ZXN0UGF0aFBhdHRlcm5dO1xufTtcblxuY29uc3QgZmluZFVuY292ZXJlZFNvdXJjZUZpbGVzID0gKCk6IHN0cmluZ1tdID0+IHtcbiAgY29uc3Qgc291cmNlRmlsZXMgPSBnbG9iU3luYygnc3JjLyoqLyoue3RzLHRzeCxqcyxqc3h9Jywge1xuICAgIGN3ZDogcHJvY2Vzcy5jd2QoKSxcbiAgICBpZ25vcmU6IFsnKiovbm9kZV9tb2R1bGVzLyoqJywgJyoqL2Rpc3QvKionLCAnKiovbGliLyoqJywgJyoqLyoudGVzdC4qJywgJyoqLyouc3BlYy4qJ11cbiAgfSk7XG5cbiAgY29uc3QgdGVzdEZpbGVzID0gZ2xvYlN5bmMoJyoqLyoue3Rlc3Qsc3BlY30ue3RzLHRzeCxqcyxqc3h9Jywge1xuICAgIGN3ZDogcHJvY2Vzcy5jd2QoKSxcbiAgICBpZ25vcmU6IFsnKiovbm9kZV9tb2R1bGVzLyoqJywgJyoqL2Rpc3QvKionLCAnKiovbGliLyoqJ11cbiAgfSk7XG5cbiAgcmV0dXJuIHNvdXJjZUZpbGVzLmZpbHRlcigoc291cmNlRmlsZSkgPT4ge1xuICAgIGNvbnN0IGJhc2VOYW1lID0gc291cmNlRmlsZS5yZXBsYWNlKC9cXC5bXi8uXSskLywgJycpO1xuICAgIHJldHVybiAhdGVzdEZpbGVzLnNvbWUoKHRlc3RGaWxlKSA9PiB0ZXN0RmlsZS5pbmNsdWRlcyhiYXNlTmFtZSkpO1xuICB9KTtcbn07XG5cbmNvbnN0IHByb2Nlc3NUZXN0UmVzdWx0cyA9IChvdXRwdXRGaWxlPzogc3RyaW5nKTogYW55ID0+IHtcbiAgaWYoIW91dHB1dEZpbGUpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHRyeSB7XG4gICAgY29uc3QgY29udGVudCA9IHJlYWRGaWxlU3luYyhvdXRwdXRGaWxlLCAndXRmLTgnKTtcbiAgICByZXR1cm4gSlNPTi5wYXJzZShjb250ZW50KTtcbiAgfSBjYXRjaChfZXJyb3IpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHRlc3QgPSBhc3luYyAoXG4gIG9wdGlvbnM6IFRlc3RPcHRpb25zLFxuICBhcmdzPzogc3RyaW5nW10sXG4gIGZpbGVzT3JDYWxsYmFjaz86IHN0cmluZ1tdIHwgVGVzdENhbGxiYWNrLFxuICBjYWxsYmFja1BhcmFtPzogVGVzdENhbGxiYWNrXG4pOiBQcm9taXNlPG51bWJlcj4gPT4ge1xuICAvLyBCYWNrd2FyZC1jb21wYXQgYXJndW1lbnQgbm9ybWFsaXphdGlvbjogYWxsb3cgY2FsbGJhY2sgYXMgdGhpcmQgcGFyYW1cbiAgbGV0IGZpbGVzOiBzdHJpbmdbXSB8IHVuZGVmaW5lZDtcbiAgbGV0IGNhbGxiYWNrOiBUZXN0Q2FsbGJhY2sgPSBkZWZhdWx0RXhpdDtcblxuICBpZih0eXBlb2YgZmlsZXNPckNhbGxiYWNrID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2FsbGJhY2sgPSBmaWxlc09yQ2FsbGJhY2sgYXMgVGVzdENhbGxiYWNrO1xuICB9IGVsc2Uge1xuICAgIGZpbGVzID0gZmlsZXNPckNhbGxiYWNrIGFzIHN0cmluZ1tdIHwgdW5kZWZpbmVkO1xuICAgIGNhbGxiYWNrID0gY2FsbGJhY2tQYXJhbSB8fCBkZWZhdWx0RXhpdDtcbiAgfVxuICBjb25zdCB7XG4gICAgYW5hbHl6ZSA9IGZhbHNlLFxuICAgIGFpQW5hbHl6ZSA9IGZhbHNlLFxuICAgIGFpRGVidWcgPSBmYWxzZSxcbiAgICBhaUdlbmVyYXRlID0gZmFsc2UsXG4gICAgYmFpbCxcbiAgICBjaGFuZ2VkRmlsZXNXaXRoQW5jZXN0b3IsXG4gICAgY2hhbmdlZFNpbmNlLFxuICAgIGNpLFxuICAgIGNsZWFyQ2FjaGUsXG4gICAgY2xpTmFtZSA9ICdMZXgnLFxuICAgIGNvbGxlY3RDb3ZlcmFnZUZyb20sXG4gICAgY29sb3JzLFxuICAgIGNvbmZpZyxcbiAgICBkZWJ1ZyA9IGZhbHNlLFxuICAgIGRlYnVnVGVzdHMgPSBmYWxzZSxcbiAgICBkZXRlY3RPcGVuSGFuZGxlcyxcbiAgICBlbnZpcm9ubWVudCxcbiAgICBlbnYsXG4gICAgZXJyb3JPbkRlcHJlY2F0ZWQsXG4gICAgZXhwYW5kLFxuICAgIGZvcmNlRXhpdCxcbiAgICBnZW5lcmF0ZSA9IGZhbHNlLFxuICAgIGpzb24sXG4gICAgbGFzdENvbW1pdCxcbiAgICBsaXN0VGVzdHMsXG4gICAgbG9nSGVhcFVzYWdlLFxuICAgIG1heFdvcmtlcnMsXG4gICAgbm9TdGFja1RyYWNlLFxuICAgIG5vdGlmeSxcbiAgICBvbmx5Q2hhbmdlZCxcbiAgICBvdXRwdXRGaWxlLFxuICAgIHBhc3NXaXRoTm9UZXN0cyxcbiAgICBxdWlldCxcbiAgICByZW1vdmVDYWNoZSxcbiAgICBydW5JbkJhbmQsXG4gICAgc2V0dXAsXG4gICAgc2hvd0NvbmZpZyxcbiAgICBzaWxlbnQsXG4gICAgdGVzdExvY2F0aW9uSW5SZXN1bHRzLFxuICAgIHRlc3ROYW1lUGF0dGVybixcbiAgICB0ZXN0UGF0aFBhdHRlcm4sXG4gICAgdXBkYXRlLFxuICAgIHVzZVN0ZGVycixcbiAgICB2ZXJib3NlLFxuICAgIHdhdGNoLFxuICAgIHdhdGNoQWxsXG4gIH0gPSBvcHRpb25zO1xuXG4gIGNvbnN0IHVzZUdlbmVyYXRlID0gZ2VuZXJhdGUgfHwgYWlHZW5lcmF0ZTtcbiAgY29uc3QgdXNlQW5hbHl6ZSA9IGFuYWx5emUgfHwgYWlBbmFseXplO1xuICBjb25zdCB1c2VEZWJ1ZyA9IGRlYnVnVGVzdHMgfHwgYWlEZWJ1ZztcblxuICBsb2coYCR7Y2xpTmFtZX0gdGVzdGluZy4uLmAsICdpbmZvJywgcXVpZXQpO1xuXG4gIGNvbnN0IHNwaW5uZXIgPSBjcmVhdGVTcGlubmVyKHF1aWV0KTtcblxuICBhd2FpdCBMZXhDb25maWcucGFyc2VDb25maWcob3B0aW9ucyk7XG5cbiAgY29uc3Qge3VzZVR5cGVzY3JpcHR9ID0gTGV4Q29uZmlnLmNvbmZpZztcblxuICBpZih1c2VUeXBlc2NyaXB0KSB7XG4gICAgY29uc3QgdGVzdENvbmZpZ1BhdGggPSBnZXRUeXBlU2NyaXB0Q29uZmlnUGF0aCgndHNjb25maWcudGVzdC5qc29uJyk7XG4gICAgaWYoZXhpc3RzU3luYyh0ZXN0Q29uZmlnUGF0aCkpIHtcbiAgICAgIGxvZygnVXNpbmcgdHNjb25maWcudGVzdC5qc29uIGZvciB0ZXN0aW5nLi4uJywgJ2luZm8nLCBxdWlldCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIExleENvbmZpZy5jaGVja1Rlc3RUeXBlc2NyaXB0Q29uZmlnKCk7XG4gICAgfVxuICB9XG5cbiAgaWYodXNlR2VuZXJhdGUpIHtcbiAgICBzcGlubmVyLnN0YXJ0KCdBSSBpcyBhbmFseXppbmcgY29kZSB0byBnZW5lcmF0ZSB0ZXN0IGNhc2VzLi4uJyk7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgdW5jb3ZlcmVkRmlsZXMgPSBmaW5kVW5jb3ZlcmVkU291cmNlRmlsZXMoKTtcblxuICAgICAgaWYodW5jb3ZlcmVkRmlsZXMubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCB0YXJnZXRGaWxlID0gdW5jb3ZlcmVkRmlsZXNbMF07XG5cbiAgICAgICAgYXdhaXQgYWlGdW5jdGlvbih7XG4gICAgICAgICAgY29udGV4dDogdHJ1ZSxcbiAgICAgICAgICBmaWxlOiB0YXJnZXRGaWxlLFxuICAgICAgICAgIHByb21wdDogYEdlbmVyYXRlIFZpdGVzdCB1bml0IHRlc3RzIGZvciB0aGlzIGZpbGU6ICR7dGFyZ2V0RmlsZX1cXG5cXG4ke3JlYWRGaWxlU3luYyh0YXJnZXRGaWxlLCAndXRmLTgnKX1cXG5cXG5QbGVhc2UgY3JlYXRlIGNvbXByZWhlbnNpdmUgdGVzdHMgdGhhdCBjb3ZlciB0aGUgbWFpbiBmdW5jdGlvbmFsaXR5LiBJbmNsdWRlIHRlc3QgZml4dHVyZXMgYW5kIG1vY2tzIHdoZXJlIG5lY2Vzc2FyeS5gLFxuICAgICAgICAgIHF1aWV0LFxuICAgICAgICAgIHRhc2s6ICd0ZXN0J1xuICAgICAgICB9KTtcblxuICAgICAgICBzcGlubmVyLnN1Y2NlZWQoYEFJIHRlc3QgZ2VuZXJhdGlvbiBzdWdnZXN0aW9ucyBwcm92aWRlZCBmb3IgJHt0YXJnZXRGaWxlfWApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3Bpbm5lci5zdWNjZWVkKCdBbGwgc291cmNlIGZpbGVzIGFwcGVhciB0byBoYXZlIGNvcnJlc3BvbmRpbmcgdGVzdCBmaWxlcycpO1xuICAgICAgfVxuICAgIH0gY2F0Y2goYWlFcnJvcikge1xuICAgICAgc3Bpbm5lci5mYWlsKCdDb3VsZCBub3QgZ2VuZXJhdGUgQUkgdGVzdCBzdWdnZXN0aW9ucycpO1xuICAgICAgaWYoIXF1aWV0KSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ0FJIHRlc3QgZ2VuZXJhdGlvbiBlcnJvcjonLCBhaUVycm9yKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb25zdCBwcm9qZWN0Vml0ZXN0QmluID0gcGF0aFJlc29sdmUocHJvY2Vzcy5jd2QoKSwgJ25vZGVfbW9kdWxlcy8uYmluL3ZpdGVzdCcpO1xuICBsZXQgdml0ZXN0UGF0aDogc3RyaW5nO1xuXG4gIGlmKGV4aXN0c1N5bmMocHJvamVjdFZpdGVzdEJpbikpIHtcbiAgICB2aXRlc3RQYXRoID0gcHJvamVjdFZpdGVzdEJpbjtcbiAgfSBlbHNlIHtcbiAgICB2aXRlc3RQYXRoID0gcmVzb2x2ZUJpbmFyeVBhdGgoJ3ZpdGVzdCcpO1xuICB9XG5cbiAgaWYoIXZpdGVzdFBhdGgpIHtcbiAgICBsb2coYFxcbiR7Y2xpTmFtZX0gRXJyb3I6IFZpdGVzdCBiaW5hcnkgbm90IGZvdW5kIGluIExleCdzIG5vZGVfbW9kdWxlcyBvciBtb25vcmVwbyByb290YCwgJ2Vycm9yJywgcXVpZXQpO1xuICAgIGxvZygnUGxlYXNlIHJlaW5zdGFsbCBMZXggb3IgY2hlY2sgeW91ciBpbnN0YWxsYXRpb24uJywgJ2luZm8nLCBxdWlldCk7XG4gICAgcmV0dXJuIDE7XG4gIH1cblxuICBsZXQgdml0ZXN0Q29uZmlnRmlsZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBsZXQgcHJvamVjdFZpdGVzdENvbmZpZzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCBudWxsID0gbnVsbDtcblxuICBpZihjb25maWcpIHtcbiAgICB2aXRlc3RDb25maWdGaWxlID0gY29uZmlnO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IHByb2plY3RWaXRlc3RDb25maWdQYXRocyA9IFtcbiAgICAgIHBhdGhSZXNvbHZlKHByb2Nlc3MuY3dkKCksICd2aXRlc3QuY29uZmlnLnRzJyksXG4gICAgICBwYXRoUmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCAndml0ZXN0LmNvbmZpZy5tdHMnKSxcbiAgICAgIHBhdGhSZXNvbHZlKHByb2Nlc3MuY3dkKCksICd2aXRlc3QuY29uZmlnLmpzJyksXG4gICAgICBwYXRoUmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCAndml0ZXN0LmNvbmZpZy5tanMnKSxcbiAgICAgIHBhdGhSZXNvbHZlKHByb2Nlc3MuY3dkKCksICd2aXRlc3QuY29uZmlnLmNqcycpXG4gICAgXTtcbiAgICBjb25zdCBleGlzdGluZ0NvbmZpZ1BhdGggPSBwcm9qZWN0Vml0ZXN0Q29uZmlnUGF0aHMuZmluZCgoY29uZmlnUGF0aCkgPT4gZXhpc3RzU3luYyhjb25maWdQYXRoKSk7XG5cbiAgICBpZihleGlzdGluZ0NvbmZpZ1BhdGgpIHtcbiAgICAgIHZpdGVzdENvbmZpZ0ZpbGUgPSBleGlzdGluZ0NvbmZpZ1BhdGg7XG4gICAgICBpZihkZWJ1Zykge1xuICAgICAgICBsb2coYFVzaW5nIHByb2plY3QgVml0ZXN0IGNvbmZpZyBmaWxlOiAke3ZpdGVzdENvbmZpZ0ZpbGV9YCwgJ2luZm8nLCBxdWlldCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE5vIFZpdGVzdCBjb25maWcgZmlsZSBleGlzdHMgaW4gdGhlIHByb2plY3RcbiAgICAgIC8vIENoZWNrIGlmIHRoZXJlJ3MgYSBWaXRlc3QgY29uZmlnIGluIGxleC5jb25maWcuY2pzXG4gICAgICBwcm9qZWN0Vml0ZXN0Q29uZmlnID0gTGV4Q29uZmlnLmNvbmZpZy52aXRlc3QgfHwgbnVsbDtcblxuICAgICAgY29uc3QgbGV4RGlyID0gTGV4Q29uZmlnLmdldExleERpcigpO1xuICAgICAgY29uc3QgbGV4Vml0ZXN0Q29uZmlnID0gcGF0aFJlc29sdmUobGV4RGlyLCAndml0ZXN0LmNvbmZpZy5tanMnKTtcblxuICAgICAgaWYoZGVidWcpIHtcbiAgICAgICAgbG9nKGBMb29raW5nIGZvciBWaXRlc3QgY29uZmlnIGF0OiAke2xleFZpdGVzdENvbmZpZ31gLCAnaW5mbycsIHF1aWV0KTtcbiAgICAgICAgbG9nKGBGaWxlIGV4aXN0czogJHtleGlzdHNTeW5jKGxleFZpdGVzdENvbmZpZyl9YCwgJ2luZm8nLCBxdWlldCk7XG4gICAgICB9XG5cbiAgICAgIGlmKGV4aXN0c1N5bmMobGV4Vml0ZXN0Q29uZmlnKSkge1xuICAgICAgICB2aXRlc3RDb25maWdGaWxlID0gbGV4Vml0ZXN0Q29uZmlnO1xuICAgICAgICBpZihwcm9qZWN0Vml0ZXN0Q29uZmlnICYmIE9iamVjdC5rZXlzKHByb2plY3RWaXRlc3RDb25maWcpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBpZihkZWJ1Zykge1xuICAgICAgICAgICAgbG9nKGBVc2luZyBMZXggVml0ZXN0IGNvbmZpZyB3aXRoIHByb2plY3QgVml0ZXN0IGNvbmZpZyBmcm9tIGxleC5jb25maWcuY2pzOiAke3ZpdGVzdENvbmZpZ0ZpbGV9YCwgJ2luZm8nLCBxdWlldCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYoZGVidWcpIHtcbiAgICAgICAgICBsb2coYFVzaW5nIExleCBWaXRlc3QgY29uZmlnIChubyBwcm9qZWN0IFZpdGVzdCBjb25maWcgZm91bmQpOiAke3ZpdGVzdENvbmZpZ0ZpbGV9YCwgJ2luZm8nLCBxdWlldCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmKGRlYnVnKSB7XG4gICAgICAgICAgbG9nKCdObyBWaXRlc3QgY29uZmlnIGZvdW5kIGluIHByb2plY3Qgb3IgTGV4JywgJ3dhcm4nLCBxdWlldCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZihzaG93Q29uZmlnKSB7XG4gICAgaWYodml0ZXN0Q29uZmlnRmlsZSkge1xuICAgICAgY29uc3QgcmVzb2x2ZWRDb25maWcgPSBhd2FpdCBpbXBvcnQodml0ZXN0Q29uZmlnRmlsZSk7XG4gICAgICBsb2coSlNPTi5zdHJpbmdpZnkocmVzb2x2ZWRDb25maWcuZGVmYXVsdCA/PyByZXNvbHZlZENvbmZpZywgbnVsbCwgMiksICdpbmZvJywgcXVpZXQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsb2coSlNPTi5zdHJpbmdpZnkoe3Rlc3Q6IHByb2plY3RWaXRlc3RDb25maWcgPz8ge319LCBudWxsLCAyKSwgJ2luZm8nLCBxdWlldCk7XG4gICAgfVxuICAgIGNhbGxiYWNrKDApO1xuICAgIHJldHVybiAwO1xuICB9XG5cbiAgY29uc3Qgdml0ZXN0U2V0dXBGaWxlOiBzdHJpbmcgPSBzZXR1cCB8fCBwYXRoUmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCAndml0ZXN0LnNldHVwLmpzJyk7XG4gIGNvbnN0IHZpdGVzdEFyZ3M6IHN0cmluZ1tdID0gW107XG4gIGNvbnN0IHZpdGVzdE9wdGlvbnM6IHN0cmluZ1tdID0gW107XG4gIGNvbnN0IHJlcG9ydGVycyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBjb25zdCBmaWx0ZXJzOiBzdHJpbmdbXSA9IFtdO1xuICBjb25zdCB3YXRjaE1vZGUgPSBCb29sZWFuKHdhdGNoIHx8IHdhdGNoQWxsKTtcbiAgY29uc3QgbGlzdE1vZGUgPSBCb29sZWFuKGxpc3RUZXN0cyk7XG5cbiAgaWYobGlzdE1vZGUpIHtcbiAgICB2aXRlc3RBcmdzLnB1c2goJ2xpc3QnKTtcbiAgfSBlbHNlIGlmKHdhdGNoTW9kZSkge1xuICAgIHZpdGVzdEFyZ3MucHVzaCgnd2F0Y2gnKTtcbiAgfSBlbHNlIHtcbiAgICB2aXRlc3RBcmdzLnB1c2goJ3J1bicpO1xuICB9XG5cbiAgY29uc3QgaXNFU00gPSBkZXRlY3RFU00ocHJvY2Vzcy5jd2QoKSk7XG4gIGxldCBub2RlT3B0aW9ucyA9IHByb2Nlc3MuZW52Lk5PREVfT1BUSU9OUyB8fCAnJztcbiAgaWYoaXNFU00pIHtcbiAgICBpZighbm9kZU9wdGlvbnMuaW5jbHVkZXMoJy0tZXhwZXJpbWVudGFsLXZtLW1vZHVsZXMnKSkge1xuICAgICAgbm9kZU9wdGlvbnMgPSBgJHtub2RlT3B0aW9uc30gLS1leHBlcmltZW50YWwtdm0tbW9kdWxlc2AudHJpbSgpO1xuICAgIH1cbiAgICBsb2coJ0VTTSBwcm9qZWN0IGRldGVjdGVkLCB1c2luZyAtLWV4cGVyaW1lbnRhbC12bS1tb2R1bGVzIGluIE5PREVfT1BUSU9OUycsICdpbmZvJywgcXVpZXQpO1xuICB9XG5cbiAgaWYodml0ZXN0Q29uZmlnRmlsZSkge1xuICAgIHZpdGVzdE9wdGlvbnMucHVzaCgnLS1jb25maWcnLCB2aXRlc3RDb25maWdGaWxlKTtcbiAgfVxuXG4gIGlmKGJhaWwpIHtcbiAgICB2aXRlc3RPcHRpb25zLnB1c2goJy0tYmFpbCcsICcxJyk7XG4gIH1cblxuICBpZihjaGFuZ2VkRmlsZXNXaXRoQW5jZXN0b3IpIHtcbiAgICB2aXRlc3RPcHRpb25zLnB1c2goJy0tY2hhbmdlZCcpO1xuICB9XG5cbiAgaWYoY2hhbmdlZFNpbmNlKSB7XG4gICAgdml0ZXN0T3B0aW9ucy5wdXNoKCctLWNoYW5nZWQnLCBjaGFuZ2VkU2luY2UpO1xuICB9XG5cbiAgaWYoY2kpIHtcbiAgICB2aXRlc3RPcHRpb25zLnB1c2goJy0tcnVuJyk7XG4gIH1cblxuICBpZihjb2xsZWN0Q292ZXJhZ2VGcm9tKSB7XG4gICAgdml0ZXN0T3B0aW9ucy5wdXNoKCctLWNvdmVyYWdlJywgJy0tY292ZXJhZ2UuaW5jbHVkZScsIGNvbGxlY3RDb3ZlcmFnZUZyb20pO1xuICB9XG5cbiAgaWYoZGVidWcpIHtcbiAgICB2aXRlc3RPcHRpb25zLnB1c2goJy0taW5zcGVjdCcpO1xuICB9XG5cbiAgaWYoZGV0ZWN0T3BlbkhhbmRsZXMpIHtcbiAgICByZXBvcnRlcnMuYWRkKCdoYW5naW5nLXByb2Nlc3MnKTtcbiAgfVxuXG4gIGNvbnN0IGVudmlyb25tZW50TmFtZSA9IGVudmlyb25tZW50IHx8IGVudjtcbiAgaWYoZW52aXJvbm1lbnROYW1lKSB7XG4gICAgdml0ZXN0T3B0aW9ucy5wdXNoKCctLWVudmlyb25tZW50JywgZW52aXJvbm1lbnROYW1lKTtcbiAgfVxuXG4gIGlmKGVycm9yT25EZXByZWNhdGVkKSB7XG4gICAgbG9nKCdWaXRlc3QgZG9lcyBub3Qgc3VwcG9ydCAtLWVycm9yT25EZXByZWNhdGVkOyBvcHRpb24gaWdub3JlZC4nLCAnd2FybicsIHF1aWV0KTtcbiAgfVxuXG4gIGlmKGV4cGFuZCkge1xuICAgIHZpdGVzdE9wdGlvbnMucHVzaCgnLS1leHBhbmRTbmFwc2hvdERpZmYnKTtcbiAgfVxuXG4gIGlmKGZvcmNlRXhpdCkge1xuICAgIGxvZygnVml0ZXN0IGRvZXMgbm90IHN1cHBvcnQgLS1mb3JjZUV4aXQ7IG9wdGlvbiBpZ25vcmVkLicsICd3YXJuJywgcXVpZXQpO1xuICB9XG5cbiAgaWYobGFzdENvbW1pdCkge1xuICAgIHZpdGVzdE9wdGlvbnMucHVzaCgnLS1jaGFuZ2VkJyk7XG4gIH1cblxuICBpZihsb2dIZWFwVXNhZ2UpIHtcbiAgICB2aXRlc3RPcHRpb25zLnB1c2goJy0tbG9nSGVhcFVzYWdlJyk7XG4gIH1cblxuICBpZihtYXhXb3JrZXJzKSB7XG4gICAgdml0ZXN0T3B0aW9ucy5wdXNoKCctLW1heFdvcmtlcnMnLCBtYXhXb3JrZXJzKTtcbiAgfVxuXG4gIGlmKG5vU3RhY2tUcmFjZSkge1xuICAgIGxvZygnVml0ZXN0IGRvZXMgbm90IHN1cHBvcnQgLS1ub1N0YWNrVHJhY2U7IG9wdGlvbiBpZ25vcmVkLicsICd3YXJuJywgcXVpZXQpO1xuICB9XG5cbiAgaWYobm90aWZ5KSB7XG4gICAgbG9nKCdWaXRlc3QgZG9lcyBub3Qgc3VwcG9ydCAtLW5vdGlmeTsgb3B0aW9uIGlnbm9yZWQuJywgJ3dhcm4nLCBxdWlldCk7XG4gIH1cblxuICBpZihvbmx5Q2hhbmdlZCkge1xuICAgIHZpdGVzdE9wdGlvbnMucHVzaCgnLS1jaGFuZ2VkJyk7XG4gIH1cblxuICBsZXQgdGVtcE91dHB1dEZpbGUgPSBvdXRwdXRGaWxlO1xuICBjb25zdCBzaG91bGRXcml0ZUpzb24gPSBqc29uIHx8IHVzZUFuYWx5emUgfHwgdXNlRGVidWcgfHwgQm9vbGVhbihvdXRwdXRGaWxlKTtcblxuICBpZihzaG91bGRXcml0ZUpzb24pIHtcbiAgICB0ZW1wT3V0cHV0RmlsZSA9IG91dHB1dEZpbGUgfHwgJy5sZXgtdGVzdC1yZXN1bHRzLmpzb24nO1xuICAgIHZpdGVzdE9wdGlvbnMucHVzaCgnLS1vdXRwdXRGaWxlJywgdGVtcE91dHB1dEZpbGUpO1xuICAgIHJlcG9ydGVycy5hZGQoJ2pzb24nKTtcbiAgfVxuXG4gIGlmKHBhc3NXaXRoTm9UZXN0cykge1xuICAgIHZpdGVzdE9wdGlvbnMucHVzaCgnLS1wYXNzV2l0aE5vVGVzdHMnKTtcbiAgfVxuXG4gIGlmKHJ1bkluQmFuZCkge1xuICAgIHZpdGVzdE9wdGlvbnMucHVzaCgnLS1uby1maWxlLXBhcmFsbGVsaXNtJywgJy0tbWF4V29ya2VycycsICcxJyk7XG4gIH1cblxuICBpZihzaWxlbnQpIHtcbiAgICB2aXRlc3RPcHRpb25zLnB1c2goJy0tc2lsZW50Jyk7XG4gIH1cblxuICBpZih0ZXN0TG9jYXRpb25JblJlc3VsdHMpIHtcbiAgICB2aXRlc3RPcHRpb25zLnB1c2goJy0taW5jbHVkZVRhc2tMb2NhdGlvbicpO1xuICB9XG5cbiAgaWYodGVzdE5hbWVQYXR0ZXJuKSB7XG4gICAgdml0ZXN0T3B0aW9ucy5wdXNoKCctLXRlc3ROYW1lUGF0dGVybicsIHRlc3ROYW1lUGF0dGVybik7XG4gIH1cblxuICBpZih0ZXN0UGF0aFBhdHRlcm4pIHtcbiAgICBmaWx0ZXJzLnB1c2godGVzdFBhdGhQYXR0ZXJuKTtcbiAgfVxuXG4gIGlmKHVzZVN0ZGVycikge1xuICAgIGxvZygnVml0ZXN0IGRvZXMgbm90IHN1cHBvcnQgLS11c2VTdGRlcnI7IG9wdGlvbiBpZ25vcmVkLicsICd3YXJuJywgcXVpZXQpO1xuICB9XG5cbiAgaWYodmVyYm9zZSkge1xuICAgIHJlcG9ydGVycy5hZGQoJ3ZlcmJvc2UnKTtcbiAgfVxuXG4gIGlmKHJlbW92ZUNhY2hlIHx8IGNsZWFyQ2FjaGUpIHtcbiAgICB2aXRlc3RPcHRpb25zLnB1c2goJy0tY2xlYXJDYWNoZScpO1xuICB9XG5cbiAgaWYodXBkYXRlKSB7XG4gICAgdml0ZXN0T3B0aW9ucy5wdXNoKCctLXVwZGF0ZScpO1xuICB9XG5cbiAgaWYod2F0Y2gpIHtcbiAgICBmaWx0ZXJzLnB1c2god2F0Y2gpO1xuICB9XG5cbiAgaWYoYXJncykge1xuICAgIHZpdGVzdE9wdGlvbnMucHVzaCguLi5hcmdzKTtcbiAgfVxuXG4gIGlmKGZpbGVzICYmIGZpbGVzLmxlbmd0aCA+IDApIHtcbiAgICBmaWx0ZXJzLnB1c2goLi4uZmlsZXMpO1xuICB9XG5cbiAgaWYocmVwb3J0ZXJzLnNpemUgPiAwKSB7XG4gICAgY29uc3QgcmVwb3J0ZXJMaXN0ID0gQXJyYXkuZnJvbShyZXBvcnRlcnMpO1xuICAgIGlmKHJlcG9ydGVyTGlzdC5pbmNsdWRlcygnanNvbicpICYmICFyZXBvcnRlckxpc3QuaW5jbHVkZXMoJ3ZlcmJvc2UnKSkge1xuICAgICAgLy8gS2VlcCBjb25zb2xlIG91dHB1dCB3aGlsZSB3cml0aW5nIEpTT04gcmVzdWx0cy5cbiAgICAgIHJlcG9ydGVyTGlzdC51bnNoaWZ0KCdkZWZhdWx0Jyk7XG4gICAgfVxuICAgIHJlcG9ydGVyTGlzdC5mb3JFYWNoKChyZXBvcnRlcikgPT4gdml0ZXN0T3B0aW9ucy5wdXNoKCctLXJlcG9ydGVyJywgcmVwb3J0ZXIpKTtcbiAgfVxuXG4gIGNvbnN0IGZpbmFsQXJncyA9IFsuLi52aXRlc3RBcmdzLCAuLi52aXRlc3RPcHRpb25zLCAuLi5maWx0ZXJzXTtcblxuICBpZihkZWJ1Zykge1xuICAgIGxvZyhgVml0ZXN0IG9wdGlvbnM6ICR7ZmluYWxBcmdzLmpvaW4oJyAnKX1gLCAnaW5mbycsIHF1aWV0KTtcbiAgICBsb2coYE5PREVfT1BUSU9OUzogJHtub2RlT3B0aW9uc31gLCAnaW5mbycsIHF1aWV0KTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgY29uc3QgZW52OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAgICAgLi4ucHJvY2Vzcy5lbnYsXG4gICAgICBOT0RFX09QVElPTlM6IG5vZGVPcHRpb25zXG4gICAgfTtcblxuICAgIGlmKGNvbG9ycykge1xuICAgICAgZW52LkZPUkNFX0NPTE9SID0gJzEnO1xuICAgIH1cblxuICAgIGlmKGNpKSB7XG4gICAgICBlbnYuQ0kgPSAndHJ1ZSc7XG4gICAgfVxuXG4gICAgaWYodml0ZXN0U2V0dXBGaWxlICYmIGV4aXN0c1N5bmModml0ZXN0U2V0dXBGaWxlKSkge1xuICAgICAgZW52LkxFWF9WSVRFU1RfU0VUVVAgPSB2aXRlc3RTZXR1cEZpbGU7XG4gICAgfVxuXG4gICAgYXdhaXQgZXhlY2Eodml0ZXN0UGF0aCwgZmluYWxBcmdzLCB7XG4gICAgICBlbmNvZGluZzogJ3V0ZjgnLFxuICAgICAgZW52LFxuICAgICAgc3RkaW86ICdpbmhlcml0J1xuICAgIH0pO1xuXG4gICAgc3Bpbm5lci5zdWNjZWVkKCdUZXN0aW5nIGNvbXBsZXRlZCEnKTtcblxuICAgIGlmKHVzZUFuYWx5emUpIHtcbiAgICAgIHNwaW5uZXIuc3RhcnQoJ0FJIGlzIGFuYWx5emluZyB0ZXN0IGNvdmVyYWdlIGFuZCBzdWdnZXN0aW5nIGltcHJvdmVtZW50cy4uLicpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCB0ZXN0UmVzdWx0cyA9IHByb2Nlc3NUZXN0UmVzdWx0cyh0ZW1wT3V0cHV0RmlsZSk7XG4gICAgICAgIGNvbnN0IGZpbGVQYXR0ZXJucyA9IGdldFRlc3RGaWxlUGF0dGVybnModGVzdFBhdGhQYXR0ZXJuKTtcblxuICAgICAgICBhd2FpdCBhaUZ1bmN0aW9uKHtcbiAgICAgICAgICBjb250ZXh0OiB0cnVlLFxuICAgICAgICAgIHByb21wdDogYEFuYWx5emUgdGhlc2UgVml0ZXN0IHRlc3QgcmVzdWx0cyBhbmQgc3VnZ2VzdCB0ZXN0IGNvdmVyYWdlIGltcHJvdmVtZW50czpcblxuJHtKU09OLnN0cmluZ2lmeSh0ZXN0UmVzdWx0cywgbnVsbCwgMil9XG5cblRlc3QgcGF0dGVybnM6ICR7ZmlsZVBhdHRlcm5zLmpvaW4oJywgJyl9XG5cblBsZWFzZSBwcm92aWRlOlxuMS4gQW5hbHlzaXMgb2YgY3VycmVudCBjb3ZlcmFnZSBnYXBzXG4yLiBTdWdnZXN0aW9ucyBmb3IgaW1wcm92aW5nIHRlc3QgY2FzZXNcbjMuIFJlY29tbWVuZGF0aW9ucyBmb3IgYWRkaXRpb25hbCBpbnRlZ3JhdGlvbiB0ZXN0IHNjZW5hcmlvc1xuNC4gQmVzdCBwcmFjdGljZXMgZm9yIGluY3JlYXNpbmcgdGVzdCBlZmZlY3RpdmVuZXNzYCxcbiAgICAgICAgICBxdWlldCxcbiAgICAgICAgICB0YXNrOiAnb3B0aW1pemUnXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNwaW5uZXIuc3VjY2VlZCgnQUkgdGVzdCBhbmFseXNpcyBjb21wbGV0ZScpO1xuICAgICAgfSBjYXRjaChhaUVycm9yKSB7XG4gICAgICAgIHNwaW5uZXIuZmFpbCgnQ291bGQgbm90IGdlbmVyYXRlIEFJIHRlc3QgYW5hbHlzaXMnKTtcbiAgICAgICAgaWYoIXF1aWV0KSB7XG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgICBjb25zb2xlLmVycm9yKCdBSSBhbmFseXNpcyBlcnJvcjonLCBhaUVycm9yKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGNhbGxiYWNrKDApO1xuICAgIHJldHVybiAwO1xuICB9IGNhdGNoKGVycm9yKSB7XG4gICAgbG9nKGBcXG4ke2NsaU5hbWV9IEVycm9yOiBDaGVjayBmb3IgdW5pdCB0ZXN0IGVycm9ycyBhbmQvb3IgY292ZXJhZ2UuYCwgJ2Vycm9yJywgcXVpZXQpO1xuXG4gICAgc3Bpbm5lci5mYWlsKCdUZXN0aW5nIGZhaWxlZCEnKTtcblxuICAgIGlmKHVzZURlYnVnKSB7XG4gICAgICBzcGlubmVyLnN0YXJ0KCdBSSBpcyBhbmFseXppbmcgdGVzdCBmYWlsdXJlcy4uLicpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCB0ZXN0UmVzdWx0cyA9IHByb2Nlc3NUZXN0UmVzdWx0cyh0ZW1wT3V0cHV0RmlsZSk7XG5cbiAgICAgICAgYXdhaXQgYWlGdW5jdGlvbih7XG4gICAgICAgICAgY29udGV4dDogdHJ1ZSxcbiAgICAgICAgICBwcm9tcHQ6IGBEZWJ1ZyB0aGVzZSBmYWlsZWQgVml0ZXN0IHRlc3RzIGFuZCBzdWdnZXN0IGZpeGVzOlxuXG4ke0pTT04uc3RyaW5naWZ5KGVycm9yLm1lc3NhZ2UsIG51bGwsIDIpfVxuXG5UZXN0IHJlc3VsdHM6ICR7SlNPTi5zdHJpbmdpZnkodGVzdFJlc3VsdHMsIG51bGwsIDIpfVxuXG5QbGVhc2UgcHJvdmlkZTpcbjEuIEFuYWx5c2lzIG9mIHdoeSB0aGUgdGVzdHMgYXJlIGZhaWxpbmdcbjIuIFNwZWNpZmljIHN1Z2dlc3Rpb25zIHRvIGZpeCBlYWNoIGZhaWxpbmcgdGVzdFxuMy4gQW55IHBvdGVudGlhbCBpc3N1ZXMgd2l0aCB0ZXN0IGZpeHR1cmVzIG9yIG1vY2tzXG40LiBDb2RlIGV4YW1wbGVzIGZvciBzb2x1dGlvbnNgLFxuICAgICAgICAgIHF1aWV0LFxuICAgICAgICAgIHRhc2s6ICdoZWxwJ1xuICAgICAgICB9KTtcblxuICAgICAgICBzcGlubmVyLnN1Y2NlZWQoJ0FJIGRlYnVnZ2luZyBhc3Npc3RhbmNlIGNvbXBsZXRlJyk7XG4gICAgICB9IGNhdGNoKGFpRXJyb3IpIHtcbiAgICAgICAgc3Bpbm5lci5mYWlsKCdDb3VsZCBub3QgZ2VuZXJhdGUgQUkgZGVidWdnaW5nIGFzc2lzdGFuY2UnKTtcbiAgICAgICAgaWYoIXF1aWV0KSB7XG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgICBjb25zb2xlLmVycm9yKCdBSSBkZWJ1Z2dpbmcgZXJyb3I6JywgYWlFcnJvcik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBjYWxsYmFjaygxKTtcbiAgICByZXR1cm4gMTtcbiAgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgdGVzdDtcbiJdLCJuYW1lcyI6WyJleGVjYSIsImV4aXN0c1N5bmMiLCJyZWFkRmlsZVN5bmMiLCJzeW5jIiwiZ2xvYlN5bmMiLCJyZXNvbHZlIiwicGF0aFJlc29sdmUiLCJMZXhDb25maWciLCJnZXRUeXBlU2NyaXB0Q29uZmlnUGF0aCIsImNyZWF0ZVNwaW5uZXIiLCJyZXNvbHZlQmluYXJ5UGF0aCIsImxvZyIsImFpRnVuY3Rpb24iLCJkZXRlY3RFU00iLCJjd2QiLCJwYWNrYWdlSnNvblBhdGgiLCJwYWNrYWdlSnNvbkNvbnRlbnQiLCJwYWNrYWdlSnNvbiIsIkpTT04iLCJwYXJzZSIsInR5cGUiLCJfZXJyb3IiLCJkZWZhdWx0RXhpdCIsImNvZGUiLCJwcm9jZXNzIiwiZW52IiwiVklURVNUIiwiVklURVNUX1dPUktFUl9JRCIsIk5PREVfRU5WIiwidW5kZWZpbmVkIiwiZXhpdCIsImdldFRlc3RGaWxlUGF0dGVybnMiLCJ0ZXN0UGF0aFBhdHRlcm4iLCJkZWZhdWx0UGF0dGVybnMiLCJmaW5kVW5jb3ZlcmVkU291cmNlRmlsZXMiLCJzb3VyY2VGaWxlcyIsImlnbm9yZSIsInRlc3RGaWxlcyIsImZpbHRlciIsInNvdXJjZUZpbGUiLCJiYXNlTmFtZSIsInJlcGxhY2UiLCJzb21lIiwidGVzdEZpbGUiLCJpbmNsdWRlcyIsInByb2Nlc3NUZXN0UmVzdWx0cyIsIm91dHB1dEZpbGUiLCJjb250ZW50IiwidGVzdCIsIm9wdGlvbnMiLCJhcmdzIiwiZmlsZXNPckNhbGxiYWNrIiwiY2FsbGJhY2tQYXJhbSIsImZpbGVzIiwiY2FsbGJhY2siLCJhbmFseXplIiwiYWlBbmFseXplIiwiYWlEZWJ1ZyIsImFpR2VuZXJhdGUiLCJiYWlsIiwiY2hhbmdlZEZpbGVzV2l0aEFuY2VzdG9yIiwiY2hhbmdlZFNpbmNlIiwiY2kiLCJjbGVhckNhY2hlIiwiY2xpTmFtZSIsImNvbGxlY3RDb3ZlcmFnZUZyb20iLCJjb2xvcnMiLCJjb25maWciLCJkZWJ1ZyIsImRlYnVnVGVzdHMiLCJkZXRlY3RPcGVuSGFuZGxlcyIsImVudmlyb25tZW50IiwiZXJyb3JPbkRlcHJlY2F0ZWQiLCJleHBhbmQiLCJmb3JjZUV4aXQiLCJnZW5lcmF0ZSIsImpzb24iLCJsYXN0Q29tbWl0IiwibGlzdFRlc3RzIiwibG9nSGVhcFVzYWdlIiwibWF4V29ya2VycyIsIm5vU3RhY2tUcmFjZSIsIm5vdGlmeSIsIm9ubHlDaGFuZ2VkIiwicGFzc1dpdGhOb1Rlc3RzIiwicXVpZXQiLCJyZW1vdmVDYWNoZSIsInJ1bkluQmFuZCIsInNldHVwIiwic2hvd0NvbmZpZyIsInNpbGVudCIsInRlc3RMb2NhdGlvbkluUmVzdWx0cyIsInRlc3ROYW1lUGF0dGVybiIsInVwZGF0ZSIsInVzZVN0ZGVyciIsInZlcmJvc2UiLCJ3YXRjaCIsIndhdGNoQWxsIiwidXNlR2VuZXJhdGUiLCJ1c2VBbmFseXplIiwidXNlRGVidWciLCJzcGlubmVyIiwicGFyc2VDb25maWciLCJ1c2VUeXBlc2NyaXB0IiwidGVzdENvbmZpZ1BhdGgiLCJjaGVja1Rlc3RUeXBlc2NyaXB0Q29uZmlnIiwic3RhcnQiLCJ1bmNvdmVyZWRGaWxlcyIsImxlbmd0aCIsInRhcmdldEZpbGUiLCJjb250ZXh0IiwiZmlsZSIsInByb21wdCIsInRhc2siLCJzdWNjZWVkIiwiYWlFcnJvciIsImZhaWwiLCJjb25zb2xlIiwiZXJyb3IiLCJwcm9qZWN0Vml0ZXN0QmluIiwidml0ZXN0UGF0aCIsInZpdGVzdENvbmZpZ0ZpbGUiLCJwcm9qZWN0Vml0ZXN0Q29uZmlnIiwicHJvamVjdFZpdGVzdENvbmZpZ1BhdGhzIiwiZXhpc3RpbmdDb25maWdQYXRoIiwiZmluZCIsImNvbmZpZ1BhdGgiLCJ2aXRlc3QiLCJsZXhEaXIiLCJnZXRMZXhEaXIiLCJsZXhWaXRlc3RDb25maWciLCJPYmplY3QiLCJrZXlzIiwicmVzb2x2ZWRDb25maWciLCJzdHJpbmdpZnkiLCJkZWZhdWx0Iiwidml0ZXN0U2V0dXBGaWxlIiwidml0ZXN0QXJncyIsInZpdGVzdE9wdGlvbnMiLCJyZXBvcnRlcnMiLCJTZXQiLCJmaWx0ZXJzIiwid2F0Y2hNb2RlIiwiQm9vbGVhbiIsImxpc3RNb2RlIiwicHVzaCIsImlzRVNNIiwibm9kZU9wdGlvbnMiLCJOT0RFX09QVElPTlMiLCJ0cmltIiwiYWRkIiwiZW52aXJvbm1lbnROYW1lIiwidGVtcE91dHB1dEZpbGUiLCJzaG91bGRXcml0ZUpzb24iLCJzaXplIiwicmVwb3J0ZXJMaXN0IiwiQXJyYXkiLCJmcm9tIiwidW5zaGlmdCIsImZvckVhY2giLCJyZXBvcnRlciIsImZpbmFsQXJncyIsImpvaW4iLCJGT1JDRV9DT0xPUiIsIkNJIiwiTEVYX1ZJVEVTVF9TRVRVUCIsImVuY29kaW5nIiwic3RkaW8iLCJ0ZXN0UmVzdWx0cyIsImZpbGVQYXR0ZXJucyIsIm1lc3NhZ2UiXSwibWFwcGluZ3MiOiJBQUFBOzs7Q0FHQyxHQUNELFNBQVFBLEtBQUssUUFBTyxRQUFRO0FBQzVCLFNBQVFDLFVBQVUsRUFBRUMsWUFBWSxRQUFPLEtBQUs7QUFDNUMsU0FBUUMsUUFBUUMsUUFBUSxRQUFPLE9BQU87QUFDdEMsU0FBUUMsV0FBV0MsV0FBVyxRQUFPLE9BQU87QUFFNUMsU0FBUUMsU0FBUyxFQUFFQyx1QkFBdUIsUUFBTyxxQkFBcUI7QUFDdEUsU0FBUUMsYUFBYSxRQUFPLHFCQUFxQjtBQUNqRCxTQUFRQyxpQkFBaUIsUUFBTyxzQkFBc0I7QUFDdEQsU0FBUUMsR0FBRyxRQUFPLHFCQUFxQjtBQUN2QyxTQUFRQyxVQUFVLFFBQU8sY0FBYztBQUV2QyxNQUFNQyxZQUFZLENBQUNDO0lBQ2pCLE1BQU1DLGtCQUFrQlQsWUFBWVEsS0FBSztJQUV6QyxJQUFHYixXQUFXYyxrQkFBa0I7UUFDOUIsSUFBSTtZQUNGLE1BQU1DLHFCQUFxQmQsYUFBYWEsaUJBQWlCO1lBQ3pELE1BQU1FLGNBQWNDLEtBQUtDLEtBQUssQ0FBQ0g7WUFDL0IsT0FBT0MsWUFBWUcsSUFBSSxLQUFLO1FBQzlCLEVBQUUsT0FBTUMsUUFBUTtZQUNkLE9BQU87UUFDVDtJQUNGO0lBRUEsT0FBTztBQUNUO0FBcURBLE1BQU1DLGNBQWUsQ0FBQ0M7SUFDcEIsSUFBR0MsUUFBUUMsR0FBRyxDQUFDQyxNQUFNLElBQUlGLFFBQVFDLEdBQUcsQ0FBQ0UsZ0JBQWdCLElBQUlILFFBQVFDLEdBQUcsQ0FBQ0csUUFBUSxLQUFLLFFBQVE7UUFDeEYsT0FBT0M7SUFDVDtJQUVBTCxRQUFRTSxJQUFJLENBQUNQO0FBQ2Y7QUFFQSxPQUFPLE1BQU1RLHNCQUFzQixDQUFDQztJQUNsQyxNQUFNQyxrQkFBa0I7UUFBQztRQUFlO1FBQWU7S0FBcUI7SUFF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
497
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21tYW5kcy90ZXN0L3Rlc3QudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTgtUHJlc2VudCwgTml0cm9nZW4gTGFicywgSW5jLlxuICogQ29weXJpZ2h0cyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSB0aGUgYWNjb21wYW55aW5nIExJQ0VOU0UgZmlsZSBmb3IgdGVybXMuXG4gKi9cbmltcG9ydCB7ZXhlY2F9IGZyb20gJ2V4ZWNhJztcbmltcG9ydCB7ZXhpc3RzU3luYywgcmVhZEZpbGVTeW5jfSBmcm9tICdmcyc7XG5pbXBvcnQge3N5bmMgYXMgZ2xvYlN5bmN9IGZyb20gJ2dsb2InO1xuaW1wb3J0IHtyZXNvbHZlIGFzIHBhdGhSZXNvbHZlfSBmcm9tICdwYXRoJztcblxuaW1wb3J0IHtMZXhDb25maWcsIGdldFR5cGVTY3JpcHRDb25maWdQYXRofSBmcm9tICcuLi8uLi9MZXhDb25maWcuanMnO1xuaW1wb3J0IHtjcmVhdGVTcGlubmVyfSBmcm9tICcuLi8uLi91dGlscy9hcHAuanMnO1xuaW1wb3J0IHtyZXNvbHZlQmluYXJ5UGF0aH0gZnJvbSAnLi4vLi4vdXRpbHMvZmlsZS5qcyc7XG5pbXBvcnQge2xvZ30gZnJvbSAnLi4vLi4vdXRpbHMvbG9nLmpzJztcbmltcG9ydCB7YWlGdW5jdGlvbn0gZnJvbSAnLi4vYWkvYWkuanMnO1xuXG5jb25zdCBkZXRlY3RFU00gPSAoY3dkOiBzdHJpbmcpOiBib29sZWFuID0+IHtcbiAgY29uc3QgcGFja2FnZUpzb25QYXRoID0gcGF0aFJlc29sdmUoY3dkLCAncGFja2FnZS5qc29uJyk7XG5cbiAgaWYoZXhpc3RzU3luYyhwYWNrYWdlSnNvblBhdGgpKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBhY2thZ2VKc29uQ29udGVudCA9IHJlYWRGaWxlU3luYyhwYWNrYWdlSnNvblBhdGgsICd1dGY4Jyk7XG4gICAgICBjb25zdCBwYWNrYWdlSnNvbiA9IEpTT04ucGFyc2UocGFja2FnZUpzb25Db250ZW50KTtcbiAgICAgIHJldHVybiBwYWNrYWdlSnNvbi50eXBlID09PSAnbW9kdWxlJztcbiAgICB9IGNhdGNoKF9lcnJvcikge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVzdE9wdGlvbnMge1xuICByZWFkb25seSBhbmFseXplPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgYWlEZWJ1Zz86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGFpR2VuZXJhdGU/OiBib29sZWFuO1xuICByZWFkb25seSBhaUFuYWx5emU/OiBib29sZWFuO1xuICByZWFkb25seSBiYWlsPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgY2hhbmdlZEZpbGVzV2l0aEFuY2VzdG9yPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgY2hhbmdlZFNpbmNlPzogc3RyaW5nO1xuICByZWFkb25seSBjaT86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGNsZWFyQ2FjaGU/OiBib29sZWFuO1xuICByZWFkb25seSBjbGlOYW1lPzogc3RyaW5nO1xuICByZWFkb25seSBjb2xsZWN0Q292ZXJhZ2VGcm9tPzogc3RyaW5nO1xuICByZWFkb25seSBjb2xvcnM/OiBib29sZWFuO1xuICByZWFkb25seSBjb25maWc/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGRlYnVnPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgZGVidWdUZXN0cz86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGRldGVjdE9wZW5IYW5kbGVzPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgZW52aXJvbm1lbnQ/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGVudj86IHN0cmluZztcbiAgcmVhZG9ubHkgZXJyb3JPbkRlcHJlY2F0ZWQ/OiBib29sZWFuO1xuICByZWFkb25seSBleHBhbmQ/OiBib29sZWFuO1xuICByZWFkb25seSBlMmU/OiBib29sZWFuO1xuICByZWFkb25seSBlMmVDb25maWc/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGZvcmNlRXhpdD86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGdlbmVyYXRlPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkganNvbj86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGxhc3RDb21taXQ/OiBib29sZWFuO1xuICByZWFkb25seSBsaXN0VGVzdHM/OiBib29sZWFuO1xuICByZWFkb25seSBsb2dIZWFwVXNhZ2U/OiBib29sZWFuO1xuICByZWFkb25seSBtYXhXb3JrZXJzPzogc3RyaW5nO1xuICByZWFkb25seSBub1N0YWNrVHJhY2U/OiBib29sZWFuO1xuICByZWFkb25seSBub3RpZnk/OiBib29sZWFuO1xuICByZWFkb25seSBvbmx5Q2hhbmdlZD86IGJvb2xlYW47XG4gIHJlYWRvbmx5IG91dHB1dEZpbGU/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHBhc3NXaXRoTm9UZXN0cz86IGJvb2xlYW47XG4gIHJlYWRvbmx5IHF1aWV0PzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgcmVtb3ZlQ2FjaGU/OiBib29sZWFuO1xuICByZWFkb25seSBydW5JbkJhbmQ/OiBib29sZWFuO1xuICByZWFkb25seSBzZXR1cD86IHN0cmluZztcbiAgcmVhZG9ubHkgc2hvd0NvbmZpZz86IGJvb2xlYW47XG4gIHJlYWRvbmx5IHNpbGVudD86IGJvb2xlYW47XG4gIHJlYWRvbmx5IHRlc3RMb2NhdGlvbkluUmVzdWx0cz86IGJvb2xlYW47XG4gIHJlYWRvbmx5IHRlc3ROYW1lUGF0dGVybj86IHN0cmluZztcbiAgcmVhZG9ubHkgdGVzdFBhdGhQYXR0ZXJuPzogc3RyaW5nO1xuICByZWFkb25seSB1bml0PzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgdXBkYXRlPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgdXNlU3RkZXJyPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgdmVyYm9zZT86IGJvb2xlYW47XG4gIHJlYWRvbmx5IHdhdGNoPzogc3RyaW5nO1xuICByZWFkb25seSB3YXRjaEFsbD86IGJvb2xlYW47XG59XG5cbmV4cG9ydCB0eXBlIFRlc3RDYWxsYmFjayA9IHR5cGVvZiBwcm9jZXNzLmV4aXQ7XG5cbmNvbnN0IGRlZmF1bHRFeGl0ID0gKChjb2RlPzogbnVtYmVyKSA9PiB7XG4gIGlmKHByb2Nlc3MuZW52LlZJVEVTVCB8fCBwcm9jZXNzLmVudi5WSVRFU1RfV09SS0VSX0lEIHx8IHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAndGVzdCcpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkIGFzIG5ldmVyO1xuICB9XG5cbiAgcHJvY2Vzcy5leGl0KGNvZGUpO1xufSkgYXMgdHlwZW9mIHByb2Nlc3MuZXhpdDtcblxuZXhwb3J0IGNvbnN0IGdldFRlc3RGaWxlUGF0dGVybnMgPSAodGVzdFBhdGhQYXR0ZXJuPzogc3RyaW5nKTogc3RyaW5nW10gPT4ge1xuICBjb25zdCBkZWZhdWx0UGF0dGVybnMgPSBbJyoqLyoudGVzdC57dHMsdHN4LGpzLGpzeH0nXTtcblxuICBpZighdGVzdFBhdGhQYXR0ZXJuKSB7XG4gICAgcmV0dXJuIGRlZmF1bHRQYXR0ZXJucztcbiAgfVxuXG4gIHJldHVybiBbdGVzdFBhdGhQYXR0ZXJuXTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRFMkVUZXN0RmlsZVBhdHRlcm5zID0gKCk6IHN0cmluZ1tdID0+IFsnKiovKi5lMmUue3RzLHRzeCxqcyxqc3h9J107XG5cbmNvbnN0IGZpbmRVbmNvdmVyZWRTb3VyY2VGaWxlcyA9ICgpOiBzdHJpbmdbXSA9PiB7XG4gIGNvbnN0IHNvdXJjZUZpbGVzID0gZ2xvYlN5bmMoJ3NyYy8qKi8qLnt0cyx0c3gsanMsanN4fScsIHtcbiAgICBjd2Q6IHByb2Nlc3MuY3dkKCksXG4gICAgaWdub3JlOiBbJyoqL25vZGVfbW9kdWxlcy8qKicsICcqKi9kaXN0LyoqJywgJyoqL2xpYi8qKicsICcqKi8qLnRlc3QuKicsICcqKi8qLnNwZWMuKiddXG4gIH0pO1xuXG4gIGNvbnN0IHRlc3RGaWxlcyA9IGdsb2JTeW5jKCcqKi8qLnRlc3Que3RzLHRzeCxqcyxqc3h9Jywge1xuICAgIGN3ZDogcHJvY2Vzcy5jd2QoKSxcbiAgICBpZ25vcmU6IFsnKiovbm9kZV9tb2R1bGVzLyoqJywgJyoqL2Rpc3QvKionLCAnKiovbGliLyoqJ11cbiAgfSk7XG5cbiAgcmV0dXJuIHNvdXJjZUZpbGVzLmZpbHRlcigoc291cmNlRmlsZSkgPT4ge1xuICAgIGNvbnN0IGJhc2VOYW1lID0gc291cmNlRmlsZS5yZXBsYWNlKC9cXC5bXi8uXSskLywgJycpO1xuICAgIHJldHVybiAhdGVzdEZpbGVzLnNvbWUoKHRlc3RGaWxlKSA9PiB0ZXN0RmlsZS5pbmNsdWRlcyhiYXNlTmFtZSkpO1xuICB9KTtcbn07XG5cbmNvbnN0IHByb2Nlc3NUZXN0UmVzdWx0cyA9IChvdXRwdXRGaWxlPzogc3RyaW5nKTogYW55ID0+IHtcbiAgaWYoIW91dHB1dEZpbGUpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHRyeSB7XG4gICAgY29uc3QgY29udGVudCA9IHJlYWRGaWxlU3luYyhvdXRwdXRGaWxlLCAndXRmLTgnKTtcbiAgICByZXR1cm4gSlNPTi5wYXJzZShjb250ZW50KTtcbiAgfSBjYXRjaChfZXJyb3IpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHRlc3QgPSBhc3luYyAoXG4gIG9wdGlvbnM6IFRlc3RPcHRpb25zLFxuICBhcmdzPzogc3RyaW5nW10sXG4gIGZpbGVzT3JDYWxsYmFjaz86IHN0cmluZ1tdIHwgVGVzdENhbGxiYWNrLFxuICBjYWxsYmFja1BhcmFtPzogVGVzdENhbGxiYWNrXG4pOiBQcm9taXNlPG51bWJlcj4gPT4ge1xuICAvLyBCYWNrd2FyZC1jb21wYXQgYXJndW1lbnQgbm9ybWFsaXphdGlvbjogYWxsb3cgY2FsbGJhY2sgYXMgdGhpcmQgcGFyYW1cbiAgbGV0IGZpbGVzOiBzdHJpbmdbXSB8IHVuZGVmaW5lZDtcbiAgbGV0IGNhbGxiYWNrOiBUZXN0Q2FsbGJhY2sgPSBkZWZhdWx0RXhpdDtcblxuICBpZih0eXBlb2YgZmlsZXNPckNhbGxiYWNrID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2FsbGJhY2sgPSBmaWxlc09yQ2FsbGJhY2sgYXMgVGVzdENhbGxiYWNrO1xuICB9IGVsc2Uge1xuICAgIGZpbGVzID0gZmlsZXNPckNhbGxiYWNrIGFzIHN0cmluZ1tdIHwgdW5kZWZpbmVkO1xuICAgIGNhbGxiYWNrID0gY2FsbGJhY2tQYXJhbSB8fCBkZWZhdWx0RXhpdDtcbiAgfVxuICBjb25zdCB7XG4gICAgYW5hbHl6ZSA9IGZhbHNlLFxuICAgIGFpQW5hbHl6ZSA9IGZhbHNlLFxuICAgIGFpRGVidWcgPSBmYWxzZSxcbiAgICBhaUdlbmVyYXRlID0gZmFsc2UsXG4gICAgYmFpbCxcbiAgICBjaGFuZ2VkRmlsZXNXaXRoQW5jZXN0b3IsXG4gICAgY2hhbmdlZFNpbmNlLFxuICAgIGNpLFxuICAgIGNsZWFyQ2FjaGUsXG4gICAgY2xpTmFtZSA9ICdMZXgnLFxuICAgIGNvbGxlY3RDb3ZlcmFnZUZyb20sXG4gICAgY29sb3JzLFxuICAgIGNvbmZpZyxcbiAgICBkZWJ1ZyA9IGZhbHNlLFxuICAgIGRlYnVnVGVzdHMgPSBmYWxzZSxcbiAgICBkZXRlY3RPcGVuSGFuZGxlcyxcbiAgICBlMmUgPSBmYWxzZSxcbiAgICBlMmVDb25maWcsXG4gICAgZW52aXJvbm1lbnQsXG4gICAgZW52LFxuICAgIGVycm9yT25EZXByZWNhdGVkLFxuICAgIGV4cGFuZCxcbiAgICBmb3JjZUV4aXQsXG4gICAgZ2VuZXJhdGUgPSBmYWxzZSxcbiAgICBqc29uLFxuICAgIGxhc3RDb21taXQsXG4gICAgbGlzdFRlc3RzLFxuICAgIGxvZ0hlYXBVc2FnZSxcbiAgICBtYXhXb3JrZXJzLFxuICAgIG5vU3RhY2tUcmFjZSxcbiAgICBub3RpZnksXG4gICAgb25seUNoYW5nZWQsXG4gICAgb3V0cHV0RmlsZSxcbiAgICBwYXNzV2l0aE5vVGVzdHMsXG4gICAgcXVpZXQsXG4gICAgcmVtb3ZlQ2FjaGUsXG4gICAgcnVuSW5CYW5kLFxuICAgIHNldHVwLFxuICAgIHNob3dDb25maWcsXG4gICAgc2lsZW50LFxuICAgIHRlc3RMb2NhdGlvbkluUmVzdWx0cyxcbiAgICB0ZXN0TmFtZVBhdHRlcm4sXG4gICAgdGVzdFBhdGhQYXR0ZXJuLFxuICAgIHVuaXQgPSBmYWxzZSxcbiAgICB1cGRhdGUsXG4gICAgdXNlU3RkZXJyLFxuICAgIHZlcmJvc2UsXG4gICAgd2F0Y2gsXG4gICAgd2F0Y2hBbGxcbiAgfSA9IG9wdGlvbnM7XG5cbiAgY29uc3QgdXNlR2VuZXJhdGUgPSBnZW5lcmF0ZSB8fCBhaUdlbmVyYXRlO1xuICBjb25zdCB1c2VBbmFseXplID0gYW5hbHl6ZSB8fCBhaUFuYWx5emU7XG4gIGNvbnN0IHVzZURlYnVnID0gZGVidWdUZXN0cyB8fCBhaURlYnVnO1xuICBjb25zdCBydW5FMkUgPSBlMmU7XG4gIGNvbnN0IHJ1blVuaXQgPSB1bml0IHx8ICFydW5FMkU7XG5cbiAgbG9nKGAke2NsaU5hbWV9IHRlc3RpbmcuLi5gLCAnaW5mbycsIHF1aWV0KTtcblxuICBjb25zdCBzcGlubmVyID0gY3JlYXRlU3Bpbm5lcihxdWlldCk7XG5cbiAgYXdhaXQgTGV4Q29uZmlnLnBhcnNlQ29uZmlnKG9wdGlvbnMpO1xuXG4gIGNvbnN0IHt1c2VUeXBlc2NyaXB0fSA9IExleENvbmZpZy5jb25maWc7XG5cbiAgaWYodXNlVHlwZXNjcmlwdCkge1xuICAgIGNvbnN0IHRlc3RDb25maWdQYXRoID0gZ2V0VHlwZVNjcmlwdENvbmZpZ1BhdGgoJ3RzY29uZmlnLnRlc3QuanNvbicpO1xuICAgIGlmKGV4aXN0c1N5bmModGVzdENvbmZpZ1BhdGgpKSB7XG4gICAgICBsb2coJ1VzaW5nIHRzY29uZmlnLnRlc3QuanNvbiBmb3IgdGVzdGluZy4uLicsICdpbmZvJywgcXVpZXQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBMZXhDb25maWcuY2hlY2tUZXN0VHlwZXNjcmlwdENvbmZpZygpO1xuICAgIH1cbiAgfVxuXG4gIGlmKHVzZUdlbmVyYXRlKSB7XG4gICAgc3Bpbm5lci5zdGFydCgnQUkgaXMgYW5hbHl6aW5nIGNvZGUgdG8gZ2VuZXJhdGUgdGVzdCBjYXNlcy4uLicpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHVuY292ZXJlZEZpbGVzID0gZmluZFVuY292ZXJlZFNvdXJjZUZpbGVzKCk7XG5cbiAgICAgIGlmKHVuY292ZXJlZEZpbGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgdGFyZ2V0RmlsZSA9IHVuY292ZXJlZEZpbGVzWzBdO1xuXG4gICAgICAgIGF3YWl0IGFpRnVuY3Rpb24oe1xuICAgICAgICAgIGNvbnRleHQ6IHRydWUsXG4gICAgICAgICAgZmlsZTogdGFyZ2V0RmlsZSxcbiAgICAgICAgICBwcm9tcHQ6IGBHZW5lcmF0ZSBWaXRlc3QgdW5pdCB0ZXN0cyBmb3IgdGhpcyBmaWxlOiAke3RhcmdldEZpbGV9XFxuXFxuJHtyZWFkRmlsZVN5bmModGFyZ2V0RmlsZSwgJ3V0Zi04Jyl9XFxuXFxuUGxlYXNlIGNyZWF0ZSBjb21wcmVoZW5zaXZlIHRlc3RzIHRoYXQgY292ZXIgdGhlIG1haW4gZnVuY3Rpb25hbGl0eS4gSW5jbHVkZSB0ZXN0IGZpeHR1cmVzIGFuZCBtb2NrcyB3aGVyZSBuZWNlc3NhcnkuYCxcbiAgICAgICAgICBxdWlldCxcbiAgICAgICAgICB0YXNrOiAndGVzdCdcbiAgICAgICAgfSk7XG5cbiAgICAgICAgc3Bpbm5lci5zdWNjZWVkKGBBSSB0ZXN0IGdlbmVyYXRpb24gc3VnZ2VzdGlvbnMgcHJvdmlkZWQgZm9yICR7dGFyZ2V0RmlsZX1gKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNwaW5uZXIuc3VjY2VlZCgnQWxsIHNvdXJjZSBmaWxlcyBhcHBlYXIgdG8gaGF2ZSBjb3JyZXNwb25kaW5nIHRlc3QgZmlsZXMnKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoKGFpRXJyb3IpIHtcbiAgICAgIHNwaW5uZXIuZmFpbCgnQ291bGQgbm90IGdlbmVyYXRlIEFJIHRlc3Qgc3VnZ2VzdGlvbnMnKTtcbiAgICAgIGlmKCFxdWlldCkge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgICBjb25zb2xlLmVycm9yKCdBSSB0ZXN0IGdlbmVyYXRpb24gZXJyb3I6JywgYWlFcnJvcik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc3QgaXNFU00gPSBkZXRlY3RFU00ocHJvY2Vzcy5jd2QoKSk7XG4gIGxldCBub2RlT3B0aW9ucyA9IHByb2Nlc3MuZW52Lk5PREVfT1BUSU9OUyB8fCAnJztcbiAgaWYoaXNFU00pIHtcbiAgICBpZighbm9kZU9wdGlvbnMuaW5jbHVkZXMoJy0tZXhwZXJpbWVudGFsLXZtLW1vZHVsZXMnKSkge1xuICAgICAgbm9kZU9wdGlvbnMgPSBgJHtub2RlT3B0aW9uc30gLS1leHBlcmltZW50YWwtdm0tbW9kdWxlc2AudHJpbSgpO1xuICAgIH1cbiAgICBsb2coJ0VTTSBwcm9qZWN0IGRldGVjdGVkLCB1c2luZyAtLWV4cGVyaW1lbnRhbC12bS1tb2R1bGVzIGluIE5PREVfT1BUSU9OUycsICdpbmZvJywgcXVpZXQpO1xuICB9XG5cbiAgbGV0IHRlbXBPdXRwdXRGaWxlID0gb3V0cHV0RmlsZTtcblxuICB0cnkge1xuICAgIGNvbnN0IHByb2Nlc3NFbnY6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgICAuLi5wcm9jZXNzLmVudixcbiAgICAgIE5PREVfT1BUSU9OUzogbm9kZU9wdGlvbnNcbiAgICB9O1xuXG4gICAgaWYoY29sb3JzKSB7XG4gICAgICBwcm9jZXNzRW52LkZPUkNFX0NPTE9SID0gJzEnO1xuICAgIH1cblxuICAgIGlmKGNpKSB7XG4gICAgICBwcm9jZXNzRW52LkNJID0gJ3RydWUnO1xuICAgIH1cblxuICAgIGlmKHJ1blVuaXQpIHtcbiAgICAgIGNvbnN0IHByb2plY3RWaXRlc3RCaW4gPSBwYXRoUmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCAnbm9kZV9tb2R1bGVzLy5iaW4vdml0ZXN0Jyk7XG4gICAgICBsZXQgdml0ZXN0UGF0aDogc3RyaW5nO1xuXG4gICAgICBpZihleGlzdHNTeW5jKHByb2plY3RWaXRlc3RCaW4pKSB7XG4gICAgICAgIHZpdGVzdFBhdGggPSBwcm9qZWN0Vml0ZXN0QmluO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdml0ZXN0UGF0aCA9IHJlc29sdmVCaW5hcnlQYXRoKCd2aXRlc3QnKTtcbiAgICAgIH1cblxuICAgICAgaWYoIXZpdGVzdFBhdGgpIHtcbiAgICAgICAgbG9nKGBcXG4ke2NsaU5hbWV9IEVycm9yOiBWaXRlc3QgYmluYXJ5IG5vdCBmb3VuZCBpbiBMZXgncyBub2RlX21vZHVsZXMgb3IgbW9ub3JlcG8gcm9vdGAsICdlcnJvcicsIHF1aWV0KTtcbiAgICAgICAgbG9nKCdQbGVhc2UgcmVpbnN0YWxsIExleCBvciBjaGVjayB5b3VyIGluc3RhbGxhdGlvbi4nLCAnaW5mbycsIHF1aWV0KTtcbiAgICAgICAgY2FsbGJhY2soMSk7XG4gICAgICAgIHJldHVybiAxO1xuICAgICAgfVxuXG4gICAgICBsZXQgdml0ZXN0Q29uZmlnRmlsZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgICAgbGV0IHByb2plY3RWaXRlc3RDb25maWc6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgbnVsbCA9IG51bGw7XG5cbiAgICAgIGlmKGNvbmZpZykge1xuICAgICAgICB2aXRlc3RDb25maWdGaWxlID0gY29uZmlnO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgcHJvamVjdFZpdGVzdENvbmZpZ1BhdGhzID0gW1xuICAgICAgICAgIHBhdGhSZXNvbHZlKHByb2Nlc3MuY3dkKCksICd2aXRlc3QuY29uZmlnLnRzJyksXG4gICAgICAgICAgcGF0aFJlc29sdmUocHJvY2Vzcy5jd2QoKSwgJ3ZpdGVzdC5jb25maWcubXRzJyksXG4gICAgICAgICAgcGF0aFJlc29sdmUocHJvY2Vzcy5jd2QoKSwgJ3ZpdGVzdC5jb25maWcuanMnKSxcbiAgICAgICAgICBwYXRoUmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCAndml0ZXN0LmNvbmZpZy5tanMnKSxcbiAgICAgICAgICBwYXRoUmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCAndml0ZXN0LmNvbmZpZy5janMnKVxuICAgICAgICBdO1xuICAgICAgICBjb25zdCBleGlzdGluZ0NvbmZpZ1BhdGggPSBwcm9qZWN0Vml0ZXN0Q29uZmlnUGF0aHMuZmluZCgoY29uZmlnUGF0aCkgPT4gZXhpc3RzU3luYyhjb25maWdQYXRoKSk7XG5cbiAgICAgICAgaWYoZXhpc3RpbmdDb25maWdQYXRoKSB7XG4gICAgICAgICAgdml0ZXN0Q29uZmlnRmlsZSA9IGV4aXN0aW5nQ29uZmlnUGF0aDtcbiAgICAgICAgICBpZihkZWJ1Zykge1xuICAgICAgICAgICAgbG9nKGBVc2luZyBwcm9qZWN0IFZpdGVzdCBjb25maWcgZmlsZTogJHt2aXRlc3RDb25maWdGaWxlfWAsICdpbmZvJywgcXVpZXQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwcm9qZWN0Vml0ZXN0Q29uZmlnID0gTGV4Q29uZmlnLmNvbmZpZy52aXRlc3QgfHwgbnVsbDtcblxuICAgICAgICAgIGNvbnN0IGxleERpciA9IExleENvbmZpZy5nZXRMZXhEaXIoKTtcbiAgICAgICAgICBjb25zdCBsZXhWaXRlc3RDb25maWcgPSBwYXRoUmVzb2x2ZShsZXhEaXIsICd2aXRlc3QuY29uZmlnLm1qcycpO1xuXG4gICAgICAgICAgaWYoZGVidWcpIHtcbiAgICAgICAgICAgIGxvZyhgTG9va2luZyBmb3IgVml0ZXN0IGNvbmZpZyBhdDogJHtsZXhWaXRlc3RDb25maWd9YCwgJ2luZm8nLCBxdWlldCk7XG4gICAgICAgICAgICBsb2coYEZpbGUgZXhpc3RzOiAke2V4aXN0c1N5bmMobGV4Vml0ZXN0Q29uZmlnKX1gLCAnaW5mbycsIHF1aWV0KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZihleGlzdHNTeW5jKGxleFZpdGVzdENvbmZpZykpIHtcbiAgICAgICAgICAgIHZpdGVzdENvbmZpZ0ZpbGUgPSBsZXhWaXRlc3RDb25maWc7XG4gICAgICAgICAgICBpZihwcm9qZWN0Vml0ZXN0Q29uZmlnICYmIE9iamVjdC5rZXlzKHByb2plY3RWaXRlc3RDb25maWcpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgaWYoZGVidWcpIHtcbiAgICAgICAgICAgICAgICBsb2coYFVzaW5nIExleCBWaXRlc3QgY29uZmlnIHdpdGggcHJvamVjdCBWaXRlc3QgY29uZmlnIGZyb20gbGV4LmNvbmZpZy5janM6ICR7dml0ZXN0Q29uZmlnRmlsZX1gLCAnaW5mbycsIHF1aWV0KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmKGRlYnVnKSB7XG4gICAgICAgICAgICAgIGxvZyhgVXNpbmcgTGV4IFZpdGVzdCBjb25maWcgKG5vIHByb2plY3QgVml0ZXN0IGNvbmZpZyBmb3VuZCk6ICR7dml0ZXN0Q29uZmlnRmlsZX1gLCAnaW5mbycsIHF1aWV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2UgaWYoZGVidWcpIHtcbiAgICAgICAgICAgIGxvZygnTm8gVml0ZXN0IGNvbmZpZyBmb3VuZCBpbiBwcm9qZWN0IG9yIExleCcsICd3YXJuJywgcXVpZXQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZihzaG93Q29uZmlnKSB7XG4gICAgICAgIGlmKHZpdGVzdENvbmZpZ0ZpbGUpIHtcbiAgICAgICAgICBjb25zdCByZXNvbHZlZENvbmZpZyA9IGF3YWl0IGltcG9ydCh2aXRlc3RDb25maWdGaWxlKTtcbiAgICAgICAgICBsb2coSlNPTi5zdHJpbmdpZnkocmVzb2x2ZWRDb25maWcuZGVmYXVsdCA/PyByZXNvbHZlZENvbmZpZywgbnVsbCwgMiksICdpbmZvJywgcXVpZXQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGxvZyhKU09OLnN0cmluZ2lmeSh7dGVzdDogcHJvamVjdFZpdGVzdENvbmZpZyA/PyB7fX0sIG51bGwsIDIpLCAnaW5mbycsIHF1aWV0KTtcbiAgICAgICAgfVxuICAgICAgICBjYWxsYmFjaygwKTtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHZpdGVzdFNldHVwRmlsZTogc3RyaW5nID0gc2V0dXAgfHwgcGF0aFJlc29sdmUocHJvY2Vzcy5jd2QoKSwgJ3ZpdGVzdC5zZXR1cC5qcycpO1xuICAgICAgY29uc3Qgdml0ZXN0QXJnczogc3RyaW5nW10gPSBbXTtcbiAgICAgIGNvbnN0IHZpdGVzdE9wdGlvbnM6IHN0cmluZ1tdID0gW107XG4gICAgICBjb25zdCByZXBvcnRlcnMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICAgIGNvbnN0IGZpbHRlcnM6IHN0cmluZ1tdID0gW107XG4gICAgICBjb25zdCB3YXRjaE1vZGUgPSBCb29sZWFuKHdhdGNoIHx8IHdhdGNoQWxsKTtcbiAgICAgIGNvbnN0IGxpc3RNb2RlID0gQm9vbGVhbihsaXN0VGVzdHMpO1xuXG4gICAgICBpZihsaXN0TW9kZSkge1xuICAgICAgICB2aXRlc3RBcmdzLnB1c2goJ2xpc3QnKTtcbiAgICAgIH0gZWxzZSBpZih3YXRjaE1vZGUpIHtcbiAgICAgICAgdml0ZXN0QXJncy5wdXNoKCd3YXRjaCcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdml0ZXN0QXJncy5wdXNoKCdydW4nKTtcbiAgICAgIH1cblxuICAgICAgaWYodml0ZXN0Q29uZmlnRmlsZSkge1xuICAgICAgICB2aXRlc3RPcHRpb25zLnB1c2goJy0tY29uZmlnJywgdml0ZXN0Q29uZmlnRmlsZSk7XG4gICAgICB9XG5cbiAgICAgIGlmKGJhaWwpIHtcbiAgICAgICAgdml0ZXN0T3B0aW9ucy5wdXNoKCctLWJhaWwnLCAnMScpO1xuICAgICAgfVxuXG4gICAgICBpZihjaGFuZ2VkRmlsZXNXaXRoQW5jZXN0b3IpIHtcbiAgICAgICAgdml0ZXN0T3B0aW9ucy5wdXNoKCctLWNoYW5nZWQnKTtcbiAgICAgIH1cblxuICAgICAgaWYoY2hhbmdlZFNpbmNlKSB7XG4gICAgICAgIHZpdGVzdE9wdGlvbnMucHVzaCgnLS1jaGFuZ2VkJywgY2hhbmdlZFNpbmNlKTtcbiAgICAgIH1cblxuICAgICAgaWYoY2kpIHtcbiAgICAgICAgdml0ZXN0T3B0aW9ucy5wdXNoKCctLXJ1bicpO1xuICAgICAgfVxuXG4gICAgICBpZihjb2xsZWN0Q292ZXJhZ2VGcm9tKSB7XG4gICAgICAgIHZpdGVzdE9wdGlvbnMucHVzaCgnLS1jb3ZlcmFnZScsICctLWNvdmVyYWdlLmluY2x1ZGUnLCBjb2xsZWN0Q292ZXJhZ2VGcm9tKTtcbiAgICAgIH1cblxuICAgICAgaWYoZGVidWcpIHtcbiAgICAgICAgdml0ZXN0T3B0aW9ucy5wdXNoKCctLWluc3BlY3QnKTtcbiAgICAgIH1cblxuICAgICAgaWYoZGV0ZWN0T3BlbkhhbmRsZXMpIHtcbiAgICAgICAgcmVwb3J0ZXJzLmFkZCgnaGFuZ2luZy1wcm9jZXNzJyk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGVudmlyb25tZW50TmFtZSA9IGVudmlyb25tZW50IHx8IGVudjtcbiAgICAgIGlmKGVudmlyb25tZW50TmFtZSkge1xuICAgICAgICB2aXRlc3RPcHRpb25zLnB1c2goJy0tZW52aXJvbm1lbnQnLCBlbnZpcm9ubWVudE5hbWUpO1xuICAgICAgfVxuXG4gICAgICBpZihlcnJvck9uRGVwcmVjYXRlZCkge1xuICAgICAgICBsb2coJ1ZpdGVzdCBkb2VzIG5vdCBzdXBwb3J0IC0tZXJyb3JPbkRlcHJlY2F0ZWQ7IG9wdGlvbiBpZ25vcmVkLicsICd3YXJuJywgcXVpZXQpO1xuICAgICAgfVxuXG4gICAgICBpZihleHBhbmQpIHtcbiAgICAgICAgdml0ZXN0T3B0aW9ucy5wdXNoKCctLWV4cGFuZFNuYXBzaG90RGlmZicpO1xuICAgICAgfVxuXG4gICAgICBpZihmb3JjZUV4aXQpIHtcbiAgICAgICAgbG9nKCdWaXRlc3QgZG9lcyBub3Qgc3VwcG9ydCAtLWZvcmNlRXhpdDsgb3B0aW9uIGlnbm9yZWQuJywgJ3dhcm4nLCBxdWlldCk7XG4gICAgICB9XG5cbiAgICAgIGlmKGxhc3RDb21taXQpIHtcbiAgICAgICAgdml0ZXN0T3B0aW9ucy5wdXNoKCctLWNoYW5nZWQnKTtcbiAgICAgIH1cblxuICAgICAgaWYobG9nSGVhcFVzYWdlKSB7XG4gICAgICAgIHZpdGVzdE9wdGlvbnMucHVzaCgnLS1sb2dIZWFwVXNhZ2UnKTtcbiAgICAgIH1cblxuICAgICAgaWYobWF4V29ya2Vycykge1xuICAgICAgICB2aXRlc3RPcHRpb25zLnB1c2goJy0tbWF4V29ya2VycycsIG1heFdvcmtlcnMpO1xuICAgICAgfVxuXG4gICAgICBpZihub1N0YWNrVHJhY2UpIHtcbiAgICAgICAgbG9nKCdWaXRlc3QgZG9lcyBub3Qgc3VwcG9ydCAtLW5vU3RhY2tUcmFjZTsgb3B0aW9uIGlnbm9yZWQuJywgJ3dhcm4nLCBxdWlldCk7XG4gICAgICB9XG5cbiAgICAgIGlmKG5vdGlmeSkge1xuICAgICAgICBsb2coJ1ZpdGVzdCBkb2VzIG5vdCBzdXBwb3J0IC0tbm90aWZ5OyBvcHRpb24gaWdub3JlZC4nLCAnd2FybicsIHF1aWV0KTtcbiAgICAgIH1cblxuICAgICAgaWYob25seUNoYW5nZWQpIHtcbiAgICAgICAgdml0ZXN0T3B0aW9ucy5wdXNoKCctLWNoYW5nZWQnKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc2hvdWxkV3JpdGVKc29uID0ganNvbiB8fCB1c2VBbmFseXplIHx8IHVzZURlYnVnIHx8IEJvb2xlYW4ob3V0cHV0RmlsZSk7XG5cbiAgICAgIGlmKHNob3VsZFdyaXRlSnNvbikge1xuICAgICAgICB0ZW1wT3V0cHV0RmlsZSA9IG91dHB1dEZpbGUgfHwgJy5sZXgtdGVzdC1yZXN1bHRzLmpzb24nO1xuICAgICAgICB2aXRlc3RPcHRpb25zLnB1c2goJy0tb3V0cHV0RmlsZScsIHRlbXBPdXRwdXRGaWxlKTtcbiAgICAgICAgcmVwb3J0ZXJzLmFkZCgnanNvbicpO1xuICAgICAgfVxuXG4gICAgICBpZihwYXNzV2l0aE5vVGVzdHMpIHtcbiAgICAgICAgdml0ZXN0T3B0aW9ucy5wdXNoKCctLXBhc3NXaXRoTm9UZXN0cycpO1xuICAgICAgfVxuXG4gICAgICBpZihydW5JbkJhbmQpIHtcbiAgICAgICAgdml0ZXN0T3B0aW9ucy5wdXNoKCctLW5vLWZpbGUtcGFyYWxsZWxpc20nLCAnLS1tYXhXb3JrZXJzJywgJzEnKTtcbiAgICAgIH1cblxuICAgICAgaWYoc2lsZW50KSB7XG4gICAgICAgIHZpdGVzdE9wdGlvbnMucHVzaCgnLS1zaWxlbnQnKTtcbiAgICAgIH1cblxuICAgICAgaWYodGVzdExvY2F0aW9uSW5SZXN1bHRzKSB7XG4gICAgICAgIHZpdGVzdE9wdGlvbnMucHVzaCgnLS1pbmNsdWRlVGFza0xvY2F0aW9uJyk7XG4gICAgICB9XG5cbiAgICAgIGlmKHRlc3ROYW1lUGF0dGVybikge1xuICAgICAgICB2aXRlc3RPcHRpb25zLnB1c2goJy0tdGVzdE5hbWVQYXR0ZXJuJywgdGVzdE5hbWVQYXR0ZXJuKTtcbiAgICAgIH1cblxuICAgICAgaWYodGVzdFBhdGhQYXR0ZXJuKSB7XG4gICAgICAgIGZpbHRlcnMucHVzaCh0ZXN0UGF0aFBhdHRlcm4pO1xuICAgICAgfVxuXG4gICAgICBpZih1c2VTdGRlcnIpIHtcbiAgICAgICAgbG9nKCdWaXRlc3QgZG9lcyBub3Qgc3VwcG9ydCAtLXVzZVN0ZGVycjsgb3B0aW9uIGlnbm9yZWQuJywgJ3dhcm4nLCBxdWlldCk7XG4gICAgICB9XG5cbiAgICAgIGlmKHZlcmJvc2UpIHtcbiAgICAgICAgcmVwb3J0ZXJzLmFkZCgndmVyYm9zZScpO1xuICAgICAgfVxuXG4gICAgICBpZihyZW1vdmVDYWNoZSB8fCBjbGVhckNhY2hlKSB7XG4gICAgICAgIHZpdGVzdE9wdGlvbnMucHVzaCgnLS1jbGVhckNhY2hlJyk7XG4gICAgICB9XG5cbiAgICAgIGlmKHVwZGF0ZSkge1xuICAgICAgICB2aXRlc3RPcHRpb25zLnB1c2goJy0tdXBkYXRlJyk7XG4gICAgICB9XG5cbiAgICAgIGlmKHdhdGNoKSB7XG4gICAgICAgIGZpbHRlcnMucHVzaCh3YXRjaCk7XG4gICAgICB9XG5cbiAgICAgIGlmKGFyZ3MpIHtcbiAgICAgICAgdml0ZXN0T3B0aW9ucy5wdXNoKC4uLmFyZ3MpO1xuICAgICAgfVxuXG4gICAgICBpZihmaWxlcyAmJiBmaWxlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGZpbHRlcnMucHVzaCguLi5maWxlcy5maWx0ZXIoKGZpbGUpID0+ICEvXFwuZTJlXFwuLy50ZXN0KGZpbGUpKSk7XG4gICAgICB9XG5cbiAgICAgIGlmKHJlcG9ydGVycy5zaXplID4gMCkge1xuICAgICAgICBjb25zdCByZXBvcnRlckxpc3QgPSBBcnJheS5mcm9tKHJlcG9ydGVycyk7XG4gICAgICAgIGlmKHJlcG9ydGVyTGlzdC5pbmNsdWRlcygnanNvbicpICYmICFyZXBvcnRlckxpc3QuaW5jbHVkZXMoJ3ZlcmJvc2UnKSkge1xuICAgICAgICAgIHJlcG9ydGVyTGlzdC51bnNoaWZ0KCdkZWZhdWx0Jyk7XG4gICAgICAgIH1cbiAgICAgICAgcmVwb3J0ZXJMaXN0LmZvckVhY2goKHJlcG9ydGVyKSA9PiB2aXRlc3RPcHRpb25zLnB1c2goJy0tcmVwb3J0ZXInLCByZXBvcnRlcikpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBmaW5hbEFyZ3MgPSBbLi4udml0ZXN0QXJncywgLi4udml0ZXN0T3B0aW9ucywgLi4uZmlsdGVyc107XG5cbiAgICAgIGlmKGRlYnVnKSB7XG4gICAgICAgIGxvZyhgVml0ZXN0IG9wdGlvbnM6ICR7ZmluYWxBcmdzLmpvaW4oJyAnKX1gLCAnaW5mbycsIHF1aWV0KTtcbiAgICAgICAgbG9nKGBOT0RFX09QVElPTlM6ICR7bm9kZU9wdGlvbnN9YCwgJ2luZm8nLCBxdWlldCk7XG4gICAgICB9XG5cbiAgICAgIGlmKHZpdGVzdFNldHVwRmlsZSAmJiBleGlzdHNTeW5jKHZpdGVzdFNldHVwRmlsZSkpIHtcbiAgICAgICAgcHJvY2Vzc0Vudi5MRVhfVklURVNUX1NFVFVQID0gdml0ZXN0U2V0dXBGaWxlO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCBleGVjYSh2aXRlc3RQYXRoLCBmaW5hbEFyZ3MsIHtcbiAgICAgICAgZW5jb2Rpbmc6ICd1dGY4JyxcbiAgICAgICAgZW52OiBwcm9jZXNzRW52LFxuICAgICAgICBzdGRpbzogJ2luaGVyaXQnXG4gICAgICB9KTtcblxuICAgICAgaWYodXNlQW5hbHl6ZSkge1xuICAgICAgICBzcGlubmVyLnN0YXJ0KCdBSSBpcyBhbmFseXppbmcgdGVzdCBjb3ZlcmFnZSBhbmQgc3VnZ2VzdGluZyBpbXByb3ZlbWVudHMuLi4nKTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHRlc3RSZXN1bHRzID0gcHJvY2Vzc1Rlc3RSZXN1bHRzKHRlbXBPdXRwdXRGaWxlKTtcbiAgICAgICAgICBjb25zdCBmaWxlUGF0dGVybnMgPSBnZXRUZXN0RmlsZVBhdHRlcm5zKHRlc3RQYXRoUGF0dGVybik7XG5cbiAgICAgICAgICBhd2FpdCBhaUZ1bmN0aW9uKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRydWUsXG4gICAgICAgICAgICBwcm9tcHQ6IGBBbmFseXplIHRoZXNlIFZpdGVzdCB0ZXN0IHJlc3VsdHMgYW5kIHN1Z2dlc3QgdGVzdCBjb3ZlcmFnZSBpbXByb3ZlbWVudHM6XG5cbiR7SlNPTi5zdHJpbmdpZnkodGVzdFJlc3VsdHMsIG51bGwsIDIpfVxuXG5UZXN0IHBhdHRlcm5zOiAke2ZpbGVQYXR0ZXJucy5qb2luKCcsICcpfVxuXG5QbGVhc2UgcHJvdmlkZTpcbjEuIEFuYWx5c2lzIG9mIGN1cnJlbnQgY292ZXJhZ2UgZ2Fwc1xuMi4gU3VnZ2VzdGlvbnMgZm9yIGltcHJvdmluZyB0ZXN0IGNhc2VzXG4zLiBSZWNvbW1lbmRhdGlvbnMgZm9yIGFkZGl0aW9uYWwgaW50ZWdyYXRpb24gdGVzdCBzY2VuYXJpb3NcbjQuIEJlc3QgcHJhY3RpY2VzIGZvciBpbmNyZWFzaW5nIHRlc3QgZWZmZWN0aXZlbmVzc2AsXG4gICAgICAgICAgICBxdWlldCxcbiAgICAgICAgICAgIHRhc2s6ICdvcHRpbWl6ZSdcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHNwaW5uZXIuc3VjY2VlZCgnQUkgdGVzdCBhbmFseXNpcyBjb21wbGV0ZScpO1xuICAgICAgICB9IGNhdGNoKGFpRXJyb3IpIHtcbiAgICAgICAgICBzcGlubmVyLmZhaWwoJ0NvdWxkIG5vdCBnZW5lcmF0ZSBBSSB0ZXN0IGFuYWx5c2lzJyk7XG4gICAgICAgICAgaWYoIXF1aWV0KSB7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgICAgICAgY29uc29sZS5lcnJvcignQUkgYW5hbHlzaXMgZXJyb3I6JywgYWlFcnJvcik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYocnVuRTJFKSB7XG4gICAgICBjb25zdCBwcm9qZWN0UGxheXdyaWdodEJpbiA9IHBhdGhSZXNvbHZlKHByb2Nlc3MuY3dkKCksICdub2RlX21vZHVsZXMvLmJpbi9wbGF5d3JpZ2h0Jyk7XG4gICAgICBsZXQgcGxheXdyaWdodFBhdGg6IHN0cmluZztcblxuICAgICAgaWYoZXhpc3RzU3luYyhwcm9qZWN0UGxheXdyaWdodEJpbikpIHtcbiAgICAgICAgcGxheXdyaWdodFBhdGggPSBwcm9qZWN0UGxheXdyaWdodEJpbjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBsYXl3cmlnaHRQYXRoID0gcmVzb2x2ZUJpbmFyeVBhdGgoJ3BsYXl3cmlnaHQnKTtcbiAgICAgIH1cblxuICAgICAgaWYoIXBsYXl3cmlnaHRQYXRoKSB7XG4gICAgICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBFcnJvcjogUGxheXdyaWdodCBiaW5hcnkgbm90IGZvdW5kIGluIExleCdzIG5vZGVfbW9kdWxlcyBvciBtb25vcmVwbyByb290YCwgJ2Vycm9yJywgcXVpZXQpO1xuICAgICAgICBsb2coJ1BsZWFzZSBpbnN0YWxsIEBwbGF5d3JpZ2h0L3Rlc3QgdG8gcnVuIEUyRSB0ZXN0cy4nLCAnaW5mbycsIHF1aWV0KTtcbiAgICAgICAgY2FsbGJhY2soMSk7XG4gICAgICAgIHJldHVybiAxO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBlMmVDb25maWdQYXRocyA9IFtcbiAgICAgICAgcGF0aFJlc29sdmUocHJvY2Vzcy5jd2QoKSwgJ3BsYXl3cmlnaHQuY29uZmlnLnRzJyksXG4gICAgICAgIHBhdGhSZXNvbHZlKHByb2Nlc3MuY3dkKCksICdwbGF5d3JpZ2h0LmNvbmZpZy5tdHMnKSxcbiAgICAgICAgcGF0aFJlc29sdmUocHJvY2Vzcy5jd2QoKSwgJ3BsYXl3cmlnaHQuY29uZmlnLmpzJyksXG4gICAgICAgIHBhdGhSZXNvbHZlKHByb2Nlc3MuY3dkKCksICdwbGF5d3JpZ2h0LmNvbmZpZy5tanMnKSxcbiAgICAgICAgcGF0aFJlc29sdmUocHJvY2Vzcy5jd2QoKSwgJ3BsYXl3cmlnaHQuY29uZmlnLmNqcycpXG4gICAgICBdO1xuICAgICAgY29uc3QgcGxheXdyaWdodENvbmZpZ0ZpbGUgPSBlMmVDb25maWcgfHwgZTJlQ29uZmlnUGF0aHMuZmluZCgoY29uZmlnUGF0aCkgPT4gZXhpc3RzU3luYyhjb25maWdQYXRoKSk7XG4gICAgICBjb25zdCBwbGF5d3JpZ2h0QXJncyA9IFsndGVzdCddO1xuXG4gICAgICBpZihwbGF5d3JpZ2h0Q29uZmlnRmlsZSkge1xuICAgICAgICBwbGF5d3JpZ2h0QXJncy5wdXNoKCctLWNvbmZpZycsIHBsYXl3cmlnaHRDb25maWdGaWxlKTtcbiAgICAgIH1cblxuICAgICAgaWYobGlzdFRlc3RzKSB7XG4gICAgICAgIHBsYXl3cmlnaHRBcmdzLnB1c2goJy0tbGlzdCcpO1xuICAgICAgfVxuXG4gICAgICBpZihwYXNzV2l0aE5vVGVzdHMpIHtcbiAgICAgICAgcGxheXdyaWdodEFyZ3MucHVzaCgnLS1wYXNzLXdpdGgtbm8tdGVzdHMnKTtcbiAgICAgIH1cblxuICAgICAgaWYodGVzdE5hbWVQYXR0ZXJuKSB7XG4gICAgICAgIHBsYXl3cmlnaHRBcmdzLnB1c2goJy0tZ3JlcCcsIHRlc3ROYW1lUGF0dGVybik7XG4gICAgICB9XG5cbiAgICAgIGlmKG1heFdvcmtlcnMpIHtcbiAgICAgICAgcGxheXdyaWdodEFyZ3MucHVzaCgnLS13b3JrZXJzJywgbWF4V29ya2Vycyk7XG4gICAgICB9XG5cbiAgICAgIGlmKHJ1bkluQmFuZCkge1xuICAgICAgICBwbGF5d3JpZ2h0QXJncy5wdXNoKCctLXdvcmtlcnMnLCAnMScpO1xuICAgICAgfVxuXG4gICAgICBpZih1cGRhdGUpIHtcbiAgICAgICAgcGxheXdyaWdodEFyZ3MucHVzaCgnLS11cGRhdGUtc25hcHNob3RzJyk7XG4gICAgICB9XG5cbiAgICAgIGlmKHRlc3RQYXRoUGF0dGVybikge1xuICAgICAgICBwbGF5d3JpZ2h0QXJncy5wdXNoKHRlc3RQYXRoUGF0dGVybik7XG4gICAgICB9XG5cbiAgICAgIGlmKGZpbGVzICYmIGZpbGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcGxheXdyaWdodEFyZ3MucHVzaCguLi5maWxlcy5maWx0ZXIoKGZpbGUpID0+IC9cXC5lMmVcXC4vLnRlc3QoZmlsZSkpKTtcbiAgICAgIH1cblxuICAgICAgaWYoZGVidWcpIHtcbiAgICAgICAgbG9nKGBQbGF5d3JpZ2h0IG9wdGlvbnM6ICR7cGxheXdyaWdodEFyZ3Muam9pbignICcpfWAsICdpbmZvJywgcXVpZXQpO1xuICAgICAgfVxuXG4gICAgICBpZih1c2VHZW5lcmF0ZSB8fCB1c2VBbmFseXplIHx8IHVzZURlYnVnKSB7XG4gICAgICAgIGxvZygnQUkgdGVzdCBoZWxwZXJzIGN1cnJlbnRseSBhcHBseSB0byBWaXRlc3QgdW5pdCB0ZXN0IHJ1bnMgb25seTsgc2tpcHBpbmcgdGhlbSBmb3IgUGxheXdyaWdodCBFMkUuJywgJ3dhcm4nLCBxdWlldCk7XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IGV4ZWNhKHBsYXl3cmlnaHRQYXRoLCBwbGF5d3JpZ2h0QXJncywge1xuICAgICAgICBlbmNvZGluZzogJ3V0ZjgnLFxuICAgICAgICBlbnY6IHByb2Nlc3NFbnYsXG4gICAgICAgIHN0ZGlvOiAnaW5oZXJpdCdcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHNwaW5uZXIuc3VjY2VlZCgnVGVzdGluZyBjb21wbGV0ZWQhJyk7XG5cbiAgICBjYWxsYmFjaygwKTtcbiAgICByZXR1cm4gMDtcbiAgfSBjYXRjaChlcnJvcikge1xuICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKTtcblxuICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBFcnJvcjogQ2hlY2sgZm9yIHRlc3QgZmFpbHVyZXMgYW5kIGNvdmVyYWdlIGlzc3Vlcy5gLCAnZXJyb3InLCBxdWlldCk7XG5cbiAgICBzcGlubmVyLmZhaWwoJ1Rlc3RpbmcgZmFpbGVkIScpO1xuXG4gICAgaWYodXNlRGVidWcgJiYgcnVuVW5pdCkge1xuICAgICAgc3Bpbm5lci5zdGFydCgnQUkgaXMgYW5hbHl6aW5nIHRlc3QgZmFpbHVyZXMuLi4nKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgdGVzdFJlc3VsdHMgPSBwcm9jZXNzVGVzdFJlc3VsdHModGVtcE91dHB1dEZpbGUpO1xuXG4gICAgICAgIGF3YWl0IGFpRnVuY3Rpb24oe1xuICAgICAgICAgIGNvbnRleHQ6IHRydWUsXG4gICAgICAgICAgcHJvbXB0OiBgRGVidWcgdGhlc2UgZmFpbGVkIFZpdGVzdCB0ZXN0cyBhbmQgc3VnZ2VzdCBmaXhlczpcblxuJHtKU09OLnN0cmluZ2lmeShlcnJvck1lc3NhZ2UsIG51bGwsIDIpfVxuXG5UZXN0IHJlc3VsdHM6ICR7SlNPTi5zdHJpbmdpZnkodGVzdFJlc3VsdHMsIG51bGwsIDIpfVxuXG5QbGVhc2UgcHJvdmlkZTpcbjEuIEFuYWx5c2lzIG9mIHdoeSB0aGUgdGVzdHMgYXJlIGZhaWxpbmdcbjIuIFNwZWNpZmljIHN1Z2dlc3Rpb25zIHRvIGZpeCBlYWNoIGZhaWxpbmcgdGVzdFxuMy4gQW55IHBvdGVudGlhbCBpc3N1ZXMgd2l0aCB0ZXN0IGZpeHR1cmVzIG9yIG1vY2tzXG40LiBDb2RlIGV4YW1wbGVzIGZvciBzb2x1dGlvbnNgLFxuICAgICAgICAgIHF1aWV0LFxuICAgICAgICAgIHRhc2s6ICdoZWxwJ1xuICAgICAgICB9KTtcblxuICAgICAgICBzcGlubmVyLnN1Y2NlZWQoJ0FJIGRlYnVnZ2luZyBhc3Npc3RhbmNlIGNvbXBsZXRlJyk7XG4gICAgICB9IGNhdGNoKGFpRXJyb3IpIHtcbiAgICAgICAgc3Bpbm5lci5mYWlsKCdDb3VsZCBub3QgZ2VuZXJhdGUgQUkgZGVidWdnaW5nIGFzc2lzdGFuY2UnKTtcbiAgICAgICAgaWYoIXF1aWV0KSB7XG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgICBjb25zb2xlLmVycm9yKCdBSSBkZWJ1Z2dpbmcgZXJyb3I6JywgYWlFcnJvcik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYodXNlRGVidWcgJiYgcnVuRTJFKSB7XG4gICAgICBsb2coJ0FJIGRlYnVnZ2luZyBhc3Npc3RhbmNlIGN1cnJlbnRseSBzdXBwb3J0cyBWaXRlc3QgdW5pdCBydW5zIG9ubHkuJywgJ3dhcm4nLCBxdWlldCk7XG4gICAgfVxuXG4gICAgY2FsbGJhY2soMSk7XG4gICAgcmV0dXJuIDE7XG4gIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IHRlc3Q7XG4iXSwibmFtZXMiOlsiZXhlY2EiLCJleGlzdHNTeW5jIiwicmVhZEZpbGVTeW5jIiwic3luYyIsImdsb2JTeW5jIiwicmVzb2x2ZSIsInBhdGhSZXNvbHZlIiwiTGV4Q29uZmlnIiwiZ2V0VHlwZVNjcmlwdENvbmZpZ1BhdGgiLCJjcmVhdGVTcGlubmVyIiwicmVzb2x2ZUJpbmFyeVBhdGgiLCJsb2ciLCJhaUZ1bmN0aW9uIiwiZGV0ZWN0RVNNIiwiY3dkIiwicGFja2FnZUpzb25QYXRoIiwicGFja2FnZUpzb25Db250ZW50IiwicGFja2FnZUpzb24iLCJKU09OIiwicGFyc2UiLCJ0eXBlIiwiX2Vycm9yIiwiZGVmYXVsdEV4aXQiLCJjb2RlIiwicHJvY2VzcyIsImVudiIsIlZJVEVTVCIsIlZJVEVTVF9XT1JLRVJfSUQiLCJOT0RFX0VOViIsInVuZGVmaW5lZCIsImV4aXQiLCJnZXRUZXN0RmlsZVBhdHRlcm5zIiwidGVzdFBhdGhQYXR0ZXJuIiwiZGVmYXVsdFBhdHRlcm5zIiwiZ2V0RTJFVGVzdEZpbGVQYXR0ZXJucyIsImZpbmRVbmNvdmVyZWRTb3VyY2VGaWxlcyIsInNvdXJjZUZpbGVzIiwiaWdub3JlIiwidGVzdEZpbGVzIiwiZmlsdGVyIiwic291cmNlRmlsZSIsImJhc2VOYW1lIiwicmVwbGFjZSIsInNvbWUiLCJ0ZXN0RmlsZSIsImluY2x1ZGVzIiwicHJvY2Vzc1Rlc3RSZXN1bHRzIiwib3V0cHV0RmlsZSIsImNvbnRlbnQiLCJ0ZXN0Iiwib3B0aW9ucyIsImFyZ3MiLCJmaWxlc09yQ2FsbGJhY2siLCJjYWxsYmFja1BhcmFtIiwiZmlsZXMiLCJjYWxsYmFjayIsImFuYWx5emUiLCJhaUFuYWx5emUiLCJhaURlYnVnIiwiYWlHZW5lcmF0ZSIsImJhaWwiLCJjaGFuZ2VkRmlsZXNXaXRoQW5jZXN0b3IiLCJjaGFuZ2VkU2luY2UiLCJjaSIsImNsZWFyQ2FjaGUiLCJjbGlOYW1lIiwiY29sbGVjdENvdmVyYWdlRnJvbSIsImNvbG9ycyIsImNvbmZpZyIsImRlYnVnIiwiZGVidWdUZXN0cyIsImRldGVjdE9wZW5IYW5kbGVzIiwiZTJlIiwiZTJlQ29uZmlnIiwiZW52aXJvbm1lbnQiLCJlcnJvck9uRGVwcmVjYXRlZCIsImV4cGFuZCIsImZvcmNlRXhpdCIsImdlbmVyYXRlIiwianNvbiIsImxhc3RDb21taXQiLCJsaXN0VGVzdHMiLCJsb2dIZWFwVXNhZ2UiLCJtYXhXb3JrZXJzIiwibm9TdGFja1RyYWNlIiwibm90aWZ5Iiwib25seUNoYW5nZWQiLCJwYXNzV2l0aE5vVGVzdHMiLCJxdWlldCIsInJlbW92ZUNhY2hlIiwicnVuSW5CYW5kIiwic2V0dXAiLCJzaG93Q29uZmlnIiwic2lsZW50IiwidGVzdExvY2F0aW9uSW5SZXN1bHRzIiwidGVzdE5hbWVQYXR0ZXJuIiwidW5pdCIsInVwZGF0ZSIsInVzZVN0ZGVyciIsInZlcmJvc2UiLCJ3YXRjaCIsIndhdGNoQWxsIiwidXNlR2VuZXJhdGUiLCJ1c2VBbmFseXplIiwidXNlRGVidWciLCJydW5FMkUiLCJydW5Vbml0Iiwic3Bpbm5lciIsInBhcnNlQ29uZmlnIiwidXNlVHlwZXNjcmlwdCIsInRlc3RDb25maWdQYXRoIiwiY2hlY2tUZXN0VHlwZXNjcmlwdENvbmZpZyIsInN0YXJ0IiwidW5jb3ZlcmVkRmlsZXMiLCJsZW5ndGgiLCJ0YXJnZXRGaWxlIiwiY29udGV4dCIsImZpbGUiLCJwcm9tcHQiLCJ0YXNrIiwic3VjY2VlZCIsImFpRXJyb3IiLCJmYWlsIiwiY29uc29sZSIsImVycm9yIiwiaXNFU00iLCJub2RlT3B0aW9ucyIsIk5PREVfT1BUSU9OUyIsInRyaW0iLCJ0ZW1wT3V0cHV0RmlsZSIsInByb2Nlc3NFbnYiLCJGT1JDRV9DT0xPUiIsIkNJIiwicHJvamVjdFZpdGVzdEJpbiIsInZpdGVzdFBhdGgiLCJ2aXRlc3RDb25maWdGaWxlIiwicHJvamVjdFZpdGVzdENvbmZpZyIsInByb2plY3RWaXRlc3RDb25maWdQYXRocyIsImV4aXN0aW5nQ29uZmlnUGF0aCIsImZpbmQiLCJjb25maWdQYXRoIiwidml0ZXN0IiwibGV4RGlyIiwiZ2V0TGV4RGlyIiwibGV4Vml0ZXN0Q29uZmlnIiwiT2JqZWN0Iiwia2V5cyIsInJlc29sdmVkQ29uZmlnIiwic3RyaW5naWZ5IiwiZGVmYXVsdCIsInZpdGVzdFNldHVwRmlsZSIsInZpdGVzdEFyZ3MiLCJ2aXRlc3RPcHRpb25zIiwicmVwb3J0ZXJzIiwiU2V0IiwiZmlsdGVycyIsIndhdGNoTW9kZSIsIkJvb2xlYW4iLCJsaXN0TW9kZSIsInB1c2giLCJhZGQiLCJlbnZpcm9ubWVudE5hbWUiLCJzaG91bGRXcml0ZUpzb24iLCJzaXplIiwicmVwb3J0ZXJMaXN0IiwiQXJyYXkiLCJmcm9tIiwidW5zaGlmdCIsImZvckVhY2giLCJyZXBvcnRlciIsImZpbmFsQXJncyIsImpvaW4iLCJMRVhfVklURVNUX1NFVFVQIiwiZW5jb2RpbmciLCJzdGRpbyIsInRlc3RSZXN1bHRzIiwiZmlsZVBhdHRlcm5zIiwicHJvamVjdFBsYXl3cmlnaHRCaW4iLCJwbGF5d3JpZ2h0UGF0aCIsImUyZUNvbmZpZ1BhdGhzIiwicGxheXdyaWdodENvbmZpZ0ZpbGUiLCJwbGF5d3JpZ2h0QXJncyIsImVycm9yTWVzc2FnZSIsIkVycm9yIiwibWVzc2FnZSIsIlN0cmluZyJdLCJtYXBwaW5ncyI6IkFBQUE7OztDQUdDLEdBQ0QsU0FBUUEsS0FBSyxRQUFPLFFBQVE7QUFDNUIsU0FBUUMsVUFBVSxFQUFFQyxZQUFZLFFBQU8sS0FBSztBQUM1QyxTQUFRQyxRQUFRQyxRQUFRLFFBQU8sT0FBTztBQUN0QyxTQUFRQyxXQUFXQyxXQUFXLFFBQU8sT0FBTztBQUU1QyxTQUFRQyxTQUFTLEVBQUVDLHVCQUF1QixRQUFPLHFCQUFxQjtBQUN0RSxTQUFRQyxhQUFhLFFBQU8scUJBQXFCO0FBQ2pELFNBQVFDLGlCQUFpQixRQUFPLHNCQUFzQjtBQUN0RCxTQUFRQyxHQUFHLFFBQU8scUJBQXFCO0FBQ3ZDLFNBQVFDLFVBQVUsUUFBTyxjQUFjO0FBRXZDLE1BQU1DLFlBQVksQ0FBQ0M7SUFDakIsTUFBTUMsa0JBQWtCVCxZQUFZUSxLQUFLO0lBRXpDLElBQUdiLFdBQVdjLGtCQUFrQjtRQUM5QixJQUFJO1lBQ0YsTUFBTUMscUJBQXFCZCxhQUFhYSxpQkFBaUI7WUFDekQsTUFBTUUsY0FBY0MsS0FBS0MsS0FBSyxDQUFDSDtZQUMvQixPQUFPQyxZQUFZRyxJQUFJLEtBQUs7UUFDOUIsRUFBRSxPQUFNQyxRQUFRO1lBQ2QsT0FBTztRQUNUO0lBQ0Y7SUFF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