@nlabs/lex 1.56.2 → 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.
- package/lib/LexConfig.js +3 -2
- package/lib/commands/build/build.js +3 -3
- package/lib/commands/compile/compile.js +5 -5
- package/lib/commands/package-lambda/package-lambda.d.ts +20 -0
- package/lib/commands/package-lambda/package-lambda.js +110 -0
- package/lib/commands/serverless/serverless.js +149 -40
- package/lib/commands/test/test.d.ts +4 -0
- package/lib/commands/test/test.js +305 -237
- package/lib/index.d.ts +1 -0
- package/lib/index.js +2 -1
- package/lib/lex.js +7 -2
- package/package.json +7 -3
- package/playwright.config.ts +24 -0
- package/tsconfig.build.json +1 -0
- package/tsconfig.lint.json +1 -0
- package/tsconfig.test.json +2 -0
- package/vitest.config.mjs +2 -2
|
@@ -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('**/*.
|
|
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
|
|
144
|
+
const processEnv = {
|
|
341
145
|
...process.env,
|
|
342
146
|
NODE_OPTIONS: nodeOptions
|
|
343
147
|
};
|
|
344
148
|
if (colors) {
|
|
345
|
-
|
|
149
|
+
processEnv.FORCE_COLOR = '1';
|
|
346
150
|
}
|
|
347
151
|
if (ci) {
|
|
348
|
-
|
|
349
|
-
}
|
|
350
|
-
if (vitestSetupFile && existsSync(vitestSetupFile)) {
|
|
351
|
-
env.LEX_VITEST_SETUP = vitestSetupFile;
|
|
152
|
+
processEnv.CI = 'true';
|
|
352
153
|
}
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
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
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
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
|
-
|
|
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(
|
|
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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
|