@workflow/next 5.0.0-beta.1 → 5.0.0-beta.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/builder-deferred.d.ts.map +1 -1
- package/dist/builder-deferred.js +292 -498
- package/dist/builder-eager.d.ts.map +1 -1
- package/dist/builder-eager.js +60 -76
- package/dist/builder.d.ts +1 -1
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +4 -4
- package/dist/environment-flag.d.ts +2 -0
- package/dist/environment-flag.d.ts.map +1 -0
- package/dist/environment-flag.js +15 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +285 -11
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +52 -60
- package/dist/runtime.js +1 -1
- package/dist/socket-server.d.ts +20 -0
- package/dist/socket-server.d.ts.map +1 -1
- package/dist/socket-server.js +29 -2
- package/docs/api-reference/with-workflow.mdx +34 -2
- package/docs/next.mdx +5 -3
- package/package.json +4 -5
- package/dist/builder-deferred.js.map +0 -1
- package/dist/builder-eager.js.map +0 -1
- package/dist/builder.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/loader.js.map +0 -1
- package/dist/runtime.js.map +0 -1
- package/dist/socket-server.js.map +0 -1
- package/dist/step-copy-utils.d.ts +0 -19
- package/dist/step-copy-utils.d.ts.map +0 -1
- package/dist/step-copy-utils.js +0 -101
- package/dist/step-copy-utils.js.map +0 -1
package/dist/builder-deferred.js
CHANGED
|
@@ -7,11 +7,10 @@ exports.getNextBuilderDeferred = getNextBuilderDeferred;
|
|
|
7
7
|
const node_crypto_1 = require("node:crypto");
|
|
8
8
|
const node_fs_1 = require("node:fs");
|
|
9
9
|
const promises_1 = require("node:fs/promises");
|
|
10
|
+
const node_module_1 = require("node:module");
|
|
10
11
|
const node_os_1 = __importDefault(require("node:os"));
|
|
11
12
|
const node_path_1 = require("node:path");
|
|
12
|
-
const enhanced_resolve_1 = __importDefault(require("enhanced-resolve"));
|
|
13
13
|
const socket_server_js_1 = require("./socket-server.js");
|
|
14
|
-
const step_copy_utils_js_1 = require("./step-copy-utils.js");
|
|
15
14
|
const ROUTE_STUB_FILE_MARKER = 'WORKFLOW_ROUTE_STUB_FILE';
|
|
16
15
|
const ROUTE_STUB_MARKER_SCAN_BYTES = 4 * 1024;
|
|
17
16
|
let CachedNextBuilderDeferred;
|
|
@@ -22,46 +21,15 @@ async function getNextBuilderDeferred() {
|
|
|
22
21
|
if (CachedNextBuilderDeferred) {
|
|
23
22
|
return CachedNextBuilderDeferred;
|
|
24
23
|
}
|
|
25
|
-
|
|
24
|
+
// V2: STEP_QUEUE_TRIGGER, getImportPath, and enhanced-resolve infrastructure
|
|
25
|
+
// were removed because the V2 combined handler eliminates the separate step
|
|
26
|
+
// route/topic. The step copy import rewriting (getRelativeImportSpecifier,
|
|
27
|
+
// getStepCopyFileName, rewriteRelativeImportsForCopiedStep) from main was also
|
|
28
|
+
// removed — V2 doesn't use step copies. If step copy support is needed, it
|
|
29
|
+
// should land as a complete feature set.
|
|
30
|
+
const { BaseBuilder: BaseBuilderClass, WORKFLOW_QUEUE_TRIGGER, detectWorkflowPatterns, applySwcTransform, resolveWorkflowAliasRelativePath,
|
|
26
31
|
// biome-ignore lint/security/noGlobalEval: Need to use eval here to avoid TypeScript from transpiling the import statement into `require()`
|
|
27
32
|
} = (await eval('import("@workflow/builders")'));
|
|
28
|
-
// Shared resolve options matching the configuration used by the SWC
|
|
29
|
-
// esbuild plugin (swc-esbuild-plugin.ts) for consistent resolution
|
|
30
|
-
// semantics across the toolchain.
|
|
31
|
-
const NODE_RESOLVE_OPTIONS = {
|
|
32
|
-
dependencyType: 'commonjs',
|
|
33
|
-
modules: ['node_modules'],
|
|
34
|
-
exportsFields: ['exports'],
|
|
35
|
-
importsFields: ['imports'],
|
|
36
|
-
conditionNames: ['node', 'require'],
|
|
37
|
-
descriptionFiles: ['package.json'],
|
|
38
|
-
extensions: [
|
|
39
|
-
'.ts',
|
|
40
|
-
'.tsx',
|
|
41
|
-
'.mts',
|
|
42
|
-
'.cts',
|
|
43
|
-
'.cjs',
|
|
44
|
-
'.mjs',
|
|
45
|
-
'.js',
|
|
46
|
-
'.jsx',
|
|
47
|
-
'.json',
|
|
48
|
-
'.node',
|
|
49
|
-
],
|
|
50
|
-
enforceExtensions: false,
|
|
51
|
-
symlinks: true,
|
|
52
|
-
mainFields: ['main'],
|
|
53
|
-
mainFiles: ['index'],
|
|
54
|
-
roots: [],
|
|
55
|
-
fullySpecified: false,
|
|
56
|
-
preferRelative: false,
|
|
57
|
-
preferAbsolute: false,
|
|
58
|
-
restrictions: [],
|
|
59
|
-
};
|
|
60
|
-
const NODE_ESM_RESOLVE_OPTIONS = {
|
|
61
|
-
...NODE_RESOLVE_OPTIONS,
|
|
62
|
-
dependencyType: 'esm',
|
|
63
|
-
conditionNames: ['node', 'import'],
|
|
64
|
-
};
|
|
65
33
|
class NextDeferredBuilder extends BaseBuilderClass {
|
|
66
34
|
socketIO;
|
|
67
35
|
discoveredWorkflowFiles = new Set();
|
|
@@ -73,11 +41,6 @@ async function getNextBuilderDeferred() {
|
|
|
73
41
|
cacheWriteTimer = null;
|
|
74
42
|
deferredRebuildTimer = null;
|
|
75
43
|
lastDeferredBuildSignature = null;
|
|
76
|
-
// Lazily initialized resolvers for bare specifier rewriting.
|
|
77
|
-
// Cached to avoid re-creating on every import rewrite.
|
|
78
|
-
esmSyncResolver;
|
|
79
|
-
cjsSyncResolver;
|
|
80
|
-
manifestStepResolveBaseDirs = null;
|
|
81
44
|
async build() {
|
|
82
45
|
const outputDir = await this.findAppDirectory();
|
|
83
46
|
await this.initializeDiscoveryState();
|
|
@@ -141,6 +104,14 @@ async function getNextBuilderDeferred() {
|
|
|
141
104
|
}
|
|
142
105
|
}
|
|
143
106
|
this.lastDeferredBuildSignature = buildSignature;
|
|
107
|
+
if (!this.config.watch) {
|
|
108
|
+
// Production builds can persist newly discovered deferred-entry files to
|
|
109
|
+
// the cache after the first pass completes. Reload that cache before we
|
|
110
|
+
// decide whether the input signature stabilized so staged tarball builds
|
|
111
|
+
// can immediately replay with the expanded step set.
|
|
112
|
+
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
113
|
+
await this.loadWorkflowsCache();
|
|
114
|
+
}
|
|
144
115
|
const postBuildInputFiles = this.getCurrentInputFiles(implicitStepFiles);
|
|
145
116
|
const postBuildSignature = await this.createDeferredBuildSignature(postBuildInputFiles);
|
|
146
117
|
if (postBuildSignature === buildSignature) {
|
|
@@ -157,15 +128,11 @@ async function getNextBuilderDeferred() {
|
|
|
157
128
|
const outputDir = await this.findAppDirectory();
|
|
158
129
|
const generatedRouteFiles = [
|
|
159
130
|
(0, node_path_1.join)(outputDir, '.well-known/workflow/v1/flow/route.js'),
|
|
160
|
-
(0, node_path_1.join)(outputDir, '.well-known/workflow/v1/step/route.js'),
|
|
161
131
|
(0, node_path_1.join)(outputDir, '.well-known/workflow/v1/webhook/[token]/route.js'),
|
|
162
132
|
];
|
|
163
133
|
for (const routeFilePath of generatedRouteFiles) {
|
|
164
134
|
const routeState = await this.getGeneratedRouteState(routeFilePath);
|
|
165
|
-
if (routeState === 'missing') {
|
|
166
|
-
return true;
|
|
167
|
-
}
|
|
168
|
-
if (routeState === 'stub') {
|
|
135
|
+
if (routeState === 'missing' || routeState === 'stub') {
|
|
169
136
|
return true;
|
|
170
137
|
}
|
|
171
138
|
}
|
|
@@ -383,18 +350,17 @@ async function getNextBuilderDeferred() {
|
|
|
383
350
|
...this.discoveredSerdeFiles,
|
|
384
351
|
...trackedDiscoveredEntries.discoveredSerdeFiles,
|
|
385
352
|
])).sort();
|
|
386
|
-
const discoveredStepFiles = await this.filterExistingFiles(discoveredStepFileCandidates);
|
|
387
353
|
const discoveredWorkflowFiles = await this.filterExistingFiles(discoveredWorkflowFileCandidates);
|
|
354
|
+
const existingStepFileCandidates = await this.filterExistingFiles(discoveredStepFileCandidates);
|
|
355
|
+
const discoveredStepFiles = await this.collectTransitiveStepFiles({
|
|
356
|
+
entryFiles: [...existingStepFileCandidates, ...discoveredWorkflowFiles],
|
|
357
|
+
stepFiles: existingStepFileCandidates,
|
|
358
|
+
});
|
|
388
359
|
const existingSerdeFileCandidates = await this.filterExistingFiles(discoveredSerdeFileCandidates);
|
|
389
360
|
const discoveredSerdeFiles = await this.collectTransitiveSerdeFiles({
|
|
390
361
|
entryFiles: [...discoveredStepFiles, ...discoveredWorkflowFiles],
|
|
391
362
|
serdeFiles: existingSerdeFileCandidates,
|
|
392
363
|
});
|
|
393
|
-
const discoveredEntries = {
|
|
394
|
-
discoveredSteps: new Set(discoveredStepFiles),
|
|
395
|
-
discoveredWorkflows: new Set(discoveredWorkflowFiles),
|
|
396
|
-
discoveredSerdeFiles: new Set(discoveredSerdeFiles),
|
|
397
|
-
};
|
|
398
364
|
const existingInputFiles = await this.filterExistingFiles(inputFiles);
|
|
399
365
|
const buildInputFiles = Array.from(new Set([
|
|
400
366
|
...existingInputFiles,
|
|
@@ -402,38 +368,42 @@ async function getNextBuilderDeferred() {
|
|
|
402
368
|
...discoveredWorkflowFiles,
|
|
403
369
|
...discoveredSerdeFiles,
|
|
404
370
|
])).sort();
|
|
371
|
+
const discoveredEntries = {
|
|
372
|
+
discoveredSteps: new Set(discoveredStepFiles),
|
|
373
|
+
discoveredWorkflows: new Set(discoveredWorkflowFiles),
|
|
374
|
+
discoveredSerdeFiles: new Set(discoveredSerdeFiles),
|
|
375
|
+
};
|
|
405
376
|
// Ensure output directories exist
|
|
406
377
|
await (0, promises_1.mkdir)(workflowGeneratedDir, { recursive: true });
|
|
407
378
|
await this.writeFileIfChanged((0, node_path_1.join)(workflowGeneratedDir, '.gitignore'), '*');
|
|
408
379
|
const tsconfigPath = await this.findTsConfigPath();
|
|
409
|
-
|
|
380
|
+
// V2: Build combined route (replaces separate step + flow routes)
|
|
381
|
+
const flowRouteDir = (0, node_path_1.join)(workflowGeneratedDir, 'flow');
|
|
382
|
+
await (0, promises_1.mkdir)(flowRouteDir, { recursive: true });
|
|
383
|
+
// Write step registrations to final name directly (not temp) so the
|
|
384
|
+
// import path in the flow route is correct. The flow route uses temp
|
|
385
|
+
// naming to avoid HMR churn via copyFileIfChanged, but the step
|
|
386
|
+
// registrations file is a side-effect import and doesn't need that.
|
|
387
|
+
const stepsOutfile = (0, node_path_1.join)(flowRouteDir, '__step_registrations.js');
|
|
388
|
+
const combinedResult = await this.createCombinedBundle({
|
|
389
|
+
format: 'esm',
|
|
410
390
|
inputFiles: buildInputFiles,
|
|
411
|
-
|
|
391
|
+
stepsOutfile,
|
|
392
|
+
flowOutfile: (0, node_path_1.join)(flowRouteDir, tempRouteFileName),
|
|
393
|
+
bundleFinalOutput: false,
|
|
394
|
+
externalizeNonSteps: true,
|
|
412
395
|
tsconfigPath,
|
|
413
|
-
routeFileName: tempRouteFileName,
|
|
414
396
|
discoveredEntries,
|
|
415
|
-
};
|
|
416
|
-
const workflowsBundle = await this.buildWorkflowsFunction(options);
|
|
417
|
-
const { manifest: stepsManifest } = await this.buildStepsFunction({
|
|
418
|
-
...options,
|
|
419
|
-
additionalStepSourceManifest: workflowsBundle?.manifest,
|
|
420
397
|
});
|
|
421
398
|
await this.buildWebhookRoute({
|
|
422
399
|
workflowGeneratedDir,
|
|
423
400
|
routeFileName: tempRouteFileName,
|
|
424
401
|
});
|
|
425
402
|
await this.refreshTrackedDependencyFiles(workflowGeneratedDir, tempRouteFileName);
|
|
426
|
-
// Merge manifests from both bundles
|
|
427
403
|
const manifest = {
|
|
428
|
-
steps: { ...
|
|
429
|
-
workflows: {
|
|
430
|
-
|
|
431
|
-
...workflowsBundle?.manifest?.workflows,
|
|
432
|
-
},
|
|
433
|
-
classes: {
|
|
434
|
-
...stepsManifest.classes,
|
|
435
|
-
...workflowsBundle?.manifest?.classes,
|
|
436
|
-
},
|
|
404
|
+
steps: { ...combinedResult?.manifest?.steps },
|
|
405
|
+
workflows: { ...combinedResult?.manifest?.workflows },
|
|
406
|
+
classes: { ...combinedResult?.manifest?.classes },
|
|
437
407
|
};
|
|
438
408
|
const manifestFilePath = (0, node_path_1.join)(workflowGeneratedDir, 'manifest.json');
|
|
439
409
|
const manifestBuildPath = (0, node_path_1.join)(manifestBuildDir, 'manifest.json');
|
|
@@ -452,14 +422,17 @@ async function getNextBuilderDeferred() {
|
|
|
452
422
|
await (0, promises_1.rm)(manifestFilePath, { force: true });
|
|
453
423
|
}
|
|
454
424
|
await this.writeFunctionsConfig(outputDir);
|
|
425
|
+
// V2: Combined route (flow) — step registrations already at final path
|
|
455
426
|
await this.copyFileIfChanged((0, node_path_1.join)(workflowGeneratedDir, `flow/${tempRouteFileName}`), (0, node_path_1.join)(workflowGeneratedDir, 'flow/route.js'));
|
|
456
|
-
await this.copyFileIfChanged((0, node_path_1.join)(workflowGeneratedDir, `step/${tempRouteFileName}`), (0, node_path_1.join)(workflowGeneratedDir, 'step/route.js'));
|
|
457
427
|
await this.copyFileIfChanged((0, node_path_1.join)(workflowGeneratedDir, `webhook/[token]/${tempRouteFileName}`), (0, node_path_1.join)(workflowGeneratedDir, 'webhook/[token]/route.js'));
|
|
458
428
|
// Expose manifest as a static file when WORKFLOW_PUBLIC_MANIFEST=1.
|
|
459
429
|
// Next.js serves files from public/ at the root URL.
|
|
460
430
|
if (this.shouldExposePublicManifest && manifestJson) {
|
|
461
431
|
const publicManifestDir = (0, node_path_1.join)(this.config.workingDir, 'public/.well-known/workflow/v1');
|
|
462
432
|
await (0, promises_1.mkdir)(publicManifestDir, { recursive: true });
|
|
433
|
+
if (process.env.VERCEL_DEPLOYMENT_ID === undefined) {
|
|
434
|
+
await this.writeFileIfChanged((0, node_path_1.join)(publicManifestDir, '.gitignore'), '*');
|
|
435
|
+
}
|
|
463
436
|
await this.copyFileIfChanged(manifestFilePath, (0, node_path_1.join)(publicManifestDir, 'manifest.json'));
|
|
464
437
|
}
|
|
465
438
|
// Notify deferred entry loaders waiting on route.js stubs.
|
|
@@ -474,17 +447,17 @@ async function getNextBuilderDeferred() {
|
|
|
474
447
|
(0, node_path_1.join)(flowRouteDir, 'route.js.temp'),
|
|
475
448
|
(0, node_path_1.join)(flowRouteDir, 'route.js.temp.debug.json'),
|
|
476
449
|
(0, node_path_1.join)(flowRouteDir, 'route.js.debug.json'),
|
|
477
|
-
(0, node_path_1.join)(
|
|
478
|
-
(0, node_path_1.join)(
|
|
479
|
-
|
|
480
|
-
|
|
450
|
+
(0, node_path_1.join)(flowRouteDir, '__step_registrations.route.js.temp'),
|
|
451
|
+
(0, node_path_1.join)(flowRouteDir, '__step_registrations.route.js.temp.debug.json'),
|
|
452
|
+
// V2: clean up stale V1 step route directory
|
|
453
|
+
stepRouteDir,
|
|
481
454
|
(0, node_path_1.join)(webhookRouteDir, 'route.js.temp'),
|
|
482
455
|
(0, node_path_1.join)(workflowGeneratedDir, 'manifest.json'),
|
|
483
456
|
];
|
|
484
|
-
await Promise.all(staleArtifactPaths.map((stalePath) => (0, promises_1.rm)(stalePath, { recursive: true, force: true })));
|
|
485
457
|
await Promise.all([
|
|
458
|
+
...staleArtifactPaths.map((stalePath) => (0, promises_1.rm)(stalePath, { recursive: true, force: true })),
|
|
459
|
+
(0, socket_server_js_1.cleanupStaleSocketInfoFiles)((0, node_path_1.join)(this.config.workingDir, this.getDistDir())),
|
|
486
460
|
this.removeStaleDeferredTempFiles(flowRouteDir),
|
|
487
|
-
this.removeStaleDeferredTempFiles(stepRouteDir),
|
|
488
461
|
this.removeStaleDeferredTempFiles(webhookRouteDir),
|
|
489
462
|
]);
|
|
490
463
|
}
|
|
@@ -545,7 +518,11 @@ async function getNextBuilderDeferred() {
|
|
|
545
518
|
if (hasCacheTrackingChange) {
|
|
546
519
|
this.scheduleWorkflowsCacheWrite();
|
|
547
520
|
}
|
|
548
|
-
if (
|
|
521
|
+
if (hasWorkflow ||
|
|
522
|
+
hasStep ||
|
|
523
|
+
hasSerde ||
|
|
524
|
+
hasCacheTrackingChange ||
|
|
525
|
+
wasTrackedDependency) {
|
|
549
526
|
this.scheduleDeferredRebuild();
|
|
550
527
|
}
|
|
551
528
|
},
|
|
@@ -571,41 +548,68 @@ async function getNextBuilderDeferred() {
|
|
|
571
548
|
return (0, node_path_1.join)(this.config.workingDir, this.getDistDir(), 'cache', 'workflows.json');
|
|
572
549
|
}
|
|
573
550
|
getSocketInfoFilePath() {
|
|
574
|
-
return (0, node_path_1.join)(this.config.workingDir, this.getDistDir(),
|
|
551
|
+
return (0, node_path_1.join)(this.config.workingDir, this.getDistDir(), socket_server_js_1.SOCKET_INFO_FILENAME);
|
|
575
552
|
}
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
553
|
+
findPackageJsonPath(filePath) {
|
|
554
|
+
let currentDir = (0, node_path_1.dirname)(filePath);
|
|
555
|
+
let previousDir = '';
|
|
556
|
+
while (currentDir !== previousDir) {
|
|
557
|
+
const packageJsonPath = (0, node_path_1.join)(currentDir, 'package.json');
|
|
558
|
+
if ((0, node_fs_1.existsSync)(packageJsonPath)) {
|
|
559
|
+
return packageJsonPath;
|
|
560
|
+
}
|
|
561
|
+
previousDir = currentDir;
|
|
562
|
+
currentDir = (0, node_path_1.dirname)(currentDir);
|
|
563
|
+
}
|
|
564
|
+
return null;
|
|
565
|
+
}
|
|
566
|
+
shouldPreferSourceBackedPackagePath(filePath) {
|
|
567
|
+
const normalizedPath = filePath.replace(/\\/g, '/');
|
|
568
|
+
// Only prefer source for workspace packages (not in node_modules).
|
|
569
|
+
// For tarball-installed packages, using source-backed paths causes
|
|
570
|
+
// esbuild to bundle the full source tree (including world.ts with
|
|
571
|
+
// process.cwd()) instead of externalizing properly.
|
|
572
|
+
if (normalizedPath.includes('/packages/') &&
|
|
573
|
+
!normalizedPath.includes('/node_modules/')) {
|
|
574
|
+
return true;
|
|
575
|
+
}
|
|
576
|
+
if (!normalizedPath.includes('/node_modules/')) {
|
|
577
|
+
return false;
|
|
578
|
+
}
|
|
579
|
+
const packageJsonPath = this.findPackageJsonPath(filePath);
|
|
580
|
+
if (!packageJsonPath) {
|
|
581
|
+
return false;
|
|
582
|
+
}
|
|
580
583
|
try {
|
|
581
|
-
|
|
584
|
+
const packageJson = JSON.parse((0, node_fs_1.readFileSync)(packageJsonPath, 'utf-8'));
|
|
585
|
+
return (packageJson.name === 'workflow' ||
|
|
586
|
+
(typeof packageJson.name === 'string' &&
|
|
587
|
+
packageJson.name.startsWith('@workflow/')));
|
|
582
588
|
}
|
|
583
589
|
catch {
|
|
584
|
-
return
|
|
590
|
+
return false;
|
|
585
591
|
}
|
|
586
592
|
}
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
const
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
this.manifestStepResolveBaseDirs = Array.from(resolveBaseDirs);
|
|
608
|
-
return this.manifestStepResolveBaseDirs;
|
|
593
|
+
resolveSourceBackedPackagePath(filePath) {
|
|
594
|
+
const normalizedPath = filePath.replace(/\\/g, '/');
|
|
595
|
+
if (!normalizedPath.includes('/dist/')) {
|
|
596
|
+
return filePath;
|
|
597
|
+
}
|
|
598
|
+
const sourceCandidate = normalizedPath.replace('/dist/', '/src/');
|
|
599
|
+
const resolvedSourceCandidate = this.resolveCopiedStepImportTargetPath(sourceCandidate);
|
|
600
|
+
if (!(0, node_fs_1.existsSync)(resolvedSourceCandidate) ||
|
|
601
|
+
!this.shouldPreferSourceBackedPackagePath(filePath)) {
|
|
602
|
+
return filePath;
|
|
603
|
+
}
|
|
604
|
+
return (0, node_fs_1.existsSync)(resolvedSourceCandidate)
|
|
605
|
+
? resolvedSourceCandidate
|
|
606
|
+
: filePath;
|
|
607
|
+
}
|
|
608
|
+
normalizeDiscoveredFilePath(filePath) {
|
|
609
|
+
const absolutePath = (0, node_path_1.isAbsolute)(filePath)
|
|
610
|
+
? filePath
|
|
611
|
+
: (0, node_path_1.resolve)(this.config.workingDir, filePath);
|
|
612
|
+
return this.resolveSourceBackedPackagePath(absolutePath);
|
|
609
613
|
}
|
|
610
614
|
async filterExistingFiles(filePaths) {
|
|
611
615
|
const normalizedFilePaths = Array.from(new Set(filePaths.map((filePath) => this.normalizeDiscoveredFilePath(filePath)))).sort();
|
|
@@ -687,9 +691,62 @@ async function getNextBuilderDeferred() {
|
|
|
687
691
|
}
|
|
688
692
|
const baseDirectory = (0, node_path_1.dirname)(bundleFilePath);
|
|
689
693
|
const localSourceFiles = new Set();
|
|
690
|
-
|
|
694
|
+
// Extract inline base64 sourcemaps via string scanning. A previous
|
|
695
|
+
// implementation used `bundleContents.matchAll(/...[A-Za-z0-9+/=]+.../g)`
|
|
696
|
+
// which overflows V8's regex stack
|
|
697
|
+
// (`RangeError: Maximum call stack size exceeded at RegExpStringIterator.next`)
|
|
698
|
+
// on bundles with large inline sourcemaps — V8's irregexp uses
|
|
699
|
+
// recursion for greedy character-class quantifiers and certain long
|
|
700
|
+
// base64 inputs exhaust the call stack.
|
|
701
|
+
const sourceMapPrefix = '//# sourceMappingURL=data:application/json';
|
|
702
|
+
const base64Marker = ';base64,';
|
|
703
|
+
const sourceMapMatches = [];
|
|
704
|
+
let scanFrom = 0;
|
|
705
|
+
while (scanFrom < bundleContents.length) {
|
|
706
|
+
const prefixIdx = bundleContents.indexOf(sourceMapPrefix, scanFrom);
|
|
707
|
+
if (prefixIdx === -1)
|
|
708
|
+
break;
|
|
709
|
+
const base64Start = bundleContents.indexOf(base64Marker, prefixIdx + sourceMapPrefix.length);
|
|
710
|
+
if (base64Start === -1) {
|
|
711
|
+
scanFrom = prefixIdx + sourceMapPrefix.length;
|
|
712
|
+
continue;
|
|
713
|
+
}
|
|
714
|
+
// Bail if a comma appears before `;base64,` — that means this
|
|
715
|
+
// wasn't a `data:application/json[;params];base64,...` URL after
|
|
716
|
+
// all (the comma would terminate the data URL parameters).
|
|
717
|
+
const commaBefore = bundleContents.indexOf(',', prefixIdx);
|
|
718
|
+
if (commaBefore !== -1 && commaBefore < base64Start) {
|
|
719
|
+
scanFrom = base64Start;
|
|
720
|
+
continue;
|
|
721
|
+
}
|
|
722
|
+
const valueStart = base64Start + base64Marker.length;
|
|
723
|
+
// Base64 payload terminates at first non-base64 char (newline,
|
|
724
|
+
// closing `*/`, etc.). Scanning a small alphabet by char is far
|
|
725
|
+
// cheaper than backtracking a regex over a multi-MB capture.
|
|
726
|
+
let valueEnd = valueStart;
|
|
727
|
+
while (valueEnd < bundleContents.length) {
|
|
728
|
+
const code = bundleContents.charCodeAt(valueEnd);
|
|
729
|
+
// A-Z 0x41-0x5A, a-z 0x61-0x7A, 0-9 0x30-0x39, '+' 0x2B,
|
|
730
|
+
// '/' 0x2F, '=' 0x3D
|
|
731
|
+
if (!((code >= 0x41 && code <= 0x5a) ||
|
|
732
|
+
(code >= 0x61 && code <= 0x7a) ||
|
|
733
|
+
(code >= 0x30 && code <= 0x39) ||
|
|
734
|
+
code === 0x2b ||
|
|
735
|
+
code === 0x2f ||
|
|
736
|
+
code === 0x3d)) {
|
|
737
|
+
break;
|
|
738
|
+
}
|
|
739
|
+
valueEnd++;
|
|
740
|
+
}
|
|
741
|
+
if (valueEnd > valueStart) {
|
|
742
|
+
sourceMapMatches.push({
|
|
743
|
+
base64Value: bundleContents.slice(valueStart, valueEnd),
|
|
744
|
+
});
|
|
745
|
+
}
|
|
746
|
+
scanFrom = valueEnd;
|
|
747
|
+
}
|
|
691
748
|
for (const match of sourceMapMatches) {
|
|
692
|
-
const base64Value = match
|
|
749
|
+
const base64Value = match.base64Value;
|
|
693
750
|
if (!base64Value) {
|
|
694
751
|
continue;
|
|
695
752
|
}
|
|
@@ -725,9 +782,12 @@ async function getNextBuilderDeferred() {
|
|
|
725
782
|
}
|
|
726
783
|
const normalizedSourcePath = this.normalizeDiscoveredFilePath(resolvedSourcePath);
|
|
727
784
|
const normalizedSourcePathForCheck = normalizedSourcePath.replace(/\\/g, '/');
|
|
785
|
+
const isSourceBackedPackagePath = this.shouldPreferSourceBackedPackagePath(normalizedSourcePath);
|
|
728
786
|
if (normalizedSourcePathForCheck.includes('/.well-known/workflow/') ||
|
|
729
|
-
|
|
730
|
-
|
|
787
|
+
(!isSourceBackedPackagePath &&
|
|
788
|
+
normalizedSourcePathForCheck.includes('/node_modules/')) ||
|
|
789
|
+
(!isSourceBackedPackagePath &&
|
|
790
|
+
normalizedSourcePathForCheck.includes('/.pnpm/')) ||
|
|
731
791
|
normalizedSourcePathForCheck.includes('/.next/') ||
|
|
732
792
|
normalizedSourcePathForCheck.endsWith('/virtual-entry.js')) {
|
|
733
793
|
continue;
|
|
@@ -749,9 +809,6 @@ async function getNextBuilderDeferred() {
|
|
|
749
809
|
}, 50);
|
|
750
810
|
}
|
|
751
811
|
scheduleDeferredRebuild() {
|
|
752
|
-
if (!this.config.watch) {
|
|
753
|
-
return;
|
|
754
|
-
}
|
|
755
812
|
if (this.deferredRebuildTimer) {
|
|
756
813
|
clearTimeout(this.deferredRebuildTimer);
|
|
757
814
|
}
|
|
@@ -826,35 +883,61 @@ async function getNextBuilderDeferred() {
|
|
|
826
883
|
].join('\n');
|
|
827
884
|
const workflowGeneratedDir = (0, node_path_1.join)(outputDir, '.well-known/workflow/v1');
|
|
828
885
|
await (0, promises_1.mkdir)((0, node_path_1.join)(workflowGeneratedDir, 'flow'), { recursive: true });
|
|
829
|
-
await (0, promises_1.mkdir)((0, node_path_1.join)(workflowGeneratedDir, 'step'), { recursive: true });
|
|
830
886
|
await (0, promises_1.mkdir)((0, node_path_1.join)(workflowGeneratedDir, 'webhook/[token]'), {
|
|
831
887
|
recursive: true,
|
|
832
888
|
});
|
|
833
889
|
await this.writeFileIfChanged((0, node_path_1.join)(workflowGeneratedDir, '.gitignore'), '*');
|
|
834
|
-
//
|
|
835
|
-
//
|
|
890
|
+
// V2: Only flow + webhook stubs needed (no separate step route).
|
|
891
|
+
// Stubs are replaced by generated output once discovery finishes.
|
|
836
892
|
await this.writeFileIfChanged((0, node_path_1.join)(workflowGeneratedDir, 'flow/route.js'), routeStubContent);
|
|
837
|
-
await this.writeFileIfChanged((0, node_path_1.join)(workflowGeneratedDir, 'step/route.js'), routeStubContent);
|
|
838
893
|
await this.writeFileIfChanged((0, node_path_1.join)(workflowGeneratedDir, 'webhook/[token]/route.js'), routeStubContent);
|
|
839
894
|
}
|
|
895
|
+
async getInputFiles() {
|
|
896
|
+
// Read Next.js's app-paths-manifest.json from a previous build to
|
|
897
|
+
// determine which files are actual route entrypoints. This avoids
|
|
898
|
+
// predicting Next.js conventions with regexes and instead reads
|
|
899
|
+
// from Next.js's own output.
|
|
900
|
+
const nextDir = (0, node_path_1.join)(this.config.workingDir, '.next');
|
|
901
|
+
const manifestPath = (0, node_path_1.join)(nextDir, 'app-paths-manifest.json');
|
|
902
|
+
try {
|
|
903
|
+
const manifestContent = (0, node_fs_1.readFileSync)(manifestPath, 'utf-8');
|
|
904
|
+
const manifest = JSON.parse(manifestContent);
|
|
905
|
+
// The manifest maps route paths to their source files.
|
|
906
|
+
// Extract the source file paths and resolve them.
|
|
907
|
+
const manifestFiles = new Set();
|
|
908
|
+
for (const sourcePath of Object.values(manifest)) {
|
|
909
|
+
const resolved = (0, node_path_1.resolve)(nextDir, 'server', sourcePath);
|
|
910
|
+
// The manifest points to built output; find the source file
|
|
911
|
+
// by matching against the base builder's full file list.
|
|
912
|
+
manifestFiles.add(resolved);
|
|
913
|
+
}
|
|
914
|
+
// Use the manifest route paths to filter the input files.
|
|
915
|
+
// A file is included if it matches a known route segment from
|
|
916
|
+
// the manifest (e.g., app/api/route contains 'app/api/route').
|
|
917
|
+
const inputFiles = await super.getInputFiles();
|
|
918
|
+
const routeSegments = Object.keys(manifest).map((route) => route.replace(/^\//, '').replace(/\/route$/, ''));
|
|
919
|
+
return inputFiles.filter((item) => routeSegments.some((segment) => item.includes(segment)));
|
|
920
|
+
}
|
|
921
|
+
catch {
|
|
922
|
+
// No manifest from a previous build — fall back to the base
|
|
923
|
+
// builder's full file scan. This is safe but slower; subsequent
|
|
924
|
+
// builds will use the manifest.
|
|
925
|
+
return super.getInputFiles();
|
|
926
|
+
}
|
|
927
|
+
}
|
|
840
928
|
async writeFunctionsConfig(outputDir) {
|
|
841
929
|
// we don't run this in development mode as it's not needed
|
|
842
930
|
if (process.env.NODE_ENV === 'development') {
|
|
843
931
|
return;
|
|
844
932
|
}
|
|
933
|
+
// V2: Single combined trigger handles both workflow and step execution
|
|
845
934
|
const generatedConfig = {
|
|
846
935
|
version: '0',
|
|
847
|
-
steps: {
|
|
848
|
-
maxDuration: 'max',
|
|
849
|
-
experimentalTriggers: [STEP_QUEUE_TRIGGER],
|
|
850
|
-
},
|
|
851
936
|
workflows: {
|
|
852
937
|
maxDuration: 'max',
|
|
853
938
|
experimentalTriggers: [WORKFLOW_QUEUE_TRIGGER],
|
|
854
939
|
},
|
|
855
940
|
};
|
|
856
|
-
// We write this file to the generated directory for
|
|
857
|
-
// the Next.js builder to consume
|
|
858
941
|
await this.writeFileIfChanged((0, node_path_1.join)(outputDir, '.well-known/workflow/v1/config.json'), JSON.stringify(generatedConfig, null, 2));
|
|
859
942
|
}
|
|
860
943
|
async writeFileIfChanged(filePath, contents) {
|
|
@@ -901,16 +984,56 @@ async function getNextBuilderDeferred() {
|
|
|
901
984
|
// Manifest may not exist (e.g. manifest generation failed); ignore.
|
|
902
985
|
}
|
|
903
986
|
}
|
|
904
|
-
|
|
905
|
-
if (
|
|
906
|
-
|
|
987
|
+
resolveCopiedStepImportTargetPath(targetPath) {
|
|
988
|
+
if ((0, node_fs_1.existsSync)(targetPath)) {
|
|
989
|
+
return targetPath;
|
|
990
|
+
}
|
|
991
|
+
const extensionMatch = targetPath.match(/(\.[^./\\]+)$/);
|
|
992
|
+
const extension = extensionMatch?.[1]?.toLowerCase();
|
|
993
|
+
if (!extension) {
|
|
994
|
+
return targetPath;
|
|
995
|
+
}
|
|
996
|
+
const extensionFallbacks = extension === '.js'
|
|
997
|
+
? ['.ts', '.tsx', '.mts', '.cts']
|
|
998
|
+
: extension === '.mjs'
|
|
999
|
+
? ['.mts']
|
|
1000
|
+
: extension === '.cjs'
|
|
1001
|
+
? ['.cts']
|
|
1002
|
+
: extension === '.jsx'
|
|
1003
|
+
? ['.tsx']
|
|
1004
|
+
: [];
|
|
1005
|
+
if (extensionFallbacks.length === 0) {
|
|
1006
|
+
return targetPath;
|
|
907
1007
|
}
|
|
908
|
-
|
|
909
|
-
|
|
1008
|
+
const targetWithoutExtension = targetPath.slice(0, -extension.length);
|
|
1009
|
+
for (const fallbackExtension of extensionFallbacks) {
|
|
1010
|
+
const fallbackPath = `${targetWithoutExtension}${fallbackExtension}`;
|
|
1011
|
+
if ((0, node_fs_1.existsSync)(fallbackPath)) {
|
|
1012
|
+
return fallbackPath;
|
|
1013
|
+
}
|
|
910
1014
|
}
|
|
911
|
-
|
|
912
|
-
|
|
1015
|
+
return targetPath;
|
|
1016
|
+
}
|
|
1017
|
+
extractRelativeImportSpecifiers(source) {
|
|
1018
|
+
return this.extractImportSpecifiers(source).filter((specifier) => specifier.startsWith('.'));
|
|
1019
|
+
}
|
|
1020
|
+
extractImportSpecifiers(source) {
|
|
1021
|
+
const relativeSpecifiers = new Set();
|
|
1022
|
+
const importPatterns = [
|
|
1023
|
+
/from\s+['"]([^'"]+)['"]/g,
|
|
1024
|
+
/import\s+['"]([^'"]+)['"]/g,
|
|
1025
|
+
/import\(\s*['"]([^'"]+)['"]\s*\)/g,
|
|
1026
|
+
/require\(\s*['"]([^'"]+)['"]\s*\)/g,
|
|
1027
|
+
];
|
|
1028
|
+
for (const importPattern of importPatterns) {
|
|
1029
|
+
for (const match of source.matchAll(importPattern)) {
|
|
1030
|
+
const specifier = match[1];
|
|
1031
|
+
if (specifier) {
|
|
1032
|
+
relativeSpecifiers.add(specifier);
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
913
1035
|
}
|
|
1036
|
+
return Array.from(relativeSpecifiers);
|
|
914
1037
|
}
|
|
915
1038
|
async getRelativeFilenameForSwc(filePath) {
|
|
916
1039
|
const workingDir = this.config.workingDir;
|
|
@@ -948,98 +1071,7 @@ async function getNextBuilderDeferred() {
|
|
|
948
1071
|
}
|
|
949
1072
|
return relativeFilename;
|
|
950
1073
|
}
|
|
951
|
-
|
|
952
|
-
let relativePath = (0, node_path_1.relative)((0, node_path_1.dirname)(fromFilePath), toFilePath).replace(/\\/g, '/');
|
|
953
|
-
if (!relativePath.startsWith('.')) {
|
|
954
|
-
relativePath = `./${relativePath}`;
|
|
955
|
-
}
|
|
956
|
-
return relativePath;
|
|
957
|
-
}
|
|
958
|
-
getStepCopyFileName(filePath) {
|
|
959
|
-
const normalizedPath = filePath.replace(/\\/g, '/');
|
|
960
|
-
const hash = (0, node_crypto_1.createHash)('sha256').update(normalizedPath).digest('hex');
|
|
961
|
-
const extension = (0, node_path_1.extname)(normalizedPath);
|
|
962
|
-
return `${hash.slice(0, 16)}${extension || '.js'}`;
|
|
963
|
-
}
|
|
964
|
-
rewriteCopiedStepImportSpecifier(specifier, sourceFilePath, copiedFilePath, copiedStepFileBySourcePath) {
|
|
965
|
-
if (!specifier.startsWith('.')) {
|
|
966
|
-
// Bare specifiers (e.g. '@workflow/serde') that are transitive
|
|
967
|
-
// dependencies of SDK packages can't be resolved by the bundler
|
|
968
|
-
// from the copied file's location (__workflow_step_files__/ inside
|
|
969
|
-
// the app dir) because the app doesn't directly depend on them.
|
|
970
|
-
//
|
|
971
|
-
// Only rewrite when the specifier can't be resolved from the app
|
|
972
|
-
// directory. If the package is a direct dependency of the app,
|
|
973
|
-
// the bare specifier will resolve normally and should be left as-is.
|
|
974
|
-
const appResolvable = this.resolveBareCopiedStepSpecifier(specifier, copiedFilePath);
|
|
975
|
-
if (!appResolvable) {
|
|
976
|
-
const resolved = this.resolveBareCopiedStepSpecifier(specifier, sourceFilePath);
|
|
977
|
-
if (!resolved)
|
|
978
|
-
return specifier;
|
|
979
|
-
let rewrittenPath = (0, node_path_1.relative)((0, node_path_1.dirname)(copiedFilePath), resolved).replace(/\\/g, '/');
|
|
980
|
-
if (!rewrittenPath.startsWith('.')) {
|
|
981
|
-
rewrittenPath = `./${rewrittenPath}`;
|
|
982
|
-
}
|
|
983
|
-
return rewrittenPath;
|
|
984
|
-
}
|
|
985
|
-
return specifier;
|
|
986
|
-
}
|
|
987
|
-
const specifierMatch = specifier.match(/^([^?#]+)(.*)$/);
|
|
988
|
-
const importPath = specifierMatch?.[1] ?? specifier;
|
|
989
|
-
const suffix = specifierMatch?.[2] ?? '';
|
|
990
|
-
const absoluteTargetPath = (0, node_path_1.resolve)((0, node_path_1.dirname)(sourceFilePath), importPath);
|
|
991
|
-
const resolvedTargetPath = this.resolveCopiedStepImportTargetPath(absoluteTargetPath);
|
|
992
|
-
const normalizedTargetPath = resolvedTargetPath.replace(/\\/g, '/');
|
|
993
|
-
const copiedTargetPath = copiedStepFileBySourcePath.get(normalizedTargetPath) ||
|
|
994
|
-
(() => {
|
|
995
|
-
try {
|
|
996
|
-
const realTargetPath = (0, node_fs_1.realpathSync)(resolvedTargetPath).replace(/\\/g, '/');
|
|
997
|
-
return copiedStepFileBySourcePath.get(realTargetPath);
|
|
998
|
-
}
|
|
999
|
-
catch {
|
|
1000
|
-
return undefined;
|
|
1001
|
-
}
|
|
1002
|
-
})();
|
|
1003
|
-
let rewrittenPath = (0, node_path_1.relative)((0, node_path_1.dirname)(copiedFilePath), copiedTargetPath || resolvedTargetPath).replace(/\\/g, '/');
|
|
1004
|
-
if (!rewrittenPath.startsWith('.')) {
|
|
1005
|
-
rewrittenPath = `./${rewrittenPath}`;
|
|
1006
|
-
}
|
|
1007
|
-
return `${rewrittenPath}${suffix}`;
|
|
1008
|
-
}
|
|
1009
|
-
/**
|
|
1010
|
-
* Resolves a bare specifier (e.g. '@workflow/serde', 'workflow') to an
|
|
1011
|
-
* absolute file path using ESM-compatible resolution semantics via
|
|
1012
|
-
* `enhanced-resolve`. Tries ESM conditions first (`node`, `import`),
|
|
1013
|
-
* falling back to CJS resolution if ESM fails.
|
|
1014
|
-
*/
|
|
1015
|
-
resolveBareCopiedStepSpecifier(specifier, sourceFilePath) {
|
|
1016
|
-
if (!this.esmSyncResolver) {
|
|
1017
|
-
this.esmSyncResolver = enhanced_resolve_1.default.create.sync(NODE_ESM_RESOLVE_OPTIONS);
|
|
1018
|
-
}
|
|
1019
|
-
if (!this.cjsSyncResolver) {
|
|
1020
|
-
this.cjsSyncResolver =
|
|
1021
|
-
enhanced_resolve_1.default.create.sync(NODE_RESOLVE_OPTIONS);
|
|
1022
|
-
}
|
|
1023
|
-
const context = (0, node_path_1.dirname)(sourceFilePath);
|
|
1024
|
-
try {
|
|
1025
|
-
const resolved = this.esmSyncResolver(context, specifier);
|
|
1026
|
-
if (resolved)
|
|
1027
|
-
return resolved;
|
|
1028
|
-
}
|
|
1029
|
-
catch {
|
|
1030
|
-
// ESM resolution failed, try CJS
|
|
1031
|
-
}
|
|
1032
|
-
try {
|
|
1033
|
-
const resolved = this.cjsSyncResolver(context, specifier);
|
|
1034
|
-
if (resolved)
|
|
1035
|
-
return resolved;
|
|
1036
|
-
}
|
|
1037
|
-
catch {
|
|
1038
|
-
// CJS resolution also failed
|
|
1039
|
-
}
|
|
1040
|
-
return undefined;
|
|
1041
|
-
}
|
|
1042
|
-
resolveCopiedStepImportTargetPath(targetPath) {
|
|
1074
|
+
resolveImportTargetWithExtensionFallbacks(targetPath) {
|
|
1043
1075
|
if ((0, node_fs_1.existsSync)(targetPath)) {
|
|
1044
1076
|
return targetPath;
|
|
1045
1077
|
}
|
|
@@ -1069,51 +1101,38 @@ async function getNextBuilderDeferred() {
|
|
|
1069
1101
|
}
|
|
1070
1102
|
return targetPath;
|
|
1071
1103
|
}
|
|
1072
|
-
rewriteRelativeImportsForCopiedStep(source, sourceFilePath, copiedFilePath, copiedStepFileBySourcePath) {
|
|
1073
|
-
const rewriteSpecifier = (specifier) => this.rewriteCopiedStepImportSpecifier(specifier, sourceFilePath, copiedFilePath, copiedStepFileBySourcePath);
|
|
1074
|
-
const rewritePattern = (currentSource, pattern) => currentSource.replace(pattern, (_match, prefix, specifier, suffix) => `${prefix}${rewriteSpecifier(specifier)}${suffix}`);
|
|
1075
|
-
let rewrittenSource = source;
|
|
1076
|
-
rewrittenSource = rewritePattern(rewrittenSource, /(from\s+['"])([^'"]+)(['"])/g);
|
|
1077
|
-
rewrittenSource = rewritePattern(rewrittenSource, /(import\s+['"])([^'"]+)(['"])/g);
|
|
1078
|
-
rewrittenSource = rewritePattern(rewrittenSource, /(import\(\s*['"])([^'"]+)(['"]\s*\))/g);
|
|
1079
|
-
rewrittenSource = rewritePattern(rewrittenSource, /(require\(\s*['"])([^'"]+)(['"]\s*\))/g);
|
|
1080
|
-
return rewrittenSource;
|
|
1081
|
-
}
|
|
1082
|
-
extractRelativeImportSpecifiers(source) {
|
|
1083
|
-
const relativeSpecifiers = new Set();
|
|
1084
|
-
const importPatterns = [
|
|
1085
|
-
/from\s+['"]([^'"]+)['"]/g,
|
|
1086
|
-
/import\s+['"]([^'"]+)['"]/g,
|
|
1087
|
-
/import\(\s*['"]([^'"]+)['"]\s*\)/g,
|
|
1088
|
-
/require\(\s*['"]([^'"]+)['"]\s*\)/g,
|
|
1089
|
-
];
|
|
1090
|
-
for (const importPattern of importPatterns) {
|
|
1091
|
-
for (const match of source.matchAll(importPattern)) {
|
|
1092
|
-
const specifier = match[1];
|
|
1093
|
-
if (specifier?.startsWith('.')) {
|
|
1094
|
-
relativeSpecifiers.add(specifier);
|
|
1095
|
-
}
|
|
1096
|
-
}
|
|
1097
|
-
}
|
|
1098
|
-
return Array.from(relativeSpecifiers);
|
|
1099
|
-
}
|
|
1100
|
-
isGeneratedWorkflowArtifact(filePath) {
|
|
1101
|
-
const normalizedPath = filePath.replace(/\\/g, '/');
|
|
1102
|
-
return (normalizedPath.includes('/.well-known/workflow/') ||
|
|
1103
|
-
normalizedPath.includes('/.next/'));
|
|
1104
|
-
}
|
|
1105
1104
|
shouldSkipTransitiveStepFile(filePath) {
|
|
1106
1105
|
const normalizedPath = filePath.replace(/\\/g, '/');
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
normalizedPath.includes('/.
|
|
1106
|
+
const isSourceBackedPackagePath = this.shouldPreferSourceBackedPackagePath(filePath);
|
|
1107
|
+
return (normalizedPath.includes('/.well-known/workflow/') ||
|
|
1108
|
+
normalizedPath.includes('/.next/') ||
|
|
1109
|
+
(!isSourceBackedPackagePath &&
|
|
1110
|
+
(normalizedPath.includes('/node_modules/') ||
|
|
1111
|
+
normalizedPath.includes('/.pnpm/'))));
|
|
1110
1112
|
}
|
|
1111
1113
|
async resolveTransitiveStepImportTargetPath(sourceFilePath, specifier) {
|
|
1112
1114
|
const specifierMatch = specifier.match(/^([^?#]+)(.*)$/);
|
|
1113
1115
|
const importPath = specifierMatch?.[1] ?? specifier;
|
|
1116
|
+
if (!importPath.startsWith('.')) {
|
|
1117
|
+
if (importPath !== 'workflow' && !importPath.startsWith('@workflow/')) {
|
|
1118
|
+
return null;
|
|
1119
|
+
}
|
|
1120
|
+
try {
|
|
1121
|
+
const resolvedPath = (0, node_module_1.createRequire)(sourceFilePath).resolve(importPath);
|
|
1122
|
+
const normalizedResolvedPath = this.normalizeDiscoveredFilePath(resolvedPath);
|
|
1123
|
+
if (this.shouldSkipTransitiveStepFile(normalizedResolvedPath)) {
|
|
1124
|
+
return null;
|
|
1125
|
+
}
|
|
1126
|
+
const fileStats = await (0, promises_1.stat)(normalizedResolvedPath);
|
|
1127
|
+
return fileStats.isFile() ? normalizedResolvedPath : null;
|
|
1128
|
+
}
|
|
1129
|
+
catch {
|
|
1130
|
+
return null;
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1114
1133
|
const absoluteTargetPath = (0, node_path_1.resolve)((0, node_path_1.dirname)(sourceFilePath), importPath);
|
|
1115
1134
|
const candidatePaths = new Set([
|
|
1116
|
-
this.
|
|
1135
|
+
this.resolveImportTargetWithExtensionFallbacks(absoluteTargetPath),
|
|
1117
1136
|
]);
|
|
1118
1137
|
if (!(0, node_path_1.extname)(absoluteTargetPath)) {
|
|
1119
1138
|
const extensionCandidates = [
|
|
@@ -1132,7 +1151,7 @@ async function getNextBuilderDeferred() {
|
|
|
1132
1151
|
}
|
|
1133
1152
|
}
|
|
1134
1153
|
for (const candidatePath of candidatePaths) {
|
|
1135
|
-
const resolvedPath = this.
|
|
1154
|
+
const resolvedPath = this.resolveImportTargetWithExtensionFallbacks(candidatePath);
|
|
1136
1155
|
const normalizedResolvedPath = this.normalizeDiscoveredFilePath(resolvedPath);
|
|
1137
1156
|
if (this.shouldSkipTransitiveStepFile(normalizedResolvedPath)) {
|
|
1138
1157
|
continue;
|
|
@@ -1149,13 +1168,11 @@ async function getNextBuilderDeferred() {
|
|
|
1149
1168
|
}
|
|
1150
1169
|
return null;
|
|
1151
1170
|
}
|
|
1152
|
-
async collectTransitiveStepFiles({
|
|
1153
|
-
const
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
const discoveredStepFiles = new Set();
|
|
1158
|
-
const queuedFiles = [...normalizedSeedFiles];
|
|
1171
|
+
async collectTransitiveStepFiles({ entryFiles, stepFiles, }) {
|
|
1172
|
+
const normalizedEntryFiles = Array.from(new Set(entryFiles.map((entryFile) => this.normalizeDiscoveredFilePath(entryFile)))).sort();
|
|
1173
|
+
const normalizedStepSeedFiles = Array.from(new Set(stepFiles.map((stepFile) => this.normalizeDiscoveredFilePath(stepFile)))).sort();
|
|
1174
|
+
const discoveredStepFiles = new Set(normalizedStepSeedFiles);
|
|
1175
|
+
const queuedFiles = Array.from(new Set([...normalizedEntryFiles, ...normalizedStepSeedFiles]));
|
|
1159
1176
|
const visitedFiles = new Set();
|
|
1160
1177
|
const sourceCache = new Map();
|
|
1161
1178
|
const patternCache = new Map();
|
|
@@ -1196,12 +1213,8 @@ async function getNextBuilderDeferred() {
|
|
|
1196
1213
|
if (currentSource === null) {
|
|
1197
1214
|
continue;
|
|
1198
1215
|
}
|
|
1199
|
-
const
|
|
1200
|
-
|
|
1201
|
-
discoveredStepFiles.add(currentFile);
|
|
1202
|
-
}
|
|
1203
|
-
const relativeImportSpecifiers = this.extractRelativeImportSpecifiers(currentSource);
|
|
1204
|
-
for (const specifier of relativeImportSpecifiers) {
|
|
1216
|
+
const importSpecifiers = this.extractImportSpecifiers(currentSource);
|
|
1217
|
+
for (const specifier of importSpecifiers) {
|
|
1205
1218
|
const resolvedImportPath = await this.resolveTransitiveStepImportTargetPath(currentFile, specifier);
|
|
1206
1219
|
if (!resolvedImportPath) {
|
|
1207
1220
|
continue;
|
|
@@ -1313,225 +1326,6 @@ async function getNextBuilderDeferred() {
|
|
|
1313
1326
|
}));
|
|
1314
1327
|
return verifiedSerdeFiles.sort();
|
|
1315
1328
|
}
|
|
1316
|
-
async createResponseBuiltinsStepFile({ stepsRouteDir, }) {
|
|
1317
|
-
const copiedStepsDir = (0, node_path_1.join)(stepsRouteDir, step_copy_utils_js_1.DEFERRED_STEP_COPY_DIR_NAME);
|
|
1318
|
-
await (0, promises_1.mkdir)(copiedStepsDir, { recursive: true });
|
|
1319
|
-
const responseBuiltinsFilePath = (0, node_path_1.join)(copiedStepsDir, 'workflow-response-builtins.ts');
|
|
1320
|
-
const source = [
|
|
1321
|
-
'export async function __builtin_response_array_buffer(this: Request | Response) {',
|
|
1322
|
-
" 'use step';",
|
|
1323
|
-
' return this.arrayBuffer();',
|
|
1324
|
-
'}',
|
|
1325
|
-
'',
|
|
1326
|
-
'export async function __builtin_response_json(this: Request | Response) {',
|
|
1327
|
-
" 'use step';",
|
|
1328
|
-
' return this.json();',
|
|
1329
|
-
'}',
|
|
1330
|
-
'',
|
|
1331
|
-
'export async function __builtin_response_text(this: Request | Response) {',
|
|
1332
|
-
" 'use step';",
|
|
1333
|
-
' return this.text();',
|
|
1334
|
-
'}',
|
|
1335
|
-
].join('\n');
|
|
1336
|
-
const sourceMapComment = (0, step_copy_utils_js_1.createDeferredStepCopyInlineSourceMapComment)({
|
|
1337
|
-
sourcePath: responseBuiltinsFilePath,
|
|
1338
|
-
sourceContent: source,
|
|
1339
|
-
});
|
|
1340
|
-
await this.writeFileIfChanged(responseBuiltinsFilePath, `${source}\n${sourceMapComment}\n`);
|
|
1341
|
-
return responseBuiltinsFilePath;
|
|
1342
|
-
}
|
|
1343
|
-
async copyDiscoveredStepFiles({ stepFiles, stepsRouteDir, preserveFileNames = [], }) {
|
|
1344
|
-
const copiedStepsDir = (0, node_path_1.join)(stepsRouteDir, step_copy_utils_js_1.DEFERRED_STEP_COPY_DIR_NAME);
|
|
1345
|
-
await (0, promises_1.mkdir)(copiedStepsDir, { recursive: true });
|
|
1346
|
-
const normalizedStepFiles = Array.from(new Set(stepFiles.map((stepFile) => this.normalizeDiscoveredFilePath(stepFile)))).sort();
|
|
1347
|
-
const copiedStepFileBySourcePath = new Map();
|
|
1348
|
-
const expectedFileNames = new Set(preserveFileNames);
|
|
1349
|
-
const copiedStepFiles = [];
|
|
1350
|
-
for (const normalizedStepFile of normalizedStepFiles) {
|
|
1351
|
-
const copiedFileName = this.getStepCopyFileName(normalizedStepFile);
|
|
1352
|
-
const copiedFilePath = (0, node_path_1.join)(copiedStepsDir, copiedFileName);
|
|
1353
|
-
const normalizedPathKey = normalizedStepFile.replace(/\\/g, '/');
|
|
1354
|
-
copiedStepFileBySourcePath.set(normalizedPathKey, copiedFilePath);
|
|
1355
|
-
try {
|
|
1356
|
-
const realPathKey = (0, node_fs_1.realpathSync)(normalizedStepFile).replace(/\\/g, '/');
|
|
1357
|
-
copiedStepFileBySourcePath.set(realPathKey, copiedFilePath);
|
|
1358
|
-
}
|
|
1359
|
-
catch {
|
|
1360
|
-
// Keep best-effort mapping when source cannot be realpath-resolved.
|
|
1361
|
-
}
|
|
1362
|
-
expectedFileNames.add(copiedFileName);
|
|
1363
|
-
copiedStepFiles.push(copiedFilePath);
|
|
1364
|
-
}
|
|
1365
|
-
for (const normalizedStepFile of normalizedStepFiles) {
|
|
1366
|
-
const source = await (0, promises_1.readFile)(normalizedStepFile, 'utf-8');
|
|
1367
|
-
const copiedFilePath = copiedStepFileBySourcePath.get(normalizedStepFile.replace(/\\/g, '/'));
|
|
1368
|
-
if (!copiedFilePath) {
|
|
1369
|
-
continue;
|
|
1370
|
-
}
|
|
1371
|
-
const rewrittenSource = this.rewriteRelativeImportsForCopiedStep(source, normalizedStepFile, copiedFilePath, copiedStepFileBySourcePath);
|
|
1372
|
-
const metadataComment = (0, step_copy_utils_js_1.createDeferredStepSourceMetadataComment)({
|
|
1373
|
-
relativeFilename: await this.getRelativeFilenameForSwc(normalizedStepFile),
|
|
1374
|
-
absolutePath: normalizedStepFile.replace(/\\/g, '/'),
|
|
1375
|
-
});
|
|
1376
|
-
const sourceMapComment = (0, step_copy_utils_js_1.createDeferredStepCopyInlineSourceMapComment)({
|
|
1377
|
-
sourcePath: normalizedStepFile,
|
|
1378
|
-
sourceContent: source,
|
|
1379
|
-
generatedContent: rewrittenSource,
|
|
1380
|
-
});
|
|
1381
|
-
const copiedSource = `${metadataComment}\n${rewrittenSource}\n${sourceMapComment}`;
|
|
1382
|
-
await this.writeFileIfChanged(copiedFilePath, copiedSource);
|
|
1383
|
-
}
|
|
1384
|
-
const existingEntries = await (0, promises_1.readdir)(copiedStepsDir, {
|
|
1385
|
-
withFileTypes: true,
|
|
1386
|
-
}).catch(() => []);
|
|
1387
|
-
await Promise.all(existingEntries
|
|
1388
|
-
.filter((entry) => !expectedFileNames.has(entry.name))
|
|
1389
|
-
.map((entry) => (0, promises_1.rm)((0, node_path_1.join)(copiedStepsDir, entry.name), {
|
|
1390
|
-
recursive: true,
|
|
1391
|
-
force: true,
|
|
1392
|
-
})));
|
|
1393
|
-
return copiedStepFiles;
|
|
1394
|
-
}
|
|
1395
|
-
async createDeferredStepsManifest({ stepFiles, workflowFiles, serdeOnlyFiles, }) {
|
|
1396
|
-
const workflowManifest = {};
|
|
1397
|
-
const filesForStepTransform = Array.from(new Set([...stepFiles, ...serdeOnlyFiles])).sort();
|
|
1398
|
-
await Promise.all(filesForStepTransform.map(async (stepFile) => {
|
|
1399
|
-
const source = await (0, promises_1.readFile)(stepFile, 'utf-8');
|
|
1400
|
-
const relativeFilename = await this.getRelativeFilenameForSwc(stepFile);
|
|
1401
|
-
const { workflowManifest: fileManifest } = await applySwcTransform(relativeFilename, source, 'step', stepFile, this.config.projectRoot || this.config.workingDir);
|
|
1402
|
-
this.mergeWorkflowManifest(workflowManifest, fileManifest);
|
|
1403
|
-
}));
|
|
1404
|
-
const stepFileSet = new Set(stepFiles);
|
|
1405
|
-
const workflowOnlyFiles = workflowFiles
|
|
1406
|
-
.filter((workflowFile) => !stepFileSet.has(workflowFile))
|
|
1407
|
-
.sort();
|
|
1408
|
-
await Promise.all(workflowOnlyFiles.map(async (workflowFile) => {
|
|
1409
|
-
try {
|
|
1410
|
-
const source = await (0, promises_1.readFile)(workflowFile, 'utf-8');
|
|
1411
|
-
const relativeFilename = await this.getRelativeFilenameForSwc(workflowFile);
|
|
1412
|
-
const { workflowManifest: fileManifest } = await applySwcTransform(relativeFilename, source, 'workflow', workflowFile, this.config.projectRoot || this.config.workingDir);
|
|
1413
|
-
this.mergeWorkflowManifest(workflowManifest, {
|
|
1414
|
-
workflows: fileManifest.workflows,
|
|
1415
|
-
classes: fileManifest.classes,
|
|
1416
|
-
});
|
|
1417
|
-
}
|
|
1418
|
-
catch (error) {
|
|
1419
|
-
console.log(`Warning: Failed to extract workflow metadata from ${workflowFile}:`, error instanceof Error ? error.message : String(error));
|
|
1420
|
-
}
|
|
1421
|
-
}));
|
|
1422
|
-
return workflowManifest;
|
|
1423
|
-
}
|
|
1424
|
-
async collectManifestStepSourceFiles(manifest) {
|
|
1425
|
-
const manifestStepEntries = Object.keys(manifest.steps || {});
|
|
1426
|
-
if (manifestStepEntries.length === 0) {
|
|
1427
|
-
return [];
|
|
1428
|
-
}
|
|
1429
|
-
const resolveBaseDirs = this.getManifestStepResolveBaseDirs();
|
|
1430
|
-
const candidateFiles = manifestStepEntries
|
|
1431
|
-
.flatMap((stepEntry) => {
|
|
1432
|
-
if ((0, node_path_1.isAbsolute)(stepEntry)) {
|
|
1433
|
-
return [this.normalizeDiscoveredFilePath(stepEntry)];
|
|
1434
|
-
}
|
|
1435
|
-
return resolveBaseDirs.map((baseDir) => this.normalizeDiscoveredFilePath((0, node_path_1.resolve)(baseDir, stepEntry)));
|
|
1436
|
-
})
|
|
1437
|
-
.filter((candidateFile) => !this.isGeneratedWorkflowArtifact(candidateFile));
|
|
1438
|
-
const existingCandidates = await this.filterExistingFiles(candidateFiles);
|
|
1439
|
-
return Array.from(new Set(existingCandidates)).sort();
|
|
1440
|
-
}
|
|
1441
|
-
async buildStepsFunction({ workflowGeneratedDir, routeFileName = 'route.js', discoveredEntries, additionalStepSourceManifest, }) {
|
|
1442
|
-
const stepsRouteDir = (0, node_path_1.join)(workflowGeneratedDir, 'step');
|
|
1443
|
-
await (0, promises_1.mkdir)(stepsRouteDir, { recursive: true });
|
|
1444
|
-
const discovered = discoveredEntries;
|
|
1445
|
-
const workflowFiles = [...discovered.discoveredWorkflows].sort();
|
|
1446
|
-
const stepFiles = await this.collectTransitiveStepFiles({
|
|
1447
|
-
stepFiles: [...discovered.discoveredSteps].sort(),
|
|
1448
|
-
// Workflow transforms can inline step IDs and remove runtime imports,
|
|
1449
|
-
// so seed transitive traversal with workflow files too.
|
|
1450
|
-
seedFiles: workflowFiles,
|
|
1451
|
-
});
|
|
1452
|
-
const serdeFiles = [...discovered.discoveredSerdeFiles].sort();
|
|
1453
|
-
const stepFileSet = new Set(stepFiles);
|
|
1454
|
-
const serdeOnlyFiles = serdeFiles.filter((file) => !stepFileSet.has(file));
|
|
1455
|
-
const additionalManifestStepFiles = additionalStepSourceManifest
|
|
1456
|
-
? await this.collectManifestStepSourceFiles(additionalStepSourceManifest)
|
|
1457
|
-
: [];
|
|
1458
|
-
const stepFilesWithManifestSources = Array.from(new Set([...stepFiles, ...additionalManifestStepFiles])).sort();
|
|
1459
|
-
const responseBuiltinsStepFilePath = await this.createResponseBuiltinsStepFile({
|
|
1460
|
-
stepsRouteDir,
|
|
1461
|
-
});
|
|
1462
|
-
const manifestStepFiles = Array.from(new Set([...stepFilesWithManifestSources, responseBuiltinsStepFilePath])).sort();
|
|
1463
|
-
const manifest = await this.createDeferredStepsManifest({
|
|
1464
|
-
stepFiles: manifestStepFiles,
|
|
1465
|
-
workflowFiles,
|
|
1466
|
-
serdeOnlyFiles,
|
|
1467
|
-
});
|
|
1468
|
-
const manifestDiscoveredStepFiles = await this.collectManifestStepSourceFiles(manifest);
|
|
1469
|
-
// Copy all discovered step sources so they are transformed in step mode.
|
|
1470
|
-
// Importing raw node_modules files directly can bypass loader transforms,
|
|
1471
|
-
// which prevents step registrars from being emitted.
|
|
1472
|
-
const copiedStepSourceFiles = Array.from(new Set([
|
|
1473
|
-
...stepFilesWithManifestSources,
|
|
1474
|
-
...manifestDiscoveredStepFiles,
|
|
1475
|
-
])).sort();
|
|
1476
|
-
const copiedDiscoveredStepFiles = await this.copyDiscoveredStepFiles({
|
|
1477
|
-
stepFiles: copiedStepSourceFiles,
|
|
1478
|
-
stepsRouteDir,
|
|
1479
|
-
preserveFileNames: [(0, node_path_1.basename)(responseBuiltinsStepFilePath)],
|
|
1480
|
-
});
|
|
1481
|
-
const copiedStepFiles = [
|
|
1482
|
-
responseBuiltinsStepFilePath,
|
|
1483
|
-
...copiedDiscoveredStepFiles,
|
|
1484
|
-
];
|
|
1485
|
-
const stepRouteFile = (0, node_path_1.join)(stepsRouteDir, routeFileName);
|
|
1486
|
-
const copiedStepImports = copiedStepFiles
|
|
1487
|
-
.map((copiedStepFile) => {
|
|
1488
|
-
const importSpecifier = this.getRelativeImportSpecifier(stepRouteFile, copiedStepFile);
|
|
1489
|
-
return `import '${importSpecifier}';`;
|
|
1490
|
-
})
|
|
1491
|
-
.join('\n');
|
|
1492
|
-
const serdeImports = serdeOnlyFiles
|
|
1493
|
-
.map((serdeFile) => {
|
|
1494
|
-
const normalizedSerdeFile = this.normalizeDiscoveredFilePath(serdeFile);
|
|
1495
|
-
const { importPath, isPackage } = getImportPath(normalizedSerdeFile, this.config.workingDir);
|
|
1496
|
-
if (isPackage) {
|
|
1497
|
-
return `import '${importPath}';`;
|
|
1498
|
-
}
|
|
1499
|
-
const importSpecifier = this.getRelativeImportSpecifier(stepRouteFile, normalizedSerdeFile);
|
|
1500
|
-
return `import '${importSpecifier}';`;
|
|
1501
|
-
})
|
|
1502
|
-
.join('\n');
|
|
1503
|
-
const routeContents = [
|
|
1504
|
-
'// biome-ignore-all lint: generated file',
|
|
1505
|
-
'/* eslint-disable */',
|
|
1506
|
-
copiedStepImports,
|
|
1507
|
-
serdeImports
|
|
1508
|
-
? `// Serde files for cross-context class registration\n${serdeImports}`
|
|
1509
|
-
: '',
|
|
1510
|
-
"export { stepEntrypoint as POST } from 'workflow/runtime';",
|
|
1511
|
-
]
|
|
1512
|
-
.filter(Boolean)
|
|
1513
|
-
.join('\n');
|
|
1514
|
-
await this.writeFileIfChanged(stepRouteFile, routeContents);
|
|
1515
|
-
return {
|
|
1516
|
-
context: undefined,
|
|
1517
|
-
manifest,
|
|
1518
|
-
};
|
|
1519
|
-
}
|
|
1520
|
-
async buildWorkflowsFunction({ inputFiles, workflowGeneratedDir, tsconfigPath, routeFileName = 'route.js', discoveredEntries, }) {
|
|
1521
|
-
const workflowsRouteDir = (0, node_path_1.join)(workflowGeneratedDir, 'flow');
|
|
1522
|
-
await (0, promises_1.mkdir)(workflowsRouteDir, { recursive: true });
|
|
1523
|
-
return await this.createWorkflowsBundle({
|
|
1524
|
-
format: 'esm',
|
|
1525
|
-
outfile: (0, node_path_1.join)(workflowsRouteDir, routeFileName),
|
|
1526
|
-
bundleFinalOutput: false,
|
|
1527
|
-
// Deferred builds do not reuse the interim esbuild context. Dispose it
|
|
1528
|
-
// after each pass to avoid leaking contexts during watch-mode rebuilds.
|
|
1529
|
-
keepInterimBundleContext: false,
|
|
1530
|
-
inputFiles,
|
|
1531
|
-
tsconfigPath,
|
|
1532
|
-
discoveredEntries,
|
|
1533
|
-
});
|
|
1534
|
-
}
|
|
1535
1329
|
async buildWebhookRoute({ workflowGeneratedDir, routeFileName = 'route.js', }) {
|
|
1536
1330
|
const webhookRouteFile = (0, node_path_1.join)(workflowGeneratedDir, `webhook/[token]/${routeFileName}`);
|
|
1537
1331
|
await this.createWebhookBundle({
|
|
@@ -1586,4 +1380,4 @@ async function getNextBuilderDeferred() {
|
|
|
1586
1380
|
CachedNextBuilderDeferred = NextDeferredBuilder;
|
|
1587
1381
|
return NextDeferredBuilder;
|
|
1588
1382
|
}
|
|
1589
|
-
//# sourceMappingURL=builder-deferred.js.map
|
|
1383
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGRlci1kZWZlcnJlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9idWlsZGVyLWRlZmVycmVkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBdUNBLHdEQXUwREM7QUE5MkRELDZDQUF5QztBQUN6QyxxQ0FBOEQ7QUFDOUQsK0NBUzBCO0FBQzFCLDZDQUE0QztBQUM1QyxzREFBeUI7QUFDekIseUNBUW1CO0FBQ25CLHlEQU00QjtBQUU1QixNQUFNLHNCQUFzQixHQUFHLDBCQUEwQixDQUFDO0FBQzFELE1BQU0sNEJBQTRCLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQztBQUU5QyxJQUFJLHlCQUE4QixDQUFDO0FBRW5DLGlGQUFpRjtBQUNqRixnRkFBZ0Y7QUFDaEYsb0VBQW9FO0FBQzdELEtBQUssVUFBVSxzQkFBc0I7SUFDMUMsSUFBSSx5QkFBeUIsRUFBRSxDQUFDO1FBQzlCLE9BQU8seUJBQXlCLENBQUM7SUFDbkMsQ0FBQztJQUVELDZFQUE2RTtJQUM3RSw0RUFBNEU7SUFDNUUsMkVBQTJFO0lBQzNFLCtFQUErRTtJQUMvRSwyRUFBMkU7SUFDM0UseUNBQXlDO0lBQ3pDLE1BQU0sRUFDSixXQUFXLEVBQUUsZ0JBQWdCLEVBQzdCLHNCQUFzQixFQUN0QixzQkFBc0IsRUFDdEIsaUJBQWlCLEVBQ2pCLGdDQUFnQztJQUNoQyw0SUFBNEk7TUFDN0ksR0FBRyxDQUFDLE1BQU0sSUFBSSxDQUNiLDhCQUE4QixDQUMvQixDQUF3QyxDQUFDO0lBRTFDLE1BQU0sbUJBQW9CLFNBQVEsZ0JBQWdCO1FBQ3hDLFFBQVEsQ0FBWTtRQUNYLHVCQUF1QixHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7UUFDNUMsbUJBQW1CLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztRQUN4QyxvQkFBb0IsR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO1FBQ2xELHNCQUFzQixHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7UUFDM0Msa0JBQWtCLEdB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QUFDO2dCQUNoQywrQ0FBK0M7Z0JBQy9DLE1BQU0sSUFBQSxnQkFBSyxFQUFDLE1BQU0sRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO2dCQUN6QyxPQUFPLE1BQU0sQ0FBQztZQUNoQixDQUFDO1lBRUQsSUFBSSxNQUFNLFdBQVcsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO2dCQUNuQyx1REFBdUQ7Z0JBQ3ZELE1BQU0sSUFBQSxnQkFBSyxFQUFDLFNBQVMsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO2dCQUM1QyxPQUFPLFNBQVMsQ0FBQztZQUNuQixDQUFDO1lBRUQsTUFBTSxJQUFJLEtBQUssQ0FDYixxSEFBcUgsQ0FDdEgsQ0FBQztRQUNKLENBQUM7S0FDRjtJQUVELHlCQUF5QixHQUFHLG1CQUFtQixDQUFDO0lBQ2hELE9BQU8sbUJBQW1CLENBQUM7QUFDN0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGNyZWF0ZUhhc2ggfSBmcm9tICdub2RlOmNyeXB0byc7XG5pbXBvcnQgeyBjb25zdGFudHMsIGV4aXN0c1N5bmMsIHJlYWRGaWxlU3luYyB9IGZyb20gJ25vZGU6ZnMnO1xuaW1wb3J0IHtcbiAgYWNjZXNzLFxuICBta2RpcixcbiAgb3BlbixcbiAgcmVhZGRpcixcbiAgcmVhZEZpbGUsXG4gIHJtLFxuICBzdGF0LFxuICB3cml0ZUZpbGUsXG59IGZyb20gJ25vZGU6ZnMvcHJvbWlzZXMnO1xuaW1wb3J0IHsgY3JlYXRlUmVxdWlyZSB9IGZyb20gJ25vZGU6bW9kdWxlJztcbmltcG9ydCBvcyBmcm9tICdub2RlOm9zJztcbmltcG9ydCB7XG4gIGJhc2VuYW1lLFxuICBkaXJuYW1lLFxuICBleHRuYW1lLFxuICBpc0Fic29sdXRlLFxuICBqb2luLFxuICByZWxhdGl2ZSxcbiAgcmVzb2x2ZSxcbn0gZnJvbSAnbm9kZTpwYXRoJztcbmltcG9ydCB7XG4gIGNsZWFudXBTdGFsZVNvY2tldEluZm9GaWxlcyxcbiAgY3JlYXRlU29ja2V0U2VydmVyLFxuICBTT0NLRVRfSU5GT19GSUxFTkFNRSxcbiAgdHlwZSBTb2NrZXRJTyxcbiAgdHlwZSBTb2NrZXRTZXJ2ZXJDb25maWcsXG59IGZyb20gJy4vc29ja2V0LXNlcnZlci5qcyc7XG5cbmNvbnN0IFJPVVRFX1NUVUJfRklMRV9NQVJLRVIgPSAnV09SS0ZMT1dfUk9VVEVfU1RVQl9GSUxFJztcbmNvbnN0IFJPVVRFX1NUVUJfTUFSS0VSX1NDQU5fQllURVMgPSA0ICogMTAyNDtcblxubGV0IENhY2hlZE5leHRCdWlsZGVyRGVmZXJyZWQ6IGFueTtcblxuLy8gQ3JlYXRlIHRoZSBkZWZlcnJlZCBOZXh0IGJ1aWxkZXIgZHluYW1pY2FsbHkgYnkgZXh0ZW5kaW5nIHRoZSBFU00gQmFzZUJ1aWxkZXIuXG4vLyBFeHBvcnRlZCBhcyBnZXROZXh0QnVpbGRlckRlZmVycmVkKCkgdG8gYWxsb3cgQ29tbW9uSlMgbW9kdWxlcyB0byBpbXBvcnQgZnJvbVxuLy8gdGhlIEVTTSBAd29ya2Zsb3cvYnVpbGRlcnMgcGFja2FnZSB2aWEgZHluYW1pYyBpbXBvcnQgYXQgcnVudGltZS5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXROZXh0QnVpbGRlckRlZmVycmVkKCkge1xuICBpZiAoQ2FjaGVkTmV4dEJ1aWxkZXJEZWZlcnJlZCkge1xuICAgIHJldHVybiBDYWNoZWROZXh0QnVpbGRlckRlZmVycmVkO1xuICB9XG5cbiAgLy8gVjI6IFNURVBfUVVFVUVfVFJJR0dFUiwgZ2V0SW1wb3J0UGF0aCwgYW5kIGVuaGFuY2VkLXJlc29sdmUgaW5mcmFzdHJ1Y3R1cmVcbiAgLy8gd2VyZSByZW1vdmVkIGJlY2F1c2UgdGhlIFYyIGNvbWJpbmVkIGhhbmRsZXIgZWxpbWluYXRlcyB0aGUgc2VwYXJhdGUgc3RlcFxuICAvLyByb3V0ZS90b3BpYy4gVGhlIHN0ZXAgY29weSBpbXBvcnQgcmV3cml0aW5nIChnZXRSZWxhdGl2ZUltcG9ydFNwZWNpZmllcixcbiAgLy8gZ2V0U3RlcENvcHlGaWxlTmFtZSwgcmV3cml0ZVJlbGF0aXZlSW1wb3J0c0ZvckNvcGllZFN0ZXApIGZyb20gbWFpbiB3YXMgYWxzb1xuICAvLyByZW1vdmVkIOKAlCBWMiBkb2Vzbid0IHVzZSBzdGVwIGNvcGllcy4gSWYgc3RlcCBjb3B5IHN1cHBvcnQgaXMgbmVlZGVkLCBpdFxuICAvLyBzaG91bGQgbGFuZCBhcyBhIGNvbXBsZXRlIGZlYXR1cmUgc2V0LlxuICBjb25zdCB7XG4gICAgQmFzZUJ1aWxkZXI6IEJhc2VCdWlsZGVyQ2xhc3MsXG4gICAgV09SS0ZMT1dfUVVFVUVfVFJJR0dFUixcbiAgICBkZXRlY3RXb3JrZmxvd1BhdHRlcm5zLFxuICAgIGFwcGx5U3djVHJhbnNmb3JtLFxuICAgIHJlc29sdmVXb3JrZmxvd0FsaWFzUmVsYXRpdmVQYXRoLFxuICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3NlY3VyaXR5L25vR2xvYmFsRXZhbDogTmVlZCB0byB1c2UgZXZhbCBoZXJlIHRvIGF2b2lkIFR5cGVTY3JpcHQgZnJvbSB0cmFuc3BpbGluZyB0aGUgaW1wb3J0IHN0YXRlbWVudCBpbnRvIGByZXF1aXJlKClgXG4gIH0gPSAoYXdhaXQgZXZhbChcbiAgICAnaW1wb3J0KFwiQHdvcmtmbG93L2J1aWxkZXJzXCIpJ1xuICApKSBhcyB0eXBlb2YgaW1wb3J0KCdAd29ya2Zsb3cvYnVpbGRlcnMnKTtcblxuICBjbGFzcyBOZXh0RGVmZXJyZWRCdWlsZGVyIGV4dGVuZHMgQmFzZUJ1aWxkZXJDbGFzcyB7XG4gICAgcHJpdmF0ZSBzb2NrZXRJTz86IFNvY2tldElPO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgZGlzY292ZXJlZFdvcmtmbG93RmlsZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGRpc2NvdmVyZWRTdGVwRmlsZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGRpc2NvdmVyZWRTZXJkZUZpbGVzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgcHJpdmF0ZSB0cmFja2VkRGVwZW5kZW5jeUZpbGVzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgcHJpdmF0ZSBkZWZlcnJlZEJ1aWxkUXVldWUgPSBQcm9taXNlLnJlc29sdmUoKTtcbiAgICBwcml2YXRlIGNhY2hlSW5pdGlhbGl6ZWQgPSBmYWxzZTtcbiAgICBwcml2YXRlIGNhY2hlV3JpdGVUaW1lcjogTm9kZUpTLlRpbWVvdXQgfCBudWxsID0gbnVsbDtcbiAgICBwcml2YXRlIGRlZmVycmVkUmVidWlsZFRpbWVyOiBOb2RlSlMuVGltZW91dCB8IG51bGwgPSBudWxsO1xuICAgIHByaXZhdGUgbGFzdERlZmVycmVkQnVpbGRTaWduYXR1cmU6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG4gICAgYXN5bmMgYnVpbGQoKSB7XG4gICAgICBjb25zdCBvdXRwdXREaXIgPSBhd2FpdCB0aGlzLmZpbmRBcHBEaXJlY3RvcnkoKTtcblxuICAgICAgYXdhaXQgdGhpcy5pbml0aWFsaXplRGlzY292ZXJ5U3RhdGUoKTtcbiAgICAgIGF3YWl0IHRoaXMuY2xlYW51cEdlbmVyYXRlZEFydGlmYWN0c09uQm9vdChvdXRwdXREaXIpO1xuXG4gICAgICBhd2FpdCB0aGlzLndyaXRlU3R1YkZpbGVzKG91dHB1dERpcik7XG4gICAgICBhd2FpdCB0aGlzLmNyZWF0ZURpc2NvdmVyeVNvY2tldFNlcnZlcigpO1xuICAgIH1cblxuICAgIGFzeW5jIG9uQmVmb3JlRGVmZXJyZWRFbnRyaWVzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgYXdhaXQgdGhpcy5pbml0aWFsaXplRGlzY292ZXJ5U3RhdGUoKTtcbiAgICAgIGF3YWl0IHRoaXMudmFsaWRhdGVEaXNjb3ZlcmVkRW50cnlGaWxlcygpO1xuICAgICAgY29uc3QgaW1wbGljaXRTdGVwRmlsZXMgPSBhd2FpdCB0aGlzLnJlc29sdmVJbXBsaWNpdFN0ZXBGaWxlcygpO1xuXG4gICAgICBjb25zdCBwZW5kaW5nQnVpbGQgPSB0aGlzLmRlZmVycmVkQnVpbGRRdWV1ZS50aGVuKCgpID0+XG4gICAgICAgIHRoaXMuYnVpbGREZWZlcnJlZEVudHJpZXNVbnRpbFN0YWJsZShpbXBsaWNpdFN0ZXBGaWxlcylcbiAgICAgICk7XG5cbiAgICAgIC8vIEtlZXAgdGhlIHF1ZXVlIGNoYWluIGFsaXZlIGV2ZW4gd2hlbiB0aGUgY3VycmVudCBidWlsZCBmYWlscyBzbyBmdXR1cmVcbiAgICAgIC8vIGNhbGxiYWNrcyBjYW4gZW5xdWV1ZSBhbm90aGVyIGF0dGVtcHQgd2l0aG91dCB0cmlnZ2VyaW5nIHVuaGFuZGxlZFxuICAgICAgLy8gcmVqZWN0aW9uIHdhcm5pbmdzLlxuICAgICAgdGhpcy5kZWZlcnJlZEJ1aWxkUXVldWUgPSBwZW5kaW5nQnVpbGQuY2F0Y2goKCkgPT4ge1xuICAgICAgICAvLyBFcnJvciBpcyBzdXJmYWNlZCB0aHJvdWdoIGBwZW5kaW5nQnVpbGRgIGJlbG93LlxuICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IHBlbmRpbmdCdWlsZDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldEN1cnJlbnRJbnB1dEZpbGVzKGltcGxpY2l0U3RlcEZpbGVzOiBzdHJpbmdbXSk6IHN0cmluZ1tdIHtcbiAgICAgIHJldHVybiBBcnJheS5mcm9tKFxuICAgICAgICBuZXcgU2V0KFtcbiAgICAgICAgICAuLi50aGlzLmRpc2NvdmVyZWRXb3JrZmxvd0ZpbGVzLFxuICAgICAgICAgIC4uLnRoaXMuZGlzY292ZXJlZFN0ZXBGaWxlcyxcbiAgICAgICAgICAuLi50aGlzLmRpc2NvdmVyZWRTZXJkZUZpbGVzLFxuICAgICAgICAgIC4uLmltcGxpY2l0U3RlcEZpbGVzLFxuICAgICAgICBdKVxuICAgICAgKS5zb3J0KCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBidWlsZERlZmVycmVkRW50cmllc1VudGlsU3RhYmxlKFxuICAgICAgaW1wbGljaXRTdGVwRmlsZXM6IHN0cmluZ1tdXG4gICAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAvLyBBIHN1Y2Nlc3NmdWwgYnVpbGQgY2FuIGRpc2NvdmVyIGFkZGl0aW9uYWwgdHJhbnNpdGl2ZSBkZXBlbmRlbmN5IGZpbGVzXG4gICAgICAvLyAodmlhIHNvdXJjZSBtYXBzKSwgd2hpY2ggY2hhbmdlcyB0aGUgc2lnbmF0dXJlIGFuZCBtYXkgcmVxdWlyZSBvbmUgbW9yZVxuICAgICAgLy8gYnVpbGQgcGFzcyB0byBpbmNsdWRlIG5ld2x5IGRpc2NvdmVyZWQgc2VyZGUgZmlsZXMuXG4gICAgICBjb25zdCBtYXhCdWlsZFBhc3NlcyA9IDM7XG5cbiAgICAgIGZvciAobGV0IGJ1aWxkUGFzcyA9IDA7IGJ1aWxkUGFzcyA8IG1heEJ1aWxkUGFzc2VzOyBidWlsZFBhc3MrKykge1xuICAgICAgICBjb25zdCBpbnB1dEZpbGVzID0gdGhpcy5nZXRDdXJyZW50SW5wdXRGaWxlcyhpbXBsaWNpdFN0ZXBGaWxlcyk7XG4gICAgICAgIGNvbnN0IGJ1aWxkU2lnbmF0dXJlID1cbiAgICAgICAgICBhd2FpdCB0aGlzLmNyZWF0ZURlZmVycmVkQnVpbGRTaWduYXR1cmUoaW5wdXRGaWxlcyk7XG4gICAgICAgIGNvbnN0IHNob3VsZEZvcmNlQnVpbGRGb3JHZW5lcmF0ZWRSb3V0ZXMgPVxuICAgICAgICAgIGF3YWl0IHRoaXMuc2hvdWxkRm9yY2VCdWlsZEZvckdlbmVyYXRlZFJvdXRlcygpO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgYnVpbGRTaWduYXR1cmUgPT09IHRoaXMubGFzdERlZmVycmVkQnVpbGRTaWduYXR1cmUgJiZcbiAgICAgICAgICAhc2hvdWxkRm9yY2VCdWlsZEZvckdlbmVyYXRlZFJvdXRlc1xuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IHRoaXMuYnVpbGREaXNjb3ZlcmVkRmlsZXMoaW5wdXRGaWxlcywgaW1wbGljaXRTdGVwRmlsZXMpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGlmICh0aGlzLmNvbmZpZy53YXRjaCkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy52YWxpZGF0ZURpc2NvdmVyZWRFbnRyeUZpbGVzKCk7XG4gICAgICAgICAgICBjb25zdCByZWNvdmVyZWRJbnB1dEZpbGVzID1cbiAgICAgICAgICAgICAgdGhpcy5nZXRDdXJyZW50SW5wdXRGaWxlcyhpbXBsaWNpdFN0ZXBGaWxlcyk7XG4gICAgICAgICAgICBjb25zdCByZWNvdmVyZWRTaWduYXR1cmUgPVxuICAgICAgICAgICAgICBhd2FpdCB0aGlzLmNyZWF0ZURlZmVycmVkQnVpbGRTaWduYXR1cmUocmVjb3ZlcmVkSW5wdXRGaWxlcyk7XG4gICAgICAgICAgICBpZiAocmVjb3ZlcmVkU2lnbmF0dXJlICE9PSBidWlsZFNpZ25hdHVyZSkge1xuICAgICAgICAgICAgICAvLyBBIGZpbGUgd2FzIGFkZGVkL3JlbW92ZWQgd2hpbGUgdGhpcyBidWlsZCB3YXMgcnVubmluZzsgcmV0cnlcbiAgICAgICAgICAgICAgLy8gaW1tZWRpYXRlbHkgd2l0aCB0aGUgcmVmcmVzaGVkIGRpc2NvdmVyZWQtZW50cnkgc3RhdGUuXG4gICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICAnW3dvcmtmbG93XSBEZWZlcnJlZCBlbnRyaWVzIGJ1aWxkIGZhaWxlZC4gV2lsbCByZXRyeSBvbmx5IGFmdGVyIGlucHV0cyBjaGFuZ2UuJyxcbiAgICAgICAgICAgICAgZXJyb3JcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aGlzLmxhc3REZWZlcnJlZEJ1aWxkU2lnbmF0dXJlID0gYnVpbGRTaWduYXR1cmU7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLmxhc3REZWZlcnJlZEJ1aWxkU2lnbmF0dXJlID0gYnVpbGRTaWduYXR1cmU7XG5cbiAgICAgICAgaWYgKCF0aGlzLmNvbmZpZy53YXRjaCkge1xuICAgICAgICAgIC8vIFByb2R1Y3Rpb24gYnVpbGRzIGNhbiBwZXJzaXN0IG5ld2x5IGRpc2NvdmVyZWQgZGVmZXJyZWQtZW50cnkgZmlsZXMgdG9cbiAgICAgICAgICAvLyB0aGUgY2FjaGUgYWZ0ZXIgdGhlIGZpcnN0IHBhc3MgY29tcGxldGVzLiBSZWxvYWQgdGhhdCBjYWNoZSBiZWZvcmUgd2VcbiAgICAgICAgICAvLyBkZWNpZGUgd2hldGhlciB0aGUgaW5wdXQgc2lnbmF0dXJlIHN0YWJpbGl6ZWQgc28gc3RhZ2VkIHRhcmJhbGwgYnVpbGRzXG4gICAgICAgICAgLy8gY2FuIGltbWVkaWF0ZWx5IHJlcGxheSB3aXRoIHRoZSBleHBhbmRlZCBzdGVwIHNldC5cbiAgICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gc2V0VGltZW91dChyZXNvbHZlLCAyNTApKTtcbiAgICAgICAgICBhd2FpdCB0aGlzLmxvYWRXb3JrZmxvd3NDYWNoZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcG9zdEJ1aWxkSW5wdXRGaWxlcyA9XG4gICAgICAgICAgdGhpcy5nZXRDdXJyZW50SW5wdXRGaWxlcyhpbXBsaWNpdFN0ZXBGaWxlcyk7XG4gICAgICAgIGNvbnN0IHBvc3RCdWlsZFNpZ25hdHVyZSA9XG4gICAgICAgICAgYXdhaXQgdGhpcy5jcmVhdGVEZWZlcnJlZEJ1aWxkU2lnbmF0dXJlKHBvc3RCdWlsZElucHV0RmlsZXMpO1xuICAgICAgICBpZiAocG9zdEJ1aWxkU2lnbmF0dXJlID09PSBidWlsZFNpZ25hdHVyZSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICdbd29ya2Zsb3ddIERlZmVycmVkIGVudHJpZXMgYnVpbGQgc2lnbmF0dXJlIGRpZCBub3Qgc3RhYmlsaXplIGFmdGVyIDMgcGFzc2VzLidcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyByZXNvbHZlSW1wbGljaXRTdGVwRmlsZXMoKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgICAgY29uc3Qgd29ya2Zsb3dTdGRsaWJQYXRoID0gdGhpcy5yZXNvbHZlV29ya2Zsb3dTdGRsaWJTdGVwRmlsZVBhdGgoKTtcbiAgICAgIHJldHVybiB3b3JrZmxvd1N0ZGxpYlBhdGggPyBbd29ya2Zsb3dTdGRsaWJQYXRoXSA6IFtdO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgc2hvdWxkRm9yY2VCdWlsZEZvckdlbmVyYXRlZFJvdXRlcygpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAgIGNvbnN0IG91dHB1dERpciA9IGF3YWl0IHRoaXMuZmluZEFwcERpcmVjdG9yeSgpO1xuICAgICAgY29uc3QgZ2VuZXJhdGVkUm91dGVGaWxlcyA9IFtcbiAgICAgICAgam9pbihvdXRwdXREaXIsICcud2VsbC1rbm93bi93b3JrZmxvdy92MS9mbG93L3JvdXRlLmpzJyksXG4gICAgICAgIGpvaW4ob3V0cHV0RGlyLCAnLndlbGwta25vd24vd29ya2Zsb3cvdjEvd2ViaG9vay9bdG9rZW5dL3JvdXRlLmpzJyksXG4gICAgICBdO1xuXG4gICAgICBmb3IgKGNvbnN0IHJvdXRlRmlsZVBhdGggb2YgZ2VuZXJhdGVkUm91dGVGaWxlcykge1xuICAgICAgICBjb25zdCByb3V0ZVN0YXRlID0gYXdhaXQgdGhpcy5nZXRHZW5lcmF0ZWRSb3V0ZVN0YXRlKHJvdXRlRmlsZVBhdGgpO1xuICAgICAgICBpZiAocm91dGVTdGF0ZSA9PT0gJ21pc3NpbmcnIHx8IHJvdXRlU3RhdGUgPT09ICdzdHViJykge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGdldEdlbmVyYXRlZFJvdXRlU3RhdGUoXG4gICAgICByb3V0ZUZpbGVQYXRoOiBzdHJpbmdcbiAgICApOiBQcm9taXNlPCdtaXNzaW5nJyB8ICdzdHViJyB8ICdnZW5lcmF0ZWQnPiB7XG4gICAgICBsZXQgcm91dGVTdGF0cztcbiAgICAgIHRyeSB7XG4gICAgICAgIHJvdXRlU3RhdHMgPSBhd2FpdCBzdGF0KHJvdXRlRmlsZVBhdGgpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHJldHVybiAnbWlzc2luZyc7XG4gICAgICB9XG4gICAgICBpZiAoIXJvdXRlU3RhdHMuaXNGaWxlKCkpIHtcbiAgICAgICAgcmV0dXJuICdtaXNzaW5nJztcbiAgICAgIH1cblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3Qgcm91dGVGaWxlSGFuZGxlID0gYXdhaXQgb3Blbihyb3V0ZUZpbGVQYXRoLCAncicpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IG1hcmtlclNjYW5CdWZmZXIgPSBCdWZmZXIuYWxsb2MoUk9VVEVfU1RVQl9NQVJLRVJfU0NBTl9CWVRFUyk7XG4gICAgICAgICAgY29uc3QgeyBieXRlc1JlYWQgfSA9IGF3YWl0IHJvdXRlRmlsZUhhbmRsZS5yZWFkKFxuICAgICAgICAgICAgbWFya2VyU2NhbkJ1ZmZlcixcbiAgICAgICAgICAgIDAsXG4gICAgICAgICAgICBST1VURV9TVFVCX01BUktFUl9TQ0FOX0JZVEVTLFxuICAgICAgICAgICAgMFxuICAgICAgICAgICk7XG4gICAgICAgICAgY29uc3QgbWFya2VyU2NhblNvdXJjZSA9IG1hcmtlclNjYW5CdWZmZXIudG9TdHJpbmcoXG4gICAgICAgICAgICAndXRmOCcsXG4gICAgICAgICAgICAwLFxuICAgICAgICAgICAgYnl0ZXNSZWFkXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm4gbWFya2VyU2NhblNvdXJjZS5pbmNsdWRlcyhST1VURV9TVFVCX0ZJTEVfTUFSS0VSKVxuICAgICAgICAgICAgPyAnc3R1YidcbiAgICAgICAgICAgIDogJ2dlbmVyYXRlZCc7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgYXdhaXQgcm91dGVGaWxlSGFuZGxlLmNsb3NlKCk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICByZXR1cm4gJ21pc3NpbmcnO1xuICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgcmVzb2x2ZVdvcmtmbG93U3RkbGliU3RlcEZpbGVQYXRoKCk6IHN0cmluZyB8IG51bGwge1xuICAgICAgbGV0IHdvcmtmbG93Q2pzRW50cnk6IHN0cmluZztcbiAgICAgIHRyeSB7XG4gICAgICAgIHdvcmtmbG93Q2pzRW50cnkgPSByZXF1aXJlLnJlc29sdmUoJ3dvcmtmbG93Jywge1xuICAgICAgICAgIHBhdGhzOiBbdGhpcy5jb25maWcud29ya2luZ0Rpcl0sXG4gICAgICAgIH0pO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB3b3JrZmxvd0Rpc3REaXIgPSBkaXJuYW1lKHdvcmtmbG93Q2pzRW50cnkpO1xuICAgICAgY29uc3Qgd29ya2Zsb3dTdGRsaWJQYXRoID0gdGhpcy5ub3JtYWxpemVEaXNjb3ZlcmVkRmlsZVBhdGgoXG4gICAgICAgIGpvaW4od29ya2Zsb3dEaXN0RGlyLCAnc3RkbGliLmpzJylcbiAgICAgICk7XG4gICAgICByZXR1cm4gZXhpc3RzU3luYyh3b3JrZmxvd1N0ZGxpYlBhdGgpID8gd29ya2Zsb3dTdGRsaWJQYXRoIDogbnVsbDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIHJlY29uY2lsZURpc2NvdmVyZWRFbnRyaWVzKHtcbiAgICAgIHdvcmtmbG93Q2FuZGlkYXRlcyxcbiAgICAgIHN0ZXBDYW5kaWRhdGVzLFxuICAgICAgc2VyZGVDYW5kaWRhdGVzLFxuICAgICAgdmFsaWRhdGVQYXR0ZXJucyxcbiAgICB9OiB7XG4gICAgICB3b3JrZmxvd0NhbmRpZGF0ZXM6IEl0ZXJhYmxlPHN0cmluZz47XG4gICAgICBzdGVwQ2FuZGlkYXRlczogSXRlcmFibGU8c3RyaW5nPjtcbiAgICAgIHNlcmRlQ2FuZGlkYXRlcz86IEl0ZXJhYmxlPHN0cmluZz47XG4gICAgICB2YWxpZGF0ZVBhdHRlcm5zOiBib29sZWFuO1xuICAgIH0pOiBQcm9taXNlPHtcbiAgICAgIHdvcmtmbG93RmlsZXM6IFNldDxzdHJpbmc+O1xuICAgICAgc3RlcEZpbGVzOiBTZXQ8c3RyaW5nPjtcbiAgICAgIHNlcmRlRmlsZXM6IFNldDxzdHJpbmc+O1xuICAgIH0+IHtcbiAgICAgIGNvbnN0IGNhbmRpZGF0ZXNCeUZpbGUgPSBuZXcgTWFwPFxuICAgICAgICBzdHJpbmcsXG4gICAgICAgIHtcbiAgICAgICAgICBoYXNXb3JrZmxvd0NhbmRpZGF0ZTogYm9vbGVhbjtcbiAgICAgICAgICBoYXNTdGVwQ2FuZGlkYXRlOiBib29sZWFuO1xuICAgICAgICAgIGhhc1NlcmRlQ2FuZGlkYXRlOiBib29sZWFuO1xuICAgICAgICB9XG4gICAgICA+KCk7XG5cbiAgICAgIGZvciAoY29uc3QgZmlsZVBhdGggb2Ygd29ya2Zsb3dDYW5kaWRhdGVzKSB7XG4gICAgICAgIGNvbnN0IG5vcm1hbGl6ZWRQYXRoID0gdGhpcy5ub3JtYWxpemVEaXNjb3ZlcmVkRmlsZVBhdGgoZmlsZVBhdGgpO1xuICAgICAgICBjb25zdCBleGlzdGluZyA9IGNhbmRpZGF0ZXNCeUZpbGUuZ2V0KG5vcm1hbGl6ZWRQYXRoKTtcbiAgICAgICAgaWYgKGV4aXN0aW5nKSB7XG4gICAgICAgICAgZXhpc3RpbmcuaGFzV29ya2Zsb3dDYW5kaWRhdGUgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNhbmRpZGF0ZXNCeUZpbGUuc2V0KG5vcm1hbGl6ZWRQYXRoLCB7XG4gICAgICAgICAgICBoYXNXb3JrZmxvd0NhbmRpZGF0ZTogdHJ1ZSxcbiAgICAgICAgICAgIGhhc1N0ZXBDYW5kaWRhdGU6IGZhbHNlLFxuICAgICAgICAgICAgaGFzU2VyZGVDYW5kaWRhdGU6IGZhbHNlLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgZmlsZVBhdGggb2Ygc3RlcENhbmRpZGF0ZXMpIHtcbiAgICAgICAgY29uc3Qgbm9ybWFsaXplZFBhdGggPSB0aGlzLm5vcm1hbGl6ZURpc2NvdmVyZWRGaWxlUGF0aChmaWxlUGF0aCk7XG4gICAgICAgIGNvbnN0IGV4aXN0aW5nID0gY2FuZGlkYXRlc0J5RmlsZS5nZXQobm9ybWFsaXplZFBhdGgpO1xuICAgICAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgICAgICBleGlzdGluZy5oYXNTdGVwQ2FuZGlkYXRlID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjYW5kaWRhdGVzQnlGaWxlLnNldChub3JtYWxpemVkUGF0aCwge1xuICAgICAgICAgICAgaGFzV29ya2Zsb3dDYW5kaWRhdGU6IGZhbHNlLFxuICAgICAgICAgICAgaGFzU3RlcENhbmRpZGF0ZTogdHJ1ZSxcbiAgICAgICAgICAgIGhhc1NlcmRlQ2FuZGlkYXRlOiBmYWxzZSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoc2VyZGVDYW5kaWRhdGVzKSB7XG4gICAgICAgIGZvciAoY29uc3QgZmlsZVBhdGggb2Ygc2VyZGVDYW5kaWRhdGVzKSB7XG4gICAgICAgICAgY29uc3Qgbm9ybWFsaXplZFBhdGggPSB0aGlzLm5vcm1hbGl6ZURpc2NvdmVyZWRGaWxlUGF0aChmaWxlUGF0aCk7XG4gICAgICAgICAgY29uc3QgZXhpc3RpbmcgPSBjYW5kaWRhdGVzQnlGaWxlLmdldChub3JtYWxpemVkUGF0aCk7XG4gICAgICAgICAgaWYgKGV4aXN0aW5nKSB7XG4gICAgICAgICAgICBleGlzdGluZy5oYXNTZXJkZUNhbmRpZGF0ZSA9IHRydWU7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNhbmRpZGF0ZXNCeUZpbGUuc2V0KG5vcm1hbGl6ZWRQYXRoLCB7XG4gICAgICAgICAgICAgIGhhc1dvcmtmbG93Q2FuZGlkYXRlOiBmYWxzZSxcbiAgICAgICAgICAgICAgaGFzU3RlcENhbmRpZGF0ZTogZmFsc2UsXG4gICAgICAgICAgICAgIGhhc1NlcmRlQ2FuZGlkYXRlOiB0cnVlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGZpbGVFbnRyaWVzID0gQXJyYXkuZnJvbShjYW5kaWRhdGVzQnlGaWxlLmVudHJpZXMoKSkuc29ydChcbiAgICAgICAgKFthXSwgW2JdKSA9PiBhLmxvY2FsZUNvbXBhcmUoYilcbiAgICAgICk7XG4gICAgICBjb25zdCB2YWxpZGF0ZWRFbnRyaWVzID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgIGZpbGVFbnRyaWVzLm1hcChhc3luYyAoW2ZpbGVQYXRoLCBjYW5kaWRhdGVzXSkgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBmaWxlU3RhdHMgPSBhd2FpdCBzdGF0KGZpbGVQYXRoKTtcbiAgICAgICAgICAgIGlmICghZmlsZVN0YXRzLmlzRmlsZSgpKSB7XG4gICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIXZhbGlkYXRlUGF0dGVybnMpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBmaWxlUGF0aCxcbiAgICAgICAgICAgICAgICBoYXNVc2VXb3JrZmxvdzogY2FuZGlkYXRlcy5oYXNXb3JrZmxvd0NhbmRpZGF0ZSxcbiAgICAgICAgICAgICAgICBoYXNVc2VTdGVwOiBjYW5kaWRhdGVzLmhhc1N0ZXBDYW5kaWRhdGUsXG4gICAgICAgICAgICAgICAgaGFzU2VyZGU6IGNhbmRpZGF0ZXMuaGFzU2VyZGVDYW5kaWRhdGUsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHNvdXJjZSA9IGF3YWl0IHJlYWRGaWxlKGZpbGVQYXRoLCAndXRmLTgnKTtcbiAgICAgICAgICAgIGNvbnN0IHBhdHRlcm5zID0gZGV0ZWN0V29ya2Zsb3dQYXR0ZXJucyhzb3VyY2UpO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgZmlsZVBhdGgsXG4gICAgICAgICAgICAgIGhhc1VzZVdvcmtmbG93OiBwYXR0ZXJucy5oYXNVc2VXb3JrZmxvdyxcbiAgICAgICAgICAgICAgaGFzVXNlU3RlcDogcGF0dGVybnMuaGFzVXNlU3RlcCxcbiAgICAgICAgICAgICAgaGFzU2VyZGU6IHBhdHRlcm5zLmhhc1NlcmRlLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IHdvcmtmbG93RmlsZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICAgIGNvbnN0IHN0ZXBGaWxlcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgICAgY29uc3Qgc2VyZGVGaWxlcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiB2YWxpZGF0ZWRFbnRyaWVzKSB7XG4gICAgICAgIGlmICghZW50cnkpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZW50cnkuaGFzVXNlV29ya2Zsb3cpIHtcbiAgICAgICAgICB3b3JrZmxvd0ZpbGVzLmFkZChlbnRyeS5maWxlUGF0aCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVudHJ5Lmhhc1VzZVN0ZXApIHtcbiAgICAgICAgICBzdGVwRmlsZXMuYWRkKGVudHJ5LmZpbGVQYXRoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZW50cnkuaGFzU2VyZGUpIHtcbiAgICAgICAgICBzZXJkZUZpbGVzLmFkZChlbnRyeS5maWxlUGF0aCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHsgd29ya2Zsb3dGaWxlcywgc3RlcEZpbGVzLCBzZXJkZUZpbGVzIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyB2YWxpZGF0ZURpc2NvdmVyZWRFbnRyeUZpbGVzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgY29uc3Qgd29ya2Zsb3dDYW5kaWRhdGVzID0gbmV3IFNldCh0aGlzLmRpc2NvdmVyZWRXb3JrZmxvd0ZpbGVzKTtcbiAgICAgIGNvbnN0IHN0ZXBDYW5kaWRhdGVzID0gbmV3IFNldCh0aGlzLmRpc2NvdmVyZWRTdGVwRmlsZXMpO1xuICAgICAgY29uc3Qgc2VyZGVDYW5kaWRhdGVzID0gbmV3IFNldCh0aGlzLmRpc2NvdmVyZWRTZXJkZUZpbGVzKTtcbiAgICAgIGNvbnN0IHsgd29ya2Zsb3dGaWxlcywgc3RlcEZpbGVzLCBzZXJkZUZpbGVzIH0gPVxuICAgICAgICBhd2FpdCB0aGlzLnJlY29uY2lsZURpc2NvdmVyZWRFbnRyaWVzKHtcbiAgICAgICAgICB3b3JrZmxvd0NhbmRpZGF0ZXMsXG4gICAgICAgICAgc3RlcENhbmRpZGF0ZXMsXG4gICAgICAgICAgc2VyZGVDYW5kaWRhdGVzLFxuICAgICAgICAgIHZhbGlkYXRlUGF0dGVybnM6IHRydWUsXG4gICAgICAgIH0pO1xuXG4gICAgICAvLyBSZWNvbmNpbGUgdmFsaWRhdGVkIGVudHJpZXMgYWdhaW5zdCB0aGUgc25hcHNob3Qgd2Ugc3RhcnRlZCB3aXRoIHNvXG4gICAgICAvLyBmaWxlIGRpc2NvdmVyaWVzIHRoYXQgYXJyaXZlIGR1cmluZyB2YWxpZGF0aW9uIGFyZSBwcmVzZXJ2ZWQuXG4gICAgICBsZXQgd29ya2Zsb3dzQ2hhbmdlZCA9IGZhbHNlO1xuICAgICAgbGV0IHN0ZXBzQ2hhbmdlZCA9IGZhbHNlO1xuICAgICAgbGV0IHNlcmRlQ2hhbmdlZCA9IGZhbHNlO1xuXG4gICAgICBmb3IgKGNvbnN0IGZpbGVQYXRoIG9mIHdvcmtmbG93Q2FuZGlkYXRlcykge1xuICAgICAgICBpZiAoIXdvcmtmbG93RmlsZXMuaGFzKGZpbGVQYXRoKSkge1xuICAgICAgICAgIHdvcmtmbG93c0NoYW5nZWQgPVxuICAgICAgICAgICAgdGhpcy5kaXNjb3ZlcmVkV29ya2Zsb3dGaWxlcy5kZWxldGUoZmlsZVBhdGgpIHx8IHdvcmtmbG93c0NoYW5nZWQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3QgZmlsZVBhdGggb2Ygd29ya2Zsb3dGaWxlcykge1xuICAgICAgICBpZiAoIXRoaXMuZGlzY292ZXJlZFdvcmtmbG93RmlsZXMuaGFzKGZpbGVQYXRoKSkge1xuICAgICAgICAgIHRoaXMuZGlzY292ZXJlZFdvcmtmbG93RmlsZXMuYWRkKGZpbGVQYXRoKTtcbiAgICAgICAgICB3b3JrZmxvd3NDaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IGZpbGVQYXRoIG9mIHN0ZXBDYW5kaWRhdGVzKSB7XG4gICAgICAgIGlmICghc3RlcEZpbGVzLmhhcyhmaWxlUGF0aCkpIHtcbiAgICAgICAgICBzdGVwc0NoYW5nZWQgPVxuICAgICAgICAgICAgdGhpcy5kaXNjb3ZlcmVkU3RlcEZpbGVzLmRlbGV0ZShmaWxlUGF0aCkgfHwgc3RlcHNDaGFuZ2VkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IGZpbGVQYXRoIG9mIHN0ZXBGaWxlcykge1xuICAgICAgICBpZiAoIXRoaXMuZGlzY292ZXJlZFN0ZXBGaWxlcy5oYXMoZmlsZVBhdGgpKSB7XG4gICAgICAgICAgdGhpcy5kaXNjb3ZlcmVkU3RlcEZpbGVzLmFkZChmaWxlUGF0aCk7XG4gICAgICAgICAgc3RlcHNDaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IGZpbGVQYXRoIG9mIHNlcmRlQ2FuZGlkYXRlcykge1xuICAgICAgICBpZiAoIXNlcmRlRmlsZXMuaGFzKGZpbGVQYXRoKSkge1xuICAgICAgICAgIHNlcmRlQ2hhbmdlZCA9XG4gICAgICAgICAgICB0aGlzLmRpc2NvdmVyZWRTZXJkZUZpbGVzLmRlbGV0ZShmaWxlUGF0aCkgfHwgc2VyZGVDaGFuZ2VkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IGZpbGVQYXRoIG9mIHNlcmRlRmlsZXMpIHtcbiAgICAgICAgaWYgKCF0aGlzLmRpc2NvdmVyZWRTZXJkZUZpbGVzLmhhcyhmaWxlUGF0aCkpIHtcbiAgICAgICAgICB0aGlzLmRpc2NvdmVyZWRTZXJkZUZpbGVzLmFkZChmaWxlUGF0aCk7XG4gICAgICAgICAgc2VyZGVDaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAod29ya2Zsb3dzQ2hhbmdlZCB8fCBzdGVwc0NoYW5nZWQpIHtcbiAgICAgICAgdGhpcy5zY2hlZHVsZVdvcmtmbG93c0NhY2hlV3JpdGUoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGJ1aWxkRGlzY292ZXJlZEZpbGVzKFxuICAgICAgaW5wdXRGaWxlczogc3RyaW5nW10sXG4gICAgICBpbXBsaWNpdFN0ZXBGaWxlczogc3RyaW5nW11cbiAgICApIHtcbiAgICAgIGNvbnN0IG91dHB1dERpciA9IGF3YWl0IHRoaXMuZmluZEFwcERpcmVjdG9yeSgpO1xuICAgICAgY29uc3Qgd29ya2Zsb3dHZW5lcmF0ZWREaXIgPSBqb2luKG91dHB1dERpciwgJy53ZWxsLWtub3duL3dvcmtmbG93L3YxJyk7XG4gICAgICBjb25zdCBjYWNoZURpciA9IGpvaW4odGhpcy5jb25maWcud29ya2luZ0RpciwgdGhpcy5nZXREaXN0RGlyKCksICdjYWNoZScpO1xuICAgICAgYXdhaXQgbWtkaXIoY2FjaGVEaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgY29uc3QgbWFuaWZlc3RCdWlsZERpciA9IGpvaW4oY2FjaGVEaXIsICd3b3JrZmxvdy1nZW5lcmF0ZWQtbWFuaWZlc3QnKTtcbiAgICAgIGNvbnN0IHRlbXBSb3V0ZUZpbGVOYW1lID0gJ3JvdXRlLmpzLnRlbXAnO1xuICAgICAgY29uc3QgdHJhY2tlZERpc2NvdmVyZWRFbnRyaWVzID1cbiAgICAgICAgYXdhaXQgdGhpcy5jb2xsZWN0VHJhY2tlZERpc2NvdmVyZWRFbnRyaWVzKCk7XG4gICAgICBjb25zdCBkaXNjb3ZlcmVkU3RlcEZpbGVDYW5kaWRhdGVzID0gQXJyYXkuZnJvbShcbiAgICAgICAgbmV3IFNldChbXG4gICAgICAgICAgLi4udGhpcy5kaXNjb3ZlcmVkU3RlcEZpbGVzLFxuICAgICAgICAgIC4uLnRyYWNrZWREaXNjb3ZlcmVkRW50cmllcy5kaXNjb3ZlcmVkU3RlcHMsXG4gICAgICAgICAgLi4uaW1wbGljaXRTdGVwRmlsZXMsXG4gICAgICAgIF0pXG4gICAgICApLnNvcnQoKTtcbiAgICAgIGNvbnN0IGRpc2NvdmVyZWRXb3JrZmxvd0ZpbGVDYW5kaWRhdGVzID0gQXJyYXkuZnJvbShcbiAgICAgICAgbmV3IFNldChbXG4gICAgICAgICAgLi4udGhpcy5kaXNjb3ZlcmVkV29ya2Zsb3dGaWxlcyxcbiAgICAgICAgICAuLi50cmFja2VkRGlzY292ZXJlZEVudHJpZXMuZGlzY292ZXJlZFdvcmtmbG93cyxcbiAgICAgICAgXSlcbiAgICAgICkuc29ydCgpO1xuICAgICAgY29uc3QgZGlzY292ZXJlZFNlcmRlRmlsZUNhbmRpZGF0ZXMgPSBBcnJheS5mcm9tKFxuICAgICAgICBuZXcgU2V0KFtcbiAgICAgICAgICAuLi50aGlzLmRpc2NvdmVyZWRTZXJkZUZpbGVzLFxuICAgICAgICAgIC4uLnRyYWNrZWREaXNjb3ZlcmVkRW50cmllcy5kaXNjb3ZlcmVkU2VyZGVGaWxlcyxcbiAgICAgICAgXSlcbiAgICAgICkuc29ydCgpO1xuICAgICAgY29uc3QgZGlzY292ZXJlZFdvcmtmbG93RmlsZXMgPSBhd2FpdCB0aGlzLmZpbHRlckV4aXN0aW5nRmlsZXMoXG4gICAgICAgIGRpc2NvdmVyZWRXb3JrZmxvd0ZpbGVDYW5kaWRhdGVzXG4gICAgICApO1xuICAgICAgY29uc3QgZXhpc3RpbmdTdGVwRmlsZUNhbmRpZGF0ZXMgPSBhd2FpdCB0aGlzLmZpbHRlckV4aXN0aW5nRmlsZXMoXG4gICAgICAgIGRpc2NvdmVyZWRTdGVwRmlsZUNhbmRpZGF0ZXNcbiAgICAgICk7XG4gICAgICBjb25zdCBkaXNjb3ZlcmVkU3RlcEZpbGVzID0gYXdhaXQgdGhpcy5jb2xsZWN0VHJhbnNpdGl2ZVN0ZXBGaWxlcyh7XG4gICAgICAgIGVudHJ5RmlsZXM6IFsuLi5leGlzdGluZ1N0ZXBGaWxlQ2FuZGlkYXRlcywgLi4uZGlzY292ZXJlZFdvcmtmbG93RmlsZXNdLFxuICAgICAgICBzdGVwRmlsZXM6IGV4aXN0aW5nU3RlcEZpbGVDYW5kaWRhdGVzLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBleGlzdGluZ1NlcmRlRmlsZUNhbmRpZGF0ZXMgPSBhd2FpdCB0aGlzLmZpbHRlckV4aXN0aW5nRmlsZXMoXG4gICAgICAgIGRpc2NvdmVyZWRTZXJkZUZpbGVDYW5kaWRhdGVzXG4gICAgICApO1xuICAgICAgY29uc3QgZGlzY292ZXJlZFNlcmRlRmlsZXMgPSBhd2FpdCB0aGlzLmNvbGxlY3RUcmFuc2l0aXZlU2VyZGVGaWxlcyh7XG4gICAgICAgIGVudHJ5RmlsZXM6IFsuLi5kaXNjb3ZlcmVkU3RlcEZpbGVzLCAuLi5kaXNjb3ZlcmVkV29ya2Zsb3dGaWxlc10sXG4gICAgICAgIHNlcmRlRmlsZXM6IGV4aXN0aW5nU2VyZGVGaWxlQ2FuZGlkYXRlcyxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgZXhpc3RpbmdJbnB1dEZpbGVzID0gYXdhaXQgdGhpcy5maWx0ZXJFeGlzdGluZ0ZpbGVzKGlucHV0RmlsZXMpO1xuICAgICAgY29uc3QgYnVpbGRJbnB1dEZpbGVzID0gQXJyYXkuZnJvbShcbiAgICAgICAgbmV3IFNldChbXG4gICAgICAgICAgLi4uZXhpc3RpbmdJbnB1dEZpbGVzLFxuICAgICAgICAgIC4uLmRpc2NvdmVyZWRTdGVwRmlsZXMsXG4gICAgICAgICAgLi4uZGlzY292ZXJlZFdvcmtmbG93RmlsZXMsXG4gICAgICAgICAgLi4uZGlzY292ZXJlZFNlcmRlRmlsZXMsXG4gICAgICAgIF0pXG4gICAgICApLnNvcnQoKTtcbiAgICAgIGNvbnN0IGRpc2NvdmVyZWRFbnRyaWVzID0ge1xuICAgICAgICBkaXNjb3ZlcmVkU3RlcHM6IG5ldyBTZXQoZGlzY292ZXJlZFN0ZXBGaWxlcyksXG4gICAgICAgIGRpc2NvdmVyZWRXb3JrZmxvd3M6IG5ldyBTZXQoZGlzY292ZXJlZFdvcmtmbG93RmlsZXMpLFxuICAgICAgICBkaXNjb3ZlcmVkU2VyZGVGaWxlczogbmV3IFNldChkaXNjb3ZlcmVkU2VyZGVGaWxlcyksXG4gICAgICB9O1xuXG4gICAgICAvLyBFbnN1cmUgb3V0cHV0IGRpcmVjdG9yaWVzIGV4aXN0XG4gICAgICBhd2FpdCBta2Rpcih3b3JrZmxvd0dlbmVyYXRlZERpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG5cbiAgICAgIGF3YWl0IHRoaXMud3JpdGVGaWxlSWZDaGFuZ2VkKFxuICAgICAgICBqb2luKHdvcmtmbG93R2VuZXJhdGVkRGlyLCAnLmdpdGlnbm9yZScpLFxuICAgICAgICAnKidcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IHRzY29uZmlnUGF0aCA9IGF3YWl0IHRoaXMuZmluZFRzQ29uZmlnUGF0aCgpO1xuXG4gICAgICAvLyBWMjogQnVpbGQgY29tYmluZWQgcm91dGUgKHJlcGxhY2VzIHNlcGFyYXRlIHN0ZXAgKyBmbG93IHJvdXRlcylcbiAgICAgIGNvbnN0IGZsb3dSb3V0ZURpciA9IGpvaW4od29ya2Zsb3dHZW5lcmF0ZWREaXIsICdmbG93Jyk7XG4gICAgICBhd2FpdCBta2RpcihmbG93Um91dGVEaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgLy8gV3JpdGUgc3RlcCByZWdpc3RyYXRpb25zIHRvIGZpbmFsIG5hbWUgZGlyZWN0bHkgKG5vdCB0ZW1wKSBzbyB0aGVcbiAgICAgIC8vIGltcG9ydCBwYXRoIGluIHRoZSBmbG93IHJvdXRlIGlzIGNvcnJlY3QuIFRoZSBmbG93IHJvdXRlIHVzZXMgdGVtcFxuICAgICAgLy8gbmFtaW5nIHRvIGF2b2lkIEhNUiBjaHVybiB2aWEgY29weUZpbGVJZkNoYW5nZWQsIGJ1dCB0aGUgc3RlcFxuICAgICAgLy8gcmVnaXN0cmF0aW9ucyBmaWxlIGlzIGEgc2lkZS1lZmZlY3QgaW1wb3J0IGFuZCBkb2Vzbid0IG5lZWQgdGhhdC5cbiAgICAgIGNvbnN0IHN0ZXBzT3V0ZmlsZSA9IGpvaW4oZmxvd1JvdXRlRGlyLCAnX19zdGVwX3JlZ2lzdHJhdGlvbnMuanMnKTtcbiAgICAgIGNvbnN0IGNvbWJpbmVkUmVzdWx0ID0gYXdhaXQgdGhpcy5jcmVhdGVDb21iaW5lZEJ1bmRsZSh7XG4gICAgICAgIGZvcm1hdDogJ2VzbScsXG4gICAgICAgIGlucHV0RmlsZXM6IGJ1aWxkSW5wdXRGaWxlcyxcbiAgICAgICAgc3RlcHNPdXRmaWxlLFxuICAgICAgICBmbG93T3V0ZmlsZTogam9pbihmbG93Um91dGVEaXIsIHRlbXBSb3V0ZUZpbGVOYW1lKSxcbiAgICAgICAgYnVuZGxlRmluYWxPdXRwdXQ6IGZhbHNlLFxuICAgICAgICBleHRlcm5hbGl6ZU5vblN0ZXBzOiB0cnVlLFxuICAgICAgICB0c2NvbmZpZ1BhdGgsXG4gICAgICAgIGRpc2NvdmVyZWRFbnRyaWVzLFxuICAgICAgfSk7XG4gICAgICBhd2FpdCB0aGlzLmJ1aWxkV2ViaG9va1JvdXRlKHtcbiAgICAgICAgd29ya2Zsb3dHZW5lcmF0ZWREaXIsXG4gICAgICAgIHJvdXRlRmlsZU5hbWU6IHRlbXBSb3V0ZUZpbGVOYW1lLFxuICAgICAgfSk7XG4gICAgICBhd2FpdCB0aGlzLnJlZnJlc2hUcmFja2VkRGVwZW5kZW5jeUZpbGVzKFxuICAgICAgICB3b3JrZmxvd0dlbmVyYXRlZERpcixcbiAgICAgICAgdGVtcFJvdXRlRmlsZU5hbWVcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IG1hbmlmZXN0ID0ge1xuICAgICAgICBzdGVwczogeyAuLi5jb21iaW5lZFJlc3VsdD8ubWFuaWZlc3Q/LnN0ZXBzIH0sXG4gICAgICAgIHdvcmtmbG93czogeyAuLi5jb21iaW5lZFJlc3VsdD8ubWFuaWZlc3Q/LndvcmtmbG93cyB9LFxuICAgICAgICBjbGFzc2VzOiB7IC4uLmNvbWJpbmVkUmVzdWx0Py5tYW5pZmVzdD8uY2xhc3NlcyB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgbWFuaWZlc3RGaWxlUGF0aCA9IGpvaW4od29ya2Zsb3dHZW5lcmF0ZWREaXIsICdtYW5pZmVzdC5qc29uJyk7XG4gICAgICBjb25zdCBtYW5pZmVzdEJ1aWxkUGF0aCA9IGpvaW4obWFuaWZlc3RCdWlsZERpciwgJ21hbmlmZXN0Lmpzb24nKTtcbiAgICAgIGNvbnN0IHdvcmtmbG93QnVuZGxlUGF0aCA9IGpvaW4oXG4gICAgICAgIHdvcmtmbG93R2VuZXJhdGVkRGlyLFxuICAgICAgICBgZmxvdy8ke3RlbXBSb3V0ZUZpbGVOYW1lfWBcbiAgICAgICk7XG4gICAgICBjb25zdCBtYW5pZmVzdEpzb24gPSBhd2FpdCB0aGlzLmNyZWF0ZU1hbmlmZXN0KHtcbiAgICAgICAgd29ya2Zsb3dCdW5kbGVQYXRoLFxuICAgICAgICBtYW5pZmVzdERpcjogbWFuaWZlc3RCdWlsZERpcixcbiAgICAgICAgbWFuaWZlc3QsXG4gICAgICB9KTtcbiAgICAgIGlmIChtYW5pZmVzdEpzb24pIHtcbiAgICAgICAgYXdhaXQgdGhpcy5yZXdyaXRlSnNvbkZpbGVXaXRoU3RhYmxlS2V5T3JkZXIobWFuaWZlc3RCdWlsZFBhdGgpO1xuICAgICAgICBhd2FpdCB0aGlzLmNvcHlGaWxlSWZDaGFuZ2VkKG1hbmlmZXN0QnVpbGRQYXRoLCBtYW5pZmVzdEZpbGVQYXRoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGF3YWl0IHJtKG1hbmlmZXN0QnVpbGRQYXRoLCB7IGZvcmNlOiB0cnVlIH0pO1xuICAgICAgICBhd2FpdCBybShtYW5pZmVzdEZpbGVQYXRoLCB7IGZvcmNlOiB0cnVlIH0pO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCB0aGlzLndyaXRlRnVuY3Rpb25zQ29uZmlnKG91dHB1dERpcik7XG5cbiAgICAgIC8vIFYyOiBDb21iaW5lZCByb3V0ZSAoZmxvdykg4oCUIHN0ZXAgcmVnaXN0cmF0aW9ucyBhbHJlYWR5IGF0IGZpbmFsIHBhdGhcbiAgICAgIGF3YWl0IHRoaXMuY29weUZpbGVJZkNoYW5nZWQoXG4gICAgICAgIGpvaW4od29ya2Zsb3dHZW5lcmF0ZWREaXIsIGBmbG93LyR7dGVtcFJvdXRlRmlsZU5hbWV9YCksXG4gICAgICAgIGpvaW4od29ya2Zsb3dHZW5lcmF0ZWREaXIsICdmbG93L3JvdXRlLmpzJylcbiAgICAgICk7XG4gICAgICBhd2FpdCB0aGlzLmNvcHlGaWxlSWZDaGFuZ2VkKFxuICAgICAgICBqb2luKHdvcmtmbG93R2VuZXJhdGVkRGlyLCBgd2ViaG9vay9bdG9rZW5dLyR7dGVtcFJvdXRlRmlsZU5hbWV9YCksXG4gICAgICAgIGpvaW4od29ya2Zsb3dHZW5lcmF0ZWREaXIsICd3ZWJob29rL1t0b2tlbl0vcm91dGUuanMnKVxuICAgICAgKTtcblxuICAgICAgLy8gRXhwb3NlIG1hbmlmZXN0IGFzIGEgc3RhdGljIGZpbGUgd2hlbiBXT1JLRkxPV19QVUJMSUNfTUFOSUZFU1Q9MS5cbiAgICAgIC8vIE5leHQuanMgc2VydmVzIGZpbGVzIGZyb20gcHVibGljLyBhdCB0aGUgcm9vdCBVUkwuXG4gICAgICBpZiAodGhpcy5zaG91bGRFeHBvc2VQdWJsaWNNYW5pZmVzdCAmJiBtYW5pZmVzdEpzb24pIHtcbiAgICAgICAgY29uc3QgcHVibGljTWFuaWZlc3REaXIgPSBqb2luKFxuICAgICAgICAgIHRoaXMuY29uZmlnLndvcmtpbmdEaXIsXG4gICAgICAgICAgJ3B1YmxpYy8ud2VsbC1rbm93bi93b3JrZmxvdy92MSdcbiAgICAgICAgKTtcbiAgICAgICAgYXdhaXQgbWtkaXIocHVibGljTWFuaWZlc3REaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgICBpZiAocHJvY2Vzcy5lbnYuVkVSQ0VMX0RFUExPWU1FTlRfSUQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGF3YWl0IHRoaXMud3JpdGVGaWxlSWZDaGFuZ2VkKFxuICAgICAgICAgICAgam9pbihwdWJsaWNNYW5pZmVzdERpciwgJy5naXRpZ25vcmUnKSxcbiAgICAgICAgICAgICcqJ1xuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgdGhpcy5jb3B5RmlsZUlmQ2hhbmdlZChcbiAgICAgICAgICBtYW5pZmVzdEZpbGVQYXRoLFxuICAgICAgICAgIGpvaW4ocHVibGljTWFuaWZlc3REaXIsICdtYW5pZmVzdC5qc29uJylcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gTm90aWZ5IGRlZmVycmVkIGVudHJ5IGxvYWRlcnMgd2FpdGluZyBvbiByb3V0ZS5qcyBzdHVicy5cbiAgICAgIHRoaXMuc29ja2V0SU8/LmVtaXQoJ2J1aWxkLWNvbXBsZXRlJyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBjbGVhbnVwR2VuZXJhdGVkQXJ0aWZhY3RzT25Cb290KFxuICAgICAgb3V0cHV0RGlyOiBzdHJpbmdcbiAgICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgIGNvbnN0IHdvcmtmbG93R2VuZXJhdGVkRGlyID0gam9pbihvdXRwdXREaXIsICcud2VsbC1rbm93bi93b3JrZmxvdy92MScpO1xuICAgICAgY29uc3QgZmxvd1JvdXRlRGlyID0gam9pbih3b3JrZmxvd0dlbmVyYXRlZERpciwgJ2Zsb3cnKTtcbiAgICAgIGNvbnN0IHN0ZXBSb3V0ZURpciA9IGpvaW4od29ya2Zsb3dHZW5lcmF0ZWREaXIsICdzdGVwJyk7XG4gICAgICBjb25zdCB3ZWJob29rUm91dGVEaXIgPSBqb2luKHdvcmtmbG93R2VuZXJhdGVkRGlyLCAnd2ViaG9vay9bdG9rZW5dJyk7XG5cbiAgICAgIGNvbnN0IHN0YWxlQXJ0aWZhY3RQYXRocyA9IFtcbiAgICAgICAgam9pbihmbG93Um91dGVEaXIsICdyb3V0ZS5qcy50ZW1wJyksXG4gICAgICAgIGpvaW4oZmxvd1JvdXRlRGlyLCAncm91dGUuanMudGVtcC5kZWJ1Zy5qc29uJyksXG4gICAgICAgIGpvaW4oZmxvd1JvdXRlRGlyLCAncm91dGUuanMuZGVidWcuanNvbicpLFxuICAgICAgICBqb2luKGZsb3dSb3V0ZURpciwgJ19fc3RlcF9yZWdpc3RyYXRpb25zLnJvdXRlLmpzLnRlbXAnKSxcbiAgICAgICAgam9pbihmbG93Um91dGVEaXIsICdfX3N0ZXBfcmVnaXN0cmF0aW9ucy5yb3V0ZS5qcy50ZW1wLmRlYnVnLmpzb24nKSxcbiAgICAgICAgLy8gVjI6IGNsZWFuIHVwIHN0YWxlIFYxIHN0ZXAgcm91dGUgZGlyZWN0b3J5XG4gICAgICAgIHN0ZXBSb3V0ZURpcixcbiAgICAgICAgam9pbih3ZWJob29rUm91dGVEaXIsICdyb3V0ZS5qcy50ZW1wJyksXG4gICAgICAgIGpvaW4od29ya2Zsb3dHZW5lcmF0ZWREaXIsICdtYW5pZmVzdC5qc29uJyksXG4gICAgICBdO1xuXG4gICAgICBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgIC4uLnN0YWxlQXJ0aWZhY3RQYXRocy5tYXAoKHN0YWxlUGF0aCkgPT5cbiAgICAgICAgICBybShzdGFsZVBhdGgsIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KVxuICAgICAgICApLFxuICAgICAgICBjbGVhbnVwU3RhbGVTb2NrZXRJbmZvRmlsZXMoXG4gICAgICAgICAgam9pbih0aGlzLmNvbmZpZy53b3JraW5nRGlyLCB0aGlzLmdldERpc3REaXIoKSlcbiAgICAgICAgKSxcbiAgICAgICAgdGhpcy5yZW1vdmVTdGFsZURlZmVycmVkVGVtcEZpbGVzKGZsb3dSb3V0ZURpciksXG4gICAgICAgIHRoaXMucmVtb3ZlU3RhbGVEZWZlcnJlZFRlbXBGaWxlcyh3ZWJob29rUm91dGVEaXIpLFxuICAgICAgXSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyByZW1vdmVTdGFsZURlZmVycmVkVGVtcEZpbGVzKFxuICAgICAgcm91dGVEaXI6IHN0cmluZ1xuICAgICk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgY29uc3Qgcm91dGVFbnRyaWVzID0gYXdhaXQgcmVhZGRpcihyb3V0ZURpciwge1xuICAgICAgICB3aXRoRmlsZVR5cGVzOiB0cnVlLFxuICAgICAgfSkuY2F0Y2goKCkgPT4gW10pO1xuICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgIHJvdXRlRW50cmllc1xuICAgICAgICAgIC5maWx0ZXIoXG4gICAgICAgICAgICAoZW50cnkpID0+XG4gICAgICAgICAgICAgIGVudHJ5LmlzRmlsZSgpICYmXG4gICAgICAgICAgICAgIGVudHJ5Lm5hbWUuc3RhcnRzV2l0aCgncm91dGUuanMuJykgJiZcbiAgICAgICAgICAgICAgZW50cnkubmFtZS5lbmRzV2l0aCgnLnRtcCcpXG4gICAgICAgICAgKVxuICAgICAgICAgIC5tYXAoKGVudHJ5KSA9PlxuICAgICAgICAgICAgcm0oam9pbihyb3V0ZURpciwgZW50cnkubmFtZSksIHtcbiAgICAgICAgICAgICAgZm9yY2U6IHRydWUsXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIClcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBjcmVhdGVEaXNjb3ZlcnlTb2NrZXRTZXJ2ZXIoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICBpZiAodGhpcy5zb2NrZXRJTyB8fCBwcm9jZXNzLmVudi5XT1JLRkxPV19TT0NLRVRfUE9SVCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHByb2Nlc3MuZW52LldPUktGTE9XX1NPQ0tFVF9JTkZPX1BBVEggPSB0aGlzLmdldFNvY2tldEluZm9GaWxlUGF0aCgpO1xuICAgICAgY29uc3QgY29uZmlnOiBTb2NrZXRTZXJ2ZXJDb25maWcgPSB7XG4gICAgICAgIGlzRGV2U2VydmVyOiBCb29sZWFuKHRoaXMuY29uZmlnLndhdGNoKSxcbiAgICAgICAgc29ja2V0SW5mb0ZpbGVQYXRoOiB0aGlzLmdldFNvY2tldEluZm9GaWxlUGF0aCgpLFxuICAgICAgICBvbkZpbGVEaXNjb3ZlcmVkOiAoXG4gICAgICAgICAgZmlsZVBhdGg6IHN0cmluZyxcbiAgICAgICAgICBoYXNXb3JrZmxvdzogYm9vbGVhbixcbiAgICAgICAgICBoYXNTdGVwOiBib29sZWFuLFxuICAgICAgICAgIGhhc1NlcmRlOiBib29sZWFuXG4gICAgICAgICkgPT4ge1xuICAgICAgICAgIGNvbnN0IG5vcm1hbGl6ZWRGaWxlUGF0aCA9IHRoaXMubm9ybWFsaXplRGlzY292ZXJlZEZpbGVQYXRoKGZpbGVQYXRoKTtcbiAgICAgICAgICBsZXQgaGFzQ2FjaGVUcmFja2luZ0NoYW5nZSA9IGZhbHNlO1xuICAgICAgICAgIGNvbnN0IHdhc1RyYWNrZWREZXBlbmRlbmN5ID1cbiAgICAgICAgICAgIHRoaXMudHJhY2tlZERlcGVuZGVuY3lGaWxlcy5oYXMobm9ybWFsaXplZEZpbGVQYXRoKTtcblxuICAgICAgICAgIGlmIChoYXNXb3JrZmxvdykge1xuICAgICAgICAgICAgaWYgKCF0aGlzLmRpc2NvdmVyZWRXb3JrZmxvd0ZpbGVzLmhhcyhub3JtYWxpemVkRmlsZVBhdGgpKSB7XG4gICAgICAgICAgICAgIHRoaXMuZGlzY292ZXJlZFdvcmtmbG93RmlsZXMuYWRkKG5vcm1hbGl6ZWRGaWxlUGF0aCk7XG4gICAgICAgICAgICAgIGhhc0NhY2hlVHJhY2tpbmdDaGFuZ2UgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCB3YXNEZWxldGVkID1cbiAgICAgICAgICAgICAgdGhpcy5kaXNjb3ZlcmVkV29ya2Zsb3dGaWxlcy5kZWxldGUobm9ybWFsaXplZEZpbGVQYXRoKTtcbiAgICAgICAgICAgIGhhc0NhY2hlVHJhY2tpbmdDaGFuZ2UgPSB3YXNEZWxldGVkIHx8IGhhc0NhY2hlVHJhY2tpbmdDaGFuZ2U7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGhhc1N0ZXApIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5kaXNjb3ZlcmVkU3RlcEZpbGVzLmhhcyhub3JtYWxpemVkRmlsZVBhdGgpKSB7XG4gICAgICAgICAgICAgIHRoaXMuZGlzY292ZXJlZFN0ZXBGaWxlcy5hZGQobm9ybWFsaXplZEZpbGVQYXRoKTtcbiAgICAgICAgICAgICAgaGFzQ2FjaGVUcmFja2luZ0NoYW5nZSA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHdhc0RlbGV0ZWQgPVxuICAgICAgICAgICAgICB0aGlzLmRpc2NvdmVyZWRTdGVwRmlsZXMuZGVsZXRlKG5vcm1hbGl6ZWRGaWxlUGF0aCk7XG4gICAgICAgICAgICBoYXNDYWNoZVRyYWNraW5nQ2hhbmdlID0gd2FzRGVsZXRlZCB8fCBoYXNDYWNoZVRyYWNraW5nQ2hhbmdlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChoYXNTZXJkZSkge1xuICAgICAgICAgICAgaWYgKCF0aGlzLmRpc2NvdmVyZWRTZXJkZUZpbGVzLmhhcyhub3JtYWxpemVkRmlsZVBhdGgpKSB7XG4gICAgICAgICAgICAgIGhhc0NhY2hlVHJhY2tpbmdDaGFuZ2UgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5kaXNjb3ZlcmVkU2VyZGVGaWxlcy5hZGQobm9ybWFsaXplZEZpbGVQYXRoKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3Qgd2FzRGVsZXRlZCA9XG4gICAgICAgICAgICAgIHRoaXMuZGlzY292ZXJlZFNlcmRlRmlsZXMuZGVsZXRlKG5vcm1hbGl6ZWRGaWxlUGF0aCk7XG4gICAgICAgICAgICBoYXNDYWNoZVRyYWNraW5nQ2hhbmdlID0gd2FzRGVsZXRlZCB8fCBoYXNDYWNoZVRyYWNraW5nQ2hhbmdlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChoYXNDYWNoZVRyYWNraW5nQ2hhbmdlKSB7XG4gICAgICAgICAgICB0aGlzLnNjaGVkdWxlV29ya2Zsb3dzQ2FjaGVXcml0ZSgpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIGhhc1dvcmtmbG93IHx8XG4gICAgICAgICAgICBoYXNTdGVwIHx8XG4gICAgICAgICAgICBoYXNTZXJkZSB8fFxuICAgICAgICAgICAgaGFzQ2FjaGVUcmFja2luZ0NoYW5nZSB8fFxuICAgICAgICAgICAgd2FzVHJhY2tlZERlcGVuZGVuY3lcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHRoaXMuc2NoZWR1bGVEZWZlcnJlZFJlYnVpbGQoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIG9uVHJpZ2dlckJ1aWxkOiAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5zY2hlZHVsZURlZmVycmVkUmVidWlsZCgpO1xuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgdGhpcy5zb2NrZXRJTyA9IGF3YWl0IGNyZWF0ZVNvY2tldFNlcnZlcihjb25maWcpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgaW5pdGlhbGl6ZURpc2NvdmVyeVN0YXRlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgaWYgKHRoaXMuY2FjaGVJbml0aWFsaXplZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IHRoaXMubG9hZFdvcmtmbG93c0NhY2hlKCk7XG4gICAgICAvLyBEZWZlcnJlZCBtb2RlIG11c3Qgbm90IHJ1biBlYWdlciBpbnB1dC1ncmFwaCBkaXNjb3Zlcnk7IGVudHJpZXMgYXJlXG4gICAgICAvLyBkaXNjb3ZlcmVkIHZpYSBsb2FkZXItPnNvY2tldCBub3RpZmljYXRpb25zIGR1cmluZyBOZXh0J3MgYnVpbGQuXG4gICAgICB0aGlzLmNhY2hlSW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0RGlzdERpcigpOiBzdHJpbmcge1xuICAgICAgcmV0dXJuICh0aGlzLmNvbmZpZyBhcyB7IGRpc3REaXI/OiBzdHJpbmcgfSkuZGlzdERpciB8fCAnLm5leHQnO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0V29ya2Zsb3dzQ2FjaGVGaWxlUGF0aCgpOiBzdHJpbmcge1xuICAgICAgcmV0dXJuIGpvaW4oXG4gICAgICAgIHRoaXMuY29uZmlnLndvcmtpbmdEaXIsXG4gICAgICAgIHRoaXMuZ2V0RGlzdERpcigpLFxuICAgICAgICAnY2FjaGUnLFxuICAgICAgICAnd29ya2Zsb3dzLmpzb24nXG4gICAgICApO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0U29ja2V0SW5mb0ZpbGVQYXRoKCk6IHN0cmluZyB7XG4gICAgICByZXR1cm4gam9pbihcbiAgICAgICAgdGhpcy5jb25maWcud29ya2luZ0RpcixcbiAgICAgICAgdGhpcy5nZXREaXN0RGlyKCksXG4gICAgICAgIFNPQ0tFVF9JTkZPX0ZJTEVOQU1FXG4gICAgICApO1xuICAgIH1cblxuICAgIHByaXZhdGUgZmluZFBhY2thZ2VKc29uUGF0aChmaWxlUGF0aDogc3RyaW5nKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgICBsZXQgY3VycmVudERpciA9IGRpcm5hbWUoZmlsZVBhdGgpO1xuICAgICAgbGV0IHByZXZpb3VzRGlyID0gJyc7XG5cbiAgICAgIHdoaWxlIChjdXJyZW50RGlyICE9PSBwcmV2aW91c0Rpcikge1xuICAgICAgICBjb25zdCBwYWNrYWdlSnNvblBhdGggPSBqb2luKGN1cnJlbnREaXIsICdwYWNrYWdlLmpzb24nKTtcbiAgICAgICAgaWYgKGV4aXN0c1N5bmMocGFja2FnZUpzb25QYXRoKSkge1xuICAgICAgICAgIHJldHVybiBwYWNrYWdlSnNvblBhdGg7XG4gICAgICAgIH1cbiAgICAgICAgcHJldmlvdXNEaXIgPSBjdXJyZW50RGlyO1xuICAgICAgICBjdXJyZW50RGlyID0gZGlybmFtZShjdXJyZW50RGlyKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzaG91bGRQcmVmZXJTb3VyY2VCYWNrZWRQYWNrYWdlUGF0aChmaWxlUGF0aDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICBjb25zdCBub3JtYWxpemVkUGF0aCA9IGZpbGVQYXRoLnJlcGxhY2UoL1xcXFwvZywgJy8nKTtcbiAgICAgIC8vIE9ubHkgcHJlZmVyIHNvdXJjZSBmb3Igd29ya3NwYWNlIHBhY2thZ2VzIChub3QgaW4gbm9kZV9tb2R1bGVzKS5cbiAgICAgIC8vIEZvciB0YXJiYWxsLWluc3RhbGxlZCBwYWNrYWdlcywgdXNpbmcgc291cmNlLWJhY2tlZCBwYXRocyBjYXVzZXNcbiAgICAgIC8vIGVzYnVpbGQgdG8gYnVuZGxlIHRoZSBmdWxsIHNvdXJjZSB0cmVlIChpbmNsdWRpbmcgd29ybGQudHMgd2l0aFxuICAgICAgLy8gcHJvY2Vzcy5jd2QoKSkgaW5zdGVhZCBvZiBleHRlcm5hbGl6aW5nIHByb3Blcmx5LlxuICAgICAgaWYgKFxuICAgICAgICBub3JtYWxpemVkUGF0aC5pbmNsdWRlcygnL3BhY2thZ2VzLycpICYmXG4gICAgICAgICFub3JtYWxpemVkUGF0aC5pbmNsdWRlcygnL25vZGVfbW9kdWxlcy8nKVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoIW5vcm1hbGl6ZWRQYXRoLmluY2x1ZGVzKCcvbm9kZV9tb2R1bGVzLycpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcGFja2FnZUpzb25QYXRoID0gdGhpcy5maW5kUGFja2FnZUpzb25QYXRoKGZpbGVQYXRoKTtcbiAgICAgIGlmICghcGFja2FnZUpzb25QYXRoKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcGFja2FnZUpzb24gPSBKU09OLnBhcnNlKFxuICAgICAgICAgIHJlYWRGaWxlU3luYyhwYWNrYWdlSnNvblBhdGgsICd1dGYtOCcpXG4gICAgICAgICkgYXMgeyBuYW1lPzogdW5rbm93biB9O1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIHBhY2thZ2VKc29uLm5hbWUgPT09ICd3b3JrZmxvdycgfHxcbiAgICAgICAgICAodHlwZW9mIHBhY2thZ2VKc29uLm5hbWUgPT09ICdzdHJpbmcnICYmXG4gICAgICAgICAgICBwYWNrYWdlSnNvbi5uYW1lLnN0YXJ0c1dpdGgoJ0B3b3JrZmxvdy8nKSlcbiAgICAgICAgKTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZXNvbHZlU291cmNlQmFja2VkUGFja2FnZVBhdGgoZmlsZVBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICBjb25zdCBub3JtYWxpemVkUGF0aCA9IGZpbGVQYXRoLnJlcGxhY2UoL1xcXFwvZywgJy8nKTtcbiAgICAgIGlmICghbm9ybWFsaXplZFBhdGguaW5jbHVkZXMoJy9kaXN0LycpKSB7XG4gICAgICAgIHJldHVybiBmaWxlUGF0aDtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc291cmNlQ2FuZGlkYXRlID0gbm9ybWFsaXplZFBhdGgucmVwbGFjZSgnL2Rpc3QvJywgJy9zcmMvJyk7XG4gICAgICBjb25zdCByZXNvbHZlZFNvdXJjZUNhbmRpZGF0ZSA9XG4gICAgICAgIHRoaXMucmVzb2x2ZUNvcGllZFN0ZXBJbXBvcnRUYXJnZXRQYXRoKHNvdXJjZUNhbmRpZGF0ZSk7XG4gICAgICBpZiAoXG4gICAgICAgICFleGlzdHNTeW5jKHJlc29sdmVkU291cmNlQ2FuZGlkYXRlKSB8fFxuICAgICAgICAhdGhpcy5zaG91bGRQcmVmZXJTb3VyY2VCYWNrZWRQYWNrYWdlUGF0aChmaWxlUGF0aClcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gZmlsZVBhdGg7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBleGlzdHNTeW5jKHJlc29sdmVkU291cmNlQ2FuZGlkYXRlKVxuICAgICAgICA/IHJlc29sdmVkU291cmNlQ2FuZGlkYXRlXG4gICAgICAgIDogZmlsZVBhdGg7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBub3JtYWxpemVEaXNjb3ZlcmVkRmlsZVBhdGgoZmlsZVBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICBjb25zdCBhYnNvbHV0ZVBhdGggPSBpc0Fic29sdXRlKGZpbGVQYXRoKVxuICAgICAgICA/IGZpbGVQYXRoXG4gICAgICAgIDogcmVzb2x2ZSh0aGlzLmNvbmZpZy53b3JraW5nRGlyLCBmaWxlUGF0aCk7XG4gICAgICByZXR1cm4gdGhpcy5yZXNvbHZlU291cmNlQmFja2VkUGFja2FnZVBhdGgoYWJzb2x1dGVQYXRoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGZpbHRlckV4aXN0aW5nRmlsZXMoZmlsZVBhdGhzOiBzdHJpbmdbXSk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWRGaWxlUGF0aHMgPSBBcnJheS5mcm9tKFxuICAgICAgICBuZXcgU2V0KFxuICAgICAgICAgIGZpbGVQYXRocy5tYXAoKGZpbGVQYXRoKSA9PlxuICAgICAgICAgICAgdGhpcy5ub3JtYWxpemVEaXNjb3ZlcmVkRmlsZVBhdGgoZmlsZVBhdGgpXG4gICAgICAgICAgKVxuICAgICAgICApXG4gICAgICApLnNvcnQoKTtcblxuICAgICAgY29uc3QgZXhpc3RpbmdGaWxlcyA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICBub3JtYWxpemVkRmlsZVBhdGhzLm1hcChhc3luYyAoZmlsZVBhdGgpID0+IHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgZmlsZVN0YXRzID0gYXdhaXQgc3RhdChmaWxlUGF0aCk7XG4gICAgICAgICAgICByZXR1cm4gZmlsZVN0YXRzLmlzRmlsZSgpID8gZmlsZVBhdGggOiBudWxsO1xuICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgKTtcblxuICAgICAgcmV0dXJuIGV4aXN0aW5nRmlsZXMuZmlsdGVyKChmaWxlUGF0aCk6IGZpbGVQYXRoIGlzIHN0cmluZyA9PlxuICAgICAgICBCb29sZWFuKGZpbGVQYXRoKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGNyZWF0ZURlZmVycmVkQnVpbGRTaWduYXR1cmUoXG4gICAgICBpbnB1dEZpbGVzOiBzdHJpbmdbXVxuICAgICk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICBjb25zdCBub3JtYWxpemVkRmlsZXMgPSBBcnJheS5mcm9tKFxuICAgICAgICBuZXcgU2V0KFtcbiAgICAgICAgICAuLi5pbnB1dEZpbGVzLm1hcCgoZmlsZVBhdGgpID0+XG4gICAgICAgICAgICB0aGlzLm5vcm1hbGl6ZURpc2NvdmVyZWRGaWxlUGF0aChmaWxlUGF0aClcbiAgICAgICAgICApLFxuICAgICAgICAgIC4uLnRoaXMudHJhY2tlZERlcGVuZGVuY3lGaWxlcyxcbiAgICAgICAgXSlcbiAgICAgICkuc29ydCgpO1xuXG4gICAgICBjb25zdCBzaWduYXR1cmVQYXJ0cyA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICBub3JtYWxpemVkRmlsZXMubWFwKGFzeW5jIChmaWxlUGF0aCkgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBmaWxlU3RhdHMgPSBhd2FpdCBzdGF0KGZpbGVQYXRoKTtcbiAgICAgICAgICAgIHJldHVybiBgJHtmaWxlUGF0aH06JHtmaWxlU3RhdHMuc2l6ZX06JHtNYXRoLnRydW5jKGZpbGVTdGF0cy5tdGltZU1zKX1gO1xuICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgcmV0dXJuIGAke2ZpbGVQYXRofTptaXNzaW5nYDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICApO1xuXG4gICAgICBjb25zdCBzaWduYXR1cmVIYXNoID0gY3JlYXRlSGFzaCgnc2hhMjU2Jyk7XG4gICAgICBmb3IgKGNvbnN0IHNpZ25hdHVyZVBhcnQgb2Ygc2lnbmF0dXJlUGFydHMpIHtcbiAgICAgICAgc2lnbmF0dXJlSGFzaC51cGRhdGUoc2lnbmF0dXJlUGFydCk7XG4gICAgICAgIHNpZ25hdHVyZUhhc2gudXBkYXRlKCdcXG4nKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHNpZ25hdHVyZUhhc2guZGlnZXN0KCdoZXgnKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGNvbGxlY3RUcmFja2VkRGlzY292ZXJlZEVudHJpZXMoKTogUHJvbWlzZTx7XG4gICAgICBkaXNjb3ZlcmVkU3RlcHM6IHN0cmluZ1tdO1xuICAgICAgZGlzY292ZXJlZFdvcmtmbG93czogc3RyaW5nW107XG4gICAgICBkaXNjb3ZlcmVkU2VyZGVGaWxlczogc3RyaW5nW107XG4gICAgfT4ge1xuICAgICAgaWYgKHRoaXMudHJhY2tlZERlcGVuZGVuY3lGaWxlcy5zaXplID09PSAwKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgZGlzY292ZXJlZFN0ZXBzOiBbXSxcbiAgICAgICAgICBkaXNjb3ZlcmVkV29ya2Zsb3dzOiBbXSxcbiAgICAgICAgICBkaXNjb3ZlcmVkU2VyZGVGaWxlczogW10sXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHsgd29ya2Zsb3dGaWxlcywgc3RlcEZpbGVzLCBzZXJkZUZpbGVzIH0gPVxuICAgICAgICBhd2FpdCB0aGlzLnJlY29uY2lsZURpc2NvdmVyZWRFbnRyaWVzKHtcbiAgICAgICAgICB3b3JrZmxvd0NhbmRpZGF0ZXM6IHRoaXMudHJhY2tlZERlcGVuZGVuY3lGaWxlcyxcbiAgICAgICAgICBzdGVwQ2FuZGlkYXRlczogdGhpcy50cmFja2VkRGVwZW5kZW5jeUZpbGVzLFxuICAgICAgICAgIHNlcmRlQ2FuZGlkYXRlczogdGhpcy50cmFja2VkRGVwZW5kZW5jeUZpbGVzLFxuICAgICAgICAgIHZhbGlkYXRlUGF0dGVybnM6IHRydWUsXG4gICAgICAgIH0pO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBkaXNjb3ZlcmVkU3RlcHM6IEFycmF5LmZyb20oc3RlcEZpbGVzKS5zb3J0KCksXG4gICAgICAgIGRpc2NvdmVyZWRXb3JrZmxvd3M6IEFycmF5LmZyb20od29ya2Zsb3dGaWxlcykuc29ydCgpLFxuICAgICAgICBkaXNjb3ZlcmVkU2VyZGVGaWxlczogQXJyYXkuZnJvbShzZXJkZUZpbGVzKS5zb3J0KCksXG4gICAgICB9O1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgcmVmcmVzaFRyYWNrZWREZXBlbmRlbmN5RmlsZXMoXG4gICAgICB3b3JrZmxvd0dlbmVyYXRlZERpcjogc3RyaW5nLFxuICAgICAgcm91dGVGaWxlTmFtZTogc3RyaW5nXG4gICAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICBjb25zdCBidW5kbGVGaWxlcyA9IFtcbiAgICAgICAgam9pbih3b3JrZmxvd0dlbmVyYXRlZERpciwgYHN0ZXAvJHtyb3V0ZUZpbGVOYW1lfWApLFxuICAgICAgICBqb2luKHdvcmtmbG93R2VuZXJhdGVkRGlyLCBgZmxvdy8ke3JvdXRlRmlsZU5hbWV9YCksXG4gICAgICBdO1xuICAgICAgY29uc3QgdHJhY2tlZEZpbGVzID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbiAgICAgIGZvciAoY29uc3QgYnVuZGxlRmlsZSBvZiBidW5kbGVGaWxlcykge1xuICAgICAgICBjb25zdCBidW5kbGVTb3VyY2VzID0gYXdhaXQgdGhpcy5leHRyYWN0QnVuZGxlU291cmNlRmlsZXMoYnVuZGxlRmlsZSk7XG4gICAgICAgIGZvciAoY29uc3Qgc291cmNlRmlsZSBvZiBidW5kbGVTb3VyY2VzKSB7XG4gICAgICAgICAgdHJhY2tlZEZpbGVzLmFkZChzb3VyY2VGaWxlKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAodHJhY2tlZEZpbGVzLnNpemUgPiAwKSB7XG4gICAgICAgIHRoaXMudHJhY2tlZERlcGVuZGVuY3lGaWxlcyA9IHRyYWNrZWRGaWxlcztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGV4dHJhY3RCdW5kbGVTb3VyY2VGaWxlcyhcbiAgICAgIGJ1bmRsZUZpbGVQYXRoOiBzdHJpbmdcbiAgICApOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgICBsZXQgYnVuZGxlQ29udGVudHM6IHN0cmluZztcbiAgICAgIHRyeSB7XG4gICAgICAgIGJ1bmRsZUNvbnRlbnRzID0gYXdhaXQgcmVhZEZpbGUoYnVuZGxlRmlsZVBhdGgsICd1dGYtOCcpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgYmFzZURpcmVjdG9yeSA9IGRpcm5hbWUoYnVuZGxlRmlsZVBhdGgpO1xuICAgICAgY29uc3QgbG9jYWxTb3VyY2VGaWxlcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gICAgICAvLyBFeHRyYWN0IGlubGluZSBiYXNlNjQgc291cmNlbWFwcyB2aWEgc3RyaW5nIHNjYW5uaW5nLiBBIHByZXZpb3VzXG4gICAgICAvLyBpbXBsZW1lbnRhdGlvbiB1c2VkIGBidW5kbGVDb250ZW50cy5tYXRjaEFsbCgvLi4uW0EtWmEtejAtOSsvPV0rLi4uL2cpYFxuICAgICAgLy8gd2hpY2ggb3ZlcmZsb3dzIFY4J3MgcmVnZXggc3RhY2tcbiAgICAgIC8vIChgUmFuZ2VFcnJvcjogTWF4aW11bSBjYWxsIHN0YWNrIHNpemUgZXhjZWVkZWQgYXQgUmVnRXhwU3RyaW5nSXRlcmF0b3IubmV4dGApXG4gICAgICAvLyBvbiBidW5kbGVzIHdpdGggbGFyZ2UgaW5saW5lIHNvdXJjZW1hcHMg4oCUIFY4J3MgaXJyZWdleHAgdXNlc1xuICAgICAgLy8gcmVjdXJzaW9uIGZvciBncmVlZHkgY2hhcmFjdGVyLWNsYXNzIHF1YW50aWZpZXJzIGFuZCBjZXJ0YWluIGxvbmdcbiAgICAgIC8vIGJhc2U2NCBpbnB1dHMgZXhoYXVzdCB0aGUgY2FsbCBzdGFjay5cbiAgICAgIGNvbnN0IHNvdXJjZU1hcFByZWZpeCA9ICcvLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb24nO1xuICAgICAgY29uc3QgYmFzZTY0TWFya2VyID0gJztiYXNlNjQsJztcbiAgICAgIGNvbnN0IHNvdXJjZU1hcE1hdGNoZXM6IEFycmF5PHsgYmFzZTY0VmFsdWU6IHN0cmluZyB9PiA9IFtdO1xuICAgICAgbGV0IHNjYW5Gcm9tID0gMDtcbiAgICAgIHdoaWxlIChzY2FuRnJvbSA8IGJ1bmRsZUNvbnRlbnRzLmxlbmd0aCkge1xuICAgICAgICBjb25zdCBwcmVmaXhJZHggPSBidW5kbGVDb250ZW50cy5pbmRleE9mKHNvdXJjZU1hcFByZWZpeCwgc2NhbkZyb20pO1xuICAgICAgICBpZiAocHJlZml4SWR4ID09PSAtMSkgYnJlYWs7XG4gICAgICAgIGNvbnN0IGJhc2U2NFN0YXJ0ID0gYnVuZGxlQ29udGVudHMuaW5kZXhPZihcbiAgICAgICAgICBiYXNlNjRNYXJrZXIsXG4gICAgICAgICAgcHJlZml4SWR4ICsgc291cmNlTWFwUHJlZml4Lmxlbmd0aFxuICAgICAgICApO1xuICAgICAgICBpZiAoYmFzZTY0U3RhcnQgPT09IC0xKSB7XG4gICAgICAgICAgc2NhbkZyb20gPSBwcmVmaXhJZHggKyBzb3VyY2VNYXBQcmVmaXgubGVuZ3RoO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJhaWwgaWYgYSBjb21tYSBhcHBlYXJzIGJlZm9yZSBgO2Jhc2U2NCxgIOKAlCB0aGF0IG1lYW5zIHRoaXNcbiAgICAgICAgLy8gd2Fzbid0IGEgYGRhdGE6YXBwbGljYXRpb24vanNvbls7cGFyYW1zXTtiYXNlNjQsLi4uYCBVUkwgYWZ0ZXJcbiAgICAgICAgLy8gYWxsICh0aGUgY29tbWEgd291bGQgdGVybWluYXRlIHRoZSBkYXRhIFVSTCBwYXJhbWV0ZXJzKS5cbiAgICAgICAgY29uc3QgY29tbWFCZWZvcmUgPSBidW5kbGVDb250ZW50cy5pbmRleE9mKCcsJywgcHJlZml4SWR4KTtcbiAgICAgICAgaWYgKGNvbW1hQmVmb3JlICE9PSAtMSAmJiBjb21tYUJlZm9yZSA8IGJhc2U2NFN0YXJ0KSB7XG4gICAgICAgICAgc2NhbkZyb20gPSBiYXNlNjRTdGFydDtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB2YWx1ZVN0YXJ0ID0gYmFzZTY0U3RhcnQgKyBiYXNlNjRNYXJrZXIubGVuZ3RoO1xuICAgICAgICAvLyBCYXNlNjQgcGF5bG9hZCB0ZXJtaW5hdGVzIGF0IGZpcnN0IG5vbi1iYXNlNjQgY2hhciAobmV3bGluZSxcbiAgICAgICAgLy8gY2xvc2luZyBgKi9gLCBldGMuKS4gU2Nhbm5pbmcgYSBzbWFsbCBhbHBoYWJldCBieSBjaGFyIGlzIGZhclxuICAgICAgICAvLyBjaGVhcGVyIHRoYW4gYmFja3RyYWNraW5nIGEgcmVnZXggb3ZlciBhIG11bHRpLU1CIGNhcHR1cmUuXG4gICAgICAgIGxldCB2YWx1ZUVuZCA9IHZhbHVlU3RhcnQ7XG4gICAgICAgIHdoaWxlICh2YWx1ZUVuZCA8IGJ1bmRsZUNvbnRlbnRzLmxlbmd0aCkge1xuICAgICAgICAgIGNvbnN0IGNvZGUgPSBidW5kbGVDb250ZW50cy5jaGFyQ29kZUF0KHZhbHVlRW5kKTtcbiAgICAgICAgICAvLyBBLVogMHg0MS0weDVBLCBhLXogMHg2MS0weDdBLCAwLTkgMHgzMC0weDM5LCAnKycgMHgyQixcbiAgICAgICAgICAvLyAnLycgMHgyRiwgJz0nIDB4M0RcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAhKFxuICAgICAgICAgICAgICAoY29kZSA+PSAweDQxICYmIGNvZGUgPD0gMHg1YSkgfHxcbiAgICAgICAgICAgICAgKGNvZGUgPj0gMHg2MSAmJiBjb2RlIDw9IDB4N2EpIHx8XG4gICAgICAgICAgICAgIChjb2RlID49IDB4MzAgJiYgY29kZSA8PSAweDM5KSB8fFxuICAgICAgICAgICAgICBjb2RlID09PSAweDJiIHx8XG4gICAgICAgICAgICAgIGNvZGUgPT09IDB4MmYgfHxcbiAgICAgICAgICAgICAgY29kZSA9PT0gMHgzZFxuICAgICAgICAgICAgKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIHZhbHVlRW5kKys7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZhbHVlRW5kID4gdmFsdWVTdGFydCkge1xuICAgICAgICAgIHNvdXJjZU1hcE1hdGNoZXMucHVzaCh7XG4gICAgICAgICAgICBiYXNlNjRWYWx1ZTogYnVuZGxlQ29udGVudHMuc2xpY2UodmFsdWVTdGFydCwgdmFsdWVFbmQpLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHNjYW5Gcm9tID0gdmFsdWVFbmQ7XG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgbWF0Y2ggb2Ygc291cmNlTWFwTWF0Y2hlcykge1xuICAgICAgICBjb25zdCBiYXNlNjRWYWx1ZSA9IG1hdGNoLmJhc2U2NFZhbHVlO1xuICAgICAgICBpZiAoIWJhc2U2NFZhbHVlKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgc291cmNlTWFwOiB7IHNvdXJjZVJvb3Q/OiB1bmtub3duOyBzb3VyY2VzPzogdW5rbm93biB9O1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHNvdXJjZU1hcCA9IEpTT04ucGFyc2UoXG4gICAgICAgICAgICBCdWZmZXIuZnJvbShiYXNlNjRWYWx1ZSwgJ2Jhc2U2NCcpLnRvU3RyaW5nKCd1dGYtOCcpXG4gICAgICAgICAgKSBhcyB7IHNvdXJjZVJvb3Q/OiB1bmtub3duOyBzb3VyY2VzPzogdW5rbm93biB9O1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNvdXJjZVJvb3QgPVxuICAgICAgICAgIHR5cGVvZiBzb3VyY2VNYXAuc291cmNlUm9vdCA9PT0gJ3N0cmluZycgPyBzb3VyY2VNYXAuc291cmNlUm9vdCA6ICcnO1xuICAgICAgICBjb25zdCBzb3VyY2VzID0gQXJyYXkuaXNBcnJheShzb3VyY2VNYXAuc291cmNlcylcbiAgICAgICAgICA/IHNvdXJjZU1hcC5zb3VyY2VzLmZpbHRlcihcbiAgICAgICAgICAgICAgKHNvdXJjZSk6IHNvdXJjZSBpcyBzdHJpbmcgPT4gdHlwZW9mIHNvdXJjZSA9PT0gJ3N0cmluZydcbiAgICAgICAgICAgIClcbiAgICAgICAgICA6IFtdO1xuXG4gICAgICAgIGZvciAoY29uc3Qgc291cmNlIG9mIHNvdXJjZXMpIHtcbiAgICAgICAgICBpZiAoc291cmNlLnN0YXJ0c1dpdGgoJ3dlYnBhY2s6Ly8nKSB8fCBzb3VyY2Uuc3RhcnRzV2l0aCgnPCcpKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBsZXQgcmVzb2x2ZWRTb3VyY2VQYXRoOiBzdHJpbmc7XG4gICAgICAgICAgaWYgKHNvdXJjZS5zdGFydHNXaXRoKCdmaWxlOi8vJykpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIHJlc29sdmVkU291cmNlUGF0aCA9IGRlY29kZVVSSUNvbXBvbmVudChuZXcgVVJMKHNvdXJjZSkucGF0aG5hbWUpO1xuICAgICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAoaXNBYnNvbHV0ZShzb3VyY2UpKSB7XG4gICAgICAgICAgICByZXNvbHZlZFNvdXJjZVBhdGggPSBzb3VyY2U7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlc29sdmVkU291cmNlUGF0aCA9IHJlc29sdmUoYmFzZURpcmVjdG9yeSwgc291cmNlUm9vdCwgc291cmNlKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBub3JtYWxpemVkU291cmNlUGF0aCA9XG4gICAgICAgICAgICB0aGlzLm5vcm1hbGl6ZURpc2NvdmVyZWRGaWxlUGF0aChyZXNvbHZlZFNvdXJjZVBhdGgpO1xuICAgICAgICAgIGNvbnN0IG5vcm1hbGl6ZWRTb3VyY2VQYXRoRm9yQ2hlY2sgPSBub3JtYWxpemVkU291cmNlUGF0aC5yZXBsYWNlKFxuICAgICAgICAgICAgL1xcXFwvZyxcbiAgICAgICAgICAgICcvJ1xuICAgICAgICAgICk7XG4gICAgICAgICAgY29uc3QgaXNTb3VyY2VCYWNrZWRQYWNrYWdlUGF0aCA9XG4gICAgICAgICAgICB0aGlzLnNob3VsZFByZWZlclNvdXJjZUJhY2tlZFBhY2thZ2VQYXRoKG5vcm1hbGl6ZWRTb3VyY2VQYXRoKTtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBub3JtYWxpemVkU291cmNlUGF0aEZvckNoZWNrLmluY2x1ZGVzKCcvLndlbGwta25vd24vd29ya2Zsb3cvJykgfHxcbiAgICAgICAgICAgICghaXNTb3VyY2VCYWNrZWRQYWNrYWdlUGF0aCAmJlxuICAgICAgICAgICAgICBub3JtYWxpemVkU291cmNlUGF0aEZvckNoZWNrLmluY2x1ZGVzKCcvbm9kZV9tb2R1bGVzLycpKSB8fFxuICAgICAgICAgICAgKCFpc1NvdXJjZUJhY2tlZFBhY2thZ2VQYXRoICYmXG4gICAgICAgICAgICAgIG5vcm1hbGl6ZWRTb3VyY2VQYXRoRm9yQ2hlY2suaW5jbHVkZXMoJy8ucG5wbS8nKSkgfHxcbiAgICAgICAgICAgIG5vcm1hbGl6ZWRTb3VyY2VQYXRoRm9yQ2hlY2suaW5jbHVkZXMoJy8ubmV4dC8nKSB8fFxuICAgICAgICAgICAgbm9ybWFsaXplZFNvdXJjZVBhdGhGb3JDaGVjay5lbmRzV2l0aCgnL3ZpcnR1YWwtZW50cnkuanMnKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgbG9jYWxTb3VyY2VGaWxlcy5hZGQobm9ybWFsaXplZFNvdXJjZVBhdGgpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBBcnJheS5mcm9tKGxvY2FsU291cmNlRmlsZXMpO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2NoZWR1bGVXb3JrZmxvd3NDYWNoZVdyaXRlKCk6IHZvaWQge1xuICAgICAgaWYgKHRoaXMuY2FjaGVXcml0ZVRpbWVyKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aGlzLmNhY2hlV3JpdGVUaW1lcik7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuY2FjaGVXcml0ZVRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuY2FjaGVXcml0ZVRpbWVyID0gbnVsbDtcbiAgICAgICAgdm9pZCB0aGlzLndyaXRlV29ya2Zsb3dzQ2FjaGUoKS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oJ0ZhaWxlZCB0byB3cml0ZSB3b3JrZmxvdyBkaXNjb3ZlcnkgY2FjaGUnLCBlcnJvcik7XG4gICAgICAgIH0pO1xuICAgICAgfSwgNTApO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2NoZWR1bGVEZWZlcnJlZFJlYnVpbGQoKTogdm9pZCB7XG4gICAgICBpZiAodGhpcy5kZWZlcnJlZFJlYnVpbGRUaW1lcikge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5kZWZlcnJlZFJlYnVpbGRUaW1lcik7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuZGVmZXJyZWRSZWJ1aWxkVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5kZWZlcnJlZFJlYnVpbGRUaW1lciA9IG51bGw7XG4gICAgICAgIHZvaWQgdGhpcy5vbkJlZm9yZURlZmVycmVkRW50cmllcygpLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICdbd29ya2Zsb3ddIERlZmVycmVkIHJlYnVpbGQgYWZ0ZXIgc291cmNlIHVwZGF0ZSBmYWlsZWQuJyxcbiAgICAgICAgICAgIGVycm9yXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9LCA3NSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyByZWFkV29ya2Zsb3dzQ2FjaGUoKTogUHJvbWlzZTx7XG4gICAgICB3b3JrZmxvd0ZpbGVzOiBzdHJpbmdbXTtcbiAgICAgIHN0ZXBGaWxlczogc3RyaW5nW107XG4gICAgfSB8IG51bGw+IHtcbiAgICAgIGNvbnN0IGNhY2hlRmlsZVBhdGggPSB0aGlzLmdldFdvcmtmbG93c0NhY2hlRmlsZVBhdGgoKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgY2FjaGVDb250ZW50cyA9IGF3YWl0IHJlYWRGaWxlKGNhY2hlRmlsZVBhdGgsICd1dGYtOCcpO1xuICAgICAgICBjb25zdCBwYXJzZWQgPSBKU09OLnBhcnNlKGNhY2hlQ29udGVudHMpIGFzIHtcbiAgICAgICAgICB3b3JrZmxvd0ZpbGVzPzogdW5rbm93bjtcbiAgICAgICAgICBzdGVwRmlsZXM/OiB1bmtub3duO1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHdvcmtmbG93RmlsZXMgPSBBcnJheS5pc0FycmF5KHBhcnNlZC53b3JrZmxvd0ZpbGVzKVxuICAgICAgICAgID8gcGFyc2VkLndvcmtmbG93RmlsZXMuZmlsdGVyKFxuICAgICAgICAgICAgICAoaXRlbSk6IGl0ZW0gaXMgc3RyaW5nID0+IHR5cGVvZiBpdGVtID09PSAnc3RyaW5nJ1xuICAgICAgICAgICAgKVxuICAgICAgICAgIDogW107XG4gICAgICAgIGNvbnN0IHN0ZXBGaWxlcyA9IEFycmF5LmlzQXJyYXkocGFyc2VkLnN0ZXBGaWxlcylcbiAgICAgICAgICA/IHBhcnNlZC5zdGVwRmlsZXMuZmlsdGVyKFxuICAgICAgICAgICAgICAoaXRlbSk6IGl0ZW0gaXMgc3RyaW5nID0+IHR5cGVvZiBpdGVtID09PSAnc3RyaW5nJ1xuICAgICAgICAgICAgKVxuICAgICAgICAgIDogW107XG5cbiAgICAgICAgcmV0dXJuIHsgd29ya2Zsb3dGaWxlcywgc3RlcEZpbGVzIH07XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBsb2FkV29ya2Zsb3dzQ2FjaGUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICBjb25zdCBjYWNoZWREYXRhID0gYXdhaXQgdGhpcy5yZWFkV29ya2Zsb3dzQ2FjaGUoKTtcbiAgICAgIGlmICghY2FjaGVkRGF0YSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCB7IHdvcmtmbG93RmlsZXMsIHN0ZXBGaWxlcywgc2VyZGVGaWxlcyB9ID1cbiAgICAgICAgYXdhaXQgdGhpcy5yZWNvbmNpbGVEaXNjb3ZlcmVkRW50cmllcyh7XG4gICAgICAgICAgd29ya2Zsb3dDYW5kaWRhdGVzOiBjYWNoZWREYXRhLndvcmtmbG93RmlsZXMsXG4gICAgICAgICAgc3RlcENhbmRpZGF0ZXM6IGNhY2hlZERhdGEuc3RlcEZpbGVzLFxuICAgICAgICAgIHNlcmRlQ2FuZGlkYXRlczogdGhpcy5kaXNjb3ZlcmVkU2VyZGVGaWxlcyxcbiAgICAgICAgICB2YWxpZGF0ZVBhdHRlcm5zOiB0cnVlLFxuICAgICAgICB9KTtcblxuICAgICAgdGhpcy5kaXNjb3ZlcmVkV29ya2Zsb3dGaWxlcy5jbGVhcigpO1xuICAgICAgdGhpcy5kaXNjb3ZlcmVkU3RlcEZpbGVzLmNsZWFyKCk7XG4gICAgICB0aGlzLmRpc2NvdmVyZWRTZXJkZUZpbGVzLmNsZWFyKCk7XG4gICAgICBmb3IgKGNvbnN0IGZpbGVQYXRoIG9mIHdvcmtmbG93RmlsZXMpIHtcbiAgICAgICAgdGhpcy5kaXNjb3ZlcmVkV29ya2Zsb3dGaWxlcy5hZGQoZmlsZVBhdGgpO1xuICAgICAgfVxuICAgICAgZm9yIChjb25zdCBmaWxlUGF0aCBvZiBzdGVwRmlsZXMpIHtcbiAgICAgICAgdGhpcy5kaXNjb3ZlcmVkU3RlcEZpbGVzLmFkZChmaWxlUGF0aCk7XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IGZpbGVQYXRoIG9mIHNlcmRlRmlsZXMpIHtcbiAgICAgICAgdGhpcy5kaXNjb3ZlcmVkU2VyZGVGaWxlcy5hZGQoZmlsZVBhdGgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgd3JpdGVXb3JrZmxvd3NDYWNoZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgIGNvbnN0IGNhY2hlRmlsZVBhdGggPSB0aGlzLmdldFdvcmtmbG93c0NhY2hlRmlsZVBhdGgoKTtcbiAgICAgIGNvbnN0IGNhY2hlRGlyID0gam9pbih0aGlzLmNvbmZpZy53b3JraW5nRGlyLCB0aGlzLmdldERpc3REaXIoKSwgJ2NhY2hlJyk7XG4gICAgICBhd2FpdCBta2RpcihjYWNoZURpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG5cbiAgICAgIGNvbnN0IGNhY2hlRGF0YSA9IHtcbiAgICAgICAgd29ya2Zsb3dGaWxlczogQXJyYXkuZnJvbSh0aGlzLmRpc2NvdmVyZWRXb3JrZmxvd0ZpbGVzKS5zb3J0KCksXG4gICAgICAgIHN0ZXBGaWxlczogQXJyYXkuZnJvbSh0aGlzLmRpc2NvdmVyZWRTdGVwRmlsZXMpLnNvcnQoKSxcbiAgICAgIH07XG5cbiAgICAgIGF3YWl0IHdyaXRlRmlsZShjYWNoZUZpbGVQYXRoLCBKU09OLnN0cmluZ2lmeShjYWNoZURhdGEsIG51bGwsIDIpKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIHdyaXRlU3R1YkZpbGVzKG91dHB1dERpcjogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAvLyBUdXJib3BhY2sgY3VycmVudGx5IGhhcyBhIHdvcmtlci1jb25jdXJyZW5jeSBsaW1pdGF0aW9uIGZvciBwZW5kaW5nXG4gICAgICAvLyB2aXJ0dWFsIGVudHJpZXMuIFdhcm4gaWYgcGFyYWxsZWxpc20gaXMgdG9vIGxvdyB0byByZWxpYWJseSBkaXNjb3Zlci5cbiAgICAgIGNvbnN0IHBhcmFsbGVsaXNtQ291bnQgPSBvcy5hdmFpbGFibGVQYXJhbGxlbGlzbSgpO1xuICAgICAgaWYgKHByb2Nlc3MuZW52LlRVUkJPUEFDSyAmJiBwYXJhbGxlbGlzbUNvdW50IDwgNCkge1xuICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgYEF2YWlsYWJsZSBwYXJhbGxlbGlzbSBvZiAke3BhcmFsbGVsaXNtQ291bnR9IGlzIGxlc3MgdGhhbiBuZWVkZWQgNC4gVGhpcyBjYW4gY2F1c2Ugd29ya2Zsb3dzL3N0ZXBzIHRvIGZhaWwgdG8gZGlzY292ZXIgcHJvcGVybHkgaW4gdHVyYm9wYWNrYFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCByb3V0ZVN0dWJDb250ZW50ID0gW1xuICAgICAgICBgLy8gJHtST1VURV9TVFVCX0ZJTEVfTUFSS0VSfWAsXG4gICAgICAgICdleHBvcnQgY29uc3QgX193b3JrZmxvd1JvdXRlU3R1YiA9IHRydWU7JyxcbiAgICAgIF0uam9pbignXFxuJyk7XG4gICAgICBjb25zdCB3b3JrZmxvd0dlbmVyYXRlZERpciA9IGpvaW4ob3V0cHV0RGlyLCAnLndlbGwta25vd24vd29ya2Zsb3cvdjEnKTtcblxuICAgICAgYXdhaXQgbWtkaXIoam9pbih3b3JrZmxvd0dlbmVyYXRlZERpciwgJ2Zsb3cnKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgICBhd2FpdCBta2Rpcihqb2luKHdvcmtmbG93R2VuZXJhdGVkRGlyLCAnd2ViaG9vay9bdG9rZW5dJyksIHtcbiAgICAgICAgcmVjdXJzaXZlOiB0cnVlLFxuICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IHRoaXMud3JpdGVGaWxlSWZDaGFuZ2VkKFxuICAgICAgICBqb2luKHdvcmtmbG93R2VuZXJhdGVkRGlyLCAnLmdpdGlnbm9yZScpLFxuICAgICAgICAnKidcbiAgICAgICk7XG5cbiAgICAgIC8vIFYyOiBPbmx5IGZsb3cgKyB3ZWJob29rIHN0dWJzIG5lZWRlZCAobm8gc2VwYXJhdGUgc3RlcCByb3V0ZSkuXG4gICAgICAvLyBTdHVicyBhcmUgcmVwbGFjZWQgYnkgZ2VuZXJhdGVkIG91dHB1dCBvbmNlIGRpc2NvdmVyeSBmaW5pc2hlcy5cbiAgICAgIGF3YWl0IHRoaXMud3JpdGVGaWxlSWZDaGFuZ2VkKFxuICAgICAgICBqb2luKHdvcmtmbG93R2VuZXJhdGVkRGlyLCAnZmxvdy9yb3V0ZS5qcycpLFxuICAgICAgICByb3V0ZVN0dWJDb250ZW50XG4gICAgICApO1xuICAgICAgYXdhaXQgdGhpcy53cml0ZUZpbGVJZkNoYW5nZWQoXG4gICAgICAgIGpvaW4od29ya2Zsb3dHZW5lcmF0ZWREaXIsICd3ZWJob29rL1t0b2tlbl0vcm91dGUuanMnKSxcbiAgICAgICAgcm91dGVTdHViQ29udGVudFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgYXN5bmMgZ2V0SW5wdXRGaWxlcygpOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgICAvLyBSZWFkIE5leHQuanMncyBhcHAtcGF0aHMtbWFuaWZlc3QuanNvbiBmcm9tIGEgcHJldmlvdXMgYnVpbGQgdG9cbiAgICAgIC8vIGRldGVybWluZSB3aGljaCBmaWxlcyBhcmUgYWN0dWFsIHJvdXRlIGVudHJ5cG9pbnRzLiBUaGlzIGF2b2lkc1xuICAgICAgLy8gcHJlZGljdGluZyBOZXh0LmpzIGNvbnZlbnRpb25zIHdpdGggcmVnZXhlcyBhbmQgaW5zdGVhZCByZWFkc1xuICAgICAgLy8gZnJvbSBOZXh0LmpzJ3Mgb3duIG91dHB1dC5cbiAgICAgIGNvbnN0IG5leHREaXIgPSBqb2luKHRoaXMuY29uZmlnLndvcmtpbmdEaXIsICcubmV4dCcpO1xuICAgICAgY29uc3QgbWFuaWZlc3RQYXRoID0gam9pbihuZXh0RGlyLCAnYXBwLXBhdGhzLW1hbmlmZXN0Lmpzb24nKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IG1hbmlmZXN0Q29udGVudCA9IHJlYWRGaWxlU3luYyhtYW5pZmVzdFBhdGgsICd1dGYtOCcpO1xuICAgICAgICBjb25zdCBtYW5pZmVzdCA9IEpTT04ucGFyc2UobWFuaWZlc3RDb250ZW50KSBhcyBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICAgICAgICAvLyBUaGUgbWFuaWZlc3QgbWFwcyByb3V0ZSBwYXRocyB0byB0aGVpciBzb3VyY2UgZmlsZXMuXG4gICAgICAgIC8vIEV4dHJhY3QgdGhlIHNvdXJjZSBmaWxlIHBhdGhzIGFuZCByZXNvbHZlIHRoZW0uXG4gICAgICAgIGNvbnN0IG1hbmlmZXN0RmlsZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICAgICAgZm9yIChjb25zdCBzb3VyY2VQYXRoIG9mIE9iamVjdC52YWx1ZXMobWFuaWZlc3QpKSB7XG4gICAgICAgICAgY29uc3QgcmVzb2x2ZWQgPSByZXNvbHZlKG5leHREaXIsICdzZXJ2ZXInLCBzb3VyY2VQYXRoKTtcbiAgICAgICAgICAvLyBUaGUgbWFuaWZlc3QgcG9pbnRzIHRvIGJ1aWx0IG91dHB1dDsgZmluZCB0aGUgc291cmNlIGZpbGVcbiAgICAgICAgICAvLyBieSBtYXRjaGluZyBhZ2FpbnN0IHRoZSBiYXNlIGJ1aWxkZXIncyBmdWxsIGZpbGUgbGlzdC5cbiAgICAgICAgICBtYW5pZmVzdEZpbGVzLmFkZChyZXNvbHZlZCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBVc2UgdGhlIG1hbmlmZXN0IHJvdXRlIHBhdGhzIHRvIGZpbHRlciB0aGUgaW5wdXQgZmlsZXMuXG4gICAgICAgIC8vIEEgZmlsZSBpcyBpbmNsdWRlZCBpZiBpdCBtYXRjaGVzIGEga25vd24gcm91dGUgc2VnbWVudCBmcm9tXG4gICAgICAgIC8vIHRoZSBtYW5pZmVzdCAoZS5nLiwgYXBwL2FwaS9yb3V0ZSBjb250YWlucyAnYXBwL2FwaS9yb3V0ZScpLlxuICAgICAgICBjb25zdCBpbnB1dEZpbGVzID0gYXdhaXQgc3VwZXIuZ2V0SW5wdXRGaWxlcygpO1xuICAgICAgICBjb25zdCByb3V0ZVNlZ21lbnRzID0gT2JqZWN0LmtleXMobWFuaWZlc3QpLm1hcCgocm91dGUpID0+XG4gICAgICAgICAgcm91dGUucmVwbGFjZSgvXlxcLy8sICcnKS5yZXBsYWNlKC9cXC9yb3V0ZSQvLCAnJylcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIGlucHV0RmlsZXMuZmlsdGVyKChpdGVtKSA9PlxuICAgICAgICAgIHJvdXRlU2VnbWVudHMuc29tZSgoc2VnbWVudCkgPT4gaXRlbS5pbmNsdWRlcyhzZWdtZW50KSlcbiAgICAgICAgKTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBObyBtYW5pZmVzdCBmcm9tIGEgcHJldmlvdXMgYnVpbGQg4oCUIGZhbGwgYmFjayB0byB0aGUgYmFzZVxuICAgICAgICAvLyBidWlsZGVyJ3MgZnVsbCBmaWxlIHNjYW4uIFRoaXMgaXMgc2FmZSBidXQgc2xvd2VyOyBzdWJzZXF1ZW50XG4gICAgICAgIC8vIGJ1aWxkcyB3aWxsIHVzZSB0aGUgbWFuaWZlc3QuXG4gICAgICAgIHJldHVybiBzdXBlci5nZXRJbnB1dEZpbGVzKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyB3cml0ZUZ1bmN0aW9uc0NvbmZpZyhvdXRwdXREaXI6IHN0cmluZykge1xuICAgICAgLy8gd2UgZG9uJ3QgcnVuIHRoaXMgaW4gZGV2ZWxvcG1lbnQgbW9kZSBhcyBpdCdzIG5vdCBuZWVkZWRcbiAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gJ2RldmVsb3BtZW50Jykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICAvLyBWMjogU2luZ2xlIGNvbWJpbmVkIHRyaWdnZXIgaGFuZGxlcyBib3RoIHdvcmtmbG93IGFuZCBzdGVwIGV4ZWN1dGlvblxuICAgICAgY29uc3QgZ2VuZXJhdGVkQ29uZmlnID0ge1xuICAgICAgICB2ZXJzaW9uOiAnMCcsXG4gICAgICAgIHdvcmtmbG93czoge1xuICAgICAgICAgIG1heER1cmF0aW9uOiAnbWF4JyxcbiAgICAgICAgICBleHBlcmltZW50YWxUcmlnZ2VyczogW1dPUktGTE9XX1FVRVVFX1RSSUdHRVJdLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgYXdhaXQgdGhpcy53cml0ZUZpbGVJZkNoYW5nZWQoXG4gICAgICAgIGpvaW4ob3V0cHV0RGlyLCAnLndlbGwta25vd24vd29ya2Zsb3cvdjEvY29uZmlnLmpzb24nKSxcbiAgICAgICAgSlNPTi5zdHJpbmdpZnkoZ2VuZXJhdGVkQ29uZmlnLCBudWxsLCAyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIHdyaXRlRmlsZUlmQ2hhbmdlZChcbiAgICAgIGZpbGVQYXRoOiBzdHJpbmcsXG4gICAgICBjb250ZW50czogc3RyaW5nIHwgQnVmZmVyXG4gICAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICBjb25zdCBuZXh0QnVmZmVyID0gQnVmZmVyLmlzQnVmZmVyKGNvbnRlbnRzKVxuICAgICAgICA/IGNvbnRlbnRzXG4gICAgICAgIDogQnVmZmVyLmZyb20oY29udGVudHMpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBjdXJyZW50QnVmZmVyID0gYXdhaXQgcmVhZEZpbGUoZmlsZVBhdGgpO1xuICAgICAgICBpZiAoY3VycmVudEJ1ZmZlci5lcXVhbHMobmV4dEJ1ZmZlcikpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBGaWxlIGRvZXMgbm90IGV4aXN0IHlldCBvciBjYW5ub3QgYmUgcmVhZDsgd3JpdGUgYSBmcmVzaCBjb3B5LlxuICAgICAgfVxuXG4gICAgICBhd2FpdCBta2RpcihkaXJuYW1lKGZpbGVQYXRoKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgICBhd2FpdCB3cml0ZUZpbGUoZmlsZVBhdGgsIG5leHRCdWZmZXIpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBjb3B5RmlsZUlmQ2hhbmdlZChcbiAgICAgIHNvdXJjZVBhdGg6IHN0cmluZyxcbiAgICAgIGRlc3RpbmF0aW9uUGF0aDogc3RyaW5nXG4gICAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICBjb25zdCBzb3VyY2VDb250ZW50cyA9IGF3YWl0IHJlYWRGaWxlKHNvdXJjZVBhdGgpO1xuICAgICAgcmV0dXJuIHRoaXMud3JpdGVGaWxlSWZDaGFuZ2VkKGRlc3RpbmF0aW9uUGF0aCwgc291cmNlQ29udGVudHMpO1xuICAgIH1cblxuICAgIHByaXZhdGUgc29ydEpzb25WYWx1ZSh2YWx1ZTogdW5rbm93bik6IHVua25vd24ge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZS5tYXAoKGl0ZW0pID0+IHRoaXMuc29ydEpzb25WYWx1ZShpdGVtKSk7XG4gICAgICB9XG4gICAgICBpZiAodmFsdWUgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xuICAgICAgICBjb25zdCBzb3J0ZWRFbnRyaWVzID0gT2JqZWN0LmVudHJpZXModmFsdWUgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pXG4gICAgICAgICAgLnNvcnQoKFthXSwgW2JdKSA9PiBhLmxvY2FsZUNvbXBhcmUoYikpXG4gICAgICAgICAgLm1hcCgoW2tleSwgZW50cnlWYWx1ZV0pID0+IFtrZXksIHRoaXMuc29ydEpzb25WYWx1ZShlbnRyeVZhbHVlKV0pO1xuICAgICAgICByZXR1cm4gT2JqZWN0LmZyb21FbnRyaWVzKHNvcnRlZEVudHJpZXMpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgcmV3cml0ZUpzb25GaWxlV2l0aFN0YWJsZUtleU9yZGVyKFxuICAgICAgZmlsZVBhdGg6IHN0cmluZ1xuICAgICk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgY29udGVudHMgPSBhd2FpdCByZWFkRmlsZShmaWxlUGF0aCwgJ3V0Zi04Jyk7XG4gICAgICAgIGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UoY29udGVudHMpIGFzIHVua25vd247XG4gICAgICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSB0aGlzLnNvcnRKc29uVmFsdWUocGFyc2VkKTtcbiAgICAgICAgYXdhaXQgdGhpcy53cml0ZUZpbGVJZkNoYW5nZWQoXG4gICAgICAgICAgZmlsZVBhdGgsXG4gICAgICAgICAgYCR7SlNPTi5zdHJpbmdpZnkobm9ybWFsaXplZCwgbnVsbCwgMil9XFxuYFxuICAgICAgICApO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIE1hbmlmZXN0IG1heSBub3QgZXhpc3QgKGUuZy4gbWFuaWZlc3QgZ2VuZXJhdGlvbiBmYWlsZWQpOyBpZ25vcmUuXG4gICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZXNvbHZlQ29waWVkU3RlcEltcG9ydFRhcmdldFBhdGgodGFyZ2V0UGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgIGlmIChleGlzdHNTeW5jKHRhcmdldFBhdGgpKSB7XG4gICAgICAgIHJldHVybiB0YXJnZXRQYXRoO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBleHRlbnNpb25NYXRjaCA9IHRhcmdldFBhdGgubWF0Y2goLyhcXC5bXi4vXFxcXF0rKSQvKTtcbiAgICAgIGNvbnN0IGV4dGVuc2lvbiA9IGV4dGVuc2lvbk1hdGNoPy5bMV0/LnRvTG93ZXJDYXNlKCk7XG4gICAgICBpZiAoIWV4dGVuc2lvbikge1xuICAgICAgICByZXR1cm4gdGFyZ2V0UGF0aDtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZXh0ZW5zaW9uRmFsbGJhY2tzID1cbiAgICAgICAgZXh0ZW5zaW9uID09PSAnLmpzJ1xuICAgICAgICAgID8gWycudHMnLCAnLnRzeCcsICcubXRzJywgJy5jdHMnXVxuICAgICAgICAgIDogZXh0ZW5zaW9uID09PSAnLm1qcydcbiAgICAgICAgICAgID8gWycubXRzJ11cbiAgICAgICAgICAgIDogZXh0ZW5zaW9uID09PSAnLmNqcydcbiAgICAgICAgICAgICAgPyBbJy5jdHMnXVxuICAgICAgICAgICAgICA6IGV4dGVuc2lvbiA9PT0gJy5qc3gnXG4gICAgICAgICAgICAgICAgPyBbJy50c3gnXVxuICAgICAgICAgICAgICAgIDogW107XG5cbiAgICAgIGlmIChleHRlbnNpb25GYWxsYmFja3MubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiB0YXJnZXRQYXRoO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB0YXJnZXRXaXRob3V0RXh0ZW5zaW9uID0gdGFyZ2V0UGF0aC5zbGljZSgwLCAtZXh0ZW5zaW9uLmxlbmd0aCk7XG4gICAgICBmb3IgKGNvbnN0IGZhbGxiYWNrRXh0ZW5zaW9uIG9mIGV4dGVuc2lvbkZhbGxiYWNrcykge1xuICAgICAgICBjb25zdCBmYWxsYmFja1BhdGggPSBgJHt0YXJnZXRXaXRob3V0RXh0ZW5zaW9ufSR7ZmFsbGJhY2tFeHRlbnNpb259YDtcbiAgICAgICAgaWYgKGV4aXN0c1N5bmMoZmFsbGJhY2tQYXRoKSkge1xuICAgICAgICAgIHJldHVybiBmYWxsYmFja1BhdGg7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRhcmdldFBhdGg7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBleHRyYWN0UmVsYXRpdmVJbXBvcnRTcGVjaWZpZXJzKHNvdXJjZTogc3RyaW5nKTogc3RyaW5nW10ge1xuICAgICAgcmV0dXJuIHRoaXMuZXh0cmFjdEltcG9ydFNwZWNpZmllcnMoc291cmNlKS5maWx0ZXIoKHNwZWNpZmllcikgPT5cbiAgICAgICAgc3BlY2lmaWVyLnN0YXJ0c1dpdGgoJy4nKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGV4dHJhY3RJbXBvcnRTcGVjaWZpZXJzKHNvdXJjZTogc3RyaW5nKTogc3RyaW5nW10ge1xuICAgICAgY29uc3QgcmVsYXRpdmVTcGVjaWZpZXJzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgICBjb25zdCBpbXBvcnRQYXR0ZXJucyA9IFtcbiAgICAgICAgL2Zyb21cXHMrWydcIl0oW14nXCJdKylbJ1wiXS9nLFxuICAgICAgICAvaW1wb3J0XFxzK1snXCJdKFteJ1wiXSspWydcIl0vZyxcbiAgICAgICAgL2ltcG9ydFxcKFxccypbJ1wiXShbXidcIl0rKVsnXCJdXFxzKlxcKS9nLFxuICAgICAgICAvcmVxdWlyZVxcKFxccypbJ1wiXShbXidcIl0rKVsnXCJdXFxzKlxcKS9nLFxuICAgICAgXTtcblxuICAgICAgZm9yIChjb25zdCBpbXBvcnRQYXR0ZXJuIG9mIGltcG9ydFBhdHRlcm5zKSB7XG4gICAgICAgIGZvciAoY29uc3QgbWF0Y2ggb2Ygc291cmNlLm1hdGNoQWxsKGltcG9ydFBhdHRlcm4pKSB7XG4gICAgICAgICAgY29uc3Qgc3BlY2lmaWVyID0gbWF0Y2hbMV07XG4gICAgICAgICAgaWYgKHNwZWNpZmllcikge1xuICAgICAgICAgICAgcmVsYXRpdmVTcGVjaWZpZXJzLmFkZChzcGVjaWZpZXIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gQXJyYXkuZnJvbShyZWxhdGl2ZVNwZWNpZmllcnMpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgZ2V0UmVsYXRpdmVGaWxlbmFtZUZvclN3YyhmaWxlUGF0aDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgIGNvbnN0IHdvcmtpbmdEaXIgPSB0aGlzLmNvbmZpZy53b3JraW5nRGlyO1xuICAgICAgY29uc3Qgbm9ybWFsaXplZFdvcmtpbmdEaXIgPSB3b3JraW5nRGlyXG4gICAgICAgIC5yZXBsYWNlKC9cXFxcL2csICcvJylcbiAgICAgICAgLnJlcGxhY2UoL1xcLyQvLCAnJyk7XG4gICAgICBjb25zdCBub3JtYWxpemVkRmlsZXBhdGggPSBmaWxlUGF0aC5yZXBsYWNlKC9cXFxcL2csICcvJyk7XG5cbiAgICAgIC8vIFdpbmRvd3MgZml4OiBVc2UgY2FzZS1pbnNlbnNpdGl2ZSBjb21wYXJpc29uIHRvIHdvcmsgYXJvdW5kIGRyaXZlIGxldHRlciBjYXNpbmcgaXNzdWVzLlxuICAgICAgY29uc3QgbG93ZXJXZCA9IG5vcm1hbGl6ZWRXb3JraW5nRGlyLnRvTG93ZXJDYXNlKCk7XG4gICAgICBjb25zdCBsb3dlclBhdGggPSBub3JtYWxpemVkRmlsZXBhdGgudG9Mb3dlckNhc2UoKTtcblxuICAgICAgbGV0IHJlbGF0aXZlRmlsZW5hbWU6IHN0cmluZztcbiAgICAgIGlmIChsb3dlclBhdGguc3RhcnRzV2l0aChgJHtsb3dlcldkfS9gKSkge1xuICAgICAgICByZWxhdGl2ZUZpbGVuYW1lID0gbm9ybWFsaXplZEZpbGVwYXRoLnN1YnN0cmluZyhcbiAgICAgICAgICBub3JtYWxpemVkV29ya2luZ0Rpci5sZW5ndGggKyAxXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKGxvd2VyUGF0aCA9PT0gbG93ZXJXZCkge1xuICAgICAgICByZWxhdGl2ZUZpbGVuYW1lID0gJy4nO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVsYXRpdmVGaWxlbmFtZSA9IHJlbGF0aXZlKHdvcmtpbmdEaXIsIGZpbGVQYXRoKS5yZXBsYWNlKC9cXFxcL2csICcvJyk7XG4gICAgICAgIGlmIChyZWxhdGl2ZUZpbGVuYW1lLnN0YXJ0c1dpdGgoJy4uLycpKSB7XG4gICAgICAgICAgY29uc3QgYWxpYXNlZFJlbGF0aXZlUGF0aCA9IGF3YWl0IHJlc29sdmVXb3JrZmxvd0FsaWFzUmVsYXRpdmVQYXRoKFxuICAgICAgICAgICAgZmlsZVBhdGgsXG4gICAgICAgICAgICB3b3JraW5nRGlyXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoYWxpYXNlZFJlbGF0aXZlUGF0aCkge1xuICAgICAgICAgICAgcmVsYXRpdmVGaWxlbmFtZSA9IGFsaWFzZWRSZWxhdGl2ZVBhdGg7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlbGF0aXZlRmlsZW5hbWUgPSByZWxhdGl2ZUZpbGVuYW1lXG4gICAgICAgICAgICAgIC5zcGxpdCgnLycpXG4gICAgICAgICAgICAgIC5maWx0ZXIoKHBhcnQpID0+IHBhcnQgIT09ICcuLicpXG4gICAgICAgICAgICAgIC5qb2luKCcvJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChyZWxhdGl2ZUZpbGVuYW1lLmluY2x1ZGVzKCc6JykgfHwgcmVsYXRpdmVGaWxlbmFtZS5zdGFydHNXaXRoKCcvJykpIHtcbiAgICAgICAgcmVsYXRpdmVGaWxlbmFtZSA9IGJhc2VuYW1lKG5vcm1hbGl6ZWRGaWxlcGF0aCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZWxhdGl2ZUZpbGVuYW1lO1xuICAgIH1cblxuICAgIHByaXZhdGUgcmVzb2x2ZUltcG9ydFRhcmdldFdpdGhFeHRlbnNpb25GYWxsYmFja3MoXG4gICAgICB0YXJnZXRQYXRoOiBzdHJpbmdcbiAgICApOiBzdHJpbmcge1xuICAgICAgaWYgKGV4aXN0c1N5bmModGFyZ2V0UGF0aCkpIHtcbiAgICAgICAgcmV0dXJuIHRhcmdldFBhdGg7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGV4dGVuc2lvbk1hdGNoID0gdGFyZ2V0UGF0aC5tYXRjaCgvKFxcLlteLi9cXFxcXSspJC8pO1xuICAgICAgY29uc3QgZXh0ZW5zaW9uID0gZXh0ZW5zaW9uTWF0Y2g/LlsxXT8udG9Mb3dlckNhc2UoKTtcbiAgICAgIGlmICghZXh0ZW5zaW9uKSB7XG4gICAgICAgIHJldHVybiB0YXJnZXRQYXRoO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBleHRlbnNpb25GYWxsYmFja3MgPVxuICAgICAgICBleHRlbnNpb24gPT09ICcuanMnXG4gICAgICAgICAgPyBbJy50cycsICcudHN4JywgJy5tdHMnLCAnLmN0cyddXG4gICAgICAgICAgOiBleHRlbnNpb24gPT09ICcubWpzJ1xuICAgICAgICAgICAgPyBbJy5tdHMnXVxuICAgICAgICAgICAgOiBleHRlbnNpb24gPT09ICcuY2pzJ1xuICAgICAgICAgICAgICA/IFsnLmN0cyddXG4gICAgICAgICAgICAgIDogZXh0ZW5zaW9uID09PSAnLmpzeCdcbiAgICAgICAgICAgICAgICA/IFsnLnRzeCddXG4gICAgICAgICAgICAgICAgOiBbXTtcblxuICAgICAgaWYgKGV4dGVuc2lvbkZhbGxiYWNrcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHRhcmdldFBhdGg7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHRhcmdldFdpdGhvdXRFeHRlbnNpb24gPSB0YXJnZXRQYXRoLnNsaWNlKDAsIC1leHRlbnNpb24ubGVuZ3RoKTtcbiAgICAgIGZvciAoY29uc3QgZmFsbGJhY2tFeHRlbnNpb24gb2YgZXh0ZW5zaW9uRmFsbGJhY2tzKSB7XG4gICAgICAgIGNvbnN0IGZhbGxiYWNrUGF0aCA9IGAke3RhcmdldFdpdGhvdXRFeHRlbnNpb259JHtmYWxsYmFja0V4dGVuc2lvbn1gO1xuICAgICAgICBpZiAoZXhpc3RzU3luYyhmYWxsYmFja1BhdGgpKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbGxiYWNrUGF0aDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGFyZ2V0UGF0aDtcbiAgICB9XG5cbiAgICBwcml2YXRlIHNob3VsZFNraXBUcmFuc2l0aXZlU3RlcEZpbGUoZmlsZVBhdGg6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgY29uc3Qgbm9ybWFsaXplZFBhdGggPSBmaWxlUGF0aC5yZXBsYWNlKC9cXFxcL2csICcvJyk7XG4gICAgICBjb25zdCBpc1NvdXJjZUJhY2tlZFBhY2thZ2VQYXRoID1cbiAgICAgICAgdGhpcy5zaG91bGRQcmVmZXJTb3VyY2VCYWNrZWRQYWNrYWdlUGF0aChmaWxlUGF0aCk7XG4gICAgICByZXR1cm4gKFxuICAgICAgICBub3JtYWxpemVkUGF0aC5pbmNsdWRlcygnLy53ZWxsLWtub3duL3dvcmtmbG93LycpIHx8XG4gICAgICAgIG5vcm1hbGl6ZWRQYXRoLmluY2x1ZGVzKCcvLm5leHQvJykgfHxcbiAgICAgICAgKCFpc1NvdXJjZUJhY2tlZFBhY2thZ2VQYXRoICYmXG4gICAgICAgICAgKG5vcm1hbGl6ZWRQYXRoLmluY2x1ZGVzKCcvbm9kZV9tb2R1bGVzLycpIHx8XG4gICAgICAgICAgICBub3JtYWxpemVkUGF0aC5pbmNsdWRlcygnLy5wbnBtLycpKSlcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyByZXNvbHZlVHJhbnNpdGl2ZVN0ZXBJbXBvcnRUYXJnZXRQYXRoKFxuICAgICAgc291cmNlRmlsZVBhdGg6IHN0cmluZyxcbiAgICAgIHNwZWNpZmllcjogc3RyaW5nXG4gICAgKTogUHJvbWlzZTxzdHJpbmcgfCBudWxsPiB7XG4gICAgICBjb25zdCBzcGVjaWZpZXJNYXRjaCA9IHNwZWNpZmllci5tYXRjaCgvXihbXj8jXSspKC4qKSQvKTtcbiAgICAgIGNvbnN0IGltcG9ydFBhdGggPSBzcGVjaWZpZXJNYXRjaD8uWzFdID8/IHNwZWNpZmllcjtcblxuICAgICAgaWYgKCFpbXBvcnRQYXRoLnN0YXJ0c1dpdGgoJy4nKSkge1xuICAgICAgICBpZiAoaW1wb3J0UGF0aCAhPT0gJ3dvcmtmbG93JyAmJiAhaW1wb3J0UGF0aC5zdGFydHNXaXRoKCdAd29ya2Zsb3cvJykpIHtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgcmVzb2x2ZWRQYXRoID1cbiAgICAgICAgICAgIGNyZWF0ZVJlcXVpcmUoc291cmNlRmlsZVBhdGgpLnJlc29sdmUoaW1wb3J0UGF0aCk7XG4gICAgICAgICAgY29uc3Qgbm9ybWFsaXplZFJlc29sdmVkUGF0aCA9XG4gICAgICAgICAgICB0aGlzLm5vcm1hbGl6ZURpc2NvdmVyZWRGaWxlUGF0aChyZXNvbHZlZFBhdGgpO1xuICAgICAgICAgIGlmICh0aGlzLnNob3VsZFNraXBUcmFuc2l0aXZlU3RlcEZpbGUobm9ybWFsaXplZFJlc29sdmVkUGF0aCkpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGZpbGVTdGF0cyA9IGF3YWl0IHN0YXQobm9ybWFsaXplZFJlc29sdmVkUGF0aCk7XG4gICAgICAgICAgcmV0dXJuIGZpbGVTdGF0cy5pc0ZpbGUoKSA/IG5vcm1hbGl6ZWRSZXNvbHZlZFBhdGggOiBudWxsO1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBhYnNvbHV0ZVRhcmdldFBhdGggPSByZXNvbHZlKGRpcm5hbWUoc291cmNlRmlsZVBhdGgpLCBpbXBvcnRQYXRoKTtcblxuICAgICAgY29uc3QgY2FuZGlkYXRlUGF0aHMgPSBuZXcgU2V0PHN0cmluZz4oW1xuICAgICAgICB0aGlzLnJlc29sdmVJbXBvcnRUYXJnZXRXaXRoRXh0ZW5zaW9uRmFsbGJhY2tzKGFic29sdXRlVGFyZ2V0UGF0aCksXG4gICAgICBdKTtcblxuICAgICAgaWYgKCFleHRuYW1lKGFic29sdXRlVGFyZ2V0UGF0aCkpIHtcbiAgICAgICAgY29uc3QgZXh0ZW5zaW9uQ2FuZGlkYXRlcyA9IFtcbiAgICAgICAgICAnLnRzJyxcbiAgICAgICAgICAnLnRzeCcsXG4gICAgICAgICAgJy5tdHMnLFxuICAgICAgICAgICcuY3RzJyxcbiAgICAgICAgICAnLmpzJyxcbiAgICAgICAgICAnLmpzeCcsXG4gICAgICAgICAgJy5tanMnLFxuICAgICAgICAgICcuY2pzJyxcbiAgICAgICAgXTtcbiAgICAgICAgZm9yIChjb25zdCBleHRlbnNpb25DYW5kaWRhdGUgb2YgZXh0ZW5zaW9uQ2FuZGlkYXRlcykge1xuICAgICAgICAgIGNhbmRpZGF0ZVBhdGhzLmFkZChgJHthYnNvbHV0ZVRhcmdldFBhdGh9JHtleHRlbnNpb25DYW5kaWRhdGV9YCk7XG4gICAgICAgICAgY2FuZGlkYXRlUGF0aHMuYWRkKFxuICAgICAgICAgICAgam9pbihhYnNvbHV0ZVRhcmdldFBhdGgsIGBpbmRleCR7ZXh0ZW5zaW9uQ2FuZGlkYXRlfWApXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IGNhbmRpZGF0ZVBhdGggb2YgY2FuZGlkYXRlUGF0aHMpIHtcbiAgICAgICAgY29uc3QgcmVzb2x2ZWRQYXRoID1cbiAgICAgICAgICB0aGlzLnJlc29sdmVJbXBvcnRUYXJnZXRXaXRoRXh0ZW5zaW9uRmFsbGJhY2tzKGNhbmRpZGF0ZVBhdGgpO1xuICAgICAgICBjb25zdCBub3JtYWxpemVkUmVzb2x2ZWRQYXRoID1cbiAgICAgICAgICB0aGlzLm5vcm1hbGl6ZURpc2NvdmVyZWRGaWxlUGF0aChyZXNvbHZlZFBhdGgpO1xuXG4gICAgICAgIGlmICh0aGlzLnNob3VsZFNraXBUcmFuc2l0aXZlU3RlcEZpbGUobm9ybWFsaXplZFJlc29sdmVkUGF0aCkpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgZmlsZVN0YXRzID0gYXdhaXQgc3RhdChub3JtYWxpemVkUmVzb2x2ZWRQYXRoKTtcbiAgICAgICAgICBpZiAoZmlsZVN0YXRzLmlzRmlsZSgpKSB7XG4gICAgICAgICAgICByZXR1cm4gbm9ybWFsaXplZFJlc29sdmVkUGF0aDtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgIC8vIFRyeSB0aGUgbmV4dCBjYW5kaWRhdGUgcGF0aC5cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGNvbGxlY3RUcmFuc2l0aXZlU3RlcEZpbGVzKHtcbiAgICAgIGVudHJ5RmlsZXMsXG4gICAgICBzdGVwRmlsZXMsXG4gICAgfToge1xuICAgICAgZW50cnlGaWxlczogc3RyaW5nW107XG4gICAgICBzdGVwRmlsZXM6IHN0cmluZ1tdO1xuICAgIH0pOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgICBjb25zdCBub3JtYWxpemVkRW50cnlGaWxlcyA9IEFycmF5LmZyb20oXG4gICAgICAgIG5ldyBTZXQoXG4gICAgICAgICAgZW50cnlGaWxlcy5tYXAoKGVudHJ5RmlsZSkgPT5cbiAgICAgICAgICAgIHRoaXMubm9ybWFsaXplRGlzY292ZXJlZEZpbGVQYXRoKGVudHJ5RmlsZSlcbiAgICAgICAgICApXG4gICAgICAgIClcbiAgICAgICkuc29ydCgpO1xuICAgICAgY29uc3Qgbm9ybWFsaXplZFN0ZXBTZWVkRmlsZXMgPSBBcnJheS5mcm9tKFxuICAgICAgICBuZXcgU2V0KFxuICAgICAgICAgIHN0ZXBGaWxlcy5tYXAoKHN0ZXBGaWxlKSA9PlxuICAgICAgICAgICAgdGhpcy5ub3JtYWxpemVEaXNjb3ZlcmVkRmlsZVBhdGgoc3RlcEZpbGUpXG4gICAgICAgICAgKVxuICAgICAgICApXG4gICAgICApLnNvcnQoKTtcbiAgICAgIGNvbnN0IGRpc2NvdmVyZWRTdGVwRmlsZXMgPSBuZXcgU2V0PHN0cmluZz4obm9ybWFsaXplZFN0ZXBTZWVkRmlsZXMpO1xuICAgICAgY29uc3QgcXVldWVkRmlsZXMgPSBBcnJheS5mcm9tKFxuICAgICAgICBuZXcgU2V0KFsuLi5ub3JtYWxpemVkRW50cnlGaWxlcywgLi4ubm9ybWFsaXplZFN0ZXBTZWVkRmlsZXNdKVxuICAgICAgKTtcbiAgICAgIGNvbnN0IHZpc2l0ZWRGaWxlcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgICAgY29uc3Qgc291cmNlQ2FjaGUgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nIHwgbnVsbD4oKTtcbiAgICAgIGNvbnN0IHBhdHRlcm5DYWNoZSA9IG5ldyBNYXA8XG4gICAgICAgIHN0cmluZyxcbiAgICAgICAgUmV0dXJuVHlwZTx0eXBlb2YgZGV0ZWN0V29ya2Zsb3dQYXR0ZXJucz4gfCBudWxsXG4gICAgICA+KCk7XG5cbiAgICAgIGNvbnN0IGdldFNvdXJjZSA9IGFzeW5jIChmaWxlUGF0aDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmcgfCBudWxsPiA9PiB7XG4gICAgICAgIGlmIChzb3VyY2VDYWNoZS5oYXMoZmlsZVBhdGgpKSB7XG4gICAgICAgICAgcmV0dXJuIHNvdXJjZUNhY2hlLmdldChmaWxlUGF0aCkgPz8gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHNvdXJjZSA9IGF3YWl0IHJlYWRGaWxlKGZpbGVQYXRoLCAndXRmLTgnKTtcbiAgICAgICAgICBzb3VyY2VDYWNoZS5zZXQoZmlsZVBhdGgsIHNvdXJjZSk7XG4gICAgICAgICAgcmV0dXJuIHNvdXJjZTtcbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgc291cmNlQ2FjaGUuc2V0KGZpbGVQYXRoLCBudWxsKTtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgY29uc3QgZ2V0UGF0dGVybnMgPSBhc3luYyAoXG4gICAgICAgIGZpbGVQYXRoOiBzdHJpbmdcbiAgICAgICk6IFByb21pc2U8UmV0dXJuVHlwZTx0eXBlb2YgZGV0ZWN0V29ya2Zsb3dQYXR0ZXJucz4gfCBudWxsPiA9PiB7XG4gICAgICAgIGlmIChwYXR0ZXJuQ2FjaGUuaGFzKGZpbGVQYXRoKSkge1xuICAgICAgICAgIHJldHVybiBwYXR0ZXJuQ2FjaGUuZ2V0KGZpbGVQYXRoKSA/PyBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHNvdXJjZSA9IGF3YWl0IGdldFNvdXJjZShmaWxlUGF0aCk7XG4gICAgICAgIGlmIChzb3VyY2UgPT09IG51bGwpIHtcbiAgICAgICAgICBwYXR0ZXJuQ2FjaGUuc2V0KGZpbGVQYXRoLCBudWxsKTtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwYXR0ZXJucyA9IGRldGVjdFdvcmtmbG93UGF0dGVybnMoc291cmNlKTtcbiAgICAgICAgcGF0dGVybkNhY2hlLnNldChmaWxlUGF0aCwgcGF0dGVybnMpO1xuICAgICAgICByZXR1cm4gcGF0dGVybnM7XG4gICAgICB9O1xuXG4gICAgICB3aGlsZSAocXVldWVkRmlsZXMubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCBjdXJyZW50RmlsZSA9IHF1ZXVlZEZpbGVzLnBvcCgpO1xuICAgICAgICBpZiAoIWN1cnJlbnRGaWxlIHx8IHZpc2l0ZWRGaWxlcy5oYXMoY3VycmVudEZpbGUpKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdmlzaXRlZEZpbGVzLmFkZChjdXJyZW50RmlsZSk7XG5cbiAgICAgICAgY29uc3QgY3VycmVudFNvdXJjZSA9IGF3YWl0IGdldFNvdXJjZShjdXJyZW50RmlsZSk7XG4gICAgICAgIGlmIChjdXJyZW50U291cmNlID09PSBudWxsKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBpbXBvcnRTcGVjaWZpZXJzID0gdGhpcy5leHRyYWN0SW1wb3J0U3BlY2lmaWVycyhjdXJyZW50U291cmNlKTtcbiAgICAgICAgZm9yIChjb25zdCBzcGVjaWZpZXIgb2YgaW1wb3J0U3BlY2lmaWVycykge1xuICAgICAgICAgIGNvbnN0IHJlc29sdmVkSW1wb3J0UGF0aCA9XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnJlc29sdmVUcmFuc2l0aXZlU3RlcEltcG9ydFRhcmdldFBhdGgoXG4gICAgICAgICAgICAgIGN1cnJlbnRGaWxlLFxuICAgICAgICAgICAgICBzcGVjaWZpZXJcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKCFyZXNvbHZlZEltcG9ydFBhdGgpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICghdmlzaXRlZEZpbGVzLmhhcyhyZXNvbHZlZEltcG9ydFBhdGgpKSB7XG4gICAgICAgICAgICBxdWV1ZWRGaWxlcy5wdXNoKHJlc29sdmVkSW1wb3J0UGF0aCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgaW1wb3J0UGF0dGVybnMgPSBhd2FpdCBnZXRQYXR0ZXJucyhyZXNvbHZlZEltcG9ydFBhdGgpO1xuICAgICAgICAgIGlmIChpbXBvcnRQYXR0ZXJucz8uaGFzVXNlU3RlcCkge1xuICAgICAgICAgICAgZGlzY292ZXJlZFN0ZXBGaWxlcy5hZGQocmVzb2x2ZWRJbXBvcnRQYXRoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIEFycmF5LmZyb20oZGlzY292ZXJlZFN0ZXBGaWxlcykuc29ydCgpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgY29sbGVjdFRyYW5zaXRpdmVTZXJkZUZpbGVzKHtcbiAgICAgIGVudHJ5RmlsZXMsXG4gICAgICBzZXJkZUZpbGVzLFxuICAgIH06IHtcbiAgICAgIGVudHJ5RmlsZXM6IHN0cmluZ1tdO1xuICAgICAgc2VyZGVGaWxlczogc3RyaW5nW107XG4gICAgfSk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWRFbnRyeUZpbGVzID0gQXJyYXkuZnJvbShcbiAgICAgICAgbmV3IFNldChcbiAgICAgICAgICBlbnRyeUZpbGVzLm1hcCgoZW50cnlGaWxlKSA9PlxuICAgICAgICAgICAgdGhpcy5ub3JtYWxpemVEaXNjb3ZlcmVkRmlsZVBhdGgoZW50cnlGaWxlKVxuICAgICAgICAgIClcbiAgICAgICAgKVxuICAgICAgKS5zb3J0KCk7XG4gICAgICBjb25zdCBub3JtYWxpemVkU2VyZGVTZWVkRmlsZXMgPSBBcnJheS5mcm9tKFxuICAgICAgICBuZXcgU2V0KFxuICAgICAgICAgIHNlcmRlRmlsZXMubWFwKChzZXJkZUZpbGUpID0+XG4gICAgICAgICAgICB0aGlzLm5vcm1hbGl6ZURpc2NvdmVyZWRGaWxlUGF0aChzZXJkZUZpbGUpXG4gICAgICAgICAgKVxuICAgICAgICApXG4gICAgICApLnNvcnQoKTtcbiAgICAgIC8vIEludGVudGlvbmFsbHkgcmUtdmFsaWRhdGUgc2VyZGUgc2VlZHMgYWdhaW5zdCBzb3VyY2UgcGF0dGVybnMuXG4gICAgICAvLyBUaGlzIGtlZXBzIHByZXZpb3VzbHkgZGlzY292ZXJlZC9tYW51YWwgc2VlZCBlbnRyaWVzIGZyb20gc3RpY2tpbmcgd2hlblxuICAgICAgLy8gZmlsZXMgbm8gbG9uZ2VyIG1hdGNoIHNlcmRlIHBhdHRlcm5zLlxuICAgICAgY29uc3QgZGlzY292ZXJlZFNlcmRlRmlsZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICAgIGNvbnN0IHF1ZXVlZEZpbGVzID0gQXJyYXkuZnJvbShcbiAgICAgICAgbmV3IFNldChbLi4ubm9ybWFsaXplZEVudHJ5RmlsZXMsIC4uLm5vcm1hbGl6ZWRTZXJkZVNlZWRGaWxlc10pXG4gICAgICApO1xuICAgICAgY29uc3QgdmlzaXRlZEZpbGVzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgICBjb25zdCBzb3VyY2VDYWNoZSA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmcgfCBudWxsPigpO1xuICAgICAgY29uc3QgcGF0dGVybkNhY2hlID0gbmV3IE1hcDxcbiAgICAgICAgc3RyaW5nLFxuICAgICAgICBSZXR1cm5UeXBlPHR5cGVvZiBkZXRlY3RXb3JrZmxvd1BhdHRlcm5zPiB8IG51bGxcbiAgICAgID4oKTtcblxuICAgICAgY29uc3QgZ2V0U291cmNlID0gYXN5bmMgKGZpbGVQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZyB8IG51bGw+ID0+IHtcbiAgICAgICAgaWYgKHNvdXJjZUNhY2hlLmhhcyhmaWxlUGF0aCkpIHtcbiAgICAgICAgICByZXR1cm4gc291cmNlQ2FjaGUuZ2V0KGZpbGVQYXRoKSA/PyBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3Qgc291cmNlID0gYXdhaXQgcmVhZEZpbGUoZmlsZVBhdGgsICd1dGYtOCcpO1xuICAgICAgICAgIHNvdXJjZUNhY2hlLnNldChmaWxlUGF0aCwgc291cmNlKTtcbiAgICAgICAgICByZXR1cm4gc291cmNlO1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICBzb3VyY2VDYWNoZS5zZXQoZmlsZVBhdGgsIG51bGwpO1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBjb25zdCBnZXRQYXR0ZXJucyA9IGFzeW5jIChcbiAgICAgICAgZmlsZVBhdGg6IHN0cmluZ1xuICAgICAgKTogUHJvbWlzZTxSZXR1cm5UeXBlPHR5cGVvZiBkZXRlY3RXb3JrZmxvd1BhdHRlcm5zPiB8IG51bGw+ID0+IHtcbiAgICAgICAgaWYgKHBhdHRlcm5DYWNoZS5oYXMoZmlsZVBhdGgpKSB7XG4gICAgICAgICAgcmV0dXJuIHBhdHRlcm5DYWNoZS5nZXQoZmlsZVBhdGgpID8/IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc291cmNlID0gYXdhaXQgZ2V0U291cmNlKGZpbGVQYXRoKTtcbiAgICAgICAgaWYgKHNvdXJjZSA9PT0gbnVsbCkge1xuICAgICAgICAgIHBhdHRlcm5DYWNoZS5zZXQoZmlsZVBhdGgsIG51bGwpO1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBhdHRlcm5zID0gZGV0ZWN0V29ya2Zsb3dQYXR0ZXJucyhzb3VyY2UpO1xuICAgICAgICBwYXR0ZXJuQ2FjaGUuc2V0KGZpbGVQYXRoLCBwYXR0ZXJucyk7XG4gICAgICAgIHJldHVybiBwYXR0ZXJucztcbiAgICAgIH07XG5cbiAgICAgIGZvciAoY29uc3Qgc2VyZGVTZWVkRmlsZSBvZiBub3JtYWxpemVkU2VyZGVTZWVkRmlsZXMpIHtcbiAgICAgICAgY29uc3Qgc2VlZFBhdHRlcm5zID0gYXdhaXQgZ2V0UGF0dGVybnMoc2VyZGVTZWVkRmlsZSk7XG4gICAgICAgIGlmIChzZWVkUGF0dGVybnM/Lmhhc1NlcmRlKSB7XG4gICAgICAgICAgZGlzY292ZXJlZFNlcmRlRmlsZXMuYWRkKHNlcmRlU2VlZEZpbGUpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHdoaWxlIChxdWV1ZWRGaWxlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRGaWxlID0gcXVldWVkRmlsZXMucG9wKCk7XG4gICAgICAgIGlmICghY3VycmVudEZpbGUgfHwgdmlzaXRlZEZpbGVzLmhhcyhjdXJyZW50RmlsZSkpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICB2aXNpdGVkRmlsZXMuYWRkKGN1cnJlbnRGaWxlKTtcblxuICAgICAgICBjb25zdCBjdXJyZW50U291cmNlID0gYXdhaXQgZ2V0U291cmNlKGN1cnJlbnRGaWxlKTtcbiAgICAgICAgaWYgKGN1cnJlbnRTb3VyY2UgPT09IG51bGwpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlbGF0aXZlSW1wb3J0U3BlY2lmaWVycyA9XG4gICAgICAgICAgdGhpcy5leHRyYWN0UmVsYXRpdmVJbXBvcnRTcGVjaWZpZXJzKGN1cnJlbnRTb3VyY2UpO1xuICAgICAgICBmb3IgKGNvbnN0IHNwZWNpZmllciBvZiByZWxhdGl2ZUltcG9ydFNwZWNpZmllcnMpIHtcbiAgICAgICAgICBjb25zdCByZXNvbHZlZEltcG9ydFBhdGggPVxuICAgICAgICAgICAgYXdhaXQgdGhpcy5yZXNvbHZlVHJhbnNpdGl2ZVN0ZXBJbXBvcnRUYXJnZXRQYXRoKFxuICAgICAgICAgICAgICBjdXJyZW50RmlsZSxcbiAgICAgICAgICAgICAgc3BlY2lmaWVyXG4gICAgICAgICAgICApO1xuICAgICAgICAgIGlmICghcmVzb2x2ZWRJbXBvcnRQYXRoKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoIXZpc2l0ZWRGaWxlcy5oYXMocmVzb2x2ZWRJbXBvcnRQYXRoKSkge1xuICAgICAgICAgICAgcXVldWVkRmlsZXMucHVzaChyZXNvbHZlZEltcG9ydFBhdGgpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGltcG9ydFBhdHRlcm5zID0gYXdhaXQgZ2V0UGF0dGVybnMocmVzb2x2ZWRJbXBvcnRQYXRoKTtcbiAgICAgICAgICBpZiAoaW1wb3J0UGF0dGVybnM/Lmhhc1NlcmRlKSB7XG4gICAgICAgICAgICBkaXNjb3ZlcmVkU2VyZGVGaWxlcy5hZGQocmVzb2x2ZWRJbXBvcnRQYXRoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gQVNULWxldmVsIHZlcmlmaWNhdGlvbjogcnVuIFNXQyBkZXRlY3QgbW9kZSBvbiByZWdleC1tYXRjaGVkIGNhbmRpZGF0ZXNcbiAgICAgIC8vIHRvIGNvbmZpcm0gdGhleSBhY3R1YWxseSBkZWZpbmUgc2VyZGUgY2xhc3Nlcy4gVGhpcyBwcmV2ZW50cyBTREsgaW50ZXJuYWxcbiAgICAgIC8vIGZpbGVzICh3aGljaCBtYXRjaCBzZXJkZSByZWdleCBwYXR0ZXJucyBidXQgZGVmaW5lIG5vIGNsYXNzZXMpIGZyb20gYmVpbmdcbiAgICAgIC8vIGJ1bmRsZWQgaW50byB0aGUgd29ya2Zsb3cgc2FuZGJveC5cbiAgICAgIGNvbnN0IHByb2plY3RSb290ID0gdGhpcy5jb25maWcucHJvamVjdFJvb3QgfHwgdGhpcy5jb25maWcud29ya2luZ0RpcjtcbiAgICAgIGNvbnN0IHZlcmlmaWVkU2VyZGVGaWxlczogc3RyaW5nW10gPSBbXTtcbiAgICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICBBcnJheS5mcm9tKGRpc2NvdmVyZWRTZXJkZUZpbGVzKS5tYXAoYXN5bmMgKGZpbGVQYXRoKSA9PiB7XG4gICAgICAgICAgY29uc3Qgc291cmNlID0gYXdhaXQgZ2V0U291cmNlKGZpbGVQYXRoKTtcbiAgICAgICAgICBpZiAoIXNvdXJjZSkgcmV0dXJuO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCByZWxhdGl2ZUZpbGVuYW1lID1cbiAgICAgICAgICAgICAgYXdhaXQgdGhpcy5nZXRSZWxhdGl2ZUZpbGVuYW1lRm9yU3djKGZpbGVQYXRoKTtcbiAgICAgICAgICAgIGNvbnN0IHsgd29ya2Zsb3dNYW5pZmVzdCB9ID0gYXdhaXQgYXBwbHlTd2NUcmFuc2Zvcm0oXG4gICAgICAgICAgICAgIHJlbGF0aXZlRmlsZW5hbWUsXG4gICAgICAgICAgICAgIHNvdXJjZSxcbiAgICAgICAgICAgICAgJ2RldGVjdCcsXG4gICAgICAgICAgICAgIGZpbGVQYXRoLFxuICAgICAgICAgICAgICBwcm9qZWN0Um9vdFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIC8vIE9ubHkgaW5jbHVkZSBmaWxlcyB0aGF0IGFjdHVhbGx5IGRlZmluZSBzZXJkZSBjbGFzc2VzXG4gICAgICAgICAgICBjb25zdCBoYXNDbGFzc2VzID1cbiAgICAgICAgICAgICAgd29ya2Zsb3dNYW5pZmVzdC5jbGFzc2VzICYmXG4gICAgICAgICAgICAgIE9iamVjdC52YWx1ZXMod29ya2Zsb3dNYW5pZmVzdC5jbGFzc2VzKS5zb21lKFxuICAgICAgICAgICAgICAgIChlbnRyaWVzKSA9PiBPYmplY3Qua2V5cyhlbnRyaWVzKS5sZW5ndGggPiAwXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAoaGFzQ2xhc3Nlcykge1xuICAgICAgICAgICAgICB2ZXJpZmllZFNlcmRlRmlsZXMucHVzaChmaWxlUGF0aCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAvLyBJZiBkZXRlY3QgZmFpbHMsIGluY2x1ZGUgdGhlIGZpbGUgdG8gYmUgc2FmZVxuICAgICAgICAgICAgdmVyaWZpZWRTZXJkZUZpbGVzLnB1c2goZmlsZVBhdGgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICk7XG5cbiAgICAgIHJldHVybiB2ZXJpZmllZFNlcmRlRmlsZXMuc29ydCgpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgYnVpbGRXZWJob29rUm91dGUoe1xuICAgICAgd29ya2Zsb3dHZW5lcmF0ZWREaXIsXG4gICAgICByb3V0ZUZpbGVOYW1lID0gJ3JvdXRlLmpzJyxcbiAgICB9OiB7XG4gICAgICB3b3JrZmxvd0dlbmVyYXRlZERpcjogc3RyaW5nO1xuICAgICAgcm91dGVGaWxlTmFtZT86IHN0cmluZztcbiAgICB9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICBjb25zdCB3ZWJob29rUm91dGVGaWxlID0gam9pbihcbiAgICAgICAgd29ya2Zsb3dHZW5lcmF0ZWREaXIsXG4gICAgICAgIGB3ZWJob29rL1t0b2tlbl0vJHtyb3V0ZUZpbGVOYW1lfWBcbiAgICAgICk7XG4gICAgICBhd2FpdCB0aGlzLmNyZWF0ZVdlYmhvb2tCdW5kbGUoe1xuICAgICAgICBvdXRmaWxlOiB3ZWJob29rUm91dGVGaWxlLFxuICAgICAgICBidW5kbGU6IGZhbHNlLCAvLyBOZXh0LmpzIGRvZXNuJ3QgbmVlZCBidW5kbGluZ1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBmaW5kQXBwRGlyZWN0b3J5KCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICBjb25zdCBhcHBEaXIgPSByZXNvbHZlKHRoaXMuY29uZmlnLndvcmtpbmdEaXIsICdhcHAnKTtcbiAgICAgIGNvbnN0IHNyY0FwcERpciA9IHJlc29sdmUodGhpcy5jb25maWcud29ya2luZ0RpciwgJ3NyYy9hcHAnKTtcbiAgICAgIGNvbnN0IHBhZ2VzRGlyID0gcmVzb2x2ZSh0aGlzLmNvbmZpZy53b3JraW5nRGlyLCAncGFnZXMnKTtcbiAgICAgIGNvbnN0IHNyY1BhZ2VzRGlyID0gcmVzb2x2ZSh0aGlzLmNvbmZpZy53b3JraW5nRGlyLCAnc3JjL3BhZ2VzJyk7XG5cbiAgICAgIC8vIEhlbHBlciB0byBjaGVjayBpZiBhIHBhdGggZXhpc3RzIGFuZCBpcyBhIGRpcmVjdG9yeVxuICAgICAgY29uc3QgaXNEaXJlY3RvcnkgPSBhc3luYyAocGF0aDogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgYWNjZXNzKHBhdGgsIGNvbnN0YW50cy5GX09LKTtcbiAgICAgICAgICBjb25zdCBzdGF0cyA9IGF3YWl0IHN0YXQocGF0aCk7XG4gICAgICAgICAgaWYgKCFzdGF0cy5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFBhdGggZXhpc3RzIGJ1dCBpcyBub3QgYSBkaXJlY3Rvcnk6ICR7cGF0aH1gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIEVycm9yICYmIGUubWVzc2FnZS5pbmNsdWRlcygnbm90IGEgZGlyZWN0b3J5JykpIHtcbiAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgLy8gQ2hlY2sgaWYgYXBwIGRpcmVjdG9yeSBleGlzdHNcbiAgICAgIGlmIChhd2FpdCBpc0RpcmVjdG9yeShhcHBEaXIpKSB7XG4gICAgICAgIHJldHVybiBhcHBEaXI7XG4gICAgICB9XG5cbiAgICAgIC8vIENoZWNrIGlmIHNyYy9hcHAgZGlyZWN0b3J5IGV4aXN0c1xuICAgICAgaWYgKGF3YWl0IGlzRGlyZWN0b3J5KHNyY0FwcERpcikpIHtcbiAgICAgICAgcmV0dXJuIHNyY0FwcERpcjtcbiAgICAgIH1cblxuICAgICAgLy8gSWYgbm8gYXBwIGRpcmVjdG9yeSBleGlzdHMsIGNoZWNrIGZvciBwYWdlcyBkaXJlY3RvcnkgYW5kIGNyZWF0ZSBhcHAgbmV4dCB0byBpdFxuICAgICAgaWYgKGF3YWl0IGlzRGlyZWN0b3J5KHBhZ2VzRGlyKSkge1xuICAgICAgICAvLyBDcmVhdGUgYXBwIGRpcmVjdG9yeSBuZXh0IHRvIHBhZ2VzIGRpcmVjdG9yeVxuICAgICAgICBhd2FpdCBta2RpcihhcHBEaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgICByZXR1cm4gYXBwRGlyO1xuICAgICAgfVxuXG4gICAgICBpZiAoYXdhaXQgaXNEaXJlY3Rvcnkoc3JjUGFnZXNEaXIpKSB7XG4gICAgICAgIC8vIENyZWF0ZSBzcmMvYXBwIGRpcmVjdG9yeSBuZXh0IHRvIHNyYy9wYWdlcyBkaXJlY3RvcnlcbiAgICAgICAgYXdhaXQgbWtkaXIoc3JjQXBwRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICAgICAgcmV0dXJuIHNyY0FwcERpcjtcbiAgICAgIH1cblxuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnQ291bGQgbm90IGZpbmQgTmV4dC5qcyBhcHAgb3IgcGFnZXMgZGlyZWN0b3J5LiBFeHBlY3RlZCBvbmUgb2Y6IFwiYXBwXCIsIFwic3JjL2FwcFwiLCBcInBhZ2VzXCIsIG9yIFwic3JjL3BhZ2VzXCIgdG8gZXhpc3QuJ1xuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBDYWNoZWROZXh0QnVpbGRlckRlZmVycmVkID0gTmV4dERlZmVycmVkQnVpbGRlcjtcbiAgcmV0dXJuIE5leHREZWZlcnJlZEJ1aWxkZXI7XG59XG4iXX0=
|