@nlabs/lex 1.49.5 → 1.50.1

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 (52) hide show
  1. package/.swcrc +35 -0
  2. package/README.md +43 -59
  3. package/config.json +32 -8
  4. package/examples/lex.config.js +110 -10
  5. package/lex.config.js +34 -7
  6. package/lib/Button.stories.js +99 -0
  7. package/lib/LexConfig.d.ts +60 -22
  8. package/lib/LexConfig.js +285 -244
  9. package/lib/commands/ai/ai.js +287 -288
  10. package/lib/commands/ai/index.js +8 -7
  11. package/lib/commands/build/build.d.ts +2 -2
  12. package/lib/commands/build/build.js +349 -458
  13. package/lib/commands/clean/clean.js +45 -33
  14. package/lib/commands/compile/compile.js +214 -228
  15. package/lib/commands/config/config.js +46 -42
  16. package/lib/commands/copy/copy.js +36 -35
  17. package/lib/commands/create/create.js +200 -121
  18. package/lib/commands/dev/dev.d.ts +1 -0
  19. package/lib/commands/dev/dev.js +261 -259
  20. package/lib/commands/init/init.js +108 -88
  21. package/lib/commands/link/link.js +18 -14
  22. package/lib/commands/lint/lint.js +735 -742
  23. package/lib/commands/migrate/migrate.js +49 -36
  24. package/lib/commands/publish/publish.js +116 -96
  25. package/lib/commands/serverless/serverless.js +611 -585
  26. package/lib/commands/storybook/storybook.js +242 -238
  27. package/lib/commands/test/test.js +381 -409
  28. package/lib/commands/update/update.js +141 -120
  29. package/lib/commands/upgrade/upgrade.js +51 -44
  30. package/lib/commands/versions/versions.d.ts +1 -1
  31. package/lib/commands/versions/versions.js +36 -38
  32. package/lib/create/changelog.js +136 -125
  33. package/lib/index.js +40 -38
  34. package/lib/lex.js +95 -68
  35. package/lib/storybook/index.js +6 -1
  36. package/lib/test-react/index.js +7 -84
  37. package/lib/types.d.ts +1 -1
  38. package/lib/types.js +7 -1
  39. package/lib/utils/aiService.js +240 -227
  40. package/lib/utils/app.js +274 -273
  41. package/lib/utils/deepMerge.js +37 -23
  42. package/lib/utils/file.js +218 -215
  43. package/lib/utils/log.js +29 -27
  44. package/lib/utils/reactShim.js +7 -85
  45. package/lib/utils/translations.js +92 -82
  46. package/package.json +59 -60
  47. package/templates/typescript/DataLayer.js.txt +218 -0
  48. package/templates/typescript/DataLayer.test.js.txt +268 -0
  49. package/templates/typescript/DataLayer.test.ts.txt +269 -0
  50. package/templates/typescript/DataLayer.ts.txt +227 -0
  51. package/webpack.config.js +38 -28
  52. package/lib/commands/lint/autofix.d.ts +0 -2
@@ -1,415 +1,390 @@
1
- import { execa } from "execa";
2
- import { existsSync, readFileSync } from "fs";
3
- import { sync as globSync } from "glob";
4
- import { resolve as pathResolve } from "path";
5
- import { LexConfig, getTypeScriptConfigPath } from "../../LexConfig.js";
6
- import { createSpinner } from "../../utils/app.js";
7
- import { resolveBinaryPath } from "../../utils/file.js";
8
- import { log } from "../../utils/log.js";
9
- import { aiFunction } from "../ai/ai.js";
10
- const detectESM = (cwd) => {
11
- const packageJsonPath = pathResolve(cwd, "package.json");
12
- if (existsSync(packageJsonPath)) {
13
- try {
14
- const packageJsonContent = readFileSync(packageJsonPath, "utf8");
15
- const packageJson = JSON.parse(packageJsonContent);
16
- return packageJson.type === "module";
17
- } catch (_error) {
18
- return false;
1
+ /**
2
+ * Copyright (c) 2018-Present, Nitrogen Labs, Inc.
3
+ * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms.
4
+ */ import { execa } from 'execa';
5
+ import { existsSync, readFileSync } from 'fs';
6
+ import { sync as globSync } from 'glob';
7
+ import { resolve as pathResolve } from 'path';
8
+ import { LexConfig, getTypeScriptConfigPath } from '../../LexConfig.js';
9
+ import { createSpinner } from '../../utils/app.js';
10
+ import { resolveBinaryPath } from '../../utils/file.js';
11
+ import { log } from '../../utils/log.js';
12
+ import { aiFunction } from '../ai/ai.js';
13
+ const detectESM = (cwd)=>{
14
+ const packageJsonPath = pathResolve(cwd, 'package.json');
15
+ if (existsSync(packageJsonPath)) {
16
+ try {
17
+ const packageJsonContent = readFileSync(packageJsonPath, 'utf8');
18
+ const packageJson = JSON.parse(packageJsonContent);
19
+ return packageJson.type === 'module';
20
+ } catch (_error) {
21
+ return false;
22
+ }
19
23
  }
20
- }
21
- return false;
24
+ return false;
22
25
  };
23
- const defaultExit = (code) => {
24
- if (process.env.JEST_WORKER_ID || process.env.NODE_ENV === "test") {
25
- return void 0;
26
- }
27
- process.exit(code);
26
+ const defaultExit = (code)=>{
27
+ if (process.env.JEST_WORKER_ID || process.env.NODE_ENV === 'test') {
28
+ return undefined;
29
+ }
30
+ process.exit(code);
28
31
  };
29
- const getTestFilePatterns = (testPathPattern) => {
30
- const defaultPatterns = ["**/*.test.*", "**/*.spec.*", "**/*.integration.*"];
31
- if (!testPathPattern) {
32
- return defaultPatterns;
33
- }
34
- return [testPathPattern];
32
+ export const getTestFilePatterns = (testPathPattern)=>{
33
+ const defaultPatterns = [
34
+ '**/*.test.*',
35
+ '**/*.spec.*',
36
+ '**/*.integration.*'
37
+ ];
38
+ if (!testPathPattern) {
39
+ return defaultPatterns;
40
+ }
41
+ return [
42
+ testPathPattern
43
+ ];
35
44
  };
36
- const findUncoveredSourceFiles = () => {
37
- const sourceFiles = globSync("src/**/*.{ts,tsx,js,jsx}", {
38
- cwd: process.cwd(),
39
- ignore: ["**/node_modules/**", "**/dist/**", "**/lib/**", "**/*.test.*", "**/*.spec.*"]
40
- });
41
- const testFiles = globSync("**/*.{test,spec}.{ts,tsx,js,jsx}", {
42
- cwd: process.cwd(),
43
- ignore: ["**/node_modules/**", "**/dist/**", "**/lib/**"]
44
- });
45
- return sourceFiles.filter((sourceFile) => {
46
- const baseName = sourceFile.replace(/\.[^/.]+$/, "");
47
- return !testFiles.some((testFile) => testFile.includes(baseName));
48
- });
45
+ const findUncoveredSourceFiles = ()=>{
46
+ const sourceFiles = globSync('src/**/*.{ts,tsx,js,jsx}', {
47
+ cwd: process.cwd(),
48
+ ignore: [
49
+ '**/node_modules/**',
50
+ '**/dist/**',
51
+ '**/lib/**',
52
+ '**/*.test.*',
53
+ '**/*.spec.*'
54
+ ]
55
+ });
56
+ const testFiles = globSync('**/*.{test,spec}.{ts,tsx,js,jsx}', {
57
+ cwd: process.cwd(),
58
+ ignore: [
59
+ '**/node_modules/**',
60
+ '**/dist/**',
61
+ '**/lib/**'
62
+ ]
63
+ });
64
+ return sourceFiles.filter((sourceFile)=>{
65
+ const baseName = sourceFile.replace(/\.[^/.]+$/, '');
66
+ return !testFiles.some((testFile)=>testFile.includes(baseName));
67
+ });
49
68
  };
50
- const processTestResults = (outputFile) => {
51
- if (!outputFile) {
52
- return null;
53
- }
54
- try {
55
- const content = readFileSync(outputFile, "utf-8");
56
- return JSON.parse(content);
57
- } catch (_error) {
58
- return null;
59
- }
69
+ const processTestResults = (outputFile)=>{
70
+ if (!outputFile) {
71
+ return null;
72
+ }
73
+ try {
74
+ const content = readFileSync(outputFile, 'utf-8');
75
+ return JSON.parse(content);
76
+ } catch (_error) {
77
+ return null;
78
+ }
60
79
  };
61
- const test = async (options, args, filesOrCallback, callbackParam) => {
62
- let files;
63
- let callback = defaultExit;
64
- if (typeof filesOrCallback === "function") {
65
- callback = filesOrCallback;
66
- } else {
67
- files = filesOrCallback;
68
- callback = callbackParam || defaultExit;
69
- }
70
- const {
71
- analyze = false,
72
- aiAnalyze = false,
73
- aiDebug = false,
74
- aiGenerate = false,
75
- bail,
76
- changedFilesWithAncestor,
77
- changedSince,
78
- ci,
79
- cliName = "Lex",
80
- collectCoverageFrom,
81
- colors,
82
- config,
83
- debug = false,
84
- debugTests = false,
85
- detectOpenHandles,
86
- env,
87
- errorOnDeprecated,
88
- expand,
89
- forceExit,
90
- generate = false,
91
- json,
92
- lastCommit,
93
- listTests,
94
- logHeapUsage,
95
- maxWorkers,
96
- noStackTrace,
97
- notify,
98
- onlyChanged,
99
- outputFile,
100
- passWithNoTests,
101
- quiet,
102
- removeCache,
103
- runInBand,
104
- setup,
105
- showConfig,
106
- silent,
107
- testLocationInResults,
108
- testNamePattern,
109
- testPathPattern,
110
- update,
111
- useStderr,
112
- verbose,
113
- watch,
114
- watchAll
115
- } = options;
116
- const useGenerate = generate || aiGenerate;
117
- const useAnalyze = analyze || aiAnalyze;
118
- const useDebug = debugTests || aiDebug;
119
- log(`${cliName} testing...`, "info", quiet);
120
- const spinner = createSpinner(quiet);
121
- await LexConfig.parseConfig(options);
122
- const { useTypescript } = LexConfig.config;
123
- if (useTypescript) {
124
- const testConfigPath = getTypeScriptConfigPath("tsconfig.test.json");
125
- if (existsSync(testConfigPath)) {
126
- log("Using tsconfig.test.json for testing...", "info", quiet);
80
+ export const test = async (options, args, filesOrCallback, callbackParam)=>{
81
+ // Backward-compat argument normalization: allow callback as third param
82
+ let files;
83
+ let callback = defaultExit;
84
+ if (typeof filesOrCallback === 'function') {
85
+ callback = filesOrCallback;
127
86
  } else {
128
- LexConfig.checkTestTypescriptConfig();
87
+ files = filesOrCallback;
88
+ callback = callbackParam || defaultExit;
129
89
  }
130
- }
131
- if (useGenerate) {
132
- spinner.start("AI is analyzing code to generate test cases...");
133
- try {
134
- const uncoveredFiles = findUncoveredSourceFiles();
135
- if (uncoveredFiles.length > 0) {
136
- const targetFile = uncoveredFiles[0];
137
- await aiFunction({
138
- context: true,
139
- file: targetFile,
140
- prompt: `Generate Jest unit tests for this file: ${targetFile}
141
-
142
- ${readFileSync(targetFile, "utf-8")}
143
-
144
- Please create comprehensive tests that cover the main functionality. Include test fixtures and mocks where necessary.`,
145
- quiet,
146
- task: "test"
147
- });
148
- spinner.succeed(`AI test generation suggestions provided for ${targetFile}`);
149
- } else {
150
- spinner.succeed("All source files appear to have corresponding test files");
151
- }
152
- } catch (aiError) {
153
- spinner.fail("Could not generate AI test suggestions");
154
- if (!quiet) {
155
- console.error("AI test generation error:", aiError);
156
- }
157
- }
158
- }
159
- const projectJestBin = pathResolve(process.cwd(), "node_modules/.bin/jest");
160
- let jestPath;
161
- if (existsSync(projectJestBin)) {
162
- jestPath = projectJestBin;
163
- } else {
164
- jestPath = resolveBinaryPath("jest");
165
- }
166
- if (!jestPath) {
167
- log(`
168
- ${cliName} Error: Jest binary not found in Lex's node_modules or monorepo root`, "error", quiet);
169
- log("Please reinstall Lex or check your installation.", "info", quiet);
170
- return 1;
171
- }
172
- let jestConfigFile;
173
- let projectJestConfig = null;
174
- if (config) {
175
- jestConfigFile = config;
176
- } else {
177
- const projectJestConfigPath = pathResolve(process.cwd(), "jest.config.js");
178
- const projectJestConfigCjsPath = pathResolve(process.cwd(), "jest.config.cjs");
179
- const projectJestConfigMjsPath = pathResolve(process.cwd(), "jest.config.mjs");
180
- const projectJestConfigJsonPath = pathResolve(process.cwd(), "jest.config.json");
181
- if (existsSync(projectJestConfigPath)) {
182
- jestConfigFile = projectJestConfigPath;
183
- if (debug) {
184
- log(`Using project Jest config file: ${jestConfigFile}`, "info", quiet);
185
- }
186
- } else if (existsSync(projectJestConfigCjsPath)) {
187
- jestConfigFile = projectJestConfigCjsPath;
188
- if (debug) {
189
- log(`Using project Jest config file (CJS): ${jestConfigFile}`, "info", quiet);
190
- }
191
- } else if (existsSync(projectJestConfigMjsPath)) {
192
- jestConfigFile = projectJestConfigMjsPath;
193
- if (debug) {
194
- log(`Using project Jest config file (MJS): ${jestConfigFile}`, "info", quiet);
195
- }
196
- } else if (existsSync(projectJestConfigJsonPath)) {
197
- jestConfigFile = projectJestConfigJsonPath;
198
- if (debug) {
199
- log(`Using project Jest config file (JSON): ${jestConfigFile}`, "info", quiet);
200
- }
90
+ const { analyze = false, aiAnalyze = false, aiDebug = false, aiGenerate = false, bail, changedFilesWithAncestor, changedSince, ci, cliName = 'Lex', collectCoverageFrom, colors, config, debug = false, debugTests = false, detectOpenHandles, 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 useGenerate = generate || aiGenerate;
92
+ const useAnalyze = analyze || aiAnalyze;
93
+ const useDebug = debugTests || aiDebug;
94
+ log(`${cliName} testing...`, 'info', quiet);
95
+ const spinner = createSpinner(quiet);
96
+ await LexConfig.parseConfig(options);
97
+ const { useTypescript } = LexConfig.config;
98
+ if (useTypescript) {
99
+ const testConfigPath = getTypeScriptConfigPath('tsconfig.test.json');
100
+ if (existsSync(testConfigPath)) {
101
+ log('Using tsconfig.test.json for testing...', 'info', quiet);
102
+ } else {
103
+ LexConfig.checkTestTypescriptConfig();
104
+ }
105
+ }
106
+ if (useGenerate) {
107
+ spinner.start('AI is analyzing code to generate test cases...');
108
+ try {
109
+ const uncoveredFiles = findUncoveredSourceFiles();
110
+ if (uncoveredFiles.length > 0) {
111
+ const targetFile = uncoveredFiles[0];
112
+ await aiFunction({
113
+ context: true,
114
+ file: targetFile,
115
+ prompt: `Generate Jest unit tests for this file: ${targetFile}\n\n${readFileSync(targetFile, 'utf-8')}\n\nPlease create comprehensive tests that cover the main functionality. Include test fixtures and mocks where necessary.`,
116
+ quiet,
117
+ task: 'test'
118
+ });
119
+ spinner.succeed(`AI test generation suggestions provided for ${targetFile}`);
120
+ } else {
121
+ spinner.succeed('All source files appear to have corresponding test files');
122
+ }
123
+ } catch (aiError) {
124
+ spinner.fail('Could not generate AI test suggestions');
125
+ if (!quiet) {
126
+ // eslint-disable-next-line no-console
127
+ console.error('AI test generation error:', aiError);
128
+ }
129
+ }
130
+ }
131
+ const projectJestBin = pathResolve(process.cwd(), 'node_modules/.bin/jest');
132
+ let jestPath;
133
+ if (existsSync(projectJestBin)) {
134
+ jestPath = projectJestBin;
201
135
  } else {
202
- projectJestConfig = LexConfig.config.jest;
203
- const lexDir = LexConfig.getLexDir();
204
- const lexJestConfig = pathResolve(lexDir, "jest.config.mjs");
205
- if (debug) {
206
- log(`Looking for Jest config at: ${lexJestConfig}`, "info", quiet);
207
- log(`File exists: ${existsSync(lexJestConfig)}`, "info", quiet);
208
- }
209
- if (existsSync(lexJestConfig)) {
210
- jestConfigFile = lexJestConfig;
211
- if (projectJestConfig && Object.keys(projectJestConfig).length > 0) {
212
- if (debug) {
213
- log(`Using Lex Jest config with project Jest config from lex.config.cjs: ${jestConfigFile}`, "info", quiet);
214
- }
136
+ jestPath = resolveBinaryPath('jest');
137
+ }
138
+ if (!jestPath) {
139
+ log(`\n${cliName} Error: Jest 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 jestConfigFile;
144
+ let projectJestConfig = null;
145
+ if (config) {
146
+ jestConfigFile = config;
147
+ } else {
148
+ const projectJestConfigPath = pathResolve(process.cwd(), 'jest.config.js');
149
+ const projectJestConfigCjsPath = pathResolve(process.cwd(), 'jest.config.cjs');
150
+ const projectJestConfigMjsPath = pathResolve(process.cwd(), 'jest.config.mjs');
151
+ const projectJestConfigJsonPath = pathResolve(process.cwd(), 'jest.config.json');
152
+ if (existsSync(projectJestConfigPath)) {
153
+ jestConfigFile = projectJestConfigPath;
154
+ if (debug) {
155
+ log(`Using project Jest config file: ${jestConfigFile}`, 'info', quiet);
156
+ }
157
+ } else if (existsSync(projectJestConfigCjsPath)) {
158
+ jestConfigFile = projectJestConfigCjsPath;
159
+ if (debug) {
160
+ log(`Using project Jest config file (CJS): ${jestConfigFile}`, 'info', quiet);
161
+ }
162
+ } else if (existsSync(projectJestConfigMjsPath)) {
163
+ jestConfigFile = projectJestConfigMjsPath;
164
+ if (debug) {
165
+ log(`Using project Jest config file (MJS): ${jestConfigFile}`, 'info', quiet);
166
+ }
167
+ } else if (existsSync(projectJestConfigJsonPath)) {
168
+ jestConfigFile = projectJestConfigJsonPath;
169
+ if (debug) {
170
+ log(`Using project Jest config file (JSON): ${jestConfigFile}`, 'info', quiet);
171
+ }
215
172
  } else {
216
- if (debug) {
217
- log(`Using Lex Jest config (no project Jest config found): ${jestConfigFile}`, "info", quiet);
218
- }
173
+ // No Jest config file exists in the project
174
+ // Check if there's a Jest config in lex.config.cjs
175
+ projectJestConfig = LexConfig.config.jest;
176
+ const lexDir = LexConfig.getLexDir();
177
+ const lexJestConfig = pathResolve(lexDir, 'jest.config.mjs');
178
+ if (debug) {
179
+ log(`Looking for Jest config at: ${lexJestConfig}`, 'info', quiet);
180
+ log(`File exists: ${existsSync(lexJestConfig)}`, 'info', quiet);
181
+ }
182
+ if (existsSync(lexJestConfig)) {
183
+ jestConfigFile = lexJestConfig;
184
+ if (projectJestConfig && Object.keys(projectJestConfig).length > 0) {
185
+ if (debug) {
186
+ log(`Using Lex Jest config with project Jest config from lex.config.cjs: ${jestConfigFile}`, 'info', quiet);
187
+ }
188
+ } else {
189
+ if (debug) {
190
+ log(`Using Lex Jest config (no project Jest config found): ${jestConfigFile}`, 'info', quiet);
191
+ }
192
+ }
193
+ } else {
194
+ if (debug) {
195
+ log('No Jest config found in project or Lex', 'warn', quiet);
196
+ }
197
+ jestConfigFile = '';
198
+ }
219
199
  }
220
- } else {
221
- if (debug) {
222
- log("No Jest config found in project or Lex", "warn", quiet);
200
+ }
201
+ const jestSetupFile = setup || pathResolve(process.cwd(), 'jest.setup.js');
202
+ const jestOptions = [
203
+ '--no-cache'
204
+ ];
205
+ const isESM = detectESM(process.cwd());
206
+ let nodeOptions = process.env.NODE_OPTIONS || '';
207
+ if (isESM) {
208
+ if (!nodeOptions.includes('--experimental-vm-modules')) {
209
+ nodeOptions = `${nodeOptions} --experimental-vm-modules`.trim();
223
210
  }
224
- jestConfigFile = "";
225
- }
226
- }
227
- }
228
- const jestSetupFile = setup || pathResolve(process.cwd(), "jest.setup.js");
229
- const jestOptions = ["--no-cache"];
230
- const isESM = detectESM(process.cwd());
231
- let nodeOptions = process.env.NODE_OPTIONS || "";
232
- if (isESM) {
233
- if (!nodeOptions.includes("--experimental-vm-modules")) {
234
- nodeOptions = `${nodeOptions} --experimental-vm-modules`.trim();
235
- }
236
- log("ESM project detected, using --experimental-vm-modules in NODE_OPTIONS", "info", quiet);
237
- }
238
- if (jestConfigFile) {
239
- jestOptions.push("--config", jestConfigFile);
240
- }
241
- if (bail) {
242
- jestOptions.push("--bail");
243
- }
244
- if (changedFilesWithAncestor) {
245
- jestOptions.push("--changedFilesWithAncestor");
246
- }
247
- if (changedSince) {
248
- jestOptions.push("--changedSince");
249
- }
250
- if (ci) {
251
- jestOptions.push("--ci");
252
- }
253
- if (collectCoverageFrom) {
254
- jestOptions.push("--collectCoverageFrom", collectCoverageFrom);
255
- }
256
- if (colors) {
257
- jestOptions.push("--colors");
258
- }
259
- if (debug) {
260
- jestOptions.push("--debug");
261
- }
262
- if (detectOpenHandles) {
263
- jestOptions.push("--detectOpenHandles");
264
- }
265
- if (env) {
266
- jestOptions.push("--env");
267
- }
268
- if (errorOnDeprecated) {
269
- jestOptions.push("--errorOnDeprecated");
270
- }
271
- if (expand) {
272
- jestOptions.push("--expand");
273
- }
274
- if (forceExit) {
275
- jestOptions.push("--forceExit");
276
- }
277
- if (json) {
278
- jestOptions.push("--json");
279
- }
280
- if (lastCommit) {
281
- jestOptions.push("--lastCommit");
282
- }
283
- if (listTests) {
284
- jestOptions.push("--listTests");
285
- }
286
- if (logHeapUsage) {
287
- jestOptions.push("--logHeapUsage");
288
- }
289
- if (maxWorkers) {
290
- jestOptions.push("--maxWorkers", maxWorkers);
291
- }
292
- if (noStackTrace) {
293
- jestOptions.push("--noStackTrace");
294
- }
295
- if (notify) {
296
- jestOptions.push("--notify");
297
- }
298
- if (onlyChanged) {
299
- jestOptions.push("--onlyChanged");
300
- }
301
- let tempOutputFile = outputFile;
302
- if ((useAnalyze || useDebug) && !outputFile) {
303
- tempOutputFile = ".lex-test-results.json";
304
- jestOptions.push("--json", "--outputFile", tempOutputFile);
305
- } else if (outputFile) {
306
- jestOptions.push("--outputFile", outputFile);
307
- }
308
- if (passWithNoTests) {
309
- jestOptions.push("--passWithNoTests");
310
- }
311
- if (runInBand) {
312
- jestOptions.push("--runInBand");
313
- }
314
- if (showConfig) {
315
- jestOptions.push("--showConfig");
316
- }
317
- if (silent) {
318
- jestOptions.push("--silent");
319
- }
320
- if (testLocationInResults) {
321
- jestOptions.push("--testLocationInResults");
322
- }
323
- if (testNamePattern) {
324
- jestOptions.push("--testNamePattern", testNamePattern);
325
- }
326
- if (testPathPattern) {
327
- jestOptions.push("--testPathPattern", testPathPattern);
328
- }
329
- if (useStderr) {
330
- jestOptions.push("--useStderr");
331
- }
332
- if (verbose) {
333
- jestOptions.push("--verbose");
334
- }
335
- if (watchAll) {
336
- jestOptions.push("--watchAll");
337
- }
338
- if (removeCache) {
339
- jestOptions.push("--no-cache");
340
- }
341
- if (jestSetupFile && existsSync(jestSetupFile)) {
342
- jestOptions.push(`--setupFilesAfterEnv=${jestSetupFile}`);
343
- }
344
- if (update) {
345
- jestOptions.push("--updateSnapshot");
346
- }
347
- if (watch) {
348
- jestOptions.push("--watch", watch);
349
- }
350
- if (args) {
351
- jestOptions.push(...args);
352
- }
353
- if (files && files.length > 0) {
354
- jestOptions.push(...files);
355
- }
356
- if (debug) {
357
- log(`Jest options: ${jestOptions.join(" ")}`, "info", quiet);
358
- log(`NODE_OPTIONS: ${nodeOptions}`, "info", quiet);
359
- }
360
- try {
361
- const env2 = {
362
- ...process.env,
363
- NODE_OPTIONS: nodeOptions
364
- };
365
- await execa(jestPath, jestOptions, {
366
- encoding: "utf8",
367
- env: env2,
368
- stdio: "inherit"
369
- });
370
- spinner.succeed("Testing completed!");
371
- if (useAnalyze) {
372
- spinner.start("AI is analyzing test coverage and suggesting improvements...");
373
- try {
374
- const testResults = processTestResults(tempOutputFile);
375
- const filePatterns = getTestFilePatterns(testPathPattern);
376
- await aiFunction({
377
- context: true,
378
- prompt: `Analyze these Jest test results and suggest test coverage improvements:
211
+ log('ESM project detected, using --experimental-vm-modules in NODE_OPTIONS', 'info', quiet);
212
+ }
213
+ if (jestConfigFile) {
214
+ jestOptions.push('--config', jestConfigFile);
215
+ }
216
+ if (bail) {
217
+ jestOptions.push('--bail');
218
+ }
219
+ if (changedFilesWithAncestor) {
220
+ jestOptions.push('--changedFilesWithAncestor');
221
+ }
222
+ if (changedSince) {
223
+ jestOptions.push('--changedSince');
224
+ }
225
+ if (ci) {
226
+ jestOptions.push('--ci');
227
+ }
228
+ if (collectCoverageFrom) {
229
+ jestOptions.push('--collectCoverageFrom', collectCoverageFrom);
230
+ }
231
+ if (colors) {
232
+ jestOptions.push('--colors');
233
+ }
234
+ if (debug) {
235
+ jestOptions.push('--debug');
236
+ }
237
+ if (detectOpenHandles) {
238
+ jestOptions.push('--detectOpenHandles');
239
+ }
240
+ if (env) {
241
+ jestOptions.push('--env');
242
+ }
243
+ if (errorOnDeprecated) {
244
+ jestOptions.push('--errorOnDeprecated');
245
+ }
246
+ if (expand) {
247
+ jestOptions.push('--expand');
248
+ }
249
+ if (forceExit) {
250
+ jestOptions.push('--forceExit');
251
+ }
252
+ if (json) {
253
+ jestOptions.push('--json');
254
+ }
255
+ if (lastCommit) {
256
+ jestOptions.push('--lastCommit');
257
+ }
258
+ if (listTests) {
259
+ jestOptions.push('--listTests');
260
+ }
261
+ if (logHeapUsage) {
262
+ jestOptions.push('--logHeapUsage');
263
+ }
264
+ if (maxWorkers) {
265
+ jestOptions.push('--maxWorkers', maxWorkers);
266
+ }
267
+ if (noStackTrace) {
268
+ jestOptions.push('--noStackTrace');
269
+ }
270
+ if (notify) {
271
+ jestOptions.push('--notify');
272
+ }
273
+ if (onlyChanged) {
274
+ jestOptions.push('--onlyChanged');
275
+ }
276
+ let tempOutputFile = outputFile;
277
+ if ((useAnalyze || useDebug) && !outputFile) {
278
+ tempOutputFile = '.lex-test-results.json';
279
+ jestOptions.push('--json', '--outputFile', tempOutputFile);
280
+ } else if (outputFile) {
281
+ jestOptions.push('--outputFile', outputFile);
282
+ }
283
+ if (passWithNoTests) {
284
+ jestOptions.push('--passWithNoTests');
285
+ }
286
+ if (runInBand) {
287
+ jestOptions.push('--runInBand');
288
+ }
289
+ if (showConfig) {
290
+ jestOptions.push('--showConfig');
291
+ }
292
+ if (silent) {
293
+ jestOptions.push('--silent');
294
+ }
295
+ if (testLocationInResults) {
296
+ jestOptions.push('--testLocationInResults');
297
+ }
298
+ if (testNamePattern) {
299
+ jestOptions.push('--testNamePattern', testNamePattern);
300
+ }
301
+ if (testPathPattern) {
302
+ jestOptions.push('--testPathPattern', testPathPattern);
303
+ }
304
+ if (useStderr) {
305
+ jestOptions.push('--useStderr');
306
+ }
307
+ if (verbose) {
308
+ jestOptions.push('--verbose');
309
+ }
310
+ if (watchAll) {
311
+ jestOptions.push('--watchAll');
312
+ }
313
+ if (removeCache) {
314
+ jestOptions.push('--no-cache');
315
+ }
316
+ if (jestSetupFile && existsSync(jestSetupFile)) {
317
+ jestOptions.push(`--setupFilesAfterEnv=${jestSetupFile}`);
318
+ }
319
+ if (update) {
320
+ jestOptions.push('--updateSnapshot');
321
+ }
322
+ if (watch) {
323
+ jestOptions.push('--watch', watch);
324
+ }
325
+ if (args) {
326
+ jestOptions.push(...args);
327
+ }
328
+ if (files && files.length > 0) {
329
+ jestOptions.push(...files);
330
+ }
331
+ if (debug) {
332
+ log(`Jest options: ${jestOptions.join(' ')}`, 'info', quiet);
333
+ log(`NODE_OPTIONS: ${nodeOptions}`, 'info', quiet);
334
+ }
335
+ try {
336
+ const env = {
337
+ ...process.env,
338
+ NODE_OPTIONS: nodeOptions
339
+ };
340
+ await execa(jestPath, jestOptions, {
341
+ encoding: 'utf8',
342
+ env,
343
+ stdio: 'inherit'
344
+ });
345
+ spinner.succeed('Testing completed!');
346
+ if (useAnalyze) {
347
+ spinner.start('AI is analyzing test coverage and suggesting improvements...');
348
+ try {
349
+ const testResults = processTestResults(tempOutputFile);
350
+ const filePatterns = getTestFilePatterns(testPathPattern);
351
+ await aiFunction({
352
+ context: true,
353
+ prompt: `Analyze these Jest test results and suggest test coverage improvements:
379
354
 
380
355
  ${JSON.stringify(testResults, null, 2)}
381
356
 
382
- Test patterns: ${filePatterns.join(", ")}
357
+ Test patterns: ${filePatterns.join(', ')}
383
358
 
384
359
  Please provide:
385
360
  1. Analysis of current coverage gaps
386
361
  2. Suggestions for improving test cases
387
362
  3. Recommendations for additional integration test scenarios
388
363
  4. Best practices for increasing test effectiveness`,
389
- quiet,
390
- task: "optimize"
391
- });
392
- spinner.succeed("AI test analysis complete");
393
- } catch (aiError) {
394
- spinner.fail("Could not generate AI test analysis");
395
- if (!quiet) {
396
- console.error("AI analysis error:", aiError);
364
+ quiet,
365
+ task: 'optimize'
366
+ });
367
+ spinner.succeed('AI test analysis complete');
368
+ } catch (aiError) {
369
+ spinner.fail('Could not generate AI test analysis');
370
+ if (!quiet) {
371
+ // eslint-disable-next-line no-console
372
+ console.error('AI analysis error:', aiError);
373
+ }
374
+ }
397
375
  }
398
- }
399
- }
400
- callback(0);
401
- return 0;
402
- } catch (error) {
403
- log(`
404
- ${cliName} Error: Check for unit test errors and/or coverage.`, "error", quiet);
405
- spinner.fail("Testing failed!");
406
- if (useDebug) {
407
- spinner.start("AI is analyzing test failures...");
408
- try {
409
- const testResults = processTestResults(tempOutputFile);
410
- await aiFunction({
411
- context: true,
412
- prompt: `Debug these failed Jest tests and suggest fixes:
376
+ callback(0);
377
+ return 0;
378
+ } catch (error) {
379
+ log(`\n${cliName} Error: Check for unit test errors and/or coverage.`, 'error', quiet);
380
+ spinner.fail('Testing failed!');
381
+ if (useDebug) {
382
+ spinner.start('AI is analyzing test failures...');
383
+ try {
384
+ const testResults = processTestResults(tempOutputFile);
385
+ await aiFunction({
386
+ context: true,
387
+ prompt: `Debug these failed Jest tests and suggest fixes:
413
388
 
414
389
  ${JSON.stringify(error.message, null, 2)}
415
390
 
@@ -420,25 +395,22 @@ Please provide:
420
395
  2. Specific suggestions to fix each failing test
421
396
  3. Any potential issues with test fixtures or mocks
422
397
  4. Code examples for solutions`,
423
- quiet,
424
- task: "help"
425
- });
426
- spinner.succeed("AI debugging assistance complete");
427
- } catch (aiError) {
428
- spinner.fail("Could not generate AI debugging assistance");
429
- if (!quiet) {
430
- console.error("AI debugging error:", aiError);
398
+ quiet,
399
+ task: 'help'
400
+ });
401
+ spinner.succeed('AI debugging assistance complete');
402
+ } catch (aiError) {
403
+ spinner.fail('Could not generate AI debugging assistance');
404
+ if (!quiet) {
405
+ // eslint-disable-next-line no-console
406
+ console.error('AI debugging error:', aiError);
407
+ }
408
+ }
431
409
  }
432
- }
410
+ callback(1);
411
+ return 1;
433
412
  }
434
- callback(1);
435
- return 1;
436
- }
437
413
  };
438
- var test_default = test;
439
- export {
440
- test_default as default,
441
- getTestFilePatterns,
442
- test
443
- };
444
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2NvbW1hbmRzL3Rlc3QvdGVzdC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTgtUHJlc2VudCwgTml0cm9nZW4gTGFicywgSW5jLlxuICogQ29weXJpZ2h0cyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSB0aGUgYWNjb21wYW55aW5nIExJQ0VOU0UgZmlsZSBmb3IgdGVybXMuXG4gKi9cbmltcG9ydCB7ZXhlY2F9IGZyb20gJ2V4ZWNhJztcbmltcG9ydCB7ZXhpc3RzU3luYywgcmVhZEZpbGVTeW5jfSBmcm9tICdmcyc7XG5pbXBvcnQge3N5bmMgYXMgZ2xvYlN5bmN9IGZyb20gJ2dsb2InO1xuaW1wb3J0IHtyZXNvbHZlIGFzIHBhdGhSZXNvbHZlfSBmcm9tICdwYXRoJztcblxuaW1wb3J0IHtMZXhDb25maWcsIGdldFR5cGVTY3JpcHRDb25maWdQYXRofSBmcm9tICcuLi8uLi9MZXhDb25maWcuanMnO1xuaW1wb3J0IHtjcmVhdGVTcGlubmVyfSBmcm9tICcuLi8uLi91dGlscy9hcHAuanMnO1xuaW1wb3J0IHtyZXNvbHZlQmluYXJ5UGF0aH0gZnJvbSAnLi4vLi4vdXRpbHMvZmlsZS5qcyc7XG5pbXBvcnQge2xvZ30gZnJvbSAnLi4vLi4vdXRpbHMvbG9nLmpzJztcbmltcG9ydCB7YWlGdW5jdGlvbn0gZnJvbSAnLi4vYWkvYWkuanMnO1xuXG5jb25zdCBkZXRlY3RFU00gPSAoY3dkOiBzdHJpbmcpOiBib29sZWFuID0+IHtcbiAgY29uc3QgcGFja2FnZUpzb25QYXRoID0gcGF0aFJlc29sdmUoY3dkLCAncGFja2FnZS5qc29uJyk7XG5cbiAgaWYoZXhpc3RzU3luYyhwYWNrYWdlSnNvblBhdGgpKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBhY2thZ2VKc29uQ29udGVudCA9IHJlYWRGaWxlU3luYyhwYWNrYWdlSnNvblBhdGgsICd1dGY4Jyk7XG4gICAgICBjb25zdCBwYWNrYWdlSnNvbiA9IEpTT04ucGFyc2UocGFja2FnZUpzb25Db250ZW50KTtcbiAgICAgIHJldHVybiBwYWNrYWdlSnNvbi50eXBlID09PSAnbW9kdWxlJztcbiAgICB9IGNhdGNoIChfZXJyb3IpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIFRlc3RPcHRpb25zIHtcbiAgcmVhZG9ubHkgYW5hbHl6ZT86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGFpRGVidWc/OiBib29sZWFuO1xuICByZWFkb25seSBhaUdlbmVyYXRlPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgYWlBbmFseXplPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgYmFpbD86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGNoYW5nZWRGaWxlc1dpdGhBbmNlc3Rvcj86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGNoYW5nZWRTaW5jZT86IHN0cmluZztcbiAgcmVhZG9ubHkgY2k/OiBib29sZWFuO1xuICByZWFkb25seSBjbGlOYW1lPzogc3RyaW5nO1xuICByZWFkb25seSBjb2xsZWN0Q292ZXJhZ2VGcm9tPzogc3RyaW5nO1xuICByZWFkb25seSBjb2xvcnM/OiBib29sZWFuO1xuICByZWFkb25seSBjb25maWc/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGRlYnVnPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgZGVidWdUZXN0cz86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGRldGVjdE9wZW5IYW5kbGVzPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgZW52Pzogc3RyaW5nO1xuICByZWFkb25seSBlcnJvck9uRGVwcmVjYXRlZD86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGV4cGFuZD86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGZvcmNlRXhpdD86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGdlbmVyYXRlPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkganNvbj86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGxhc3RDb21taXQ/OiBib29sZWFuO1xuICByZWFkb25seSBsaXN0VGVzdHM/OiBib29sZWFuO1xuICByZWFkb25seSBsb2dIZWFwVXNhZ2U/OiBib29sZWFuO1xuICByZWFkb25seSBtYXhXb3JrZXJzPzogc3RyaW5nO1xuICByZWFkb25seSBub1N0YWNrVHJhY2U/OiBib29sZWFuO1xuICByZWFkb25seSBub3RpZnk/OiBib29sZWFuO1xuICByZWFkb25seSBvbmx5Q2hhbmdlZD86IGJvb2xlYW47XG4gIHJlYWRvbmx5IG91dHB1dEZpbGU/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHBhc3NXaXRoTm9UZXN0cz86IGJvb2xlYW47XG4gIHJlYWRvbmx5IHF1aWV0PzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgcmVtb3ZlQ2FjaGU/OiBib29sZWFuO1xuICByZWFkb25seSBydW5JbkJhbmQ/OiBib29sZWFuO1xuICByZWFkb25seSBzZXR1cD86IHN0cmluZztcbiAgcmVhZG9ubHkgc2hvd0NvbmZpZz86IGJvb2xlYW47XG4gIHJlYWRvbmx5IHNpbGVudD86IGJvb2xlYW47XG4gIHJlYWRvbmx5IHRlc3RMb2NhdGlvbkluUmVzdWx0cz86IGJvb2xlYW47XG4gIHJlYWRvbmx5IHRlc3ROYW1lUGF0dGVybj86IHN0cmluZztcbiAgcmVhZG9ubHkgdGVzdFBhdGhQYXR0ZXJuPzogc3RyaW5nO1xuICByZWFkb25seSB1cGRhdGU/OiBib29sZWFuO1xuICByZWFkb25seSB1c2VTdGRlcnI/OiBib29sZWFuO1xuICByZWFkb25seSB2ZXJib3NlPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgd2F0Y2g/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHdhdGNoQWxsPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IHR5cGUgVGVzdENhbGxiYWNrID0gdHlwZW9mIHByb2Nlc3MuZXhpdDtcblxuY29uc3QgZGVmYXVsdEV4aXQgPSAoKGNvZGU/OiBudW1iZXIpID0+IHtcbiAgaWYocHJvY2Vzcy5lbnYuSkVTVF9XT1JLRVJfSUQgfHwgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICd0ZXN0Jykge1xuICAgIHJldHVybiB1bmRlZmluZWQgYXMgbmV2ZXI7XG4gIH1cblxuICBwcm9jZXNzLmV4aXQoY29kZSk7XG59KSBhcyB0eXBlb2YgcHJvY2Vzcy5leGl0O1xuXG5leHBvcnQgY29uc3QgZ2V0VGVzdEZpbGVQYXR0ZXJucyA9ICh0ZXN0UGF0aFBhdHRlcm4/OiBzdHJpbmcpOiBzdHJpbmdbXSA9PiB7XG4gIGNvbnN0IGRlZmF1bHRQYXR0ZXJucyA9IFsnKiovKi50ZXN0LionLCAnKiovKi5zcGVjLionLCAnKiovKi5pbnRlZ3JhdGlvbi4qJ107XG5cbiAgaWYoIXRlc3RQYXRoUGF0dGVybikge1xuICAgIHJldHVybiBkZWZhdWx0UGF0dGVybnM7XG4gIH1cblxuICByZXR1cm4gW3Rlc3RQYXRoUGF0dGVybl07XG59O1xuXG5jb25zdCBmaW5kVW5jb3ZlcmVkU291cmNlRmlsZXMgPSAoKTogc3RyaW5nW10gPT4ge1xuICBjb25zdCBzb3VyY2VGaWxlcyA9IGdsb2JTeW5jKCdzcmMvKiovKi57dHMsdHN4LGpzLGpzeH0nLCB7XG4gICAgY3dkOiBwcm9jZXNzLmN3ZCgpLFxuICAgIGlnbm9yZTogWycqKi9ub2RlX21vZHVsZXMvKionLCAnKiovZGlzdC8qKicsICcqKi9saWIvKionLCAnKiovKi50ZXN0LionLCAnKiovKi5zcGVjLionXVxuICB9KTtcblxuICBjb25zdCB0ZXN0RmlsZXMgPSBnbG9iU3luYygnKiovKi57dGVzdCxzcGVjfS57dHMsdHN4LGpzLGpzeH0nLCB7XG4gICAgY3dkOiBwcm9jZXNzLmN3ZCgpLFxuICAgIGlnbm9yZTogWycqKi9ub2RlX21vZHVsZXMvKionLCAnKiovZGlzdC8qKicsICcqKi9saWIvKionXVxuICB9KTtcblxuICByZXR1cm4gc291cmNlRmlsZXMuZmlsdGVyKChzb3VyY2VGaWxlKSA9PiB7XG4gICAgY29uc3QgYmFzZU5hbWUgPSBzb3VyY2VGaWxlLnJlcGxhY2UoL1xcLlteLy5dKyQvLCAnJyk7XG4gICAgcmV0dXJuICF0ZXN0RmlsZXMuc29tZSgodGVzdEZpbGUpID0+IHRlc3RGaWxlLmluY2x1ZGVzKGJhc2VOYW1lKSk7XG4gIH0pO1xufTtcblxuY29uc3QgcHJvY2Vzc1Rlc3RSZXN1bHRzID0gKG91dHB1dEZpbGU/OiBzdHJpbmcpOiBhbnkgPT4ge1xuICBpZighb3V0cHV0RmlsZSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBjb25zdCBjb250ZW50ID0gcmVhZEZpbGVTeW5jKG91dHB1dEZpbGUsICd1dGYtOCcpO1xuICAgIHJldHVybiBKU09OLnBhcnNlKGNvbnRlbnQpO1xuICB9IGNhdGNoIChfZXJyb3IpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHRlc3QgPSBhc3luYyAoXG4gIG9wdGlvbnM6IFRlc3RPcHRpb25zLFxuICBhcmdzPzogc3RyaW5nW10sXG4gIGZpbGVzT3JDYWxsYmFjaz86IHN0cmluZ1tdIHwgVGVzdENhbGxiYWNrLFxuICBjYWxsYmFja1BhcmFtPzogVGVzdENhbGxiYWNrXG4pOiBQcm9taXNlPG51bWJlcj4gPT4ge1xuICAvLyBCYWNrd2FyZC1jb21wYXQgYXJndW1lbnQgbm9ybWFsaXphdGlvbjogYWxsb3cgY2FsbGJhY2sgYXMgdGhpcmQgcGFyYW1cbiAgbGV0IGZpbGVzOiBzdHJpbmdbXSB8IHVuZGVmaW5lZDtcbiAgbGV0IGNhbGxiYWNrOiBUZXN0Q2FsbGJhY2sgPSBkZWZhdWx0RXhpdDtcblxuICBpZih0eXBlb2YgZmlsZXNPckNhbGxiYWNrID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2FsbGJhY2sgPSBmaWxlc09yQ2FsbGJhY2sgYXMgVGVzdENhbGxiYWNrO1xuICB9IGVsc2Uge1xuICAgIGZpbGVzID0gZmlsZXNPckNhbGxiYWNrIGFzIHN0cmluZ1tdIHwgdW5kZWZpbmVkO1xuICAgIGNhbGxiYWNrID0gY2FsbGJhY2tQYXJhbSB8fCBkZWZhdWx0RXhpdDtcbiAgfVxuICBjb25zdCB7XG4gICAgYW5hbHl6ZSA9IGZhbHNlLFxuICAgIGFpQW5hbHl6ZSA9IGZhbHNlLFxuICAgIGFpRGVidWcgPSBmYWxzZSxcbiAgICBhaUdlbmVyYXRlID0gZmFsc2UsXG4gICAgYmFpbCxcbiAgICBjaGFuZ2VkRmlsZXNXaXRoQW5jZXN0b3IsXG4gICAgY2hhbmdlZFNpbmNlLFxuICAgIGNpLFxuICAgIGNsaU5hbWUgPSAnTGV4JyxcbiAgICBjb2xsZWN0Q292ZXJhZ2VGcm9tLFxuICAgIGNvbG9ycyxcbiAgICBjb25maWcsXG4gICAgZGVidWcgPSBmYWxzZSxcbiAgICBkZWJ1Z1Rlc3RzID0gZmFsc2UsXG4gICAgZGV0ZWN0T3BlbkhhbmRsZXMsXG4gICAgZW52LFxuICAgIGVycm9yT25EZXByZWNhdGVkLFxuICAgIGV4cGFuZCxcbiAgICBmb3JjZUV4aXQsXG4gICAgZ2VuZXJhdGUgPSBmYWxzZSxcbiAgICBqc29uLFxuICAgIGxhc3RDb21taXQsXG4gICAgbGlzdFRlc3RzLFxuICAgIGxvZ0hlYXBVc2FnZSxcbiAgICBtYXhXb3JrZXJzLFxuICAgIG5vU3RhY2tUcmFjZSxcbiAgICBub3RpZnksXG4gICAgb25seUNoYW5nZWQsXG4gICAgb3V0cHV0RmlsZSxcbiAgICBwYXNzV2l0aE5vVGVzdHMsXG4gICAgcXVpZXQsXG4gICAgcmVtb3ZlQ2FjaGUsXG4gICAgcnVuSW5CYW5kLFxuICAgIHNldHVwLFxuICAgIHNob3dDb25maWcsXG4gICAgc2lsZW50LFxuICAgIHRlc3RMb2NhdGlvbkluUmVzdWx0cyxcbiAgICB0ZXN0TmFtZVBhdHRlcm4sXG4gICAgdGVzdFBhdGhQYXR0ZXJuLFxuICAgIHVwZGF0ZSxcbiAgICB1c2VTdGRlcnIsXG4gICAgdmVyYm9zZSxcbiAgICB3YXRjaCxcbiAgICB3YXRjaEFsbFxuICB9ID0gb3B0aW9ucztcblxuICBjb25zdCB1c2VHZW5lcmF0ZSA9IGdlbmVyYXRlIHx8IGFpR2VuZXJhdGU7XG4gIGNvbnN0IHVzZUFuYWx5emUgPSBhbmFseXplIHx8IGFpQW5hbHl6ZTtcbiAgY29uc3QgdXNlRGVidWcgPSBkZWJ1Z1Rlc3RzIHx8IGFpRGVidWc7XG5cbiAgbG9nKGAke2NsaU5hbWV9IHRlc3RpbmcuLi5gLCAnaW5mbycsIHF1aWV0KTtcblxuICBjb25zdCBzcGlubmVyID0gY3JlYXRlU3Bpbm5lcihxdWlldCk7XG5cbiAgYXdhaXQgTGV4Q29uZmlnLnBhcnNlQ29uZmlnKG9wdGlvbnMpO1xuXG4gIGNvbnN0IHt1c2VUeXBlc2NyaXB0fSA9IExleENvbmZpZy5jb25maWc7XG5cbiAgaWYodXNlVHlwZXNjcmlwdCkge1xuICAgIGNvbnN0IHRlc3RDb25maWdQYXRoID0gZ2V0VHlwZVNjcmlwdENvbmZpZ1BhdGgoJ3RzY29uZmlnLnRlc3QuanNvbicpO1xuICAgIGlmKGV4aXN0c1N5bmModGVzdENvbmZpZ1BhdGgpKSB7XG4gICAgICBsb2coJ1VzaW5nIHRzY29uZmlnLnRlc3QuanNvbiBmb3IgdGVzdGluZy4uLicsICdpbmZvJywgcXVpZXQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBMZXhDb25maWcuY2hlY2tUZXN0VHlwZXNjcmlwdENvbmZpZygpO1xuICAgIH1cbiAgfVxuXG4gIGlmKHVzZUdlbmVyYXRlKSB7XG4gICAgc3Bpbm5lci5zdGFydCgnQUkgaXMgYW5hbHl6aW5nIGNvZGUgdG8gZ2VuZXJhdGUgdGVzdCBjYXNlcy4uLicpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHVuY292ZXJlZEZpbGVzID0gZmluZFVuY292ZXJlZFNvdXJjZUZpbGVzKCk7XG5cbiAgICAgIGlmKHVuY292ZXJlZEZpbGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgdGFyZ2V0RmlsZSA9IHVuY292ZXJlZEZpbGVzWzBdO1xuXG4gICAgICAgIGF3YWl0IGFpRnVuY3Rpb24oe1xuICAgICAgICAgIGNvbnRleHQ6IHRydWUsXG4gICAgICAgICAgZmlsZTogdGFyZ2V0RmlsZSxcbiAgICAgICAgICBwcm9tcHQ6IGBHZW5lcmF0ZSBKZXN0IHVuaXQgdGVzdHMgZm9yIHRoaXMgZmlsZTogJHt0YXJnZXRGaWxlfVxcblxcbiR7cmVhZEZpbGVTeW5jKHRhcmdldEZpbGUsICd1dGYtOCcpfVxcblxcblBsZWFzZSBjcmVhdGUgY29tcHJlaGVuc2l2ZSB0ZXN0cyB0aGF0IGNvdmVyIHRoZSBtYWluIGZ1bmN0aW9uYWxpdHkuIEluY2x1ZGUgdGVzdCBmaXh0dXJlcyBhbmQgbW9ja3Mgd2hlcmUgbmVjZXNzYXJ5LmAsXG4gICAgICAgICAgcXVpZXQsXG4gICAgICAgICAgdGFzazogJ3Rlc3QnXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNwaW5uZXIuc3VjY2VlZChgQUkgdGVzdCBnZW5lcmF0aW9uIHN1Z2dlc3Rpb25zIHByb3ZpZGVkIGZvciAke3RhcmdldEZpbGV9YCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzcGlubmVyLnN1Y2NlZWQoJ0FsbCBzb3VyY2UgZmlsZXMgYXBwZWFyIHRvIGhhdmUgY29ycmVzcG9uZGluZyB0ZXN0IGZpbGVzJyk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoYWlFcnJvcikge1xuICAgICAgc3Bpbm5lci5mYWlsKCdDb3VsZCBub3QgZ2VuZXJhdGUgQUkgdGVzdCBzdWdnZXN0aW9ucycpO1xuICAgICAgaWYoIXF1aWV0KSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ0FJIHRlc3QgZ2VuZXJhdGlvbiBlcnJvcjonLCBhaUVycm9yKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb25zdCBwcm9qZWN0SmVzdEJpbiA9IHBhdGhSZXNvbHZlKHByb2Nlc3MuY3dkKCksICdub2RlX21vZHVsZXMvLmJpbi9qZXN0Jyk7XG4gIGxldCBqZXN0UGF0aDogc3RyaW5nO1xuXG4gIGlmKGV4aXN0c1N5bmMocHJvamVjdEplc3RCaW4pKSB7XG4gICAgamVzdFBhdGggPSBwcm9qZWN0SmVzdEJpbjtcbiAgfSBlbHNlIHtcbiAgICBqZXN0UGF0aCA9IHJlc29sdmVCaW5hcnlQYXRoKCdqZXN0Jyk7XG4gIH1cblxuICBpZighamVzdFBhdGgpIHtcbiAgICBsb2coYFxcbiR7Y2xpTmFtZX0gRXJyb3I6IEplc3QgYmluYXJ5IG5vdCBmb3VuZCBpbiBMZXgncyBub2RlX21vZHVsZXMgb3IgbW9ub3JlcG8gcm9vdGAsICdlcnJvcicsIHF1aWV0KTtcbiAgICBsb2coJ1BsZWFzZSByZWluc3RhbGwgTGV4IG9yIGNoZWNrIHlvdXIgaW5zdGFsbGF0aW9uLicsICdpbmZvJywgcXVpZXQpO1xuICAgIHJldHVybiAxO1xuICB9XG5cbiAgbGV0IGplc3RDb25maWdGaWxlOiBzdHJpbmc7XG4gIGxldCBwcm9qZWN0SmVzdENvbmZpZzogYW55ID0gbnVsbDtcblxuICBpZihjb25maWcpIHtcbiAgICBqZXN0Q29uZmlnRmlsZSA9IGNvbmZpZztcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBwcm9qZWN0SmVzdENvbmZpZ1BhdGggPSBwYXRoUmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCAnamVzdC5jb25maWcuanMnKTtcbiAgICBjb25zdCBwcm9qZWN0SmVzdENvbmZpZ0Nqc1BhdGggPSBwYXRoUmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCAnamVzdC5jb25maWcuY2pzJyk7XG4gICAgY29uc3QgcHJvamVjdEplc3RDb25maWdNanNQYXRoID0gcGF0aFJlc29sdmUocHJvY2Vzcy5jd2QoKSwgJ2plc3QuY29uZmlnLm1qcycpO1xuICAgIGNvbnN0IHByb2plY3RKZXN0Q29uZmlnSnNvblBhdGggPSBwYXRoUmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCAnamVzdC5jb25maWcuanNvbicpO1xuXG4gICAgaWYoZXhpc3RzU3luYyhwcm9qZWN0SmVzdENvbmZpZ1BhdGgpKSB7XG4gICAgICBqZXN0Q29uZmlnRmlsZSA9IHByb2plY3RKZXN0Q29uZmlnUGF0aDtcbiAgICAgIGlmKGRlYnVnKSB7XG4gICAgICAgIGxvZyhgVXNpbmcgcHJvamVjdCBKZXN0IGNvbmZpZyBmaWxlOiAke2plc3RDb25maWdGaWxlfWAsICdpbmZvJywgcXVpZXQpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZihleGlzdHNTeW5jKHByb2plY3RKZXN0Q29uZmlnQ2pzUGF0aCkpIHtcbiAgICAgIGplc3RDb25maWdGaWxlID0gcHJvamVjdEplc3RDb25maWdDanNQYXRoO1xuICAgICAgaWYoZGVidWcpIHtcbiAgICAgICAgbG9nKGBVc2luZyBwcm9qZWN0IEplc3QgY29uZmlnIGZpbGUgKENKUyk6ICR7amVzdENvbmZpZ0ZpbGV9YCwgJ2luZm8nLCBxdWlldCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmKGV4aXN0c1N5bmMocHJvamVjdEplc3RDb25maWdNanNQYXRoKSkge1xuICAgICAgamVzdENvbmZpZ0ZpbGUgPSBwcm9qZWN0SmVzdENvbmZpZ01qc1BhdGg7XG4gICAgICBpZihkZWJ1Zykge1xuICAgICAgICBsb2coYFVzaW5nIHByb2plY3QgSmVzdCBjb25maWcgZmlsZSAoTUpTKTogJHtqZXN0Q29uZmlnRmlsZX1gLCAnaW5mbycsIHF1aWV0KTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYoZXhpc3RzU3luYyhwcm9qZWN0SmVzdENvbmZpZ0pzb25QYXRoKSkge1xuICAgICAgamVzdENvbmZpZ0ZpbGUgPSBwcm9qZWN0SmVzdENvbmZpZ0pzb25QYXRoO1xuICAgICAgaWYoZGVidWcpIHtcbiAgICAgICAgbG9nKGBVc2luZyBwcm9qZWN0IEplc3QgY29uZmlnIGZpbGUgKEpTT04pOiAke2plc3RDb25maWdGaWxlfWAsICdpbmZvJywgcXVpZXQpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBObyBKZXN0IGNvbmZpZyBmaWxlIGV4aXN0cyBpbiB0aGUgcHJvamVjdFxuICAgICAgLy8gQ2hlY2sgaWYgdGhlcmUncyBhIEplc3QgY29uZmlnIGluIGxleC5jb25maWcuY2pzXG4gICAgICBwcm9qZWN0SmVzdENvbmZpZyA9IExleENvbmZpZy5jb25maWcuamVzdDtcblxuICAgICAgY29uc3QgbGV4RGlyID0gTGV4Q29uZmlnLmdldExleERpcigpO1xuICAgICAgY29uc3QgbGV4SmVzdENvbmZpZyA9IHBhdGhSZXNvbHZlKGxleERpciwgJ2plc3QuY29uZmlnLm1qcycpO1xuXG4gICAgICBpZihkZWJ1Zykge1xuICAgICAgICBsb2coYExvb2tpbmcgZm9yIEplc3QgY29uZmlnIGF0OiAke2xleEplc3RDb25maWd9YCwgJ2luZm8nLCBxdWlldCk7XG4gICAgICAgIGxvZyhgRmlsZSBleGlzdHM6ICR7ZXhpc3RzU3luYyhsZXhKZXN0Q29uZmlnKX1gLCAnaW5mbycsIHF1aWV0KTtcbiAgICAgIH1cblxuICAgICAgaWYoZXhpc3RzU3luYyhsZXhKZXN0Q29uZmlnKSkge1xuICAgICAgICBqZXN0Q29uZmlnRmlsZSA9IGxleEplc3RDb25maWc7XG4gICAgICAgIGlmKHByb2plY3RKZXN0Q29uZmlnICYmIE9iamVjdC5rZXlzKHByb2plY3RKZXN0Q29uZmlnKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgaWYoZGVidWcpIHtcbiAgICAgICAgICAgIGxvZyhgVXNpbmcgTGV4IEplc3QgY29uZmlnIHdpdGggcHJvamVjdCBKZXN0IGNvbmZpZyBmcm9tIGxleC5jb25maWcuY2pzOiAke2plc3RDb25maWdGaWxlfWAsICdpbmZvJywgcXVpZXQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZihkZWJ1Zykge1xuICAgICAgICAgICAgbG9nKGBVc2luZyBMZXggSmVzdCBjb25maWcgKG5vIHByb2plY3QgSmVzdCBjb25maWcgZm91bmQpOiAke2plc3RDb25maWdGaWxlfWAsICdpbmZvJywgcXVpZXQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYoZGVidWcpIHtcbiAgICAgICAgICBsb2coJ05vIEplc3QgY29uZmlnIGZvdW5kIGluIHByb2plY3Qgb3IgTGV4JywgJ3dhcm4nLCBxdWlldCk7XG4gICAgICAgIH1cbiAgICAgICAgamVzdENvbmZpZ0ZpbGUgPSAnJztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb25zdCBqZXN0U2V0dXBGaWxlOiBzdHJpbmcgPSBzZXR1cCB8fCBwYXRoUmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCAnamVzdC5zZXR1cC5qcycpO1xuICBjb25zdCBqZXN0T3B0aW9uczogc3RyaW5nW10gPSBbJy0tbm8tY2FjaGUnXTtcblxuICBjb25zdCBpc0VTTSA9IGRldGVjdEVTTShwcm9jZXNzLmN3ZCgpKTtcbiAgbGV0IG5vZGVPcHRpb25zID0gcHJvY2Vzcy5lbnYuTk9ERV9PUFRJT05TIHx8ICcnO1xuICBpZihpc0VTTSkge1xuICAgIGlmKCFub2RlT3B0aW9ucy5pbmNsdWRlcygnLS1leHBlcmltZW50YWwtdm0tbW9kdWxlcycpKSB7XG4gICAgICBub2RlT3B0aW9ucyA9IGAke25vZGVPcHRpb25zfSAtLWV4cGVyaW1lbnRhbC12bS1tb2R1bGVzYC50cmltKCk7XG4gICAgfVxuICAgIGxvZygnRVNNIHByb2plY3QgZGV0ZWN0ZWQsIHVzaW5nIC0tZXhwZXJpbWVudGFsLXZtLW1vZHVsZXMgaW4gTk9ERV9PUFRJT05TJywgJ2luZm8nLCBxdWlldCk7XG4gIH1cblxuICBpZihqZXN0Q29uZmlnRmlsZSkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tY29uZmlnJywgamVzdENvbmZpZ0ZpbGUpO1xuICB9XG5cbiAgaWYoYmFpbCkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tYmFpbCcpO1xuICB9XG5cbiAgaWYoY2hhbmdlZEZpbGVzV2l0aEFuY2VzdG9yKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1jaGFuZ2VkRmlsZXNXaXRoQW5jZXN0b3InKTtcbiAgfVxuXG4gIGlmKGNoYW5nZWRTaW5jZSkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tY2hhbmdlZFNpbmNlJyk7XG4gIH1cblxuICBpZihjaSkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tY2knKTtcbiAgfVxuXG4gIGlmKGNvbGxlY3RDb3ZlcmFnZUZyb20pIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLWNvbGxlY3RDb3ZlcmFnZUZyb20nLCBjb2xsZWN0Q292ZXJhZ2VGcm9tKTtcbiAgfVxuXG4gIGlmKGNvbG9ycykge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tY29sb3JzJyk7XG4gIH1cblxuICBpZihkZWJ1Zykge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tZGVidWcnKTtcbiAgfVxuXG4gIGlmKGRldGVjdE9wZW5IYW5kbGVzKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1kZXRlY3RPcGVuSGFuZGxlcycpO1xuICB9XG5cbiAgaWYoZW52KSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1lbnYnKTtcbiAgfVxuXG4gIGlmKGVycm9yT25EZXByZWNhdGVkKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1lcnJvck9uRGVwcmVjYXRlZCcpO1xuICB9XG5cbiAgaWYoZXhwYW5kKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1leHBhbmQnKTtcbiAgfVxuXG4gIGlmKGZvcmNlRXhpdCkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tZm9yY2VFeGl0Jyk7XG4gIH1cblxuICBpZihqc29uKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1qc29uJyk7XG4gIH1cblxuICBpZihsYXN0Q29tbWl0KSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1sYXN0Q29tbWl0Jyk7XG4gIH1cblxuICBpZihsaXN0VGVzdHMpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLWxpc3RUZXN0cycpO1xuICB9XG5cbiAgaWYobG9nSGVhcFVzYWdlKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1sb2dIZWFwVXNhZ2UnKTtcbiAgfVxuXG4gIGlmKG1heFdvcmtlcnMpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLW1heFdvcmtlcnMnLCBtYXhXb3JrZXJzKTtcbiAgfVxuXG4gIGlmKG5vU3RhY2tUcmFjZSkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tbm9TdGFja1RyYWNlJyk7XG4gIH1cblxuICBpZihub3RpZnkpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLW5vdGlmeScpO1xuICB9XG5cbiAgaWYob25seUNoYW5nZWQpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLW9ubHlDaGFuZ2VkJyk7XG4gIH1cblxuICBsZXQgdGVtcE91dHB1dEZpbGUgPSBvdXRwdXRGaWxlO1xuXG4gIGlmKCh1c2VBbmFseXplIHx8IHVzZURlYnVnKSAmJiAhb3V0cHV0RmlsZSkge1xuICAgIHRlbXBPdXRwdXRGaWxlID0gJy5sZXgtdGVzdC1yZXN1bHRzLmpzb24nO1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tanNvbicsICctLW91dHB1dEZpbGUnLCB0ZW1wT3V0cHV0RmlsZSk7XG4gIH0gZWxzZSBpZihvdXRwdXRGaWxlKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1vdXRwdXRGaWxlJywgb3V0cHV0RmlsZSk7XG4gIH1cblxuICBpZihwYXNzV2l0aE5vVGVzdHMpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLXBhc3NXaXRoTm9UZXN0cycpO1xuICB9XG5cbiAgaWYocnVuSW5CYW5kKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1ydW5JbkJhbmQnKTtcbiAgfVxuXG4gIGlmKHNob3dDb25maWcpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLXNob3dDb25maWcnKTtcbiAgfVxuXG4gIGlmKHNpbGVudCkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tc2lsZW50Jyk7XG4gIH1cblxuICBpZih0ZXN0TG9jYXRpb25JblJlc3VsdHMpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLXRlc3RMb2NhdGlvbkluUmVzdWx0cycpO1xuICB9XG5cbiAgaWYodGVzdE5hbWVQYXR0ZXJuKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS10ZXN0TmFtZVBhdHRlcm4nLCB0ZXN0TmFtZVBhdHRlcm4pO1xuICB9XG5cbiAgaWYodGVzdFBhdGhQYXR0ZXJuKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS10ZXN0UGF0aFBhdHRlcm4nLCB0ZXN0UGF0aFBhdHRlcm4pO1xuICB9XG5cbiAgaWYodXNlU3RkZXJyKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS11c2VTdGRlcnInKTtcbiAgfVxuXG4gIGlmKHZlcmJvc2UpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLXZlcmJvc2UnKTtcbiAgfVxuXG4gIGlmKHdhdGNoQWxsKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS13YXRjaEFsbCcpO1xuICB9XG5cbiAgaWYocmVtb3ZlQ2FjaGUpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLW5vLWNhY2hlJyk7XG4gIH1cblxuICBpZihqZXN0U2V0dXBGaWxlICYmIGV4aXN0c1N5bmMoamVzdFNldHVwRmlsZSkpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKGAtLXNldHVwRmlsZXNBZnRlckVudj0ke2plc3RTZXR1cEZpbGV9YCk7XG4gIH1cblxuICBpZih1cGRhdGUpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLXVwZGF0ZVNuYXBzaG90Jyk7XG4gIH1cblxuICBpZih3YXRjaCkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0td2F0Y2gnLCB3YXRjaCk7XG4gIH1cblxuICBpZihhcmdzKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCguLi5hcmdzKTtcbiAgfVxuXG4gIGlmKGZpbGVzICYmIGZpbGVzLmxlbmd0aCA+IDApIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKC4uLmZpbGVzKTtcbiAgfVxuXG4gIGlmKGRlYnVnKSB7XG4gICAgbG9nKGBKZXN0IG9wdGlvbnM6ICR7amVzdE9wdGlvbnMuam9pbignICcpfWAsICdpbmZvJywgcXVpZXQpO1xuICAgIGxvZyhgTk9ERV9PUFRJT05TOiAke25vZGVPcHRpb25zfWAsICdpbmZvJywgcXVpZXQpO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBjb25zdCBlbnY6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgICAuLi5wcm9jZXNzLmVudixcbiAgICAgIE5PREVfT1BUSU9OUzogbm9kZU9wdGlvbnNcbiAgICB9O1xuXG4gICAgYXdhaXQgZXhlY2EoamVzdFBhdGgsIGplc3RPcHRpb25zLCB7XG4gICAgICBlbmNvZGluZzogJ3V0ZjgnLFxuICAgICAgZW52LFxuICAgICAgc3RkaW86ICdpbmhlcml0J1xuICAgIH0pO1xuXG4gICAgc3Bpbm5lci5zdWNjZWVkKCdUZXN0aW5nIGNvbXBsZXRlZCEnKTtcblxuICAgIGlmKHVzZUFuYWx5emUpIHtcbiAgICAgIHNwaW5uZXIuc3RhcnQoJ0FJIGlzIGFuYWx5emluZyB0ZXN0IGNvdmVyYWdlIGFuZCBzdWdnZXN0aW5nIGltcHJvdmVtZW50cy4uLicpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCB0ZXN0UmVzdWx0cyA9IHByb2Nlc3NUZXN0UmVzdWx0cyh0ZW1wT3V0cHV0RmlsZSk7XG4gICAgICAgIGNvbnN0IGZpbGVQYXR0ZXJucyA9IGdldFRlc3RGaWxlUGF0dGVybnModGVzdFBhdGhQYXR0ZXJuKTtcblxuICAgICAgICBhd2FpdCBhaUZ1bmN0aW9uKHtcbiAgICAgICAgICBjb250ZXh0OiB0cnVlLFxuICAgICAgICAgIHByb21wdDogYEFuYWx5emUgdGhlc2UgSmVzdCB0ZXN0IHJlc3VsdHMgYW5kIHN1Z2dlc3QgdGVzdCBjb3ZlcmFnZSBpbXByb3ZlbWVudHM6XG5cbiR7SlNPTi5zdHJpbmdpZnkodGVzdFJlc3VsdHMsIG51bGwsIDIpfVxuXG5UZXN0IHBhdHRlcm5zOiAke2ZpbGVQYXR0ZXJucy5qb2luKCcsICcpfVxuXG5QbGVhc2UgcHJvdmlkZTpcbjEuIEFuYWx5c2lzIG9mIGN1cnJlbnQgY292ZXJhZ2UgZ2Fwc1xuMi4gU3VnZ2VzdGlvbnMgZm9yIGltcHJvdmluZyB0ZXN0IGNhc2VzXG4zLiBSZWNvbW1lbmRhdGlvbnMgZm9yIGFkZGl0aW9uYWwgaW50ZWdyYXRpb24gdGVzdCBzY2VuYXJpb3NcbjQuIEJlc3QgcHJhY3RpY2VzIGZvciBpbmNyZWFzaW5nIHRlc3QgZWZmZWN0aXZlbmVzc2AsXG4gICAgICAgICAgcXVpZXQsXG4gICAgICAgICAgdGFzazogJ29wdGltaXplJ1xuICAgICAgICB9KTtcblxuICAgICAgICBzcGlubmVyLnN1Y2NlZWQoJ0FJIHRlc3QgYW5hbHlzaXMgY29tcGxldGUnKTtcbiAgICAgIH0gY2F0Y2ggKGFpRXJyb3IpIHtcbiAgICAgICAgc3Bpbm5lci5mYWlsKCdDb3VsZCBub3QgZ2VuZXJhdGUgQUkgdGVzdCBhbmFseXNpcycpO1xuICAgICAgICBpZighcXVpZXQpIHtcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0FJIGFuYWx5c2lzIGVycm9yOicsIGFpRXJyb3IpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgY2FsbGJhY2soMCk7XG4gICAgcmV0dXJuIDA7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgbG9nKGBcXG4ke2NsaU5hbWV9IEVycm9yOiBDaGVjayBmb3IgdW5pdCB0ZXN0IGVycm9ycyBhbmQvb3IgY292ZXJhZ2UuYCwgJ2Vycm9yJywgcXVpZXQpO1xuXG4gICAgc3Bpbm5lci5mYWlsKCdUZXN0aW5nIGZhaWxlZCEnKTtcblxuICAgIGlmKHVzZURlYnVnKSB7XG4gICAgICBzcGlubmVyLnN0YXJ0KCdBSSBpcyBhbmFseXppbmcgdGVzdCBmYWlsdXJlcy4uLicpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCB0ZXN0UmVzdWx0cyA9IHByb2Nlc3NUZXN0UmVzdWx0cyh0ZW1wT3V0cHV0RmlsZSk7XG5cbiAgICAgICAgYXdhaXQgYWlGdW5jdGlvbih7XG4gICAgICAgICAgY29udGV4dDogdHJ1ZSxcbiAgICAgICAgICBwcm9tcHQ6IGBEZWJ1ZyB0aGVzZSBmYWlsZWQgSmVzdCB0ZXN0cyBhbmQgc3VnZ2VzdCBmaXhlczpcblxuJHtKU09OLnN0cmluZ2lmeShlcnJvci5tZXNzYWdlLCBudWxsLCAyKX1cblxuVGVzdCByZXN1bHRzOiAke0pTT04uc3RyaW5naWZ5KHRlc3RSZXN1bHRzLCBudWxsLCAyKX1cblxuUGxlYXNlIHByb3ZpZGU6XG4xLiBBbmFseXNpcyBvZiB3aHkgdGhlIHRlc3RzIGFyZSBmYWlsaW5nXG4yLiBTcGVjaWZpYyBzdWdnZXN0aW9ucyB0byBmaXggZWFjaCBmYWlsaW5nIHRlc3RcbjMuIEFueSBwb3RlbnRpYWwgaXNzdWVzIHdpdGggdGVzdCBmaXh0dXJlcyBvciBtb2Nrc1xuNC4gQ29kZSBleGFtcGxlcyBmb3Igc29sdXRpb25zYCxcbiAgICAgICAgICBxdWlldCxcbiAgICAgICAgICB0YXNrOiAnaGVscCdcbiAgICAgICAgfSk7XG5cbiAgICAgICAgc3Bpbm5lci5zdWNjZWVkKCdBSSBkZWJ1Z2dpbmcgYXNzaXN0YW5jZSBjb21wbGV0ZScpO1xuICAgICAgfSBjYXRjaCAoYWlFcnJvcikge1xuICAgICAgICBzcGlubmVyLmZhaWwoJ0NvdWxkIG5vdCBnZW5lcmF0ZSBBSSBkZWJ1Z2dpbmcgYXNzaXN0YW5jZScpO1xuICAgICAgICBpZighcXVpZXQpIHtcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0FJIGRlYnVnZ2luZyBlcnJvcjonLCBhaUVycm9yKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGNhbGxiYWNrKDEpO1xuICAgIHJldHVybiAxO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCB0ZXN0OyJdLAogICJtYXBwaW5ncyI6ICJBQUlBLFNBQVEsYUFBWTtBQUNwQixTQUFRLFlBQVksb0JBQW1CO0FBQ3ZDLFNBQVEsUUFBUSxnQkFBZTtBQUMvQixTQUFRLFdBQVcsbUJBQWtCO0FBRXJDLFNBQVEsV0FBVywrQkFBOEI7QUFDakQsU0FBUSxxQkFBb0I7QUFDNUIsU0FBUSx5QkFBd0I7QUFDaEMsU0FBUSxXQUFV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
414
+ export default test;
415
+
416
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21tYW5kcy90ZXN0L3Rlc3QudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTgtUHJlc2VudCwgTml0cm9nZW4gTGFicywgSW5jLlxuICogQ29weXJpZ2h0cyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSB0aGUgYWNjb21wYW55aW5nIExJQ0VOU0UgZmlsZSBmb3IgdGVybXMuXG4gKi9cbmltcG9ydCB7ZXhlY2F9IGZyb20gJ2V4ZWNhJztcbmltcG9ydCB7ZXhpc3RzU3luYywgcmVhZEZpbGVTeW5jfSBmcm9tICdmcyc7XG5pbXBvcnQge3N5bmMgYXMgZ2xvYlN5bmN9IGZyb20gJ2dsb2InO1xuaW1wb3J0IHtyZXNvbHZlIGFzIHBhdGhSZXNvbHZlfSBmcm9tICdwYXRoJztcblxuaW1wb3J0IHtMZXhDb25maWcsIGdldFR5cGVTY3JpcHRDb25maWdQYXRofSBmcm9tICcuLi8uLi9MZXhDb25maWcuanMnO1xuaW1wb3J0IHtjcmVhdGVTcGlubmVyfSBmcm9tICcuLi8uLi91dGlscy9hcHAuanMnO1xuaW1wb3J0IHtyZXNvbHZlQmluYXJ5UGF0aH0gZnJvbSAnLi4vLi4vdXRpbHMvZmlsZS5qcyc7XG5pbXBvcnQge2xvZ30gZnJvbSAnLi4vLi4vdXRpbHMvbG9nLmpzJztcbmltcG9ydCB7YWlGdW5jdGlvbn0gZnJvbSAnLi4vYWkvYWkuanMnO1xuXG5jb25zdCBkZXRlY3RFU00gPSAoY3dkOiBzdHJpbmcpOiBib29sZWFuID0+IHtcbiAgY29uc3QgcGFja2FnZUpzb25QYXRoID0gcGF0aFJlc29sdmUoY3dkLCAncGFja2FnZS5qc29uJyk7XG5cbiAgaWYoZXhpc3RzU3luYyhwYWNrYWdlSnNvblBhdGgpKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBhY2thZ2VKc29uQ29udGVudCA9IHJlYWRGaWxlU3luYyhwYWNrYWdlSnNvblBhdGgsICd1dGY4Jyk7XG4gICAgICBjb25zdCBwYWNrYWdlSnNvbiA9IEpTT04ucGFyc2UocGFja2FnZUpzb25Db250ZW50KTtcbiAgICAgIHJldHVybiBwYWNrYWdlSnNvbi50eXBlID09PSAnbW9kdWxlJztcbiAgICB9IGNhdGNoKF9lcnJvcikge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVzdE9wdGlvbnMge1xuICByZWFkb25seSBhbmFseXplPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgYWlEZWJ1Zz86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGFpR2VuZXJhdGU/OiBib29sZWFuO1xuICByZWFkb25seSBhaUFuYWx5emU/OiBib29sZWFuO1xuICByZWFkb25seSBiYWlsPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgY2hhbmdlZEZpbGVzV2l0aEFuY2VzdG9yPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgY2hhbmdlZFNpbmNlPzogc3RyaW5nO1xuICByZWFkb25seSBjaT86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGNsaU5hbWU/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGNvbGxlY3RDb3ZlcmFnZUZyb20/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGNvbG9ycz86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGNvbmZpZz86IHN0cmluZztcbiAgcmVhZG9ubHkgZGVidWc/OiBib29sZWFuO1xuICByZWFkb25seSBkZWJ1Z1Rlc3RzPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgZGV0ZWN0T3BlbkhhbmRsZXM/OiBib29sZWFuO1xuICByZWFkb25seSBlbnY/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGVycm9yT25EZXByZWNhdGVkPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgZXhwYW5kPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgZm9yY2VFeGl0PzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgZ2VuZXJhdGU/OiBib29sZWFuO1xuICByZWFkb25seSBqc29uPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgbGFzdENvbW1pdD86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGxpc3RUZXN0cz86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGxvZ0hlYXBVc2FnZT86IGJvb2xlYW47XG4gIHJlYWRvbmx5IG1heFdvcmtlcnM/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IG5vU3RhY2tUcmFjZT86IGJvb2xlYW47XG4gIHJlYWRvbmx5IG5vdGlmeT86IGJvb2xlYW47XG4gIHJlYWRvbmx5IG9ubHlDaGFuZ2VkPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgb3V0cHV0RmlsZT86IHN0cmluZztcbiAgcmVhZG9ubHkgcGFzc1dpdGhOb1Rlc3RzPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgcXVpZXQ/OiBib29sZWFuO1xuICByZWFkb25seSByZW1vdmVDYWNoZT86IGJvb2xlYW47XG4gIHJlYWRvbmx5IHJ1bkluQmFuZD86IGJvb2xlYW47XG4gIHJlYWRvbmx5IHNldHVwPzogc3RyaW5nO1xuICByZWFkb25seSBzaG93Q29uZmlnPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgc2lsZW50PzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgdGVzdExvY2F0aW9uSW5SZXN1bHRzPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgdGVzdE5hbWVQYXR0ZXJuPzogc3RyaW5nO1xuICByZWFkb25seSB0ZXN0UGF0aFBhdHRlcm4/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHVwZGF0ZT86IGJvb2xlYW47XG4gIHJlYWRvbmx5IHVzZVN0ZGVycj86IGJvb2xlYW47XG4gIHJlYWRvbmx5IHZlcmJvc2U/OiBib29sZWFuO1xuICByZWFkb25seSB3YXRjaD86IHN0cmluZztcbiAgcmVhZG9ubHkgd2F0Y2hBbGw/OiBib29sZWFuO1xufVxuXG5leHBvcnQgdHlwZSBUZXN0Q2FsbGJhY2sgPSB0eXBlb2YgcHJvY2Vzcy5leGl0O1xuXG5jb25zdCBkZWZhdWx0RXhpdCA9ICgoY29kZT86IG51bWJlcikgPT4ge1xuICBpZihwcm9jZXNzLmVudi5KRVNUX1dPUktFUl9JRCB8fCBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gJ3Rlc3QnKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZCBhcyBuZXZlcjtcbiAgfVxuXG4gIHByb2Nlc3MuZXhpdChjb2RlKTtcbn0pIGFzIHR5cGVvZiBwcm9jZXNzLmV4aXQ7XG5cbmV4cG9ydCBjb25zdCBnZXRUZXN0RmlsZVBhdHRlcm5zID0gKHRlc3RQYXRoUGF0dGVybj86IHN0cmluZyk6IHN0cmluZ1tdID0+IHtcbiAgY29uc3QgZGVmYXVsdFBhdHRlcm5zID0gWycqKi8qLnRlc3QuKicsICcqKi8qLnNwZWMuKicsICcqKi8qLmludGVncmF0aW9uLionXTtcblxuICBpZighdGVzdFBhdGhQYXR0ZXJuKSB7XG4gICAgcmV0dXJuIGRlZmF1bHRQYXR0ZXJucztcbiAgfVxuXG4gIHJldHVybiBbdGVzdFBhdGhQYXR0ZXJuXTtcbn07XG5cbmNvbnN0IGZpbmRVbmNvdmVyZWRTb3VyY2VGaWxlcyA9ICgpOiBzdHJpbmdbXSA9PiB7XG4gIGNvbnN0IHNvdXJjZUZpbGVzID0gZ2xvYlN5bmMoJ3NyYy8qKi8qLnt0cyx0c3gsanMsanN4fScsIHtcbiAgICBjd2Q6IHByb2Nlc3MuY3dkKCksXG4gICAgaWdub3JlOiBbJyoqL25vZGVfbW9kdWxlcy8qKicsICcqKi9kaXN0LyoqJywgJyoqL2xpYi8qKicsICcqKi8qLnRlc3QuKicsICcqKi8qLnNwZWMuKiddXG4gIH0pO1xuXG4gIGNvbnN0IHRlc3RGaWxlcyA9IGdsb2JTeW5jKCcqKi8qLnt0ZXN0LHNwZWN9Lnt0cyx0c3gsanMsanN4fScsIHtcbiAgICBjd2Q6IHByb2Nlc3MuY3dkKCksXG4gICAgaWdub3JlOiBbJyoqL25vZGVfbW9kdWxlcy8qKicsICcqKi9kaXN0LyoqJywgJyoqL2xpYi8qKiddXG4gIH0pO1xuXG4gIHJldHVybiBzb3VyY2VGaWxlcy5maWx0ZXIoKHNvdXJjZUZpbGUpID0+IHtcbiAgICBjb25zdCBiYXNlTmFtZSA9IHNvdXJjZUZpbGUucmVwbGFjZSgvXFwuW14vLl0rJC8sICcnKTtcbiAgICByZXR1cm4gIXRlc3RGaWxlcy5zb21lKCh0ZXN0RmlsZSkgPT4gdGVzdEZpbGUuaW5jbHVkZXMoYmFzZU5hbWUpKTtcbiAgfSk7XG59O1xuXG5jb25zdCBwcm9jZXNzVGVzdFJlc3VsdHMgPSAob3V0cHV0RmlsZT86IHN0cmluZyk6IGFueSA9PiB7XG4gIGlmKCFvdXRwdXRGaWxlKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB0cnkge1xuICAgIGNvbnN0IGNvbnRlbnQgPSByZWFkRmlsZVN5bmMob3V0cHV0RmlsZSwgJ3V0Zi04Jyk7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UoY29udGVudCk7XG4gIH0gY2F0Y2goX2Vycm9yKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCB0ZXN0ID0gYXN5bmMgKFxuICBvcHRpb25zOiBUZXN0T3B0aW9ucyxcbiAgYXJncz86IHN0cmluZ1tdLFxuICBmaWxlc09yQ2FsbGJhY2s/OiBzdHJpbmdbXSB8IFRlc3RDYWxsYmFjayxcbiAgY2FsbGJhY2tQYXJhbT86IFRlc3RDYWxsYmFja1xuKTogUHJvbWlzZTxudW1iZXI+ID0+IHtcbiAgLy8gQmFja3dhcmQtY29tcGF0IGFyZ3VtZW50IG5vcm1hbGl6YXRpb246IGFsbG93IGNhbGxiYWNrIGFzIHRoaXJkIHBhcmFtXG4gIGxldCBmaWxlczogc3RyaW5nW10gfCB1bmRlZmluZWQ7XG4gIGxldCBjYWxsYmFjazogVGVzdENhbGxiYWNrID0gZGVmYXVsdEV4aXQ7XG5cbiAgaWYodHlwZW9mIGZpbGVzT3JDYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNhbGxiYWNrID0gZmlsZXNPckNhbGxiYWNrIGFzIFRlc3RDYWxsYmFjaztcbiAgfSBlbHNlIHtcbiAgICBmaWxlcyA9IGZpbGVzT3JDYWxsYmFjayBhcyBzdHJpbmdbXSB8IHVuZGVmaW5lZDtcbiAgICBjYWxsYmFjayA9IGNhbGxiYWNrUGFyYW0gfHwgZGVmYXVsdEV4aXQ7XG4gIH1cbiAgY29uc3Qge1xuICAgIGFuYWx5emUgPSBmYWxzZSxcbiAgICBhaUFuYWx5emUgPSBmYWxzZSxcbiAgICBhaURlYnVnID0gZmFsc2UsXG4gICAgYWlHZW5lcmF0ZSA9IGZhbHNlLFxuICAgIGJhaWwsXG4gICAgY2hhbmdlZEZpbGVzV2l0aEFuY2VzdG9yLFxuICAgIGNoYW5nZWRTaW5jZSxcbiAgICBjaSxcbiAgICBjbGlOYW1lID0gJ0xleCcsXG4gICAgY29sbGVjdENvdmVyYWdlRnJvbSxcbiAgICBjb2xvcnMsXG4gICAgY29uZmlnLFxuICAgIGRlYnVnID0gZmFsc2UsXG4gICAgZGVidWdUZXN0cyA9IGZhbHNlLFxuICAgIGRldGVjdE9wZW5IYW5kbGVzLFxuICAgIGVudixcbiAgICBlcnJvck9uRGVwcmVjYXRlZCxcbiAgICBleHBhbmQsXG4gICAgZm9yY2VFeGl0LFxuICAgIGdlbmVyYXRlID0gZmFsc2UsXG4gICAganNvbixcbiAgICBsYXN0Q29tbWl0LFxuICAgIGxpc3RUZXN0cyxcbiAgICBsb2dIZWFwVXNhZ2UsXG4gICAgbWF4V29ya2VycyxcbiAgICBub1N0YWNrVHJhY2UsXG4gICAgbm90aWZ5LFxuICAgIG9ubHlDaGFuZ2VkLFxuICAgIG91dHB1dEZpbGUsXG4gICAgcGFzc1dpdGhOb1Rlc3RzLFxuICAgIHF1aWV0LFxuICAgIHJlbW92ZUNhY2hlLFxuICAgIHJ1bkluQmFuZCxcbiAgICBzZXR1cCxcbiAgICBzaG93Q29uZmlnLFxuICAgIHNpbGVudCxcbiAgICB0ZXN0TG9jYXRpb25JblJlc3VsdHMsXG4gICAgdGVzdE5hbWVQYXR0ZXJuLFxuICAgIHRlc3RQYXRoUGF0dGVybixcbiAgICB1cGRhdGUsXG4gICAgdXNlU3RkZXJyLFxuICAgIHZlcmJvc2UsXG4gICAgd2F0Y2gsXG4gICAgd2F0Y2hBbGxcbiAgfSA9IG9wdGlvbnM7XG5cbiAgY29uc3QgdXNlR2VuZXJhdGUgPSBnZW5lcmF0ZSB8fCBhaUdlbmVyYXRlO1xuICBjb25zdCB1c2VBbmFseXplID0gYW5hbHl6ZSB8fCBhaUFuYWx5emU7XG4gIGNvbnN0IHVzZURlYnVnID0gZGVidWdUZXN0cyB8fCBhaURlYnVnO1xuXG4gIGxvZyhgJHtjbGlOYW1lfSB0ZXN0aW5nLi4uYCwgJ2luZm8nLCBxdWlldCk7XG5cbiAgY29uc3Qgc3Bpbm5lciA9IGNyZWF0ZVNwaW5uZXIocXVpZXQpO1xuXG4gIGF3YWl0IExleENvbmZpZy5wYXJzZUNvbmZpZyhvcHRpb25zKTtcblxuICBjb25zdCB7dXNlVHlwZXNjcmlwdH0gPSBMZXhDb25maWcuY29uZmlnO1xuXG4gIGlmKHVzZVR5cGVzY3JpcHQpIHtcbiAgICBjb25zdCB0ZXN0Q29uZmlnUGF0aCA9IGdldFR5cGVTY3JpcHRDb25maWdQYXRoKCd0c2NvbmZpZy50ZXN0Lmpzb24nKTtcbiAgICBpZihleGlzdHNTeW5jKHRlc3RDb25maWdQYXRoKSkge1xuICAgICAgbG9nKCdVc2luZyB0c2NvbmZpZy50ZXN0Lmpzb24gZm9yIHRlc3RpbmcuLi4nLCAnaW5mbycsIHF1aWV0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgTGV4Q29uZmlnLmNoZWNrVGVzdFR5cGVzY3JpcHRDb25maWcoKTtcbiAgICB9XG4gIH1cblxuICBpZih1c2VHZW5lcmF0ZSkge1xuICAgIHNwaW5uZXIuc3RhcnQoJ0FJIGlzIGFuYWx5emluZyBjb2RlIHRvIGdlbmVyYXRlIHRlc3QgY2FzZXMuLi4nKTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCB1bmNvdmVyZWRGaWxlcyA9IGZpbmRVbmNvdmVyZWRTb3VyY2VGaWxlcygpO1xuXG4gICAgICBpZih1bmNvdmVyZWRGaWxlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IHRhcmdldEZpbGUgPSB1bmNvdmVyZWRGaWxlc1swXTtcblxuICAgICAgICBhd2FpdCBhaUZ1bmN0aW9uKHtcbiAgICAgICAgICBjb250ZXh0OiB0cnVlLFxuICAgICAgICAgIGZpbGU6IHRhcmdldEZpbGUsXG4gICAgICAgICAgcHJvbXB0OiBgR2VuZXJhdGUgSmVzdCB1bml0IHRlc3RzIGZvciB0aGlzIGZpbGU6ICR7dGFyZ2V0RmlsZX1cXG5cXG4ke3JlYWRGaWxlU3luYyh0YXJnZXRGaWxlLCAndXRmLTgnKX1cXG5cXG5QbGVhc2UgY3JlYXRlIGNvbXByZWhlbnNpdmUgdGVzdHMgdGhhdCBjb3ZlciB0aGUgbWFpbiBmdW5jdGlvbmFsaXR5LiBJbmNsdWRlIHRlc3QgZml4dHVyZXMgYW5kIG1vY2tzIHdoZXJlIG5lY2Vzc2FyeS5gLFxuICAgICAgICAgIHF1aWV0LFxuICAgICAgICAgIHRhc2s6ICd0ZXN0J1xuICAgICAgICB9KTtcblxuICAgICAgICBzcGlubmVyLnN1Y2NlZWQoYEFJIHRlc3QgZ2VuZXJhdGlvbiBzdWdnZXN0aW9ucyBwcm92aWRlZCBmb3IgJHt0YXJnZXRGaWxlfWApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3Bpbm5lci5zdWNjZWVkKCdBbGwgc291cmNlIGZpbGVzIGFwcGVhciB0byBoYXZlIGNvcnJlc3BvbmRpbmcgdGVzdCBmaWxlcycpO1xuICAgICAgfVxuICAgIH0gY2F0Y2goYWlFcnJvcikge1xuICAgICAgc3Bpbm5lci5mYWlsKCdDb3VsZCBub3QgZ2VuZXJhdGUgQUkgdGVzdCBzdWdnZXN0aW9ucycpO1xuICAgICAgaWYoIXF1aWV0KSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ0FJIHRlc3QgZ2VuZXJhdGlvbiBlcnJvcjonLCBhaUVycm9yKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb25zdCBwcm9qZWN0SmVzdEJpbiA9IHBhdGhSZXNvbHZlKHByb2Nlc3MuY3dkKCksICdub2RlX21vZHVsZXMvLmJpbi9qZXN0Jyk7XG4gIGxldCBqZXN0UGF0aDogc3RyaW5nO1xuXG4gIGlmKGV4aXN0c1N5bmMocHJvamVjdEplc3RCaW4pKSB7XG4gICAgamVzdFBhdGggPSBwcm9qZWN0SmVzdEJpbjtcbiAgfSBlbHNlIHtcbiAgICBqZXN0UGF0aCA9IHJlc29sdmVCaW5hcnlQYXRoKCdqZXN0Jyk7XG4gIH1cblxuICBpZighamVzdFBhdGgpIHtcbiAgICBsb2coYFxcbiR7Y2xpTmFtZX0gRXJyb3I6IEplc3QgYmluYXJ5IG5vdCBmb3VuZCBpbiBMZXgncyBub2RlX21vZHVsZXMgb3IgbW9ub3JlcG8gcm9vdGAsICdlcnJvcicsIHF1aWV0KTtcbiAgICBsb2coJ1BsZWFzZSByZWluc3RhbGwgTGV4IG9yIGNoZWNrIHlvdXIgaW5zdGFsbGF0aW9uLicsICdpbmZvJywgcXVpZXQpO1xuICAgIHJldHVybiAxO1xuICB9XG5cbiAgbGV0IGplc3RDb25maWdGaWxlOiBzdHJpbmc7XG4gIGxldCBwcm9qZWN0SmVzdENvbmZpZzogYW55ID0gbnVsbDtcblxuICBpZihjb25maWcpIHtcbiAgICBqZXN0Q29uZmlnRmlsZSA9IGNvbmZpZztcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBwcm9qZWN0SmVzdENvbmZpZ1BhdGggPSBwYXRoUmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCAnamVzdC5jb25maWcuanMnKTtcbiAgICBjb25zdCBwcm9qZWN0SmVzdENvbmZpZ0Nqc1BhdGggPSBwYXRoUmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCAnamVzdC5jb25maWcuY2pzJyk7XG4gICAgY29uc3QgcHJvamVjdEplc3RDb25maWdNanNQYXRoID0gcGF0aFJlc29sdmUocHJvY2Vzcy5jd2QoKSwgJ2plc3QuY29uZmlnLm1qcycpO1xuICAgIGNvbnN0IHByb2plY3RKZXN0Q29uZmlnSnNvblBhdGggPSBwYXRoUmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCAnamVzdC5jb25maWcuanNvbicpO1xuXG4gICAgaWYoZXhpc3RzU3luYyhwcm9qZWN0SmVzdENvbmZpZ1BhdGgpKSB7XG4gICAgICBqZXN0Q29uZmlnRmlsZSA9IHByb2plY3RKZXN0Q29uZmlnUGF0aDtcbiAgICAgIGlmKGRlYnVnKSB7XG4gICAgICAgIGxvZyhgVXNpbmcgcHJvamVjdCBKZXN0IGNvbmZpZyBmaWxlOiAke2plc3RDb25maWdGaWxlfWAsICdpbmZvJywgcXVpZXQpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZihleGlzdHNTeW5jKHByb2plY3RKZXN0Q29uZmlnQ2pzUGF0aCkpIHtcbiAgICAgIGplc3RDb25maWdGaWxlID0gcHJvamVjdEplc3RDb25maWdDanNQYXRoO1xuICAgICAgaWYoZGVidWcpIHtcbiAgICAgICAgbG9nKGBVc2luZyBwcm9qZWN0IEplc3QgY29uZmlnIGZpbGUgKENKUyk6ICR7amVzdENvbmZpZ0ZpbGV9YCwgJ2luZm8nLCBxdWlldCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmKGV4aXN0c1N5bmMocHJvamVjdEplc3RDb25maWdNanNQYXRoKSkge1xuICAgICAgamVzdENvbmZpZ0ZpbGUgPSBwcm9qZWN0SmVzdENvbmZpZ01qc1BhdGg7XG4gICAgICBpZihkZWJ1Zykge1xuICAgICAgICBsb2coYFVzaW5nIHByb2plY3QgSmVzdCBjb25maWcgZmlsZSAoTUpTKTogJHtqZXN0Q29uZmlnRmlsZX1gLCAnaW5mbycsIHF1aWV0KTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYoZXhpc3RzU3luYyhwcm9qZWN0SmVzdENvbmZpZ0pzb25QYXRoKSkge1xuICAgICAgamVzdENvbmZpZ0ZpbGUgPSBwcm9qZWN0SmVzdENvbmZpZ0pzb25QYXRoO1xuICAgICAgaWYoZGVidWcpIHtcbiAgICAgICAgbG9nKGBVc2luZyBwcm9qZWN0IEplc3QgY29uZmlnIGZpbGUgKEpTT04pOiAke2plc3RDb25maWdGaWxlfWAsICdpbmZvJywgcXVpZXQpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBObyBKZXN0IGNvbmZpZyBmaWxlIGV4aXN0cyBpbiB0aGUgcHJvamVjdFxuICAgICAgLy8gQ2hlY2sgaWYgdGhlcmUncyBhIEplc3QgY29uZmlnIGluIGxleC5jb25maWcuY2pzXG4gICAgICBwcm9qZWN0SmVzdENvbmZpZyA9IExleENvbmZpZy5jb25maWcuamVzdDtcblxuICAgICAgY29uc3QgbGV4RGlyID0gTGV4Q29uZmlnLmdldExleERpcigpO1xuICAgICAgY29uc3QgbGV4SmVzdENvbmZpZyA9IHBhdGhSZXNvbHZlKGxleERpciwgJ2plc3QuY29uZmlnLm1qcycpO1xuXG4gICAgICBpZihkZWJ1Zykge1xuICAgICAgICBsb2coYExvb2tpbmcgZm9yIEplc3QgY29uZmlnIGF0OiAke2xleEplc3RDb25maWd9YCwgJ2luZm8nLCBxdWlldCk7XG4gICAgICAgIGxvZyhgRmlsZSBleGlzdHM6ICR7ZXhpc3RzU3luYyhsZXhKZXN0Q29uZmlnKX1gLCAnaW5mbycsIHF1aWV0KTtcbiAgICAgIH1cblxuICAgICAgaWYoZXhpc3RzU3luYyhsZXhKZXN0Q29uZmlnKSkge1xuICAgICAgICBqZXN0Q29uZmlnRmlsZSA9IGxleEplc3RDb25maWc7XG4gICAgICAgIGlmKHByb2plY3RKZXN0Q29uZmlnICYmIE9iamVjdC5rZXlzKHByb2plY3RKZXN0Q29uZmlnKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgaWYoZGVidWcpIHtcbiAgICAgICAgICAgIGxvZyhgVXNpbmcgTGV4IEplc3QgY29uZmlnIHdpdGggcHJvamVjdCBKZXN0IGNvbmZpZyBmcm9tIGxleC5jb25maWcuY2pzOiAke2plc3RDb25maWdGaWxlfWAsICdpbmZvJywgcXVpZXQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZihkZWJ1Zykge1xuICAgICAgICAgICAgbG9nKGBVc2luZyBMZXggSmVzdCBjb25maWcgKG5vIHByb2plY3QgSmVzdCBjb25maWcgZm91bmQpOiAke2plc3RDb25maWdGaWxlfWAsICdpbmZvJywgcXVpZXQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYoZGVidWcpIHtcbiAgICAgICAgICBsb2coJ05vIEplc3QgY29uZmlnIGZvdW5kIGluIHByb2plY3Qgb3IgTGV4JywgJ3dhcm4nLCBxdWlldCk7XG4gICAgICAgIH1cbiAgICAgICAgamVzdENvbmZpZ0ZpbGUgPSAnJztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb25zdCBqZXN0U2V0dXBGaWxlOiBzdHJpbmcgPSBzZXR1cCB8fCBwYXRoUmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCAnamVzdC5zZXR1cC5qcycpO1xuICBjb25zdCBqZXN0T3B0aW9uczogc3RyaW5nW10gPSBbJy0tbm8tY2FjaGUnXTtcblxuICBjb25zdCBpc0VTTSA9IGRldGVjdEVTTShwcm9jZXNzLmN3ZCgpKTtcbiAgbGV0IG5vZGVPcHRpb25zID0gcHJvY2Vzcy5lbnYuTk9ERV9PUFRJT05TIHx8ICcnO1xuICBpZihpc0VTTSkge1xuICAgIGlmKCFub2RlT3B0aW9ucy5pbmNsdWRlcygnLS1leHBlcmltZW50YWwtdm0tbW9kdWxlcycpKSB7XG4gICAgICBub2RlT3B0aW9ucyA9IGAke25vZGVPcHRpb25zfSAtLWV4cGVyaW1lbnRhbC12bS1tb2R1bGVzYC50cmltKCk7XG4gICAgfVxuICAgIGxvZygnRVNNIHByb2plY3QgZGV0ZWN0ZWQsIHVzaW5nIC0tZXhwZXJpbWVudGFsLXZtLW1vZHVsZXMgaW4gTk9ERV9PUFRJT05TJywgJ2luZm8nLCBxdWlldCk7XG4gIH1cblxuICBpZihqZXN0Q29uZmlnRmlsZSkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tY29uZmlnJywgamVzdENvbmZpZ0ZpbGUpO1xuICB9XG5cbiAgaWYoYmFpbCkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tYmFpbCcpO1xuICB9XG5cbiAgaWYoY2hhbmdlZEZpbGVzV2l0aEFuY2VzdG9yKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1jaGFuZ2VkRmlsZXNXaXRoQW5jZXN0b3InKTtcbiAgfVxuXG4gIGlmKGNoYW5nZWRTaW5jZSkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tY2hhbmdlZFNpbmNlJyk7XG4gIH1cblxuICBpZihjaSkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tY2knKTtcbiAgfVxuXG4gIGlmKGNvbGxlY3RDb3ZlcmFnZUZyb20pIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLWNvbGxlY3RDb3ZlcmFnZUZyb20nLCBjb2xsZWN0Q292ZXJhZ2VGcm9tKTtcbiAgfVxuXG4gIGlmKGNvbG9ycykge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tY29sb3JzJyk7XG4gIH1cblxuICBpZihkZWJ1Zykge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tZGVidWcnKTtcbiAgfVxuXG4gIGlmKGRldGVjdE9wZW5IYW5kbGVzKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1kZXRlY3RPcGVuSGFuZGxlcycpO1xuICB9XG5cbiAgaWYoZW52KSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1lbnYnKTtcbiAgfVxuXG4gIGlmKGVycm9yT25EZXByZWNhdGVkKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1lcnJvck9uRGVwcmVjYXRlZCcpO1xuICB9XG5cbiAgaWYoZXhwYW5kKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1leHBhbmQnKTtcbiAgfVxuXG4gIGlmKGZvcmNlRXhpdCkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tZm9yY2VFeGl0Jyk7XG4gIH1cblxuICBpZihqc29uKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1qc29uJyk7XG4gIH1cblxuICBpZihsYXN0Q29tbWl0KSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1sYXN0Q29tbWl0Jyk7XG4gIH1cblxuICBpZihsaXN0VGVzdHMpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLWxpc3RUZXN0cycpO1xuICB9XG5cbiAgaWYobG9nSGVhcFVzYWdlKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1sb2dIZWFwVXNhZ2UnKTtcbiAgfVxuXG4gIGlmKG1heFdvcmtlcnMpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLW1heFdvcmtlcnMnLCBtYXhXb3JrZXJzKTtcbiAgfVxuXG4gIGlmKG5vU3RhY2tUcmFjZSkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tbm9TdGFja1RyYWNlJyk7XG4gIH1cblxuICBpZihub3RpZnkpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLW5vdGlmeScpO1xuICB9XG5cbiAgaWYob25seUNoYW5nZWQpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLW9ubHlDaGFuZ2VkJyk7XG4gIH1cblxuICBsZXQgdGVtcE91dHB1dEZpbGUgPSBvdXRwdXRGaWxlO1xuXG4gIGlmKCh1c2VBbmFseXplIHx8IHVzZURlYnVnKSAmJiAhb3V0cHV0RmlsZSkge1xuICAgIHRlbXBPdXRwdXRGaWxlID0gJy5sZXgtdGVzdC1yZXN1bHRzLmpzb24nO1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tanNvbicsICctLW91dHB1dEZpbGUnLCB0ZW1wT3V0cHV0RmlsZSk7XG4gIH0gZWxzZSBpZihvdXRwdXRGaWxlKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1vdXRwdXRGaWxlJywgb3V0cHV0RmlsZSk7XG4gIH1cblxuICBpZihwYXNzV2l0aE5vVGVzdHMpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLXBhc3NXaXRoTm9UZXN0cycpO1xuICB9XG5cbiAgaWYocnVuSW5CYW5kKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1ydW5JbkJhbmQnKTtcbiAgfVxuXG4gIGlmKHNob3dDb25maWcpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLXNob3dDb25maWcnKTtcbiAgfVxuXG4gIGlmKHNpbGVudCkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tc2lsZW50Jyk7XG4gIH1cblxuICBpZih0ZXN0TG9jYXRpb25JblJlc3VsdHMpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLXRlc3RMb2NhdGlvbkluUmVzdWx0cycpO1xuICB9XG5cbiAgaWYodGVzdE5hbWVQYXR0ZXJuKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS10ZXN0TmFtZVBhdHRlcm4nLCB0ZXN0TmFtZVBhdHRlcm4pO1xuICB9XG5cbiAgaWYodGVzdFBhdGhQYXR0ZXJuKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS10ZXN0UGF0aFBhdHRlcm4nLCB0ZXN0UGF0aFBhdHRlcm4pO1xuICB9XG5cbiAgaWYodXNlU3RkZXJyKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS11c2VTdGRlcnInKTtcbiAgfVxuXG4gIGlmKHZlcmJvc2UpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLXZlcmJvc2UnKTtcbiAgfVxuXG4gIGlmKHdhdGNoQWxsKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS13YXRjaEFsbCcpO1xuICB9XG5cbiAgaWYocmVtb3ZlQ2FjaGUpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLW5vLWNhY2hlJyk7XG4gIH1cblxuICBpZihqZXN0U2V0dXBGaWxlICYmIGV4aXN0c1N5bmMoamVzdFNldHVwRmlsZSkpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKGAtLXNldHVwRmlsZXNBZnRlckVudj0ke2plc3RTZXR1cEZpbGV9YCk7XG4gIH1cblxuICBpZih1cGRhdGUpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLXVwZGF0ZVNuYXBzaG90Jyk7XG4gIH1cblxuICBpZih3YXRjaCkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0td2F0Y2gnLCB3YXRjaCk7XG4gIH1cblxuICBpZihhcmdzKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCguLi5hcmdzKTtcbiAgfVxuXG4gIGlmKGZpbGVzICYmIGZpbGVzLmxlbmd0aCA+IDApIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKC4uLmZpbGVzKTtcbiAgfVxuXG4gIGlmKGRlYnVnKSB7XG4gICAgbG9nKGBKZXN0IG9wdGlvbnM6ICR7amVzdE9wdGlvbnMuam9pbignICcpfWAsICdpbmZvJywgcXVpZXQpO1xuICAgIGxvZyhgTk9ERV9PUFRJT05TOiAke25vZGVPcHRpb25zfWAsICdpbmZvJywgcXVpZXQpO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBjb25zdCBlbnY6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgICAuLi5wcm9jZXNzLmVudixcbiAgICAgIE5PREVfT1BUSU9OUzogbm9kZU9wdGlvbnNcbiAgICB9O1xuXG4gICAgYXdhaXQgZXhlY2EoamVzdFBhdGgsIGplc3RPcHRpb25zLCB7XG4gICAgICBlbmNvZGluZzogJ3V0ZjgnLFxuICAgICAgZW52LFxuICAgICAgc3RkaW86ICdpbmhlcml0J1xuICAgIH0pO1xuXG4gICAgc3Bpbm5lci5zdWNjZWVkKCdUZXN0aW5nIGNvbXBsZXRlZCEnKTtcblxuICAgIGlmKHVzZUFuYWx5emUpIHtcbiAgICAgIHNwaW5uZXIuc3RhcnQoJ0FJIGlzIGFuYWx5emluZyB0ZXN0IGNvdmVyYWdlIGFuZCBzdWdnZXN0aW5nIGltcHJvdmVtZW50cy4uLicpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCB0ZXN0UmVzdWx0cyA9IHByb2Nlc3NUZXN0UmVzdWx0cyh0ZW1wT3V0cHV0RmlsZSk7XG4gICAgICAgIGNvbnN0IGZpbGVQYXR0ZXJucyA9IGdldFRlc3RGaWxlUGF0dGVybnModGVzdFBhdGhQYXR0ZXJuKTtcblxuICAgICAgICBhd2FpdCBhaUZ1bmN0aW9uKHtcbiAgICAgICAgICBjb250ZXh0OiB0cnVlLFxuICAgICAgICAgIHByb21wdDogYEFuYWx5emUgdGhlc2UgSmVzdCB0ZXN0IHJlc3VsdHMgYW5kIHN1Z2dlc3QgdGVzdCBjb3ZlcmFnZSBpbXByb3ZlbWVudHM6XG5cbiR7SlNPTi5zdHJpbmdpZnkodGVzdFJlc3VsdHMsIG51bGwsIDIpfVxuXG5UZXN0IHBhdHRlcm5zOiAke2ZpbGVQYXR0ZXJucy5qb2luKCcsICcpfVxuXG5QbGVhc2UgcHJvdmlkZTpcbjEuIEFuYWx5c2lzIG9mIGN1cnJlbnQgY292ZXJhZ2UgZ2Fwc1xuMi4gU3VnZ2VzdGlvbnMgZm9yIGltcHJvdmluZyB0ZXN0IGNhc2VzXG4zLiBSZWNvbW1lbmRhdGlvbnMgZm9yIGFkZGl0aW9uYWwgaW50ZWdyYXRpb24gdGVzdCBzY2VuYXJpb3NcbjQuIEJlc3QgcHJhY3RpY2VzIGZvciBpbmNyZWFzaW5nIHRlc3QgZWZmZWN0aXZlbmVzc2AsXG4gICAgICAgICAgcXVpZXQsXG4gICAgICAgICAgdGFzazogJ29wdGltaXplJ1xuICAgICAgICB9KTtcblxuICAgICAgICBzcGlubmVyLnN1Y2NlZWQoJ0FJIHRlc3QgYW5hbHlzaXMgY29tcGxldGUnKTtcbiAgICAgIH0gY2F0Y2goYWlFcnJvcikge1xuICAgICAgICBzcGlubmVyLmZhaWwoJ0NvdWxkIG5vdCBnZW5lcmF0ZSBBSSB0ZXN0IGFuYWx5c2lzJyk7XG4gICAgICAgIGlmKCFxdWlldCkge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgICAgY29uc29sZS5lcnJvcignQUkgYW5hbHlzaXMgZXJyb3I6JywgYWlFcnJvcik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBjYWxsYmFjaygwKTtcbiAgICByZXR1cm4gMDtcbiAgfSBjYXRjaChlcnJvcikge1xuICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBFcnJvcjogQ2hlY2sgZm9yIHVuaXQgdGVzdCBlcnJvcnMgYW5kL29yIGNvdmVyYWdlLmAsICdlcnJvcicsIHF1aWV0KTtcblxuICAgIHNwaW5uZXIuZmFpbCgnVGVzdGluZyBmYWlsZWQhJyk7XG5cbiAgICBpZih1c2VEZWJ1Zykge1xuICAgICAgc3Bpbm5lci5zdGFydCgnQUkgaXMgYW5hbHl6aW5nIHRlc3QgZmFpbHVyZXMuLi4nKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgdGVzdFJlc3VsdHMgPSBwcm9jZXNzVGVzdFJlc3VsdHModGVtcE91dHB1dEZpbGUpO1xuXG4gICAgICAgIGF3YWl0IGFpRnVuY3Rpb24oe1xuICAgICAgICAgIGNvbnRleHQ6IHRydWUsXG4gICAgICAgICAgcHJvbXB0OiBgRGVidWcgdGhlc2UgZmFpbGVkIEplc3QgdGVzdHMgYW5kIHN1Z2dlc3QgZml4ZXM6XG5cbiR7SlNPTi5zdHJpbmdpZnkoZXJyb3IubWVzc2FnZSwgbnVsbCwgMil9XG5cblRlc3QgcmVzdWx0czogJHtKU09OLnN0cmluZ2lmeSh0ZXN0UmVzdWx0cywgbnVsbCwgMil9XG5cblBsZWFzZSBwcm92aWRlOlxuMS4gQW5hbHlzaXMgb2Ygd2h5IHRoZSB0ZXN0cyBhcmUgZmFpbGluZ1xuMi4gU3BlY2lmaWMgc3VnZ2VzdGlvbnMgdG8gZml4IGVhY2ggZmFpbGluZyB0ZXN0XG4zLiBBbnkgcG90ZW50aWFsIGlzc3VlcyB3aXRoIHRlc3QgZml4dHVyZXMgb3IgbW9ja3NcbjQuIENvZGUgZXhhbXBsZXMgZm9yIHNvbHV0aW9uc2AsXG4gICAgICAgICAgcXVpZXQsXG4gICAgICAgICAgdGFzazogJ2hlbHAnXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNwaW5uZXIuc3VjY2VlZCgnQUkgZGVidWdnaW5nIGFzc2lzdGFuY2UgY29tcGxldGUnKTtcbiAgICAgIH0gY2F0Y2goYWlFcnJvcikge1xuICAgICAgICBzcGlubmVyLmZhaWwoJ0NvdWxkIG5vdCBnZW5lcmF0ZSBBSSBkZWJ1Z2dpbmcgYXNzaXN0YW5jZScpO1xuICAgICAgICBpZighcXVpZXQpIHtcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0FJIGRlYnVnZ2luZyBlcnJvcjonLCBhaUVycm9yKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGNhbGxiYWNrKDEpO1xuICAgIHJldHVybiAxO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCB0ZXN0OyJdLCJuYW1lcyI6WyJleGVjYSIsImV4aXN0c1N5bmMiLCJyZWFkRmlsZVN5bmMiLCJzeW5jIiwiZ2xvYlN5bmMiLCJyZXNvbHZlIiwicGF0aFJlc29sdmUiLCJMZXhDb25maWciLCJnZXRUeXBlU2NyaXB0Q29uZmlnUGF0aCIsImNyZWF0ZVNwaW5uZXIiLCJyZXNvbHZlQmluYXJ5UGF0aCIsImxvZyIsImFpRnVuY3Rpb24iLCJkZXRlY3RFU00iLCJjd2QiLCJwYWNrYWdlSnNvblBhdGgiLCJwYWNrYWdlSnNvbkNvbnRlbnQiLCJwYWNrYWdlSnNvbiIsIkpTT04iLCJwYXJzZSIsInR5cGUiLCJfZXJyb3IiLCJkZWZhdWx0RXhpdCIsImNvZGUiLCJwcm9jZXNzIiwiZW52IiwiSkVTVF9XT1JLRVJfSUQiLCJOT0RFX0VOViIsInVuZGVmaW5lZCIsImV4aXQiLCJnZXRUZXN0RmlsZVBhdHRlcm5zIiwidGVzdFBhdGhQYXR0ZXJuIiwiZGVmYXVsdFBhdHRlcm5zIiwiZmluZFVuY292ZXJlZFNvdXJjZUZpbGVzIiwic291cmNlRmlsZXMiLCJpZ25vcmUiLCJ0ZXN0RmlsZXMiLCJmaWx0ZXIiLCJzb3VyY2VGaWxlIiwiYmFzZU5hbWUiLCJyZXBsYWNlIiwic29tZSIsInRlc3RGaWxlIiwiaW5jbHVkZXMiLCJwcm9jZXNzVGVzdFJlc3VsdHMiLCJvdXRwdXRGaWxlIiwiY29udGVudCIsInRlc3QiLCJvcHRpb25zIiwiYXJncyIsImZpbGVzT3JDYWxsYmFjayIsImNhbGxiYWNrUGFyYW0iLCJmaWxlcyIsImNhbGxiYWNrIiwiYW5hbHl6ZSIsImFpQW5hbHl6ZSIsImFpRGVidWciLCJhaUdlbmVyYXRlIiwiYmFpbCIsImNoYW5nZWRGaWxlc1dpdGhBbmNlc3RvciIsImNoYW5nZWRTaW5jZSIsImNpIiwiY2xpTmFtZSIsImNvbGxlY3RDb3ZlcmFnZUZyb20iLCJjb2xvcnMiLCJjb25maWciLCJkZWJ1ZyIsImRlYnVnVGVzdHMiLCJkZXRlY3RPcGVuSGFuZGxlcyIsImVycm9yT25EZXByZWNhdGVkIiwiZXhwYW5kIiwiZm9yY2VFeGl0IiwiZ2VuZXJhdGUiLCJqc29uIiwibGFzdENvbW1pdCIsImxpc3RUZXN0cyIsImxvZ0hlYXBVc2FnZSIsIm1heFdvcmtlcnMiLCJub1N0YWNrVHJhY2UiLCJub3RpZnkiLCJvbmx5Q2hhbmdlZCIsInBhc3NXaXRoTm9UZXN0cyIsInF1aWV0IiwicmVtb3ZlQ2FjaGUiLCJydW5JbkJhbmQiLCJzZXR1cCIsInNob3dDb25maWciLCJzaWxlbnQiLCJ0ZXN0TG9jYXRpb25JblJlc3VsdHMiLCJ0ZXN0TmFtZVBhdHRlcm4iLCJ1cGRhdGUiLCJ1c2VTdGRlcnIiLCJ2ZXJib3NlIiwid2F0Y2giLCJ3YXRjaEFsbCIsInVzZUdlbmVyYXRlIiwidXNlQW5hbHl6ZSIsInVzZURlYnVnIiwic3Bpbm5lciIsInBhcnNlQ29uZmlnIiwidXNlVHlwZXNjcmlwdCIsInRlc3RDb25maWdQYXRoIiwiY2hlY2tUZXN0VHlwZXNjcmlwdENvbmZpZyIsInN0YXJ0IiwidW5jb3ZlcmVkRmlsZXMiLCJsZW5ndGgiLCJ0YXJnZXRGaWxlIiwiY29udGV4dCIsImZpbGUiLCJwcm9tcHQiLCJ0YXNrIiwic3VjY2VlZCIsImFpRXJyb3IiLCJmYWlsIiwiY29uc29sZSIsImVycm9yIiwicHJvamVjdEplc3RCaW4iLCJqZXN0UGF0aCIsImplc3RDb25maWdGaWxlIiwicHJvamVjdEplc3RDb25maWciLCJwcm9qZWN0SmVzdENvbmZpZ1BhdGgiLCJwcm9qZWN0SmVzdENvbmZpZ0Nqc1BhdGgiLCJwcm9qZWN0SmVzdENvbmZpZ01qc1BhdGgiLCJwcm9qZWN0SmVzdENvbmZpZ0pzb25QYXRoIiwiamVzdCIsImxleERpciIsImdldExleERpciIsImxleEplc3RDb25maWciLCJPYmplY3QiLCJrZXlzIiwiamVzdFNldHVwRmlsZSIsImplc3RPcHRpb25zIiwiaXNFU00iLCJub2RlT3B0aW9ucyIsIk5PREVfT1BUSU9OUyIsInRyaW0iLCJwdXNoIiwidGVtcE91dHB1dEZpbGUiLCJqb2luIiwiZW5jb2RpbmciLCJzdGRpbyIsInRlc3RSZXN1bHRzIiwiZmlsZVBhdHRlcm5zIiwic3RyaW5naWZ5IiwibWVzc2FnZSJdLCJtYXBwaW5ncyI6IkFBQUE7OztDQUdDLEdBQ0QsU0FBUUEsS0FBSyxRQUFPLFFBQVE7QUFDNUIsU0FBUUMsVUFBVSxFQUFFQyxZQUFZLFFBQU8sS0FBSztBQUM1QyxTQUFRQyxRQUFRQyxRQUFRLFFBQU8sT0FBTztBQUN0QyxTQUFRQyxXQUFXQyxXQUFX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