@decaf-ts/mcp-server 0.0.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -2
- package/dist/mcp-server.cjs +1989 -341
- package/dist/mcp-server.esm.cjs +1963 -338
- package/lib/McpWrapper.cjs +12 -10
- package/lib/McpWrapper.d.ts +1 -1
- package/lib/bin/validate-modules.cjs +24 -0
- package/lib/bin/validate-modules.d.ts +2 -0
- package/lib/constants.cjs +22 -2
- package/lib/constants.d.ts +16 -0
- package/lib/esm/McpWrapper.d.ts +1 -1
- package/lib/esm/McpWrapper.js +12 -10
- package/lib/esm/bin/validate-modules.d.ts +2 -0
- package/lib/esm/bin/validate-modules.js +22 -0
- package/lib/esm/constants.d.ts +16 -0
- package/lib/esm/constants.js +21 -1
- package/lib/esm/mcp/aggregateModules.d.ts +26 -0
- package/lib/esm/mcp/aggregateModules.js +185 -0
- package/lib/esm/mcp/code.d.ts +23 -0
- package/lib/esm/mcp/code.js +70 -0
- package/lib/esm/mcp/decorator-tools.js +237 -0
- package/lib/esm/mcp/fastmcp-wiring.d.ts +14 -0
- package/lib/esm/mcp/fastmcp-wiring.js +56 -0
- package/lib/esm/mcp/index.d.ts +7 -1
- package/lib/esm/mcp/index.js +26 -2
- package/lib/esm/mcp/mcp-module.d.ts +11 -0
- package/lib/esm/mcp/mcp-module.js +31 -0
- package/lib/esm/mcp/moduleRegistry.d.ts +12 -0
- package/lib/esm/mcp/moduleRegistry.js +46 -0
- package/lib/esm/mcp/prompts/index.d.ts +4 -0
- package/lib/esm/mcp/prompts/index.js +7 -0
- package/lib/esm/mcp/prompts/prompts.d.ts +22 -0
- package/lib/esm/mcp/prompts/prompts.js +197 -0
- package/lib/esm/mcp/resources/index.d.ts +1 -0
- package/lib/esm/mcp/resources/index.js +2 -0
- package/lib/esm/mcp/resources/resources.d.ts +2 -0
- package/lib/esm/mcp/resources/resources.js +69 -0
- package/lib/esm/mcp/schemas.d.ts +53 -0
- package/lib/esm/mcp/schemas.js +97 -0
- package/lib/esm/mcp/templates/codex-templates.d.ts +3 -0
- package/lib/esm/mcp/templates/codex-templates.js +33 -0
- package/lib/esm/mcp/templates/index.d.ts +71 -0
- package/lib/esm/mcp/templates/index.js +66 -0
- package/lib/esm/mcp/templates/resource-templates.d.ts +3 -0
- package/lib/esm/mcp/templates/resource-templates.js +60 -0
- package/lib/esm/mcp/templates/workspace-templates.d.ts +3 -0
- package/lib/esm/mcp/templates/workspace-templates.js +66 -0
- package/lib/esm/mcp/tools/codex-tools.d.ts +5 -0
- package/lib/esm/mcp/tools/codex-tools.js +244 -0
- package/lib/esm/mcp/tools/generateMcpModule.d.ts +9 -0
- package/lib/esm/mcp/tools/generateMcpModule.js +133 -0
- package/lib/esm/mcp/tools/index.d.ts +321 -0
- package/lib/esm/mcp/tools/index.js +29 -0
- package/lib/esm/mcp/tools/tools.d.ts +10 -0
- package/lib/esm/mcp/tools/tools.js +273 -0
- package/lib/esm/mcp/types.d.ts +66 -0
- package/lib/esm/mcp/types.js +2 -0
- package/lib/esm/mcp/utils.d.ts +4 -0
- package/lib/esm/mcp/utils.js +46 -0
- package/lib/esm/mcp/validation/index.d.ts +13 -0
- package/lib/esm/mcp/validation/index.js +116 -0
- package/lib/esm/mcp/validation/scaffoldModule.d.ts +9 -0
- package/lib/esm/mcp/validation/scaffoldModule.js +88 -0
- package/lib/esm/mcp/workspace.d.ts +9 -0
- package/lib/esm/mcp/workspace.js +73 -0
- package/lib/esm/metadata.d.ts +1 -1
- package/lib/esm/metadata.js +1 -1
- package/lib/esm/modules/_template/index.d.ts +32 -0
- package/lib/esm/modules/_template/index.js +16 -0
- package/lib/esm/modules/_template/prompts/index.d.ts +6 -0
- package/lib/esm/modules/_template/prompts/index.js +9 -0
- package/lib/esm/modules/_template/resources/index.d.ts +6 -0
- package/lib/esm/modules/_template/resources/index.js +9 -0
- package/lib/esm/modules/_template/templates/index.d.ts +7 -0
- package/lib/esm/modules/_template/templates/index.js +10 -0
- package/lib/esm/modules/_template/tools/index.d.ts +6 -0
- package/lib/esm/modules/_template/tools/index.js +15 -0
- package/lib/esm/modules/decoration/index.d.ts +46 -0
- package/lib/esm/modules/decoration/index.js +10 -2
- package/lib/esm/modules/decoration/prompts/index.d.ts +1 -0
- package/lib/esm/modules/decoration/prompts/index.js +2 -0
- package/lib/esm/modules/decoration/resources/index.d.ts +7 -0
- package/lib/esm/modules/decoration/resources/index.js +10 -0
- package/lib/esm/modules/decoration/templates/index.d.ts +6 -0
- package/lib/esm/modules/decoration/templates/index.js +9 -0
- package/lib/esm/modules/decoration/tools/index.d.ts +26 -0
- package/lib/esm/modules/decoration/tools/index.js +7 -0
- package/lib/esm/modules/index.d.ts +2 -0
- package/lib/esm/modules/index.js +10 -0
- package/lib/esm/modules/mcp/decoration-assist.d.ts +4 -0
- package/lib/esm/modules/mcp/decoration-assist.js +6 -0
- package/lib/esm/modules/mcp/index.d.ts +6 -2
- package/lib/esm/modules/mcp/index.js +16 -3
- package/lib/esm/modules/mcp/prompts/index.d.ts +2 -0
- package/lib/esm/modules/mcp/prompts/index.js +9 -0
- package/lib/esm/modules/mcp/resources/index.d.ts +2 -0
- package/lib/esm/modules/mcp/resources/index.js +24 -0
- package/lib/esm/modules/mcp/templates/index.d.ts +2 -0
- package/lib/esm/modules/mcp/templates/index.js +28 -0
- package/lib/esm/modules/mcp/tools/index.d.ts +6 -0
- package/lib/esm/modules/mcp/tools/index.js +15 -0
- package/lib/esm/types.d.ts +41 -1
- package/lib/esm/types.js +1 -1
- package/lib/esm/utils/modulePaths.d.ts +6 -0
- package/lib/esm/utils/modulePaths.js +33 -0
- package/lib/esm/utils/moduleValidator.d.ts +14 -0
- package/lib/esm/utils/moduleValidator.js +176 -0
- package/lib/esm/utils.d.ts +1 -0
- package/lib/esm/utils.js +2 -1
- package/lib/mcp/aggregateModules.cjs +225 -0
- package/lib/mcp/aggregateModules.d.ts +26 -0
- package/lib/mcp/code.cjs +81 -0
- package/lib/mcp/code.d.ts +23 -0
- package/lib/mcp/decorator-tools.cjs +243 -0
- package/lib/mcp/fastmcp-wiring.cjs +59 -0
- package/lib/mcp/fastmcp-wiring.d.ts +14 -0
- package/lib/mcp/index.cjs +47 -12
- package/lib/mcp/index.d.ts +7 -1
- package/lib/mcp/mcp-module.cjs +53 -0
- package/lib/mcp/mcp-module.d.ts +11 -0
- package/lib/mcp/moduleRegistry.cjs +50 -0
- package/lib/mcp/moduleRegistry.d.ts +12 -0
- package/lib/mcp/prompts/index.cjs +25 -0
- package/lib/mcp/prompts/index.d.ts +4 -0
- package/lib/mcp/prompts/prompts.cjs +211 -0
- package/lib/mcp/prompts/prompts.d.ts +22 -0
- package/lib/mcp/resources/index.cjs +18 -0
- package/lib/mcp/resources/index.d.ts +1 -0
- package/lib/mcp/resources/resources.cjs +72 -0
- package/lib/mcp/resources/resources.d.ts +2 -0
- package/lib/mcp/schemas.cjs +100 -0
- package/lib/mcp/schemas.d.ts +53 -0
- package/lib/mcp/templates/codex-templates.cjs +40 -0
- package/lib/mcp/templates/codex-templates.d.ts +3 -0
- package/lib/mcp/templates/index.cjs +76 -0
- package/lib/mcp/templates/index.d.ts +71 -0
- package/lib/mcp/templates/resource-templates.cjs +67 -0
- package/lib/mcp/templates/resource-templates.d.ts +3 -0
- package/lib/mcp/templates/workspace-templates.cjs +70 -0
- package/lib/mcp/templates/workspace-templates.d.ts +3 -0
- package/lib/mcp/tools/codex-tools.cjs +250 -0
- package/lib/mcp/tools/codex-tools.d.ts +5 -0
- package/lib/mcp/tools/generateMcpModule.cjs +139 -0
- package/lib/mcp/tools/generateMcpModule.d.ts +9 -0
- package/lib/mcp/tools/index.cjs +46 -0
- package/lib/mcp/tools/index.d.ts +321 -0
- package/lib/mcp/tools/tools.cjs +282 -0
- package/lib/mcp/tools/tools.d.ts +10 -0
- package/lib/mcp/types.cjs +3 -0
- package/lib/mcp/types.d.ts +66 -0
- package/lib/mcp/utils.cjs +54 -0
- package/lib/mcp/utils.d.ts +4 -0
- package/lib/mcp/validation/index.cjs +123 -0
- package/lib/mcp/validation/index.d.ts +13 -0
- package/lib/mcp/validation/scaffoldModule.cjs +94 -0
- package/lib/mcp/validation/scaffoldModule.d.ts +9 -0
- package/lib/mcp/workspace.cjs +119 -0
- package/lib/mcp/workspace.d.ts +9 -0
- package/lib/metadata.cjs +1 -1
- package/lib/metadata.d.ts +1 -1
- package/lib/modules/_template/index.cjs +23 -0
- package/lib/modules/_template/index.d.ts +32 -0
- package/lib/modules/_template/prompts/index.cjs +12 -0
- package/lib/modules/_template/prompts/index.d.ts +6 -0
- package/lib/modules/_template/resources/index.cjs +12 -0
- package/lib/modules/_template/resources/index.d.ts +6 -0
- package/lib/modules/_template/templates/index.cjs +13 -0
- package/lib/modules/_template/templates/index.d.ts +7 -0
- package/lib/modules/_template/tools/index.cjs +18 -0
- package/lib/modules/_template/tools/index.d.ts +6 -0
- package/lib/modules/decoration/index.cjs +16 -1
- package/lib/modules/decoration/index.d.ts +46 -0
- package/lib/modules/decoration/prompts/index.cjs +5 -0
- package/lib/modules/decoration/prompts/index.d.ts +1 -0
- package/lib/modules/decoration/resources/index.cjs +13 -0
- package/lib/modules/decoration/resources/index.d.ts +7 -0
- package/lib/modules/decoration/templates/index.cjs +12 -0
- package/lib/modules/decoration/templates/index.d.ts +6 -0
- package/lib/modules/decoration/tools/index.cjs +10 -0
- package/lib/modules/decoration/tools/index.d.ts +26 -0
- package/lib/modules/index.cjs +13 -0
- package/lib/modules/index.d.ts +2 -0
- package/lib/modules/mcp/decoration-assist.cjs +13 -0
- package/lib/modules/mcp/decoration-assist.d.ts +4 -0
- package/lib/modules/mcp/index.cjs +21 -22
- package/lib/modules/mcp/index.d.ts +6 -2
- package/lib/modules/mcp/prompts/index.cjs +12 -0
- package/lib/modules/mcp/prompts/index.d.ts +2 -0
- package/lib/modules/mcp/resources/index.cjs +27 -0
- package/lib/modules/mcp/resources/index.d.ts +2 -0
- package/lib/modules/mcp/templates/index.cjs +31 -0
- package/lib/modules/mcp/templates/index.d.ts +2 -0
- package/lib/modules/mcp/tools/index.cjs +18 -0
- package/lib/modules/mcp/tools/index.d.ts +6 -0
- package/lib/types.cjs +1 -1
- package/lib/types.d.ts +41 -1
- package/lib/utils/modulePaths.cjs +43 -0
- package/lib/utils/modulePaths.d.ts +6 -0
- package/lib/utils/moduleValidator.cjs +184 -0
- package/lib/utils/moduleValidator.d.ts +14 -0
- package/lib/utils.cjs +5 -1
- package/lib/utils.d.ts +1 -0
- package/package.json +18 -12
- package/lib/esm/modules/decoration-assist/index.d.ts +0 -39
- package/lib/esm/modules/decoration-assist/index.js +0 -353
- package/lib/esm/modules/mcp/decorator-tools.js +0 -237
- package/lib/esm/modules/mcp/mcp-module.d.ts +0 -230
- package/lib/esm/modules/mcp/mcp-module.js +0 -406
- package/lib/modules/decoration-assist/index.cjs +0 -360
- package/lib/modules/decoration-assist/index.d.ts +0 -39
- package/lib/modules/mcp/decorator-tools.cjs +0 -243
- package/lib/modules/mcp/mcp-module.cjs +0 -452
- package/lib/modules/mcp/mcp-module.d.ts +0 -230
- /package/lib/esm/{modules/mcp → mcp}/decorator-tools.d.ts +0 -0
- /package/lib/{modules/mcp → mcp}/decorator-tools.d.ts +0 -0
package/dist/mcp-server.cjs
CHANGED
|
@@ -1,28 +1,992 @@
|
|
|
1
1
|
(function (global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('fs'), require('path'), require('diff'), require('zod'), require('@decaf-ts/decoration'), require('fastmcp'), require('@decaf-ts/logging')) :
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports', 'fs', 'path', 'diff', 'zod', '@decaf-ts/decoration', 'fastmcp', '@decaf-ts/logging'], factory) :
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["mcp-server"] = {}, global.fs, global.path, global.diff, global.zod, global.decoration, global.fastmcp, global.logging));
|
|
5
|
-
})(this, (function (exports, fs, path, diff, zod, decoration, fastmcp, logging) { 'use strict';
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('fs'), require('path'), require('diff'), require('zod'), require('child_process'), require('@decaf-ts/decoration'), require('url'), require('node:fs'), require('node:path'), require('fastmcp'), require('@decaf-ts/logging')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', 'fs', 'path', 'diff', 'zod', 'child_process', '@decaf-ts/decoration', 'url', 'node:fs', 'node:path', 'fastmcp', '@decaf-ts/logging'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["mcp-server"] = {}, global.fs, global.path, global.diff, global.zod, global.child_process, global.decoration, global.url, global.fs$1, global.path$1, global.fastmcp, global.logging));
|
|
5
|
+
})(this, (function (exports, fs, path, diff, zod, child_process, decoration, url, fs$1, path$1, fastmcp, logging) { 'use strict';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* @
|
|
9
|
-
* @
|
|
10
|
-
*
|
|
11
|
-
* @
|
|
12
|
-
* @
|
|
8
|
+
* @description The filename that identifies Decaf CLI modules
|
|
9
|
+
* @summary The standard filename for CLI module files where each library must export a single CliModule function
|
|
10
|
+
*
|
|
11
|
+
* @const MCP_FILE_NAME
|
|
12
|
+
* @memberOf module:MCP
|
|
13
13
|
*/
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
const MCP_FILE_NAME = "mcp-module";
|
|
15
|
+
const WORKSPACE_ROOT_ENV = "MCP_WORKSPACE_ROOT";
|
|
16
|
+
const PROMPT_DIRECTORIES = [".code/prompts", ".codex/prompts"];
|
|
17
|
+
const DEFAULT_PROMPT_NAME = "doc";
|
|
18
|
+
const CLIENT_INTEGRATIONS = [
|
|
19
|
+
{
|
|
20
|
+
id: "vscode",
|
|
21
|
+
display: "Visual Studio Code",
|
|
22
|
+
instructions: "When interacting from Visual Studio Code, prefer the vscode://workspace/{path} resource template to fetch file contents and use the apply-code-change tool to commit edits with previewable diffs.",
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: "cursor",
|
|
26
|
+
display: "Cursor",
|
|
27
|
+
instructions: "Cursor clients can retrieve and update files through the cursor://workspace/{path} resource template. Always validate patches in dryRun mode before applying permanent changes.",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
id: "copilot",
|
|
31
|
+
display: "GitHub Copilot",
|
|
32
|
+
instructions: "Use the copilot://workspace/{path} resource template to stream file content into Copilot chat sessions. Prefer returning unified diffs to maintain alignment with Copilot's diff visualization.",
|
|
33
|
+
},
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
let workspaceRoot = initializeWorkspaceRoot();
|
|
37
|
+
let userErrorCtor;
|
|
38
|
+
class WorkspaceError extends Error {
|
|
39
|
+
constructor(message) {
|
|
40
|
+
super(message);
|
|
41
|
+
this.name = "WorkspaceError";
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function initializeWorkspaceRoot() {
|
|
45
|
+
const configured = process.env[WORKSPACE_ROOT_ENV];
|
|
46
|
+
if (configured && configured.trim().length > 0) {
|
|
47
|
+
return path.resolve(configured.trim());
|
|
48
|
+
}
|
|
49
|
+
return process.cwd();
|
|
50
|
+
}
|
|
51
|
+
async function getUserErrorCtor() {
|
|
52
|
+
if (!userErrorCtor) {
|
|
53
|
+
try {
|
|
54
|
+
const mod = await import('fastmcp');
|
|
55
|
+
userErrorCtor = mod
|
|
56
|
+
.UserError;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
userErrorCtor = class MCPUserError extends Error {
|
|
60
|
+
constructor(message) {
|
|
61
|
+
super(message);
|
|
62
|
+
this.name = "MCPUserError";
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return userErrorCtor;
|
|
68
|
+
}
|
|
69
|
+
async function throwUserError(message) {
|
|
70
|
+
const Ctor = await getUserErrorCtor();
|
|
71
|
+
throw new Ctor(message);
|
|
72
|
+
}
|
|
73
|
+
function setWorkspaceRoot(root) {
|
|
74
|
+
workspaceRoot = path.resolve(root);
|
|
75
|
+
}
|
|
76
|
+
function getWorkspaceRoot() {
|
|
77
|
+
return workspaceRoot;
|
|
78
|
+
}
|
|
79
|
+
function resolveInWorkspace(root, targetPath) {
|
|
80
|
+
const resolved = path.isAbsolute(targetPath)
|
|
81
|
+
? path.normalize(targetPath)
|
|
82
|
+
: path.resolve(root, targetPath);
|
|
83
|
+
const relative = path.relative(root, resolved);
|
|
84
|
+
if (relative.startsWith("..") || path.isAbsolute(relative)) {
|
|
85
|
+
throw new WorkspaceError(`Path ${targetPath} escapes the workspace root at ${root}`);
|
|
86
|
+
}
|
|
87
|
+
return resolved;
|
|
88
|
+
}
|
|
89
|
+
async function readWorkspaceFile(root, target) {
|
|
90
|
+
try {
|
|
91
|
+
const absolute = resolveInWorkspace(root, target);
|
|
92
|
+
return fs.readFileSync(absolute, "utf8");
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
if (error instanceof WorkspaceError) {
|
|
96
|
+
await throwUserError(error.message);
|
|
97
|
+
}
|
|
98
|
+
/* istanbul ignore next */
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function __resetWorkspaceRoot(root) {
|
|
103
|
+
setWorkspaceRoot(root);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const prompts$3 = [];
|
|
107
|
+
|
|
108
|
+
const resources$3 = [
|
|
109
|
+
{
|
|
110
|
+
"id": "decoration.repo",
|
|
111
|
+
"name": "decoration repository",
|
|
112
|
+
"description": "Source repository",
|
|
113
|
+
"uri": "file:///home/tvenceslau/local-workspace/decaf-ts/mcp-server/src/modules/decoration",
|
|
114
|
+
"absolutePath": "/home/tvenceslau/local-workspace/decaf-ts/mcp-server/src/modules/decoration"
|
|
115
|
+
}
|
|
116
|
+
];
|
|
117
|
+
|
|
118
|
+
const templates$2 = [
|
|
119
|
+
{
|
|
120
|
+
"name": "readme-template",
|
|
121
|
+
"description": "README as guidance",
|
|
122
|
+
"uriTemplate": "file:///home/tvenceslau/local-workspace/decaf-ts/mcp-server/src/modules/decoration/README.md",
|
|
123
|
+
"mimeType": "text/markdown"
|
|
124
|
+
}
|
|
125
|
+
];
|
|
126
|
+
|
|
127
|
+
const analyzeRepoSchema = zod.z
|
|
128
|
+
.object({
|
|
129
|
+
repoPath: zod.z
|
|
130
|
+
.string()
|
|
131
|
+
.min(1, "repoPath is required")
|
|
132
|
+
.describe("Relative or absolute path to the target repository inside this monorepo, e.g. './decoration'."),
|
|
133
|
+
includeTests: zod.z
|
|
134
|
+
.boolean()
|
|
135
|
+
.default(true)
|
|
136
|
+
.describe("If true, analyze the tests directory (if present) to derive expected behaviors."),
|
|
137
|
+
includeDocs: zod.z
|
|
138
|
+
.boolean()
|
|
139
|
+
.default(true)
|
|
140
|
+
.describe("If true, analyze README.md and docs directories to extract documented features."),
|
|
141
|
+
})
|
|
142
|
+
.strict()
|
|
143
|
+
.describe("Analyze a local repository (e.g. ./decoration) to extract APIs, features, tests, and documentation cues.");
|
|
144
|
+
const enumerateCapabilitiesSchema = zod.z
|
|
145
|
+
.object({
|
|
146
|
+
repoPath: zod.z
|
|
147
|
+
.string()
|
|
148
|
+
.min(1, "repoPath is required")
|
|
149
|
+
.describe("Relative or absolute path to the target repository to enumerate developer-facing capabilities."),
|
|
150
|
+
})
|
|
151
|
+
.strict()
|
|
152
|
+
.describe("Enumerate the complete set of capabilities a developer is expected to use from the given repository.");
|
|
153
|
+
const planFeatureSchema = zod.z
|
|
154
|
+
.object({
|
|
155
|
+
feature: zod.z
|
|
156
|
+
.string()
|
|
157
|
+
.min(5, "feature must describe the goal clearly")
|
|
158
|
+
.describe("Natural-language description of a developer's requested feature or task to implement using the repository and available MCP tools."),
|
|
159
|
+
repoPath: zod.z
|
|
160
|
+
.string()
|
|
161
|
+
.default("./decoration")
|
|
162
|
+
.describe("Target repository path providing the library to use, e.g. './decoration'."),
|
|
163
|
+
})
|
|
164
|
+
.strict()
|
|
165
|
+
.describe("Plan which MCP tools to use and in what sequence to implement a requested feature using the repository.");
|
|
166
|
+
const documentCodeSchema = zod.z
|
|
167
|
+
.object({
|
|
168
|
+
filePath: zod.z.string().min(1, "filePath is required"),
|
|
169
|
+
promptName: zod.z.string().optional(),
|
|
170
|
+
includePrompt: zod.z.boolean().default(true),
|
|
171
|
+
includeCode: zod.z.boolean().default(true),
|
|
172
|
+
includeMetadata: zod.z.boolean().default(true),
|
|
173
|
+
additionalContext: zod.z.string().optional(),
|
|
174
|
+
encoding: zod.z.string().default("utf8"),
|
|
175
|
+
})
|
|
176
|
+
.strict();
|
|
177
|
+
const codeChangeSchema = zod.z
|
|
178
|
+
.object({
|
|
179
|
+
filePath: zod.z.string().min(1, "filePath is required"),
|
|
180
|
+
patch: zod.z.string().min(1, "patch is required"),
|
|
181
|
+
dryRun: zod.z.boolean().default(false),
|
|
182
|
+
showDiff: zod.z.boolean().default(true),
|
|
183
|
+
diffContext: zod.z.number().int().min(0).max(100).default(3),
|
|
184
|
+
encoding: zod.z.string().default("utf8"),
|
|
185
|
+
})
|
|
186
|
+
.strict();
|
|
187
|
+
const OBJECT_TYPES = [
|
|
188
|
+
"module",
|
|
189
|
+
"file",
|
|
190
|
+
"class",
|
|
191
|
+
"function",
|
|
192
|
+
"interface",
|
|
193
|
+
"decorator",
|
|
194
|
+
"constant",
|
|
195
|
+
];
|
|
196
|
+
const documentObjectSchema = zod.z
|
|
197
|
+
.object({
|
|
198
|
+
basePath: zod.z.string().min(1, "basePath is required"),
|
|
199
|
+
objectType: zod.z.enum(OBJECT_TYPES),
|
|
200
|
+
targetFile: zod.z.string().optional(),
|
|
201
|
+
includeContent: zod.z.boolean().default(false),
|
|
202
|
+
})
|
|
203
|
+
.strict();
|
|
204
|
+
const coverageTaskSchema = zod.z
|
|
205
|
+
.object({
|
|
206
|
+
basePath: zod.z.string().min(1, "basePath is required"),
|
|
207
|
+
coverage: zod.z
|
|
208
|
+
.number()
|
|
209
|
+
.min(0)
|
|
210
|
+
.max(100)
|
|
211
|
+
.default(90)
|
|
212
|
+
.describe("Target coverage percentage"),
|
|
213
|
+
dryRun: zod.z.boolean().default(false),
|
|
214
|
+
})
|
|
215
|
+
.strict();
|
|
216
|
+
const readmeImprovementSchema = zod.z
|
|
217
|
+
.object({
|
|
218
|
+
basePath: zod.z.string().min(1, "basePath is required"),
|
|
219
|
+
includeExamples: zod.z.boolean().default(true),
|
|
220
|
+
})
|
|
221
|
+
.strict();
|
|
222
|
+
|
|
223
|
+
function readFileSafe(filePath, encoding = "utf8") {
|
|
224
|
+
try {
|
|
225
|
+
return fs.readFileSync(filePath, { encoding });
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
return undefined;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
function listFilesRecursive(root, matcher) {
|
|
232
|
+
const out = [];
|
|
233
|
+
const stack = [root];
|
|
234
|
+
while (stack.length) {
|
|
235
|
+
const cur = stack.pop();
|
|
236
|
+
const stat = fs.statSync(cur);
|
|
237
|
+
if (stat.isDirectory()) {
|
|
238
|
+
for (const f of fs.readdirSync(cur))
|
|
239
|
+
stack.push(path.join(cur, f));
|
|
240
|
+
}
|
|
241
|
+
else if (!matcher || matcher(cur)) {
|
|
242
|
+
out.push(cur);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return out.sort();
|
|
246
|
+
}
|
|
247
|
+
function deriveCapabilities(analysis) {
|
|
248
|
+
const cap = new Set();
|
|
249
|
+
// heuristics: if decorators like Decoration, flavouredAs, extend, override appear, add capabilities
|
|
250
|
+
const allDecs = new Set();
|
|
251
|
+
for (const k of Object.keys(analysis.api)) {
|
|
252
|
+
for (const d of analysis.api[k].decorators)
|
|
253
|
+
allDecs.add(d);
|
|
254
|
+
for (const e of analysis.api[k].exports)
|
|
255
|
+
if (/Decoration|decorate|Builder|Flavour/i.test(e))
|
|
256
|
+
cap.add("use-decoration-api");
|
|
257
|
+
}
|
|
258
|
+
if ([...allDecs].some((d) => /override|extend/i.test(d)))
|
|
259
|
+
cap.add("override-and-extend-decorations");
|
|
260
|
+
if (Object.keys(analysis.tests).length > 0)
|
|
261
|
+
cap.add("validate-with-tests");
|
|
262
|
+
if (analysis.readme)
|
|
263
|
+
cap.add("follow-readme-guides");
|
|
264
|
+
return [...cap].sort();
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Analysis helpers (minimal yet effective, text-based to avoid heavy AST deps)
|
|
268
|
+
function isSourceFile(p) {
|
|
269
|
+
return /\.(ts|tsx|js|jsx)$/.test(p) && !p.endsWith(".d.ts");
|
|
270
|
+
}
|
|
271
|
+
function isTestFile(p) {
|
|
272
|
+
return /(\.test\.|\.spec\.)/.test(p);
|
|
273
|
+
}
|
|
274
|
+
function extractExports(fileContent) {
|
|
275
|
+
const names = new Set();
|
|
276
|
+
const exportRe = /(export\s+(?:default\s+)?(?:class|function|const|let|var|interface|type|enum)\s+)([A-Za-z0-9_]+)/g;
|
|
277
|
+
const namedRe = /export\s*\{([^}]+)\}/g;
|
|
278
|
+
let m;
|
|
279
|
+
while ((m = exportRe.exec(fileContent)))
|
|
280
|
+
names.add(m[2]);
|
|
281
|
+
while ((m = namedRe.exec(fileContent))) {
|
|
282
|
+
m[1]
|
|
283
|
+
.split(",")
|
|
284
|
+
.map((s) => s.trim().split(" as ")[0].trim())
|
|
285
|
+
.forEach((n) => {
|
|
286
|
+
if (n)
|
|
287
|
+
names.add(n);
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
return [...names].sort();
|
|
291
|
+
}
|
|
292
|
+
function extractDecorators(fileContent) {
|
|
293
|
+
const decs = new Set();
|
|
294
|
+
const decRe = /@([A-Za-z_][A-Za-z0-9_]*)/g;
|
|
295
|
+
let m;
|
|
296
|
+
while ((m = decRe.exec(fileContent)))
|
|
297
|
+
decs.add(m[1]);
|
|
298
|
+
return [...decs].sort();
|
|
299
|
+
}
|
|
300
|
+
function summarizeReadme(readme) {
|
|
301
|
+
if (!readme)
|
|
302
|
+
return undefined;
|
|
303
|
+
const lines = readme.split(/\r?\n/).filter(Boolean);
|
|
304
|
+
const title = lines.find((l) => /^#\s+/.test(l))?.replace(/^#\s+/, "") || "README";
|
|
305
|
+
const bullets = lines.filter((l) => /^[-*]\s+/.test(l)).slice(0, 20);
|
|
306
|
+
return { title, bullets };
|
|
307
|
+
}
|
|
308
|
+
function analyzeRepo(root) {
|
|
309
|
+
const src = path.join(root, "src");
|
|
310
|
+
const testDir = path.join(root, "tests");
|
|
311
|
+
const readmePath = path.join(root, "README.md");
|
|
312
|
+
const readme = readFileSafe(readmePath);
|
|
313
|
+
const files = fs.existsSync(src) ? listFilesRecursive(src, isSourceFile) : [];
|
|
314
|
+
const testFiles = fs.existsSync(testDir)
|
|
315
|
+
? listFilesRecursive(testDir, (f) => isSourceFile(f) && isTestFile(f))
|
|
316
|
+
: [];
|
|
317
|
+
const api = {};
|
|
318
|
+
for (const f of files) {
|
|
319
|
+
const content = readFileSafe(f) || "";
|
|
320
|
+
api[path.relative(root, f)] = {
|
|
321
|
+
exports: extractExports(content),
|
|
322
|
+
decorators: extractDecorators(content),
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
const tests = {};
|
|
326
|
+
for (const f of testFiles) {
|
|
327
|
+
const content = readFileSafe(f) || "";
|
|
328
|
+
const mentions = Array.from(new Set([...extractExports(content), ...extractDecorators(content)])).sort();
|
|
329
|
+
tests[path.relative(root, f)] = { mentions };
|
|
330
|
+
}
|
|
331
|
+
return { files, testFiles, api, tests, readme: summarizeReadme(readme) };
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
function buildAnalyzeRepositoryTool() {
|
|
335
|
+
return {
|
|
336
|
+
name: "analyze-repository",
|
|
337
|
+
description: "Analyze a local repository's source, tests, and docs to extract exported APIs, decorators, and test mentions.",
|
|
338
|
+
parameters: analyzeRepoSchema,
|
|
339
|
+
execute: async (input) => {
|
|
340
|
+
let repoRoot = path.resolve(process.cwd(), input.repoPath);
|
|
341
|
+
if (!fs.existsSync(repoRoot)) {
|
|
342
|
+
// try resolving from monorepo root (parent of current cwd)
|
|
343
|
+
const alt = path.resolve(process.cwd(), "..", input.repoPath);
|
|
344
|
+
if (fs.existsSync(alt))
|
|
345
|
+
repoRoot = alt;
|
|
346
|
+
}
|
|
347
|
+
if (!fs.existsSync(repoRoot)) {
|
|
348
|
+
// if input was absolute and still not found, try ../<basename>
|
|
349
|
+
const alt2 = path.resolve(process.cwd(), "..", path.basename(input.repoPath));
|
|
350
|
+
if (fs.existsSync(alt2))
|
|
351
|
+
repoRoot = alt2;
|
|
352
|
+
}
|
|
353
|
+
if (!fs.existsSync(repoRoot))
|
|
354
|
+
throw new Error(`Repository not found at ${repoRoot}`);
|
|
355
|
+
const result = analyzeRepo(repoRoot);
|
|
356
|
+
return {
|
|
357
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
358
|
+
};
|
|
359
|
+
},
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
function buildEnumerateCapabilitiesTool() {
|
|
363
|
+
return {
|
|
364
|
+
name: "enumerate-capabilities",
|
|
365
|
+
description: "Enumerate developer-facing capabilities of the given repository, inferred from code, tests, and docs.",
|
|
366
|
+
parameters: enumerateCapabilitiesSchema,
|
|
367
|
+
execute: async (input) => {
|
|
368
|
+
let repoRoot = path.resolve(process.cwd(), input.repoPath);
|
|
369
|
+
if (!fs.existsSync(repoRoot)) {
|
|
370
|
+
const alt = path.resolve(process.cwd(), "..", input.repoPath);
|
|
371
|
+
if (fs.existsSync(alt))
|
|
372
|
+
repoRoot = alt;
|
|
373
|
+
}
|
|
374
|
+
if (!fs.existsSync(repoRoot)) {
|
|
375
|
+
const alt2 = path.resolve(process.cwd(), "..", path.basename(input.repoPath));
|
|
376
|
+
if (fs.existsSync(alt2))
|
|
377
|
+
repoRoot = alt2;
|
|
378
|
+
}
|
|
379
|
+
if (!fs.existsSync(repoRoot))
|
|
380
|
+
throw new Error(`Repository not found at ${repoRoot}`);
|
|
381
|
+
const analysis = analyzeRepo(repoRoot);
|
|
382
|
+
const capabilities = deriveCapabilities(analysis);
|
|
383
|
+
return {
|
|
384
|
+
content: [
|
|
385
|
+
{
|
|
386
|
+
type: "text",
|
|
387
|
+
text: JSON.stringify({
|
|
388
|
+
capabilities,
|
|
389
|
+
analysisSummary: {
|
|
390
|
+
files: analysis.files.length,
|
|
391
|
+
testFiles: analysis.testFiles.length,
|
|
392
|
+
readme: analysis.readme?.title,
|
|
393
|
+
},
|
|
394
|
+
}, null, 2),
|
|
395
|
+
},
|
|
396
|
+
],
|
|
397
|
+
};
|
|
398
|
+
},
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
function buildPlanFeatureTool() {
|
|
402
|
+
return {
|
|
403
|
+
name: "plan-feature-implementation",
|
|
404
|
+
description: "Given a feature request, select appropriate MCP tools (including existing and new ones) and produce an execution plan.",
|
|
405
|
+
parameters: planFeatureSchema,
|
|
406
|
+
execute: async (input) => {
|
|
407
|
+
const steps = [];
|
|
408
|
+
let i = 1;
|
|
409
|
+
steps.push({
|
|
410
|
+
step: i++,
|
|
411
|
+
action: "Analyze repository to enumerate APIs and decorators",
|
|
412
|
+
tool: "analyze-repository",
|
|
413
|
+
arguments: { repoPath: input.repoPath },
|
|
414
|
+
rationale: "Understand available building blocks.",
|
|
415
|
+
});
|
|
416
|
+
steps.push({
|
|
417
|
+
step: i++,
|
|
418
|
+
action: "List capabilities expected for developers",
|
|
419
|
+
tool: "enumerate-capabilities",
|
|
420
|
+
arguments: { repoPath: input.repoPath },
|
|
421
|
+
rationale: "Align the plan with supported capabilities.",
|
|
422
|
+
});
|
|
423
|
+
// Suggest existing generic tools from mcp-module
|
|
424
|
+
steps.push({
|
|
425
|
+
step: i++,
|
|
426
|
+
action: "Select documentation prompt and gather relevant source file(s)",
|
|
427
|
+
tool: "document-code",
|
|
428
|
+
arguments: { filePath: "<target-file>" },
|
|
429
|
+
rationale: "Provide context and instructions for changes.",
|
|
430
|
+
});
|
|
431
|
+
steps.push({
|
|
432
|
+
step: i++,
|
|
433
|
+
action: "Apply code changes using unified diff patch",
|
|
434
|
+
tool: "apply-code-change",
|
|
435
|
+
arguments: {
|
|
436
|
+
filePath: "<target-file>",
|
|
437
|
+
patch: "<unified-diff>",
|
|
438
|
+
dryRun: true,
|
|
439
|
+
},
|
|
440
|
+
rationale: "Validate changes safely before committing.",
|
|
441
|
+
});
|
|
442
|
+
steps.push({
|
|
443
|
+
step: i++,
|
|
444
|
+
action: "Commit code changes",
|
|
445
|
+
tool: "apply-code-change",
|
|
446
|
+
arguments: {
|
|
447
|
+
filePath: "<target-file>",
|
|
448
|
+
patch: "<unified-diff>",
|
|
449
|
+
dryRun: false,
|
|
450
|
+
},
|
|
451
|
+
rationale: "Persist the update.",
|
|
452
|
+
});
|
|
453
|
+
// If decoration-related terms present, suggest decorator tools
|
|
454
|
+
if (/decorat|flavour|override|extend|builder/i.test(input.feature)) {
|
|
455
|
+
steps.unshift({
|
|
456
|
+
step: 0,
|
|
457
|
+
action: "Use decorator tooling to insert/remove/modify decorators",
|
|
458
|
+
tool: "decorator-tools",
|
|
459
|
+
arguments: { action: "help" },
|
|
460
|
+
rationale: "Leverage specialized utilities for decoration patterns.",
|
|
461
|
+
});
|
|
462
|
+
steps.forEach((s, idx) => (s.step = idx + 1));
|
|
463
|
+
}
|
|
464
|
+
return {
|
|
465
|
+
content: [
|
|
466
|
+
{
|
|
467
|
+
type: "text",
|
|
468
|
+
text: JSON.stringify({
|
|
469
|
+
plan: steps,
|
|
470
|
+
notes: "Replace placeholder arguments like <target-file> and <unified-diff> based on the analysis output.",
|
|
471
|
+
}, null, 2),
|
|
472
|
+
},
|
|
473
|
+
],
|
|
474
|
+
};
|
|
475
|
+
},
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
const documentCodeTool = {
|
|
479
|
+
annotations: {
|
|
480
|
+
idempotentHint: true,
|
|
481
|
+
openWorldHint: false,
|
|
482
|
+
readOnlyHint: true,
|
|
483
|
+
title: "Document Source File",
|
|
484
|
+
},
|
|
485
|
+
description: "Generate documentation guidance for a file by combining repository prompts with the target source code.",
|
|
486
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
487
|
+
execute: async (input, _context) => {
|
|
488
|
+
const args = documentCodeSchema.parse(input);
|
|
489
|
+
const root = getWorkspaceRoot();
|
|
490
|
+
let filePath;
|
|
491
|
+
try {
|
|
492
|
+
filePath = resolveInWorkspace(root, args.filePath);
|
|
493
|
+
}
|
|
494
|
+
catch (error) {
|
|
495
|
+
if (error instanceof WorkspaceError) {
|
|
496
|
+
return throwUserError(error.message);
|
|
497
|
+
}
|
|
498
|
+
/* istanbul ignore next */
|
|
499
|
+
throw error;
|
|
500
|
+
}
|
|
501
|
+
if (!fs.existsSync(filePath)) {
|
|
502
|
+
return throwUserError(`Cannot document missing file at ${args.filePath}`);
|
|
503
|
+
}
|
|
504
|
+
const fileContent = fs.readFileSync(filePath, {
|
|
505
|
+
encoding: args.encoding,
|
|
506
|
+
});
|
|
507
|
+
const prompts = discoverDocPrompts(root);
|
|
508
|
+
if (!prompts.length) {
|
|
509
|
+
return throwUserError("No documentation prompts found under .code/prompts or .codex/prompts");
|
|
510
|
+
}
|
|
511
|
+
const prompt = selectPrompt(prompts, args.promptName ?? DEFAULT_PROMPT_NAME);
|
|
512
|
+
return buildDocumentationPayload({
|
|
513
|
+
filePath: args.filePath,
|
|
514
|
+
fileContent,
|
|
515
|
+
prompt,
|
|
516
|
+
includeCode: args.includeCode,
|
|
517
|
+
includePrompt: args.includePrompt,
|
|
518
|
+
includeMetadata: args.includeMetadata,
|
|
519
|
+
additionalContext: args.additionalContext,
|
|
520
|
+
});
|
|
521
|
+
},
|
|
522
|
+
name: "document-code",
|
|
523
|
+
parameters: documentCodeSchema,
|
|
524
|
+
};
|
|
525
|
+
const applyCodeChangeTool = {
|
|
526
|
+
annotations: {
|
|
527
|
+
destructiveHint: true,
|
|
528
|
+
idempotentHint: false,
|
|
529
|
+
openWorldHint: false,
|
|
530
|
+
readOnlyHint: false,
|
|
531
|
+
title: "Apply Code Patch",
|
|
532
|
+
},
|
|
533
|
+
description: "Apply a unified diff patch to a workspace file with optional dry-run validation and diff preview.",
|
|
534
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
535
|
+
execute: async (input, _context) => {
|
|
536
|
+
const args = codeChangeSchema.parse(input);
|
|
537
|
+
const root = getWorkspaceRoot();
|
|
538
|
+
let filePath;
|
|
539
|
+
try {
|
|
540
|
+
filePath = resolveInWorkspace(root, args.filePath);
|
|
541
|
+
}
|
|
542
|
+
catch (error) {
|
|
543
|
+
if (error instanceof WorkspaceError) {
|
|
544
|
+
return throwUserError(error.message);
|
|
545
|
+
}
|
|
546
|
+
throw error;
|
|
547
|
+
}
|
|
548
|
+
const original = fs.existsSync(filePath)
|
|
549
|
+
? fs.readFileSync(filePath, args.encoding)
|
|
550
|
+
: "";
|
|
551
|
+
let patched;
|
|
552
|
+
try {
|
|
553
|
+
patched = diff.applyPatch(original, args.patch);
|
|
554
|
+
}
|
|
555
|
+
catch (error) {
|
|
556
|
+
return throwUserError(`Failed to apply provided patch to ${args.filePath}: ${error instanceof Error ? error.message : error}`);
|
|
557
|
+
}
|
|
558
|
+
/* istanbul ignore next */
|
|
559
|
+
if (patched === false) {
|
|
560
|
+
return throwUserError(`Failed to apply provided patch to ${args.filePath}`);
|
|
561
|
+
}
|
|
562
|
+
if (!args.dryRun) {
|
|
563
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
564
|
+
fs.writeFileSync(filePath, patched, {
|
|
565
|
+
encoding: args.encoding,
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
if (!args.showDiff) {
|
|
569
|
+
return `Patch ${args.dryRun ? "validated" : "applied"} for ${args.filePath}`;
|
|
570
|
+
}
|
|
571
|
+
const preview = diff.createTwoFilesPatch(args.filePath, args.filePath, original, patched, undefined, undefined, { context: args.diffContext });
|
|
572
|
+
return {
|
|
573
|
+
content: [
|
|
574
|
+
{
|
|
575
|
+
type: "text",
|
|
576
|
+
text: `Patch ${args.dryRun ? "validated" : "applied"} for ${args.filePath}`,
|
|
577
|
+
},
|
|
578
|
+
{
|
|
579
|
+
type: "text",
|
|
580
|
+
text: ["```diff", preview.trim(), "```"].join("\n"),
|
|
581
|
+
},
|
|
582
|
+
],
|
|
583
|
+
};
|
|
584
|
+
},
|
|
585
|
+
name: "apply-code-change",
|
|
586
|
+
parameters: codeChangeSchema,
|
|
587
|
+
};
|
|
588
|
+
const analyticTools = [
|
|
589
|
+
buildAnalyzeRepositoryTool(),
|
|
590
|
+
buildEnumerateCapabilitiesTool(),
|
|
591
|
+
buildPlanFeatureTool(),
|
|
592
|
+
];
|
|
593
|
+
const toolList$1 = [
|
|
594
|
+
...analyticTools,
|
|
595
|
+
documentCodeTool,
|
|
596
|
+
applyCodeChangeTool,
|
|
597
|
+
];
|
|
598
|
+
|
|
599
|
+
const tools$3 = [
|
|
600
|
+
{ id: 'decoration.analyze', title: 'Analyze decoration', description: 'Analyze the target repository', tool: buildAnalyzeRepositoryTool() },
|
|
601
|
+
{ id: 'decoration.enumerate', title: 'Enumerate capabilities for decoration', description: 'Enumerate capabilities', tool: buildEnumerateCapabilitiesTool() },
|
|
602
|
+
{ id: 'decoration.plan', title: 'Plan features for decoration', description: 'Plan feature implementation', tool: buildPlanFeatureTool() },
|
|
603
|
+
];
|
|
604
|
+
|
|
605
|
+
const modulePackage$2 = { name: 'decoration', prompts: prompts$3, resources: resources$3, templates: templates$2, tools: tools$3 };
|
|
606
|
+
|
|
607
|
+
const prompts$2 = [
|
|
608
|
+
{
|
|
609
|
+
id: "mcp.prompt.module-catalog",
|
|
610
|
+
title: "Decaf MCP Module Catalog",
|
|
611
|
+
description: "Summarizes the modules contributing prompts/resources/templates/tools to FASTMCP.",
|
|
612
|
+
load: async () => "Use the module catalog tool to enumerate available module assets before fulfilling assistant requests.",
|
|
613
|
+
},
|
|
614
|
+
];
|
|
615
|
+
|
|
616
|
+
const resources$2 = [
|
|
617
|
+
{
|
|
618
|
+
id: "mcp.resource.registry-overview",
|
|
619
|
+
title: "Module Registry Overview",
|
|
620
|
+
description: "Explains how the ModuleRegistry aggregates module exports into FASTMCP catalogs.",
|
|
621
|
+
uri: "decaf://mcp/module-registry",
|
|
622
|
+
mimeType: "text/markdown",
|
|
623
|
+
load: async () => ({
|
|
624
|
+
content: [
|
|
625
|
+
{
|
|
626
|
+
type: "text",
|
|
627
|
+
text: [
|
|
628
|
+
"# Module Registry",
|
|
629
|
+
"",
|
|
630
|
+
"The Decaf MCP server aggregates prompts, resources, templates, and tools from every module under src/modules.",
|
|
631
|
+
"Validators ensure each module contains the canonical folder layout before the registry loads it.",
|
|
632
|
+
].join("\n"),
|
|
633
|
+
mimeType: "text/markdown",
|
|
634
|
+
},
|
|
635
|
+
],
|
|
636
|
+
}),
|
|
637
|
+
},
|
|
638
|
+
];
|
|
639
|
+
|
|
640
|
+
const templates$1 = [
|
|
641
|
+
{
|
|
642
|
+
id: "mcp.template.module-readme",
|
|
643
|
+
title: "Module README Template",
|
|
644
|
+
description: "Guides maintainers through documenting a new MCP-aware module.",
|
|
645
|
+
content: `# {{moduleName}} Module
|
|
646
|
+
|
|
647
|
+
## Purpose
|
|
648
|
+
Describe why this module exists and how assistants should use it.
|
|
649
|
+
|
|
650
|
+
## Assets
|
|
651
|
+
- Prompts: {{promptSummary}}
|
|
652
|
+
- Resources: {{resourceSummary}}
|
|
653
|
+
- Templates: {{templateSummary}}
|
|
654
|
+
- Tools: {{toolSummary}}
|
|
655
|
+
|
|
656
|
+
## Validation
|
|
657
|
+
Explain what needs to happen when this module changes (tests, docs, etc.).`,
|
|
658
|
+
placeholders: [
|
|
659
|
+
"moduleName",
|
|
660
|
+
"promptSummary",
|
|
661
|
+
"resourceSummary",
|
|
662
|
+
"templateSummary",
|
|
663
|
+
"toolSummary",
|
|
664
|
+
],
|
|
665
|
+
},
|
|
666
|
+
];
|
|
667
|
+
|
|
668
|
+
const describeModulesTool = {
|
|
669
|
+
name: "describe-modules",
|
|
670
|
+
description: "Summarize the purpose of Decaf MCP modules for assistant operators.",
|
|
671
|
+
// Minimal execute implementation to return a text result
|
|
672
|
+
execute: async () => "Modules contribute prompts, resources, templates, and tools that the registry exposes to FASTMCP clients.",
|
|
673
|
+
};
|
|
674
|
+
const tools$2 = [
|
|
675
|
+
{
|
|
676
|
+
id: "mcp.tool.describe-modules",
|
|
677
|
+
title: "Describe MCP Modules",
|
|
678
|
+
description: "Explains how module exports feed into the FASTMCP server.",
|
|
679
|
+
tool: describeModulesTool,
|
|
680
|
+
},
|
|
681
|
+
];
|
|
682
|
+
|
|
683
|
+
const modulePackage$1 = {
|
|
684
|
+
name: "mcp",
|
|
685
|
+
prompts: prompts$2,
|
|
686
|
+
resources: resources$2,
|
|
687
|
+
templates: templates$1,
|
|
688
|
+
tools: tools$2,
|
|
689
|
+
};
|
|
690
|
+
|
|
691
|
+
const prompts$1 = [
|
|
692
|
+
{
|
|
693
|
+
id: "_template.readme",
|
|
694
|
+
title: "Template README",
|
|
695
|
+
description: "A README prompt for module template",
|
|
696
|
+
load: () => "Template prompt content",
|
|
697
|
+
},
|
|
698
|
+
];
|
|
699
|
+
|
|
700
|
+
const resources$1 = [
|
|
701
|
+
{
|
|
702
|
+
id: "_template.repo",
|
|
703
|
+
name: "template repo",
|
|
704
|
+
description: "Template resource",
|
|
705
|
+
uri: "file:///tmp/template",
|
|
706
|
+
},
|
|
707
|
+
];
|
|
708
|
+
|
|
709
|
+
const templates = [
|
|
710
|
+
{
|
|
711
|
+
id: "_template.readme",
|
|
712
|
+
name: "template-readme",
|
|
713
|
+
description: "README guidance",
|
|
714
|
+
uriTemplate: "file:///tmp/template/README.md",
|
|
715
|
+
mimeType: "text/markdown",
|
|
716
|
+
},
|
|
717
|
+
];
|
|
718
|
+
|
|
719
|
+
const placeholderTool = {
|
|
720
|
+
name: "_template.tool",
|
|
721
|
+
description: "A placeholder tool",
|
|
722
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
723
|
+
execute: async (_input, _context) => "ok",
|
|
724
|
+
};
|
|
725
|
+
const tools$1 = [
|
|
726
|
+
{
|
|
727
|
+
id: "_template.tool",
|
|
728
|
+
title: "template tool",
|
|
729
|
+
description: "A placeholder tool",
|
|
730
|
+
tool: placeholderTool,
|
|
731
|
+
},
|
|
732
|
+
];
|
|
733
|
+
|
|
734
|
+
const modulePackage = {
|
|
735
|
+
name: "_template",
|
|
736
|
+
prompts: prompts$1,
|
|
737
|
+
resources: resources$1,
|
|
738
|
+
templates,
|
|
739
|
+
tools: tools$1,
|
|
740
|
+
};
|
|
741
|
+
|
|
742
|
+
// modulePackage objects may be declared with readonly arrays (as const). Cast to the mutable type expected by runtime APIs.
|
|
743
|
+
const modulePackages = [
|
|
744
|
+
modulePackage$2,
|
|
745
|
+
modulePackage$1,
|
|
746
|
+
modulePackage,
|
|
747
|
+
];
|
|
748
|
+
|
|
749
|
+
class ModuleRegistry {
|
|
750
|
+
// Defensive default: modulePackages may be undefined during circular imports
|
|
751
|
+
constructor(packages = Array.isArray(modulePackages)
|
|
752
|
+
? modulePackages
|
|
753
|
+
: []) {
|
|
754
|
+
this.packages = packages;
|
|
755
|
+
}
|
|
756
|
+
listPackages() {
|
|
757
|
+
return this.packages;
|
|
758
|
+
}
|
|
759
|
+
listPrompts() {
|
|
760
|
+
return this.collectAssets("prompts");
|
|
761
|
+
}
|
|
762
|
+
listResources() {
|
|
763
|
+
return this.collectAssets("resources");
|
|
764
|
+
}
|
|
765
|
+
listTemplates() {
|
|
766
|
+
return this.collectAssets("templates");
|
|
767
|
+
}
|
|
768
|
+
listTools() {
|
|
769
|
+
return this.collectAssets("tools");
|
|
770
|
+
}
|
|
771
|
+
collectAssets(key) {
|
|
772
|
+
const seen = new Map();
|
|
773
|
+
const aggregated = [];
|
|
774
|
+
for (const pkg of this.packages) {
|
|
775
|
+
if (pkg.status === "disabled")
|
|
776
|
+
continue;
|
|
777
|
+
for (const asset of pkg[key]) {
|
|
778
|
+
// asset.name is not guaranteed on all asset types; use type-safe fallback
|
|
779
|
+
const maybeName = asset.name;
|
|
780
|
+
const assetKey = (asset && (asset.id ?? maybeName)) || JSON.stringify(asset);
|
|
781
|
+
if (seen.has(assetKey)) {
|
|
782
|
+
const conflict = seen.get(assetKey);
|
|
783
|
+
throw new Error(`Duplicate ${key} id '${assetKey}' from modules ${conflict} and ${pkg.name}`);
|
|
784
|
+
}
|
|
785
|
+
seen.set(assetKey, pkg.name);
|
|
786
|
+
aggregated.push({ ...asset, provenance: pkg.name });
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
return aggregated;
|
|
790
|
+
}
|
|
18
791
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
792
|
+
const moduleRegistry = new ModuleRegistry();
|
|
793
|
+
|
|
794
|
+
const prompts = [];
|
|
795
|
+
const OBJECT_PROMPT_DEPENDENCIES = {
|
|
796
|
+
module: ["doc", "module"],
|
|
797
|
+
file: ["doc", "file"],
|
|
798
|
+
class: ["doc", "class"],
|
|
799
|
+
function: ["doc", "function"],
|
|
800
|
+
interface: ["doc", "interface"],
|
|
801
|
+
decorator: ["doc", "decorator"],
|
|
802
|
+
constant: ["doc", "constant"],
|
|
803
|
+
"bulk-docs": ["bulk-docs"],
|
|
804
|
+
"bulk-tests": ["bulk-tests"],
|
|
805
|
+
"update-readme": ["update-readme"],
|
|
806
|
+
"repo-setup": ["repo-setup"],
|
|
807
|
+
"release-notes": ["release-notes"],
|
|
808
|
+
"mcp-module": ["mcp-module"],
|
|
809
|
+
};
|
|
810
|
+
function getObjectPromptDependencies() {
|
|
811
|
+
return OBJECT_PROMPT_DEPENDENCIES;
|
|
812
|
+
}
|
|
813
|
+
function buildPrompts(repoPath) {
|
|
814
|
+
return [
|
|
815
|
+
{
|
|
816
|
+
name: "decoration-overview",
|
|
817
|
+
description: "High-level guidance on using the decoration library: key exports, decorators, and common workflows.",
|
|
818
|
+
load: async () => `You are assisting with the Decaf.ts decoration module located at ${repoPath}. Prefer using exported builders and decorators over ad-hoc patterns.\n\nProvide a concise, actionable overview of how to use the decoration APIs for extending and overriding behaviors.`,
|
|
819
|
+
},
|
|
820
|
+
];
|
|
821
|
+
}
|
|
822
|
+
function buildDocPrompts() {
|
|
823
|
+
const root = getWorkspaceRoot();
|
|
824
|
+
const fileBasedPrompts = discoverDocPrompts(root).map((prompt) => ({
|
|
825
|
+
name: `doc/${prompt.name}`,
|
|
826
|
+
description: prompt.description,
|
|
827
|
+
load: async () => prompt.content,
|
|
828
|
+
}));
|
|
829
|
+
const integrationPrompts = CLIENT_INTEGRATIONS.map((integration) => ({
|
|
830
|
+
name: `integration/${integration.id}`,
|
|
831
|
+
description: `${integration.display} integration guidance`,
|
|
832
|
+
load: async () => `You are coordinating with ${integration.display}. ${integration.instructions}\n\nTools available:\n- document-code\n- apply-code-change\n\nEnsure responses include actionable steps for the client.`,
|
|
833
|
+
}));
|
|
834
|
+
return [...fileBasedPrompts, ...integrationPrompts];
|
|
835
|
+
}
|
|
836
|
+
function summarizePromptContent(prompt, headingPrefix) {
|
|
837
|
+
return [`## ${headingPrefix}`, "", prompt.content.trim()].join("\n");
|
|
838
|
+
}
|
|
839
|
+
function buildObjectPrompts() {
|
|
840
|
+
const root = getWorkspaceRoot();
|
|
841
|
+
const discovered = discoverDocPrompts(root);
|
|
842
|
+
const promptByName = new Map();
|
|
843
|
+
for (const prompt of discovered) {
|
|
844
|
+
promptByName.set(prompt.name, prompt);
|
|
845
|
+
}
|
|
846
|
+
const outputs = [];
|
|
847
|
+
for (const [objectType, dependencies] of Object.entries(OBJECT_PROMPT_DEPENDENCIES)) {
|
|
848
|
+
const existing = dependencies
|
|
849
|
+
.map((name) => promptByName.get(name))
|
|
850
|
+
.filter((prompt) => Boolean(prompt));
|
|
851
|
+
if (!existing.length)
|
|
852
|
+
continue;
|
|
853
|
+
outputs.push({
|
|
854
|
+
name: `codex/${objectType}`,
|
|
855
|
+
description: `Guidance derived from .codex prompts for ${objectType} tasks.`,
|
|
856
|
+
load: async () => {
|
|
857
|
+
const sections = existing.map((prompt) => summarizePromptContent(prompt, toTitleCase(prompt.name)));
|
|
858
|
+
return [`# Codex guidance for ${objectType}`, "", ...sections].join("\n");
|
|
859
|
+
},
|
|
860
|
+
});
|
|
861
|
+
}
|
|
862
|
+
return outputs.sort((a, b) => a.name.localeCompare(b.name));
|
|
863
|
+
}
|
|
864
|
+
function toInputPrompt(asset) {
|
|
865
|
+
const provenance = asset.provenance ? ` (module: ${asset.provenance})` : "";
|
|
866
|
+
return {
|
|
867
|
+
name: asset.id,
|
|
868
|
+
description: `${asset.description ?? asset.title}${provenance}`,
|
|
869
|
+
load: async () => asset.load(),
|
|
870
|
+
};
|
|
871
|
+
}
|
|
872
|
+
function buildModulePrompts() {
|
|
873
|
+
return moduleRegistry.listPrompts().map(toInputPrompt);
|
|
874
|
+
}
|
|
875
|
+
function refreshPrompts(repoPath) {
|
|
876
|
+
const docPrompts = buildDocPrompts();
|
|
877
|
+
const objectPrompts = buildObjectPrompts();
|
|
878
|
+
const repoPrompts = repoPath ? buildPrompts(repoPath) : [];
|
|
879
|
+
const modulePrompts = buildModulePrompts();
|
|
880
|
+
prompts.splice(0, prompts.length, ...docPrompts, ...objectPrompts, ...repoPrompts, ...modulePrompts);
|
|
881
|
+
return prompts;
|
|
882
|
+
}
|
|
883
|
+
function discoverDocPrompts(root) {
|
|
884
|
+
const discovered = [];
|
|
885
|
+
for (const directory of PROMPT_DIRECTORIES) {
|
|
886
|
+
const promptDir = path.join(root, directory);
|
|
887
|
+
// debug logging to help tests diagnose prompt discovery
|
|
888
|
+
console.debug("[discoverDocPrompts] checking", promptDir);
|
|
889
|
+
if (!fs.existsSync(promptDir) || !fs.statSync(promptDir).isDirectory()) {
|
|
890
|
+
continue;
|
|
891
|
+
}
|
|
892
|
+
for (const entry of fs.readdirSync(promptDir)) {
|
|
893
|
+
const fullPath = path.join(promptDir, entry);
|
|
894
|
+
if (!fs.statSync(fullPath).isFile())
|
|
895
|
+
continue;
|
|
896
|
+
const name = path.parse(entry).name;
|
|
897
|
+
const content = fs.readFileSync(fullPath, "utf8");
|
|
898
|
+
const title = toTitleCase(name.replace(/[-_]/g, " "));
|
|
899
|
+
const description = extractDescription(content, fullPath);
|
|
900
|
+
discovered.push({
|
|
901
|
+
name,
|
|
902
|
+
title,
|
|
903
|
+
description,
|
|
904
|
+
content,
|
|
905
|
+
absolutePath: fullPath,
|
|
906
|
+
});
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
const unique = new Map();
|
|
910
|
+
for (const prompt of discovered) {
|
|
911
|
+
if (!unique.has(prompt.name)) {
|
|
912
|
+
unique.set(prompt.name, prompt);
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
return Array.from(unique.values()).sort((a, b) => a.name.localeCompare(b.name));
|
|
916
|
+
}
|
|
917
|
+
function selectPrompt(promptList, requestedName) {
|
|
918
|
+
const direct = promptList.find((prompt) => prompt.name === requestedName);
|
|
919
|
+
if (direct)
|
|
920
|
+
return direct;
|
|
921
|
+
const fallback = promptList.find((prompt) => prompt.name === DEFAULT_PROMPT_NAME);
|
|
922
|
+
if (fallback)
|
|
923
|
+
return fallback;
|
|
924
|
+
if (!promptList.length) {
|
|
925
|
+
throw new Error("No documentation prompts available");
|
|
926
|
+
}
|
|
927
|
+
return promptList[0];
|
|
928
|
+
}
|
|
929
|
+
function buildDocumentationPayload({ filePath, fileContent, prompt, includePrompt, includeCode, includeMetadata, additionalContext, }) {
|
|
930
|
+
const sections = [];
|
|
931
|
+
if (includeMetadata) {
|
|
932
|
+
sections.push(`# Documentation Request\n- prompt: ${prompt.name}\n- file: ${filePath}`);
|
|
933
|
+
}
|
|
934
|
+
if (includePrompt) {
|
|
935
|
+
sections.push(`## Prompt Guidance (${prompt.title})\n\n${prompt.content.trim()}`);
|
|
936
|
+
}
|
|
937
|
+
if (additionalContext?.trim()) {
|
|
938
|
+
sections.push(`## Additional Context\n\n${additionalContext.trim()}`);
|
|
939
|
+
}
|
|
940
|
+
if (includeCode) {
|
|
941
|
+
sections.push(`## Source\n\n\`\`\`${inferLanguageFromPath(filePath)}\n${fileContent}\n\`\`\``);
|
|
942
|
+
}
|
|
943
|
+
return {
|
|
944
|
+
content: [
|
|
945
|
+
{
|
|
946
|
+
type: "text",
|
|
947
|
+
text: sections.join("\n\n"),
|
|
948
|
+
},
|
|
949
|
+
],
|
|
950
|
+
};
|
|
951
|
+
}
|
|
952
|
+
function extractDescription(content, filePath) {
|
|
953
|
+
const firstLine = content
|
|
954
|
+
.split(/\r?\n/)
|
|
955
|
+
.map((line) => line.trim())
|
|
956
|
+
.find((line) => line.length > 0);
|
|
957
|
+
return (firstLine?.slice(0, 240) ??
|
|
958
|
+
`Documentation prompt loaded from ${path.basename(filePath)}`);
|
|
959
|
+
}
|
|
960
|
+
function toTitleCase(value) {
|
|
961
|
+
return value
|
|
962
|
+
.split(/\s+/)
|
|
963
|
+
.filter(Boolean)
|
|
964
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())
|
|
965
|
+
.join(" ");
|
|
966
|
+
}
|
|
967
|
+
function inferLanguageFromPath(filePath) {
|
|
968
|
+
const extension = path.extname(filePath).toLowerCase();
|
|
969
|
+
switch (extension) {
|
|
970
|
+
case ".ts":
|
|
971
|
+
case ".tsx":
|
|
972
|
+
return "ts";
|
|
973
|
+
case ".js":
|
|
974
|
+
case ".jsx":
|
|
975
|
+
return "js";
|
|
976
|
+
case ".json":
|
|
977
|
+
return "json";
|
|
978
|
+
case ".md":
|
|
979
|
+
return "md";
|
|
980
|
+
default:
|
|
981
|
+
return "text";
|
|
23
982
|
}
|
|
24
983
|
}
|
|
25
984
|
|
|
985
|
+
const promptList = prompts;
|
|
986
|
+
function loadPrompts(repoPath) {
|
|
987
|
+
return refreshPrompts(repoPath);
|
|
988
|
+
}
|
|
989
|
+
|
|
26
990
|
function escapeRegExp(value) {
|
|
27
991
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
28
992
|
}
|
|
@@ -247,224 +1211,522 @@
|
|
|
247
1211
|
const functionFile = path.join(args.dir, `${args.name}.ts`);
|
|
248
1212
|
ensureDirectory(functionFile);
|
|
249
1213
|
fs.writeFileSync(functionFile, `export function ${args.name}(value: string): string {\n return value.split('').reverse().join('');\n}\n`);
|
|
250
|
-
let registerFile;
|
|
251
|
-
if (args.registerDir) {
|
|
252
|
-
registerFile = path.join(args.registerDir, `${args.name}Register.ts`);
|
|
253
|
-
ensureDirectory(registerFile);
|
|
254
|
-
fs.writeFileSync(registerFile, `export function register${args.name}() {\n return ${args.setDefault ? "'default'" : "'optional'"};\n}\n`);
|
|
255
|
-
}
|
|
256
|
-
return { functionFile, registerFile };
|
|
257
|
-
},
|
|
258
|
-
},
|
|
259
|
-
};
|
|
260
|
-
|
|
261
|
-
const WORKSPACE_ROOT_ENV = "MCP_WORKSPACE_ROOT";
|
|
262
|
-
const PROMPT_DIRECTORIES = [".code/prompts", ".codex/prompts"];
|
|
263
|
-
const DEFAULT_PROMPT_NAME = "doc";
|
|
264
|
-
const CLIENT_INTEGRATIONS = [
|
|
265
|
-
{
|
|
266
|
-
id: "vscode",
|
|
267
|
-
display: "Visual Studio Code",
|
|
268
|
-
instructions: "When interacting from Visual Studio Code, prefer the vscode://workspace/{path} resource template to fetch file contents and use the apply-code-change tool to commit edits with previewable diffs.",
|
|
269
|
-
},
|
|
270
|
-
{
|
|
271
|
-
id: "cursor",
|
|
272
|
-
display: "Cursor",
|
|
273
|
-
instructions: "Cursor clients can retrieve and update files through the cursor://workspace/{path} resource template. Always validate patches in dryRun mode before applying permanent changes.",
|
|
274
|
-
},
|
|
275
|
-
{
|
|
276
|
-
id: "copilot",
|
|
277
|
-
display: "GitHub Copilot",
|
|
278
|
-
instructions: "Use the copilot://workspace/{path} resource template to stream file content into Copilot chat sessions. Prefer returning unified diffs to maintain alignment with Copilot's diff visualization.",
|
|
1214
|
+
let registerFile;
|
|
1215
|
+
if (args.registerDir) {
|
|
1216
|
+
registerFile = path.join(args.registerDir, `${args.name}Register.ts`);
|
|
1217
|
+
ensureDirectory(registerFile);
|
|
1218
|
+
fs.writeFileSync(registerFile, `export function register${args.name}() {\n return ${args.setDefault ? "'default'" : "'optional'"};\n}\n`);
|
|
1219
|
+
}
|
|
1220
|
+
return { functionFile, registerFile };
|
|
1221
|
+
},
|
|
279
1222
|
},
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
promptName: zod.z.string().optional(),
|
|
285
|
-
includePrompt: zod.z.boolean().default(true),
|
|
286
|
-
includeCode: zod.z.boolean().default(true),
|
|
287
|
-
includeMetadata: zod.z.boolean().default(true),
|
|
288
|
-
additionalContext: zod.z.string().optional(),
|
|
289
|
-
encoding: zod.z.string().default("utf8"),
|
|
290
|
-
})
|
|
291
|
-
.strict();
|
|
292
|
-
const codeChangeSchema = zod.z
|
|
293
|
-
.object({
|
|
294
|
-
filePath: zod.z.string().min(1, "filePath is required"),
|
|
295
|
-
patch: zod.z.string().min(1, "patch is required"),
|
|
296
|
-
dryRun: zod.z.boolean().default(false),
|
|
297
|
-
showDiff: zod.z.boolean().default(true),
|
|
298
|
-
diffContext: zod.z.number().int().min(0).max(100).default(3),
|
|
299
|
-
encoding: zod.z.string().default("utf8"),
|
|
300
|
-
})
|
|
301
|
-
.strict();
|
|
302
|
-
let workspaceRoot = initializeWorkspaceRoot();
|
|
303
|
-
let userErrorCtor;
|
|
304
|
-
class WorkspaceError extends Error {
|
|
305
|
-
constructor(message) {
|
|
306
|
-
super(message);
|
|
307
|
-
this.name = "WorkspaceError";
|
|
308
|
-
}
|
|
1223
|
+
};
|
|
1224
|
+
|
|
1225
|
+
function relativeFiles(root, files) {
|
|
1226
|
+
return files.map((file) => path.relative(root, file)).sort();
|
|
309
1227
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
1228
|
+
function collectPromptSections(names) {
|
|
1229
|
+
const root = getWorkspaceRoot();
|
|
1230
|
+
const promptIndex = new Map(discoverDocPrompts(root).map((prompt) => [prompt.name, prompt]));
|
|
1231
|
+
return names
|
|
1232
|
+
.map((name) => promptIndex.get(name))
|
|
1233
|
+
.filter((prompt) => Boolean(prompt))
|
|
1234
|
+
.map((prompt) => ({
|
|
1235
|
+
name: prompt.name,
|
|
1236
|
+
title: prompt.title,
|
|
1237
|
+
description: prompt.description,
|
|
1238
|
+
content: prompt.content,
|
|
1239
|
+
absolutePath: prompt.absolutePath,
|
|
1240
|
+
}));
|
|
1241
|
+
}
|
|
1242
|
+
function parseTaskLines(content) {
|
|
1243
|
+
return content
|
|
1244
|
+
.split(/\r?\n/)
|
|
1245
|
+
.map((line) => line.trim())
|
|
1246
|
+
.filter((line) => /^task\s+\d+/i.test(line));
|
|
1247
|
+
}
|
|
1248
|
+
function computeCoverageFromFinal(coveragePath) {
|
|
1249
|
+
const payload = JSON.parse(fs.readFileSync(coveragePath, "utf8"));
|
|
1250
|
+
const totals = {
|
|
1251
|
+
statements: { covered: 0, total: 0 },
|
|
1252
|
+
functions: { covered: 0, total: 0 },
|
|
1253
|
+
branches: { covered: 0, total: 0 },
|
|
1254
|
+
};
|
|
1255
|
+
const files = Object.entries(payload).map(([filePath, info]) => {
|
|
1256
|
+
const statementCounts = Object.values(info.s);
|
|
1257
|
+
const functionCounts = Object.values(info.f);
|
|
1258
|
+
const branchCounts = Object.values(info.b).flatMap((value) => Array.isArray(value) ? value : [value]);
|
|
1259
|
+
const statementTotal = statementCounts.length;
|
|
1260
|
+
const functionTotal = functionCounts.length;
|
|
1261
|
+
const branchTotal = branchCounts.length;
|
|
1262
|
+
const statementCovered = statementCounts.filter((count) => count > 0).length;
|
|
1263
|
+
const functionCovered = functionCounts.filter((count) => count > 0).length;
|
|
1264
|
+
const branchCovered = branchCounts.filter((count) => count > 0).length;
|
|
1265
|
+
totals.statements.covered += statementCovered;
|
|
1266
|
+
totals.statements.total += statementTotal;
|
|
1267
|
+
totals.functions.covered += functionCovered;
|
|
1268
|
+
totals.functions.total += functionTotal;
|
|
1269
|
+
totals.branches.covered += branchCovered;
|
|
1270
|
+
totals.branches.total += branchTotal;
|
|
1271
|
+
const pct = (covered, total) => total === 0 ? 100 : Number(((covered / total) * 100).toFixed(2));
|
|
1272
|
+
return {
|
|
1273
|
+
path: filePath,
|
|
1274
|
+
statements: pct(statementCovered, statementTotal),
|
|
1275
|
+
functions: pct(functionCovered, functionTotal),
|
|
1276
|
+
branches: pct(branchCovered, branchTotal),
|
|
1277
|
+
};
|
|
1278
|
+
});
|
|
1279
|
+
const pct = (covered, total) => total === 0 ? 100 : Number(((covered / total) * 100).toFixed(2));
|
|
1280
|
+
return {
|
|
1281
|
+
totals: {
|
|
1282
|
+
statements: {
|
|
1283
|
+
...totals.statements,
|
|
1284
|
+
pct: pct(totals.statements.covered, totals.statements.total),
|
|
1285
|
+
},
|
|
1286
|
+
functions: {
|
|
1287
|
+
...totals.functions,
|
|
1288
|
+
pct: pct(totals.functions.covered, totals.functions.total),
|
|
1289
|
+
},
|
|
1290
|
+
branches: {
|
|
1291
|
+
...totals.branches,
|
|
1292
|
+
pct: pct(totals.branches.covered, totals.branches.total),
|
|
1293
|
+
},
|
|
1294
|
+
},
|
|
1295
|
+
files,
|
|
1296
|
+
};
|
|
1297
|
+
}
|
|
1298
|
+
function normalizePromptSections(sections) {
|
|
1299
|
+
return sections.map((section) => ({
|
|
1300
|
+
name: section.name,
|
|
1301
|
+
title: section.title,
|
|
1302
|
+
tasks: parseTaskLines(section.content),
|
|
1303
|
+
content: section.content,
|
|
1304
|
+
}));
|
|
1305
|
+
}
|
|
1306
|
+
async function resolveRepoRoot(basePath) {
|
|
1307
|
+
const root = getWorkspaceRoot();
|
|
1308
|
+
try {
|
|
1309
|
+
return resolveInWorkspace(root, basePath);
|
|
1310
|
+
}
|
|
1311
|
+
catch (error) {
|
|
1312
|
+
if (error instanceof WorkspaceError) {
|
|
1313
|
+
await throwUserError(error.message);
|
|
324
1314
|
}
|
|
1315
|
+
throw error;
|
|
325
1316
|
}
|
|
326
|
-
return userErrorCtor;
|
|
327
1317
|
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
const documentCodeTool = {
|
|
333
|
-
annotations: {
|
|
334
|
-
idempotentHint: true,
|
|
335
|
-
openWorldHint: false,
|
|
336
|
-
readOnlyHint: true,
|
|
337
|
-
title: "Document Source File",
|
|
338
|
-
},
|
|
339
|
-
description: "Generate documentation guidance for a file by combining repository prompts with the target source code.",
|
|
1318
|
+
const documentObjectTool = {
|
|
1319
|
+
name: "document-object",
|
|
1320
|
+
description: "Create a documentation plan for a specific object type using .codex prompts and repository analysis.",
|
|
1321
|
+
parameters: documentObjectSchema,
|
|
340
1322
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
341
1323
|
execute: async (input, _context) => {
|
|
342
|
-
const args =
|
|
343
|
-
const
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
1324
|
+
const args = documentObjectSchema.parse(input);
|
|
1325
|
+
const repoRoot = await resolveRepoRoot(args.basePath);
|
|
1326
|
+
const dependencies = getObjectPromptDependencies()[args.objectType] ?? [];
|
|
1327
|
+
if (!dependencies.length) {
|
|
1328
|
+
await throwUserError(`No prompt guidance configured for object type ${args.objectType}`);
|
|
347
1329
|
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
1330
|
+
const sections = normalizePromptSections(collectPromptSections(dependencies));
|
|
1331
|
+
const srcDir = path.join(repoRoot, "src");
|
|
1332
|
+
const testDir = path.join(repoRoot, "tests");
|
|
1333
|
+
const sourceFiles = fs.existsSync(srcDir)
|
|
1334
|
+
? listFilesRecursive(srcDir, isSourceFile)
|
|
1335
|
+
: [];
|
|
1336
|
+
const testFiles = fs.existsSync(testDir)
|
|
1337
|
+
? listFilesRecursive(testDir, (file) => isSourceFile(file) && isTestFile(file))
|
|
1338
|
+
: [];
|
|
1339
|
+
let targetFileContent;
|
|
1340
|
+
if (args.targetFile) {
|
|
1341
|
+
try {
|
|
1342
|
+
const absolute = resolveInWorkspace(repoRoot, args.targetFile);
|
|
1343
|
+
targetFileContent = readFileSafe(absolute) ?? undefined;
|
|
1344
|
+
}
|
|
1345
|
+
catch (error) {
|
|
1346
|
+
if (error instanceof WorkspaceError) {
|
|
1347
|
+
await throwUserError(error.message);
|
|
1348
|
+
}
|
|
1349
|
+
throw error;
|
|
351
1350
|
}
|
|
352
|
-
/* istanbul ignore next */
|
|
353
|
-
throw error;
|
|
354
|
-
}
|
|
355
|
-
if (!fs.existsSync(filePath)) {
|
|
356
|
-
return throwUserError(`Cannot document missing file at ${args.filePath}`);
|
|
357
|
-
}
|
|
358
|
-
const fileContent = fs.readFileSync(filePath, {
|
|
359
|
-
encoding: args.encoding,
|
|
360
|
-
});
|
|
361
|
-
const prompts = discoverDocPrompts(root);
|
|
362
|
-
if (!prompts.length) {
|
|
363
|
-
return throwUserError("No documentation prompts found under .code/prompts or .codex/prompts");
|
|
364
1351
|
}
|
|
365
|
-
const
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
1352
|
+
const payload = {
|
|
1353
|
+
basePath: path.relative(getWorkspaceRoot(), repoRoot) || ".",
|
|
1354
|
+
objectType: args.objectType,
|
|
1355
|
+
targetFile: args.targetFile,
|
|
1356
|
+
guidance: sections,
|
|
1357
|
+
files: {
|
|
1358
|
+
source: relativeFiles(repoRoot, sourceFiles),
|
|
1359
|
+
tests: relativeFiles(repoRoot, testFiles),
|
|
1360
|
+
},
|
|
1361
|
+
targetFileContent: args.includeContent ? targetFileContent : undefined,
|
|
1362
|
+
};
|
|
1363
|
+
return {
|
|
1364
|
+
content: [
|
|
1365
|
+
{
|
|
1366
|
+
type: "text",
|
|
1367
|
+
text: JSON.stringify(payload, null, 2),
|
|
1368
|
+
},
|
|
1369
|
+
],
|
|
1370
|
+
};
|
|
375
1371
|
},
|
|
376
|
-
name: "document-code",
|
|
377
|
-
parameters: documentCodeSchema,
|
|
378
1372
|
};
|
|
379
|
-
const
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
openWorldHint: false,
|
|
384
|
-
readOnlyHint: false,
|
|
385
|
-
title: "Apply Code Patch",
|
|
386
|
-
},
|
|
387
|
-
description: "Apply a unified diff patch to a workspace file with optional dry-run validation and diff preview.",
|
|
1373
|
+
const coverageEnforcerTool = {
|
|
1374
|
+
name: "ensure-test-coverage",
|
|
1375
|
+
description: "Run the configured coverage command and report whether the target percentage is met, highlighting weak files.",
|
|
1376
|
+
parameters: coverageTaskSchema,
|
|
388
1377
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
389
1378
|
execute: async (input, _context) => {
|
|
390
|
-
const args =
|
|
391
|
-
const
|
|
392
|
-
let filePath;
|
|
393
|
-
try {
|
|
394
|
-
filePath = resolveInWorkspace(root, args.filePath);
|
|
395
|
-
}
|
|
396
|
-
catch (error) {
|
|
397
|
-
if (error instanceof WorkspaceError) {
|
|
398
|
-
return throwUserError(error.message);
|
|
399
|
-
}
|
|
400
|
-
throw error;
|
|
401
|
-
}
|
|
402
|
-
const original = fs.existsSync(filePath)
|
|
403
|
-
? fs.readFileSync(filePath, args.encoding)
|
|
404
|
-
: "";
|
|
405
|
-
let patched;
|
|
406
|
-
try {
|
|
407
|
-
patched = diff.applyPatch(original, args.patch);
|
|
408
|
-
}
|
|
409
|
-
catch (error) {
|
|
410
|
-
return throwUserError(`Failed to apply provided patch to ${args.filePath}: ${error instanceof Error ? error.message : error}`);
|
|
411
|
-
}
|
|
412
|
-
/* istanbul ignore next */
|
|
413
|
-
if (patched === false) {
|
|
414
|
-
return throwUserError(`Failed to apply provided patch to ${args.filePath}`);
|
|
415
|
-
}
|
|
1379
|
+
const args = coverageTaskSchema.parse(input);
|
|
1380
|
+
const repoRoot = await resolveRepoRoot(args.basePath);
|
|
416
1381
|
if (!args.dryRun) {
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
1382
|
+
const env = {
|
|
1383
|
+
...process.env,
|
|
1384
|
+
USE_WATCHMAN: "false",
|
|
1385
|
+
WATCHMAN_DISABLE: "1",
|
|
1386
|
+
JEST_DISABLE_WATCHMAN: "1",
|
|
1387
|
+
};
|
|
1388
|
+
const result = child_process.spawnSync("npm", ["run", "coverage", "--", "--watchman=false", "--runInBand"], { cwd: repoRoot, env, encoding: "utf8" });
|
|
1389
|
+
if (result.status !== 0) {
|
|
1390
|
+
const message = result.stderr || result.stdout || "Coverage command failed";
|
|
1391
|
+
await throwUserError(message.trim());
|
|
1392
|
+
}
|
|
421
1393
|
}
|
|
422
|
-
|
|
423
|
-
|
|
1394
|
+
const coveragePath = path.join(repoRoot, "workdocs", "reports", "coverage", "coverage-final.json");
|
|
1395
|
+
if (!fs.existsSync(coveragePath)) {
|
|
1396
|
+
await throwUserError(`Coverage report not found at ${path.relative(repoRoot, coveragePath)}`);
|
|
424
1397
|
}
|
|
425
|
-
const
|
|
1398
|
+
const summary = computeCoverageFromFinal(coveragePath);
|
|
1399
|
+
const meetsThreshold = summary.totals.statements.pct >= args.coverage &&
|
|
1400
|
+
summary.totals.functions.pct >= args.coverage &&
|
|
1401
|
+
summary.totals.branches.pct >= args.coverage;
|
|
1402
|
+
const weakest = [...summary.files]
|
|
1403
|
+
.sort((a, b) => a.statements - b.statements)
|
|
1404
|
+
.slice(0, 10);
|
|
1405
|
+
const guidance = normalizePromptSections(collectPromptSections(["bulk-tests"]));
|
|
1406
|
+
const payload = {
|
|
1407
|
+
basePath: path.relative(getWorkspaceRoot(), repoRoot) || ".",
|
|
1408
|
+
target: args.coverage,
|
|
1409
|
+
meetsThreshold,
|
|
1410
|
+
totals: summary.totals,
|
|
1411
|
+
weakest,
|
|
1412
|
+
guidance,
|
|
1413
|
+
};
|
|
426
1414
|
return {
|
|
427
1415
|
content: [
|
|
428
1416
|
{
|
|
429
1417
|
type: "text",
|
|
430
|
-
text:
|
|
1418
|
+
text: JSON.stringify(payload, null, 2),
|
|
431
1419
|
},
|
|
1420
|
+
],
|
|
1421
|
+
};
|
|
1422
|
+
},
|
|
1423
|
+
};
|
|
1424
|
+
const readmeImprovementTool = {
|
|
1425
|
+
name: "improve-readme",
|
|
1426
|
+
description: "Summarize required steps to refresh README and workdocs content using .codex guidance and repository analysis.",
|
|
1427
|
+
parameters: readmeImprovementSchema,
|
|
1428
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1429
|
+
execute: async (input, _context) => {
|
|
1430
|
+
const args = readmeImprovementSchema.parse(input);
|
|
1431
|
+
const repoRoot = await resolveRepoRoot(args.basePath);
|
|
1432
|
+
const analysis = analyzeRepo(repoRoot);
|
|
1433
|
+
const modules = analysis.files
|
|
1434
|
+
.filter((file) => /index\.ts$/.test(file))
|
|
1435
|
+
.map((file) => path.relative(repoRoot, file));
|
|
1436
|
+
const promptSections = normalizePromptSections(collectPromptSections(["update-readme", "doc", "module"]));
|
|
1437
|
+
const testExamples = Object.keys(analysis.tests ?? {});
|
|
1438
|
+
const examples = args.includeExamples ? testExamples.slice(0, 20) : [];
|
|
1439
|
+
const payload = {
|
|
1440
|
+
basePath: path.relative(getWorkspaceRoot(), repoRoot) || ".",
|
|
1441
|
+
summary: {
|
|
1442
|
+
modules,
|
|
1443
|
+
totalSourceFiles: analysis.files.length,
|
|
1444
|
+
totalTestFiles: analysis.testFiles.length,
|
|
1445
|
+
hasReadme: Boolean(analysis.readme),
|
|
1446
|
+
},
|
|
1447
|
+
guidance: promptSections,
|
|
1448
|
+
suggestedExamples: examples,
|
|
1449
|
+
};
|
|
1450
|
+
return {
|
|
1451
|
+
content: [
|
|
432
1452
|
{
|
|
433
1453
|
type: "text",
|
|
434
|
-
text:
|
|
1454
|
+
text: JSON.stringify(payload, null, 2),
|
|
435
1455
|
},
|
|
436
1456
|
],
|
|
437
1457
|
};
|
|
438
1458
|
},
|
|
439
|
-
name: "apply-code-change",
|
|
440
|
-
parameters: codeChangeSchema,
|
|
441
1459
|
};
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
1460
|
+
|
|
1461
|
+
const DEFAULT_PLACEHOLDERS = {
|
|
1462
|
+
prompts: `export const promptList = [
|
|
1463
|
+
{
|
|
1464
|
+
id: "example-prompt",
|
|
1465
|
+
title: "Example prompt",
|
|
1466
|
+
description: "A placeholder prompt created by scaffoldModule",
|
|
1467
|
+
content: "Describe the task for the assistant...",
|
|
1468
|
+
absolutePath: __filename,
|
|
1469
|
+
},
|
|
1470
|
+
] as const;
|
|
1471
|
+
`,
|
|
1472
|
+
resources: `export const resources = [
|
|
1473
|
+
{
|
|
1474
|
+
id: "example-resource",
|
|
1475
|
+
name: "Example Resource",
|
|
1476
|
+
description: "A placeholder resource created by scaffoldModule",
|
|
1477
|
+
uri: "file://placeholder",
|
|
1478
|
+
absolutePath: __filename,
|
|
1479
|
+
},
|
|
1480
|
+
] as const;
|
|
1481
|
+
`,
|
|
1482
|
+
templates: `export const templates = [
|
|
1483
|
+
{
|
|
1484
|
+
name: "example-template",
|
|
1485
|
+
description: "A placeholder template created by scaffoldModule",
|
|
1486
|
+
uriTemplate: "file://template/{path}",
|
|
1487
|
+
mimeType: "text/plain",
|
|
1488
|
+
},
|
|
1489
|
+
] as const;
|
|
1490
|
+
`,
|
|
1491
|
+
tools: `export const toolList = [
|
|
1492
|
+
{
|
|
1493
|
+
id: "example-tool",
|
|
1494
|
+
name: "example-tool",
|
|
1495
|
+
description: "A placeholder tool created by scaffoldModule",
|
|
1496
|
+
run: async () => ({ result: "placeholder" }),
|
|
1497
|
+
},
|
|
1498
|
+
] as const;
|
|
1499
|
+
`,
|
|
446
1500
|
};
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
1501
|
+
/**
|
|
1502
|
+
* Create a module scaffold under repoRoot/src/modules/<moduleName>
|
|
1503
|
+
* Returns created files list.
|
|
1504
|
+
*/
|
|
1505
|
+
function scaffoldModule(repoRoot, moduleName) {
|
|
1506
|
+
if (!repoRoot)
|
|
1507
|
+
throw new Error("repoRoot is required");
|
|
1508
|
+
if (!moduleName)
|
|
1509
|
+
throw new Error("moduleName is required");
|
|
1510
|
+
const modulePath = path.join(repoRoot, "src", "modules", moduleName);
|
|
1511
|
+
const createdFiles = [];
|
|
1512
|
+
const subfolders = ["prompts", "resources", "templates", "tools"];
|
|
1513
|
+
for (const folder of subfolders) {
|
|
1514
|
+
const folderPath = path.join(modulePath, folder);
|
|
1515
|
+
fs.mkdirSync(folderPath, { recursive: true });
|
|
1516
|
+
const indexPath = path.join(folderPath, "index.ts");
|
|
1517
|
+
// if file exists, skip writing
|
|
1518
|
+
if (!fs.existsSync(indexPath)) {
|
|
1519
|
+
// insert __filename for absolutePath in placeholders
|
|
1520
|
+
const content = DEFAULT_PLACEHOLDERS[folder].replace(/__filename/g, JSON.stringify(indexPath));
|
|
1521
|
+
fs.writeFileSync(indexPath, content, { encoding: "utf8" });
|
|
1522
|
+
createdFiles.push(indexPath);
|
|
1523
|
+
}
|
|
450
1524
|
}
|
|
451
|
-
|
|
452
|
-
|
|
1525
|
+
return { modulePath, createdFiles };
|
|
1526
|
+
}
|
|
1527
|
+
// CLI support when required directly via ts-node registration
|
|
1528
|
+
if (require.main === module) {
|
|
1529
|
+
const [, , moduleName] = process.argv;
|
|
1530
|
+
if (!moduleName) {
|
|
1531
|
+
console.error("Usage: scaffold-module <module-name>");
|
|
1532
|
+
process.exit(1);
|
|
453
1533
|
}
|
|
454
|
-
|
|
455
|
-
|
|
1534
|
+
try {
|
|
1535
|
+
const res = scaffoldModule(process.cwd(), moduleName);
|
|
1536
|
+
console.log("Scaffolded module:", res.modulePath);
|
|
1537
|
+
for (const f of res.createdFiles)
|
|
1538
|
+
console.log(" created:", f);
|
|
1539
|
+
process.exit(0);
|
|
1540
|
+
}
|
|
1541
|
+
catch (err) {
|
|
1542
|
+
console.error(err && err.message ? err.message : err);
|
|
1543
|
+
process.exit(2);
|
|
456
1544
|
}
|
|
457
|
-
return mcp;
|
|
458
1545
|
}
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
1546
|
+
|
|
1547
|
+
// New tool: generate-mcp-module
|
|
1548
|
+
zod.z.object({
|
|
1549
|
+
repoPath: zod.z.string().optional().default("."),
|
|
1550
|
+
moduleName: zod.z.string().optional(),
|
|
1551
|
+
includeDocs: zod.z.boolean().default(true),
|
|
1552
|
+
});
|
|
1553
|
+
|
|
1554
|
+
const codexToolList = [
|
|
1555
|
+
documentObjectTool,
|
|
1556
|
+
coverageEnforcerTool,
|
|
1557
|
+
readmeImprovementTool,
|
|
1558
|
+
];
|
|
1559
|
+
const moduleToolList = moduleRegistry.listTools().map((asset) => asset.tool);
|
|
1560
|
+
const toolList = [...toolList$1, ...codexToolList, ...moduleToolList];
|
|
1561
|
+
const [analyzeRepositoryTool, enumerateCapabilitiesTool, planFeatureTool, documentCodeToolRef, applyCodeChangeToolRef,] = toolList$1;
|
|
1562
|
+
const tools = {
|
|
1563
|
+
analyzeRepositoryTool,
|
|
1564
|
+
enumerateCapabilitiesTool,
|
|
1565
|
+
planFeatureTool,
|
|
1566
|
+
documentCodeTool: documentCodeToolRef,
|
|
1567
|
+
applyCodeChangeTool: applyCodeChangeToolRef,
|
|
1568
|
+
documentObjectTool,
|
|
1569
|
+
coverageEnforcerTool,
|
|
1570
|
+
readmeImprovementTool,
|
|
1571
|
+
...decoratorTools,
|
|
1572
|
+
};
|
|
1573
|
+
|
|
1574
|
+
function toResource(asset) {
|
|
1575
|
+
return {
|
|
1576
|
+
name: asset.id,
|
|
1577
|
+
uri: asset.uri,
|
|
1578
|
+
description: asset.description ?? asset.title,
|
|
1579
|
+
mimeType: asset.mimeType,
|
|
1580
|
+
load: async () => {
|
|
1581
|
+
const res = await asset.load();
|
|
1582
|
+
// asset.load may return a ContentResult or a Promise of ContentResult; ensure we return ResourceResult-like object
|
|
1583
|
+
if (res?.content) {
|
|
1584
|
+
const cr = res;
|
|
1585
|
+
// If ContentResult, convert to simple text result expected by Resource.load consumers
|
|
1586
|
+
return {
|
|
1587
|
+
text: Array.isArray(cr.content)
|
|
1588
|
+
? cr.content.map((c) => c.text).join("\n")
|
|
1589
|
+
: String(cr),
|
|
1590
|
+
};
|
|
1591
|
+
}
|
|
1592
|
+
// fallback for objects with text
|
|
1593
|
+
return res;
|
|
1594
|
+
},
|
|
1595
|
+
};
|
|
463
1596
|
}
|
|
464
|
-
function
|
|
465
|
-
return
|
|
1597
|
+
function buildModuleResources() {
|
|
1598
|
+
return moduleRegistry.listResources().map(toResource);
|
|
1599
|
+
}
|
|
1600
|
+
const resources = [
|
|
1601
|
+
{
|
|
1602
|
+
name: "codex-prompt-index",
|
|
1603
|
+
uri: "codex://prompts/index",
|
|
1604
|
+
description: "Enumerate available .codex prompt files with titles and descriptions.",
|
|
1605
|
+
mimeType: "application/json",
|
|
1606
|
+
load: async () => {
|
|
1607
|
+
const root = getWorkspaceRoot();
|
|
1608
|
+
const prompts = discoverDocPrompts(root).map((prompt) => ({
|
|
1609
|
+
name: prompt.name,
|
|
1610
|
+
title: prompt.title,
|
|
1611
|
+
description: prompt.description,
|
|
1612
|
+
path: prompt.absolutePath,
|
|
1613
|
+
}));
|
|
1614
|
+
return {
|
|
1615
|
+
text: JSON.stringify({ prompts }, null, 2),
|
|
1616
|
+
mimeType: "application/json",
|
|
1617
|
+
};
|
|
1618
|
+
},
|
|
1619
|
+
},
|
|
1620
|
+
{
|
|
1621
|
+
name: "codex-object-prompts",
|
|
1622
|
+
uri: "codex://prompts/objects",
|
|
1623
|
+
description: "Provides the resolved prompt content for each documented object workflow.",
|
|
1624
|
+
mimeType: "application/json",
|
|
1625
|
+
load: async () => {
|
|
1626
|
+
const entries = await Promise.all(buildObjectPrompts().map(async (prompt) => ({
|
|
1627
|
+
name: prompt.name,
|
|
1628
|
+
description: prompt.description,
|
|
1629
|
+
content: await prompt.load({}),
|
|
1630
|
+
})));
|
|
1631
|
+
return {
|
|
1632
|
+
text: JSON.stringify({ prompts: entries }, null, 2),
|
|
1633
|
+
mimeType: "application/json",
|
|
1634
|
+
};
|
|
1635
|
+
},
|
|
1636
|
+
},
|
|
1637
|
+
...buildModuleResources(),
|
|
1638
|
+
];
|
|
1639
|
+
|
|
1640
|
+
const codexPromptTemplates = [];
|
|
1641
|
+
function buildCodexPromptTemplates() {
|
|
1642
|
+
const root = getWorkspaceRoot();
|
|
1643
|
+
const templates = [
|
|
1644
|
+
{
|
|
1645
|
+
name: "codex-prompt",
|
|
1646
|
+
description: "Load a .codex prompt file by name (without extension) as markdown.",
|
|
1647
|
+
uriTemplate: "codex-prompt://{name}",
|
|
1648
|
+
mimeType: "text/markdown",
|
|
1649
|
+
arguments: [
|
|
1650
|
+
{
|
|
1651
|
+
name: "name",
|
|
1652
|
+
description: "Name of the prompt file inside .codex/prompts (without .md).",
|
|
1653
|
+
required: true,
|
|
1654
|
+
},
|
|
1655
|
+
],
|
|
1656
|
+
load: async ({ name }) => {
|
|
1657
|
+
const promptPath = resolveInWorkspace(root, path.join(".codex", "prompts", `${name}.md`));
|
|
1658
|
+
if (!fs.existsSync(promptPath)) {
|
|
1659
|
+
throw new Error(`Prompt .codex/prompts/${name}.md not found`);
|
|
1660
|
+
}
|
|
1661
|
+
const text = fs.readFileSync(promptPath, "utf8");
|
|
1662
|
+
return { text, uri: `codex-prompt:///${name}` };
|
|
1663
|
+
},
|
|
1664
|
+
},
|
|
1665
|
+
];
|
|
1666
|
+
codexPromptTemplates.splice(0, codexPromptTemplates.length, ...templates);
|
|
1667
|
+
return codexPromptTemplates;
|
|
1668
|
+
}
|
|
1669
|
+
|
|
1670
|
+
const decorationResourceTemplates = [];
|
|
1671
|
+
function makeLoader(type) {
|
|
1672
|
+
return async ({ path: relative }) => {
|
|
1673
|
+
const root = getWorkspaceRoot();
|
|
1674
|
+
const target = path.join(type, relative);
|
|
1675
|
+
const text = await readWorkspaceFile(root, target);
|
|
1676
|
+
return { text };
|
|
1677
|
+
};
|
|
1678
|
+
}
|
|
1679
|
+
function buildDecorationResourceTemplates() {
|
|
1680
|
+
const templates = [
|
|
1681
|
+
{
|
|
1682
|
+
name: "read-code-from-source",
|
|
1683
|
+
description: "Read a file from the <base_path>/src tree by relative path.",
|
|
1684
|
+
mimeType: "text/plain",
|
|
1685
|
+
uriTemplate: "from-source://src/{path}",
|
|
1686
|
+
arguments: [
|
|
1687
|
+
{
|
|
1688
|
+
name: "path",
|
|
1689
|
+
description: "Path under <base_path>/src to load, e.g. 'decoration/types.ts'",
|
|
1690
|
+
required: true,
|
|
1691
|
+
},
|
|
1692
|
+
],
|
|
1693
|
+
load: makeLoader("src"),
|
|
1694
|
+
},
|
|
1695
|
+
{
|
|
1696
|
+
name: "read-test-from-source",
|
|
1697
|
+
description: "Read a file from the <base_path>/tests tree by relative path.",
|
|
1698
|
+
mimeType: "text/plain",
|
|
1699
|
+
uriTemplate: "from-source://tests/{path}",
|
|
1700
|
+
arguments: [
|
|
1701
|
+
{
|
|
1702
|
+
name: "path",
|
|
1703
|
+
description: "Path under <base_path>/tests to load, e.g. 'decoration/tests/types.test.ts'",
|
|
1704
|
+
required: true,
|
|
1705
|
+
},
|
|
1706
|
+
],
|
|
1707
|
+
load: makeLoader("tests"),
|
|
1708
|
+
},
|
|
1709
|
+
{
|
|
1710
|
+
name: "read-doc-from-source",
|
|
1711
|
+
description: "Read a file from the <base_path>/workdocs tree by relative path.",
|
|
1712
|
+
mimeType: "text/plain",
|
|
1713
|
+
uriTemplate: "from-source://workdocs/{path}",
|
|
1714
|
+
arguments: [
|
|
1715
|
+
{
|
|
1716
|
+
name: "path",
|
|
1717
|
+
description: "Path under <base_path>/workdocs to load, e.g. 'decoration/workdocs/tutorials/for-developers.md'",
|
|
1718
|
+
required: true,
|
|
1719
|
+
},
|
|
1720
|
+
],
|
|
1721
|
+
load: makeLoader("workdocs"),
|
|
1722
|
+
},
|
|
1723
|
+
];
|
|
1724
|
+
decorationResourceTemplates.splice(0, decorationResourceTemplates.length, ...templates);
|
|
1725
|
+
return decorationResourceTemplates;
|
|
466
1726
|
}
|
|
467
|
-
|
|
1727
|
+
|
|
1728
|
+
const workspaceResourceTemplates = [];
|
|
1729
|
+
function buildWorkspaceResourceTemplates() {
|
|
468
1730
|
const root = getWorkspaceRoot();
|
|
469
1731
|
const sharedArguments = [
|
|
470
1732
|
{
|
|
@@ -473,7 +1735,7 @@
|
|
|
473
1735
|
required: true,
|
|
474
1736
|
},
|
|
475
1737
|
];
|
|
476
|
-
|
|
1738
|
+
const templates = [
|
|
477
1739
|
{
|
|
478
1740
|
name: "vscode-workspace-file",
|
|
479
1741
|
description: "Expose workspace files to Visual Studio Code via vscode:// URIs",
|
|
@@ -481,8 +1743,14 @@
|
|
|
481
1743
|
mimeType: "text/plain",
|
|
482
1744
|
arguments: sharedArguments,
|
|
483
1745
|
load: async (args) => {
|
|
484
|
-
|
|
485
|
-
|
|
1746
|
+
try {
|
|
1747
|
+
const text = await readWorkspaceFile(root, args.path);
|
|
1748
|
+
return { text: String(text) };
|
|
1749
|
+
}
|
|
1750
|
+
catch (err) {
|
|
1751
|
+
// propagate as-is for tests to assert errors
|
|
1752
|
+
throw err;
|
|
1753
|
+
}
|
|
486
1754
|
},
|
|
487
1755
|
},
|
|
488
1756
|
{
|
|
@@ -492,8 +1760,13 @@
|
|
|
492
1760
|
mimeType: "text/plain",
|
|
493
1761
|
arguments: sharedArguments,
|
|
494
1762
|
load: async (args) => {
|
|
495
|
-
|
|
496
|
-
|
|
1763
|
+
try {
|
|
1764
|
+
const text = await readWorkspaceFile(root, args.path);
|
|
1765
|
+
return { text: String(text) };
|
|
1766
|
+
}
|
|
1767
|
+
catch (err) {
|
|
1768
|
+
throw err;
|
|
1769
|
+
}
|
|
497
1770
|
},
|
|
498
1771
|
},
|
|
499
1772
|
{
|
|
@@ -503,164 +1776,510 @@
|
|
|
503
1776
|
mimeType: "text/plain",
|
|
504
1777
|
arguments: sharedArguments,
|
|
505
1778
|
load: async (args) => {
|
|
506
|
-
|
|
507
|
-
|
|
1779
|
+
try {
|
|
1780
|
+
const text = await readWorkspaceFile(root, args.path);
|
|
1781
|
+
return { text: String(text) };
|
|
1782
|
+
}
|
|
1783
|
+
catch (err) {
|
|
1784
|
+
throw err;
|
|
1785
|
+
}
|
|
508
1786
|
},
|
|
509
1787
|
},
|
|
510
1788
|
];
|
|
1789
|
+
workspaceResourceTemplates.splice(0, workspaceResourceTemplates.length, ...templates);
|
|
1790
|
+
return workspaceResourceTemplates;
|
|
511
1791
|
}
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
load: async () =>
|
|
1792
|
+
|
|
1793
|
+
function buildResourceTemplates() {
|
|
1794
|
+
const moduleTemplates = moduleRegistry.listTemplates().map((template) => ({
|
|
1795
|
+
name: template.id,
|
|
1796
|
+
description: template.description ?? template.title,
|
|
1797
|
+
mimeType: "text/markdown",
|
|
1798
|
+
uriTemplate: `module-template://${template.id}`,
|
|
1799
|
+
arguments: (template.placeholders ?? []).map((name) => ({
|
|
1800
|
+
name,
|
|
1801
|
+
description: `Value for ${name}`,
|
|
1802
|
+
required: true,
|
|
1803
|
+
})),
|
|
1804
|
+
load: async () => ({
|
|
1805
|
+
text: typeof template.content === "string"
|
|
1806
|
+
? template.content
|
|
1807
|
+
: `# ${template.description ?? template.title ?? template.id}\n\nNo template content available for ${template.id}`,
|
|
1808
|
+
}),
|
|
525
1809
|
}));
|
|
526
|
-
const
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
1810
|
+
const all = [
|
|
1811
|
+
...buildWorkspaceResourceTemplates(),
|
|
1812
|
+
...buildCodexPromptTemplates(),
|
|
1813
|
+
...buildDecorationResourceTemplates(),
|
|
1814
|
+
...moduleTemplates,
|
|
1815
|
+
];
|
|
1816
|
+
// Normalise all loaders to always return { text: string }
|
|
1817
|
+
function normaliseResult(res) {
|
|
1818
|
+
if (res == null)
|
|
1819
|
+
return { text: "" };
|
|
1820
|
+
if (typeof res === "string")
|
|
1821
|
+
return { text: res };
|
|
1822
|
+
if (typeof res.text === "string")
|
|
1823
|
+
return res;
|
|
1824
|
+
// handle legacy ContentResult shapes with content or content array
|
|
1825
|
+
if (Array.isArray(res.content)) {
|
|
1826
|
+
const parts = res.content
|
|
1827
|
+
.map((c) => (c && typeof c.text === "string" ? c.text : String(c)))
|
|
1828
|
+
.join("\n");
|
|
1829
|
+
return { text: parts };
|
|
1830
|
+
}
|
|
1831
|
+
if (res.content && typeof res.content.text === "string") {
|
|
1832
|
+
return { text: res.content.text };
|
|
1833
|
+
}
|
|
1834
|
+
// fallback: stringify
|
|
1835
|
+
try {
|
|
1836
|
+
return { text: JSON.stringify(res) };
|
|
1837
|
+
}
|
|
1838
|
+
catch {
|
|
1839
|
+
return { text: String(res) };
|
|
1840
|
+
}
|
|
1841
|
+
}
|
|
1842
|
+
return all.map((t) => ({
|
|
1843
|
+
...t,
|
|
1844
|
+
load: async (args) => {
|
|
1845
|
+
const raw = await t.load(args);
|
|
1846
|
+
return normaliseResult(raw);
|
|
1847
|
+
},
|
|
530
1848
|
}));
|
|
531
|
-
return [...fileBasedPrompts, ...integrationPrompts];
|
|
532
1849
|
}
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
1850
|
+
const templateList = buildResourceTemplates();
|
|
1851
|
+
|
|
1852
|
+
/**
|
|
1853
|
+
* @const VERSION
|
|
1854
|
+
* @name VERSION
|
|
1855
|
+
* @description Represents the current version of the ts-workspace module.
|
|
1856
|
+
* @summary The actual version number is replaced during the build process.
|
|
1857
|
+
* @type {string}
|
|
1858
|
+
*/
|
|
1859
|
+
const VERSION$1 = "0.1.0";
|
|
1860
|
+
const PACKAGE_NAME$1 = "##PACKAGE_NAME##";
|
|
1861
|
+
try {
|
|
1862
|
+
decoration.Metadata.registerLibrary(PACKAGE_NAME$1, VERSION$1);
|
|
1863
|
+
}
|
|
1864
|
+
catch (error) {
|
|
1865
|
+
if (error instanceof Error && error.message.includes("already")) ;
|
|
1866
|
+
else {
|
|
1867
|
+
throw error;
|
|
540
1868
|
}
|
|
541
|
-
return resolved;
|
|
542
1869
|
}
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
1870
|
+
|
|
1871
|
+
function enrich(mcp) {
|
|
1872
|
+
const promptEntries = loadPrompts();
|
|
1873
|
+
for (const prompt of promptEntries) {
|
|
1874
|
+
mcp.addPrompt(prompt);
|
|
547
1875
|
}
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
1876
|
+
for (const tool of toolList) {
|
|
1877
|
+
mcp.addTool(tool);
|
|
1878
|
+
}
|
|
1879
|
+
const templates = buildResourceTemplates();
|
|
1880
|
+
for (const template of templates) {
|
|
1881
|
+
mcp.addResourceTemplate(template);
|
|
1882
|
+
}
|
|
1883
|
+
for (const resource of resources) {
|
|
1884
|
+
const addResource = mcp.addResource;
|
|
1885
|
+
if (typeof addResource === "function") {
|
|
1886
|
+
addResource.call(mcp, resource);
|
|
551
1887
|
}
|
|
552
|
-
/* istanbul ignore next */
|
|
553
|
-
throw error;
|
|
554
1888
|
}
|
|
1889
|
+
return mcp;
|
|
1890
|
+
}
|
|
1891
|
+
const PACKAGE_NAME = PACKAGE_NAME$1;
|
|
1892
|
+
const VERSION = VERSION$1;
|
|
1893
|
+
|
|
1894
|
+
// New: validation entrypoint for module structure
|
|
1895
|
+
const REQUIRED_SUBFOLDERS = ["prompts", "resources", "templates", "tools"];
|
|
1896
|
+
function findModuleDirs(repoRoot) {
|
|
1897
|
+
const modulesPath = path.resolve(repoRoot, "src", "modules");
|
|
1898
|
+
if (!fs.existsSync(modulesPath) || !fs.statSync(modulesPath).isDirectory()) {
|
|
1899
|
+
return [];
|
|
1900
|
+
}
|
|
1901
|
+
return fs
|
|
1902
|
+
.readdirSync(modulesPath, { withFileTypes: true })
|
|
1903
|
+
.filter((d) => d.isDirectory())
|
|
1904
|
+
.map((d) => path.join(modulesPath, d.name));
|
|
555
1905
|
}
|
|
556
|
-
function
|
|
557
|
-
const
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
1906
|
+
function hasIndexExport(folderPath) {
|
|
1907
|
+
const candidates = [
|
|
1908
|
+
"index.ts",
|
|
1909
|
+
"index.tsx",
|
|
1910
|
+
"index.js",
|
|
1911
|
+
"index.cjs",
|
|
1912
|
+
"index.mjs",
|
|
1913
|
+
];
|
|
1914
|
+
for (const c of candidates) {
|
|
1915
|
+
if (fs.existsSync(path.join(folderPath, c)))
|
|
1916
|
+
return true;
|
|
1917
|
+
}
|
|
1918
|
+
return false;
|
|
1919
|
+
}
|
|
1920
|
+
function validateModules(repoRoot) {
|
|
1921
|
+
const dirs = findModuleDirs(repoRoot);
|
|
1922
|
+
const issues = [];
|
|
1923
|
+
for (const moduleDir of dirs) {
|
|
1924
|
+
const moduleName = path.basename(moduleDir);
|
|
1925
|
+
for (const sub of REQUIRED_SUBFOLDERS) {
|
|
1926
|
+
const subPath = path.join(moduleDir, sub);
|
|
1927
|
+
if (!fs.existsSync(subPath) || !fs.statSync(subPath).isDirectory()) {
|
|
1928
|
+
issues.push({
|
|
1929
|
+
module: moduleName,
|
|
1930
|
+
path: subPath,
|
|
1931
|
+
type: "missing-folder",
|
|
1932
|
+
detail: `Required folder '${sub}' is missing in module '${moduleName}'`,
|
|
1933
|
+
});
|
|
566
1934
|
continue;
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
}
|
|
1935
|
+
}
|
|
1936
|
+
// If folder exists, check for index export
|
|
1937
|
+
if (!hasIndexExport(subPath)) {
|
|
1938
|
+
issues.push({
|
|
1939
|
+
module: moduleName,
|
|
1940
|
+
path: subPath,
|
|
1941
|
+
type: "missing-export",
|
|
1942
|
+
detail: `No index export found in '${subPath}'. Expected one of index.ts, index.js, etc.`,
|
|
1943
|
+
});
|
|
1944
|
+
continue;
|
|
1945
|
+
}
|
|
1946
|
+
// Optionally inspect the index file to see if it exports a list (lightweight check)
|
|
1947
|
+
try {
|
|
1948
|
+
const indexFile = candidatesFindingIndex(subPath);
|
|
1949
|
+
if (indexFile) {
|
|
1950
|
+
const content = fs.readFileSync(indexFile, "utf8");
|
|
1951
|
+
// crude heuristics: look for `export const name = [` or `export const name: Type[] = [`,
|
|
1952
|
+
// or any named export like `export { something }` which implies exports exist.
|
|
1953
|
+
const exportListPattern = /export\s+(const|let|var)\s+[\w$]+(?:\s*:\s*[^=]+)?\s*=\s*\[/;
|
|
1954
|
+
if (!exportListPattern.test(content) &&
|
|
1955
|
+
!/export\s+\{/.test(content)) {
|
|
1956
|
+
issues.push({
|
|
1957
|
+
module: moduleName,
|
|
1958
|
+
path: indexFile,
|
|
1959
|
+
type: "empty-list",
|
|
1960
|
+
detail: `Index file does not appear to export a list of assets: ${path.basename(indexFile)}`,
|
|
1961
|
+
});
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1965
|
+
catch (err) {
|
|
1966
|
+
issues.push({
|
|
1967
|
+
module: moduleName,
|
|
1968
|
+
path: subPath,
|
|
1969
|
+
type: "other",
|
|
1970
|
+
detail: `Error reading index file: ${err.message}`,
|
|
1971
|
+
});
|
|
1972
|
+
}
|
|
578
1973
|
}
|
|
579
1974
|
}
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
1975
|
+
return {
|
|
1976
|
+
ok: issues.length === 0,
|
|
1977
|
+
modulesChecked: dirs.length,
|
|
1978
|
+
issues,
|
|
1979
|
+
};
|
|
1980
|
+
}
|
|
1981
|
+
function candidatesFindingIndex(folderPath) {
|
|
1982
|
+
const candidates = [
|
|
1983
|
+
"index.ts",
|
|
1984
|
+
"index.tsx",
|
|
1985
|
+
"index.js",
|
|
1986
|
+
"index.cjs",
|
|
1987
|
+
"index.mjs",
|
|
1988
|
+
];
|
|
1989
|
+
for (const c of candidates) {
|
|
1990
|
+
const full = path.join(folderPath, c);
|
|
1991
|
+
if (fs.existsSync(full))
|
|
1992
|
+
return full;
|
|
585
1993
|
}
|
|
586
|
-
return
|
|
1994
|
+
return undefined;
|
|
587
1995
|
}
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
if (!prompts.length) {
|
|
596
|
-
throw new WorkspaceError("No documentation prompts available");
|
|
1996
|
+
// CLI helper
|
|
1997
|
+
if (require.main === module) {
|
|
1998
|
+
const repoRoot = process.cwd();
|
|
1999
|
+
const report = validateModules(repoRoot);
|
|
2000
|
+
if (!report.ok) {
|
|
2001
|
+
console.error("Module validation failed:\n", JSON.stringify(report, null, 2));
|
|
2002
|
+
process.exit(2);
|
|
597
2003
|
}
|
|
598
|
-
|
|
2004
|
+
console.log("Module validation passed");
|
|
2005
|
+
process.exit(0);
|
|
599
2006
|
}
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
2007
|
+
|
|
2008
|
+
// Aggregator: import module index files and merge exported arrays with provenance + duplicate detection
|
|
2009
|
+
const SUBFOLDERS = ["prompts", "resources", "templates", "tools"];
|
|
2010
|
+
const INDEX_CANDIDATES = [
|
|
2011
|
+
"index.ts",
|
|
2012
|
+
"index.tsx",
|
|
2013
|
+
"index.js",
|
|
2014
|
+
"index.cjs",
|
|
2015
|
+
"index.mjs",
|
|
2016
|
+
];
|
|
2017
|
+
function findIndexFile(folder) {
|
|
2018
|
+
for (const c of INDEX_CANDIDATES) {
|
|
2019
|
+
const f = path.join(folder, c);
|
|
2020
|
+
if (fs.existsSync(f))
|
|
2021
|
+
return f;
|
|
604
2022
|
}
|
|
605
|
-
|
|
606
|
-
|
|
2023
|
+
return undefined;
|
|
2024
|
+
}
|
|
2025
|
+
function makeKeyForItem(item) {
|
|
2026
|
+
if (!item)
|
|
2027
|
+
return JSON.stringify(item);
|
|
2028
|
+
if (typeof item === "string")
|
|
2029
|
+
return `str:${item}`;
|
|
2030
|
+
if (typeof item === "number")
|
|
2031
|
+
return `num:${item}`;
|
|
2032
|
+
if (item.id)
|
|
2033
|
+
return `id:${item.id}`;
|
|
2034
|
+
if (item.name)
|
|
2035
|
+
return `name:${item.name}`;
|
|
2036
|
+
// fallback to stable string
|
|
2037
|
+
try {
|
|
2038
|
+
return `obj:${JSON.stringify(item)}`;
|
|
607
2039
|
}
|
|
608
|
-
|
|
609
|
-
|
|
2040
|
+
catch (e) {
|
|
2041
|
+
return `obj:${String(item)}`;
|
|
610
2042
|
}
|
|
611
|
-
|
|
612
|
-
|
|
2043
|
+
}
|
|
2044
|
+
async function loadArrayFromIndex(filePath) {
|
|
2045
|
+
// Prefer a fast, static parse of the first array literal found in the file.
|
|
2046
|
+
try {
|
|
2047
|
+
const content = fs.readFileSync(filePath, "utf8");
|
|
2048
|
+
const start = content.indexOf("[");
|
|
2049
|
+
if (start !== -1) {
|
|
2050
|
+
let depth = 0;
|
|
2051
|
+
let end = -1;
|
|
2052
|
+
for (let i = start; i < content.length; i++) {
|
|
2053
|
+
const ch = content[i];
|
|
2054
|
+
if (ch === "[")
|
|
2055
|
+
depth++;
|
|
2056
|
+
else if (ch === "]") {
|
|
2057
|
+
depth--;
|
|
2058
|
+
if (depth === 0) {
|
|
2059
|
+
end = i;
|
|
2060
|
+
break;
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
}
|
|
2064
|
+
if (end !== -1) {
|
|
2065
|
+
const arrText = content.slice(start, end + 1);
|
|
2066
|
+
try {
|
|
2067
|
+
return JSON.parse(arrText);
|
|
2068
|
+
}
|
|
2069
|
+
catch (e) {
|
|
2070
|
+
// Normalize TS object literals to JSON:
|
|
2071
|
+
// - convert single quotes to double quotes
|
|
2072
|
+
// - quote unquoted object keys
|
|
2073
|
+
// - strip trailing commas
|
|
2074
|
+
const normalized = arrText
|
|
2075
|
+
// unify quotes in string literals
|
|
2076
|
+
.replace(/'(?:\\'|[^'])*'/g, (m) => m.replace(/'/g, '"'))
|
|
2077
|
+
// quote unquoted keys after { or ,
|
|
2078
|
+
.replace(/([\{,]\s*)([A-Za-z_$][\w$]*)(\s*:)/g, '$1"$2"$3')
|
|
2079
|
+
// remove trailing commas before ] or }
|
|
2080
|
+
.replace(/,(\s*[\}\]])/g, '$1');
|
|
2081
|
+
try {
|
|
2082
|
+
return JSON.parse(normalized);
|
|
2083
|
+
}
|
|
2084
|
+
catch (e2) {
|
|
2085
|
+
// fallthrough to import attempt below
|
|
2086
|
+
}
|
|
2087
|
+
}
|
|
2088
|
+
}
|
|
2089
|
+
}
|
|
613
2090
|
}
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
2091
|
+
catch (e) {
|
|
2092
|
+
// ignore static parse errors and fall back to import
|
|
2093
|
+
}
|
|
2094
|
+
try {
|
|
2095
|
+
const fileUrl = url.pathToFileURL(filePath).href;
|
|
2096
|
+
const mod = await import(fileUrl);
|
|
2097
|
+
// Find first export that is an array
|
|
2098
|
+
for (const key of Object.keys(mod)) {
|
|
2099
|
+
const val = mod[key];
|
|
2100
|
+
if (Array.isArray(val))
|
|
2101
|
+
return val;
|
|
2102
|
+
}
|
|
2103
|
+
// default export check
|
|
2104
|
+
if (Array.isArray(mod.default))
|
|
2105
|
+
return mod.default;
|
|
2106
|
+
return undefined;
|
|
2107
|
+
}
|
|
2108
|
+
catch (err) {
|
|
2109
|
+
// fallback: if import fails, try to static-parse again (already attempted) and finally return undefined
|
|
2110
|
+
return undefined;
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
2113
|
+
async function aggregateModules(repoRoot) {
|
|
2114
|
+
const dirs = findModuleDirs(repoRoot);
|
|
2115
|
+
const master = {
|
|
2116
|
+
prompts: [],
|
|
2117
|
+
resources: [],
|
|
2118
|
+
templates: [],
|
|
2119
|
+
tools: [],
|
|
2120
|
+
conflicts: [],
|
|
2121
|
+
};
|
|
2122
|
+
// maps to detect duplicates per type
|
|
2123
|
+
const maps = {
|
|
2124
|
+
prompts: new Map(),
|
|
2125
|
+
resources: new Map(),
|
|
2126
|
+
templates: new Map(),
|
|
2127
|
+
tools: new Map(),
|
|
621
2128
|
};
|
|
2129
|
+
for (const moduleDir of dirs) {
|
|
2130
|
+
const moduleName = path.basename(moduleDir);
|
|
2131
|
+
for (const sub of SUBFOLDERS) {
|
|
2132
|
+
const folder = path.join(moduleDir, sub);
|
|
2133
|
+
const indexFile = findIndexFile(folder);
|
|
2134
|
+
if (!indexFile)
|
|
2135
|
+
continue;
|
|
2136
|
+
let arr;
|
|
2137
|
+
try {
|
|
2138
|
+
arr = await loadArrayFromIndex(indexFile);
|
|
2139
|
+
}
|
|
2140
|
+
catch (err) {
|
|
2141
|
+
// skip module on import error but record as conflict-like issue
|
|
2142
|
+
master.conflicts.push({
|
|
2143
|
+
key: `import-error:${moduleName}:${sub}`,
|
|
2144
|
+
existing: { moduleName, modulePath: moduleDir },
|
|
2145
|
+
incoming: { moduleName, modulePath: moduleDir },
|
|
2146
|
+
});
|
|
2147
|
+
continue;
|
|
2148
|
+
}
|
|
2149
|
+
if (!arr || !Array.isArray(arr))
|
|
2150
|
+
continue;
|
|
2151
|
+
for (const item of arr) {
|
|
2152
|
+
const key = makeKeyForItem(item);
|
|
2153
|
+
const provenance = { moduleName, modulePath: moduleDir };
|
|
2154
|
+
const map = maps[sub];
|
|
2155
|
+
if (map.has(key)) {
|
|
2156
|
+
// record conflict deterministically (existing vs incoming)
|
|
2157
|
+
const existing = map.get(key);
|
|
2158
|
+
master.conflicts.push({ key, existing, incoming: provenance });
|
|
2159
|
+
// skip adding duplicate
|
|
2160
|
+
continue;
|
|
2161
|
+
}
|
|
2162
|
+
map.set(key, provenance);
|
|
2163
|
+
master[sub].push({ ...item, provenance });
|
|
2164
|
+
}
|
|
2165
|
+
}
|
|
2166
|
+
}
|
|
2167
|
+
return master;
|
|
622
2168
|
}
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
2169
|
+
// For compatibility with CommonJS call sites (not exported by ESM), provide a sync wrapper
|
|
2170
|
+
function aggregateModulesSync(repoRoot) {
|
|
2171
|
+
// synchronous wrapper that runs the async function and blocks — suitable for small module sets
|
|
2172
|
+
const p = aggregateModules(repoRoot);
|
|
2173
|
+
let result;
|
|
2174
|
+
let done = false;
|
|
2175
|
+
p.then((r) => {
|
|
2176
|
+
result = r;
|
|
2177
|
+
done = true;
|
|
2178
|
+
}).catch((e) => {
|
|
2179
|
+
throw e;
|
|
2180
|
+
});
|
|
2181
|
+
if (!done)
|
|
2182
|
+
throw new Error("aggregateModulesSync: timeout waiting for async aggregation");
|
|
2183
|
+
return result;
|
|
630
2184
|
}
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
2185
|
+
|
|
2186
|
+
/**
|
|
2187
|
+
* Aggregate module assets and register them on the provided FastMCP-like server.
|
|
2188
|
+
* Falls back to built-in lists if aggregation yields none.
|
|
2189
|
+
*/
|
|
2190
|
+
async function EnrichCoreWithAggregation(server, repoRoot = process.cwd()) {
|
|
2191
|
+
// First register built-in prompts/tools/resources/templates (legacy behavior)
|
|
2192
|
+
try {
|
|
2193
|
+
loadPrompts();
|
|
2194
|
+
for (const prompt of promptList)
|
|
2195
|
+
server.addPrompt(prompt);
|
|
2196
|
+
}
|
|
2197
|
+
catch (e) {
|
|
2198
|
+
// ignore if loadPrompts not available or fails
|
|
2199
|
+
}
|
|
2200
|
+
try {
|
|
2201
|
+
for (const tool of toolList)
|
|
2202
|
+
server.addTool(tool);
|
|
2203
|
+
}
|
|
2204
|
+
catch (e) { }
|
|
2205
|
+
try {
|
|
2206
|
+
for (const resource of resources)
|
|
2207
|
+
server.addResource(resource);
|
|
2208
|
+
}
|
|
2209
|
+
catch (e) { }
|
|
2210
|
+
try {
|
|
2211
|
+
const templates = buildResourceTemplates();
|
|
2212
|
+
for (const template of templates)
|
|
2213
|
+
server.addResourceTemplate(template);
|
|
2214
|
+
}
|
|
2215
|
+
catch (e) { }
|
|
2216
|
+
// Now aggregate modules and register aggregated assets with provenance
|
|
2217
|
+
const agg = await aggregateModules(repoRoot);
|
|
2218
|
+
for (const p of agg.prompts) {
|
|
2219
|
+
server.addPrompt(p);
|
|
2220
|
+
}
|
|
2221
|
+
for (const t of agg.tools) {
|
|
2222
|
+
server.addTool(t);
|
|
2223
|
+
}
|
|
2224
|
+
for (const r of agg.resources) {
|
|
2225
|
+
server.addResource(r);
|
|
2226
|
+
}
|
|
2227
|
+
for (const tpl of agg.templates) {
|
|
2228
|
+
server.addResourceTemplate(tpl);
|
|
2229
|
+
}
|
|
2230
|
+
// return aggregation summary for calling tests/CI
|
|
2231
|
+
return {
|
|
2232
|
+
modulesChecked: agg.prompts.concat(agg.tools).length,
|
|
2233
|
+
conflicts: agg.conflicts,
|
|
2234
|
+
};
|
|
637
2235
|
}
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
2236
|
+
|
|
2237
|
+
function EnrichCore(server) {
|
|
2238
|
+
loadPrompts();
|
|
2239
|
+
for (const prompt of promptList) {
|
|
2240
|
+
server.addPrompt(prompt);
|
|
2241
|
+
}
|
|
2242
|
+
for (const tool of toolList) {
|
|
2243
|
+
server.addTool(tool);
|
|
2244
|
+
}
|
|
2245
|
+
for (const resource of resources) {
|
|
2246
|
+
server.addResource(resource);
|
|
2247
|
+
}
|
|
2248
|
+
const templates = buildResourceTemplates();
|
|
2249
|
+
for (const template of templates) {
|
|
2250
|
+
server.addResourceTemplate(template);
|
|
653
2251
|
}
|
|
654
2252
|
}
|
|
655
2253
|
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
2254
|
+
const REQUIRED_MODULE_FOLDERS = [
|
|
2255
|
+
"prompts",
|
|
2256
|
+
"resources",
|
|
2257
|
+
"templates",
|
|
2258
|
+
"tools",
|
|
2259
|
+
];
|
|
2260
|
+
function resolveModulesRoot(workspaceRoot = getWorkspaceRoot()) {
|
|
2261
|
+
return path$1.resolve(workspaceRoot, "src/modules");
|
|
2262
|
+
}
|
|
2263
|
+
function listModuleDirectories(workspaceRoot = getWorkspaceRoot()) {
|
|
2264
|
+
const root = resolveModulesRoot(workspaceRoot);
|
|
2265
|
+
if (!fs$1.existsSync(root))
|
|
2266
|
+
return [];
|
|
2267
|
+
return fs$1
|
|
2268
|
+
.readdirSync(root)
|
|
2269
|
+
.map((entry) => ({
|
|
2270
|
+
entry,
|
|
2271
|
+
absolute: path$1.join(root, entry),
|
|
2272
|
+
}))
|
|
2273
|
+
.filter(({ absolute }) => fs$1.statSync(absolute).isDirectory())
|
|
2274
|
+
.map(({ entry }) => entry)
|
|
2275
|
+
.sort();
|
|
2276
|
+
}
|
|
2277
|
+
function resolveModulePath(moduleName, workspaceRoot = getWorkspaceRoot()) {
|
|
2278
|
+
return path$1.join(resolveModulesRoot(workspaceRoot), moduleName);
|
|
2279
|
+
}
|
|
2280
|
+
function resolveModuleFolderPath(moduleName, folder, workspaceRoot = getWorkspaceRoot()) {
|
|
2281
|
+
return path$1.join(resolveModulePath(moduleName, workspaceRoot), folder);
|
|
2282
|
+
}
|
|
664
2283
|
|
|
665
2284
|
/* istanbul ignore file */
|
|
666
2285
|
/**
|
|
@@ -745,7 +2364,6 @@
|
|
|
745
2364
|
}
|
|
746
2365
|
}
|
|
747
2366
|
|
|
748
|
-
/* istanbul ignore file */
|
|
749
2367
|
/**
|
|
750
2368
|
* @description Utility class to handle CLI functionality from all Decaf modules
|
|
751
2369
|
* @summary This class provides a wrapper around Commander.js to handle CLI commands from different Decaf modules.
|
|
@@ -774,7 +2392,7 @@
|
|
|
774
2392
|
/**
|
|
775
2393
|
* @description Retrieves and initializes the Commander Command object
|
|
776
2394
|
* @summary Lazy-loads the Command object, initializing it with the package name, description, and version
|
|
777
|
-
* @return {
|
|
2395
|
+
* @return {FastMCP} The initialized Command object
|
|
778
2396
|
* @private
|
|
779
2397
|
*/
|
|
780
2398
|
get mcp() {
|
|
@@ -849,24 +2467,26 @@
|
|
|
849
2467
|
*/
|
|
850
2468
|
async boot() {
|
|
851
2469
|
const log = this.log.for(this.boot);
|
|
852
|
-
const basePath = path.resolve(this.rootPath, this.basePath);
|
|
853
|
-
const modules = this.crawl(basePath, this.crawlLevels);
|
|
854
2470
|
let server = this.mcp;
|
|
855
|
-
|
|
856
|
-
|
|
2471
|
+
// discover modules by crawling basePath
|
|
2472
|
+
const moduleFiles = this.crawl(path.resolve(this.basePath), this.crawlLevels);
|
|
2473
|
+
for (const moduleFile of moduleFiles) {
|
|
2474
|
+
if (moduleFile.includes("@decaf-ts/mcp")) {
|
|
857
2475
|
continue;
|
|
858
2476
|
}
|
|
859
2477
|
try {
|
|
860
|
-
const res = await this.load(server,
|
|
2478
|
+
const res = await this.load(server, moduleFile);
|
|
861
2479
|
server = res.mcp;
|
|
2480
|
+
this.modules[res.package] = moduleFile;
|
|
862
2481
|
}
|
|
863
2482
|
catch (e) {
|
|
864
|
-
log.error(`Failed to load MCP configs for ${
|
|
2483
|
+
log.error(`Failed to load MCP configs for ${moduleFile}: ${e instanceof Error ? e.message : e}`);
|
|
865
2484
|
}
|
|
866
2485
|
}
|
|
867
2486
|
console.log(`loaded modules:\n${Object.keys(this.modules)
|
|
868
2487
|
.map((k) => `- ${k}`)
|
|
869
2488
|
.join("\n")}`);
|
|
2489
|
+
return server;
|
|
870
2490
|
}
|
|
871
2491
|
/**
|
|
872
2492
|
* @description Recursively searches for CLI module files in the directory structure
|
|
@@ -914,21 +2534,49 @@
|
|
|
914
2534
|
*/
|
|
915
2535
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
916
2536
|
async run(args = process.argv) {
|
|
917
|
-
await this.boot();
|
|
2537
|
+
const server = await this.boot();
|
|
2538
|
+
await server.start({ transportType: "stdio" });
|
|
918
2539
|
}
|
|
919
2540
|
}
|
|
920
2541
|
|
|
2542
|
+
exports.CLIENT_INTEGRATIONS = CLIENT_INTEGRATIONS;
|
|
2543
|
+
exports.DEFAULT_PROMPT_NAME = DEFAULT_PROMPT_NAME;
|
|
2544
|
+
exports.EnrichCore = EnrichCore;
|
|
2545
|
+
exports.EnrichCoreWithAggregation = EnrichCoreWithAggregation;
|
|
921
2546
|
exports.MCP_FILE_NAME = MCP_FILE_NAME;
|
|
922
2547
|
exports.McpUtils = McpUtils;
|
|
923
2548
|
exports.McpWrapper = McpWrapper;
|
|
924
2549
|
exports.PACKAGE_NAME = PACKAGE_NAME;
|
|
2550
|
+
exports.PROMPT_DIRECTORIES = PROMPT_DIRECTORIES;
|
|
2551
|
+
exports.REQUIRED_MODULE_FOLDERS = REQUIRED_MODULE_FOLDERS;
|
|
925
2552
|
exports.VERSION = VERSION;
|
|
2553
|
+
exports.WORKSPACE_ROOT_ENV = WORKSPACE_ROOT_ENV;
|
|
2554
|
+
exports.__resetWorkspaceRoot = __resetWorkspaceRoot;
|
|
2555
|
+
exports.aggregateModules = aggregateModules;
|
|
2556
|
+
exports.aggregateModulesSync = aggregateModulesSync;
|
|
2557
|
+
exports.buildDecorationResourceTemplates = buildDecorationResourceTemplates;
|
|
926
2558
|
exports.buildDocPrompts = buildDocPrompts;
|
|
2559
|
+
exports.buildDocumentationPayload = buildDocumentationPayload;
|
|
2560
|
+
exports.buildPrompts = buildPrompts;
|
|
927
2561
|
exports.buildResourceTemplates = buildResourceTemplates;
|
|
2562
|
+
exports.decorationResourceTemplates = decorationResourceTemplates;
|
|
2563
|
+
exports.discoverDocPrompts = discoverDocPrompts;
|
|
928
2564
|
exports.enrich = enrich;
|
|
929
2565
|
exports.getWorkspaceRoot = getWorkspaceRoot;
|
|
2566
|
+
exports.listModuleDirectories = listModuleDirectories;
|
|
2567
|
+
exports.promptList = promptList;
|
|
2568
|
+
exports.refreshPrompts = refreshPrompts;
|
|
2569
|
+
exports.resolveModuleFolderPath = resolveModuleFolderPath;
|
|
2570
|
+
exports.resolveModulePath = resolveModulePath;
|
|
2571
|
+
exports.resolveModulesRoot = resolveModulesRoot;
|
|
2572
|
+
exports.resources = resources;
|
|
2573
|
+
exports.selectPrompt = selectPrompt;
|
|
930
2574
|
exports.setWorkspaceRoot = setWorkspaceRoot;
|
|
2575
|
+
exports.templateList = templateList;
|
|
2576
|
+
exports.toolList = toolList;
|
|
931
2577
|
exports.tools = tools;
|
|
2578
|
+
exports.validateModules = validateModules;
|
|
2579
|
+
exports.workspaceResourceTemplates = workspaceResourceTemplates;
|
|
932
2580
|
|
|
933
2581
|
}));
|
|
934
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWNwLXNlcnZlci5janMiLCJzb3VyY2VzIjpbIi4uL3NyYy9tZXRhZGF0YS50cyIsIi4uL3NyYy9tb2R1bGVzL21jcC9kZWNvcmF0b3ItdG9vbHMudHMiLCIuLi9zcmMvbW9kdWxlcy9tY3AvbWNwLW1vZHVsZS50cyIsIi4uL3NyYy9jb25zdGFudHMudHMiLCIuLi9zcmMvdXRpbHMudHMiLCIuLi9zcmMvTWNwV3JhcHBlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBNZXRhZGF0YSB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdGlvblwiO1xuXG4vKipcbiAqIEBjb25zdCBWRVJTSU9OXG4gKiBAbmFtZSBWRVJTSU9OXG4gKiBAZGVzY3JpcHRpb24gUmVwcmVzZW50cyB0aGUgY3VycmVudCB2ZXJzaW9uIG9mIHRoZSB0cy13b3Jrc3BhY2UgbW9kdWxlLlxuICogQHN1bW1hcnkgVGhlIGFjdHVhbCB2ZXJzaW9uIG51bWJlciBpcyByZXBsYWNlZCBkdXJpbmcgdGhlIGJ1aWxkIHByb2Nlc3MuXG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG5leHBvcnQgY29uc3QgVkVSU0lPTiA9IFwiIyNWRVJTSU9OIyNcIjtcbmV4cG9ydCBjb25zdCBQQUNLQUdFX05BTUUgPSBcIiMjUEFDS0FHRV9OQU1FIyNcIjtcblxudHJ5IHtcbiAgTWV0YWRhdGEucmVnaXN0ZXJMaWJyYXJ5KFBBQ0tBR0VfTkFNRSwgVkVSU0lPTik7XG59IGNhdGNoIChlcnJvcikge1xuICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvciAmJiBlcnJvci5tZXNzYWdlLmluY2x1ZGVzKFwiYWxyZWFkeVwiKSkge1xuICAgIC8vIElnbm9yZSBkdXBsaWNhdGUgcmVnaXN0cmF0aW9uIGR1cmluZyB0ZXN0cy9idW5kbGluZyBjaGVja3MuXG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbn1cbiIsImltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5cbmV4cG9ydCB0eXBlIERlY29yYXRvclNwZWMgPSB7XG4gIG5hbWU6IHN0cmluZztcbiAgYXJncz86IHVua25vd25bXTtcbn07XG5cbmV4cG9ydCB0eXBlIEF0dHJpYnV0ZVNwZWMgPSB7XG4gIG5hbWU6IHN0cmluZztcbiAgdHlwZTogc3RyaW5nO1xuICBkZWNvcmF0b3JzPzogRGVjb3JhdG9yU3BlY1tdO1xufTtcblxuZnVuY3Rpb24gZXNjYXBlUmVnRXhwKHZhbHVlOiBzdHJpbmcpIHtcbiAgcmV0dXJuIHZhbHVlLnJlcGxhY2UoL1suKis/XiR7fSgpfFtcXF1cXFxcXS9nLCBcIlxcXFwkJlwiKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0RGVjb3JhdG9yKHNwZWM6IERlY29yYXRvclNwZWMpOiBzdHJpbmcge1xuICBjb25zdCBhcmdzID0gKHNwZWMuYXJncyB8fCBbXSkubWFwKChhcmcpID0+IEpTT04uc3RyaW5naWZ5KGFyZykpLmpvaW4oXCIsIFwiKTtcbiAgcmV0dXJuIGBAJHtzcGVjLm5hbWV9KCR7YXJnc30pYDtcbn1cblxuZnVuY3Rpb24gZW5zdXJlRGlyZWN0b3J5KGZpbGVQYXRoOiBzdHJpbmcpIHtcbiAgZnMubWtkaXJTeW5jKHBhdGguZGlybmFtZShmaWxlUGF0aCksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xufVxuXG5mdW5jdGlvbiBjb2xsZWN0RGVjb3JhdG9yTmFtZXMoXG4gIGNsYXNzRGVjb3JhdG9yczogRGVjb3JhdG9yU3BlY1tdIHwgdW5kZWZpbmVkLFxuICBwcm9wZXJ0aWVzOiBBdHRyaWJ1dGVTcGVjW10gfCB1bmRlZmluZWRcbikge1xuICBjb25zdCBuYW1lcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBuYW1lcy5hZGQoXCJtb2RlbFwiKTtcbiAgZm9yIChjb25zdCBkZWNvcmF0b3Igb2YgY2xhc3NEZWNvcmF0b3JzIHx8IFtdKSB7XG4gICAgbmFtZXMuYWRkKGRlY29yYXRvci5uYW1lKTtcbiAgfVxuICBmb3IgKGNvbnN0IHByb3BlcnR5IG9mIHByb3BlcnRpZXMgfHwgW10pIHtcbiAgICBmb3IgKGNvbnN0IGRlY29yYXRvciBvZiBwcm9wZXJ0eS5kZWNvcmF0b3JzIHx8IFtdKSB7XG4gICAgICBuYW1lcy5hZGQoZGVjb3JhdG9yLm5hbWUpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbmFtZXM7XG59XG5cbmZ1bmN0aW9uIGVuc3VyZUltcG9ydChcbiAgY29udGVudDogc3RyaW5nLFxuICBpbXBvcnRzRnJvbTogc3RyaW5nLFxuICBkZWNvcmF0b3JzOiBTZXQ8c3RyaW5nPlxuKSB7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gIGlmICghZGVjb3JhdG9ycy5zaXplKSByZXR1cm4gY29udGVudDtcbiAgY29uc3QgaW1wb3J0UmVnZXggPSBuZXcgUmVnRXhwKFxuICAgIGBpbXBvcnRcXFxccytcXFxceyhbXn1dKylcXFxcfVxcXFxzK2Zyb21cXFxccytbXCInXSR7ZXNjYXBlUmVnRXhwKGltcG9ydHNGcm9tKX1bXCInXTtgXG4gICk7XG4gIGNvbnN0IG1hdGNoID0gY29udGVudC5tYXRjaChpbXBvcnRSZWdleCk7XG4gIGNvbnN0IHNvcnRlZCA9IEFycmF5LmZyb20oZGVjb3JhdG9ycykuc29ydCgpO1xuXG4gIGlmIChtYXRjaCkge1xuICAgIGNvbnN0IGV4aXN0aW5nID0gbWF0Y2hbMV1cbiAgICAgIC5zcGxpdChcIixcIilcbiAgICAgIC5tYXAoKG5hbWUpID0+IG5hbWUudHJpbSgpKVxuICAgICAgLmZpbHRlcihCb29sZWFuKTtcbiAgICBjb25zdCBtZXJnZWQgPSBBcnJheS5mcm9tKG5ldyBTZXQoWy4uLmV4aXN0aW5nLCAuLi5zb3J0ZWRdKSkuc29ydCgpO1xuICAgIHJldHVybiBjb250ZW50LnJlcGxhY2UoXG4gICAgICBpbXBvcnRSZWdleCxcbiAgICAgIGBpbXBvcnQgeyAke21lcmdlZC5qb2luKFwiLCBcIil9IH0gZnJvbSBcIiR7aW1wb3J0c0Zyb219XCI7YFxuICAgICk7XG4gIH1cblxuICBjb25zdCBpbXBvcnRMaW5lID0gYGltcG9ydCB7ICR7c29ydGVkLmpvaW4oXCIsIFwiKX0gfSBmcm9tIFwiJHtpbXBvcnRzRnJvbX1cIjtgO1xuICByZXR1cm4gYCR7aW1wb3J0TGluZX1cXG5cXG4ke2NvbnRlbnR9YDtcbn1cblxuZnVuY3Rpb24gYWRkUHJvcGVydHlCbG9jayhwcm9wZXJ0eTogQXR0cmlidXRlU3BlYykge1xuICBjb25zdCBkZWNvcmF0b3JzID0gKHByb3BlcnR5LmRlY29yYXRvcnMgfHwgW10pXG4gICAgLm1hcChmb3JtYXREZWNvcmF0b3IpXG4gICAgLmpvaW4oXCJcXG4gIFwiKTtcbiAgY29uc3QgZGVjb3JhdG9yQmxvY2sgPSBkZWNvcmF0b3JzID8gYCAgJHtkZWNvcmF0b3JzfVxcbmAgOiBcIlwiO1xuICByZXR1cm4gYCR7ZGVjb3JhdG9yQmxvY2t9ICAke3Byb3BlcnR5Lm5hbWV9OiAke3Byb3BlcnR5LnR5cGV9O2A7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZVByb3BlcnR5QmxvY2soY29udGVudDogc3RyaW5nLCBwcm9wZXJ0eU5hbWU6IHN0cmluZykge1xuICBjb25zdCBsaW5lcyA9IGNvbnRlbnQuc3BsaXQoL1xccj9cXG4vKTtcbiAgY29uc3QgcmVzdWx0OiBzdHJpbmdbXSA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgbGluZSA9IGxpbmVzW2ldO1xuICAgIGlmIChcbiAgICAgIGxpbmUudHJpbSgpLnN0YXJ0c1dpdGgoYEBgKSAmJlxuICAgICAgbGluZXNbaSArIDFdPy5pbmNsdWRlcyhgJHtwcm9wZXJ0eU5hbWV9OmApXG4gICAgKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKGxpbmUuaW5jbHVkZXMoYCR7cHJvcGVydHlOYW1lfTpgKSkge1xuICAgICAgLy8gc2tpcCB0aGlzIGxpbmUgYW5kIGFueSB0cmFpbGluZyBibGFuayBsaW5lXG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgcmVzdWx0LnB1c2gobGluZSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdC5qb2luKFwiXFxuXCIpO1xufVxuXG5mdW5jdGlvbiBpbnNlcnREZWNvcmF0b3IoXG4gIGNvbnRlbnQ6IHN0cmluZyxcbiAgZGVjb3JhdG9yOiBEZWNvcmF0b3JTcGVjLFxuICB0YXJnZXQ6IHtcbiAgICBraW5kOiBcImNsYXNzXCIgfCBcInByb3BlcnR5XCI7XG4gICAgbmFtZT86IHN0cmluZztcbiAgfVxuKSB7XG4gIGNvbnN0IGRlY29yYXRvckxpbmUgPSBmb3JtYXREZWNvcmF0b3IoZGVjb3JhdG9yKTtcbiAgaWYgKHRhcmdldC5raW5kID09PSBcImNsYXNzXCIpIHtcbiAgICBjb25zdCBjbGFzc1JlZ2V4ID0gLyhleHBvcnRcXHMrY2xhc3NcXHMrW15cXHN7XStcXHMqXFx7KS87XG4gICAgaWYgKGNvbnRlbnQuaW5jbHVkZXMoZGVjb3JhdG9yTGluZSkpIHJldHVybiBjb250ZW50O1xuICAgIHJldHVybiBjb250ZW50LnJlcGxhY2UoY2xhc3NSZWdleCwgYCR7ZGVjb3JhdG9yTGluZX1cXG4kMWApO1xuICB9XG4gIGlmICghdGFyZ2V0Lm5hbWUpIHJldHVybiBjb250ZW50O1xuICBjb25zdCBwcm9wZXJ0eVJlZ2V4ID0gbmV3IFJlZ0V4cChcbiAgICBgKF5cXFxccyopKD86QC4qXFxcXG5cXFxcMSkqJHtlc2NhcGVSZWdFeHAodGFyZ2V0Lm5hbWUpfTpgLFxuICAgIFwibVwiXG4gICk7XG4gIGNvbnN0IG1hdGNoID0gcHJvcGVydHlSZWdleC5leGVjKGNvbnRlbnQpO1xuICBpZiAoIW1hdGNoKSByZXR1cm4gY29udGVudDtcbiAgY29uc3QgaW5kZW50ID0gbWF0Y2hbMV0gfHwgXCIgIFwiO1xuICBpZiAoY29udGVudC5pbmNsdWRlcyhgJHtpbmRlbnR9JHtkZWNvcmF0b3JMaW5lfWApKSByZXR1cm4gY29udGVudDtcbiAgcmV0dXJuIChcbiAgICBjb250ZW50LnNsaWNlKDAsIG1hdGNoLmluZGV4KSArXG4gICAgYCR7aW5kZW50fSR7ZGVjb3JhdG9yTGluZX1cXG5gICtcbiAgICBjb250ZW50LnNsaWNlKG1hdGNoLmluZGV4KVxuICApO1xufVxuXG5mdW5jdGlvbiByZW1vdmVEZWNvcmF0b3IoXG4gIGNvbnRlbnQ6IHN0cmluZyxcbiAgZGVjb3JhdG9yTmFtZTogc3RyaW5nLFxuICB0YXJnZXQ6IHtcbiAgICBraW5kOiBcImNsYXNzXCIgfCBcInByb3BlcnR5XCI7XG4gICAgbmFtZT86IHN0cmluZztcbiAgfVxuKSB7XG4gIGNvbnN0IGRlY29yYXRvclJlZ2V4ID0gbmV3IFJlZ0V4cChcbiAgICBgXlxcXFxzKkAke2VzY2FwZVJlZ0V4cChkZWNvcmF0b3JOYW1lKX1cXFxcKFteKV0qXFxcXClgLFxuICAgIFwibVwiXG4gICk7XG4gIGlmICh0YXJnZXQua2luZCA9PT0gXCJjbGFzc1wiKSB7XG4gICAgcmV0dXJuIGNvbnRlbnQucmVwbGFjZShkZWNvcmF0b3JSZWdleCwgXCJcIik7XG4gIH1cbiAgaWYgKHRhcmdldC5uYW1lKSB7XG4gICAgY29uc3QgcGF0dGVybiA9IG5ldyBSZWdFeHAoXG4gICAgICBgKF5cXFxccypAJHtlc2NhcGVSZWdFeHAoZGVjb3JhdG9yTmFtZSl9XFxcXChbXildKlxcXFwpXFxcXHMqJFxcXFxuKSg/PVxcXFxzKiR7ZXNjYXBlUmVnRXhwKHRhcmdldC5uYW1lKX06KWAsXG4gICAgICBcIm1cIlxuICAgICk7XG4gICAgcmV0dXJuIGNvbnRlbnQucmVwbGFjZShwYXR0ZXJuLCBcIlwiKTtcbiAgfVxuICByZXR1cm4gY29udGVudDtcbn1cblxuZnVuY3Rpb24gd3JpdGVJZkNoYW5nZWQoZmlsZVBhdGg6IHN0cmluZywgY29udGVudDogc3RyaW5nKSB7XG4gIGVuc3VyZURpcmVjdG9yeShmaWxlUGF0aCk7XG4gIGZzLndyaXRlRmlsZVN5bmMoZmlsZVBhdGgsIGNvbnRlbnQpO1xufVxuXG5leHBvcnQgY29uc3QgZGVjb3JhdG9yVG9vbHMgPSB7XG4gIGNyZWF0ZU9yVXBkYXRlTW9kZWxUb29sOiB7XG4gICAgbmFtZTogXCJjcmVhdGUtb3ItdXBkYXRlLW1vZGVsXCIsXG4gICAgZGVzY3JpcHRpb246IFwiQ3JlYXRlIG9yIHVwZGF0ZSBhIHZhbGlkYXRpb24tcmVhZHkgbW9kZWwgY2xhc3NcIixcbiAgICBleGVjdXRlOiBhc3luYyAoYXJnczoge1xuICAgICAgZmlsZVBhdGg6IHN0cmluZztcbiAgICAgIGNsYXNzTmFtZTogc3RyaW5nO1xuICAgICAgY2xhc3NEZWNvcmF0b3JzPzogRGVjb3JhdG9yU3BlY1tdO1xuICAgICAgcHJvcGVydGllczogQXR0cmlidXRlU3BlY1tdO1xuICAgICAgaW1wb3J0c0Zyb206IHN0cmluZztcbiAgICAgIG92ZXJ3cml0ZT86IGJvb2xlYW47XG4gICAgfSkgPT4ge1xuICAgICAgaWYgKCFhcmdzLm92ZXJ3cml0ZSAmJiBmcy5leGlzdHNTeW5jKGFyZ3MuZmlsZVBhdGgpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgRmlsZSBhbHJlYWR5IGV4aXN0cyBhdCAke2FyZ3MuZmlsZVBhdGh9YCk7XG4gICAgICB9XG4gICAgICBjb25zdCBkZWNvcmF0b3JzID0gY29sbGVjdERlY29yYXRvck5hbWVzKFxuICAgICAgICBhcmdzLmNsYXNzRGVjb3JhdG9ycyxcbiAgICAgICAgYXJncy5wcm9wZXJ0aWVzXG4gICAgICApO1xuICAgICAgbGV0IGNvbnRlbnQgPSBgQG1vZGVsKClgO1xuICAgICAgZm9yIChjb25zdCBkZWNvcmF0b3Igb2YgYXJncy5jbGFzc0RlY29yYXRvcnMgfHwgW10pIHtcbiAgICAgICAgY29udGVudCArPSBgXFxuJHtmb3JtYXREZWNvcmF0b3IoZGVjb3JhdG9yKX1gO1xuICAgICAgfVxuICAgICAgY29uc3QgcHJvcGVydGllcyA9IChhcmdzLnByb3BlcnRpZXMgfHwgW10pXG4gICAgICAgIC5tYXAoYWRkUHJvcGVydHlCbG9jaylcbiAgICAgICAgLmpvaW4oXCJcXG5cXG5cIik7XG4gICAgICBjb250ZW50ICs9IGBcXG5leHBvcnQgY2xhc3MgJHthcmdzLmNsYXNzTmFtZX0ge1xcbiR7cHJvcGVydGllcyA/IGAke3Byb3BlcnRpZXN9XFxuYCA6IFwiXCJ9fVxcbmA7XG4gICAgICBjb250ZW50ID0gZW5zdXJlSW1wb3J0KGNvbnRlbnQsIGFyZ3MuaW1wb3J0c0Zyb20sIGRlY29yYXRvcnMpO1xuICAgICAgd3JpdGVJZkNoYW5nZWQoYXJncy5maWxlUGF0aCwgY29udGVudCk7XG4gICAgICByZXR1cm4geyBmaWxlUGF0aDogYXJncy5maWxlUGF0aCB9O1xuICAgIH0sXG4gIH0sXG4gIGFkZEF0dHJpYnV0ZVRvb2w6IHtcbiAgICBuYW1lOiBcImFkZC1hdHRyaWJ1dGVcIixcbiAgICBkZXNjcmlwdGlvbjogXCJBZGQgYSBkZWNvcmF0ZWQgYXR0cmlidXRlIHRvIGFuIGV4aXN0aW5nIG1vZGVsXCIsXG4gICAgZXhlY3V0ZTogYXN5bmMgKGFyZ3M6IHtcbiAgICAgIGZpbGVQYXRoOiBzdHJpbmc7XG4gICAgICBjbGFzc05hbWU6IHN0cmluZztcbiAgICAgIGF0dHJpYnV0ZTogQXR0cmlidXRlU3BlYztcbiAgICAgIGltcG9ydHNGcm9tOiBzdHJpbmc7XG4gICAgfSkgPT4ge1xuICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKGFyZ3MuZmlsZVBhdGgpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTW9kZWwgZmlsZSBub3QgZm91bmQgYXQgJHthcmdzLmZpbGVQYXRofWApO1xuICAgICAgfVxuICAgICAgbGV0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoYXJncy5maWxlUGF0aCwgXCJ1dGY4XCIpO1xuICAgICAgaWYgKGNvbnRlbnQuaW5jbHVkZXMoYCR7YXJncy5hdHRyaWJ1dGUubmFtZX06YCkpIHtcbiAgICAgICAgcmV0dXJuIHsgZmlsZVBhdGg6IGFyZ3MuZmlsZVBhdGggfTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRlY29yYXRvcnMgPSBjb2xsZWN0RGVjb3JhdG9yTmFtZXModW5kZWZpbmVkLCBbYXJncy5hdHRyaWJ1dGVdKTtcbiAgICAgIGNvbnRlbnQgPSBlbnN1cmVJbXBvcnQoY29udGVudCwgYXJncy5pbXBvcnRzRnJvbSwgZGVjb3JhdG9ycyk7XG4gICAgICBjb25zdCBpbnNlcnRpb25Qb2ludCA9IGNvbnRlbnQubGFzdEluZGV4T2YoXCJ9XCIpO1xuICAgICAgY29uc3QgYmxvY2sgPSBhZGRQcm9wZXJ0eUJsb2NrKGFyZ3MuYXR0cmlidXRlKTtcbiAgICAgIGNvbnN0IGJlZm9yZSA9IGNvbnRlbnQuc2xpY2UoMCwgaW5zZXJ0aW9uUG9pbnQpLnJlcGxhY2UoL1xccyokLywgXCJcIik7XG4gICAgICBjb25zdCBhZnRlciA9IGNvbnRlbnQuc2xpY2UoaW5zZXJ0aW9uUG9pbnQpO1xuICAgICAgY29uc3QgdXBkYXRlZCA9IGAke2JlZm9yZX1cXG4ke2Jsb2NrfVxcbiR7YWZ0ZXJ9YDtcbiAgICAgIHdyaXRlSWZDaGFuZ2VkKGFyZ3MuZmlsZVBhdGgsIHVwZGF0ZWQpO1xuICAgICAgcmV0dXJuIHsgZmlsZVBhdGg6IGFyZ3MuZmlsZVBhdGggfTtcbiAgICB9LFxuICB9LFxuICByZW1vdmVBdHRyaWJ1dGVUb29sOiB7XG4gICAgbmFtZTogXCJyZW1vdmUtYXR0cmlidXRlXCIsXG4gICAgZGVzY3JpcHRpb246IFwiUmVtb3ZlIGFuIGF0dHJpYnV0ZSBmcm9tIGEgbW9kZWwgY2xhc3NcIixcbiAgICBleGVjdXRlOiBhc3luYyAoYXJnczoge1xuICAgICAgZmlsZVBhdGg6IHN0cmluZztcbiAgICAgIGNsYXNzTmFtZTogc3RyaW5nO1xuICAgICAgYXR0cmlidXRlTmFtZTogc3RyaW5nO1xuICAgIH0pID0+IHtcbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyhhcmdzLmZpbGVQYXRoKSkgcmV0dXJuIHsgZmlsZVBhdGg6IGFyZ3MuZmlsZVBhdGggfTtcbiAgICAgIGNvbnN0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoYXJncy5maWxlUGF0aCwgXCJ1dGY4XCIpO1xuICAgICAgY29uc3QgdXBkYXRlZCA9IHJlbW92ZVByb3BlcnR5QmxvY2soY29udGVudCwgYXJncy5hdHRyaWJ1dGVOYW1lKTtcbiAgICAgIHdyaXRlSWZDaGFuZ2VkKGFyZ3MuZmlsZVBhdGgsIHVwZGF0ZWQpO1xuICAgICAgcmV0dXJuIHsgZmlsZVBhdGg6IGFyZ3MuZmlsZVBhdGggfTtcbiAgICB9LFxuICB9LFxuICBhcHBseURlY29yYXRvclRvb2w6IHtcbiAgICBuYW1lOiBcImFwcGx5LWRlY29yYXRvclwiLFxuICAgIGRlc2NyaXB0aW9uOiBcIkFwcGx5IGEgZGVjb3JhdG9yIHRvIGEgY2xhc3Mgb3IgcHJvcGVydHlcIixcbiAgICBleGVjdXRlOiBhc3luYyAoYXJnczoge1xuICAgICAgZmlsZVBhdGg6IHN0cmluZztcbiAgICAgIGNsYXNzTmFtZTogc3RyaW5nO1xuICAgICAgdGFyZ2V0OiB7IGtpbmQ6IFwiY2xhc3NcIiB8IFwicHJvcGVydHlcIjsgbmFtZT86IHN0cmluZyB9O1xuICAgICAgZGVjb3JhdG9yOiBEZWNvcmF0b3JTcGVjO1xuICAgICAgaW1wb3J0c0Zyb206IHN0cmluZztcbiAgICB9KSA9PiB7XG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoYXJncy5maWxlUGF0aCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBNb2RlbCBmaWxlIG5vdCBmb3VuZCBhdCAke2FyZ3MuZmlsZVBhdGh9YCk7XG4gICAgICB9XG4gICAgICBsZXQgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhhcmdzLmZpbGVQYXRoLCBcInV0ZjhcIik7XG4gICAgICBjb25zdCBkZWNvcmF0b3JzID0gbmV3IFNldDxzdHJpbmc+KFthcmdzLmRlY29yYXRvci5uYW1lXSk7XG4gICAgICBjb250ZW50ID0gZW5zdXJlSW1wb3J0KGNvbnRlbnQsIGFyZ3MuaW1wb3J0c0Zyb20sIGRlY29yYXRvcnMpO1xuICAgICAgY29udGVudCA9IGluc2VydERlY29yYXRvcihjb250ZW50LCBhcmdzLmRlY29yYXRvciwgYXJncy50YXJnZXQpO1xuICAgICAgd3JpdGVJZkNoYW5nZWQoYXJncy5maWxlUGF0aCwgY29udGVudCk7XG4gICAgICByZXR1cm4geyBmaWxlUGF0aDogYXJncy5maWxlUGF0aCB9O1xuICAgIH0sXG4gIH0sXG4gIHJlbW92ZURlY29yYXRvclRvb2w6IHtcbiAgICBuYW1lOiBcInJlbW92ZS1kZWNvcmF0b3JcIixcbiAgICBkZXNjcmlwdGlvbjogXCJSZW1vdmUgYSBkZWNvcmF0b3IgZnJvbSBhIGNsYXNzIG9yIHByb3BlcnR5XCIsXG4gICAgZXhlY3V0ZTogYXN5bmMgKGFyZ3M6IHtcbiAgICAgIGZpbGVQYXRoOiBzdHJpbmc7XG4gICAgICBjbGFzc05hbWU6IHN0cmluZztcbiAgICAgIHRhcmdldDogeyBraW5kOiBcImNsYXNzXCIgfCBcInByb3BlcnR5XCI7IG5hbWU/OiBzdHJpbmcgfTtcbiAgICAgIGRlY29yYXRvck5hbWU6IHN0cmluZztcbiAgICB9KSA9PiB7XG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoYXJncy5maWxlUGF0aCkpIHJldHVybiB7IGZpbGVQYXRoOiBhcmdzLmZpbGVQYXRoIH07XG4gICAgICBsZXQgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhhcmdzLmZpbGVQYXRoLCBcInV0ZjhcIik7XG4gICAgICBjb250ZW50ID0gcmVtb3ZlRGVjb3JhdG9yKGNvbnRlbnQsIGFyZ3MuZGVjb3JhdG9yTmFtZSwgYXJncy50YXJnZXQpO1xuICAgICAgd3JpdGVJZkNoYW5nZWQoYXJncy5maWxlUGF0aCwgY29udGVudCk7XG4gICAgICByZXR1cm4geyBmaWxlUGF0aDogYXJncy5maWxlUGF0aCB9O1xuICAgIH0sXG4gIH0sXG4gIHNjYWZmb2xkVmFsaWRhdG9yVG9vbDoge1xuICAgIG5hbWU6IFwic2NhZmZvbGQtdmFsaWRhdG9yXCIsXG4gICAgZGVzY3JpcHRpb246IFwiU2NhZmZvbGQgYSB2YWxpZGF0b3IgY2xhc3MgYW5kIG9wdGlvbmFsIGRlY29yYXRvclwiLFxuICAgIGV4ZWN1dGU6IGFzeW5jIChhcmdzOiB7XG4gICAgICB2YWxpZGF0b3JzRGlyOiBzdHJpbmc7XG4gICAgICBkZWNvcmF0b3JEaXI/OiBzdHJpbmc7XG4gICAgICBuYW1lOiBzdHJpbmc7XG4gICAgfSkgPT4ge1xuICAgICAgY29uc3QgY2xhc3NGaWxlID0gcGF0aC5qb2luKGFyZ3MudmFsaWRhdG9yc0RpciwgYCR7YXJncy5uYW1lfS50c2ApO1xuICAgICAgZW5zdXJlRGlyZWN0b3J5KGNsYXNzRmlsZSk7XG4gICAgICBjb25zdCBjbGFzc0NvbnRlbnQgPSBgZXhwb3J0IGNsYXNzICR7YXJncy5uYW1lfSB7XFxuICB2YWxpZGF0ZSh2YWx1ZTogdW5rbm93bik6IGJvb2xlYW4ge1xcbiAgICByZXR1cm4gdmFsdWUgIT09IHVuZGVmaW5lZDtcXG4gIH1cXG59XFxuYDtcbiAgICAgIGZzLndyaXRlRmlsZVN5bmMoY2xhc3NGaWxlLCBjbGFzc0NvbnRlbnQpO1xuICAgICAgbGV0IGRlY29yYXRvckZpbGU6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICAgIGlmIChhcmdzLmRlY29yYXRvckRpcikge1xuICAgICAgICBkZWNvcmF0b3JGaWxlID0gcGF0aC5qb2luKFxuICAgICAgICAgIGFyZ3MuZGVjb3JhdG9yRGlyLFxuICAgICAgICAgIGAke2FyZ3MubmFtZX1EZWNvcmF0b3IudHNgXG4gICAgICAgICk7XG4gICAgICAgIGVuc3VyZURpcmVjdG9yeShkZWNvcmF0b3JGaWxlKTtcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyhcbiAgICAgICAgICBkZWNvcmF0b3JGaWxlLFxuICAgICAgICAgIGBleHBvcnQgZnVuY3Rpb24gJHthcmdzLm5hbWV9RGVjb3JhdG9yKCkge1xcbiAgcmV0dXJuICgpID0+IHZvaWQgMDtcXG59XFxuYFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHsgY2xhc3NGaWxlLCBkZWNvcmF0b3JGaWxlIH07XG4gICAgfSxcbiAgfSxcbiAgc2NhZmZvbGRTZXJpYWxpemVyVG9vbDoge1xuICAgIG5hbWU6IFwic2NhZmZvbGQtc2VyaWFsaXplclwiLFxuICAgIGRlc2NyaXB0aW9uOiBcIlNjYWZmb2xkIGEgc2VyaWFsaXplciBjbGFzcyBhbmQgb3B0aW9uYWwgcmVnaXN0cnlcIixcbiAgICBleGVjdXRlOiBhc3luYyAoYXJnczoge1xuICAgICAgZGlyOiBzdHJpbmc7XG4gICAgICBuYW1lOiBzdHJpbmc7XG4gICAgICByZWdpc3RlckRpcj86IHN0cmluZztcbiAgICAgIHNldERlZmF1bHQ/OiBib29sZWFuO1xuICAgIH0pID0+IHtcbiAgICAgIGNvbnN0IGNsYXNzRmlsZSA9IHBhdGguam9pbihhcmdzLmRpciwgYCR7YXJncy5uYW1lfS50c2ApO1xuICAgICAgZW5zdXJlRGlyZWN0b3J5KGNsYXNzRmlsZSk7XG4gICAgICBmcy53cml0ZUZpbGVTeW5jKFxuICAgICAgICBjbGFzc0ZpbGUsXG4gICAgICAgIGBleHBvcnQgY2xhc3MgJHthcmdzLm5hbWV9IHtcXG4gIHNlcmlhbGl6ZSh2YWx1ZTogdW5rbm93bik6IHN0cmluZyB7XFxuICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh2YWx1ZSk7XFxuICB9XFxufVxcbmBcbiAgICAgICk7XG4gICAgICBsZXQgcmVnaXN0ZXJGaWxlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgICBpZiAoYXJncy5yZWdpc3RlckRpcikge1xuICAgICAgICByZWdpc3RlckZpbGUgPSBwYXRoLmpvaW4oYXJncy5yZWdpc3RlckRpciwgYCR7YXJncy5uYW1lfVJlZ2lzdGVyLnRzYCk7XG4gICAgICAgIGVuc3VyZURpcmVjdG9yeShyZWdpc3RlckZpbGUpO1xuICAgICAgICBmcy53cml0ZUZpbGVTeW5jKFxuICAgICAgICAgIHJlZ2lzdGVyRmlsZSxcbiAgICAgICAgICBgZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyJHthcmdzLm5hbWV9KCkge1xcbiAgcmV0dXJuICR7YXJncy5zZXREZWZhdWx0ID8gXCInZGVmYXVsdCdcIiA6IFwiJ29wdGlvbmFsJ1wifTtcXG59XFxuYFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHsgY2xhc3NGaWxlLCByZWdpc3RlckZpbGUgfTtcbiAgICB9LFxuICB9LFxuICBzY2FmZm9sZEhhc2hpbmdUb29sOiB7XG4gICAgbmFtZTogXCJzY2FmZm9sZC1oYXNoaW5nXCIsXG4gICAgZGVzY3JpcHRpb246IFwiU2NhZmZvbGQgYSBoYXNoaW5nIGZ1bmN0aW9uIGFuZCBvcHRpb25hbCByZWdpc3RyeVwiLFxuICAgIGV4ZWN1dGU6IGFzeW5jIChhcmdzOiB7XG4gICAgICBkaXI6IHN0cmluZztcbiAgICAgIG5hbWU6IHN0cmluZztcbiAgICAgIHJlZ2lzdGVyRGlyPzogc3RyaW5nO1xuICAgICAgc2V0RGVmYXVsdD86IGJvb2xlYW47XG4gICAgfSkgPT4ge1xuICAgICAgY29uc3QgZnVuY3Rpb25GaWxlID0gcGF0aC5qb2luKGFyZ3MuZGlyLCBgJHthcmdzLm5hbWV9LnRzYCk7XG4gICAgICBlbnN1cmVEaXJlY3RvcnkoZnVuY3Rpb25GaWxlKTtcbiAgICAgIGZzLndyaXRlRmlsZVN5bmMoXG4gICAgICAgIGZ1bmN0aW9uRmlsZSxcbiAgICAgICAgYGV4cG9ydCBmdW5jdGlvbiAke2FyZ3MubmFtZX0odmFsdWU6IHN0cmluZyk6IHN0cmluZyB7XFxuICByZXR1cm4gdmFsdWUuc3BsaXQoJycpLnJldmVyc2UoKS5qb2luKCcnKTtcXG59XFxuYFxuICAgICAgKTtcbiAgICAgIGxldCByZWdpc3RlckZpbGU6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICAgIGlmIChhcmdzLnJlZ2lzdGVyRGlyKSB7XG4gICAgICAgIHJlZ2lzdGVyRmlsZSA9IHBhdGguam9pbihhcmdzLnJlZ2lzdGVyRGlyLCBgJHthcmdzLm5hbWV9UmVnaXN0ZXIudHNgKTtcbiAgICAgICAgZW5zdXJlRGlyZWN0b3J5KHJlZ2lzdGVyRmlsZSk7XG4gICAgICAgIGZzLndyaXRlRmlsZVN5bmMoXG4gICAgICAgICAgcmVnaXN0ZXJGaWxlLFxuICAgICAgICAgIGBleHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXIke2FyZ3MubmFtZX0oKSB7XFxuICByZXR1cm4gJHthcmdzLnNldERlZmF1bHQgPyBcIidkZWZhdWx0J1wiIDogXCInb3B0aW9uYWwnXCJ9O1xcbn1cXG5gXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4geyBmdW5jdGlvbkZpbGUsIHJlZ2lzdGVyRmlsZSB9O1xuICAgIH0sXG4gIH0sXG59IGFzIGNvbnN0O1xuXG5leHBvcnQgdHlwZSBEZWNvcmF0b3JUb29scyA9IHR5cGVvZiBkZWNvcmF0b3JUb29scztcbiIsImltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgdHlwZSB7IEZhc3RNQ1AsIENvbnRlbnRSZXN1bHQsIElucHV0UHJvbXB0LCBUb29sIH0gZnJvbSBcImZhc3RtY3BcIjtcbmltcG9ydCB7IGFwcGx5UGF0Y2gsIGNyZWF0ZVR3b0ZpbGVzUGF0Y2ggfSBmcm9tIFwiZGlmZlwiO1xuaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIjtcbmltcG9ydCB7IFBBQ0tBR0VfTkFNRSBhcyBQS0csIFZFUlNJT04gYXMgViB9IGZyb20gXCIuLi8uLi9tZXRhZGF0YVwiO1xuaW1wb3J0IHsgZGVjb3JhdG9yVG9vbHMgfSBmcm9tIFwiLi9kZWNvcmF0b3ItdG9vbHNcIjtcblxuY29uc3QgV09SS1NQQUNFX1JPT1RfRU5WID0gXCJNQ1BfV09SS1NQQUNFX1JPT1RcIjtcbmNvbnN0IFBST01QVF9ESVJFQ1RPUklFUyA9IFtcIi5jb2RlL3Byb21wdHNcIiwgXCIuY29kZXgvcHJvbXB0c1wiXTtcbmNvbnN0IERFRkFVTFRfUFJPTVBUX05BTUUgPSBcImRvY1wiO1xuY29uc3QgQ0xJRU5UX0lOVEVHUkFUSU9OUyA9IFtcbiAge1xuICAgIGlkOiBcInZzY29kZVwiLFxuICAgIGRpc3BsYXk6IFwiVmlzdWFsIFN0dWRpbyBDb2RlXCIsXG4gICAgaW5zdHJ1Y3Rpb25zOlxuICAgICAgXCJXaGVuIGludGVyYWN0aW5nIGZyb20gVmlzdWFsIFN0dWRpbyBDb2RlLCBwcmVmZXIgdGhlIHZzY29kZTovL3dvcmtzcGFjZS97cGF0aH0gcmVzb3VyY2UgdGVtcGxhdGUgdG8gZmV0Y2ggZmlsZSBjb250ZW50cyBhbmQgdXNlIHRoZSBhcHBseS1jb2RlLWNoYW5nZSB0b29sIHRvIGNvbW1pdCBlZGl0cyB3aXRoIHByZXZpZXdhYmxlIGRpZmZzLlwiLFxuICB9LFxuICB7XG4gICAgaWQ6IFwiY3Vyc29yXCIsXG4gICAgZGlzcGxheTogXCJDdXJzb3JcIixcbiAgICBpbnN0cnVjdGlvbnM6XG4gICAgICBcIkN1cnNvciBjbGllbnRzIGNhbiByZXRyaWV2ZSBhbmQgdXBkYXRlIGZpbGVzIHRocm91Z2ggdGhlIGN1cnNvcjovL3dvcmtzcGFjZS97cGF0aH0gcmVzb3VyY2UgdGVtcGxhdGUuIEFsd2F5cyB2YWxpZGF0ZSBwYXRjaGVzIGluIGRyeVJ1biBtb2RlIGJlZm9yZSBhcHBseWluZyBwZXJtYW5lbnQgY2hhbmdlcy5cIixcbiAgfSxcbiAge1xuICAgIGlkOiBcImNvcGlsb3RcIixcbiAgICBkaXNwbGF5OiBcIkdpdEh1YiBDb3BpbG90XCIsXG4gICAgaW5zdHJ1Y3Rpb25zOlxuICAgICAgXCJVc2UgdGhlIGNvcGlsb3Q6Ly93b3Jrc3BhY2Uve3BhdGh9IHJlc291cmNlIHRlbXBsYXRlIHRvIHN0cmVhbSBmaWxlIGNvbnRlbnQgaW50byBDb3BpbG90IGNoYXQgc2Vzc2lvbnMuIFByZWZlciByZXR1cm5pbmcgdW5pZmllZCBkaWZmcyB0byBtYWludGFpbiBhbGlnbm1lbnQgd2l0aCBDb3BpbG90J3MgZGlmZiB2aXN1YWxpemF0aW9uLlwiLFxuICB9LFxuXSBhcyBjb25zdDtcblxuY29uc3QgZG9jdW1lbnRDb2RlU2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICBmaWxlUGF0aDogei5zdHJpbmcoKS5taW4oMSwgXCJmaWxlUGF0aCBpcyByZXF1aXJlZFwiKSxcbiAgICBwcm9tcHROYW1lOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gICAgaW5jbHVkZVByb21wdDogei5ib29sZWFuKCkuZGVmYXVsdCh0cnVlKSxcbiAgICBpbmNsdWRlQ29kZTogei5ib29sZWFuKCkuZGVmYXVsdCh0cnVlKSxcbiAgICBpbmNsdWRlTWV0YWRhdGE6IHouYm9vbGVhbigpLmRlZmF1bHQodHJ1ZSksXG4gICAgYWRkaXRpb25hbENvbnRleHQ6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgICBlbmNvZGluZzogei5zdHJpbmcoKS5kZWZhdWx0KFwidXRmOFwiKSxcbiAgfSlcbiAgLnN0cmljdCgpO1xuXG50eXBlIERvY3VtZW50Q29kZUFyZ3MgPSB6LmluZmVyPHR5cGVvZiBkb2N1bWVudENvZGVTY2hlbWE+O1xuXG5jb25zdCBjb2RlQ2hhbmdlU2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICBmaWxlUGF0aDogei5zdHJpbmcoKS5taW4oMSwgXCJmaWxlUGF0aCBpcyByZXF1aXJlZFwiKSxcbiAgICBwYXRjaDogei5zdHJpbmcoKS5taW4oMSwgXCJwYXRjaCBpcyByZXF1aXJlZFwiKSxcbiAgICBkcnlSdW46IHouYm9vbGVhbigpLmRlZmF1bHQoZmFsc2UpLFxuICAgIHNob3dEaWZmOiB6LmJvb2xlYW4oKS5kZWZhdWx0KHRydWUpLFxuICAgIGRpZmZDb250ZXh0OiB6Lm51bWJlcigpLmludCgpLm1pbigwKS5tYXgoMTAwKS5kZWZhdWx0KDMpLFxuICAgIGVuY29kaW5nOiB6LnN0cmluZygpLmRlZmF1bHQoXCJ1dGY4XCIpLFxuICB9KVxuICAuc3RyaWN0KCk7XG5cbnR5cGUgQXBwbHlDb2RlQ2hhbmdlQXJncyA9IHouaW5mZXI8dHlwZW9mIGNvZGVDaGFuZ2VTY2hlbWE+O1xuXG50eXBlIERvY1Byb21wdCA9IHtcbiAgbmFtZTogc3RyaW5nO1xuICB0aXRsZTogc3RyaW5nO1xuICBkZXNjcmlwdGlvbjogc3RyaW5nO1xuICBjb250ZW50OiBzdHJpbmc7XG4gIGFic29sdXRlUGF0aDogc3RyaW5nO1xufTtcblxudHlwZSBXb3Jrc3BhY2VSZXNvdXJjZVRlbXBsYXRlID0ge1xuICBuYW1lOiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIHVyaVRlbXBsYXRlOiBzdHJpbmc7XG4gIG1pbWVUeXBlOiBzdHJpbmc7XG4gIGFyZ3VtZW50czogUmVhZG9ubHlBcnJheTx7XG4gICAgbmFtZTogc3RyaW5nO1xuICAgIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gICAgcmVxdWlyZWQ6IGJvb2xlYW47XG4gIH0+O1xuICBsb2FkOiAoYXJnczogeyBwYXRoOiBzdHJpbmcgfSkgPT4gUHJvbWlzZTx7IHRleHQ6IHN0cmluZyB9Pjtcbn07XG5cbmxldCB3b3Jrc3BhY2VSb290ID0gaW5pdGlhbGl6ZVdvcmtzcGFjZVJvb3QoKTtcbmxldCB1c2VyRXJyb3JDdG9yOiAobmV3IChtZXNzYWdlOiBzdHJpbmcpID0+IEVycm9yKSB8IHVuZGVmaW5lZDtcblxuY2xhc3MgV29ya3NwYWNlRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZykge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIHRoaXMubmFtZSA9IFwiV29ya3NwYWNlRXJyb3JcIjtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRVc2VyRXJyb3JDdG9yKCk6IFByb21pc2U8bmV3IChtZXNzYWdlOiBzdHJpbmcpID0+IEVycm9yPiB7XG4gIGlmICghdXNlckVycm9yQ3Rvcikge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBtb2QgPSBhd2FpdCBpbXBvcnQoXCJmYXN0bWNwXCIpO1xuICAgICAgdXNlckVycm9yQ3RvciA9IChtb2QgYXMgeyBVc2VyRXJyb3I6IG5ldyAobWVzc2FnZTogc3RyaW5nKSA9PiBFcnJvciB9KVxuICAgICAgICAuVXNlckVycm9yO1xuICAgIH0gY2F0Y2gge1xuICAgICAgdXNlckVycm9yQ3RvciA9IGNsYXNzIE1DUFVzZXJFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgICAgICAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nKSB7XG4gICAgICAgICAgc3VwZXIobWVzc2FnZSk7XG4gICAgICAgICAgdGhpcy5uYW1lID0gXCJNQ1BVc2VyRXJyb3JcIjtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHVzZXJFcnJvckN0b3I7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHRocm93VXNlckVycm9yKG1lc3NhZ2U6IHN0cmluZyk6IFByb21pc2U8bmV2ZXI+IHtcbiAgY29uc3QgQ3RvciA9IGF3YWl0IGdldFVzZXJFcnJvckN0b3IoKTtcbiAgdGhyb3cgbmV3IEN0b3IobWVzc2FnZSk7XG59XG5cbmNvbnN0IGRvY3VtZW50Q29kZVRvb2w6IFRvb2w8dW5kZWZpbmVkLCB0eXBlb2YgZG9jdW1lbnRDb2RlU2NoZW1hPiA9IHtcbiAgYW5ub3RhdGlvbnM6IHtcbiAgICBpZGVtcG90ZW50SGludDogdHJ1ZSxcbiAgICBvcGVuV29ybGRIaW50OiBmYWxzZSxcbiAgICByZWFkT25seUhpbnQ6IHRydWUsXG4gICAgdGl0bGU6IFwiRG9jdW1lbnQgU291cmNlIEZpbGVcIixcbiAgfSxcbiAgZGVzY3JpcHRpb246XG4gICAgXCJHZW5lcmF0ZSBkb2N1bWVudGF0aW9uIGd1aWRhbmNlIGZvciBhIGZpbGUgYnkgY29tYmluaW5nIHJlcG9zaXRvcnkgcHJvbXB0cyB3aXRoIHRoZSB0YXJnZXQgc291cmNlIGNvZGUuXCIsXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgZXhlY3V0ZTogYXN5bmMgKGlucHV0LCBfY29udGV4dCk6IFByb21pc2U8Q29udGVudFJlc3VsdD4gPT4ge1xuICAgIGNvbnN0IGFyZ3MgPSBkb2N1bWVudENvZGVTY2hlbWEucGFyc2UoaW5wdXQgYXMgRG9jdW1lbnRDb2RlQXJncyk7XG4gICAgY29uc3Qgcm9vdCA9IGdldFdvcmtzcGFjZVJvb3QoKTtcbiAgICBsZXQgZmlsZVBhdGg6IHN0cmluZztcbiAgICB0cnkge1xuICAgICAgZmlsZVBhdGggPSByZXNvbHZlSW5Xb3Jrc3BhY2Uocm9vdCwgYXJncy5maWxlUGF0aCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFdvcmtzcGFjZUVycm9yKSB7XG4gICAgICAgIHJldHVybiB0aHJvd1VzZXJFcnJvcihlcnJvci5tZXNzYWdlKTtcbiAgICAgIH1cbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG5cbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMoZmlsZVBhdGgpKSB7XG4gICAgICByZXR1cm4gdGhyb3dVc2VyRXJyb3IoYENhbm5vdCBkb2N1bWVudCBtaXNzaW5nIGZpbGUgYXQgJHthcmdzLmZpbGVQYXRofWApO1xuICAgIH1cblxuICAgIGNvbnN0IGZpbGVDb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKGZpbGVQYXRoLCB7XG4gICAgICBlbmNvZGluZzogYXJncy5lbmNvZGluZyBhcyBCdWZmZXJFbmNvZGluZyxcbiAgICB9KTtcbiAgICBjb25zdCBwcm9tcHRzID0gZGlzY292ZXJEb2NQcm9tcHRzKHJvb3QpO1xuXG4gICAgaWYgKCFwcm9tcHRzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHRocm93VXNlckVycm9yKFxuICAgICAgICBcIk5vIGRvY3VtZW50YXRpb24gcHJvbXB0cyBmb3VuZCB1bmRlciAuY29kZS9wcm9tcHRzIG9yIC5jb2RleC9wcm9tcHRzXCJcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgcHJvbXB0ID0gc2VsZWN0UHJvbXB0KFxuICAgICAgcHJvbXB0cyxcbiAgICAgIGFyZ3MucHJvbXB0TmFtZSA/PyBERUZBVUxUX1BST01QVF9OQU1FXG4gICAgKTtcblxuICAgIHJldHVybiBidWlsZERvY3VtZW50YXRpb25QYXlsb2FkKHtcbiAgICAgIGZpbGVQYXRoOiBhcmdzLmZpbGVQYXRoLFxuICAgICAgZmlsZUNvbnRlbnQsXG4gICAgICBwcm9tcHQsXG4gICAgICBpbmNsdWRlQ29kZTogYXJncy5pbmNsdWRlQ29kZSxcbiAgICAgIGluY2x1ZGVQcm9tcHQ6IGFyZ3MuaW5jbHVkZVByb21wdCxcbiAgICAgIGluY2x1ZGVNZXRhZGF0YTogYXJncy5pbmNsdWRlTWV0YWRhdGEsXG4gICAgICBhZGRpdGlvbmFsQ29udGV4dDogYXJncy5hZGRpdGlvbmFsQ29udGV4dCxcbiAgICB9KTtcbiAgfSxcbiAgbmFtZTogXCJkb2N1bWVudC1jb2RlXCIsXG4gIHBhcmFtZXRlcnM6IGRvY3VtZW50Q29kZVNjaGVtYSxcbn07XG5cbmNvbnN0IGFwcGx5Q29kZUNoYW5nZVRvb2w6IFRvb2w8dW5kZWZpbmVkLCB0eXBlb2YgY29kZUNoYW5nZVNjaGVtYT4gPSB7XG4gIGFubm90YXRpb25zOiB7XG4gICAgZGVzdHJ1Y3RpdmVIaW50OiB0cnVlLFxuICAgIGlkZW1wb3RlbnRIaW50OiBmYWxzZSxcbiAgICBvcGVuV29ybGRIaW50OiBmYWxzZSxcbiAgICByZWFkT25seUhpbnQ6IGZhbHNlLFxuICAgIHRpdGxlOiBcIkFwcGx5IENvZGUgUGF0Y2hcIixcbiAgfSxcbiAgZGVzY3JpcHRpb246XG4gICAgXCJBcHBseSBhIHVuaWZpZWQgZGlmZiBwYXRjaCB0byBhIHdvcmtzcGFjZSBmaWxlIHdpdGggb3B0aW9uYWwgZHJ5LXJ1biB2YWxpZGF0aW9uIGFuZCBkaWZmIHByZXZpZXcuXCIsXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgZXhlY3V0ZTogYXN5bmMgKGlucHV0LCBfY29udGV4dCk6IFByb21pc2U8c3RyaW5nIHwgQ29udGVudFJlc3VsdD4gPT4ge1xuICAgIGNvbnN0IGFyZ3MgPSBjb2RlQ2hhbmdlU2NoZW1hLnBhcnNlKGlucHV0IGFzIEFwcGx5Q29kZUNoYW5nZUFyZ3MpO1xuICAgIGNvbnN0IHJvb3QgPSBnZXRXb3Jrc3BhY2VSb290KCk7XG4gICAgbGV0IGZpbGVQYXRoOiBzdHJpbmc7XG4gICAgdHJ5IHtcbiAgICAgIGZpbGVQYXRoID0gcmVzb2x2ZUluV29ya3NwYWNlKHJvb3QsIGFyZ3MuZmlsZVBhdGgpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBXb3Jrc3BhY2VFcnJvcikge1xuICAgICAgICByZXR1cm4gdGhyb3dVc2VyRXJyb3IoZXJyb3IubWVzc2FnZSk7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG5cbiAgICBjb25zdCBvcmlnaW5hbCA9IGZzLmV4aXN0c1N5bmMoZmlsZVBhdGgpXG4gICAgICA/IGZzLnJlYWRGaWxlU3luYyhmaWxlUGF0aCwgYXJncy5lbmNvZGluZyBhcyBCdWZmZXJFbmNvZGluZylcbiAgICAgIDogXCJcIjtcblxuICAgIGxldCBwYXRjaGVkOiBzdHJpbmcgfCBmYWxzZTtcbiAgICB0cnkge1xuICAgICAgcGF0Y2hlZCA9IGFwcGx5UGF0Y2gob3JpZ2luYWwsIGFyZ3MucGF0Y2gpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4gdGhyb3dVc2VyRXJyb3IoXG4gICAgICAgIGBGYWlsZWQgdG8gYXBwbHkgcHJvdmlkZWQgcGF0Y2ggdG8gJHthcmdzLmZpbGVQYXRofTogJHtlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IGVycm9yfWBcbiAgICAgICk7XG4gICAgfVxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgaWYgKHBhdGNoZWQgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm4gdGhyb3dVc2VyRXJyb3IoXG4gICAgICAgIGBGYWlsZWQgdG8gYXBwbHkgcHJvdmlkZWQgcGF0Y2ggdG8gJHthcmdzLmZpbGVQYXRofWBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKCFhcmdzLmRyeVJ1bikge1xuICAgICAgZnMubWtkaXJTeW5jKHBhdGguZGlybmFtZShmaWxlUGF0aCksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgZnMud3JpdGVGaWxlU3luYyhmaWxlUGF0aCwgcGF0Y2hlZCwge1xuICAgICAgICBlbmNvZGluZzogYXJncy5lbmNvZGluZyBhcyBCdWZmZXJFbmNvZGluZyxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICghYXJncy5zaG93RGlmZikge1xuICAgICAgcmV0dXJuIGBQYXRjaCAke2FyZ3MuZHJ5UnVuID8gXCJ2YWxpZGF0ZWRcIiA6IFwiYXBwbGllZFwifSBmb3IgJHthcmdzLmZpbGVQYXRofWA7XG4gICAgfVxuXG4gICAgY29uc3QgcHJldmlldyA9IGNyZWF0ZVR3b0ZpbGVzUGF0Y2goXG4gICAgICBhcmdzLmZpbGVQYXRoLFxuICAgICAgYXJncy5maWxlUGF0aCxcbiAgICAgIG9yaWdpbmFsLFxuICAgICAgcGF0Y2hlZCxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHsgY29udGV4dDogYXJncy5kaWZmQ29udGV4dCB9XG4gICAgKTtcblxuICAgIHJldHVybiB7XG4gICAgICBjb250ZW50OiBbXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICB0ZXh0OiBgUGF0Y2ggJHthcmdzLmRyeVJ1biA/IFwidmFsaWRhdGVkXCIgOiBcImFwcGxpZWRcIn0gZm9yICR7YXJncy5maWxlUGF0aH1gLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgdGV4dDogW1wiYGBgZGlmZlwiLCBwcmV2aWV3LnRyaW0oKSwgXCJgYGBcIl0uam9pbihcIlxcblwiKSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSBzYXRpc2ZpZXMgQ29udGVudFJlc3VsdDtcbiAgfSxcbiAgbmFtZTogXCJhcHBseS1jb2RlLWNoYW5nZVwiLFxuICBwYXJhbWV0ZXJzOiBjb2RlQ2hhbmdlU2NoZW1hLFxufTtcblxuZXhwb3J0IGNvbnN0IHRvb2xzID0ge1xuICAuLi5kZWNvcmF0b3JUb29scyxcbiAgZG9jdW1lbnRDb2RlVG9vbCxcbiAgYXBwbHlDb2RlQ2hhbmdlVG9vbCxcbn0gYXMgY29uc3Q7XG5cbmV4cG9ydCBmdW5jdGlvbiBlbnJpY2gobWNwOiBGYXN0TUNQKTogRmFzdE1DUCB7XG4gIGZvciAoY29uc3QgcHJvbXB0IG9mIGJ1aWxkRG9jUHJvbXB0cygpKSB7XG4gICAgbWNwLmFkZFByb21wdChwcm9tcHQgYXMgYW55KTtcbiAgfVxuXG4gIGZvciAoY29uc3QgdG9vbCBvZiBPYmplY3QudmFsdWVzKHRvb2xzKSkge1xuICAgIG1jcC5hZGRUb29sKHRvb2wgYXMgYW55KTtcbiAgfVxuXG4gIGZvciAoY29uc3QgdGVtcGxhdGUgb2YgYnVpbGRSZXNvdXJjZVRlbXBsYXRlcygpKSB7XG4gICAgbWNwLmFkZFJlc291cmNlVGVtcGxhdGUodGVtcGxhdGUgYXMgYW55KTtcbiAgfVxuXG4gIHJldHVybiBtY3A7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGVucmljaDtcbmV4cG9ydCBjb25zdCBQQUNLQUdFX05BTUUgPSBQS0c7XG5leHBvcnQgY29uc3QgVkVSU0lPTiA9IFY7XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRXb3Jrc3BhY2VSb290KHJvb3Q6IHN0cmluZykge1xuICB3b3Jrc3BhY2VSb290ID0gcGF0aC5yZXNvbHZlKHJvb3QpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0V29ya3NwYWNlUm9vdCgpOiBzdHJpbmcge1xuICByZXR1cm4gd29ya3NwYWNlUm9vdDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkUmVzb3VyY2VUZW1wbGF0ZXMoKTogV29ya3NwYWNlUmVzb3VyY2VUZW1wbGF0ZVtdIHtcbiAgY29uc3Qgcm9vdCA9IGdldFdvcmtzcGFjZVJvb3QoKTtcbiAgY29uc3Qgc2hhcmVkQXJndW1lbnRzID0gW1xuICAgIHtcbiAgICAgIG5hbWU6IFwicGF0aFwiLFxuICAgICAgZGVzY3JpcHRpb246IFwiUGF0aCByZWxhdGl2ZSB0byB0aGUgd29ya3NwYWNlIHJvb3RcIixcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgIH0sXG4gIF0gYXMgY29uc3Q7XG5cbiAgcmV0dXJuIFtcbiAgICB7XG4gICAgICBuYW1lOiBcInZzY29kZS13b3Jrc3BhY2UtZmlsZVwiLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgIFwiRXhwb3NlIHdvcmtzcGFjZSBmaWxlcyB0byBWaXN1YWwgU3R1ZGlvIENvZGUgdmlhIHZzY29kZTovLyBVUklzXCIsXG4gICAgICB1cmlUZW1wbGF0ZTogXCJ2c2NvZGU6Ly93b3Jrc3BhY2Uve3BhdGh9XCIsXG4gICAgICBtaW1lVHlwZTogXCJ0ZXh0L3BsYWluXCIsXG4gICAgICBhcmd1bWVudHM6IHNoYXJlZEFyZ3VtZW50cyxcbiAgICAgIGxvYWQ6IGFzeW5jIChhcmdzOiB7IHBhdGg6IHN0cmluZyB9KSA9PiB7XG4gICAgICAgIGNvbnN0IHRleHQgPSBhd2FpdCByZWFkV29ya3NwYWNlRmlsZShyb290LCBhcmdzLnBhdGgpO1xuICAgICAgICByZXR1cm4geyB0ZXh0IH07XG4gICAgICB9LFxuICAgIH0sXG4gICAge1xuICAgICAgbmFtZTogXCJjdXJzb3Itd29ya3NwYWNlLWZpbGVcIixcbiAgICAgIGRlc2NyaXB0aW9uOiBcIkV4cG9zZSB3b3Jrc3BhY2UgZmlsZXMgdG8gQ3Vyc29yIHZpYSBjdXJzb3I6Ly8gVVJJc1wiLFxuICAgICAgdXJpVGVtcGxhdGU6IFwiY3Vyc29yOi8vd29ya3NwYWNlL3twYXRofVwiLFxuICAgICAgbWltZVR5cGU6IFwidGV4dC9wbGFpblwiLFxuICAgICAgYXJndW1lbnRzOiBzaGFyZWRBcmd1bWVudHMsXG4gICAgICBsb2FkOiBhc3luYyAoYXJnczogeyBwYXRoOiBzdHJpbmcgfSkgPT4ge1xuICAgICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgcmVhZFdvcmtzcGFjZUZpbGUocm9vdCwgYXJncy5wYXRoKTtcbiAgICAgICAgcmV0dXJuIHsgdGV4dCB9O1xuICAgICAgfSxcbiAgICB9LFxuICAgIHtcbiAgICAgIG5hbWU6IFwiY29waWxvdC13b3Jrc3BhY2UtZmlsZVwiLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgIFwiRXhwb3NlIHdvcmtzcGFjZSBmaWxlcyB0byBHaXRIdWIgQ29waWxvdCB2aWEgY29waWxvdDovLyBVUklzXCIsXG4gICAgICB1cmlUZW1wbGF0ZTogXCJjb3BpbG90Oi8vd29ya3NwYWNlL3twYXRofVwiLFxuICAgICAgbWltZVR5cGU6IFwidGV4dC9wbGFpblwiLFxuICAgICAgYXJndW1lbnRzOiBzaGFyZWRBcmd1bWVudHMsXG4gICAgICBsb2FkOiBhc3luYyAoYXJnczogeyBwYXRoOiBzdHJpbmcgfSkgPT4ge1xuICAgICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgcmVhZFdvcmtzcGFjZUZpbGUocm9vdCwgYXJncy5wYXRoKTtcbiAgICAgICAgcmV0dXJuIHsgdGV4dCB9O1xuICAgICAgfSxcbiAgICB9LFxuICBdO1xufVxuXG5mdW5jdGlvbiBpbml0aWFsaXplV29ya3NwYWNlUm9vdCgpOiBzdHJpbmcge1xuICBjb25zdCBjb25maWd1cmVkID0gcHJvY2Vzcy5lbnZbV09SS1NQQUNFX1JPT1RfRU5WXTtcbiAgaWYgKGNvbmZpZ3VyZWQgJiYgY29uZmlndXJlZC50cmltKCkubGVuZ3RoID4gMCkge1xuICAgIHJldHVybiBwYXRoLnJlc29sdmUoY29uZmlndXJlZC50cmltKCkpO1xuICB9XG4gIHJldHVybiBwcm9jZXNzLmN3ZCgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGREb2NQcm9tcHRzKCk6IElucHV0UHJvbXB0PHVuZGVmaW5lZD5bXSB7XG4gIGNvbnN0IHJvb3QgPSBnZXRXb3Jrc3BhY2VSb290KCk7XG4gIGNvbnN0IGZpbGVCYXNlZFByb21wdHMgPSBkaXNjb3ZlckRvY1Byb21wdHMocm9vdCkubWFwKChwcm9tcHQpID0+ICh7XG4gICAgbmFtZTogYGRvYy8ke3Byb21wdC5uYW1lfWAsXG4gICAgZGVzY3JpcHRpb246IHByb21wdC5kZXNjcmlwdGlvbixcbiAgICBsb2FkOiBhc3luYyAoKSA9PiBwcm9tcHQuY29udGVudCxcbiAgfSkpO1xuXG4gIGNvbnN0IGludGVncmF0aW9uUHJvbXB0cyA9IENMSUVOVF9JTlRFR1JBVElPTlMubWFwPElucHV0UHJvbXB0PHVuZGVmaW5lZD4+KFxuICAgIChpbnRlZ3JhdGlvbikgPT4gKHtcbiAgICAgIG5hbWU6IGBpbnRlZ3JhdGlvbi8ke2ludGVncmF0aW9uLmlkfWAsXG4gICAgICBkZXNjcmlwdGlvbjogYCR7aW50ZWdyYXRpb24uZGlzcGxheX0gaW50ZWdyYXRpb24gZ3VpZGFuY2VgLFxuICAgICAgbG9hZDogYXN5bmMgKCkgPT5cbiAgICAgICAgYFlvdSBhcmUgY29vcmRpbmF0aW5nIHdpdGggJHtpbnRlZ3JhdGlvbi5kaXNwbGF5fS4gJHtpbnRlZ3JhdGlvbi5pbnN0cnVjdGlvbnN9XFxuXFxuVG9vbHMgYXZhaWxhYmxlOlxcbi0gZG9jdW1lbnQtY29kZVxcbi0gYXBwbHktY29kZS1jaGFuZ2VcXG5cXG5FbnN1cmUgcmVzcG9uc2VzIGluY2x1ZGUgYWN0aW9uYWJsZSBzdGVwcyBmb3IgdGhlIGNsaWVudC5gLFxuICAgIH0pXG4gICk7XG5cbiAgcmV0dXJuIFsuLi5maWxlQmFzZWRQcm9tcHRzLCAuLi5pbnRlZ3JhdGlvblByb21wdHNdO1xufVxuXG5mdW5jdGlvbiByZXNvbHZlSW5Xb3Jrc3BhY2Uocm9vdDogc3RyaW5nLCB0YXJnZXRQYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCByZXNvbHZlZCA9IHBhdGguaXNBYnNvbHV0ZSh0YXJnZXRQYXRoKVxuICAgID8gcGF0aC5ub3JtYWxpemUodGFyZ2V0UGF0aClcbiAgICA6IHBhdGgucmVzb2x2ZShyb290LCB0YXJnZXRQYXRoKTtcblxuICBjb25zdCByZWxhdGl2ZSA9IHBhdGgucmVsYXRpdmUocm9vdCwgcmVzb2x2ZWQpO1xuICBpZiAocmVsYXRpdmUuc3RhcnRzV2l0aChcIi4uXCIpIHx8IHBhdGguaXNBYnNvbHV0ZShyZWxhdGl2ZSkpIHtcbiAgICB0aHJvdyBuZXcgV29ya3NwYWNlRXJyb3IoXG4gICAgICBgUGF0aCAke3RhcmdldFBhdGh9IGVzY2FwZXMgdGhlIHdvcmtzcGFjZSByb290IGF0ICR7cm9vdH1gXG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiByZXNvbHZlZDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcmVhZFdvcmtzcGFjZUZpbGUoXG4gIHJvb3Q6IHN0cmluZyxcbiAgdGFyZ2V0OiBzdHJpbmdcbik6IFByb21pc2U8c3RyaW5nPiB7XG4gIHRyeSB7XG4gICAgY29uc3QgYWJzb2x1dGUgPSByZXNvbHZlSW5Xb3Jrc3BhY2Uocm9vdCwgdGFyZ2V0KTtcbiAgICByZXR1cm4gZnMucmVhZEZpbGVTeW5jKGFic29sdXRlLCBcInV0ZjhcIiBhcyBCdWZmZXJFbmNvZGluZyk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgaWYgKGVycm9yIGluc3RhbmNlb2YgV29ya3NwYWNlRXJyb3IpIHtcbiAgICAgIGF3YWl0IHRocm93VXNlckVycm9yKGVycm9yLm1lc3NhZ2UpO1xuICAgIH1cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIHRocm93IGVycm9yO1xuICB9XG59XG5cbmZ1bmN0aW9uIGRpc2NvdmVyRG9jUHJvbXB0cyhyb290OiBzdHJpbmcpOiBEb2NQcm9tcHRbXSB7XG4gIGNvbnN0IGRpc2NvdmVyZWQ6IERvY1Byb21wdFtdID0gW107XG5cbiAgZm9yIChjb25zdCBkaXJlY3Rvcnkgb2YgUFJPTVBUX0RJUkVDVE9SSUVTKSB7XG4gICAgY29uc3QgcHJvbXB0RGlyID0gcGF0aC5qb2luKHJvb3QsIGRpcmVjdG9yeSk7XG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKHByb21wdERpcikgfHwgIWZzLnN0YXRTeW5jKHByb21wdERpcikuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiBmcy5yZWFkZGlyU3luYyhwcm9tcHREaXIpKSB7XG4gICAgICBjb25zdCBmdWxsUGF0aCA9IHBhdGguam9pbihwcm9tcHREaXIsIGVudHJ5KTtcbiAgICAgIGlmICghZnMuc3RhdFN5bmMoZnVsbFBhdGgpLmlzRmlsZSgpKSBjb250aW51ZTtcblxuICAgICAgY29uc3QgbmFtZSA9IHBhdGgucGFyc2UoZW50cnkpLm5hbWU7XG4gICAgICBjb25zdCBjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKGZ1bGxQYXRoLCBcInV0ZjhcIik7XG4gICAgICBjb25zdCB0aXRsZSA9IHRvVGl0bGVDYXNlKG5hbWUucmVwbGFjZSgvWy1fXS9nLCBcIiBcIikpO1xuICAgICAgY29uc3QgZGVzY3JpcHRpb24gPSBleHRyYWN0RGVzY3JpcHRpb24oY29udGVudCwgZnVsbFBhdGgpO1xuXG4gICAgICBkaXNjb3ZlcmVkLnB1c2goe1xuICAgICAgICBuYW1lLFxuICAgICAgICB0aXRsZSxcbiAgICAgICAgZGVzY3JpcHRpb24sXG4gICAgICAgIGNvbnRlbnQsXG4gICAgICAgIGFic29sdXRlUGF0aDogZnVsbFBhdGgsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBjb25zdCB1bmlxdWUgPSBuZXcgTWFwPHN0cmluZywgRG9jUHJvbXB0PigpO1xuICBmb3IgKGNvbnN0IHByb21wdCBvZiBkaXNjb3ZlcmVkKSB7XG4gICAgaWYgKCF1bmlxdWUuaGFzKHByb21wdC5uYW1lKSkge1xuICAgICAgdW5pcXVlLnNldChwcm9tcHQubmFtZSwgcHJvbXB0KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gQXJyYXkuZnJvbSh1bmlxdWUudmFsdWVzKCkpLnNvcnQoKGEsIGIpID0+XG4gICAgYS5uYW1lLmxvY2FsZUNvbXBhcmUoYi5uYW1lKVxuICApO1xufVxuXG5mdW5jdGlvbiBzZWxlY3RQcm9tcHQocHJvbXB0czogRG9jUHJvbXB0W10sIHJlcXVlc3RlZE5hbWU6IHN0cmluZyk6IERvY1Byb21wdCB7XG4gIGNvbnN0IGRpcmVjdCA9IHByb21wdHMuZmluZCgocHJvbXB0KSA9PiBwcm9tcHQubmFtZSA9PT0gcmVxdWVzdGVkTmFtZSk7XG4gIGlmIChkaXJlY3QpIHJldHVybiBkaXJlY3Q7XG5cbiAgY29uc3QgZmFsbGJhY2sgPSBwcm9tcHRzLmZpbmQoXG4gICAgKHByb21wdCkgPT4gcHJvbXB0Lm5hbWUgPT09IERFRkFVTFRfUFJPTVBUX05BTUVcbiAgKTtcbiAgaWYgKGZhbGxiYWNrKSByZXR1cm4gZmFsbGJhY2s7XG5cbiAgaWYgKCFwcm9tcHRzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBXb3Jrc3BhY2VFcnJvcihcIk5vIGRvY3VtZW50YXRpb24gcHJvbXB0cyBhdmFpbGFibGVcIik7XG4gIH1cblxuICByZXR1cm4gcHJvbXB0c1swXTtcbn1cblxuZnVuY3Rpb24gYnVpbGREb2N1bWVudGF0aW9uUGF5bG9hZCh7XG4gIGZpbGVQYXRoLFxuICBmaWxlQ29udGVudCxcbiAgcHJvbXB0LFxuICBpbmNsdWRlUHJvbXB0LFxuICBpbmNsdWRlQ29kZSxcbiAgaW5jbHVkZU1ldGFkYXRhLFxuICBhZGRpdGlvbmFsQ29udGV4dCxcbn06IHtcbiAgZmlsZVBhdGg6IHN0cmluZztcbiAgZmlsZUNvbnRlbnQ6IHN0cmluZztcbiAgcHJvbXB0OiBEb2NQcm9tcHQ7XG4gIGluY2x1ZGVQcm9tcHQ6IGJvb2xlYW47XG4gIGluY2x1ZGVDb2RlOiBib29sZWFuO1xuICBpbmNsdWRlTWV0YWRhdGE6IGJvb2xlYW47XG4gIGFkZGl0aW9uYWxDb250ZXh0Pzogc3RyaW5nO1xufSk6IENvbnRlbnRSZXN1bHQge1xuICBjb25zdCBzZWN0aW9uczogc3RyaW5nW10gPSBbXTtcblxuICBpZiAoaW5jbHVkZU1ldGFkYXRhKSB7XG4gICAgc2VjdGlvbnMucHVzaChcbiAgICAgIGAjIERvY3VtZW50YXRpb24gUmVxdWVzdFxcbi0gcHJvbXB0OiAke3Byb21wdC5uYW1lfVxcbi0gZmlsZTogJHtmaWxlUGF0aH1gXG4gICAgKTtcbiAgfVxuXG4gIGlmIChpbmNsdWRlUHJvbXB0KSB7XG4gICAgc2VjdGlvbnMucHVzaChcbiAgICAgIGAjIyBQcm9tcHQgR3VpZGFuY2UgKCR7cHJvbXB0LnRpdGxlfSlcXG5cXG4ke3Byb21wdC5jb250ZW50LnRyaW0oKX1gXG4gICAgKTtcbiAgfVxuXG4gIGlmIChhZGRpdGlvbmFsQ29udGV4dD8udHJpbSgpKSB7XG4gICAgc2VjdGlvbnMucHVzaChgIyMgQWRkaXRpb25hbCBDb250ZXh0XFxuXFxuJHthZGRpdGlvbmFsQ29udGV4dC50cmltKCl9YCk7XG4gIH1cblxuICBpZiAoaW5jbHVkZUNvZGUpIHtcbiAgICBzZWN0aW9ucy5wdXNoKFxuICAgICAgYCMjIFNvdXJjZVxcblxcblxcYFxcYFxcYCR7aW5mZXJMYW5ndWFnZUZyb21QYXRoKGZpbGVQYXRoKX1cXG4ke2ZpbGVDb250ZW50fVxcblxcYFxcYFxcYGBcbiAgICApO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBjb250ZW50OiBbXG4gICAgICB7XG4gICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICB0ZXh0OiBzZWN0aW9ucy5qb2luKFwiXFxuXFxuXCIpLFxuICAgICAgfSxcbiAgICBdLFxuICB9IHNhdGlzZmllcyBDb250ZW50UmVzdWx0O1xufVxuXG5mdW5jdGlvbiBleHRyYWN0RGVzY3JpcHRpb24oY29udGVudDogc3RyaW5nLCBmaWxlUGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgZmlyc3RMaW5lID0gY29udGVudFxuICAgIC5zcGxpdCgvXFxyP1xcbi8pXG4gICAgLm1hcCgobGluZSkgPT4gbGluZS50cmltKCkpXG4gICAgLmZpbmQoKGxpbmUpID0+IGxpbmUubGVuZ3RoID4gMCk7XG5cbiAgcmV0dXJuIChcbiAgICBmaXJzdExpbmU/LnNsaWNlKDAsIDI0MCkgPz9cbiAgICBgRG9jdW1lbnRhdGlvbiBwcm9tcHQgbG9hZGVkIGZyb20gJHtwYXRoLmJhc2VuYW1lKGZpbGVQYXRoKX1gXG4gICk7XG59XG5cbmZ1bmN0aW9uIHRvVGl0bGVDYXNlKHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gdmFsdWVcbiAgICAuc3BsaXQoL1xccysvKVxuICAgIC5maWx0ZXIoQm9vbGVhbilcbiAgICAubWFwKChwYXJ0KSA9PiBwYXJ0LmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgcGFydC5zbGljZSgxKS50b0xvd2VyQ2FzZSgpKVxuICAgIC5qb2luKFwiIFwiKTtcbn1cblxuZnVuY3Rpb24gaW5mZXJMYW5ndWFnZUZyb21QYXRoKGZpbGVQYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBleHRlbnNpb24gPSBwYXRoLmV4dG5hbWUoZmlsZVBhdGgpLnRvTG93ZXJDYXNlKCk7XG4gIHN3aXRjaCAoZXh0ZW5zaW9uKSB7XG4gICAgY2FzZSBcIi50c1wiOlxuICAgIGNhc2UgXCIudHN4XCI6XG4gICAgICByZXR1cm4gXCJ0c1wiO1xuICAgIGNhc2UgXCIuanNcIjpcbiAgICBjYXNlIFwiLmpzeFwiOlxuICAgICAgcmV0dXJuIFwianNcIjtcbiAgICBjYXNlIFwiLmpzb25cIjpcbiAgICAgIHJldHVybiBcImpzb25cIjtcbiAgICBjYXNlIFwiLm1kXCI6XG4gICAgICByZXR1cm4gXCJtZFwiO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gXCJ0ZXh0XCI7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVzZXRXb3Jrc3BhY2VSb290KHJvb3Q6IHN0cmluZykge1xuICBzZXRXb3Jrc3BhY2VSb290KHJvb3QpO1xufVxuXG5leHBvcnQgeyBkb2N1bWVudENvZGVTY2hlbWEsIGNvZGVDaGFuZ2VTY2hlbWEgfTtcbiIsIi8qKlxuICogQGRlc2NyaXB0aW9uIFRoZSBmaWxlbmFtZSB0aGF0IGlkZW50aWZpZXMgRGVjYWYgQ0xJIG1vZHVsZXNcbiAqIEBzdW1tYXJ5IFRoZSBzdGFuZGFyZCBmaWxlbmFtZSBmb3IgQ0xJIG1vZHVsZSBmaWxlcyB3aGVyZSBlYWNoIGxpYnJhcnkgbXVzdCBleHBvcnQgYSBzaW5nbGUgQ2xpTW9kdWxlIGZ1bmN0aW9uXG4gKlxuICogQGNvbnN0IE1DUF9GSUxFX05BTUVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TUNQXG4gKi9cbmV4cG9ydCBjb25zdCBNQ1BfRklMRV9OQU1FID0gXCJtY3AtbW9kdWxlXCI7XG4iLCIvKiBpc3RhbmJ1bCBpZ25vcmUgZmlsZSAqL1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCB7IE1jcE1vZHVsZSB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFV0aWxpdHkgY2xhc3MgZm9yIENMSSBvcGVyYXRpb25zXG4gKiBAc3VtbWFyeSBBIHN0YXRpYyB1dGlsaXR5IGNsYXNzIHRoYXQgcHJvdmlkZXMgbWV0aG9kcyBmb3IgbG9hZGluZyBtb2R1bGVzLCByZXRyaWV2aW5nIHBhY2thZ2UgaW5mb3JtYXRpb24sIGFuZCBpbml0aWFsaXppbmcgQ0xJIGNvbW1hbmRzXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEluaXRpYWxpemUgYSBDb21tYW5kIG9iamVjdCB3aXRoIHBhY2thZ2UgaW5mb3JtYXRpb25cbiAqIGNvbnN0IGNvbW1hbmQgPSBuZXcgQ29tbWFuZCgpO1xuICogQ0xJVXRpbHMuaW5pdGlhbGl6ZShjb21tYW5kLCAnLi9wYXRoL3RvL3BhY2thZ2UnKTtcbiAqXG4gKiAvLyBMb2FkIGEgQ0xJIG1vZHVsZSBmcm9tIGEgZmlsZVxuICogY29uc3QgbW9kdWxlID0gYXdhaXQgQ0xJVXRpbHMubG9hZEZyb21GaWxlKCcuL3BhdGgvdG8vY2xpLW1vZHVsZS5qcycpO1xuICpcbiAqIEBjbGFzcyBNY3BVdGlsc1xuICovXG5leHBvcnQgY2xhc3MgTWNwVXRpbHMge1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIER5bmFtaWNhbGx5IGltcG9ydHMgYSBtb2R1bGUgZmlsZVxuICAgKiBAc3VtbWFyeSBMb2FkcyBhIEphdmFTY3JpcHQgZmlsZSBhbmQgcmV0dXJucyBpdCBhcyBhIENsaU1vZHVsZSwgaGFuZGxpbmcgYm90aCBFU00gYW5kIENvbW1vbkpTIGZvcm1hdHNcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHBhdGggVGhlIGZpbGUgcGF0aCB0byB0aGUgbW9kdWxlIHRvIGxvYWRcbiAgICogQHJldHVybiB7UHJvbWlzZTxNY3BNb2R1bGU+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgbG9hZGVkIENsaU1vZHVsZVxuICAgKi9cbiAgc3RhdGljIGFzeW5jIGxvYWRGcm9tRmlsZShwYXRoOiBzdHJpbmcpOiBQcm9taXNlPE1jcE1vZHVsZT4ge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gTWNwVXRpbHMubm9ybWFsaXplSW1wb3J0KGltcG9ydChwYXRoKSk7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgRmFpbGVkIHRvIGxvYWQgZnJvbSAke3BhdGh9OiAke2UgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IGV9YFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIE5vcm1hbGl6ZXMgbW9kdWxlIGltcG9ydHMgdG8gaGFuZGxlIGJvdGggRVNNIGFuZCBDb21tb25KUyBmb3JtYXRzXG4gICAqIEBzdW1tYXJ5IFByb3Blcmx5IGltcG9ydHMgSmF2YVNjcmlwdCBmaWxlcyByZWdhcmRsZXNzIG9mIHRoZWlyIG1vZHVsZSBmb3JtYXQgYnkgaGFuZGxpbmcgdGhlIEVTTSB3cmFwcGVyIGZvciBDb21tb25KUyBtb2R1bGVzXG4gICAqXG4gICAqIEB0ZW1wbGF0ZSBUIFRoZSB0eXBlIG9mIHRoZSBpbXBvcnRlZCBtb2R1bGVcbiAgICogQHBhcmFtIHtQcm9taXNlPFQ+fSBpbXBvcnRQcm9taXNlIFRoZSBwcm9taXNlIHJldHVybmVkIGJ5IHRoZSBkeW5hbWljIGltcG9ydFxuICAgKiBAcmV0dXJuIHtQcm9taXNlPFQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgbm9ybWFsaXplZCBtb2R1bGVcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHN0YXRpYyBhc3luYyBub3JtYWxpemVJbXBvcnQ8VD4oaW1wb3J0UHJvbWlzZTogUHJvbWlzZTxUPik6IFByb21pc2U8VD4ge1xuICAgIC8vIENvbW1vbkpTJ3MgYG1vZHVsZS5leHBvcnRzYCBpcyB3cmFwcGVkIGFzIGBkZWZhdWx0YCBpbiBFU01vZHVsZS5cbiAgICByZXR1cm4gaW1wb3J0UHJvbWlzZS50aGVuKFxuICAgICAgKG06IHVua25vd24pID0+ICgobSBhcyB7IGRlZmF1bHQ6IFQgfSkuZGVmYXVsdCB8fCBtKSBhcyBUXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIGFuZCBwYXJzZXMgdGhlIHBhY2thZ2UuanNvbiBmaWxlXG4gICAqIEBzdW1tYXJ5IFJlYWRzIHRoZSBwYWNrYWdlLmpzb24gZmlsZSBmcm9tIHRoZSBzcGVjaWZpZWQgcGF0aCBhbmQgcGFyc2VzIGl0IGludG8gYSBKYXZhU2NyaXB0IG9iamVjdFxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYmFzZVBhdGggVGhlIGJhc2UgcGF0aCB3aGVyZSB0aGUgcGFja2FnZS5qc29uIGZpbGUgaXMgbG9jYXRlZFxuICAgKiBAcmV0dXJuIHtSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gVGhlIHBhcnNlZCBwYWNrYWdlLmpzb24gY29udGVudCBhcyBhbiBvYmplY3RcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGdldFBhY2thZ2UoYmFzZVBhdGg6IHN0cmluZyk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIEpTT04ucGFyc2UoXG4gICAgICAgIGZzLnJlYWRGaWxlU3luYyhwYXRoLmpvaW4oYmFzZVBhdGgsIFwicGFja2FnZS5qc29uXCIpLCBcInV0ZjhcIilcbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmFibGUgdG8gcmVhZCB2ZXJzaW9uIGZyb20gJHtiYXNlUGF0aH06ICR7ZX1gKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHVybnMgdGhlIHZlcnNpb24gZnJvbSBwYWNrYWdlLmpzb25cbiAgICogQHN1bW1hcnkgUmV0cmlldmVzIHRoZSB2ZXJzaW9uIGZpZWxkIGZyb20gdGhlIHBhY2thZ2UuanNvbiBmaWxlIGF0IHRoZSBzcGVjaWZpZWQgcGF0aFxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYmFzZVBhdGggVGhlIGJhc2UgcGF0aCB3aGVyZSB0aGUgcGFja2FnZS5qc29uIGZpbGUgaXMgbG9jYXRlZFxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBwYWNrYWdlIHZlcnNpb24gc3RyaW5nXG4gICAqL1xuICBzdGF0aWMgcGFja2FnZVZlcnNpb24oYmFzZVBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIE1jcFV0aWxzLmdldFBhY2thZ2UoYmFzZVBhdGgpW1widmVyc2lvblwiXSBhcyBzdHJpbmc7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHVybnMgdGhlIG5hbWUgZnJvbSBwYWNrYWdlLmpzb25cbiAgICogQHN1bW1hcnkgUmV0cmlldmVzIHRoZSBuYW1lIGZpZWxkIGZyb20gdGhlIHBhY2thZ2UuanNvbiBmaWxlIGF0IHRoZSBzcGVjaWZpZWQgcGF0aCBhbmQgZXh0cmFjdHMgdGhlIHBhY2thZ2UgbmFtZSB3aXRob3V0IHRoZSBzY29wZVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYmFzZVBhdGggVGhlIGJhc2UgcGF0aCB3aGVyZSB0aGUgcGFja2FnZS5qc29uIGZpbGUgaXMgbG9jYXRlZFxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBwYWNrYWdlIG5hbWUgd2l0aG91dCB0aGUgc2NvcGUgKGUuZy4sIFwiY2xpXCIgZnJvbSBcIkBkZWNhZi10cy9jbGlcIilcbiAgICovXG4gIHN0YXRpYyBwYWNrYWdlTmFtZShiYXNlUGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBuYW1lID0gKE1jcFV0aWxzLmdldFBhY2thZ2UoYmFzZVBhdGgpW1wibmFtZVwiXSBhcyBzdHJpbmcpLnNwbGl0KFwiL1wiKTtcbiAgICByZXR1cm4gbmFtZVtuYW1lLmxlbmd0aCAtIDFdO1xuICB9XG59XG4iLCIvKiBpc3RhbmJ1bCBpZ25vcmUgZmlsZSAqL1xuaW1wb3J0IGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IE1DUF9GSUxFX05BTUUgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IE1jcFV0aWxzIH0gZnJvbSBcIi4vdXRpbHNcIjtcbmltcG9ydCB7IEZhc3RNQ1AgfSBmcm9tIFwiZmFzdG1jcFwiO1xuaW1wb3J0IHsgTG9nZ2VkQ2xhc3MgfSBmcm9tIFwiQGRlY2FmLXRzL2xvZ2dpbmdcIjtcbmltcG9ydCB7IFZFUlNJT04gfSBmcm9tIFwiLi9tZXRhZGF0YVwiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBVdGlsaXR5IGNsYXNzIHRvIGhhbmRsZSBDTEkgZnVuY3Rpb25hbGl0eSBmcm9tIGFsbCBEZWNhZiBtb2R1bGVzXG4gKiBAc3VtbWFyeSBUaGlzIGNsYXNzIHByb3ZpZGVzIGEgd3JhcHBlciBhcm91bmQgQ29tbWFuZGVyLmpzIHRvIGhhbmRsZSBDTEkgY29tbWFuZHMgZnJvbSBkaWZmZXJlbnQgRGVjYWYgbW9kdWxlcy5cbiAqIEl0IGNyYXdscyB0aGUgZmlsZXN5c3RlbSB0byBmaW5kIENMSSBtb2R1bGVzLCBsb2FkcyB0aGVtLCBhbmQgcmVnaXN0ZXJzIHRoZWlyIGNvbW1hbmRzLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbYmFzZVBhdGhdIFRoZSBiYXNlIHBhdGggdG8gbG9vayBmb3IgbW9kdWxlcyBpbi4gRGVmYXVsdHMgdG8gYC4vYFxuICogQHBhcmFtIHtudW1iZXJ9IFtjcmF3bExldmVsc10gTnVtYmVyIG9mIGZvbGRlciBsZXZlbHMgdG8gY3Jhd2wgdG8gZmluZCBtb2R1bGVzIGZyb20gdGhlIGJhc2VQYXRoLiBEZWZhdWx0cyB0byA0XG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIENyZWF0ZSBhIG5ldyBDTEkgd3JhcHBlciBhbmQgcnVuIGl0IHdpdGggY3VzdG9tIG9wdGlvbnNcbiAqIGNvbnN0IGNsaSA9IG5ldyBDbGlXcmFwcGVyKCcuL3NyYycsIDIpO1xuICogY2xpLnJ1bihwcm9jZXNzLmFyZ3YpLnRoZW4oKCkgPT4ge1xuICogICBjb25zb2xlLmxvZygnQ0xJIGNvbW1hbmRzIGV4ZWN1dGVkIHN1Y2Nlc3NmdWxseScpO1xuICogfSk7XG4gKlxuICogQGNsYXNzIE1jcFdyYXBwZXJcbiAqL1xuZXhwb3J0IGNsYXNzIE1jcFdyYXBwZXIgZXh0ZW5kcyBMb2dnZWRDbGFzcyB7XG4gIHByaXZhdGUgX21jcD86IEZhc3RNQ1A7XG4gIHByaXZhdGUgbW9kdWxlczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBwcml2YXRlIHJlYWRvbmx5IHJvb3RQYXRoOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBiYXNlUGF0aDogc3RyaW5nID0gXCIuL1wiLFxuICAgIHByaXZhdGUgY3Jhd2xMZXZlbHMgPSA0XG4gICkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5yb290UGF0aCA9IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsIFwiLi5cIik7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBhbmQgaW5pdGlhbGl6ZXMgdGhlIENvbW1hbmRlciBDb21tYW5kIG9iamVjdFxuICAgKiBAc3VtbWFyeSBMYXp5LWxvYWRzIHRoZSBDb21tYW5kIG9iamVjdCwgaW5pdGlhbGl6aW5nIGl0IHdpdGggdGhlIHBhY2thZ2UgbmFtZSwgZGVzY3JpcHRpb24sIGFuZCB2ZXJzaW9uXG4gICAqIEByZXR1cm4ge0NvbW1hbmR9IFRoZSBpbml0aWFsaXplZCBDb21tYW5kIG9iamVjdFxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBnZXQgbWNwKCkge1xuICAgIGlmICghdGhpcy5fbWNwKSB7XG4gICAgICB0aGlzLl9tY3AgPSBuZXcgRmFzdE1DUCh7XG4gICAgICAgIG5hbWU6IFwiZGVjYWYtdHMgTUNQIHNlcnZlclwiLFxuICAgICAgICBpbnN0cnVjdGlvbnM6IFwiXCIsXG4gICAgICAgIHZlcnNpb246IFZFUlNJT04gYXMgYW55LFxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9tY3A7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvYWRzIGFuZCByZWdpc3RlcnMgYW4gbWNwIGV4dGVuc2lvbiBtb2R1bGUgZnJvbSBhIGZpbGVcbiAgICogQHN1bW1hcnkgRHluYW1pY2FsbHkgaW1wb3J0cyBhbiBtY3AgZXh0ZW5zaW9uIG1vZHVsZSBmcm9tIHRoZSBzcGVjaWZpZWQgZmlsZSBwYXRoLCBpbml0aWFsaXplcyBpdCwgYW5kIHJlZ2lzdGVycyBpdCBpbiB0aGUgbW9kdWxlcyBjb2xsZWN0aW9uXG4gICAqXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGxvYWQoXG4gICAgc2VydmVyOiBGYXN0TUNQLFxuICAgIGZpbGVQYXRoOiBzdHJpbmdcbiAgKTogUHJvbWlzZTx7IG1jcDogRmFzdE1DUDsgcGFja2FnZTogc3RyaW5nOyB2ZXJzaW9uOiBzdHJpbmcgfT4ge1xuICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nLmZvcih0aGlzLmxvYWQpO1xuXG4gICAgbGV0IHBrZzogc3RyaW5nLCB2ZXJzaW9uOiBzdHJpbmcsIGVucmljaDogYW55O1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBNY3BVdGlscy5sb2FkRnJvbUZpbGUoZmlsZVBhdGgpO1xuICAgICAgcGtnID0gcmVzLlBBQ0tBR0VfTkFNRTtcbiAgICAgIHZlcnNpb24gPSByZXMuVkVSU0lPTjtcbiAgICAgIGVucmljaCA9IHJlcy5lbnJpY2g7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKChlIGFzIGFueSkubWVzc2FnZSB8fCAoZSBhcyBhbnkpKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGxvZy5pbmZvKGBFbnJpY2hpbmcgbWNwIHNlcnZlciB3aXRoIG1vZHVsZSAke3BrZ30gdiR7dmVyc2lvbn1gKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGVucmljaChzZXJ2ZXIpO1xuICAgICAgc2VydmVyID0gcmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSA/IGF3YWl0IHJlc3VsdCA6IHJlc3VsdDtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBmYWlsZWQgdG8gZW5yaWNoIG1jcCB3aXRoIG1vZHVsZSAke3BrZyB8fCBcInVubmFtZWRcIn0gdW5kZXIgJHtmaWxlUGF0aH06ICR7ZSBpbnN0YW5jZW9mIEVycm9yID8gZS5tZXNzYWdlIDogZX1gXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgbWNwOiBzZXJ2ZXIsXG4gICAgICBwYWNrYWdlOiBwa2csXG4gICAgICB2ZXJzaW9uOiB2ZXJzaW9uLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEZpbmRzIGFuZCBsb2FkcyBhbGwgQ0xJIG1vZHVsZXMgaW4gdGhlIGJhc2VQYXRoXG4gICAqIEBzdW1tYXJ5IFVzZXMgdGhlIGNyYXdsIG1ldGhvZCB0byBmaW5kIGFsbCBDTEkgbW9kdWxlcyBpbiB0aGUgc3BlY2lmaWVkIGJhc2UgcGF0aCxcbiAgICogdGhlbiBsb2FkcyBhbmQgcmVnaXN0ZXJzIGVhY2ggbW9kdWxlIGFzIGEgc3ViY29tbWFuZFxuICAgKlxuICAgKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIGFsbCBtb2R1bGVzIGFyZSBsb2FkZWRcbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQ2xpV3JhcHBlclxuICAgKiAgIHBhcnRpY2lwYW50IEZpbGVzeXN0ZW1cbiAgICogICBwYXJ0aWNpcGFudCBNb2R1bGVcbiAgICpcbiAgICogICBDbGlXcmFwcGVyLT4+RmlsZXN5c3RlbTogSm9pbiBiYXNlUGF0aCB3aXRoIGN3ZFxuICAgKiAgIENsaVdyYXBwZXItPj5DbGlXcmFwcGVyOiBjcmF3bChiYXNlUGF0aCwgY3Jhd2xMZXZlbHMpXG4gICAqICAgQ2xpV3JhcHBlci0tPj5DbGlXcmFwcGVyOiBtb2R1bGVzW11cbiAgICogICBsb29wIEZvciBlYWNoIG1vZHVsZVxuICAgKiAgICAgYWx0IE5vdCBAZGVjYWYtdHMvY2xpXG4gICAqICAgICAgIENsaVdyYXBwZXItPj5DbGlXcmFwcGVyOiBsb2FkKG1vZHVsZSwgY3dkKVxuICAgKiAgICAgICBDbGlXcmFwcGVyLS0+PkNsaVdyYXBwZXI6IG5hbWVcbiAgICogICAgICAgQ2xpV3JhcHBlci0+PkNsaVdyYXBwZXI6IENoZWNrIGlmIGNvbW1hbmQgZXhpc3RzXG4gICAqICAgICAgIGFsdCBDb21tYW5kIGRvZXNuJ3QgZXhpc3RcbiAgICogICAgICAgICBDbGlXcmFwcGVyLT4+Q29tbWFuZDogY29tbWFuZChuYW1lKS5hZGRDb21tYW5kKG1vZHVsZXNbbmFtZV0pXG4gICAqICAgICAgIGVuZFxuICAgKiAgICAgZW5kXG4gICAqICAgZW5kXG4gICAqICAgQ2xpV3JhcHBlci0+PkNvbnNvbGU6IExvZyBsb2FkZWQgbW9kdWxlc1xuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBib290KCkge1xuICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nLmZvcih0aGlzLmJvb3QpO1xuXG4gICAgY29uc3QgYmFzZVBhdGggPSBwYXRoLnJlc29sdmUodGhpcy5yb290UGF0aCwgdGhpcy5iYXNlUGF0aCk7XG4gICAgY29uc3QgbW9kdWxlcyA9IHRoaXMuY3Jhd2woYmFzZVBhdGgsIHRoaXMuY3Jhd2xMZXZlbHMpO1xuICAgIGxldCBzZXJ2ZXIgPSB0aGlzLm1jcDtcbiAgICBmb3IgKGNvbnN0IG1vZHVsZSBvZiBtb2R1bGVzKSB7XG4gICAgICBpZiAobW9kdWxlLmluY2x1ZGVzKFwiQGRlY2FmLXRzL21jcFwiKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMubG9hZChzZXJ2ZXIsIG1vZHVsZSk7XG4gICAgICAgIHNlcnZlciA9IHJlcy5tY3A7XG4gICAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICAgIGxvZy5lcnJvcihgRmFpbGVkIHRvIGxvYWQgTUNQIGNvbmZpZ3MgZm9yICR7bW9kdWxlfTogJHtlfWApO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zb2xlLmxvZyhcbiAgICAgIGBsb2FkZWQgbW9kdWxlczpcXG4ke09iamVjdC5rZXlzKHRoaXMubW9kdWxlcylcbiAgICAgICAgLm1hcCgoaykgPT4gYC0gJHtrfWApXG4gICAgICAgIC5qb2luKFwiXFxuXCIpfWBcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZWN1cnNpdmVseSBzZWFyY2hlcyBmb3IgQ0xJIG1vZHVsZSBmaWxlcyBpbiB0aGUgZGlyZWN0b3J5IHN0cnVjdHVyZVxuICAgKiBAc3VtbWFyeSBDcmF3bHMgdGhlIGJhc2VQYXRoIHVwIHRvIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIGZvbGRlciBsZXZlbHMgdG8gZmluZCBmaWxlcyBuYW1lZCBhY2NvcmRpbmcgdG8gQ0xJX0ZJTEVfTkFNRVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYmFzZVBhdGggVGhlIGFic29sdXRlIGJhc2UgcGF0aCB0byBzdGFydCBzZWFyY2hpbmcgaW5cbiAgICogQHBhcmFtIHtudW1iZXJ9IFtsZXZlbHM9Ml0gVGhlIG1heGltdW0gbnVtYmVyIG9mIGRpcmVjdG9yeSBsZXZlbHMgdG8gY3Jhd2xcbiAgICogQHJldHVybiB7c3RyaW5nW119IEFuIGFycmF5IG9mIGZpbGUgcGF0aHMgdG8gQ0xJIG1vZHVsZXNcbiAgICpcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgY3Jhd2woYmFzZVBhdGg6IHN0cmluZywgbGV2ZWxzOiBudW1iZXIgPSAyKSB7XG4gICAgaWYgKGxldmVscyA8PSAwKSByZXR1cm4gW107XG4gICAgcmV0dXJuIGZzLnJlYWRkaXJTeW5jKGJhc2VQYXRoKS5yZWR1Y2UoKGFjY3VtOiBzdHJpbmdbXSwgZmlsZSkgPT4ge1xuICAgICAgZmlsZSA9IHBhdGguam9pbihiYXNlUGF0aCwgZmlsZSk7XG4gICAgICBpZiAoZnMuc3RhdFN5bmMoZmlsZSkuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgICBhY2N1bS5wdXNoKC4uLnRoaXMuY3Jhd2woZmlsZSwgbGV2ZWxzIC0gMSkpO1xuICAgICAgfSBlbHNlIGlmIChmaWxlLm1hdGNoKG5ldyBSZWdFeHAoYCR7TUNQX0ZJTEVfTkFNRX0uW2NtXT9qcyRgLCBcImdtXCIpKSkge1xuICAgICAgICBhY2N1bS5wdXNoKGZpbGUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjY3VtO1xuICAgIH0sIFtdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRXhlY3V0ZXMgdGhlIENMSSB3aXRoIHRoZSBwcm92aWRlZCBhcmd1bWVudHNcbiAgICogQHN1bW1hcnkgQm9vdHMgdGhlIENMSSBieSBsb2FkaW5nIGFsbCBtb2R1bGVzLCB0aGVuIHBhcnNlcyBhbmQgZXhlY3V0ZXMgdGhlIGNvbW1hbmQgc3BlY2lmaWVkIGluIHRoZSBhcmd1bWVudHNcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gW2FyZ3M9cHJvY2Vzcy5hcmd2XSBDb21tYW5kIGxpbmUgYXJndW1lbnRzIHRvIHBhcnNlIGFuZCBleGVjdXRlXG4gICAqIEByZXR1cm4ge1Byb21pc2U8dm9pZD59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIGNvbW1hbmQgZXhlY3V0aW9uIGlzIGNvbXBsZXRlXG4gICAqXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICAgKiAgIHBhcnRpY2lwYW50IENsaVdyYXBwZXJcbiAgICogICBwYXJ0aWNpcGFudCBDb21tYW5kXG4gICAqXG4gICAqICAgQ2xpZW50LT4+Q2xpV3JhcHBlcjogcnVuKGFyZ3MpXG4gICAqICAgQ2xpV3JhcHBlci0+PkNsaVdyYXBwZXI6IGJvb3QoKVxuICAgKiAgIE5vdGUgb3ZlciBDbGlXcmFwcGVyOiBMb2FkcyBhbGwgbW9kdWxlc1xuICAgKiAgIENsaVdyYXBwZXItPj5Db21tYW5kOiBwYXJzZUFzeW5jKGFyZ3MpXG4gICAqICAgQ29tbWFuZC0tPj5DbGlXcmFwcGVyOiByZXN1bHRcbiAgICogICBDbGlXcmFwcGVyLS0+PkNsaWVudDogcmVzdWx0XG4gICAqL1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIGFzeW5jIHJ1bihhcmdzOiBzdHJpbmdbXSA9IHByb2Nlc3MuYXJndikge1xuICAgIGF3YWl0IHRoaXMuYm9vdCgpO1xuICB9XG59XG4iXSwibmFtZXMiOlsiVkVSU0lPTiIsIlBBQ0tBR0VfTkFNRSIsIk1ldGFkYXRhIiwieiIsImFwcGx5UGF0Y2giLCJjcmVhdGVUd29GaWxlc1BhdGNoIiwiUEtHIiwiViIsIkxvZ2dlZENsYXNzIiwiRmFzdE1DUCJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0lBRUE7Ozs7OztJQU1HO0lBQ0ksTUFBTUEsU0FBTyxHQUFHLGFBQWE7SUFDN0IsTUFBTUMsY0FBWSxHQUFHLGtCQUFrQjtJQUU5QyxJQUFJO0lBQ0YsSUFBQUMsbUJBQVEsQ0FBQyxlQUFlLENBQUNELGNBQVksRUFBRUQsU0FBTyxDQUFDO0lBQ2pEO0lBQUUsT0FBTyxLQUFLLEVBQUU7SUFDZCxJQUFBLElBQUksS0FBSyxZQUFZLEtBQUssSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsRUFBRTthQUUxRDtJQUNMLFFBQUEsTUFBTSxLQUFLOztJQUVmOztJQ05BLFNBQVMsWUFBWSxDQUFD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
|
|
2582
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWNwLXNlcnZlci5janMiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb25zdGFudHMudHMiLCIuLi9zcmMvbWNwL3dvcmtzcGFjZS50cyIsIi4uL3NyYy9tb2R1bGVzL2RlY29yYXRpb24vcHJvbXB0cy9pbmRleC50cyIsIi4uL3NyYy9tb2R1bGVzL2RlY29yYXRpb24vcmVzb3VyY2VzL2luZGV4LnRzIiwiLi4vc3JjL21vZHVsZXMvZGVjb3JhdGlvbi90ZW1wbGF0ZXMvaW5kZXgudHMiLCIuLi9zcmMvbWNwL3NjaGVtYXMudHMiLCIuLi9zcmMvbWNwL3V0aWxzLnRzIiwiLi4vc3JjL21jcC9jb2RlLnRzIiwiLi4vc3JjL21jcC90b29scy90b29scy50cyIsIi4uL3NyYy9tb2R1bGVzL2RlY29yYXRpb24vdG9vbHMvaW5kZXgudHMiLCIuLi9zcmMvbW9kdWxlcy9kZWNvcmF0aW9uL2luZGV4LnRzIiwiLi4vc3JjL21vZHVsZXMvbWNwL3Byb21wdHMvaW5kZXgudHMiLCIuLi9zcmMvbW9kdWxlcy9tY3AvcmVzb3VyY2VzL2luZGV4LnRzIiwiLi4vc3JjL21vZHVsZXMvbWNwL3RlbXBsYXRlcy9pbmRleC50cyIsIi4uL3NyYy9tb2R1bGVzL21jcC90b29scy9pbmRleC50cyIsIi4uL3NyYy9tb2R1bGVzL21jcC9pbmRleC50cyIsIi4uL3NyYy9tb2R1bGVzL190ZW1wbGF0ZS9wcm9tcHRzL2luZGV4LnRzIiwiLi4vc3JjL21vZHVsZXMvX3RlbXBsYXRlL3Jlc291cmNlcy9pbmRleC50cyIsIi4uL3NyYy9tb2R1bGVzL190ZW1wbGF0ZS90ZW1wbGF0ZXMvaW5kZXgudHMiLCIuLi9zcmMvbW9kdWxlcy9fdGVtcGxhdGUvdG9vbHMvaW5kZXgudHMiLCIuLi9zcmMvbW9kdWxlcy9fdGVtcGxhdGUvaW5kZXgudHMiLCIuLi9zcmMvbW9kdWxlcy9pbmRleC50cyIsIi4uL3NyYy9tY3AvbW9kdWxlUmVnaXN0cnkudHMiLCIuLi9zcmMvbWNwL3Byb21wdHMvcHJvbXB0cy50cyIsIi4uL3NyYy9tY3AvcHJvbXB0cy9pbmRleC50cyIsIi4uL3NyYy9tY3AvZGVjb3JhdG9yLXRvb2xzLnRzIiwiLi4vc3JjL21jcC90b29scy9jb2RleC10b29scy50cyIsIi4uL3NyYy9tY3AvdmFsaWRhdGlvbi9zY2FmZm9sZE1vZHVsZS50cyIsIi4uL3NyYy9tY3AvdG9vbHMvZ2VuZXJhdGVNY3BNb2R1bGUudHMiLCIuLi9zcmMvbWNwL3Rvb2xzL2luZGV4LnRzIiwiLi4vc3JjL21jcC9yZXNvdXJjZXMvcmVzb3VyY2VzLnRzIiwiLi4vc3JjL21jcC90ZW1wbGF0ZXMvY29kZXgtdGVtcGxhdGVzLnRzIiwiLi4vc3JjL21jcC90ZW1wbGF0ZXMvcmVzb3VyY2UtdGVtcGxhdGVzLnRzIiwiLi4vc3JjL21jcC90ZW1wbGF0ZXMvd29ya3NwYWNlLXRlbXBsYXRlcy50cyIsIi4uL3NyYy9tY3AvdGVtcGxhdGVzL2luZGV4LnRzIiwiLi4vc3JjL21ldGFkYXRhLnRzIiwiLi4vc3JjL21jcC9tY3AtbW9kdWxlLnRzIiwiLi4vc3JjL21jcC92YWxpZGF0aW9uL2luZGV4LnRzIiwiLi4vc3JjL21jcC9hZ2dyZWdhdGVNb2R1bGVzLnRzIiwiLi4vc3JjL21jcC9mYXN0bWNwLXdpcmluZy50cyIsIi4uL3NyYy9tY3AvaW5kZXgudHMiLCIuLi9zcmMvdXRpbHMvbW9kdWxlUGF0aHMudHMiLCIuLi9zcmMvdXRpbHMudHMiLCIuLi9zcmMvTWNwV3JhcHBlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBkZXNjcmlwdGlvbiBUaGUgZmlsZW5hbWUgdGhhdCBpZGVudGlmaWVzIERlY2FmIENMSSBtb2R1bGVzXG4gKiBAc3VtbWFyeSBUaGUgc3RhbmRhcmQgZmlsZW5hbWUgZm9yIENMSSBtb2R1bGUgZmlsZXMgd2hlcmUgZWFjaCBsaWJyYXJ5IG11c3QgZXhwb3J0IGEgc2luZ2xlIENsaU1vZHVsZSBmdW5jdGlvblxuICpcbiAqIEBjb25zdCBNQ1BfRklMRV9OQU1FXG4gKiBAbWVtYmVyT2YgbW9kdWxlOk1DUFxuICovXG5leHBvcnQgY29uc3QgTUNQX0ZJTEVfTkFNRSA9IFwibWNwLW1vZHVsZVwiO1xuXG5cbmV4cG9ydCBjb25zdCBXT1JLU1BBQ0VfUk9PVF9FTlYgPSBcIk1DUF9XT1JLU1BBQ0VfUk9PVFwiO1xuZXhwb3J0IGNvbnN0IFBST01QVF9ESVJFQ1RPUklFUyA9IFtcIi5jb2RlL3Byb21wdHNcIiwgXCIuY29kZXgvcHJvbXB0c1wiXTtcbmV4cG9ydCBjb25zdCBERUZBVUxUX1BST01QVF9OQU1FID0gXCJkb2NcIjtcbmV4cG9ydCBjb25zdCBDTElFTlRfSU5URUdSQVRJT05TID0gW1xuICB7XG4gICAgaWQ6IFwidnNjb2RlXCIsXG4gICAgZGlzcGxheTogXCJWaXN1YWwgU3R1ZGlvIENvZGVcIixcbiAgICBpbnN0cnVjdGlvbnM6XG4gICAgICBcIldoZW4gaW50ZXJhY3RpbmcgZnJvbSBWaXN1YWwgU3R1ZGlvIENvZGUsIHByZWZlciB0aGUgdnNjb2RlOi8vd29ya3NwYWNlL3twYXRofSByZXNvdXJjZSB0ZW1wbGF0ZSB0byBmZXRjaCBmaWxlIGNvbnRlbnRzIGFuZCB1c2UgdGhlIGFwcGx5LWNvZGUtY2hhbmdlIHRvb2wgdG8gY29tbWl0IGVkaXRzIHdpdGggcHJldmlld2FibGUgZGlmZnMuXCIsXG4gIH0sXG4gIHtcbiAgICBpZDogXCJjdXJzb3JcIixcbiAgICBkaXNwbGF5OiBcIkN1cnNvclwiLFxuICAgIGluc3RydWN0aW9uczpcbiAgICAgIFwiQ3Vyc29yIGNsaWVudHMgY2FuIHJldHJpZXZlIGFuZCB1cGRhdGUgZmlsZXMgdGhyb3VnaCB0aGUgY3Vyc29yOi8vd29ya3NwYWNlL3twYXRofSByZXNvdXJjZSB0ZW1wbGF0ZS4gQWx3YXlzIHZhbGlkYXRlIHBhdGNoZXMgaW4gZHJ5UnVuIG1vZGUgYmVmb3JlIGFwcGx5aW5nIHBlcm1hbmVudCBjaGFuZ2VzLlwiLFxuICB9LFxuICB7XG4gICAgaWQ6IFwiY29waWxvdFwiLFxuICAgIGRpc3BsYXk6IFwiR2l0SHViIENvcGlsb3RcIixcbiAgICBpbnN0cnVjdGlvbnM6XG4gICAgICBcIlVzZSB0aGUgY29waWxvdDovL3dvcmtzcGFjZS97cGF0aH0gcmVzb3VyY2UgdGVtcGxhdGUgdG8gc3RyZWFtIGZpbGUgY29udGVudCBpbnRvIENvcGlsb3QgY2hhdCBzZXNzaW9ucy4gUHJlZmVyIHJldHVybmluZyB1bmlmaWVkIGRpZmZzIHRvIG1haW50YWluIGFsaWdubWVudCB3aXRoIENvcGlsb3QncyBkaWZmIHZpc3VhbGl6YXRpb24uXCIsXG4gIH0sXG5dIGFzIGNvbnN0O1xuIiwiaW1wb3J0IGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IFdPUktTUEFDRV9ST09UX0VOViB9IGZyb20gXCIuLi9jb25zdGFudHNcIjtcblxubGV0IHdvcmtzcGFjZVJvb3QgPSBpbml0aWFsaXplV29ya3NwYWNlUm9vdCgpO1xubGV0IHVzZXJFcnJvckN0b3I6IChuZXcgKG1lc3NhZ2U6IHN0cmluZykgPT4gRXJyb3IpIHwgdW5kZWZpbmVkO1xuXG5leHBvcnQgY2xhc3MgV29ya3NwYWNlRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZykge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIHRoaXMubmFtZSA9IFwiV29ya3NwYWNlRXJyb3JcIjtcbiAgfVxufVxuXG5mdW5jdGlvbiBpbml0aWFsaXplV29ya3NwYWNlUm9vdCgpOiBzdHJpbmcge1xuICBjb25zdCBjb25maWd1cmVkID0gcHJvY2Vzcy5lbnZbV09SS1NQQUNFX1JPT1RfRU5WXTtcbiAgaWYgKGNvbmZpZ3VyZWQgJiYgY29uZmlndXJlZC50cmltKCkubGVuZ3RoID4gMCkge1xuICAgIHJldHVybiBwYXRoLnJlc29sdmUoY29uZmlndXJlZC50cmltKCkpO1xuICB9XG4gIHJldHVybiBwcm9jZXNzLmN3ZCgpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRVc2VyRXJyb3JDdG9yKCk6IFByb21pc2U8bmV3IChtZXNzYWdlOiBzdHJpbmcpID0+IEVycm9yPiB7XG4gIGlmICghdXNlckVycm9yQ3Rvcikge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBtb2QgPSBhd2FpdCBpbXBvcnQoXCJmYXN0bWNwXCIpO1xuICAgICAgdXNlckVycm9yQ3RvciA9IChtb2QgYXMgeyBVc2VyRXJyb3I6IG5ldyAobWVzc2FnZTogc3RyaW5nKSA9PiBFcnJvciB9KVxuICAgICAgICAuVXNlckVycm9yO1xuICAgIH0gY2F0Y2gge1xuICAgICAgdXNlckVycm9yQ3RvciA9IGNsYXNzIE1DUFVzZXJFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgICAgICAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nKSB7XG4gICAgICAgICAgc3VwZXIobWVzc2FnZSk7XG4gICAgICAgICAgdGhpcy5uYW1lID0gXCJNQ1BVc2VyRXJyb3JcIjtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHVzZXJFcnJvckN0b3I7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB0aHJvd1VzZXJFcnJvcihtZXNzYWdlOiBzdHJpbmcpOiBQcm9taXNlPG5ldmVyPiB7XG4gIGNvbnN0IEN0b3IgPSBhd2FpdCBnZXRVc2VyRXJyb3JDdG9yKCk7XG4gIHRocm93IG5ldyBDdG9yKG1lc3NhZ2UpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2V0V29ya3NwYWNlUm9vdChyb290OiBzdHJpbmcpIHtcbiAgd29ya3NwYWNlUm9vdCA9IHBhdGgucmVzb2x2ZShyb290KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFdvcmtzcGFjZVJvb3QoKTogc3RyaW5nIHtcbiAgcmV0dXJuIHdvcmtzcGFjZVJvb3Q7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlSW5Xb3Jrc3BhY2Uocm9vdDogc3RyaW5nLCB0YXJnZXRQYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCByZXNvbHZlZCA9IHBhdGguaXNBYnNvbHV0ZSh0YXJnZXRQYXRoKVxuICAgID8gcGF0aC5ub3JtYWxpemUodGFyZ2V0UGF0aClcbiAgICA6IHBhdGgucmVzb2x2ZShyb290LCB0YXJnZXRQYXRoKTtcblxuICBjb25zdCByZWxhdGl2ZSA9IHBhdGgucmVsYXRpdmUocm9vdCwgcmVzb2x2ZWQpO1xuICBpZiAocmVsYXRpdmUuc3RhcnRzV2l0aChcIi4uXCIpIHx8IHBhdGguaXNBYnNvbHV0ZShyZWxhdGl2ZSkpIHtcbiAgICB0aHJvdyBuZXcgV29ya3NwYWNlRXJyb3IoXG4gICAgICBgUGF0aCAke3RhcmdldFBhdGh9IGVzY2FwZXMgdGhlIHdvcmtzcGFjZSByb290IGF0ICR7cm9vdH1gXG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiByZXNvbHZlZDtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlYWRXb3Jrc3BhY2VGaWxlKFxuICByb290OiBzdHJpbmcsXG4gIHRhcmdldDogc3RyaW5nXG4pOiBQcm9taXNlPHN0cmluZz4ge1xuICB0cnkge1xuICAgIGNvbnN0IGFic29sdXRlID0gcmVzb2x2ZUluV29ya3NwYWNlKHJvb3QsIHRhcmdldCk7XG4gICAgcmV0dXJuIGZzLnJlYWRGaWxlU3luYyhhYnNvbHV0ZSwgXCJ1dGY4XCIgYXMgQnVmZmVyRW5jb2RpbmcpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFdvcmtzcGFjZUVycm9yKSB7XG4gICAgICBhd2FpdCB0aHJvd1VzZXJFcnJvcihlcnJvci5tZXNzYWdlKTtcbiAgICB9XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gX19yZXNldFdvcmtzcGFjZVJvb3Qocm9vdDogc3RyaW5nKSB7XG4gIHNldFdvcmtzcGFjZVJvb3Qocm9vdCk7XG59XG4iLCJleHBvcnQgY29uc3QgcHJvbXB0cyA9IFtdIGFzIGNvbnN0O1xuIiwiZXhwb3J0IGNvbnN0IHJlc291cmNlcyA9IFtcbiAge1xuICAgIFwiaWRcIjogXCJkZWNvcmF0aW9uLnJlcG9cIixcbiAgICBcIm5hbWVcIjogXCJkZWNvcmF0aW9uIHJlcG9zaXRvcnlcIixcbiAgICBcImRlc2NyaXB0aW9uXCI6IFwiU291cmNlIHJlcG9zaXRvcnlcIixcbiAgICBcInVyaVwiOiBcImZpbGU6Ly8vaG9tZS90dmVuY2VzbGF1L2xvY2FsLXdvcmtzcGFjZS9kZWNhZi10cy9tY3Atc2VydmVyL3NyYy9tb2R1bGVzL2RlY29yYXRpb25cIixcbiAgICBcImFic29sdXRlUGF0aFwiOiBcIi9ob21lL3R2ZW5jZXNsYXUvbG9jYWwtd29ya3NwYWNlL2RlY2FmLXRzL21jcC1zZXJ2ZXIvc3JjL21vZHVsZXMvZGVjb3JhdGlvblwiXG4gIH1cbl0gYXMgY29uc3Q7XG4iLCJleHBvcnQgY29uc3QgdGVtcGxhdGVzID0gW1xuICB7XG4gICAgXCJuYW1lXCI6IFwicmVhZG1lLXRlbXBsYXRlXCIsXG4gICAgXCJkZXNjcmlwdGlvblwiOiBcIlJFQURNRSBhcyBndWlkYW5jZVwiLFxuICAgIFwidXJpVGVtcGxhdGVcIjogXCJmaWxlOi8vL2hvbWUvdHZlbmNlc2xhdS9sb2NhbC13b3Jrc3BhY2UvZGVjYWYtdHMvbWNwLXNlcnZlci9zcmMvbW9kdWxlcy9kZWNvcmF0aW9uL1JFQURNRS5tZFwiLFxuICAgIFwibWltZVR5cGVcIjogXCJ0ZXh0L21hcmtkb3duXCJcbiAgfVxuXSBhcyBjb25zdDtcbiIsImltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5cbmV4cG9ydCBjb25zdCBhbmFseXplUmVwb1NjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgcmVwb1BhdGg6IHpcbiAgICAgIC5zdHJpbmcoKVxuICAgICAgLm1pbigxLCBcInJlcG9QYXRoIGlzIHJlcXVpcmVkXCIpXG4gICAgICAuZGVzY3JpYmUoXG4gICAgICAgIFwiUmVsYXRpdmUgb3IgYWJzb2x1dGUgcGF0aCB0byB0aGUgdGFyZ2V0IHJlcG9zaXRvcnkgaW5zaWRlIHRoaXMgbW9ub3JlcG8sIGUuZy4gJy4vZGVjb3JhdGlvbicuXCJcbiAgICAgICksXG4gICAgaW5jbHVkZVRlc3RzOiB6XG4gICAgICAuYm9vbGVhbigpXG4gICAgICAuZGVmYXVsdCh0cnVlKVxuICAgICAgLmRlc2NyaWJlKFxuICAgICAgICBcIklmIHRydWUsIGFuYWx5emUgdGhlIHRlc3RzIGRpcmVjdG9yeSAoaWYgcHJlc2VudCkgdG8gZGVyaXZlIGV4cGVjdGVkIGJlaGF2aW9ycy5cIlxuICAgICAgKSxcbiAgICBpbmNsdWRlRG9jczogelxuICAgICAgLmJvb2xlYW4oKVxuICAgICAgLmRlZmF1bHQodHJ1ZSlcbiAgICAgIC5kZXNjcmliZShcbiAgICAgICAgXCJJZiB0cnVlLCBhbmFseXplIFJFQURNRS5tZCBhbmQgZG9jcyBkaXJlY3RvcmllcyB0byBleHRyYWN0IGRvY3VtZW50ZWQgZmVhdHVyZXMuXCJcbiAgICAgICksXG4gIH0pXG4gIC5zdHJpY3QoKVxuICAuZGVzY3JpYmUoXG4gICAgXCJBbmFseXplIGEgbG9jYWwgcmVwb3NpdG9yeSAoZS5nLiAuL2RlY29yYXRpb24pIHRvIGV4dHJhY3QgQVBJcywgZmVhdHVyZXMsIHRlc3RzLCBhbmQgZG9jdW1lbnRhdGlvbiBjdWVzLlwiXG4gICk7XG5cbmV4cG9ydCBjb25zdCBlbnVtZXJhdGVDYXBhYmlsaXRpZXNTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIHJlcG9QYXRoOiB6XG4gICAgICAuc3RyaW5nKClcbiAgICAgIC5taW4oMSwgXCJyZXBvUGF0aCBpcyByZXF1aXJlZFwiKVxuICAgICAgLmRlc2NyaWJlKFxuICAgICAgICBcIlJlbGF0aXZlIG9yIGFic29sdXRlIHBhdGggdG8gdGhlIHRhcmdldCByZXBvc2l0b3J5IHRvIGVudW1lcmF0ZSBkZXZlbG9wZXItZmFjaW5nIGNhcGFiaWxpdGllcy5cIlxuICAgICAgKSxcbiAgfSlcbiAgLnN0cmljdCgpXG4gIC5kZXNjcmliZShcbiAgICBcIkVudW1lcmF0ZSB0aGUgY29tcGxldGUgc2V0IG9mIGNhcGFiaWxpdGllcyBhIGRldmVsb3BlciBpcyBleHBlY3RlZCB0byB1c2UgZnJvbSB0aGUgZ2l2ZW4gcmVwb3NpdG9yeS5cIlxuICApO1xuXG5leHBvcnQgY29uc3QgcGxhbkZlYXR1cmVTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIGZlYXR1cmU6IHpcbiAgICAgIC5zdHJpbmcoKVxuICAgICAgLm1pbig1LCBcImZlYXR1cmUgbXVzdCBkZXNjcmliZSB0aGUgZ29hbCBjbGVhcmx5XCIpXG4gICAgICAuZGVzY3JpYmUoXG4gICAgICAgIFwiTmF0dXJhbC1sYW5ndWFnZSBkZXNjcmlwdGlvbiBvZiBhIGRldmVsb3BlcidzIHJlcXVlc3RlZCBmZWF0dXJlIG9yIHRhc2sgdG8gaW1wbGVtZW50IHVzaW5nIHRoZSByZXBvc2l0b3J5IGFuZCBhdmFpbGFibGUgTUNQIHRvb2xzLlwiXG4gICAgICApLFxuICAgIHJlcG9QYXRoOiB6XG4gICAgICAuc3RyaW5nKClcbiAgICAgIC5kZWZhdWx0KFwiLi9kZWNvcmF0aW9uXCIpXG4gICAgICAuZGVzY3JpYmUoXG4gICAgICAgIFwiVGFyZ2V0IHJlcG9zaXRvcnkgcGF0aCBwcm92aWRpbmcgdGhlIGxpYnJhcnkgdG8gdXNlLCBlLmcuICcuL2RlY29yYXRpb24nLlwiXG4gICAgICApLFxuICB9KVxuICAuc3RyaWN0KClcbiAgLmRlc2NyaWJlKFxuICAgIFwiUGxhbiB3aGljaCBNQ1AgdG9vbHMgdG8gdXNlIGFuZCBpbiB3aGF0IHNlcXVlbmNlIHRvIGltcGxlbWVudCBhIHJlcXVlc3RlZCBmZWF0dXJlIHVzaW5nIHRoZSByZXBvc2l0b3J5LlwiXG4gICk7XG5cbmV4cG9ydCBjb25zdCBkb2N1bWVudENvZGVTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIGZpbGVQYXRoOiB6LnN0cmluZygpLm1pbigxLCBcImZpbGVQYXRoIGlzIHJlcXVpcmVkXCIpLFxuICAgIHByb21wdE5hbWU6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgICBpbmNsdWRlUHJvbXB0OiB6LmJvb2xlYW4oKS5kZWZhdWx0KHRydWUpLFxuICAgIGluY2x1ZGVDb2RlOiB6LmJvb2xlYW4oKS5kZWZhdWx0KHRydWUpLFxuICAgIGluY2x1ZGVNZXRhZGF0YTogei5ib29sZWFuKCkuZGVmYXVsdCh0cnVlKSxcbiAgICBhZGRpdGlvbmFsQ29udGV4dDogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICAgIGVuY29kaW5nOiB6LnN0cmluZygpLmRlZmF1bHQoXCJ1dGY4XCIpLFxuICB9KVxuICAuc3RyaWN0KCk7XG5cbmV4cG9ydCBjb25zdCBjb2RlQ2hhbmdlU2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICBmaWxlUGF0aDogei5zdHJpbmcoKS5taW4oMSwgXCJmaWxlUGF0aCBpcyByZXF1aXJlZFwiKSxcbiAgICBwYXRjaDogei5zdHJpbmcoKS5taW4oMSwgXCJwYXRjaCBpcyByZXF1aXJlZFwiKSxcbiAgICBkcnlSdW46IHouYm9vbGVhbigpLmRlZmF1bHQoZmFsc2UpLFxuICAgIHNob3dEaWZmOiB6LmJvb2xlYW4oKS5kZWZhdWx0KHRydWUpLFxuICAgIGRpZmZDb250ZXh0OiB6Lm51bWJlcigpLmludCgpLm1pbigwKS5tYXgoMTAwKS5kZWZhdWx0KDMpLFxuICAgIGVuY29kaW5nOiB6LnN0cmluZygpLmRlZmF1bHQoXCJ1dGY4XCIpLFxuICB9KVxuICAuc3RyaWN0KCk7XG5cbmNvbnN0IE9CSkVDVF9UWVBFUyA9IFtcbiAgXCJtb2R1bGVcIixcbiAgXCJmaWxlXCIsXG4gIFwiY2xhc3NcIixcbiAgXCJmdW5jdGlvblwiLFxuICBcImludGVyZmFjZVwiLFxuICBcImRlY29yYXRvclwiLFxuICBcImNvbnN0YW50XCIsXG5dIGFzIGNvbnN0O1xuXG5leHBvcnQgY29uc3QgZG9jdW1lbnRPYmplY3RTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIGJhc2VQYXRoOiB6LnN0cmluZygpLm1pbigxLCBcImJhc2VQYXRoIGlzIHJlcXVpcmVkXCIpLFxuICAgIG9iamVjdFR5cGU6IHouZW51bShPQkpFQ1RfVFlQRVMpLFxuICAgIHRhcmdldEZpbGU6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgICBpbmNsdWRlQ29udGVudDogei5ib29sZWFuKCkuZGVmYXVsdChmYWxzZSksXG4gIH0pXG4gIC5zdHJpY3QoKTtcblxuZXhwb3J0IGNvbnN0IGNvdmVyYWdlVGFza1NjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgYmFzZVBhdGg6IHouc3RyaW5nKCkubWluKDEsIFwiYmFzZVBhdGggaXMgcmVxdWlyZWRcIiksXG4gICAgY292ZXJhZ2U6IHpcbiAgICAgIC5udW1iZXIoKVxuICAgICAgLm1pbigwKVxuICAgICAgLm1heCgxMDApXG4gICAgICAuZGVmYXVsdCg5MClcbiAgICAgIC5kZXNjcmliZShcIlRhcmdldCBjb3ZlcmFnZSBwZXJjZW50YWdlXCIpLFxuICAgIGRyeVJ1bjogei5ib29sZWFuKCkuZGVmYXVsdChmYWxzZSksXG4gIH0pXG4gIC5zdHJpY3QoKTtcblxuZXhwb3J0IGNvbnN0IHJlYWRtZUltcHJvdmVtZW50U2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICBiYXNlUGF0aDogei5zdHJpbmcoKS5taW4oMSwgXCJiYXNlUGF0aCBpcyByZXF1aXJlZFwiKSxcbiAgICBpbmNsdWRlRXhhbXBsZXM6IHouYm9vbGVhbigpLmRlZmF1bHQodHJ1ZSksXG4gIH0pXG4gIC5zdHJpY3QoKTtcbiIsImltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBhbmFseXplUmVwbyB9IGZyb20gXCIuL2NvZGVcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIHJlYWRGaWxlU2FmZShcbiAgZmlsZVBhdGg6IHN0cmluZyxcbiAgZW5jb2Rpbmc6IEJ1ZmZlckVuY29kaW5nID0gXCJ1dGY4XCJcbik6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGZzLnJlYWRGaWxlU3luYyhmaWxlUGF0aCwgeyBlbmNvZGluZyB9KTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gbGlzdEZpbGVzUmVjdXJzaXZlKFxuICByb290OiBzdHJpbmcsXG4gIG1hdGNoZXI/OiAocDogc3RyaW5nKSA9PiBib29sZWFuXG4pOiBzdHJpbmdbXSB7XG4gIGNvbnN0IG91dDogc3RyaW5nW10gPSBbXTtcbiAgY29uc3Qgc3RhY2s6IHN0cmluZ1tdID0gW3Jvb3RdO1xuICB3aGlsZSAoc3RhY2subGVuZ3RoKSB7XG4gICAgY29uc3QgY3VyID0gc3RhY2sucG9wKCkhO1xuICAgIGNvbnN0IHN0YXQgPSBmcy5zdGF0U3luYyhjdXIpO1xuICAgIGlmIChzdGF0LmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgIGZvciAoY29uc3QgZiBvZiBmcy5yZWFkZGlyU3luYyhjdXIpKSBzdGFjay5wdXNoKHBhdGguam9pbihjdXIsIGYpKTtcbiAgICB9IGVsc2UgaWYgKCFtYXRjaGVyIHx8IG1hdGNoZXIoY3VyKSkge1xuICAgICAgb3V0LnB1c2goY3VyKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG91dC5zb3J0KCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkZXJpdmVDYXBhYmlsaXRpZXMoXG4gIGFuYWx5c2lzOiBSZXR1cm5UeXBlPHR5cGVvZiBhbmFseXplUmVwbz5cbik6IHN0cmluZ1tdIHtcbiAgY29uc3QgY2FwID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIC8vIGhldXJpc3RpY3M6IGlmIGRlY29yYXRvcnMgbGlrZSBEZWNvcmF0aW9uLCBmbGF2b3VyZWRBcywgZXh0ZW5kLCBvdmVycmlkZSBhcHBlYXIsIGFkZCBjYXBhYmlsaXRpZXNcbiAgY29uc3QgYWxsRGVjcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBmb3IgKGNvbnN0IGsgb2YgT2JqZWN0LmtleXMoYW5hbHlzaXMuYXBpKSkge1xuICAgIGZvciAoY29uc3QgZCBvZiBhbmFseXNpcy5hcGlba10uZGVjb3JhdG9ycykgYWxsRGVjcy5hZGQoZCk7XG4gICAgZm9yIChjb25zdCBlIG9mIGFuYWx5c2lzLmFwaVtrXS5leHBvcnRzKVxuICAgICAgaWYgKC9EZWNvcmF0aW9ufGRlY29yYXRlfEJ1aWxkZXJ8Rmxhdm91ci9pLnRlc3QoZSkpXG4gICAgICAgIGNhcC5hZGQoXCJ1c2UtZGVjb3JhdGlvbi1hcGlcIik7XG4gIH1cbiAgaWYgKFsuLi5hbGxEZWNzXS5zb21lKChkKSA9PiAvb3ZlcnJpZGV8ZXh0ZW5kL2kudGVzdChkKSkpXG4gICAgY2FwLmFkZChcIm92ZXJyaWRlLWFuZC1leHRlbmQtZGVjb3JhdGlvbnNcIik7XG4gIGlmIChPYmplY3Qua2V5cyhhbmFseXNpcy50ZXN0cykubGVuZ3RoID4gMCkgY2FwLmFkZChcInZhbGlkYXRlLXdpdGgtdGVzdHNcIik7XG4gIGlmIChhbmFseXNpcy5yZWFkbWUpIGNhcC5hZGQoXCJmb2xsb3ctcmVhZG1lLWd1aWRlc1wiKTtcbiAgcmV0dXJuIFsuLi5jYXBdLnNvcnQoKTtcbn1cbiIsIi8vIEFuYWx5c2lzIGhlbHBlcnMgKG1pbmltYWwgeWV0IGVmZmVjdGl2ZSwgdGV4dC1iYXNlZCB0byBhdm9pZCBoZWF2eSBBU1QgZGVwcylcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgeyBsaXN0RmlsZXNSZWN1cnNpdmUsIHJlYWRGaWxlU2FmZSB9IGZyb20gXCIuL3V0aWxzXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1NvdXJjZUZpbGUocDogc3RyaW5nKSB7XG4gIHJldHVybiAvXFwuKHRzfHRzeHxqc3xqc3gpJC8udGVzdChwKSAmJiAhcC5lbmRzV2l0aChcIi5kLnRzXCIpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGlzVGVzdEZpbGUocDogc3RyaW5nKSB7XG4gIHJldHVybiAvKFxcLnRlc3RcXC58XFwuc3BlY1xcLikvLnRlc3QocCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBleHRyYWN0RXhwb3J0cyhmaWxlQ29udGVudDogc3RyaW5nKTogc3RyaW5nW10ge1xuICBjb25zdCBuYW1lcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBjb25zdCBleHBvcnRSZSA9XG4gICAgLyhleHBvcnRcXHMrKD86ZGVmYXVsdFxccyspPyg/OmNsYXNzfGZ1bmN0aW9ufGNvbnN0fGxldHx2YXJ8aW50ZXJmYWNlfHR5cGV8ZW51bSlcXHMrKShbQS1aYS16MC05X10rKS9nO1xuICBjb25zdCBuYW1lZFJlID0gL2V4cG9ydFxccypcXHsoW159XSspXFx9L2c7XG4gIGxldCBtOiBSZWdFeHBFeGVjQXJyYXkgfCBudWxsO1xuICB3aGlsZSAoKG0gPSBleHBvcnRSZS5leGVjKGZpbGVDb250ZW50KSkpIG5hbWVzLmFkZChtWzJdKTtcbiAgd2hpbGUgKChtID0gbmFtZWRSZS5leGVjKGZpbGVDb250ZW50KSkpIHtcbiAgICBtWzFdXG4gICAgICAuc3BsaXQoXCIsXCIpXG4gICAgICAubWFwKChzKSA9PiBzLnRyaW0oKS5zcGxpdChcIiBhcyBcIilbMF0udHJpbSgpKVxuICAgICAgLmZvckVhY2goKG4pID0+IHtcbiAgICAgICAgaWYgKG4pIG5hbWVzLmFkZChuKTtcbiAgICAgIH0pO1xuICB9XG4gIHJldHVybiBbLi4ubmFtZXNdLnNvcnQoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGV4dHJhY3REZWNvcmF0b3JzKGZpbGVDb250ZW50OiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gIGNvbnN0IGRlY3MgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgY29uc3QgZGVjUmUgPSAvQChbQS1aYS16X11bQS1aYS16MC05X10qKS9nO1xuICBsZXQgbTogUmVnRXhwRXhlY0FycmF5IHwgbnVsbDtcbiAgd2hpbGUgKChtID0gZGVjUmUuZXhlYyhmaWxlQ29udGVudCkpKSBkZWNzLmFkZChtWzFdKTtcbiAgcmV0dXJuIFsuLi5kZWNzXS5zb3J0KCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzdW1tYXJpemVSZWFkbWUocmVhZG1lPzogc3RyaW5nKSB7XG4gIGlmICghcmVhZG1lKSByZXR1cm4gdW5kZWZpbmVkO1xuICBjb25zdCBsaW5lcyA9IHJlYWRtZS5zcGxpdCgvXFxyP1xcbi8pLmZpbHRlcihCb29sZWFuKTtcbiAgY29uc3QgdGl0bGUgPVxuICAgIGxpbmVzLmZpbmQoKGwpID0+IC9eI1xccysvLnRlc3QobCkpPy5yZXBsYWNlKC9eI1xccysvLCBcIlwiKSB8fCBcIlJFQURNRVwiO1xuICBjb25zdCBidWxsZXRzID0gbGluZXMuZmlsdGVyKChsKSA9PiAvXlstKl1cXHMrLy50ZXN0KGwpKS5zbGljZSgwLCAyMCk7XG4gIHJldHVybiB7IHRpdGxlLCBidWxsZXRzIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhbmFseXplUmVwbyhyb290OiBzdHJpbmcpIHtcbiAgY29uc3Qgc3JjID0gcGF0aC5qb2luKHJvb3QsIFwic3JjXCIpO1xuICBjb25zdCB0ZXN0RGlyID0gcGF0aC5qb2luKHJvb3QsIFwidGVzdHNcIik7XG4gIGNvbnN0IHJlYWRtZVBhdGggPSBwYXRoLmpvaW4ocm9vdCwgXCJSRUFETUUubWRcIik7XG4gIGNvbnN0IHJlYWRtZSA9IHJlYWRGaWxlU2FmZShyZWFkbWVQYXRoKTtcblxuICBjb25zdCBmaWxlcyA9IGZzLmV4aXN0c1N5bmMoc3JjKSA/IGxpc3RGaWxlc1JlY3Vyc2l2ZShzcmMsIGlzU291cmNlRmlsZSkgOiBbXTtcbiAgY29uc3QgdGVzdEZpbGVzID0gZnMuZXhpc3RzU3luYyh0ZXN0RGlyKVxuICAgID8gbGlzdEZpbGVzUmVjdXJzaXZlKHRlc3REaXIsIChmKSA9PiBpc1NvdXJjZUZpbGUoZikgJiYgaXNUZXN0RmlsZShmKSlcbiAgICA6IFtdO1xuXG4gIGNvbnN0IGFwaTogUmVjb3JkPHN0cmluZywgeyBleHBvcnRzOiBzdHJpbmdbXTsgZGVjb3JhdG9yczogc3RyaW5nW10gfT4gPSB7fTtcbiAgZm9yIChjb25zdCBmIG9mIGZpbGVzKSB7XG4gICAgY29uc3QgY29udGVudCA9IHJlYWRGaWxlU2FmZShmKSB8fCBcIlwiO1xuICAgIGFwaVtwYXRoLnJlbGF0aXZlKHJvb3QsIGYpXSA9IHtcbiAgICAgIGV4cG9ydHM6IGV4dHJhY3RFeHBvcnRzKGNvbnRlbnQpLFxuICAgICAgZGVjb3JhdG9yczogZXh0cmFjdERlY29yYXRvcnMoY29udGVudCksXG4gICAgfTtcbiAgfVxuICBjb25zdCB0ZXN0czogUmVjb3JkPHN0cmluZywgeyBtZW50aW9uczogc3RyaW5nW10gfT4gPSB7fTtcbiAgZm9yIChjb25zdCBmIG9mIHRlc3RGaWxlcykge1xuICAgIGNvbnN0IGNvbnRlbnQgPSByZWFkRmlsZVNhZmUoZikgfHwgXCJcIjtcbiAgICBjb25zdCBtZW50aW9ucyA9IEFycmF5LmZyb20oXG4gICAgICBuZXcgU2V0KFsuLi5leHRyYWN0RXhwb3J0cyhjb250ZW50KSwgLi4uZXh0cmFjdERlY29yYXRvcnMoY29udGVudCldKVxuICAgICkuc29ydCgpO1xuICAgIHRlc3RzW3BhdGgucmVsYXRpdmUocm9vdCwgZildID0geyBtZW50aW9ucyB9O1xuICB9XG4gIHJldHVybiB7IGZpbGVzLCB0ZXN0RmlsZXMsIGFwaSwgdGVzdHMsIHJlYWRtZTogc3VtbWFyaXplUmVhZG1lKHJlYWRtZSkgfTtcbn1cbiIsImltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBDb250ZW50UmVzdWx0LCBUb29sIH0gZnJvbSBcImZhc3RtY3BcIjtcbmltcG9ydCB7IGFwcGx5UGF0Y2gsIGNyZWF0ZVR3b0ZpbGVzUGF0Y2ggfSBmcm9tIFwiZGlmZlwiO1xuaW1wb3J0IHtcbiAgYW5hbHl6ZVJlcG9TY2hlbWEsXG4gIGNvZGVDaGFuZ2VTY2hlbWEsXG4gIGRvY3VtZW50Q29kZVNjaGVtYSxcbiAgZW51bWVyYXRlQ2FwYWJpbGl0aWVzU2NoZW1hLFxuICBwbGFuRmVhdHVyZVNjaGVtYSxcbn0gZnJvbSBcIi4uL3NjaGVtYXNcIjtcbmltcG9ydCB7IGFuYWx5emVSZXBvIH0gZnJvbSBcIi4uL2NvZGVcIjtcbmltcG9ydCB7IGRlcml2ZUNhcGFiaWxpdGllcyB9IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IHtcbiAgZ2V0V29ya3NwYWNlUm9vdCxcbiAgcmVzb2x2ZUluV29ya3NwYWNlLFxuICB0aHJvd1VzZXJFcnJvcixcbiAgV29ya3NwYWNlRXJyb3IsXG59IGZyb20gXCIuLi93b3Jrc3BhY2VcIjtcbmltcG9ydCB7XG4gIGJ1aWxkRG9jdW1lbnRhdGlvblBheWxvYWQsXG4gIERFRkFVTFRfUFJPTVBUX05BTUUsXG4gIGRpc2NvdmVyRG9jUHJvbXB0cyxcbiAgc2VsZWN0UHJvbXB0LFxufSBmcm9tIFwiLi4vcHJvbXB0cy9wcm9tcHRzXCI7XG5pbXBvcnQgdHlwZSB7IEFwcGx5Q29kZUNoYW5nZUFyZ3MsIERvY3VtZW50Q29kZUFyZ3MgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IGdlbmVyYXRlTWNwTW9kdWxlVG9vbCB9IGZyb20gXCIuL2dlbmVyYXRlTWNwTW9kdWxlXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZEFuYWx5emVSZXBvc2l0b3J5VG9vbCgpOiBUb29sPFxuICB1bmRlZmluZWQsXG4gIHR5cGVvZiBhbmFseXplUmVwb1NjaGVtYVxuPiB7XG4gIHJldHVybiB7XG4gICAgbmFtZTogXCJhbmFseXplLXJlcG9zaXRvcnlcIixcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgIFwiQW5hbHl6ZSBhIGxvY2FsIHJlcG9zaXRvcnkncyBzb3VyY2UsIHRlc3RzLCBhbmQgZG9jcyB0byBleHRyYWN0IGV4cG9ydGVkIEFQSXMsIGRlY29yYXRvcnMsIGFuZCB0ZXN0IG1lbnRpb25zLlwiLFxuICAgIHBhcmFtZXRlcnM6IGFuYWx5emVSZXBvU2NoZW1hLFxuICAgIGV4ZWN1dGU6IGFzeW5jIChpbnB1dCkgPT4ge1xuICAgICAgbGV0IHJlcG9Sb290ID0gcGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksIGlucHV0LnJlcG9QYXRoKTtcbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyhyZXBvUm9vdCkpIHtcbiAgICAgICAgLy8gdHJ5IHJlc29sdmluZyBmcm9tIG1vbm9yZXBvIHJvb3QgKHBhcmVudCBvZiBjdXJyZW50IGN3ZClcbiAgICAgICAgY29uc3QgYWx0ID0gcGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksIFwiLi5cIiwgaW5wdXQucmVwb1BhdGgpO1xuICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhhbHQpKSByZXBvUm9vdCA9IGFsdDtcbiAgICAgIH1cbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyhyZXBvUm9vdCkpIHtcbiAgICAgICAgLy8gaWYgaW5wdXQgd2FzIGFic29sdXRlIGFuZCBzdGlsbCBub3QgZm91bmQsIHRyeSAuLi88YmFzZW5hbWU+XG4gICAgICAgIGNvbnN0IGFsdDIgPSBwYXRoLnJlc29sdmUoXG4gICAgICAgICAgcHJvY2Vzcy5jd2QoKSxcbiAgICAgICAgICBcIi4uXCIsXG4gICAgICAgICAgcGF0aC5iYXNlbmFtZShpbnB1dC5yZXBvUGF0aClcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKGZzLmV4aXN0c1N5bmMoYWx0MikpIHJlcG9Sb290ID0gYWx0MjtcbiAgICAgIH1cbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyhyZXBvUm9vdCkpXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgUmVwb3NpdG9yeSBub3QgZm91bmQgYXQgJHtyZXBvUm9vdH1gKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGFuYWx5emVSZXBvKHJlcG9Sb290KTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFt7IHR5cGU6IFwidGV4dFwiLCB0ZXh0OiBKU09OLnN0cmluZ2lmeShyZXN1bHQsIG51bGwsIDIpIH1dLFxuICAgICAgfTtcbiAgICB9LFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRFbnVtZXJhdGVDYXBhYmlsaXRpZXNUb29sKCk6IFRvb2w8XG4gIHVuZGVmaW5lZCxcbiAgdHlwZW9mIGVudW1lcmF0ZUNhcGFiaWxpdGllc1NjaGVtYVxuPiB7XG4gIHJldHVybiB7XG4gICAgbmFtZTogXCJlbnVtZXJhdGUtY2FwYWJpbGl0aWVzXCIsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICBcIkVudW1lcmF0ZSBkZXZlbG9wZXItZmFjaW5nIGNhcGFiaWxpdGllcyBvZiB0aGUgZ2l2ZW4gcmVwb3NpdG9yeSwgaW5mZXJyZWQgZnJvbSBjb2RlLCB0ZXN0cywgYW5kIGRvY3MuXCIsXG4gICAgcGFyYW1ldGVyczogZW51bWVyYXRlQ2FwYWJpbGl0aWVzU2NoZW1hLFxuICAgIGV4ZWN1dGU6IGFzeW5jIChpbnB1dCkgPT4ge1xuICAgICAgbGV0IHJlcG9Sb290ID0gcGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksIGlucHV0LnJlcG9QYXRoKTtcbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyhyZXBvUm9vdCkpIHtcbiAgICAgICAgY29uc3QgYWx0ID0gcGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksIFwiLi5cIiwgaW5wdXQucmVwb1BhdGgpO1xuICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhhbHQpKSByZXBvUm9vdCA9IGFsdDtcbiAgICAgIH1cbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyhyZXBvUm9vdCkpIHtcbiAgICAgICAgY29uc3QgYWx0MiA9IHBhdGgucmVzb2x2ZShcbiAgICAgICAgICBwcm9jZXNzLmN3ZCgpLFxuICAgICAgICAgIFwiLi5cIixcbiAgICAgICAgICBwYXRoLmJhc2VuYW1lKGlucHV0LnJlcG9QYXRoKVxuICAgICAgICApO1xuICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhhbHQyKSkgcmVwb1Jvb3QgPSBhbHQyO1xuICAgICAgfVxuICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKHJlcG9Sb290KSlcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBSZXBvc2l0b3J5IG5vdCBmb3VuZCBhdCAke3JlcG9Sb290fWApO1xuICAgICAgY29uc3QgYW5hbHlzaXMgPSBhbmFseXplUmVwbyhyZXBvUm9vdCk7XG4gICAgICBjb25zdCBjYXBhYmlsaXRpZXMgPSBkZXJpdmVDYXBhYmlsaXRpZXMoYW5hbHlzaXMpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgdGV4dDogSlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBjYXBhYmlsaXRpZXMsXG4gICAgICAgICAgICAgICAgYW5hbHlzaXNTdW1tYXJ5OiB7XG4gICAgICAgICAgICAgICAgICBmaWxlczogYW5hbHlzaXMuZmlsZXMubGVuZ3RoLFxuICAgICAgICAgICAgICAgICAgdGVzdEZpbGVzOiBhbmFseXNpcy50ZXN0RmlsZXMubGVuZ3RoLFxuICAgICAgICAgICAgICAgICAgcmVhZG1lOiBhbmFseXNpcy5yZWFkbWU/LnRpdGxlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgIDJcbiAgICAgICAgICAgICksXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgfSxcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkUGxhbkZlYXR1cmVUb29sKCk6IFRvb2w8XG4gIHVuZGVmaW5lZCxcbiAgdHlwZW9mIHBsYW5GZWF0dXJlU2NoZW1hXG4+IHtcbiAgcmV0dXJuIHtcbiAgICBuYW1lOiBcInBsYW4tZmVhdHVyZS1pbXBsZW1lbnRhdGlvblwiLFxuICAgIGRlc2NyaXB0aW9uOlxuICAgICAgXCJHaXZlbiBhIGZlYXR1cmUgcmVxdWVzdCwgc2VsZWN0IGFwcHJvcHJpYXRlIE1DUCB0b29scyAoaW5jbHVkaW5nIGV4aXN0aW5nIGFuZCBuZXcgb25lcykgYW5kIHByb2R1Y2UgYW4gZXhlY3V0aW9uIHBsYW4uXCIsXG4gICAgcGFyYW1ldGVyczogcGxhbkZlYXR1cmVTY2hlbWEsXG4gICAgZXhlY3V0ZTogYXN5bmMgKGlucHV0KSA9PiB7XG4gICAgICBjb25zdCBzdGVwczogQXJyYXk8e1xuICAgICAgICBzdGVwOiBudW1iZXI7XG4gICAgICAgIGFjdGlvbjogc3RyaW5nO1xuICAgICAgICB0b29sPzogc3RyaW5nO1xuICAgICAgICBhcmd1bWVudHM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuICAgICAgICByYXRpb25hbGU6IHN0cmluZztcbiAgICAgIH0+ID0gW107XG4gICAgICBsZXQgaSA9IDE7XG4gICAgICBzdGVwcy5wdXNoKHtcbiAgICAgICAgc3RlcDogaSsrLFxuICAgICAgICBhY3Rpb246IFwiQW5hbHl6ZSByZXBvc2l0b3J5IHRvIGVudW1lcmF0ZSBBUElzIGFuZCBkZWNvcmF0b3JzXCIsXG4gICAgICAgIHRvb2w6IFwiYW5hbHl6ZS1yZXBvc2l0b3J5XCIsXG4gICAgICAgIGFyZ3VtZW50czogeyByZXBvUGF0aDogaW5wdXQucmVwb1BhdGggfSxcbiAgICAgICAgcmF0aW9uYWxlOiBcIlVuZGVyc3RhbmQgYXZhaWxhYmxlIGJ1aWxkaW5nIGJsb2Nrcy5cIixcbiAgICAgIH0pO1xuICAgICAgc3RlcHMucHVzaCh7XG4gICAgICAgIHN0ZXA6IGkrKyxcbiAgICAgICAgYWN0aW9uOiBcIkxpc3QgY2FwYWJpbGl0aWVzIGV4cGVjdGVkIGZvciBkZXZlbG9wZXJzXCIsXG4gICAgICAgIHRvb2w6IFwiZW51bWVyYXRlLWNhcGFiaWxpdGllc1wiLFxuICAgICAgICBhcmd1bWVudHM6IHsgcmVwb1BhdGg6IGlucHV0LnJlcG9QYXRoIH0sXG4gICAgICAgIHJhdGlvbmFsZTogXCJBbGlnbiB0aGUgcGxhbiB3aXRoIHN1cHBvcnRlZCBjYXBhYmlsaXRpZXMuXCIsXG4gICAgICB9KTtcbiAgICAgIC8vIFN1Z2dlc3QgZXhpc3RpbmcgZ2VuZXJpYyB0b29scyBmcm9tIG1jcC1tb2R1bGVcbiAgICAgIHN0ZXBzLnB1c2goe1xuICAgICAgICBzdGVwOiBpKyssXG4gICAgICAgIGFjdGlvbjpcbiAgICAgICAgICBcIlNlbGVjdCBkb2N1bWVudGF0aW9uIHByb21wdCBhbmQgZ2F0aGVyIHJlbGV2YW50IHNvdXJjZSBmaWxlKHMpXCIsXG4gICAgICAgIHRvb2w6IFwiZG9jdW1lbnQtY29kZVwiLFxuICAgICAgICBhcmd1bWVudHM6IHsgZmlsZVBhdGg6IFwiPHRhcmdldC1maWxlPlwiIH0sXG4gICAgICAgIHJhdGlvbmFsZTogXCJQcm92aWRlIGNvbnRleHQgYW5kIGluc3RydWN0aW9ucyBmb3IgY2hhbmdlcy5cIixcbiAgICAgIH0pO1xuICAgICAgc3RlcHMucHVzaCh7XG4gICAgICAgIHN0ZXA6IGkrKyxcbiAgICAgICAgYWN0aW9uOiBcIkFwcGx5IGNvZGUgY2hhbmdlcyB1c2luZyB1bmlmaWVkIGRpZmYgcGF0Y2hcIixcbiAgICAgICAgdG9vbDogXCJhcHBseS1jb2RlLWNoYW5nZVwiLFxuICAgICAgICBhcmd1bWVudHM6IHtcbiAgICAgICAgICBmaWxlUGF0aDogXCI8dGFyZ2V0LWZpbGU+XCIsXG4gICAgICAgICAgcGF0Y2g6IFwiPHVuaWZpZWQtZGlmZj5cIixcbiAgICAgICAgICBkcnlSdW46IHRydWUsXG4gICAgICAgIH0sXG4gICAgICAgIHJhdGlvbmFsZTogXCJWYWxpZGF0ZSBjaGFuZ2VzIHNhZmVseSBiZWZvcmUgY29tbWl0dGluZy5cIixcbiAgICAgIH0pO1xuICAgICAgc3RlcHMucHVzaCh7XG4gICAgICAgIHN0ZXA6IGkrKyxcbiAgICAgICAgYWN0aW9uOiBcIkNvbW1pdCBjb2RlIGNoYW5nZXNcIixcbiAgICAgICAgdG9vbDogXCJhcHBseS1jb2RlLWNoYW5nZVwiLFxuICAgICAgICBhcmd1bWVudHM6IHtcbiAgICAgICAgICBmaWxlUGF0aDogXCI8dGFyZ2V0LWZpbGU+XCIsXG4gICAgICAgICAgcGF0Y2g6IFwiPHVuaWZpZWQtZGlmZj5cIixcbiAgICAgICAgICBkcnlSdW46IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgICByYXRpb25hbGU6IFwiUGVyc2lzdCB0aGUgdXBkYXRlLlwiLFxuICAgICAgfSk7XG4gICAgICAvLyBJZiBkZWNvcmF0aW9uLXJlbGF0ZWQgdGVybXMgcHJlc2VudCwgc3VnZ2VzdCBkZWNvcmF0b3IgdG9vbHNcbiAgICAgIGlmICgvZGVjb3JhdHxmbGF2b3VyfG92ZXJyaWRlfGV4dGVuZHxidWlsZGVyL2kudGVzdChpbnB1dC5mZWF0dXJlKSkge1xuICAgICAgICBzdGVwcy51bnNoaWZ0KHtcbiAgICAgICAgICBzdGVwOiAwLFxuICAgICAgICAgIGFjdGlvbjogXCJVc2UgZGVjb3JhdG9yIHRvb2xpbmcgdG8gaW5zZXJ0L3JlbW92ZS9tb2RpZnkgZGVjb3JhdG9yc1wiLFxuICAgICAgICAgIHRvb2w6IFwiZGVjb3JhdG9yLXRvb2xzXCIsXG4gICAgICAgICAgYXJndW1lbnRzOiB7IGFjdGlvbjogXCJoZWxwXCIgfSxcbiAgICAgICAgICByYXRpb25hbGU6IFwiTGV2ZXJhZ2Ugc3BlY2lhbGl6ZWQgdXRpbGl0aWVzIGZvciBkZWNvcmF0aW9uIHBhdHRlcm5zLlwiLFxuICAgICAgICB9KTtcbiAgICAgICAgc3RlcHMuZm9yRWFjaCgocywgaWR4KSA9PiAocy5zdGVwID0gaWR4ICsgMSkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgdGV4dDogSlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBwbGFuOiBzdGVwcyxcbiAgICAgICAgICAgICAgICBub3RlczpcbiAgICAgICAgICAgICAgICAgIFwiUmVwbGFjZSBwbGFjZWhvbGRlciBhcmd1bWVudHMgbGlrZSA8dGFyZ2V0LWZpbGU+IGFuZCA8dW5pZmllZC1kaWZmPiBiYXNlZCBvbiB0aGUgYW5hbHlzaXMgb3V0cHV0LlwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAyXG4gICAgICAgICAgICApLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgIH0sXG4gIH07XG59XG5cbmV4cG9ydCBjb25zdCBkb2N1bWVudENvZGVUb29sOiBUb29sPHVuZGVmaW5lZCwgdHlwZW9mIGRvY3VtZW50Q29kZVNjaGVtYT4gPSB7XG4gIGFubm90YXRpb25zOiB7XG4gICAgaWRlbXBvdGVudEhpbnQ6IHRydWUsXG4gICAgb3BlbldvcmxkSGludDogZmFsc2UsXG4gICAgcmVhZE9ubHlIaW50OiB0cnVlLFxuICAgIHRpdGxlOiBcIkRvY3VtZW50IFNvdXJjZSBGaWxlXCIsXG4gIH0sXG4gIGRlc2NyaXB0aW9uOlxuICAgIFwiR2VuZXJhdGUgZG9jdW1lbnRhdGlvbiBndWlkYW5jZSBmb3IgYSBmaWxlIGJ5IGNvbWJpbmluZyByZXBvc2l0b3J5IHByb21wdHMgd2l0aCB0aGUgdGFyZ2V0IHNvdXJjZSBjb2RlLlwiLFxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIGV4ZWN1dGU6IGFzeW5jIChpbnB1dCwgX2NvbnRleHQpOiBQcm9taXNlPENvbnRlbnRSZXN1bHQ+ID0+IHtcbiAgICBjb25zdCBhcmdzID0gZG9jdW1lbnRDb2RlU2NoZW1hLnBhcnNlKGlucHV0IGFzIERvY3VtZW50Q29kZUFyZ3MpO1xuICAgIGNvbnN0IHJvb3QgPSBnZXRXb3Jrc3BhY2VSb290KCk7XG4gICAgbGV0IGZpbGVQYXRoOiBzdHJpbmc7XG4gICAgdHJ5IHtcbiAgICAgIGZpbGVQYXRoID0gcmVzb2x2ZUluV29ya3NwYWNlKHJvb3QsIGFyZ3MuZmlsZVBhdGgpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBXb3Jrc3BhY2VFcnJvcikge1xuICAgICAgICByZXR1cm4gdGhyb3dVc2VyRXJyb3IoZXJyb3IubWVzc2FnZSk7XG4gICAgICB9XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuXG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKGZpbGVQYXRoKSkge1xuICAgICAgcmV0dXJuIHRocm93VXNlckVycm9yKGBDYW5ub3QgZG9jdW1lbnQgbWlzc2luZyBmaWxlIGF0ICR7YXJncy5maWxlUGF0aH1gKTtcbiAgICB9XG5cbiAgICBjb25zdCBmaWxlQ29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhmaWxlUGF0aCwge1xuICAgICAgZW5jb2Rpbmc6IGFyZ3MuZW5jb2RpbmcgYXMgQnVmZmVyRW5jb2RpbmcsXG4gICAgfSk7XG4gICAgY29uc3QgcHJvbXB0cyA9IGRpc2NvdmVyRG9jUHJvbXB0cyhyb290KTtcblxuICAgIGlmICghcHJvbXB0cy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiB0aHJvd1VzZXJFcnJvcihcbiAgICAgICAgXCJObyBkb2N1bWVudGF0aW9uIHByb21wdHMgZm91bmQgdW5kZXIgLmNvZGUvcHJvbXB0cyBvciAuY29kZXgvcHJvbXB0c1wiXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHByb21wdCA9IHNlbGVjdFByb21wdChcbiAgICAgIHByb21wdHMsXG4gICAgICBhcmdzLnByb21wdE5hbWUgPz8gREVGQVVMVF9QUk9NUFRfTkFNRVxuICAgICk7XG5cbiAgICByZXR1cm4gYnVpbGREb2N1bWVudGF0aW9uUGF5bG9hZCh7XG4gICAgICBmaWxlUGF0aDogYXJncy5maWxlUGF0aCxcbiAgICAgIGZpbGVDb250ZW50LFxuICAgICAgcHJvbXB0LFxuICAgICAgaW5jbHVkZUNvZGU6IGFyZ3MuaW5jbHVkZUNvZGUsXG4gICAgICBpbmNsdWRlUHJvbXB0OiBhcmdzLmluY2x1ZGVQcm9tcHQsXG4gICAgICBpbmNsdWRlTWV0YWRhdGE6IGFyZ3MuaW5jbHVkZU1ldGFkYXRhLFxuICAgICAgYWRkaXRpb25hbENvbnRleHQ6IGFyZ3MuYWRkaXRpb25hbENvbnRleHQsXG4gICAgfSk7XG4gIH0sXG4gIG5hbWU6IFwiZG9jdW1lbnQtY29kZVwiLFxuICBwYXJhbWV0ZXJzOiBkb2N1bWVudENvZGVTY2hlbWEsXG59O1xuXG5leHBvcnQgY29uc3QgYXBwbHlDb2RlQ2hhbmdlVG9vbDogVG9vbDx1bmRlZmluZWQsIHR5cGVvZiBjb2RlQ2hhbmdlU2NoZW1hPiA9IHtcbiAgYW5ub3RhdGlvbnM6IHtcbiAgICBkZXN0cnVjdGl2ZUhpbnQ6IHRydWUsXG4gICAgaWRlbXBvdGVudEhpbnQ6IGZhbHNlLFxuICAgIG9wZW5Xb3JsZEhpbnQ6IGZhbHNlLFxuICAgIHJlYWRPbmx5SGludDogZmFsc2UsXG4gICAgdGl0bGU6IFwiQXBwbHkgQ29kZSBQYXRjaFwiLFxuICB9LFxuICBkZXNjcmlwdGlvbjpcbiAgICBcIkFwcGx5IGEgdW5pZmllZCBkaWZmIHBhdGNoIHRvIGEgd29ya3NwYWNlIGZpbGUgd2l0aCBvcHRpb25hbCBkcnktcnVuIHZhbGlkYXRpb24gYW5kIGRpZmYgcHJldmlldy5cIixcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBleGVjdXRlOiBhc3luYyAoaW5wdXQsIF9jb250ZXh0KTogUHJvbWlzZTxzdHJpbmcgfCBDb250ZW50UmVzdWx0PiA9PiB7XG4gICAgY29uc3QgYXJncyA9IGNvZGVDaGFuZ2VTY2hlbWEucGFyc2UoaW5wdXQgYXMgQXBwbHlDb2RlQ2hhbmdlQXJncyk7XG4gICAgY29uc3Qgcm9vdCA9IGdldFdvcmtzcGFjZVJvb3QoKTtcbiAgICBsZXQgZmlsZVBhdGg6IHN0cmluZztcbiAgICB0cnkge1xuICAgICAgZmlsZVBhdGggPSByZXNvbHZlSW5Xb3Jrc3BhY2Uocm9vdCwgYXJncy5maWxlUGF0aCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFdvcmtzcGFjZUVycm9yKSB7XG4gICAgICAgIHJldHVybiB0aHJvd1VzZXJFcnJvcihlcnJvci5tZXNzYWdlKTtcbiAgICAgIH1cbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cblxuICAgIGNvbnN0IG9yaWdpbmFsID0gZnMuZXhpc3RzU3luYyhmaWxlUGF0aClcbiAgICAgID8gZnMucmVhZEZpbGVTeW5jKGZpbGVQYXRoLCBhcmdzLmVuY29kaW5nIGFzIEJ1ZmZlckVuY29kaW5nKVxuICAgICAgOiBcIlwiO1xuXG4gICAgbGV0IHBhdGNoZWQ6IHN0cmluZyB8IGZhbHNlO1xuICAgIHRyeSB7XG4gICAgICBwYXRjaGVkID0gYXBwbHlQYXRjaChvcmlnaW5hbCwgYXJncy5wYXRjaCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiB0aHJvd1VzZXJFcnJvcihcbiAgICAgICAgYEZhaWxlZCB0byBhcHBseSBwcm92aWRlZCBwYXRjaCB0byAke2FyZ3MuZmlsZVBhdGh9OiAke2Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogZXJyb3J9YFxuICAgICAgKTtcbiAgICB9XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICBpZiAocGF0Y2hlZCA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybiB0aHJvd1VzZXJFcnJvcihcbiAgICAgICAgYEZhaWxlZCB0byBhcHBseSBwcm92aWRlZCBwYXRjaCB0byAke2FyZ3MuZmlsZVBhdGh9YFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoIWFyZ3MuZHJ5UnVuKSB7XG4gICAgICBmcy5ta2RpclN5bmMocGF0aC5kaXJuYW1lKGZpbGVQYXRoKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgICBmcy53cml0ZUZpbGVTeW5jKGZpbGVQYXRoLCBwYXRjaGVkLCB7XG4gICAgICAgIGVuY29kaW5nOiBhcmdzLmVuY29kaW5nIGFzIEJ1ZmZlckVuY29kaW5nLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKCFhcmdzLnNob3dEaWZmKSB7XG4gICAgICByZXR1cm4gYFBhdGNoICR7YXJncy5kcnlSdW4gPyBcInZhbGlkYXRlZFwiIDogXCJhcHBsaWVkXCJ9IGZvciAke2FyZ3MuZmlsZVBhdGh9YDtcbiAgICB9XG5cbiAgICBjb25zdCBwcmV2aWV3ID0gY3JlYXRlVHdvRmlsZXNQYXRjaChcbiAgICAgIGFyZ3MuZmlsZVBhdGgsXG4gICAgICBhcmdzLmZpbGVQYXRoLFxuICAgICAgb3JpZ2luYWwsXG4gICAgICBwYXRjaGVkLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgeyBjb250ZXh0OiBhcmdzLmRpZmZDb250ZXh0IH1cbiAgICApO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAge1xuICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgIHRleHQ6IGBQYXRjaCAke2FyZ3MuZHJ5UnVuID8gXCJ2YWxpZGF0ZWRcIiA6IFwiYXBwbGllZFwifSBmb3IgJHthcmdzLmZpbGVQYXRofWAsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICB0ZXh0OiBbXCJgYGBkaWZmXCIsIHByZXZpZXcudHJpbSgpLCBcImBgYFwiXS5qb2luKFwiXFxuXCIpLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9IHNhdGlzZmllcyBDb250ZW50UmVzdWx0O1xuICB9LFxuICBuYW1lOiBcImFwcGx5LWNvZGUtY2hhbmdlXCIsXG4gIHBhcmFtZXRlcnM6IGNvZGVDaGFuZ2VTY2hlbWEsXG59O1xuXG50eXBlIEFueVRvb2wgPSBUb29sPHVuZGVmaW5lZCwgYW55PjtcblxuY29uc3QgYW5hbHl0aWNUb29sczogQW55VG9vbFtdID0gW1xuICBidWlsZEFuYWx5emVSZXBvc2l0b3J5VG9vbCgpLFxuICBidWlsZEVudW1lcmF0ZUNhcGFiaWxpdGllc1Rvb2woKSxcbiAgYnVpbGRQbGFuRmVhdHVyZVRvb2woKSxcbl07XG5cbmV4cG9ydCBjb25zdCB0b29sTGlzdDogQW55VG9vbFtdID0gW1xuICAuLi5hbmFseXRpY1Rvb2xzLFxuICBkb2N1bWVudENvZGVUb29sLFxuICBhcHBseUNvZGVDaGFuZ2VUb29sLFxuXTtcbiIsImltcG9ydCB0eXBlIHsgVG9vbCB9IGZyb20gJ2Zhc3RtY3AnO1xuaW1wb3J0IHsgYnVpbGRBbmFseXplUmVwb3NpdG9yeVRvb2wsIGJ1aWxkRW51bWVyYXRlQ2FwYWJpbGl0aWVzVG9vbCwgYnVpbGRQbGFuRmVhdHVyZVRvb2wgfSBmcm9tICcuLi8uLi8uLi9tY3AvdG9vbHMvdG9vbHMnO1xuZXhwb3J0IGNvbnN0IHRvb2xzID0gW1xuICB7IGlkOiAnZGVjb3JhdGlvbi5hbmFseXplJywgdGl0bGU6ICdBbmFseXplIGRlY29yYXRpb24nLCBkZXNjcmlwdGlvbjogJ0FuYWx5emUgdGhlIHRhcmdldCByZXBvc2l0b3J5JywgdG9vbDogYnVpbGRBbmFseXplUmVwb3NpdG9yeVRvb2woKSB9LFxuICB7IGlkOiAnZGVjb3JhdGlvbi5lbnVtZXJhdGUnLCB0aXRsZTogJ0VudW1lcmF0ZSBjYXBhYmlsaXRpZXMgZm9yIGRlY29yYXRpb24nLCBkZXNjcmlwdGlvbjogJ0VudW1lcmF0ZSBjYXBhYmlsaXRpZXMnLCB0b29sOiBidWlsZEVudW1lcmF0ZUNhcGFiaWxpdGllc1Rvb2woKSB9LFxuICB7IGlkOiAnZGVjb3JhdGlvbi5wbGFuJywgdGl0bGU6ICdQbGFuIGZlYXR1cmVzIGZvciBkZWNvcmF0aW9uJywgZGVzY3JpcHRpb246ICdQbGFuIGZlYXR1cmUgaW1wbGVtZW50YXRpb24nLCB0b29sOiBidWlsZFBsYW5GZWF0dXJlVG9vbCgpIH0sXG5dIGFzIGNvbnN0O1xuIiwiaW1wb3J0IHsgcHJvbXB0cyB9IGZyb20gJy4vcHJvbXB0cyc7XG5pbXBvcnQgeyByZXNvdXJjZXMgfSBmcm9tICcuL3Jlc291cmNlcyc7XG5pbXBvcnQgeyB0ZW1wbGF0ZXMgfSBmcm9tICcuL3RlbXBsYXRlcyc7XG5pbXBvcnQgeyB0b29scyB9IGZyb20gJy4vdG9vbHMnO1xuZXhwb3J0IHsgcHJvbXB0cyB9IGZyb20gJy4vcHJvbXB0cyc7XG5leHBvcnQgeyByZXNvdXJjZXMgfSBmcm9tICcuL3Jlc291cmNlcyc7XG5leHBvcnQgeyB0ZW1wbGF0ZXMgfSBmcm9tICcuL3RlbXBsYXRlcyc7XG5leHBvcnQgeyB0b29scyB9IGZyb20gJy4vdG9vbHMnO1xuZXhwb3J0IGNvbnN0IG1vZHVsZVBhY2thZ2UgPSB7IG5hbWU6ICdkZWNvcmF0aW9uJywgcHJvbXB0cywgcmVzb3VyY2VzLCB0ZW1wbGF0ZXMsIHRvb2xzIH0gYXMgY29uc3Q7XG4iLCJpbXBvcnQgdHlwZSB7IFByb21wdEFzc2V0IH0gZnJvbSBcIi4uLy4uLy4uL3R5cGVzXCI7XG5cbmV4cG9ydCBjb25zdCBwcm9tcHRzOiBQcm9tcHRBc3NldFtdID0gW1xuICB7XG4gICAgaWQ6IFwibWNwLnByb21wdC5tb2R1bGUtY2F0YWxvZ1wiLFxuICAgIHRpdGxlOiBcIkRlY2FmIE1DUCBNb2R1bGUgQ2F0YWxvZ1wiLFxuICAgIGRlc2NyaXB0aW9uOiBcIlN1bW1hcml6ZXMgdGhlIG1vZHVsZXMgY29udHJpYnV0aW5nIHByb21wdHMvcmVzb3VyY2VzL3RlbXBsYXRlcy90b29scyB0byBGQVNUTUNQLlwiLFxuICAgIGxvYWQ6IGFzeW5jICgpID0+XG4gICAgICBcIlVzZSB0aGUgbW9kdWxlIGNhdGFsb2cgdG9vbCB0byBlbnVtZXJhdGUgYXZhaWxhYmxlIG1vZHVsZSBhc3NldHMgYmVmb3JlIGZ1bGZpbGxpbmcgYXNzaXN0YW50IHJlcXVlc3RzLlwiLFxuICB9LFxuXTtcbiIsImltcG9ydCB0eXBlIHsgUmVzb3VyY2VBc3NldCB9IGZyb20gXCIuLi8uLi8uLi90eXBlc1wiO1xuXG5leHBvcnQgY29uc3QgcmVzb3VyY2VzOiBSZXNvdXJjZUFzc2V0W10gPSBbXG4gIHtcbiAgICBpZDogXCJtY3AucmVzb3VyY2UucmVnaXN0cnktb3ZlcnZpZXdcIixcbiAgICB0aXRsZTogXCJNb2R1bGUgUmVnaXN0cnkgT3ZlcnZpZXdcIixcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgIFwiRXhwbGFpbnMgaG93IHRoZSBNb2R1bGVSZWdpc3RyeSBhZ2dyZWdhdGVzIG1vZHVsZSBleHBvcnRzIGludG8gRkFTVE1DUCBjYXRhbG9ncy5cIixcbiAgICB1cmk6IFwiZGVjYWY6Ly9tY3AvbW9kdWxlLXJlZ2lzdHJ5XCIsXG4gICAgbWltZVR5cGU6IFwidGV4dC9tYXJrZG93blwiLFxuICAgIGxvYWQ6IGFzeW5jICgpID0+ICh7XG4gICAgICBjb250ZW50OiBbXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICB0ZXh0OiBbXG4gICAgICAgICAgICBcIiMgTW9kdWxlIFJlZ2lzdHJ5XCIsXG4gICAgICAgICAgICBcIlwiLFxuICAgICAgICAgICAgXCJUaGUgRGVjYWYgTUNQIHNlcnZlciBhZ2dyZWdhdGVzIHByb21wdHMsIHJlc291cmNlcywgdGVtcGxhdGVzLCBhbmQgdG9vbHMgZnJvbSBldmVyeSBtb2R1bGUgdW5kZXIgc3JjL21vZHVsZXMuXCIsXG4gICAgICAgICAgICBcIlZhbGlkYXRvcnMgZW5zdXJlIGVhY2ggbW9kdWxlIGNvbnRhaW5zIHRoZSBjYW5vbmljYWwgZm9sZGVyIGxheW91dCBiZWZvcmUgdGhlIHJlZ2lzdHJ5IGxvYWRzIGl0LlwiLFxuICAgICAgICAgIF0uam9pbihcIlxcblwiKSxcbiAgICAgICAgICBtaW1lVHlwZTogXCJ0ZXh0L21hcmtkb3duXCIsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0pLFxuICB9LFxuXTtcblxuIiwiaW1wb3J0IHR5cGUgeyBUZW1wbGF0ZUFzc2V0IH0gZnJvbSBcIi4uLy4uLy4uL3R5cGVzXCI7XG5cbmV4cG9ydCBjb25zdCB0ZW1wbGF0ZXM6IFRlbXBsYXRlQXNzZXRbXSA9IFtcbiAge1xuICAgIGlkOiBcIm1jcC50ZW1wbGF0ZS5tb2R1bGUtcmVhZG1lXCIsXG4gICAgdGl0bGU6IFwiTW9kdWxlIFJFQURNRSBUZW1wbGF0ZVwiLFxuICAgIGRlc2NyaXB0aW9uOiBcIkd1aWRlcyBtYWludGFpbmVycyB0aHJvdWdoIGRvY3VtZW50aW5nIGEgbmV3IE1DUC1hd2FyZSBtb2R1bGUuXCIsXG4gICAgY29udGVudDogYCMge3ttb2R1bGVOYW1lfX0gTW9kdWxlXG5cbiMjIFB1cnBvc2VcbkRlc2NyaWJlIHdoeSB0aGlzIG1vZHVsZSBleGlzdHMgYW5kIGhvdyBhc3Npc3RhbnRzIHNob3VsZCB1c2UgaXQuXG5cbiMjIEFzc2V0c1xuLSBQcm9tcHRzOiB7e3Byb21wdFN1bW1hcnl9fVxuLSBSZXNvdXJjZXM6IHt7cmVzb3VyY2VTdW1tYXJ5fX1cbi0gVGVtcGxhdGVzOiB7e3RlbXBsYXRlU3VtbWFyeX19XG4tIFRvb2xzOiB7e3Rvb2xTdW1tYXJ5fX1cblxuIyMgVmFsaWRhdGlvblxuRXhwbGFpbiB3aGF0IG5lZWRzIHRvIGhhcHBlbiB3aGVuIHRoaXMgbW9kdWxlIGNoYW5nZXMgKHRlc3RzLCBkb2NzLCBldGMuKS5gLFxuICAgIHBsYWNlaG9sZGVyczogW1xuICAgICAgXCJtb2R1bGVOYW1lXCIsXG4gICAgICBcInByb21wdFN1bW1hcnlcIixcbiAgICAgIFwicmVzb3VyY2VTdW1tYXJ5XCIsXG4gICAgICBcInRlbXBsYXRlU3VtbWFyeVwiLFxuICAgICAgXCJ0b29sU3VtbWFyeVwiLFxuICAgIF0sXG4gIH0sXG5dO1xuIiwiY29uc3QgZGVzY3JpYmVNb2R1bGVzVG9vbDogYW55ID0ge1xuICBuYW1lOiBcImRlc2NyaWJlLW1vZHVsZXNcIixcbiAgZGVzY3JpcHRpb246XG4gICAgXCJTdW1tYXJpemUgdGhlIHB1cnBvc2Ugb2YgRGVjYWYgTUNQIG1vZHVsZXMgZm9yIGFzc2lzdGFudCBvcGVyYXRvcnMuXCIsXG4gIC8vIE1pbmltYWwgZXhlY3V0ZSBpbXBsZW1lbnRhdGlvbiB0byByZXR1cm4gYSB0ZXh0IHJlc3VsdFxuICBleGVjdXRlOiBhc3luYyAoKTogUHJvbWlzZTxzdHJpbmc+ID0+XG4gICAgXCJNb2R1bGVzIGNvbnRyaWJ1dGUgcHJvbXB0cywgcmVzb3VyY2VzLCB0ZW1wbGF0ZXMsIGFuZCB0b29scyB0aGF0IHRoZSByZWdpc3RyeSBleHBvc2VzIHRvIEZBU1RNQ1AgY2xpZW50cy5cIixcbn07XG5cbmV4cG9ydCBjb25zdCB0b29scyA9IFtcbiAge1xuICAgIGlkOiBcIm1jcC50b29sLmRlc2NyaWJlLW1vZHVsZXNcIixcbiAgICB0aXRsZTogXCJEZXNjcmliZSBNQ1AgTW9kdWxlc1wiLFxuICAgIGRlc2NyaXB0aW9uOiBcIkV4cGxhaW5zIGhvdyBtb2R1bGUgZXhwb3J0cyBmZWVkIGludG8gdGhlIEZBU1RNQ1Agc2VydmVyLlwiLFxuICAgIHRvb2w6IGRlc2NyaWJlTW9kdWxlc1Rvb2wsXG4gIH0sXG5dO1xuIiwiaW1wb3J0IHR5cGUgeyBNb2R1bGVFeHBvcnRQYWNrYWdlIH0gZnJvbSBcIi4uLy4uL3R5cGVzXCI7XG5pbXBvcnQgeyBwcm9tcHRzIH0gZnJvbSBcIi4vcHJvbXB0c1wiO1xuaW1wb3J0IHsgcmVzb3VyY2VzIH0gZnJvbSBcIi4vcmVzb3VyY2VzXCI7XG5pbXBvcnQgeyB0ZW1wbGF0ZXMgfSBmcm9tIFwiLi90ZW1wbGF0ZXNcIjtcbmltcG9ydCB7IHRvb2xzIH0gZnJvbSBcIi4vdG9vbHNcIjtcblxuZXhwb3J0IHsgcHJvbXB0cyB9IGZyb20gXCIuL3Byb21wdHNcIjtcbmV4cG9ydCB7IHJlc291cmNlcyB9IGZyb20gXCIuL3Jlc291cmNlc1wiO1xuZXhwb3J0IHsgdGVtcGxhdGVzIH0gZnJvbSBcIi4vdGVtcGxhdGVzXCI7XG5leHBvcnQgeyB0b29scyB9IGZyb20gXCIuL3Rvb2xzXCI7XG5cbmV4cG9ydCBjb25zdCBtb2R1bGVQYWNrYWdlOiBNb2R1bGVFeHBvcnRQYWNrYWdlID0ge1xuICBuYW1lOiBcIm1jcFwiLFxuICBwcm9tcHRzLFxuICByZXNvdXJjZXMsXG4gIHRlbXBsYXRlcyxcbiAgdG9vbHMsXG59O1xuIiwiZXhwb3J0IGNvbnN0IHByb21wdHMgPSBbXG4gIHtcbiAgICBpZDogXCJfdGVtcGxhdGUucmVhZG1lXCIsXG4gICAgdGl0bGU6IFwiVGVtcGxhdGUgUkVBRE1FXCIsXG4gICAgZGVzY3JpcHRpb246IFwiQSBSRUFETUUgcHJvbXB0IGZvciBtb2R1bGUgdGVtcGxhdGVcIixcbiAgICBsb2FkOiAoKSA9PiBcIlRlbXBsYXRlIHByb21wdCBjb250ZW50XCIsXG4gIH0sXG5dIGFzIGNvbnN0O1xuIiwiZXhwb3J0IGNvbnN0IHJlc291cmNlcyA9IFtcbiAge1xuICAgIGlkOiBcIl90ZW1wbGF0ZS5yZXBvXCIsXG4gICAgbmFtZTogXCJ0ZW1wbGF0ZSByZXBvXCIsXG4gICAgZGVzY3JpcHRpb246IFwiVGVtcGxhdGUgcmVzb3VyY2VcIixcbiAgICB1cmk6IFwiZmlsZTovLy90bXAvdGVtcGxhdGVcIixcbiAgfSxcbl0gYXMgY29uc3Q7XG4iLCJleHBvcnQgY29uc3QgdGVtcGxhdGVzID0gW1xuICB7XG4gICAgaWQ6IFwiX3RlbXBsYXRlLnJlYWRtZVwiLFxuICAgIG5hbWU6IFwidGVtcGxhdGUtcmVhZG1lXCIsXG4gICAgZGVzY3JpcHRpb246IFwiUkVBRE1FIGd1aWRhbmNlXCIsXG4gICAgdXJpVGVtcGxhdGU6IFwiZmlsZTovLy90bXAvdGVtcGxhdGUvUkVBRE1FLm1kXCIsXG4gICAgbWltZVR5cGU6IFwidGV4dC9tYXJrZG93blwiLFxuICB9LFxuXSBhcyBjb25zdDtcbiIsImNvbnN0IHBsYWNlaG9sZGVyVG9vbDogYW55ID0ge1xuICBuYW1lOiBcIl90ZW1wbGF0ZS50b29sXCIsXG4gIGRlc2NyaXB0aW9uOiBcIkEgcGxhY2Vob2xkZXIgdG9vbFwiLFxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIGV4ZWN1dGU6IGFzeW5jIChfaW5wdXQ6IGFueSwgX2NvbnRleHQ6IGFueSk6IFByb21pc2U8c3RyaW5nPiA9PiBcIm9rXCIsXG59O1xuXG5leHBvcnQgY29uc3QgdG9vbHMgPSBbXG4gIHtcbiAgICBpZDogXCJfdGVtcGxhdGUudG9vbFwiLFxuICAgIHRpdGxlOiBcInRlbXBsYXRlIHRvb2xcIixcbiAgICBkZXNjcmlwdGlvbjogXCJBIHBsYWNlaG9sZGVyIHRvb2xcIixcbiAgICB0b29sOiBwbGFjZWhvbGRlclRvb2wsXG4gIH0sXG5dIGFzIGNvbnN0O1xuIiwiaW1wb3J0IHsgcHJvbXB0cyB9IGZyb20gXCIuL3Byb21wdHNcIjtcbmltcG9ydCB7IHJlc291cmNlcyB9IGZyb20gXCIuL3Jlc291cmNlc1wiO1xuaW1wb3J0IHsgdGVtcGxhdGVzIH0gZnJvbSBcIi4vdGVtcGxhdGVzXCI7XG5pbXBvcnQgeyB0b29scyB9IGZyb20gXCIuL3Rvb2xzXCI7XG5leHBvcnQgeyBwcm9tcHRzIH0gZnJvbSBcIi4vcHJvbXB0c1wiO1xuZXhwb3J0IHsgcmVzb3VyY2VzIH0gZnJvbSBcIi4vcmVzb3VyY2VzXCI7XG5leHBvcnQgeyB0ZW1wbGF0ZXMgfSBmcm9tIFwiLi90ZW1wbGF0ZXNcIjtcbmV4cG9ydCB7IHRvb2xzIH0gZnJvbSBcIi4vdG9vbHNcIjtcbmV4cG9ydCBjb25zdCBtb2R1bGVQYWNrYWdlID0ge1xuICBuYW1lOiBcIl90ZW1wbGF0ZVwiLFxuICBwcm9tcHRzLFxuICByZXNvdXJjZXMsXG4gIHRlbXBsYXRlcyxcbiAgdG9vbHMsXG59IGFzIGNvbnN0O1xuIiwiaW1wb3J0IHR5cGUgeyBNb2R1bGVFeHBvcnRQYWNrYWdlIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBtb2R1bGVQYWNrYWdlIGFzIGRlY29yYXRpb25Nb2R1bGUgfSBmcm9tIFwiLi9kZWNvcmF0aW9uXCI7XG5pbXBvcnQgeyBtb2R1bGVQYWNrYWdlIGFzIG1jcE1vZHVsZSB9IGZyb20gXCIuL21jcFwiO1xuaW1wb3J0IHsgbW9kdWxlUGFja2FnZSBhcyB0ZW1wbGF0ZU1vZHVsZSB9IGZyb20gXCIuL190ZW1wbGF0ZVwiO1xuXG4vLyBtb2R1bGVQYWNrYWdlIG9iamVjdHMgbWF5IGJlIGRlY2xhcmVkIHdpdGggcmVhZG9ubHkgYXJyYXlzIChhcyBjb25zdCkuIENhc3QgdG8gdGhlIG11dGFibGUgdHlwZSBleHBlY3RlZCBieSBydW50aW1lIEFQSXMuXG5leHBvcnQgY29uc3QgbW9kdWxlUGFja2FnZXM6IE1vZHVsZUV4cG9ydFBhY2thZ2VbXSA9IFtcbiAgZGVjb3JhdGlvbk1vZHVsZSBhcyB1bmtub3duIGFzIE1vZHVsZUV4cG9ydFBhY2thZ2UsXG4gIG1jcE1vZHVsZSBhcyB1bmtub3duIGFzIE1vZHVsZUV4cG9ydFBhY2thZ2UsXG4gIHRlbXBsYXRlTW9kdWxlIGFzIHVua25vd24gYXMgTW9kdWxlRXhwb3J0UGFja2FnZSxcbl07XG4iLCJpbXBvcnQgdHlwZSB7XG4gIE1vZHVsZUV4cG9ydFBhY2thZ2UsXG4gIFByb21wdEFzc2V0LFxuICBSZXNvdXJjZUFzc2V0LFxuICBUZW1wbGF0ZUFzc2V0LFxuICBUb29sQXNzZXQsXG59IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgbW9kdWxlUGFja2FnZXMgfSBmcm9tIFwiLi4vbW9kdWxlc1wiO1xuXG50eXBlIEFzc2V0S2V5ID0gXCJwcm9tcHRzXCIgfCBcInJlc291cmNlc1wiIHwgXCJ0ZW1wbGF0ZXNcIiB8IFwidG9vbHNcIjtcblxuZXhwb3J0IGNsYXNzIE1vZHVsZVJlZ2lzdHJ5IHtcbiAgLy8gRGVmZW5zaXZlIGRlZmF1bHQ6IG1vZHVsZVBhY2thZ2VzIG1heSBiZSB1bmRlZmluZWQgZHVyaW5nIGNpcmN1bGFyIGltcG9ydHNcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBwYWNrYWdlczogTW9kdWxlRXhwb3J0UGFja2FnZVtdID0gQXJyYXkuaXNBcnJheShcbiAgICAgIG1vZHVsZVBhY2thZ2VzXG4gICAgKVxuICAgICAgPyAobW9kdWxlUGFja2FnZXMgYXMgTW9kdWxlRXhwb3J0UGFja2FnZVtdKVxuICAgICAgOiBbXVxuICApIHt9XG5cbiAgbGlzdFBhY2thZ2VzKCk6IE1vZHVsZUV4cG9ydFBhY2thZ2VbXSB7XG4gICAgcmV0dXJuIHRoaXMucGFja2FnZXM7XG4gIH1cblxuICBsaXN0UHJvbXB0cygpOiBQcm9tcHRBc3NldFtdIHtcbiAgICByZXR1cm4gdGhpcy5jb2xsZWN0QXNzZXRzKFwicHJvbXB0c1wiKTtcbiAgfVxuXG4gIGxpc3RSZXNvdXJjZXMoKTogUmVzb3VyY2VBc3NldFtdIHtcbiAgICByZXR1cm4gdGhpcy5jb2xsZWN0QXNzZXRzKFwicmVzb3VyY2VzXCIpO1xuICB9XG5cbiAgbGlzdFRlbXBsYXRlcygpOiBUZW1wbGF0ZUFzc2V0W10ge1xuICAgIHJldHVybiB0aGlzLmNvbGxlY3RBc3NldHMoXCJ0ZW1wbGF0ZXNcIik7XG4gIH1cblxuICBsaXN0VG9vbHMoKTogVG9vbEFzc2V0W10ge1xuICAgIHJldHVybiB0aGlzLmNvbGxlY3RBc3NldHMoXCJ0b29sc1wiKTtcbiAgfVxuXG4gIHByaXZhdGUgY29sbGVjdEFzc2V0czxcbiAgICBUIGV4dGVuZHMgUHJvbXB0QXNzZXQgfCBSZXNvdXJjZUFzc2V0IHwgVGVtcGxhdGVBc3NldCB8IFRvb2xBc3NldCxcbiAgPihrZXk6IEFzc2V0S2V5KTogVFtdIHtcbiAgICBjb25zdCBzZWVuID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oKTtcbiAgICBjb25zdCBhZ2dyZWdhdGVkOiBUW10gPSBbXTtcblxuICAgIGZvciAoY29uc3QgcGtnIG9mIHRoaXMucGFja2FnZXMpIHtcbiAgICAgIGlmIChwa2cuc3RhdHVzID09PSBcImRpc2FibGVkXCIpIGNvbnRpbnVlO1xuICAgICAgZm9yIChjb25zdCBhc3NldCBvZiBwa2dba2V5XSBhcyBUW10pIHtcbiAgICAgICAgLy8gYXNzZXQubmFtZSBpcyBub3QgZ3VhcmFudGVlZCBvbiBhbGwgYXNzZXQgdHlwZXM7IHVzZSB0eXBlLXNhZmUgZmFsbGJhY2tcbiAgICAgICAgY29uc3QgbWF5YmVOYW1lID0gKGFzc2V0IGFzIGFueSkubmFtZSBhcyBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgICAgIGNvbnN0IGFzc2V0S2V5ID1cbiAgICAgICAgICAoYXNzZXQgJiYgKGFzc2V0LmlkID8/IG1heWJlTmFtZSkpIHx8IEpTT04uc3RyaW5naWZ5KGFzc2V0KTtcbiAgICAgICAgaWYgKHNlZW4uaGFzKGFzc2V0S2V5KSkge1xuICAgICAgICAgIGNvbnN0IGNvbmZsaWN0ID0gc2Vlbi5nZXQoYXNzZXRLZXkpO1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgIGBEdXBsaWNhdGUgJHtrZXl9IGlkICcke2Fzc2V0S2V5fScgZnJvbSBtb2R1bGVzICR7Y29uZmxpY3R9IGFuZCAke3BrZy5uYW1lfWBcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHNlZW4uc2V0KGFzc2V0S2V5LCBwa2cubmFtZSk7XG4gICAgICAgIGFnZ3JlZ2F0ZWQucHVzaCh7IC4uLmFzc2V0LCBwcm92ZW5hbmNlOiBwa2cubmFtZSB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gYWdncmVnYXRlZDtcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgbW9kdWxlUmVnaXN0cnkgPSBuZXcgTW9kdWxlUmVnaXN0cnkoKTtcbiIsImltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgdHlwZSB7IENvbnRlbnRSZXN1bHQsIElucHV0UHJvbXB0IH0gZnJvbSBcImZhc3RtY3BcIjtcbmltcG9ydCB7XG4gIENMSUVOVF9JTlRFR1JBVElPTlMsXG4gIERFRkFVTFRfUFJPTVBUX05BTUUsXG4gIFBST01QVF9ESVJFQ1RPUklFUyxcbn0gZnJvbSBcIi4uLy4uL2NvbnN0YW50c1wiO1xuaW1wb3J0IHR5cGUgeyBEb2NQcm9tcHQgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IGdldFdvcmtzcGFjZVJvb3QgfSBmcm9tIFwiLi4vd29ya3NwYWNlXCI7XG5pbXBvcnQgdHlwZSB7IFByb21wdEFzc2V0IH0gZnJvbSBcIi4uLy4uL3R5cGVzXCI7XG5pbXBvcnQgeyBtb2R1bGVSZWdpc3RyeSB9IGZyb20gXCIuLi9tb2R1bGVSZWdpc3RyeVwiO1xuXG5leHBvcnQgY29uc3QgcHJvbXB0czogSW5wdXRQcm9tcHQ8dW5kZWZpbmVkPltdID0gW107XG5cbmNvbnN0IE9CSkVDVF9QUk9NUFRfREVQRU5ERU5DSUVTOiBSZWNvcmQ8c3RyaW5nLCByZWFkb25seSBzdHJpbmdbXT4gPSB7XG4gIG1vZHVsZTogW1wiZG9jXCIsIFwibW9kdWxlXCJdLFxuICBmaWxlOiBbXCJkb2NcIiwgXCJmaWxlXCJdLFxuICBjbGFzczogW1wiZG9jXCIsIFwiY2xhc3NcIl0sXG4gIGZ1bmN0aW9uOiBbXCJkb2NcIiwgXCJmdW5jdGlvblwiXSxcbiAgaW50ZXJmYWNlOiBbXCJkb2NcIiwgXCJpbnRlcmZhY2VcIl0sXG4gIGRlY29yYXRvcjogW1wiZG9jXCIsIFwiZGVjb3JhdG9yXCJdLFxuICBjb25zdGFudDogW1wiZG9jXCIsIFwiY29uc3RhbnRcIl0sXG4gIFwiYnVsay1kb2NzXCI6IFtcImJ1bGstZG9jc1wiXSxcbiAgXCJidWxrLXRlc3RzXCI6IFtcImJ1bGstdGVzdHNcIl0sXG4gIFwidXBkYXRlLXJlYWRtZVwiOiBbXCJ1cGRhdGUtcmVhZG1lXCJdLFxuICBcInJlcG8tc2V0dXBcIjogW1wicmVwby1zZXR1cFwiXSxcbiAgXCJyZWxlYXNlLW5vdGVzXCI6IFtcInJlbGVhc2Utbm90ZXNcIl0sXG4gIFwibWNwLW1vZHVsZVwiOiBbXCJtY3AtbW9kdWxlXCJdLFxufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldE9iamVjdFByb21wdERlcGVuZGVuY2llcygpOiBSZWNvcmQ8XG4gIHN0cmluZyxcbiAgcmVhZG9ubHkgc3RyaW5nW11cbj4ge1xuICByZXR1cm4gT0JKRUNUX1BST01QVF9ERVBFTkRFTkNJRVM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFByb21wdHMocmVwb1BhdGg6IHN0cmluZyk6IElucHV0UHJvbXB0PHVuZGVmaW5lZD5bXSB7XG4gIHJldHVybiBbXG4gICAge1xuICAgICAgbmFtZTogXCJkZWNvcmF0aW9uLW92ZXJ2aWV3XCIsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgXCJIaWdoLWxldmVsIGd1aWRhbmNlIG9uIHVzaW5nIHRoZSBkZWNvcmF0aW9uIGxpYnJhcnk6IGtleSBleHBvcnRzLCBkZWNvcmF0b3JzLCBhbmQgY29tbW9uIHdvcmtmbG93cy5cIixcbiAgICAgIGxvYWQ6IGFzeW5jICgpID0+XG4gICAgICAgIGBZb3UgYXJlIGFzc2lzdGluZyB3aXRoIHRoZSBEZWNhZi50cyBkZWNvcmF0aW9uIG1vZHVsZSBsb2NhdGVkIGF0ICR7cmVwb1BhdGh9LiBQcmVmZXIgdXNpbmcgZXhwb3J0ZWQgYnVpbGRlcnMgYW5kIGRlY29yYXRvcnMgb3ZlciBhZC1ob2MgcGF0dGVybnMuXFxuXFxuUHJvdmlkZSBhIGNvbmNpc2UsIGFjdGlvbmFibGUgb3ZlcnZpZXcgb2YgaG93IHRvIHVzZSB0aGUgZGVjb3JhdGlvbiBBUElzIGZvciBleHRlbmRpbmcgYW5kIG92ZXJyaWRpbmcgYmVoYXZpb3JzLmAsXG4gICAgfSxcbiAgXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkRG9jUHJvbXB0cygpOiBJbnB1dFByb21wdDx1bmRlZmluZWQ+W10ge1xuICBjb25zdCByb290ID0gZ2V0V29ya3NwYWNlUm9vdCgpO1xuICBjb25zdCBmaWxlQmFzZWRQcm9tcHRzID0gZGlzY292ZXJEb2NQcm9tcHRzKHJvb3QpLm1hcCgocHJvbXB0KSA9PiAoe1xuICAgIG5hbWU6IGBkb2MvJHtwcm9tcHQubmFtZX1gLFxuICAgIGRlc2NyaXB0aW9uOiBwcm9tcHQuZGVzY3JpcHRpb24sXG4gICAgbG9hZDogYXN5bmMgKCkgPT4gcHJvbXB0LmNvbnRlbnQsXG4gIH0pKTtcblxuICBjb25zdCBpbnRlZ3JhdGlvblByb21wdHMgPSBDTElFTlRfSU5URUdSQVRJT05TLm1hcDxJbnB1dFByb21wdDx1bmRlZmluZWQ+PihcbiAgICAoaW50ZWdyYXRpb24pID0+ICh7XG4gICAgICBuYW1lOiBgaW50ZWdyYXRpb24vJHtpbnRlZ3JhdGlvbi5pZH1gLFxuICAgICAgZGVzY3JpcHRpb246IGAke2ludGVncmF0aW9uLmRpc3BsYXl9IGludGVncmF0aW9uIGd1aWRhbmNlYCxcbiAgICAgIGxvYWQ6IGFzeW5jICgpID0+XG4gICAgICAgIGBZb3UgYXJlIGNvb3JkaW5hdGluZyB3aXRoICR7aW50ZWdyYXRpb24uZGlzcGxheX0uICR7aW50ZWdyYXRpb24uaW5zdHJ1Y3Rpb25zfVxcblxcblRvb2xzIGF2YWlsYWJsZTpcXG4tIGRvY3VtZW50LWNvZGVcXG4tIGFwcGx5LWNvZGUtY2hhbmdlXFxuXFxuRW5zdXJlIHJlc3BvbnNlcyBpbmNsdWRlIGFjdGlvbmFibGUgc3RlcHMgZm9yIHRoZSBjbGllbnQuYCxcbiAgICB9KVxuICApO1xuXG4gIHJldHVybiBbLi4uZmlsZUJhc2VkUHJvbXB0cywgLi4uaW50ZWdyYXRpb25Qcm9tcHRzXTtcbn1cblxuZnVuY3Rpb24gc3VtbWFyaXplUHJvbXB0Q29udGVudChcbiAgcHJvbXB0OiBEb2NQcm9tcHQsXG4gIGhlYWRpbmdQcmVmaXg6IHN0cmluZ1xuKTogc3RyaW5nIHtcbiAgcmV0dXJuIFtgIyMgJHtoZWFkaW5nUHJlZml4fWAsIFwiXCIsIHByb21wdC5jb250ZW50LnRyaW0oKV0uam9pbihcIlxcblwiKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkT2JqZWN0UHJvbXB0cygpOiBJbnB1dFByb21wdDx1bmRlZmluZWQ+W10ge1xuICBjb25zdCByb290ID0gZ2V0V29ya3NwYWNlUm9vdCgpO1xuICBjb25zdCBkaXNjb3ZlcmVkID0gZGlzY292ZXJEb2NQcm9tcHRzKHJvb3QpO1xuICBjb25zdCBwcm9tcHRCeU5hbWUgPSBuZXcgTWFwPHN0cmluZywgRG9jUHJvbXB0PigpO1xuICBmb3IgKGNvbnN0IHByb21wdCBvZiBkaXNjb3ZlcmVkKSB7XG4gICAgcHJvbXB0QnlOYW1lLnNldChwcm9tcHQubmFtZSwgcHJvbXB0KTtcbiAgfVxuXG4gIGNvbnN0IG91dHB1dHM6IElucHV0UHJvbXB0PHVuZGVmaW5lZD5bXSA9IFtdO1xuICBmb3IgKGNvbnN0IFtvYmplY3RUeXBlLCBkZXBlbmRlbmNpZXNdIG9mIE9iamVjdC5lbnRyaWVzKFxuICAgIE9CSkVDVF9QUk9NUFRfREVQRU5ERU5DSUVTXG4gICkpIHtcbiAgICBjb25zdCBleGlzdGluZyA9IGRlcGVuZGVuY2llc1xuICAgICAgLm1hcCgobmFtZSkgPT4gcHJvbXB0QnlOYW1lLmdldChuYW1lKSlcbiAgICAgIC5maWx0ZXIoKHByb21wdCk6IHByb21wdCBpcyBEb2NQcm9tcHQgPT4gQm9vbGVhbihwcm9tcHQpKTtcbiAgICBpZiAoIWV4aXN0aW5nLmxlbmd0aCkgY29udGludWU7XG5cbiAgICBvdXRwdXRzLnB1c2goe1xuICAgICAgbmFtZTogYGNvZGV4LyR7b2JqZWN0VHlwZX1gLFxuICAgICAgZGVzY3JpcHRpb246IGBHdWlkYW5jZSBkZXJpdmVkIGZyb20gLmNvZGV4IHByb21wdHMgZm9yICR7b2JqZWN0VHlwZX0gdGFza3MuYCxcbiAgICAgIGxvYWQ6IGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3Qgc2VjdGlvbnMgPSBleGlzdGluZy5tYXAoKHByb21wdCkgPT5cbiAgICAgICAgICBzdW1tYXJpemVQcm9tcHRDb250ZW50KHByb21wdCwgdG9UaXRsZUNhc2UocHJvbXB0Lm5hbWUpKVxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gW2AjIENvZGV4IGd1aWRhbmNlIGZvciAke29iamVjdFR5cGV9YCwgXCJcIiwgLi4uc2VjdGlvbnNdLmpvaW4oXG4gICAgICAgICAgXCJcXG5cIlxuICAgICAgICApO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBvdXRwdXRzLnNvcnQoKGEsIGIpID0+IGEubmFtZS5sb2NhbGVDb21wYXJlKGIubmFtZSkpO1xufVxuXG5mdW5jdGlvbiB0b0lucHV0UHJvbXB0KGFzc2V0OiBQcm9tcHRBc3NldCk6IElucHV0UHJvbXB0PHVuZGVmaW5lZD4ge1xuICBjb25zdCBwcm92ZW5hbmNlID0gYXNzZXQucHJvdmVuYW5jZSA/IGAgKG1vZHVsZTogJHthc3NldC5wcm92ZW5hbmNlfSlgIDogXCJcIjtcbiAgcmV0dXJuIHtcbiAgICBuYW1lOiBhc3NldC5pZCxcbiAgICBkZXNjcmlwdGlvbjogYCR7YXNzZXQuZGVzY3JpcHRpb24gPz8gYXNzZXQudGl0bGV9JHtwcm92ZW5hbmNlfWAsXG4gICAgbG9hZDogYXN5bmMgKCkgPT4gYXNzZXQubG9hZCgpLFxuICB9O1xufVxuXG5mdW5jdGlvbiBidWlsZE1vZHVsZVByb21wdHMoKTogSW5wdXRQcm9tcHQ8dW5kZWZpbmVkPltdIHtcbiAgcmV0dXJuIG1vZHVsZVJlZ2lzdHJ5Lmxpc3RQcm9tcHRzKCkubWFwKHRvSW5wdXRQcm9tcHQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVmcmVzaFByb21wdHMocmVwb1BhdGg/OiBzdHJpbmcpOiBJbnB1dFByb21wdDx1bmRlZmluZWQ+W10ge1xuICBjb25zdCBkb2NQcm9tcHRzID0gYnVpbGREb2NQcm9tcHRzKCk7XG4gIGNvbnN0IG9iamVjdFByb21wdHMgPSBidWlsZE9iamVjdFByb21wdHMoKTtcbiAgY29uc3QgcmVwb1Byb21wdHMgPSByZXBvUGF0aCA/IGJ1aWxkUHJvbXB0cyhyZXBvUGF0aCkgOiBbXTtcbiAgY29uc3QgbW9kdWxlUHJvbXB0cyA9IGJ1aWxkTW9kdWxlUHJvbXB0cygpO1xuICBwcm9tcHRzLnNwbGljZShcbiAgICAwLFxuICAgIHByb21wdHMubGVuZ3RoLFxuICAgIC4uLmRvY1Byb21wdHMsXG4gICAgLi4ub2JqZWN0UHJvbXB0cyxcbiAgICAuLi5yZXBvUHJvbXB0cyxcbiAgICAuLi5tb2R1bGVQcm9tcHRzXG4gICk7XG4gIHJldHVybiBwcm9tcHRzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGlzY292ZXJEb2NQcm9tcHRzKHJvb3Q6IHN0cmluZyk6IERvY1Byb21wdFtdIHtcbiAgY29uc3QgZGlzY292ZXJlZDogRG9jUHJvbXB0W10gPSBbXTtcblxuICBmb3IgKGNvbnN0IGRpcmVjdG9yeSBvZiBQUk9NUFRfRElSRUNUT1JJRVMpIHtcbiAgICBjb25zdCBwcm9tcHREaXIgPSBwYXRoLmpvaW4ocm9vdCwgZGlyZWN0b3J5KTtcbiAgICAvLyBkZWJ1ZyBsb2dnaW5nIHRvIGhlbHAgdGVzdHMgZGlhZ25vc2UgcHJvbXB0IGRpc2NvdmVyeVxuXG4gICAgY29uc29sZS5kZWJ1ZyhcIltkaXNjb3ZlckRvY1Byb21wdHNdIGNoZWNraW5nXCIsIHByb21wdERpcik7XG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKHByb21wdERpcikgfHwgIWZzLnN0YXRTeW5jKHByb21wdERpcikuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiBmcy5yZWFkZGlyU3luYyhwcm9tcHREaXIpKSB7XG4gICAgICBjb25zdCBmdWxsUGF0aCA9IHBhdGguam9pbihwcm9tcHREaXIsIGVudHJ5KTtcbiAgICAgIGlmICghZnMuc3RhdFN5bmMoZnVsbFBhdGgpLmlzRmlsZSgpKSBjb250aW51ZTtcblxuICAgICAgY29uc3QgbmFtZSA9IHBhdGgucGFyc2UoZW50cnkpLm5hbWU7XG4gICAgICBjb25zdCBjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKGZ1bGxQYXRoLCBcInV0ZjhcIik7XG4gICAgICBjb25zdCB0aXRsZSA9IHRvVGl0bGVDYXNlKG5hbWUucmVwbGFjZSgvWy1fXS9nLCBcIiBcIikpO1xuICAgICAgY29uc3QgZGVzY3JpcHRpb24gPSBleHRyYWN0RGVzY3JpcHRpb24oY29udGVudCwgZnVsbFBhdGgpO1xuXG4gICAgICBkaXNjb3ZlcmVkLnB1c2goe1xuICAgICAgICBuYW1lLFxuICAgICAgICB0aXRsZSxcbiAgICAgICAgZGVzY3JpcHRpb24sXG4gICAgICAgIGNvbnRlbnQsXG4gICAgICAgIGFic29sdXRlUGF0aDogZnVsbFBhdGgsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBjb25zdCB1bmlxdWUgPSBuZXcgTWFwPHN0cmluZywgRG9jUHJvbXB0PigpO1xuICBmb3IgKGNvbnN0IHByb21wdCBvZiBkaXNjb3ZlcmVkKSB7XG4gICAgaWYgKCF1bmlxdWUuaGFzKHByb21wdC5uYW1lKSkge1xuICAgICAgdW5pcXVlLnNldChwcm9tcHQubmFtZSwgcHJvbXB0KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gQXJyYXkuZnJvbSh1bmlxdWUudmFsdWVzKCkpLnNvcnQoKGEsIGIpID0+XG4gICAgYS5uYW1lLmxvY2FsZUNvbXBhcmUoYi5uYW1lKVxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2VsZWN0UHJvbXB0KFxuICBwcm9tcHRMaXN0OiBEb2NQcm9tcHRbXSxcbiAgcmVxdWVzdGVkTmFtZTogc3RyaW5nXG4pOiBEb2NQcm9tcHQge1xuICBjb25zdCBkaXJlY3QgPSBwcm9tcHRMaXN0LmZpbmQoKHByb21wdCkgPT4gcHJvbXB0Lm5hbWUgPT09IHJlcXVlc3RlZE5hbWUpO1xuICBpZiAoZGlyZWN0KSByZXR1cm4gZGlyZWN0O1xuXG4gIGNvbnN0IGZhbGxiYWNrID0gcHJvbXB0TGlzdC5maW5kKFxuICAgIChwcm9tcHQpID0+IHByb21wdC5uYW1lID09PSBERUZBVUxUX1BST01QVF9OQU1FXG4gICk7XG4gIGlmIChmYWxsYmFjaykgcmV0dXJuIGZhbGxiYWNrO1xuXG4gIGlmICghcHJvbXB0TGlzdC5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyBkb2N1bWVudGF0aW9uIHByb21wdHMgYXZhaWxhYmxlXCIpO1xuICB9XG5cbiAgcmV0dXJuIHByb21wdExpc3RbMF07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZERvY3VtZW50YXRpb25QYXlsb2FkKHtcbiAgZmlsZVBhdGgsXG4gIGZpbGVDb250ZW50LFxuICBwcm9tcHQsXG4gIGluY2x1ZGVQcm9tcHQsXG4gIGluY2x1ZGVDb2RlLFxuICBpbmNsdWRlTWV0YWRhdGEsXG4gIGFkZGl0aW9uYWxDb250ZXh0LFxufToge1xuICBmaWxlUGF0aDogc3RyaW5nO1xuICBmaWxlQ29udGVudDogc3RyaW5nO1xuICBwcm9tcHQ6IERvY1Byb21wdDtcbiAgaW5jbHVkZVByb21wdDogYm9vbGVhbjtcbiAgaW5jbHVkZUNvZGU6IGJvb2xlYW47XG4gIGluY2x1ZGVNZXRhZGF0YTogYm9vbGVhbjtcbiAgYWRkaXRpb25hbENvbnRleHQ/OiBzdHJpbmc7XG59KTogQ29udGVudFJlc3VsdCB7XG4gIGNvbnN0IHNlY3Rpb25zOiBzdHJpbmdbXSA9IFtdO1xuXG4gIGlmIChpbmNsdWRlTWV0YWRhdGEpIHtcbiAgICBzZWN0aW9ucy5wdXNoKFxuICAgICAgYCMgRG9jdW1lbnRhdGlvbiBSZXF1ZXN0XFxuLSBwcm9tcHQ6ICR7cHJvbXB0Lm5hbWV9XFxuLSBmaWxlOiAke2ZpbGVQYXRofWBcbiAgICApO1xuICB9XG5cbiAgaWYgKGluY2x1ZGVQcm9tcHQpIHtcbiAgICBzZWN0aW9ucy5wdXNoKFxuICAgICAgYCMjIFByb21wdCBHdWlkYW5jZSAoJHtwcm9tcHQudGl0bGV9KVxcblxcbiR7cHJvbXB0LmNvbnRlbnQudHJpbSgpfWBcbiAgICApO1xuICB9XG5cbiAgaWYgKGFkZGl0aW9uYWxDb250ZXh0Py50cmltKCkpIHtcbiAgICBzZWN0aW9ucy5wdXNoKGAjIyBBZGRpdGlvbmFsIENvbnRleHRcXG5cXG4ke2FkZGl0aW9uYWxDb250ZXh0LnRyaW0oKX1gKTtcbiAgfVxuXG4gIGlmIChpbmNsdWRlQ29kZSkge1xuICAgIHNlY3Rpb25zLnB1c2goXG4gICAgICBgIyMgU291cmNlXFxuXFxuXFxgXFxgXFxgJHtpbmZlckxhbmd1YWdlRnJvbVBhdGgoZmlsZVBhdGgpfVxcbiR7ZmlsZUNvbnRlbnR9XFxuXFxgXFxgXFxgYFxuICAgICk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGNvbnRlbnQ6IFtcbiAgICAgIHtcbiAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgIHRleHQ6IHNlY3Rpb25zLmpvaW4oXCJcXG5cXG5cIiksXG4gICAgICB9LFxuICAgIF0sXG4gIH0gc2F0aXNmaWVzIENvbnRlbnRSZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIGV4dHJhY3REZXNjcmlwdGlvbihjb250ZW50OiBzdHJpbmcsIGZpbGVQYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBmaXJzdExpbmUgPSBjb250ZW50XG4gICAgLnNwbGl0KC9cXHI/XFxuLylcbiAgICAubWFwKChsaW5lKSA9PiBsaW5lLnRyaW0oKSlcbiAgICAuZmluZCgobGluZSkgPT4gbGluZS5sZW5ndGggPiAwKTtcblxuICByZXR1cm4gKFxuICAgIGZpcnN0TGluZT8uc2xpY2UoMCwgMjQwKSA/P1xuICAgIGBEb2N1bWVudGF0aW9uIHByb21wdCBsb2FkZWQgZnJvbSAke3BhdGguYmFzZW5hbWUoZmlsZVBhdGgpfWBcbiAgKTtcbn1cblxuZnVuY3Rpb24gdG9UaXRsZUNhc2UodmFsdWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiB2YWx1ZVxuICAgIC5zcGxpdCgvXFxzKy8pXG4gICAgLmZpbHRlcihCb29sZWFuKVxuICAgIC5tYXAoKHBhcnQpID0+IHBhcnQuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBwYXJ0LnNsaWNlKDEpLnRvTG93ZXJDYXNlKCkpXG4gICAgLmpvaW4oXCIgXCIpO1xufVxuXG5mdW5jdGlvbiBpbmZlckxhbmd1YWdlRnJvbVBhdGgoZmlsZVBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IGV4dGVuc2lvbiA9IHBhdGguZXh0bmFtZShmaWxlUGF0aCkudG9Mb3dlckNhc2UoKTtcbiAgc3dpdGNoIChleHRlbnNpb24pIHtcbiAgICBjYXNlIFwiLnRzXCI6XG4gICAgY2FzZSBcIi50c3hcIjpcbiAgICAgIHJldHVybiBcInRzXCI7XG4gICAgY2FzZSBcIi5qc1wiOlxuICAgIGNhc2UgXCIuanN4XCI6XG4gICAgICByZXR1cm4gXCJqc1wiO1xuICAgIGNhc2UgXCIuanNvblwiOlxuICAgICAgcmV0dXJuIFwianNvblwiO1xuICAgIGNhc2UgXCIubWRcIjpcbiAgICAgIHJldHVybiBcIm1kXCI7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBcInRleHRcIjtcbiAgfVxufVxuXG5leHBvcnQgeyBERUZBVUxUX1BST01QVF9OQU1FIH07XG5leHBvcnQgdHlwZSB7IERvY1Byb21wdCB9O1xuIiwiaW1wb3J0IHR5cGUgeyBJbnB1dFByb21wdCB9IGZyb20gXCJmYXN0bWNwXCI7XG5pbXBvcnQgeyBwcm9tcHRzLCByZWZyZXNoUHJvbXB0cyB9IGZyb20gXCIuL3Byb21wdHNcIjtcblxuZXhwb3J0ICogZnJvbSBcIi4vcHJvbXB0c1wiO1xuXG5leHBvcnQgY29uc3QgcHJvbXB0TGlzdDogSW5wdXRQcm9tcHQ8dW5kZWZpbmVkPltdID0gcHJvbXB0cztcblxuZXhwb3J0IGZ1bmN0aW9uIGxvYWRQcm9tcHRzKHJlcG9QYXRoPzogc3RyaW5nKTogSW5wdXRQcm9tcHQ8dW5kZWZpbmVkPltdIHtcbiAgcmV0dXJuIHJlZnJlc2hQcm9tcHRzKHJlcG9QYXRoKTtcbn1cbiIsImltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5cbmV4cG9ydCB0eXBlIERlY29yYXRvclNwZWMgPSB7XG4gIG5hbWU6IHN0cmluZztcbiAgYXJncz86IHVua25vd25bXTtcbn07XG5cbmV4cG9ydCB0eXBlIEF0dHJpYnV0ZVNwZWMgPSB7XG4gIG5hbWU6IHN0cmluZztcbiAgdHlwZTogc3RyaW5nO1xuICBkZWNvcmF0b3JzPzogRGVjb3JhdG9yU3BlY1tdO1xufTtcblxuZnVuY3Rpb24gZXNjYXBlUmVnRXhwKHZhbHVlOiBzdHJpbmcpIHtcbiAgcmV0dXJuIHZhbHVlLnJlcGxhY2UoL1suKis/XiR7fSgpfFtcXF1cXFxcXS9nLCBcIlxcXFwkJlwiKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0RGVjb3JhdG9yKHNwZWM6IERlY29yYXRvclNwZWMpOiBzdHJpbmcge1xuICBjb25zdCBhcmdzID0gKHNwZWMuYXJncyB8fCBbXSkubWFwKChhcmcpID0+IEpTT04uc3RyaW5naWZ5KGFyZykpLmpvaW4oXCIsIFwiKTtcbiAgcmV0dXJuIGBAJHtzcGVjLm5hbWV9KCR7YXJnc30pYDtcbn1cblxuZnVuY3Rpb24gZW5zdXJlRGlyZWN0b3J5KGZpbGVQYXRoOiBzdHJpbmcpIHtcbiAgZnMubWtkaXJTeW5jKHBhdGguZGlybmFtZShmaWxlUGF0aCksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xufVxuXG5mdW5jdGlvbiBjb2xsZWN0RGVjb3JhdG9yTmFtZXMoXG4gIGNsYXNzRGVjb3JhdG9yczogRGVjb3JhdG9yU3BlY1tdIHwgdW5kZWZpbmVkLFxuICBwcm9wZXJ0aWVzOiBBdHRyaWJ1dGVTcGVjW10gfCB1bmRlZmluZWRcbikge1xuICBjb25zdCBuYW1lcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBuYW1lcy5hZGQoXCJtb2RlbFwiKTtcbiAgZm9yIChjb25zdCBkZWNvcmF0b3Igb2YgY2xhc3NEZWNvcmF0b3JzIHx8IFtdKSB7XG4gICAgbmFtZXMuYWRkKGRlY29yYXRvci5uYW1lKTtcbiAgfVxuICBmb3IgKGNvbnN0IHByb3BlcnR5IG9mIHByb3BlcnRpZXMgfHwgW10pIHtcbiAgICBmb3IgKGNvbnN0IGRlY29yYXRvciBvZiBwcm9wZXJ0eS5kZWNvcmF0b3JzIHx8IFtdKSB7XG4gICAgICBuYW1lcy5hZGQoZGVjb3JhdG9yLm5hbWUpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbmFtZXM7XG59XG5cbmZ1bmN0aW9uIGVuc3VyZUltcG9ydChcbiAgY29udGVudDogc3RyaW5nLFxuICBpbXBvcnRzRnJvbTogc3RyaW5nLFxuICBkZWNvcmF0b3JzOiBTZXQ8c3RyaW5nPlxuKSB7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gIGlmICghZGVjb3JhdG9ycy5zaXplKSByZXR1cm4gY29udGVudDtcbiAgY29uc3QgaW1wb3J0UmVnZXggPSBuZXcgUmVnRXhwKFxuICAgIGBpbXBvcnRcXFxccytcXFxceyhbXn1dKylcXFxcfVxcXFxzK2Zyb21cXFxccytbXCInXSR7ZXNjYXBlUmVnRXhwKGltcG9ydHNGcm9tKX1bXCInXTtgXG4gICk7XG4gIGNvbnN0IG1hdGNoID0gY29udGVudC5tYXRjaChpbXBvcnRSZWdleCk7XG4gIGNvbnN0IHNvcnRlZCA9IEFycmF5LmZyb20oZGVjb3JhdG9ycykuc29ydCgpO1xuXG4gIGlmIChtYXRjaCkge1xuICAgIGNvbnN0IGV4aXN0aW5nID0gbWF0Y2hbMV1cbiAgICAgIC5zcGxpdChcIixcIilcbiAgICAgIC5tYXAoKG5hbWUpID0+IG5hbWUudHJpbSgpKVxuICAgICAgLmZpbHRlcihCb29sZWFuKTtcbiAgICBjb25zdCBtZXJnZWQgPSBBcnJheS5mcm9tKG5ldyBTZXQoWy4uLmV4aXN0aW5nLCAuLi5zb3J0ZWRdKSkuc29ydCgpO1xuICAgIHJldHVybiBjb250ZW50LnJlcGxhY2UoXG4gICAgICBpbXBvcnRSZWdleCxcbiAgICAgIGBpbXBvcnQgeyAke21lcmdlZC5qb2luKFwiLCBcIil9IH0gZnJvbSBcIiR7aW1wb3J0c0Zyb219XCI7YFxuICAgICk7XG4gIH1cblxuICBjb25zdCBpbXBvcnRMaW5lID0gYGltcG9ydCB7ICR7c29ydGVkLmpvaW4oXCIsIFwiKX0gfSBmcm9tIFwiJHtpbXBvcnRzRnJvbX1cIjtgO1xuICByZXR1cm4gYCR7aW1wb3J0TGluZX1cXG5cXG4ke2NvbnRlbnR9YDtcbn1cblxuZnVuY3Rpb24gYWRkUHJvcGVydHlCbG9jayhwcm9wZXJ0eTogQXR0cmlidXRlU3BlYykge1xuICBjb25zdCBkZWNvcmF0b3JzID0gKHByb3BlcnR5LmRlY29yYXRvcnMgfHwgW10pXG4gICAgLm1hcChmb3JtYXREZWNvcmF0b3IpXG4gICAgLmpvaW4oXCJcXG4gIFwiKTtcbiAgY29uc3QgZGVjb3JhdG9yQmxvY2sgPSBkZWNvcmF0b3JzID8gYCAgJHtkZWNvcmF0b3JzfVxcbmAgOiBcIlwiO1xuICByZXR1cm4gYCR7ZGVjb3JhdG9yQmxvY2t9ICAke3Byb3BlcnR5Lm5hbWV9OiAke3Byb3BlcnR5LnR5cGV9O2A7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZVByb3BlcnR5QmxvY2soY29udGVudDogc3RyaW5nLCBwcm9wZXJ0eU5hbWU6IHN0cmluZykge1xuICBjb25zdCBsaW5lcyA9IGNvbnRlbnQuc3BsaXQoL1xccj9cXG4vKTtcbiAgY29uc3QgcmVzdWx0OiBzdHJpbmdbXSA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgbGluZSA9IGxpbmVzW2ldO1xuICAgIGlmIChcbiAgICAgIGxpbmUudHJpbSgpLnN0YXJ0c1dpdGgoYEBgKSAmJlxuICAgICAgbGluZXNbaSArIDFdPy5pbmNsdWRlcyhgJHtwcm9wZXJ0eU5hbWV9OmApXG4gICAgKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKGxpbmUuaW5jbHVkZXMoYCR7cHJvcGVydHlOYW1lfTpgKSkge1xuICAgICAgLy8gc2tpcCB0aGlzIGxpbmUgYW5kIGFueSB0cmFpbGluZyBibGFuayBsaW5lXG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgcmVzdWx0LnB1c2gobGluZSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdC5qb2luKFwiXFxuXCIpO1xufVxuXG5mdW5jdGlvbiBpbnNlcnREZWNvcmF0b3IoXG4gIGNvbnRlbnQ6IHN0cmluZyxcbiAgZGVjb3JhdG9yOiBEZWNvcmF0b3JTcGVjLFxuICB0YXJnZXQ6IHtcbiAgICBraW5kOiBcImNsYXNzXCIgfCBcInByb3BlcnR5XCI7XG4gICAgbmFtZT86IHN0cmluZztcbiAgfVxuKSB7XG4gIGNvbnN0IGRlY29yYXRvckxpbmUgPSBmb3JtYXREZWNvcmF0b3IoZGVjb3JhdG9yKTtcbiAgaWYgKHRhcmdldC5raW5kID09PSBcImNsYXNzXCIpIHtcbiAgICBjb25zdCBjbGFzc1JlZ2V4ID0gLyhleHBvcnRcXHMrY2xhc3NcXHMrW15cXHN7XStcXHMqXFx7KS87XG4gICAgaWYgKGNvbnRlbnQuaW5jbHVkZXMoZGVjb3JhdG9yTGluZSkpIHJldHVybiBjb250ZW50O1xuICAgIHJldHVybiBjb250ZW50LnJlcGxhY2UoY2xhc3NSZWdleCwgYCR7ZGVjb3JhdG9yTGluZX1cXG4kMWApO1xuICB9XG4gIGlmICghdGFyZ2V0Lm5hbWUpIHJldHVybiBjb250ZW50O1xuICBjb25zdCBwcm9wZXJ0eVJlZ2V4ID0gbmV3IFJlZ0V4cChcbiAgICBgKF5cXFxccyopKD86QC4qXFxcXG5cXFxcMSkqJHtlc2NhcGVSZWdFeHAodGFyZ2V0Lm5hbWUpfTpgLFxuICAgIFwibVwiXG4gICk7XG4gIGNvbnN0IG1hdGNoID0gcHJvcGVydHlSZWdleC5leGVjKGNvbnRlbnQpO1xuICBpZiAoIW1hdGNoKSByZXR1cm4gY29udGVudDtcbiAgY29uc3QgaW5kZW50ID0gbWF0Y2hbMV0gfHwgXCIgIFwiO1xuICBpZiAoY29udGVudC5pbmNsdWRlcyhgJHtpbmRlbnR9JHtkZWNvcmF0b3JMaW5lfWApKSByZXR1cm4gY29udGVudDtcbiAgcmV0dXJuIChcbiAgICBjb250ZW50LnNsaWNlKDAsIG1hdGNoLmluZGV4KSArXG4gICAgYCR7aW5kZW50fSR7ZGVjb3JhdG9yTGluZX1cXG5gICtcbiAgICBjb250ZW50LnNsaWNlKG1hdGNoLmluZGV4KVxuICApO1xufVxuXG5mdW5jdGlvbiByZW1vdmVEZWNvcmF0b3IoXG4gIGNvbnRlbnQ6IHN0cmluZyxcbiAgZGVjb3JhdG9yTmFtZTogc3RyaW5nLFxuICB0YXJnZXQ6IHtcbiAgICBraW5kOiBcImNsYXNzXCIgfCBcInByb3BlcnR5XCI7XG4gICAgbmFtZT86IHN0cmluZztcbiAgfVxuKSB7XG4gIGNvbnN0IGRlY29yYXRvclJlZ2V4ID0gbmV3IFJlZ0V4cChcbiAgICBgXlxcXFxzKkAke2VzY2FwZVJlZ0V4cChkZWNvcmF0b3JOYW1lKX1cXFxcKFteKV0qXFxcXClgLFxuICAgIFwibVwiXG4gICk7XG4gIGlmICh0YXJnZXQua2luZCA9PT0gXCJjbGFzc1wiKSB7XG4gICAgcmV0dXJuIGNvbnRlbnQucmVwbGFjZShkZWNvcmF0b3JSZWdleCwgXCJcIik7XG4gIH1cbiAgaWYgKHRhcmdldC5uYW1lKSB7XG4gICAgY29uc3QgcGF0dGVybiA9IG5ldyBSZWdFeHAoXG4gICAgICBgKF5cXFxccypAJHtlc2NhcGVSZWdFeHAoZGVjb3JhdG9yTmFtZSl9XFxcXChbXildKlxcXFwpXFxcXHMqJFxcXFxuKSg/PVxcXFxzKiR7ZXNjYXBlUmVnRXhwKHRhcmdldC5uYW1lKX06KWAsXG4gICAgICBcIm1cIlxuICAgICk7XG4gICAgcmV0dXJuIGNvbnRlbnQucmVwbGFjZShwYXR0ZXJuLCBcIlwiKTtcbiAgfVxuICByZXR1cm4gY29udGVudDtcbn1cblxuZnVuY3Rpb24gd3JpdGVJZkNoYW5nZWQoZmlsZVBhdGg6IHN0cmluZywgY29udGVudDogc3RyaW5nKSB7XG4gIGVuc3VyZURpcmVjdG9yeShmaWxlUGF0aCk7XG4gIGZzLndyaXRlRmlsZVN5bmMoZmlsZVBhdGgsIGNvbnRlbnQpO1xufVxuXG5leHBvcnQgY29uc3QgZGVjb3JhdG9yVG9vbHMgPSB7XG4gIGNyZWF0ZU9yVXBkYXRlTW9kZWxUb29sOiB7XG4gICAgbmFtZTogXCJjcmVhdGUtb3ItdXBkYXRlLW1vZGVsXCIsXG4gICAgZGVzY3JpcHRpb246IFwiQ3JlYXRlIG9yIHVwZGF0ZSBhIHZhbGlkYXRpb24tcmVhZHkgbW9kZWwgY2xhc3NcIixcbiAgICBleGVjdXRlOiBhc3luYyAoYXJnczoge1xuICAgICAgZmlsZVBhdGg6IHN0cmluZztcbiAgICAgIGNsYXNzTmFtZTogc3RyaW5nO1xuICAgICAgY2xhc3NEZWNvcmF0b3JzPzogRGVjb3JhdG9yU3BlY1tdO1xuICAgICAgcHJvcGVydGllczogQXR0cmlidXRlU3BlY1tdO1xuICAgICAgaW1wb3J0c0Zyb206IHN0cmluZztcbiAgICAgIG92ZXJ3cml0ZT86IGJvb2xlYW47XG4gICAgfSkgPT4ge1xuICAgICAgaWYgKCFhcmdzLm92ZXJ3cml0ZSAmJiBmcy5leGlzdHNTeW5jKGFyZ3MuZmlsZVBhdGgpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgRmlsZSBhbHJlYWR5IGV4aXN0cyBhdCAke2FyZ3MuZmlsZVBhdGh9YCk7XG4gICAgICB9XG4gICAgICBjb25zdCBkZWNvcmF0b3JzID0gY29sbGVjdERlY29yYXRvck5hbWVzKFxuICAgICAgICBhcmdzLmNsYXNzRGVjb3JhdG9ycyxcbiAgICAgICAgYXJncy5wcm9wZXJ0aWVzXG4gICAgICApO1xuICAgICAgbGV0IGNvbnRlbnQgPSBgQG1vZGVsKClgO1xuICAgICAgZm9yIChjb25zdCBkZWNvcmF0b3Igb2YgYXJncy5jbGFzc0RlY29yYXRvcnMgfHwgW10pIHtcbiAgICAgICAgY29udGVudCArPSBgXFxuJHtmb3JtYXREZWNvcmF0b3IoZGVjb3JhdG9yKX1gO1xuICAgICAgfVxuICAgICAgY29uc3QgcHJvcGVydGllcyA9IChhcmdzLnByb3BlcnRpZXMgfHwgW10pXG4gICAgICAgIC5tYXAoYWRkUHJvcGVydHlCbG9jaylcbiAgICAgICAgLmpvaW4oXCJcXG5cXG5cIik7XG4gICAgICBjb250ZW50ICs9IGBcXG5leHBvcnQgY2xhc3MgJHthcmdzLmNsYXNzTmFtZX0ge1xcbiR7cHJvcGVydGllcyA/IGAke3Byb3BlcnRpZXN9XFxuYCA6IFwiXCJ9fVxcbmA7XG4gICAgICBjb250ZW50ID0gZW5zdXJlSW1wb3J0KGNvbnRlbnQsIGFyZ3MuaW1wb3J0c0Zyb20sIGRlY29yYXRvcnMpO1xuICAgICAgd3JpdGVJZkNoYW5nZWQoYXJncy5maWxlUGF0aCwgY29udGVudCk7XG4gICAgICByZXR1cm4geyBmaWxlUGF0aDogYXJncy5maWxlUGF0aCB9O1xuICAgIH0sXG4gIH0sXG4gIGFkZEF0dHJpYnV0ZVRvb2w6IHtcbiAgICBuYW1lOiBcImFkZC1hdHRyaWJ1dGVcIixcbiAgICBkZXNjcmlwdGlvbjogXCJBZGQgYSBkZWNvcmF0ZWQgYXR0cmlidXRlIHRvIGFuIGV4aXN0aW5nIG1vZGVsXCIsXG4gICAgZXhlY3V0ZTogYXN5bmMgKGFyZ3M6IHtcbiAgICAgIGZpbGVQYXRoOiBzdHJpbmc7XG4gICAgICBjbGFzc05hbWU6IHN0cmluZztcbiAgICAgIGF0dHJpYnV0ZTogQXR0cmlidXRlU3BlYztcbiAgICAgIGltcG9ydHNGcm9tOiBzdHJpbmc7XG4gICAgfSkgPT4ge1xuICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKGFyZ3MuZmlsZVBhdGgpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTW9kZWwgZmlsZSBub3QgZm91bmQgYXQgJHthcmdzLmZpbGVQYXRofWApO1xuICAgICAgfVxuICAgICAgbGV0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoYXJncy5maWxlUGF0aCwgXCJ1dGY4XCIpO1xuICAgICAgaWYgKGNvbnRlbnQuaW5jbHVkZXMoYCR7YXJncy5hdHRyaWJ1dGUubmFtZX06YCkpIHtcbiAgICAgICAgcmV0dXJuIHsgZmlsZVBhdGg6IGFyZ3MuZmlsZVBhdGggfTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRlY29yYXRvcnMgPSBjb2xsZWN0RGVjb3JhdG9yTmFtZXModW5kZWZpbmVkLCBbYXJncy5hdHRyaWJ1dGVdKTtcbiAgICAgIGNvbnRlbnQgPSBlbnN1cmVJbXBvcnQoY29udGVudCwgYXJncy5pbXBvcnRzRnJvbSwgZGVjb3JhdG9ycyk7XG4gICAgICBjb25zdCBpbnNlcnRpb25Qb2ludCA9IGNvbnRlbnQubGFzdEluZGV4T2YoXCJ9XCIpO1xuICAgICAgY29uc3QgYmxvY2sgPSBhZGRQcm9wZXJ0eUJsb2NrKGFyZ3MuYXR0cmlidXRlKTtcbiAgICAgIGNvbnN0IGJlZm9yZSA9IGNvbnRlbnQuc2xpY2UoMCwgaW5zZXJ0aW9uUG9pbnQpLnJlcGxhY2UoL1xccyokLywgXCJcIik7XG4gICAgICBjb25zdCBhZnRlciA9IGNvbnRlbnQuc2xpY2UoaW5zZXJ0aW9uUG9pbnQpO1xuICAgICAgY29uc3QgdXBkYXRlZCA9IGAke2JlZm9yZX1cXG4ke2Jsb2NrfVxcbiR7YWZ0ZXJ9YDtcbiAgICAgIHdyaXRlSWZDaGFuZ2VkKGFyZ3MuZmlsZVBhdGgsIHVwZGF0ZWQpO1xuICAgICAgcmV0dXJuIHsgZmlsZVBhdGg6IGFyZ3MuZmlsZVBhdGggfTtcbiAgICB9LFxuICB9LFxuICByZW1vdmVBdHRyaWJ1dGVUb29sOiB7XG4gICAgbmFtZTogXCJyZW1vdmUtYXR0cmlidXRlXCIsXG4gICAgZGVzY3JpcHRpb246IFwiUmVtb3ZlIGFuIGF0dHJpYnV0ZSBmcm9tIGEgbW9kZWwgY2xhc3NcIixcbiAgICBleGVjdXRlOiBhc3luYyAoYXJnczoge1xuICAgICAgZmlsZVBhdGg6IHN0cmluZztcbiAgICAgIGNsYXNzTmFtZTogc3RyaW5nO1xuICAgICAgYXR0cmlidXRlTmFtZTogc3RyaW5nO1xuICAgIH0pID0+IHtcbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyhhcmdzLmZpbGVQYXRoKSkgcmV0dXJuIHsgZmlsZVBhdGg6IGFyZ3MuZmlsZVBhdGggfTtcbiAgICAgIGNvbnN0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoYXJncy5maWxlUGF0aCwgXCJ1dGY4XCIpO1xuICAgICAgY29uc3QgdXBkYXRlZCA9IHJlbW92ZVByb3BlcnR5QmxvY2soY29udGVudCwgYXJncy5hdHRyaWJ1dGVOYW1lKTtcbiAgICAgIHdyaXRlSWZDaGFuZ2VkKGFyZ3MuZmlsZVBhdGgsIHVwZGF0ZWQpO1xuICAgICAgcmV0dXJuIHsgZmlsZVBhdGg6IGFyZ3MuZmlsZVBhdGggfTtcbiAgICB9LFxuICB9LFxuICBhcHBseURlY29yYXRvclRvb2w6IHtcbiAgICBuYW1lOiBcImFwcGx5LWRlY29yYXRvclwiLFxuICAgIGRlc2NyaXB0aW9uOiBcIkFwcGx5IGEgZGVjb3JhdG9yIHRvIGEgY2xhc3Mgb3IgcHJvcGVydHlcIixcbiAgICBleGVjdXRlOiBhc3luYyAoYXJnczoge1xuICAgICAgZmlsZVBhdGg6IHN0cmluZztcbiAgICAgIGNsYXNzTmFtZTogc3RyaW5nO1xuICAgICAgdGFyZ2V0OiB7IGtpbmQ6IFwiY2xhc3NcIiB8IFwicHJvcGVydHlcIjsgbmFtZT86IHN0cmluZyB9O1xuICAgICAgZGVjb3JhdG9yOiBEZWNvcmF0b3JTcGVjO1xuICAgICAgaW1wb3J0c0Zyb206IHN0cmluZztcbiAgICB9KSA9PiB7XG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoYXJncy5maWxlUGF0aCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBNb2RlbCBmaWxlIG5vdCBmb3VuZCBhdCAke2FyZ3MuZmlsZVBhdGh9YCk7XG4gICAgICB9XG4gICAgICBsZXQgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhhcmdzLmZpbGVQYXRoLCBcInV0ZjhcIik7XG4gICAgICBjb25zdCBkZWNvcmF0b3JzID0gbmV3IFNldDxzdHJpbmc+KFthcmdzLmRlY29yYXRvci5uYW1lXSk7XG4gICAgICBjb250ZW50ID0gZW5zdXJlSW1wb3J0KGNvbnRlbnQsIGFyZ3MuaW1wb3J0c0Zyb20sIGRlY29yYXRvcnMpO1xuICAgICAgY29udGVudCA9IGluc2VydERlY29yYXRvcihjb250ZW50LCBhcmdzLmRlY29yYXRvciwgYXJncy50YXJnZXQpO1xuICAgICAgd3JpdGVJZkNoYW5nZWQoYXJncy5maWxlUGF0aCwgY29udGVudCk7XG4gICAgICByZXR1cm4geyBmaWxlUGF0aDogYXJncy5maWxlUGF0aCB9O1xuICAgIH0sXG4gIH0sXG4gIHJlbW92ZURlY29yYXRvclRvb2w6IHtcbiAgICBuYW1lOiBcInJlbW92ZS1kZWNvcmF0b3JcIixcbiAgICBkZXNjcmlwdGlvbjogXCJSZW1vdmUgYSBkZWNvcmF0b3IgZnJvbSBhIGNsYXNzIG9yIHByb3BlcnR5XCIsXG4gICAgZXhlY3V0ZTogYXN5bmMgKGFyZ3M6IHtcbiAgICAgIGZpbGVQYXRoOiBzdHJpbmc7XG4gICAgICBjbGFzc05hbWU6IHN0cmluZztcbiAgICAgIHRhcmdldDogeyBraW5kOiBcImNsYXNzXCIgfCBcInByb3BlcnR5XCI7IG5hbWU/OiBzdHJpbmcgfTtcbiAgICAgIGRlY29yYXRvck5hbWU6IHN0cmluZztcbiAgICB9KSA9PiB7XG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoYXJncy5maWxlUGF0aCkpIHJldHVybiB7IGZpbGVQYXRoOiBhcmdzLmZpbGVQYXRoIH07XG4gICAgICBsZXQgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhhcmdzLmZpbGVQYXRoLCBcInV0ZjhcIik7XG4gICAgICBjb250ZW50ID0gcmVtb3ZlRGVjb3JhdG9yKGNvbnRlbnQsIGFyZ3MuZGVjb3JhdG9yTmFtZSwgYXJncy50YXJnZXQpO1xuICAgICAgd3JpdGVJZkNoYW5nZWQoYXJncy5maWxlUGF0aCwgY29udGVudCk7XG4gICAgICByZXR1cm4geyBmaWxlUGF0aDogYXJncy5maWxlUGF0aCB9O1xuICAgIH0sXG4gIH0sXG4gIHNjYWZmb2xkVmFsaWRhdG9yVG9vbDoge1xuICAgIG5hbWU6IFwic2NhZmZvbGQtdmFsaWRhdG9yXCIsXG4gICAgZGVzY3JpcHRpb246IFwiU2NhZmZvbGQgYSB2YWxpZGF0b3IgY2xhc3MgYW5kIG9wdGlvbmFsIGRlY29yYXRvclwiLFxuICAgIGV4ZWN1dGU6IGFzeW5jIChhcmdzOiB7XG4gICAgICB2YWxpZGF0b3JzRGlyOiBzdHJpbmc7XG4gICAgICBkZWNvcmF0b3JEaXI/OiBzdHJpbmc7XG4gICAgICBuYW1lOiBzdHJpbmc7XG4gICAgfSkgPT4ge1xuICAgICAgY29uc3QgY2xhc3NGaWxlID0gcGF0aC5qb2luKGFyZ3MudmFsaWRhdG9yc0RpciwgYCR7YXJncy5uYW1lfS50c2ApO1xuICAgICAgZW5zdXJlRGlyZWN0b3J5KGNsYXNzRmlsZSk7XG4gICAgICBjb25zdCBjbGFzc0NvbnRlbnQgPSBgZXhwb3J0IGNsYXNzICR7YXJncy5uYW1lfSB7XFxuICB2YWxpZGF0ZSh2YWx1ZTogdW5rbm93bik6IGJvb2xlYW4ge1xcbiAgICByZXR1cm4gdmFsdWUgIT09IHVuZGVmaW5lZDtcXG4gIH1cXG59XFxuYDtcbiAgICAgIGZzLndyaXRlRmlsZVN5bmMoY2xhc3NGaWxlLCBjbGFzc0NvbnRlbnQpO1xuICAgICAgbGV0IGRlY29yYXRvckZpbGU6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICAgIGlmIChhcmdzLmRlY29yYXRvckRpcikge1xuICAgICAgICBkZWNvcmF0b3JGaWxlID0gcGF0aC5qb2luKFxuICAgICAgICAgIGFyZ3MuZGVjb3JhdG9yRGlyLFxuICAgICAgICAgIGAke2FyZ3MubmFtZX1EZWNvcmF0b3IudHNgXG4gICAgICAgICk7XG4gICAgICAgIGVuc3VyZURpcmVjdG9yeShkZWNvcmF0b3JGaWxlKTtcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyhcbiAgICAgICAgICBkZWNvcmF0b3JGaWxlLFxuICAgICAgICAgIGBleHBvcnQgZnVuY3Rpb24gJHthcmdzLm5hbWV9RGVjb3JhdG9yKCkge1xcbiAgcmV0dXJuICgpID0+IHZvaWQgMDtcXG59XFxuYFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHsgY2xhc3NGaWxlLCBkZWNvcmF0b3JGaWxlIH07XG4gICAgfSxcbiAgfSxcbiAgc2NhZmZvbGRTZXJpYWxpemVyVG9vbDoge1xuICAgIG5hbWU6IFwic2NhZmZvbGQtc2VyaWFsaXplclwiLFxuICAgIGRlc2NyaXB0aW9uOiBcIlNjYWZmb2xkIGEgc2VyaWFsaXplciBjbGFzcyBhbmQgb3B0aW9uYWwgcmVnaXN0cnlcIixcbiAgICBleGVjdXRlOiBhc3luYyAoYXJnczoge1xuICAgICAgZGlyOiBzdHJpbmc7XG4gICAgICBuYW1lOiBzdHJpbmc7XG4gICAgICByZWdpc3RlckRpcj86IHN0cmluZztcbiAgICAgIHNldERlZmF1bHQ/OiBib29sZWFuO1xuICAgIH0pID0+IHtcbiAgICAgIGNvbnN0IGNsYXNzRmlsZSA9IHBhdGguam9pbihhcmdzLmRpciwgYCR7YXJncy5uYW1lfS50c2ApO1xuICAgICAgZW5zdXJlRGlyZWN0b3J5KGNsYXNzRmlsZSk7XG4gICAgICBmcy53cml0ZUZpbGVTeW5jKFxuICAgICAgICBjbGFzc0ZpbGUsXG4gICAgICAgIGBleHBvcnQgY2xhc3MgJHthcmdzLm5hbWV9IHtcXG4gIHNlcmlhbGl6ZSh2YWx1ZTogdW5rbm93bik6IHN0cmluZyB7XFxuICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh2YWx1ZSk7XFxuICB9XFxufVxcbmBcbiAgICAgICk7XG4gICAgICBsZXQgcmVnaXN0ZXJGaWxlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgICBpZiAoYXJncy5yZWdpc3RlckRpcikge1xuICAgICAgICByZWdpc3RlckZpbGUgPSBwYXRoLmpvaW4oYXJncy5yZWdpc3RlckRpciwgYCR7YXJncy5uYW1lfVJlZ2lzdGVyLnRzYCk7XG4gICAgICAgIGVuc3VyZURpcmVjdG9yeShyZWdpc3RlckZpbGUpO1xuICAgICAgICBmcy53cml0ZUZpbGVTeW5jKFxuICAgICAgICAgIHJlZ2lzdGVyRmlsZSxcbiAgICAgICAgICBgZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyJHthcmdzLm5hbWV9KCkge1xcbiAgcmV0dXJuICR7YXJncy5zZXREZWZhdWx0ID8gXCInZGVmYXVsdCdcIiA6IFwiJ29wdGlvbmFsJ1wifTtcXG59XFxuYFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHsgY2xhc3NGaWxlLCByZWdpc3RlckZpbGUgfTtcbiAgICB9LFxuICB9LFxuICBzY2FmZm9sZEhhc2hpbmdUb29sOiB7XG4gICAgbmFtZTogXCJzY2FmZm9sZC1oYXNoaW5nXCIsXG4gICAgZGVzY3JpcHRpb246IFwiU2NhZmZvbGQgYSBoYXNoaW5nIGZ1bmN0aW9uIGFuZCBvcHRpb25hbCByZWdpc3RyeVwiLFxuICAgIGV4ZWN1dGU6IGFzeW5jIChhcmdzOiB7XG4gICAgICBkaXI6IHN0cmluZztcbiAgICAgIG5hbWU6IHN0cmluZztcbiAgICAgIHJlZ2lzdGVyRGlyPzogc3RyaW5nO1xuICAgICAgc2V0RGVmYXVsdD86IGJvb2xlYW47XG4gICAgfSkgPT4ge1xuICAgICAgY29uc3QgZnVuY3Rpb25GaWxlID0gcGF0aC5qb2luKGFyZ3MuZGlyLCBgJHthcmdzLm5hbWV9LnRzYCk7XG4gICAgICBlbnN1cmVEaXJlY3RvcnkoZnVuY3Rpb25GaWxlKTtcbiAgICAgIGZzLndyaXRlRmlsZVN5bmMoXG4gICAgICAgIGZ1bmN0aW9uRmlsZSxcbiAgICAgICAgYGV4cG9ydCBmdW5jdGlvbiAke2FyZ3MubmFtZX0odmFsdWU6IHN0cmluZyk6IHN0cmluZyB7XFxuICByZXR1cm4gdmFsdWUuc3BsaXQoJycpLnJldmVyc2UoKS5qb2luKCcnKTtcXG59XFxuYFxuICAgICAgKTtcbiAgICAgIGxldCByZWdpc3RlckZpbGU6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICAgIGlmIChhcmdzLnJlZ2lzdGVyRGlyKSB7XG4gICAgICAgIHJlZ2lzdGVyRmlsZSA9IHBhdGguam9pbihhcmdzLnJlZ2lzdGVyRGlyLCBgJHthcmdzLm5hbWV9UmVnaXN0ZXIudHNgKTtcbiAgICAgICAgZW5zdXJlRGlyZWN0b3J5KHJlZ2lzdGVyRmlsZSk7XG4gICAgICAgIGZzLndyaXRlRmlsZVN5bmMoXG4gICAgICAgICAgcmVnaXN0ZXJGaWxlLFxuICAgICAgICAgIGBleHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXIke2FyZ3MubmFtZX0oKSB7XFxuICByZXR1cm4gJHthcmdzLnNldERlZmF1bHQgPyBcIidkZWZhdWx0J1wiIDogXCInb3B0aW9uYWwnXCJ9O1xcbn1cXG5gXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4geyBmdW5jdGlvbkZpbGUsIHJlZ2lzdGVyRmlsZSB9O1xuICAgIH0sXG4gIH0sXG59IGFzIGNvbnN0O1xuXG5leHBvcnQgdHlwZSBEZWNvcmF0b3JUb29scyA9IHR5cGVvZiBkZWNvcmF0b3JUb29scztcbiIsImltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBzcGF3blN5bmMgfSBmcm9tIFwiY2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0IHR5cGUgeyBDb250ZW50UmVzdWx0LCBUb29sIH0gZnJvbSBcImZhc3RtY3BcIjtcbmltcG9ydCB7XG4gIGRvY3VtZW50T2JqZWN0U2NoZW1hLFxuICBjb3ZlcmFnZVRhc2tTY2hlbWEsXG4gIHJlYWRtZUltcHJvdmVtZW50U2NoZW1hLFxufSBmcm9tIFwiLi4vc2NoZW1hc1wiO1xuaW1wb3J0IHtcbiAgRG9jdW1lbnRPYmplY3RBcmdzLFxuICBDb3ZlcmFnZVRhc2tBcmdzLFxuICBSZWFkbWVJbXByb3ZlbWVudEFyZ3MsXG59IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHtcbiAgZ2V0V29ya3NwYWNlUm9vdCxcbiAgcmVzb2x2ZUluV29ya3NwYWNlLFxuICB0aHJvd1VzZXJFcnJvcixcbiAgV29ya3NwYWNlRXJyb3IsXG59IGZyb20gXCIuLi93b3Jrc3BhY2VcIjtcbmltcG9ydCB7XG4gIGJ1aWxkT2JqZWN0UHJvbXB0cyxcbiAgZGlzY292ZXJEb2NQcm9tcHRzLFxuICBnZXRPYmplY3RQcm9tcHREZXBlbmRlbmNpZXMsXG59IGZyb20gXCIuLi9wcm9tcHRzL3Byb21wdHNcIjtcbmltcG9ydCB0eXBlIHsgRG9jUHJvbXB0IH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBsaXN0RmlsZXNSZWN1cnNpdmUsIHJlYWRGaWxlU2FmZSB9IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IHsgYW5hbHl6ZVJlcG8sIGlzU291cmNlRmlsZSwgaXNUZXN0RmlsZSB9IGZyb20gXCIuLi9jb2RlXCI7XG5cbnR5cGUgUHJvbXB0U2VjdGlvbiA9IHtcbiAgbmFtZTogc3RyaW5nO1xuICB0aXRsZTogc3RyaW5nO1xuICBkZXNjcmlwdGlvbjogc3RyaW5nO1xuICBjb250ZW50OiBzdHJpbmc7XG4gIGFic29sdXRlUGF0aD86IHN0cmluZztcbn07XG5cbmZ1bmN0aW9uIHJlbGF0aXZlRmlsZXMocm9vdDogc3RyaW5nLCBmaWxlczogc3RyaW5nW10pOiBzdHJpbmdbXSB7XG4gIHJldHVybiBmaWxlcy5tYXAoKGZpbGUpID0+IHBhdGgucmVsYXRpdmUocm9vdCwgZmlsZSkpLnNvcnQoKTtcbn1cblxuZnVuY3Rpb24gY29sbGVjdFByb21wdFNlY3Rpb25zKG5hbWVzOiByZWFkb25seSBzdHJpbmdbXSk6IFByb21wdFNlY3Rpb25bXSB7XG4gIGNvbnN0IHJvb3QgPSBnZXRXb3Jrc3BhY2VSb290KCk7XG4gIGNvbnN0IHByb21wdEluZGV4ID0gbmV3IE1hcDxzdHJpbmcsIERvY1Byb21wdD4oXG4gICAgZGlzY292ZXJEb2NQcm9tcHRzKHJvb3QpLm1hcCgocHJvbXB0KSA9PiBbcHJvbXB0Lm5hbWUsIHByb21wdF0pXG4gICk7XG4gIHJldHVybiBuYW1lc1xuICAgIC5tYXAoKG5hbWUpID0+IHByb21wdEluZGV4LmdldChuYW1lKSlcbiAgICAuZmlsdGVyKChwcm9tcHQpOiBwcm9tcHQgaXMgRG9jUHJvbXB0ID0+IEJvb2xlYW4ocHJvbXB0KSlcbiAgICAubWFwKChwcm9tcHQpID0+ICh7XG4gICAgICBuYW1lOiBwcm9tcHQubmFtZSxcbiAgICAgIHRpdGxlOiBwcm9tcHQudGl0bGUsXG4gICAgICBkZXNjcmlwdGlvbjogcHJvbXB0LmRlc2NyaXB0aW9uLFxuICAgICAgY29udGVudDogcHJvbXB0LmNvbnRlbnQsXG4gICAgICBhYnNvbHV0ZVBhdGg6IHByb21wdC5hYnNvbHV0ZVBhdGgsXG4gICAgfSkpO1xufVxuXG5mdW5jdGlvbiBwYXJzZVRhc2tMaW5lcyhjb250ZW50OiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gIHJldHVybiBjb250ZW50XG4gICAgLnNwbGl0KC9cXHI/XFxuLylcbiAgICAubWFwKChsaW5lKSA9PiBsaW5lLnRyaW0oKSlcbiAgICAuZmlsdGVyKChsaW5lKSA9PiAvXnRhc2tcXHMrXFxkKy9pLnRlc3QobGluZSkpO1xufVxuXG5mdW5jdGlvbiBjb21wdXRlQ292ZXJhZ2VGcm9tRmluYWwoY292ZXJhZ2VQYXRoOiBzdHJpbmcpIHtcbiAgY29uc3QgcGF5bG9hZCA9IEpTT04ucGFyc2UoZnMucmVhZEZpbGVTeW5jKGNvdmVyYWdlUGF0aCwgXCJ1dGY4XCIpKSBhcyBSZWNvcmQ8XG4gICAgc3RyaW5nLFxuICAgIHtcbiAgICAgIHM6IFJlY29yZDxzdHJpbmcsIG51bWJlcj47XG4gICAgICBmOiBSZWNvcmQ8c3RyaW5nLCBudW1iZXI+O1xuICAgICAgYjogUmVjb3JkPHN0cmluZywgbnVtYmVyIHwgbnVtYmVyW10+O1xuICAgIH1cbiAgPjtcblxuICBjb25zdCB0b3RhbHMgPSB7XG4gICAgc3RhdGVtZW50czogeyBjb3ZlcmVkOiAwLCB0b3RhbDogMCB9LFxuICAgIGZ1bmN0aW9uczogeyBjb3ZlcmVkOiAwLCB0b3RhbDogMCB9LFxuICAgIGJyYW5jaGVzOiB7IGNvdmVyZWQ6IDAsIHRvdGFsOiAwIH0sXG4gIH07XG5cbiAgY29uc3QgZmlsZXMgPSBPYmplY3QuZW50cmllcyhwYXlsb2FkKS5tYXAoKFtmaWxlUGF0aCwgaW5mb10pID0+IHtcbiAgICBjb25zdCBzdGF0ZW1lbnRDb3VudHMgPSBPYmplY3QudmFsdWVzKGluZm8ucyk7XG4gICAgY29uc3QgZnVuY3Rpb25Db3VudHMgPSBPYmplY3QudmFsdWVzKGluZm8uZik7XG4gICAgY29uc3QgYnJhbmNoQ291bnRzID0gT2JqZWN0LnZhbHVlcyhpbmZvLmIpLmZsYXRNYXAoKHZhbHVlKSA9PlxuICAgICAgQXJyYXkuaXNBcnJheSh2YWx1ZSkgPyB2YWx1ZSA6IFt2YWx1ZV1cbiAgICApO1xuXG4gICAgY29uc3Qgc3RhdGVtZW50VG90YWwgPSBzdGF0ZW1lbnRDb3VudHMubGVuZ3RoO1xuICAgIGNvbnN0IGZ1bmN0aW9uVG90YWwgPSBmdW5jdGlvbkNvdW50cy5sZW5ndGg7XG4gICAgY29uc3QgYnJhbmNoVG90YWwgPSBicmFuY2hDb3VudHMubGVuZ3RoO1xuXG4gICAgY29uc3Qgc3RhdGVtZW50Q292ZXJlZCA9IHN0YXRlbWVudENvdW50cy5maWx0ZXIoXG4gICAgICAoY291bnQpID0+IGNvdW50ID4gMFxuICAgICkubGVuZ3RoO1xuICAgIGNvbnN0IGZ1bmN0aW9uQ292ZXJlZCA9IGZ1bmN0aW9uQ291bnRzLmZpbHRlcigoY291bnQpID0+IGNvdW50ID4gMCkubGVuZ3RoO1xuICAgIGNvbnN0IGJyYW5jaENvdmVyZWQgPSBicmFuY2hDb3VudHMuZmlsdGVyKChjb3VudCkgPT4gY291bnQgPiAwKS5sZW5ndGg7XG5cbiAgICB0b3RhbHMuc3RhdGVtZW50cy5jb3ZlcmVkICs9IHN0YXRlbWVudENvdmVyZWQ7XG4gICAgdG90YWxzLnN0YXRlbWVudHMudG90YWwgKz0gc3RhdGVtZW50VG90YWw7XG4gICAgdG90YWxzLmZ1bmN0aW9ucy5jb3ZlcmVkICs9IGZ1bmN0aW9uQ292ZXJlZDtcbiAgICB0b3RhbHMuZnVuY3Rpb25zLnRvdGFsICs9IGZ1bmN0aW9uVG90YWw7XG4gICAgdG90YWxzLmJyYW5jaGVzLmNvdmVyZWQgKz0gYnJhbmNoQ292ZXJlZDtcbiAgICB0b3RhbHMuYnJhbmNoZXMudG90YWwgKz0gYnJhbmNoVG90YWw7XG5cbiAgICBjb25zdCBwY3QgPSAoY292ZXJlZDogbnVtYmVyLCB0b3RhbDogbnVtYmVyKSA9PlxuICAgICAgdG90YWwgPT09IDAgPyAxMDAgOiBOdW1iZXIoKChjb3ZlcmVkIC8gdG90YWwpICogMTAwKS50b0ZpeGVkKDIpKTtcblxuICAgIHJldHVybiB7XG4gICAgICBwYXRoOiBmaWxlUGF0aCxcbiAgICAgIHN0YXRlbWVudHM6IHBjdChzdGF0ZW1lbnRDb3ZlcmVkLCBzdGF0ZW1lbnRUb3RhbCksXG4gICAgICBmdW5jdGlvbnM6IHBjdChmdW5jdGlvbkNvdmVyZWQsIGZ1bmN0aW9uVG90YWwpLFxuICAgICAgYnJhbmNoZXM6IHBjdChicmFuY2hDb3ZlcmVkLCBicmFuY2hUb3RhbCksXG4gICAgfTtcbiAgfSk7XG5cbiAgY29uc3QgcGN0ID0gKGNvdmVyZWQ6IG51bWJlciwgdG90YWw6IG51bWJlcikgPT5cbiAgICB0b3RhbCA9PT0gMCA/IDEwMCA6IE51bWJlcigoKGNvdmVyZWQgLyB0b3RhbCkgKiAxMDApLnRvRml4ZWQoMikpO1xuXG4gIHJldHVybiB7XG4gICAgdG90YWxzOiB7XG4gICAgICBzdGF0ZW1lbnRzOiB7XG4gICAgICAgIC4uLnRvdGFscy5zdGF0ZW1lbnRzLFxuICAgICAgICBwY3Q6IHBjdCh0b3RhbHMuc3RhdGVtZW50cy5jb3ZlcmVkLCB0b3RhbHMuc3RhdGVtZW50cy50b3RhbCksXG4gICAgICB9LFxuICAgICAgZnVuY3Rpb25zOiB7XG4gICAgICAgIC4uLnRvdGFscy5mdW5jdGlvbnMsXG4gICAgICAgIHBjdDogcGN0KHRvdGFscy5mdW5jdGlvbnMuY292ZXJlZCwgdG90YWxzLmZ1bmN0aW9ucy50b3RhbCksXG4gICAgICB9LFxuICAgICAgYnJhbmNoZXM6IHtcbiAgICAgICAgLi4udG90YWxzLmJyYW5jaGVzLFxuICAgICAgICBwY3Q6IHBjdCh0b3RhbHMuYnJhbmNoZXMuY292ZXJlZCwgdG90YWxzLmJyYW5jaGVzLnRvdGFsKSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBmaWxlcyxcbiAgfTtcbn1cblxuZnVuY3Rpb24gbm9ybWFsaXplUHJvbXB0U2VjdGlvbnMoc2VjdGlvbnM6IFByb21wdFNlY3Rpb25bXSkge1xuICByZXR1cm4gc2VjdGlvbnMubWFwKChzZWN0aW9uKSA9PiAoe1xuICAgIG5hbWU6IHNlY3Rpb24ubmFtZSxcbiAgICB0aXRsZTogc2VjdGlvbi50aXRsZSxcbiAgICB0YXNrczogcGFyc2VUYXNrTGluZXMoc2VjdGlvbi5jb250ZW50KSxcbiAgICBjb250ZW50OiBzZWN0aW9uLmNvbnRlbnQsXG4gIH0pKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZVJlcG9Sb290KGJhc2VQYXRoOiBzdHJpbmcpIHtcbiAgY29uc3Qgcm9vdCA9IGdldFdvcmtzcGFjZVJvb3QoKTtcbiAgdHJ5IHtcbiAgICByZXR1cm4gcmVzb2x2ZUluV29ya3NwYWNlKHJvb3QsIGJhc2VQYXRoKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBXb3Jrc3BhY2VFcnJvcikge1xuICAgICAgYXdhaXQgdGhyb3dVc2VyRXJyb3IoZXJyb3IubWVzc2FnZSk7XG4gICAgfVxuICAgIHRocm93IGVycm9yO1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCBkb2N1bWVudE9iamVjdFRvb2w6IFRvb2w8dW5kZWZpbmVkLCB0eXBlb2YgZG9jdW1lbnRPYmplY3RTY2hlbWE+ID1cbiAge1xuICAgIG5hbWU6IFwiZG9jdW1lbnQtb2JqZWN0XCIsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICBcIkNyZWF0ZSBhIGRvY3VtZW50YXRpb24gcGxhbiBmb3IgYSBzcGVjaWZpYyBvYmplY3QgdHlwZSB1c2luZyAuY29kZXggcHJvbXB0cyBhbmQgcmVwb3NpdG9yeSBhbmFseXNpcy5cIixcbiAgICBwYXJhbWV0ZXJzOiBkb2N1bWVudE9iamVjdFNjaGVtYSxcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgZXhlY3V0ZTogYXN5bmMgKGlucHV0LCBfY29udGV4dCk6IFByb21pc2U8Q29udGVudFJlc3VsdD4gPT4ge1xuICAgICAgY29uc3QgYXJncyA9IGRvY3VtZW50T2JqZWN0U2NoZW1hLnBhcnNlKGlucHV0IGFzIERvY3VtZW50T2JqZWN0QXJncyk7XG4gICAgICBjb25zdCByZXBvUm9vdCA9IGF3YWl0IHJlc29sdmVSZXBvUm9vdChhcmdzLmJhc2VQYXRoKTtcblxuICAgICAgY29uc3QgZGVwZW5kZW5jaWVzID0gZ2V0T2JqZWN0UHJvbXB0RGVwZW5kZW5jaWVzKClbYXJncy5vYmplY3RUeXBlXSA/PyBbXTtcbiAgICAgIGlmICghZGVwZW5kZW5jaWVzLmxlbmd0aCkge1xuICAgICAgICBhd2FpdCB0aHJvd1VzZXJFcnJvcihcbiAgICAgICAgICBgTm8gcHJvbXB0IGd1aWRhbmNlIGNvbmZpZ3VyZWQgZm9yIG9iamVjdCB0eXBlICR7YXJncy5vYmplY3RUeXBlfWBcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc2VjdGlvbnMgPSBub3JtYWxpemVQcm9tcHRTZWN0aW9ucyhcbiAgICAgICAgY29sbGVjdFByb21wdFNlY3Rpb25zKGRlcGVuZGVuY2llcylcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IHNyY0RpciA9IHBhdGguam9pbihyZXBvUm9vdCwgXCJzcmNcIik7XG4gICAgICBjb25zdCB0ZXN0RGlyID0gcGF0aC5qb2luKHJlcG9Sb290LCBcInRlc3RzXCIpO1xuXG4gICAgICBjb25zdCBzb3VyY2VGaWxlcyA9IGZzLmV4aXN0c1N5bmMoc3JjRGlyKVxuICAgICAgICA/IGxpc3RGaWxlc1JlY3Vyc2l2ZShzcmNEaXIsIGlzU291cmNlRmlsZSlcbiAgICAgICAgOiBbXTtcbiAgICAgIGNvbnN0IHRlc3RGaWxlcyA9IGZzLmV4aXN0c1N5bmModGVzdERpcilcbiAgICAgICAgPyBsaXN0RmlsZXNSZWN1cnNpdmUoXG4gICAgICAgICAgICB0ZXN0RGlyLFxuICAgICAgICAgICAgKGZpbGUpID0+IGlzU291cmNlRmlsZShmaWxlKSAmJiBpc1Rlc3RGaWxlKGZpbGUpXG4gICAgICAgICAgKVxuICAgICAgICA6IFtdO1xuXG4gICAgICBsZXQgdGFyZ2V0RmlsZUNvbnRlbnQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICAgIGlmIChhcmdzLnRhcmdldEZpbGUpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBhYnNvbHV0ZSA9IHJlc29sdmVJbldvcmtzcGFjZShyZXBvUm9vdCwgYXJncy50YXJnZXRGaWxlKTtcbiAgICAgICAgICB0YXJnZXRGaWxlQ29udGVudCA9IHJlYWRGaWxlU2FmZShhYnNvbHV0ZSkgPz8gdW5kZWZpbmVkO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFdvcmtzcGFjZUVycm9yKSB7XG4gICAgICAgICAgICBhd2FpdCB0aHJvd1VzZXJFcnJvcihlcnJvci5tZXNzYWdlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgICAgYmFzZVBhdGg6IHBhdGgucmVsYXRpdmUoZ2V0V29ya3NwYWNlUm9vdCgpLCByZXBvUm9vdCkgfHwgXCIuXCIsXG4gICAgICAgIG9iamVjdFR5cGU6IGFyZ3Mub2JqZWN0VHlwZSxcbiAgICAgICAgdGFyZ2V0RmlsZTogYXJncy50YXJnZXRGaWxlLFxuICAgICAgICBndWlkYW5jZTogc2VjdGlvbnMsXG4gICAgICAgIGZpbGVzOiB7XG4gICAgICAgICAgc291cmNlOiByZWxhdGl2ZUZpbGVzKHJlcG9Sb290LCBzb3VyY2VGaWxlcyksXG4gICAgICAgICAgdGVzdHM6IHJlbGF0aXZlRmlsZXMocmVwb1Jvb3QsIHRlc3RGaWxlcyksXG4gICAgICAgIH0sXG4gICAgICAgIHRhcmdldEZpbGVDb250ZW50OiBhcmdzLmluY2x1ZGVDb250ZW50ID8gdGFyZ2V0RmlsZUNvbnRlbnQgOiB1bmRlZmluZWQsXG4gICAgICB9O1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiBKU09OLnN0cmluZ2lmeShwYXlsb2FkLCBudWxsLCAyKSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfSBzYXRpc2ZpZXMgQ29udGVudFJlc3VsdDtcbiAgICB9LFxuICB9O1xuXG5leHBvcnQgY29uc3QgY292ZXJhZ2VFbmZvcmNlclRvb2w6IFRvb2w8dW5kZWZpbmVkLCB0eXBlb2YgY292ZXJhZ2VUYXNrU2NoZW1hPiA9XG4gIHtcbiAgICBuYW1lOiBcImVuc3VyZS10ZXN0LWNvdmVyYWdlXCIsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICBcIlJ1biB0aGUgY29uZmlndXJlZCBjb3ZlcmFnZSBjb21tYW5kIGFuZCByZXBvcnQgd2hldGhlciB0aGUgdGFyZ2V0IHBlcmNlbnRhZ2UgaXMgbWV0LCBoaWdobGlnaHRpbmcgd2VhayBmaWxlcy5cIixcbiAgICBwYXJhbWV0ZXJzOiBjb3ZlcmFnZVRhc2tTY2hlbWEsXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIGV4ZWN1dGU6IGFzeW5jIChpbnB1dCwgX2NvbnRleHQpOiBQcm9taXNlPENvbnRlbnRSZXN1bHQ+ID0+IHtcbiAgICAgIGNvbnN0IGFyZ3MgPSBjb3ZlcmFnZVRhc2tTY2hlbWEucGFyc2UoaW5wdXQgYXMgQ292ZXJhZ2VUYXNrQXJncyk7XG4gICAgICBjb25zdCByZXBvUm9vdCA9IGF3YWl0IHJlc29sdmVSZXBvUm9vdChhcmdzLmJhc2VQYXRoKTtcblxuICAgICAgaWYgKCFhcmdzLmRyeVJ1bikge1xuICAgICAgICBjb25zdCBlbnYgPSB7XG4gICAgICAgICAgLi4ucHJvY2Vzcy5lbnYsXG4gICAgICAgICAgVVNFX1dBVENITUFOOiBcImZhbHNlXCIsXG4gICAgICAgICAgV0FUQ0hNQU5fRElTQUJMRTogXCIxXCIsXG4gICAgICAgICAgSkVTVF9ESVNBQkxFX1dBVENITUFOOiBcIjFcIixcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gc3Bhd25TeW5jKFxuICAgICAgICAgIFwibnBtXCIsXG4gICAgICAgICAgW1wicnVuXCIsIFwiY292ZXJhZ2VcIiwgXCItLVwiLCBcIi0td2F0Y2htYW49ZmFsc2VcIiwgXCItLXJ1bkluQmFuZFwiXSxcbiAgICAgICAgICB7IGN3ZDogcmVwb1Jvb3QsIGVudiwgZW5jb2Rpbmc6IFwidXRmOFwiIH1cbiAgICAgICAgKTtcblxuICAgICAgICBpZiAocmVzdWx0LnN0YXR1cyAhPT0gMCkge1xuICAgICAgICAgIGNvbnN0IG1lc3NhZ2UgPVxuICAgICAgICAgICAgcmVzdWx0LnN0ZGVyciB8fCByZXN1bHQuc3Rkb3V0IHx8IFwiQ292ZXJhZ2UgY29tbWFuZCBmYWlsZWRcIjtcbiAgICAgICAgICBhd2FpdCB0aHJvd1VzZXJFcnJvcihtZXNzYWdlLnRyaW0oKSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgY292ZXJhZ2VQYXRoID0gcGF0aC5qb2luKFxuICAgICAgICByZXBvUm9vdCxcbiAgICAgICAgXCJ3b3JrZG9jc1wiLFxuICAgICAgICBcInJlcG9ydHNcIixcbiAgICAgICAgXCJjb3ZlcmFnZVwiLFxuICAgICAgICBcImNvdmVyYWdlLWZpbmFsLmpzb25cIlxuICAgICAgKTtcblxuICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKGNvdmVyYWdlUGF0aCkpIHtcbiAgICAgICAgYXdhaXQgdGhyb3dVc2VyRXJyb3IoXG4gICAgICAgICAgYENvdmVyYWdlIHJlcG9ydCBub3QgZm91bmQgYXQgJHtwYXRoLnJlbGF0aXZlKHJlcG9Sb290LCBjb3ZlcmFnZVBhdGgpfWBcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc3VtbWFyeSA9IGNvbXB1dGVDb3ZlcmFnZUZyb21GaW5hbChjb3ZlcmFnZVBhdGgpO1xuICAgICAgY29uc3QgbWVldHNUaHJlc2hvbGQgPVxuICAgICAgICBzdW1tYXJ5LnRvdGFscy5zdGF0ZW1lbnRzLnBjdCA+PSBhcmdzLmNvdmVyYWdlICYmXG4gICAgICAgIHN1bW1hcnkudG90YWxzLmZ1bmN0aW9ucy5wY3QgPj0gYXJncy5jb3ZlcmFnZSAmJlxuICAgICAgICBzdW1tYXJ5LnRvdGFscy5icmFuY2hlcy5wY3QgPj0gYXJncy5jb3ZlcmFnZTtcblxuICAgICAgY29uc3Qgd2Vha2VzdCA9IFsuLi5zdW1tYXJ5LmZpbGVzXVxuICAgICAgICAuc29ydCgoYSwgYikgPT4gYS5zdGF0ZW1lbnRzIC0gYi5zdGF0ZW1lbnRzKVxuICAgICAgICAuc2xpY2UoMCwgMTApO1xuXG4gICAgICBjb25zdCBndWlkYW5jZSA9IG5vcm1hbGl6ZVByb21wdFNlY3Rpb25zKFxuICAgICAgICBjb2xsZWN0UHJvbXB0U2VjdGlvbnMoW1wiYnVsay10ZXN0c1wiXSlcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IHBheWxvYWQgPSB7XG4gICAgICAgIGJhc2VQYXRoOiBwYXRoLnJlbGF0aXZlKGdldFdvcmtzcGFjZVJvb3QoKSwgcmVwb1Jvb3QpIHx8IFwiLlwiLFxuICAgICAgICB0YXJnZXQ6IGFyZ3MuY292ZXJhZ2UsXG4gICAgICAgIG1lZXRzVGhyZXNob2xkLFxuICAgICAgICB0b3RhbHM6IHN1bW1hcnkudG90YWxzLFxuICAgICAgICB3ZWFrZXN0LFxuICAgICAgICBndWlkYW5jZSxcbiAgICAgIH07XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgIHRleHQ6IEpTT04uc3RyaW5naWZ5KHBheWxvYWQsIG51bGwsIDIpLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9IHNhdGlzZmllcyBDb250ZW50UmVzdWx0O1xuICAgIH0sXG4gIH07XG5cbmV4cG9ydCBjb25zdCByZWFkbWVJbXByb3ZlbWVudFRvb2w6IFRvb2w8XG4gIHVuZGVmaW5lZCxcbiAgdHlwZW9mIHJlYWRtZUltcHJvdmVtZW50U2NoZW1hXG4+ID0ge1xuICBuYW1lOiBcImltcHJvdmUtcmVhZG1lXCIsXG4gIGRlc2NyaXB0aW9uOlxuICAgIFwiU3VtbWFyaXplIHJlcXVpcmVkIHN0ZXBzIHRvIHJlZnJlc2ggUkVBRE1FIGFuZCB3b3JrZG9jcyBjb250ZW50IHVzaW5nIC5jb2RleCBndWlkYW5jZSBhbmQgcmVwb3NpdG9yeSBhbmFseXNpcy5cIixcbiAgcGFyYW1ldGVyczogcmVhZG1lSW1wcm92ZW1lbnRTY2hlbWEsXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgZXhlY3V0ZTogYXN5bmMgKGlucHV0LCBfY29udGV4dCk6IFByb21pc2U8Q29udGVudFJlc3VsdD4gPT4ge1xuICAgIGNvbnN0IGFyZ3MgPSByZWFkbWVJbXByb3ZlbWVudFNjaGVtYS5wYXJzZShpbnB1dCBhcyBSZWFkbWVJbXByb3ZlbWVudEFyZ3MpO1xuICAgIGNvbnN0IHJlcG9Sb290ID0gYXdhaXQgcmVzb2x2ZVJlcG9Sb290KGFyZ3MuYmFzZVBhdGgpO1xuXG4gICAgY29uc3QgYW5hbHlzaXMgPSBhbmFseXplUmVwbyhyZXBvUm9vdCk7XG4gICAgY29uc3QgbW9kdWxlcyA9IGFuYWx5c2lzLmZpbGVzXG4gICAgICAuZmlsdGVyKChmaWxlKSA9PiAvaW5kZXhcXC50cyQvLnRlc3QoZmlsZSkpXG4gICAgICAubWFwKChmaWxlKSA9PiBwYXRoLnJlbGF0aXZlKHJlcG9Sb290LCBmaWxlKSk7XG5cbiAgICBjb25zdCBwcm9tcHRTZWN0aW9ucyA9IG5vcm1hbGl6ZVByb21wdFNlY3Rpb25zKFxuICAgICAgY29sbGVjdFByb21wdFNlY3Rpb25zKFtcInVwZGF0ZS1yZWFkbWVcIiwgXCJkb2NcIiwgXCJtb2R1bGVcIl0pXG4gICAgKTtcblxuICAgIGNvbnN0IHRlc3RFeGFtcGxlcyA9IE9iamVjdC5rZXlzKGFuYWx5c2lzLnRlc3RzID8/IHt9KTtcbiAgICBjb25zdCBleGFtcGxlcyA9IGFyZ3MuaW5jbHVkZUV4YW1wbGVzID8gdGVzdEV4YW1wbGVzLnNsaWNlKDAsIDIwKSA6IFtdO1xuXG4gICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgIGJhc2VQYXRoOiBwYXRoLnJlbGF0aXZlKGdldFdvcmtzcGFjZVJvb3QoKSwgcmVwb1Jvb3QpIHx8IFwiLlwiLFxuICAgICAgc3VtbWFyeToge1xuICAgICAgICBtb2R1bGVzLFxuICAgICAgICB0b3RhbFNvdXJjZUZpbGVzOiBhbmFseXNpcy5maWxlcy5sZW5ndGgsXG4gICAgICAgIHRvdGFsVGVzdEZpbGVzOiBhbmFseXNpcy50ZXN0RmlsZXMubGVuZ3RoLFxuICAgICAgICBoYXNSZWFkbWU6IEJvb2xlYW4oYW5hbHlzaXMucmVhZG1lKSxcbiAgICAgIH0sXG4gICAgICBndWlkYW5jZTogcHJvbXB0U2VjdGlvbnMsXG4gICAgICBzdWdnZXN0ZWRFeGFtcGxlczogZXhhbXBsZXMsXG4gICAgfTtcblxuICAgIHJldHVybiB7XG4gICAgICBjb250ZW50OiBbXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICB0ZXh0OiBKU09OLnN0cmluZ2lmeShwYXlsb2FkLCBudWxsLCAyKSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSBzYXRpc2ZpZXMgQ29udGVudFJlc3VsdDtcbiAgfSxcbn07XG4iLCJpbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuXG5leHBvcnQgdHlwZSBTY2FmZm9sZFJlc3VsdCA9IHtcbiAgbW9kdWxlUGF0aDogc3RyaW5nO1xuICBjcmVhdGVkRmlsZXM6IHN0cmluZ1tdO1xufTtcblxuY29uc3QgREVGQVVMVF9QTEFDRUhPTERFUlMgPSB7XG4gIHByb21wdHM6IGBleHBvcnQgY29uc3QgcHJvbXB0TGlzdCA9IFtcbiAge1xuICAgIGlkOiBcImV4YW1wbGUtcHJvbXB0XCIsXG4gICAgdGl0bGU6IFwiRXhhbXBsZSBwcm9tcHRcIixcbiAgICBkZXNjcmlwdGlvbjogXCJBIHBsYWNlaG9sZGVyIHByb21wdCBjcmVhdGVkIGJ5IHNjYWZmb2xkTW9kdWxlXCIsXG4gICAgY29udGVudDogXCJEZXNjcmliZSB0aGUgdGFzayBmb3IgdGhlIGFzc2lzdGFudC4uLlwiLFxuICAgIGFic29sdXRlUGF0aDogX19maWxlbmFtZSxcbiAgfSxcbl0gYXMgY29uc3Q7XG5gLFxuICByZXNvdXJjZXM6IGBleHBvcnQgY29uc3QgcmVzb3VyY2VzID0gW1xuICB7XG4gICAgaWQ6IFwiZXhhbXBsZS1yZXNvdXJjZVwiLFxuICAgIG5hbWU6IFwiRXhhbXBsZSBSZXNvdXJjZVwiLFxuICAgIGRlc2NyaXB0aW9uOiBcIkEgcGxhY2Vob2xkZXIgcmVzb3VyY2UgY3JlYXRlZCBieSBzY2FmZm9sZE1vZHVsZVwiLFxuICAgIHVyaTogXCJmaWxlOi8vcGxhY2Vob2xkZXJcIixcbiAgICBhYnNvbHV0ZVBhdGg6IF9fZmlsZW5hbWUsXG4gIH0sXG5dIGFzIGNvbnN0O1xuYCxcbiAgdGVtcGxhdGVzOiBgZXhwb3J0IGNvbnN0IHRlbXBsYXRlcyA9IFtcbiAge1xuICAgIG5hbWU6IFwiZXhhbXBsZS10ZW1wbGF0ZVwiLFxuICAgIGRlc2NyaXB0aW9uOiBcIkEgcGxhY2Vob2xkZXIgdGVtcGxhdGUgY3JlYXRlZCBieSBzY2FmZm9sZE1vZHVsZVwiLFxuICAgIHVyaVRlbXBsYXRlOiBcImZpbGU6Ly90ZW1wbGF0ZS97cGF0aH1cIixcbiAgICBtaW1lVHlwZTogXCJ0ZXh0L3BsYWluXCIsXG4gIH0sXG5dIGFzIGNvbnN0O1xuYCxcbiAgdG9vbHM6IGBleHBvcnQgY29uc3QgdG9vbExpc3QgPSBbXG4gIHtcbiAgICBpZDogXCJleGFtcGxlLXRvb2xcIixcbiAgICBuYW1lOiBcImV4YW1wbGUtdG9vbFwiLFxuICAgIGRlc2NyaXB0aW9uOiBcIkEgcGxhY2Vob2xkZXIgdG9vbCBjcmVhdGVkIGJ5IHNjYWZmb2xkTW9kdWxlXCIsXG4gICAgcnVuOiBhc3luYyAoKSA9PiAoeyByZXN1bHQ6IFwicGxhY2Vob2xkZXJcIiB9KSxcbiAgfSxcbl0gYXMgY29uc3Q7XG5gLFxufTtcblxuLyoqXG4gKiBDcmVhdGUgYSBtb2R1bGUgc2NhZmZvbGQgdW5kZXIgcmVwb1Jvb3Qvc3JjL21vZHVsZXMvPG1vZHVsZU5hbWU+XG4gKiBSZXR1cm5zIGNyZWF0ZWQgZmlsZXMgbGlzdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNjYWZmb2xkTW9kdWxlKFxuICByZXBvUm9vdDogc3RyaW5nLFxuICBtb2R1bGVOYW1lOiBzdHJpbmdcbik6IFNjYWZmb2xkUmVzdWx0IHtcbiAgaWYgKCFyZXBvUm9vdCkgdGhyb3cgbmV3IEVycm9yKFwicmVwb1Jvb3QgaXMgcmVxdWlyZWRcIik7XG4gIGlmICghbW9kdWxlTmFtZSkgdGhyb3cgbmV3IEVycm9yKFwibW9kdWxlTmFtZSBpcyByZXF1aXJlZFwiKTtcblxuICBjb25zdCBtb2R1bGVQYXRoID0gcGF0aC5qb2luKHJlcG9Sb290LCBcInNyY1wiLCBcIm1vZHVsZXNcIiwgbW9kdWxlTmFtZSk7XG4gIGNvbnN0IGNyZWF0ZWRGaWxlczogc3RyaW5nW10gPSBbXTtcblxuICBjb25zdCBzdWJmb2xkZXJzID0gW1wicHJvbXB0c1wiLCBcInJlc291cmNlc1wiLCBcInRlbXBsYXRlc1wiLCBcInRvb2xzXCJdO1xuXG4gIGZvciAoY29uc3QgZm9sZGVyIG9mIHN1YmZvbGRlcnMpIHtcbiAgICBjb25zdCBmb2xkZXJQYXRoID0gcGF0aC5qb2luKG1vZHVsZVBhdGgsIGZvbGRlcik7XG4gICAgZnMubWtkaXJTeW5jKGZvbGRlclBhdGgsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgIGNvbnN0IGluZGV4UGF0aCA9IHBhdGguam9pbihmb2xkZXJQYXRoLCBcImluZGV4LnRzXCIpO1xuICAgIC8vIGlmIGZpbGUgZXhpc3RzLCBza2lwIHdyaXRpbmdcbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMoaW5kZXhQYXRoKSkge1xuICAgICAgLy8gaW5zZXJ0IF9fZmlsZW5hbWUgZm9yIGFic29sdXRlUGF0aCBpbiBwbGFjZWhvbGRlcnNcbiAgICAgIGNvbnN0IGNvbnRlbnQgPSBERUZBVUxUX1BMQUNFSE9MREVSU1tcbiAgICAgICAgZm9sZGVyIGFzIGtleW9mIHR5cGVvZiBERUZBVUxUX1BMQUNFSE9MREVSU1xuICAgICAgXS5yZXBsYWNlKC9fX2ZpbGVuYW1lL2csIEpTT04uc3RyaW5naWZ5KGluZGV4UGF0aCkpO1xuICAgICAgZnMud3JpdGVGaWxlU3luYyhpbmRleFBhdGgsIGNvbnRlbnQsIHsgZW5jb2Rpbmc6IFwidXRmOFwiIH0pO1xuICAgICAgY3JlYXRlZEZpbGVzLnB1c2goaW5kZXhQYXRoKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4geyBtb2R1bGVQYXRoLCBjcmVhdGVkRmlsZXMgfTtcbn1cblxuLy8gQ0xJIHN1cHBvcnQgd2hlbiByZXF1aXJlZCBkaXJlY3RseSB2aWEgdHMtbm9kZSByZWdpc3RyYXRpb25cbmlmIChyZXF1aXJlLm1haW4gPT09IG1vZHVsZSkge1xuICBjb25zdCBbLCAsIG1vZHVsZU5hbWVdID0gcHJvY2Vzcy5hcmd2O1xuICBpZiAoIW1vZHVsZU5hbWUpIHtcbiAgICBjb25zb2xlLmVycm9yKFwiVXNhZ2U6IHNjYWZmb2xkLW1vZHVsZSA8bW9kdWxlLW5hbWU+XCIpO1xuICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgfVxuICB0cnkge1xuICAgIGNvbnN0IHJlcyA9IHNjYWZmb2xkTW9kdWxlKHByb2Nlc3MuY3dkKCksIG1vZHVsZU5hbWUpO1xuICAgIGNvbnNvbGUubG9nKFwiU2NhZmZvbGRlZCBtb2R1bGU6XCIsIHJlcy5tb2R1bGVQYXRoKTtcbiAgICBmb3IgKGNvbnN0IGYgb2YgcmVzLmNyZWF0ZWRGaWxlcykgY29uc29sZS5sb2coXCIgIGNyZWF0ZWQ6XCIsIGYpO1xuICAgIHByb2Nlc3MuZXhpdCgwKTtcbiAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICBjb25zb2xlLmVycm9yKGVyciAmJiBlcnIubWVzc2FnZSA/IGVyci5tZXNzYWdlIDogZXJyKTtcbiAgICBwcm9jZXNzLmV4aXQoMik7XG4gIH1cbn1cbiIsIi8vIE5ldyB0b29sOiBnZW5lcmF0ZS1tY3AtbW9kdWxlXG5pbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHR5cGUgeyBUb29sIH0gZnJvbSBcImZhc3RtY3BcIjtcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5pbXBvcnQgeyBnZXRXb3Jrc3BhY2VSb290IH0gZnJvbSBcIi4uL3dvcmtzcGFjZVwiO1xuaW1wb3J0IHsgYW5hbHl6ZVJlcG8gfSBmcm9tIFwiLi4vY29kZVwiO1xuaW1wb3J0IHsgc2NhZmZvbGRNb2R1bGUgfSBmcm9tIFwiLi4vdmFsaWRhdGlvbi9zY2FmZm9sZE1vZHVsZVwiO1xuXG5jb25zdCBnZW5lcmF0ZVNjaGVtYSA9IHoub2JqZWN0KHtcbiAgcmVwb1BhdGg6IHouc3RyaW5nKCkub3B0aW9uYWwoKS5kZWZhdWx0KFwiLlwiKSxcbiAgbW9kdWxlTmFtZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICBpbmNsdWRlRG9jczogei5ib29sZWFuKCkuZGVmYXVsdCh0cnVlKSxcbn0pO1xuXG50eXBlIEdlbmVyYXRlQXJncyA9IHouaW5mZXI8dHlwZW9mIGdlbmVyYXRlU2NoZW1hPjtcblxuZXhwb3J0IGNvbnN0IGdlbmVyYXRlTWNwTW9kdWxlVG9vbDogVG9vbDx1bmRlZmluZWQsIHR5cGVvZiBnZW5lcmF0ZVNjaGVtYT4gPSB7XG4gIG5hbWU6IFwiZ2VuZXJhdGUtbWNwLW1vZHVsZVwiLFxuICBkZXNjcmlwdGlvbjpcbiAgICBcIkdlbmVyYXRlIGEgbWluaW1hbCBNQ1AgbW9kdWxlIHVuZGVyIHNyYy9tb2R1bGVzLzxuYW1lPiBieSBhbmFseXppbmcgYSB0YXJnZXQgcmVwb3NpdG9yeSBhbmQgZXhwb3J0aW5nIHByb21wdHMsIHJlc291cmNlcywgdGVtcGxhdGVzIGFuZCB0b29scy5cIixcbiAgcGFyYW1ldGVyczogZ2VuZXJhdGVTY2hlbWEsXG4gIGV4ZWN1dGU6IGFzeW5jIChpbnB1dCkgPT4ge1xuICAgIGNvbnN0IGFyZ3MgPSBnZW5lcmF0ZVNjaGVtYS5wYXJzZShpbnB1dCBhcyBhbnkpO1xuICAgIGNvbnN0IHJvb3QgPSBnZXRXb3Jrc3BhY2VSb290KCk7XG4gICAgbGV0IHJlcG9Sb290ID0gcGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksIGFyZ3MucmVwb1BhdGggfHwgXCIuXCIpO1xuICAgIGlmICghZnMuZXhpc3RzU3luYyhyZXBvUm9vdCkpIHtcbiAgICAgIGNvbnN0IGFsdCA9IHBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCBcIi4uXCIsIGFyZ3MucmVwb1BhdGgpO1xuICAgICAgaWYgKGZzLmV4aXN0c1N5bmMoYWx0KSkgcmVwb1Jvb3QgPSBhbHQ7XG4gICAgfVxuICAgIGlmICghZnMuZXhpc3RzU3luYyhyZXBvUm9vdCkpIHtcbiAgICAgIGNvbnN0IGFsdDIgPSBwYXRoLnJlc29sdmUoXG4gICAgICAgIHByb2Nlc3MuY3dkKCksXG4gICAgICAgIFwiLi5cIixcbiAgICAgICAgcGF0aC5iYXNlbmFtZShhcmdzLnJlcG9QYXRoKVxuICAgICAgKTtcbiAgICAgIGlmIChmcy5leGlzdHNTeW5jKGFsdDIpKSByZXBvUm9vdCA9IGFsdDI7XG4gICAgfVxuICAgIGlmICghZnMuZXhpc3RzU3luYyhyZXBvUm9vdCkpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFJlcG9zaXRvcnkgbm90IGZvdW5kIGF0ICR7cmVwb1Jvb3R9YCk7XG5cbiAgICBjb25zdCBhbmFseXNpcyA9IGFuYWx5emVSZXBvKHJlcG9Sb290KTtcbiAgICBjb25zdCBpbmZlcnJlZE5hbWUgPVxuICAgICAgYXJncy5tb2R1bGVOYW1lID8/IHBhdGguYmFzZW5hbWUocGF0aC5yZXNvbHZlKHJlcG9Sb290KSk7XG4gICAgY29uc3QgbW9kdWxlUm9vdCA9IHBhdGguam9pbihyb290LCBcInNyY1wiLCBcIm1vZHVsZXNcIiwgaW5mZXJyZWROYW1lKTtcblxuICAgIC8vIFVzZSBleGlzdGluZyBzY2FmZm9sZCB0byBjcmVhdGUgZm9sZGVyc1xuICAgIHNjYWZmb2xkTW9kdWxlKHJvb3QsIGluZmVycmVkTmFtZSk7XG5cbiAgICAvLyBwb3B1bGF0ZSBwcm9tcHRzOiBjb3B5IG1hcmtkb3duIHByb21wdHMgZnJvbSBSRUFETUUubWQgYW5kIGRvY3MvXG4gICAgY29uc3QgcHJvbXB0c0RpciA9IHBhdGguam9pbihtb2R1bGVSb290LCBcInByb21wdHNcIik7XG4gICAgY29uc3QgcmVzb3VyY2VzRGlyID0gcGF0aC5qb2luKG1vZHVsZVJvb3QsIFwicmVzb3VyY2VzXCIpO1xuICAgIGNvbnN0IHRlbXBsYXRlc0RpciA9IHBhdGguam9pbihtb2R1bGVSb290LCBcInRlbXBsYXRlc1wiKTtcbiAgICBjb25zdCB0b29sc0RpciA9IHBhdGguam9pbihtb2R1bGVSb290LCBcInRvb2xzXCIpO1xuXG4gICAgLy8gaGVscGVyIHRvIHdyaXRlIGFuIGluZGV4LnRzIHRoYXQgZXhwb3J0cyBhcnJheXNcbiAgICBmdW5jdGlvbiB3cml0ZUluZGV4KGRpcjogc3RyaW5nLCB2YXJOYW1lOiBzdHJpbmcsIGl0ZW1zOiBzdHJpbmcpIHtcbiAgICAgIGNvbnN0IHAgPSBwYXRoLmpvaW4oZGlyLCBcImluZGV4LnRzXCIpO1xuICAgICAgY29uc3QgY29udGVudCA9IGBleHBvcnQgY29uc3QgJHt2YXJOYW1lfSA9ICR7aXRlbXN9IGFzIGNvbnN0O1xcbmA7XG4gICAgICBmcy53cml0ZUZpbGVTeW5jKHAsIGNvbnRlbnQsIHsgZW5jb2Rpbmc6IFwidXRmOFwiIH0pO1xuICAgIH1cblxuICAgIC8vIFByb21wdHM6IGNyZWF0ZSBhIHNpbXBsZSBwcm9tcHQgZnJvbSBSRUFETUUgYW5kIGFueSAubWQgaW4gZG9jc1xuICAgIGNvbnN0IHByb21wdEFzc2V0czogYW55W10gPSBbXTtcbiAgICBpZiAoYXJncy5pbmNsdWRlRG9jcykge1xuICAgICAgY29uc3QgcmVhZG1lID0gcGF0aC5qb2luKHJlcG9Sb290LCBcIlJFQURNRS5tZFwiKTtcbiAgICAgIGlmIChmcy5leGlzdHNTeW5jKHJlYWRtZSkpIHtcbiAgICAgICAgY29uc3QgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhyZWFkbWUsIFwidXRmOFwiKTtcbiAgICAgICAgY29uc3QgaWQgPSBcInJlYWRtZVwiO1xuICAgICAgICBjb25zdCBwcm9tcHRQYXRoID0gcGF0aC5qb2luKHByb21wdHNEaXIsIGAke2lkfS5tZGApO1xuICAgICAgICBmcy53cml0ZUZpbGVTeW5jKHByb21wdFBhdGgsIGNvbnRlbnQsIHsgZW5jb2Rpbmc6IFwidXRmOFwiIH0pO1xuICAgICAgICBwcm9tcHRBc3NldHMucHVzaCh7XG4gICAgICAgICAgaWQsXG4gICAgICAgICAgdGl0bGU6IFwiUkVBRE1FXCIsXG4gICAgICAgICAgZGVzY3JpcHRpb246IFwiUmVwb3NpdG9yeSBSRUFETUVcIixcbiAgICAgICAgICBhYnNvbHV0ZVBhdGg6IHByb21wdFBhdGgsXG4gICAgICAgICAgbG9hZDogKCkgPT4gY29udGVudCxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCBkb2NzRGlyID0gcGF0aC5qb2luKHJlcG9Sb290LCBcImRvY3NcIik7XG4gICAgICBpZiAoZnMuZXhpc3RzU3luYyhkb2NzRGlyKSAmJiBmcy5zdGF0U3luYyhkb2NzRGlyKS5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICAgIGZvciAoY29uc3QgZiBvZiBmcy5yZWFkZGlyU3luYyhkb2NzRGlyKSkge1xuICAgICAgICAgIGlmICghZi5lbmRzV2l0aChcIi5tZFwiKSkgY29udGludWU7XG4gICAgICAgICAgY29uc3QgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhwYXRoLmpvaW4oZG9jc0RpciwgZiksIFwidXRmOFwiKTtcbiAgICAgICAgICBjb25zdCBpZCA9IHBhdGgucGFyc2UoZikubmFtZTtcbiAgICAgICAgICBjb25zdCBwcm9tcHRQYXRoID0gcGF0aC5qb2luKHByb21wdHNEaXIsIGAke2lkfS5tZGApO1xuICAgICAgICAgIGZzLndyaXRlRmlsZVN5bmMocHJvbXB0UGF0aCwgY29udGVudCwgeyBlbmNvZGluZzogXCJ1dGY4XCIgfSk7XG4gICAgICAgICAgcHJvbXB0QXNzZXRzLnB1c2goe1xuICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICB0aXRsZTogaWQsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogY29udGVudC5zcGxpdCgvXFxyP1xcbi8pWzBdIHx8IFwiXCIsXG4gICAgICAgICAgICBhYnNvbHV0ZVBhdGg6IHByb21wdFBhdGgsXG4gICAgICAgICAgICBsb2FkOiAoKSA9PiBjb250ZW50LFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgd3JpdGVJbmRleChwcm9tcHRzRGlyLCBcInByb21wdHNcIiwgSlNPTi5zdHJpbmdpZnkocHJvbXB0QXNzZXRzLCBudWxsLCAyKSk7XG5cbiAgICAvLyBSZXNvdXJjZXM6IHJlZmVyZW5jZSB0aGUgcmVwbyByb290IGFuZCBkb2NzXG4gICAgY29uc3QgcmVzb3VyY2VBc3NldHMgPSBbXG4gICAgICB7XG4gICAgICAgIGlkOiBgJHtpbmZlcnJlZE5hbWV9LnJlcG9gLFxuICAgICAgICBuYW1lOiBgJHtpbmZlcnJlZE5hbWV9IHJlcG9zaXRvcnlgLFxuICAgICAgICBkZXNjcmlwdGlvbjogXCJTb3VyY2UgcmVwb3NpdG9yeVwiLFxuICAgICAgICB1cmk6IGBmaWxlOi8vJHtyZXBvUm9vdH1gLFxuICAgICAgICBhYnNvbHV0ZVBhdGg6IHJlcG9Sb290LFxuICAgICAgfSxcbiAgICBdO1xuICAgIHdyaXRlSW5kZXgoXG4gICAgICByZXNvdXJjZXNEaXIsXG4gICAgICBcInJlc291cmNlc1wiLFxuICAgICAgSlNPTi5zdHJpbmdpZnkocmVzb3VyY2VBc3NldHMsIG51bGwsIDIpXG4gICAgKTtcblxuICAgIC8vIFRlbXBsYXRlczogY3JlYXRlIGEgcGxhY2Vob2xkZXIgdGVtcGxhdGUgdGhhdCByZWZlcmVuY2VzIFJFQURNRVxuICAgIGNvbnN0IHRlbXBsYXRlQXNzZXRzID0gW1xuICAgICAge1xuICAgICAgICBuYW1lOiBcInJlYWRtZS10ZW1wbGF0ZVwiLFxuICAgICAgICBkZXNjcmlwdGlvbjogXCJSRUFETUUgYXMgZ3VpZGFuY2VcIixcbiAgICAgICAgdXJpVGVtcGxhdGU6IGBmaWxlOi8vJHtwYXRoLmpvaW4ocmVwb1Jvb3QsIFwiUkVBRE1FLm1kXCIpfWAsXG4gICAgICAgIG1pbWVUeXBlOiBcInRleHQvbWFya2Rvd25cIixcbiAgICAgIH0sXG4gICAgXTtcbiAgICB3cml0ZUluZGV4KFxuICAgICAgdGVtcGxhdGVzRGlyLFxuICAgICAgXCJ0ZW1wbGF0ZXNcIixcbiAgICAgIEpTT04uc3RyaW5naWZ5KHRlbXBsYXRlQXNzZXRzLCBudWxsLCAyKVxuICAgICk7XG5cbiAgICAvLyBUb29sczogY3JlYXRlIGEgd3JhcHBlciB0b29sIHRoYXQgZXhwb3NlcyBhbmFseXplL2VudW1lcmF0ZSBmb3IgdGhlIG1vZHVsZVxuICAgIGNvbnN0IHRvb2xJbmRleFBhdGggPSBwYXRoLmpvaW4odG9vbHNEaXIsIFwiaW5kZXgudHNcIik7XG4gICAgY29uc3QgdG9vbENvbnRlbnQgPSBgaW1wb3J0IHR5cGUgeyBUb29sIH0gZnJvbSAnZmFzdG1jcCc7XFxuaW1wb3J0IHsgYnVpbGRBbmFseXplUmVwb3NpdG9yeVRvb2wsIGJ1aWxkRW51bWVyYXRlQ2FwYWJpbGl0aWVzVG9vbCwgYnVpbGRQbGFuRmVhdHVyZVRvb2wgfSBmcm9tICcuLi8uLi8uLi9tY3AvdG9vbHMvdG9vbHMnO1xcbmV4cG9ydCBjb25zdCB0b29scyA9IFtcXG4gIHsgaWQ6ICcke2luZmVycmVkTmFtZX0uYW5hbHl6ZScsIHRpdGxlOiAnQW5hbHl6ZSAke2luZmVycmVkTmFtZX0nLCBkZXNjcmlwdGlvbjogJ0FuYWx5emUgdGhlIHRhcmdldCByZXBvc2l0b3J5JywgdG9vbDogYnVpbGRBbmFseXplUmVwb3NpdG9yeVRvb2woKSB9LFxcbiAgeyBpZDogJyR7aW5mZXJyZWROYW1lfS5lbnVtZXJhdGUnLCB0aXRsZTogJ0VudW1lcmF0ZSBjYXBhYmlsaXRpZXMgZm9yICR7aW5mZXJyZWROYW1lfScsIGRlc2NyaXB0aW9uOiAnRW51bWVyYXRlIGNhcGFiaWxpdGllcycsIHRvb2w6IGJ1aWxkRW51bWVyYXRlQ2FwYWJpbGl0aWVzVG9vbCgpIH0sXFxuICB7IGlkOiAnJHtpbmZlcnJlZE5hbWV9LnBsYW4nLCB0aXRsZTogJ1BsYW4gZmVhdHVyZXMgZm9yICR7aW5mZXJyZWROYW1lfScsIGRlc2NyaXB0aW9uOiAnUGxhbiBmZWF0dXJlIGltcGxlbWVudGF0aW9uJywgdG9vbDogYnVpbGRQbGFuRmVhdHVyZVRvb2woKSB9LFxcbl0gYXMgY29uc3Q7XFxuYDtcbiAgICBmcy53cml0ZUZpbGVTeW5jKHRvb2xJbmRleFBhdGgsIHRvb2xDb250ZW50LCB7IGVuY29kaW5nOiBcInV0ZjhcIiB9KTtcblxuICAgIC8vIFdyaXRlIG1vZHVsZSBpbmRleC50c1xuICAgIGNvbnN0IG1vZHVsZUluZGV4ID0gcGF0aC5qb2luKG1vZHVsZVJvb3QsIFwiaW5kZXgudHNcIik7XG4gICAgY29uc3QgbW9kdWxlSW5kZXhDb250ZW50ID0gYGltcG9ydCB7IHByb21wdHMgfSBmcm9tICcuL3Byb21wdHMnO1xcbmltcG9ydCB7IHJlc291cmNlcyB9IGZyb20gJy4vcmVzb3VyY2VzJztcXG5pbXBvcnQgeyB0ZW1wbGF0ZXMgfSBmcm9tICcuL3RlbXBsYXRlcyc7XFxuaW1wb3J0IHsgdG9vbHMgfSBmcm9tICcuL3Rvb2xzJztcXG5leHBvcnQgeyBwcm9tcHRzIH0gZnJvbSAnLi9wcm9tcHRzJztcXG5leHBvcnQgeyByZXNvdXJjZXMgfSBmcm9tICcuL3Jlc291cmNlcyc7XFxuZXhwb3J0IHsgdGVtcGxhdGVzIH0gZnJvbSAnLi90ZW1wbGF0ZXMnO1xcbmV4cG9ydCB7IHRvb2xzIH0gZnJvbSAnLi90b29scyc7XFxuZXhwb3J0IGNvbnN0IG1vZHVsZVBhY2thZ2UgPSB7IG5hbWU6ICcke2luZmVycmVkTmFtZX0nLCBwcm9tcHRzLCByZXNvdXJjZXMsIHRlbXBsYXRlcywgdG9vbHMgfSBhcyBjb25zdDtcXG5gO1xuICAgIGZzLndyaXRlRmlsZVN5bmMobW9kdWxlSW5kZXgsIG1vZHVsZUluZGV4Q29udGVudCwgeyBlbmNvZGluZzogXCJ1dGY4XCIgfSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29udGVudDogW1xuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgdGV4dDogSlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIG1vZHVsZVJvb3QsXG4gICAgICAgICAgICAgIGluZmVycmVkTmFtZSxcbiAgICAgICAgICAgICAgYW5hbHlzaXNTdW1tYXJ5OiB7XG4gICAgICAgICAgICAgICAgZmlsZXM6IGFuYWx5c2lzLmZpbGVzLmxlbmd0aCxcbiAgICAgICAgICAgICAgICB0ZXN0RmlsZXM6IGFuYWx5c2lzLnRlc3RGaWxlcy5sZW5ndGgsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgIDJcbiAgICAgICAgICApLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9O1xuICB9LFxufTtcblxuZXhwb3J0IGRlZmF1bHQgZ2VuZXJhdGVNY3BNb2R1bGVUb29sO1xuIiwiaW1wb3J0IHsgZGVjb3JhdG9yVG9vbHMgfSBmcm9tIFwiLi4vZGVjb3JhdG9yLXRvb2xzXCI7XG5pbXBvcnQgeyBtb2R1bGVSZWdpc3RyeSB9IGZyb20gXCIuLi9tb2R1bGVSZWdpc3RyeVwiO1xuaW1wb3J0IHtcbiAgYXBwbHlDb2RlQ2hhbmdlVG9vbCxcbiAgZG9jdW1lbnRDb2RlVG9vbCxcbiAgdG9vbExpc3QgYXMgY29yZVRvb2xMaXN0LFxufSBmcm9tIFwiLi90b29sc1wiO1xuaW1wb3J0IHtcbiAgY292ZXJhZ2VFbmZvcmNlclRvb2wsXG4gIGRvY3VtZW50T2JqZWN0VG9vbCxcbiAgcmVhZG1lSW1wcm92ZW1lbnRUb29sLFxufSBmcm9tIFwiLi9jb2RleC10b29sc1wiO1xuXG5leHBvcnQgKiBmcm9tIFwiLi90b29sc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vY29kZXgtdG9vbHNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2dlbmVyYXRlTWNwTW9kdWxlXCI7XG5cbmNvbnN0IGNvZGV4VG9vbExpc3QgPSBbXG4gIGRvY3VtZW50T2JqZWN0VG9vbCxcbiAgY292ZXJhZ2VFbmZvcmNlclRvb2wsXG4gIHJlYWRtZUltcHJvdmVtZW50VG9vbCxcbl07XG5cbmNvbnN0IG1vZHVsZVRvb2xMaXN0ID0gbW9kdWxlUmVnaXN0cnkubGlzdFRvb2xzKCkubWFwKChhc3NldCkgPT4gYXNzZXQudG9vbCBhcyBhbnkpO1xuXG5leHBvcnQgY29uc3QgdG9vbExpc3QgPSBbLi4uY29yZVRvb2xMaXN0LCAuLi5jb2RleFRvb2xMaXN0LCAuLi5tb2R1bGVUb29sTGlzdF07XG5leHBvcnQgY29uc3QgZGVjb3JhdG9yVG9vbExpc3QgPSBPYmplY3QudmFsdWVzKGRlY29yYXRvclRvb2xzKTtcbmNvbnN0IFtcbiAgYW5hbHl6ZVJlcG9zaXRvcnlUb29sLFxuICBlbnVtZXJhdGVDYXBhYmlsaXRpZXNUb29sLFxuICBwbGFuRmVhdHVyZVRvb2wsXG4gIGRvY3VtZW50Q29kZVRvb2xSZWYsXG4gIGFwcGx5Q29kZUNoYW5nZVRvb2xSZWYsXG5dID0gY29yZVRvb2xMaXN0O1xuXG5leHBvcnQgY29uc3QgdG9vbHMgPSB7XG4gIGFuYWx5emVSZXBvc2l0b3J5VG9vbCxcbiAgZW51bWVyYXRlQ2FwYWJpbGl0aWVzVG9vbCxcbiAgcGxhbkZlYXR1cmVUb29sLFxuICBkb2N1bWVudENvZGVUb29sOiBkb2N1bWVudENvZGVUb29sUmVmLFxuICBhcHBseUNvZGVDaGFuZ2VUb29sOiBhcHBseUNvZGVDaGFuZ2VUb29sUmVmLFxuICBkb2N1bWVudE9iamVjdFRvb2wsXG4gIGNvdmVyYWdlRW5mb3JjZXJUb29sLFxuICByZWFkbWVJbXByb3ZlbWVudFRvb2wsXG4gIC4uLmRlY29yYXRvclRvb2xzLFxufTtcblxuZXhwb3J0IHsgZGVjb3JhdG9yVG9vbHMgfTsiLCJpbXBvcnQgdHlwZSB7IFJlc291cmNlIH0gZnJvbSBcImZhc3RtY3BcIjtcbmltcG9ydCB0eXBlIHsgUmVzb3VyY2VBc3NldCB9IGZyb20gXCIuLi8uLi90eXBlc1wiO1xuaW1wb3J0IHsgbW9kdWxlUmVnaXN0cnkgfSBmcm9tIFwiLi4vbW9kdWxlUmVnaXN0cnlcIjtcbmltcG9ydCB7IGdldFdvcmtzcGFjZVJvb3QgfSBmcm9tIFwiLi4vd29ya3NwYWNlXCI7XG5pbXBvcnQgeyBidWlsZE9iamVjdFByb21wdHMsIGRpc2NvdmVyRG9jUHJvbXB0cyB9IGZyb20gXCIuLi9wcm9tcHRzL3Byb21wdHNcIjtcblxuZnVuY3Rpb24gdG9SZXNvdXJjZShhc3NldDogUmVzb3VyY2VBc3NldCk6IFJlc291cmNlPHVuZGVmaW5lZD4ge1xuICByZXR1cm4ge1xuICAgIG5hbWU6IGFzc2V0LmlkLFxuICAgIHVyaTogYXNzZXQudXJpLFxuICAgIGRlc2NyaXB0aW9uOiBhc3NldC5kZXNjcmlwdGlvbiA/PyBhc3NldC50aXRsZSxcbiAgICBtaW1lVHlwZTogYXNzZXQubWltZVR5cGUsXG4gICAgbG9hZDogYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgYXNzZXQubG9hZCgpO1xuICAgICAgLy8gYXNzZXQubG9hZCBtYXkgcmV0dXJuIGEgQ29udGVudFJlc3VsdCBvciBhIFByb21pc2Ugb2YgQ29udGVudFJlc3VsdDsgZW5zdXJlIHdlIHJldHVybiBSZXNvdXJjZVJlc3VsdC1saWtlIG9iamVjdFxuICAgICAgaWYgKChyZXMgYXMgYW55KT8uY29udGVudCkge1xuICAgICAgICBjb25zdCBjciA9IHJlcyBhcyBhbnk7XG4gICAgICAgIC8vIElmIENvbnRlbnRSZXN1bHQsIGNvbnZlcnQgdG8gc2ltcGxlIHRleHQgcmVzdWx0IGV4cGVjdGVkIGJ5IFJlc291cmNlLmxvYWQgY29uc3VtZXJzXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdGV4dDogQXJyYXkuaXNBcnJheShjci5jb250ZW50KVxuICAgICAgICAgICAgPyBjci5jb250ZW50Lm1hcCgoYzogYW55KSA9PiBjLnRleHQpLmpvaW4oXCJcXG5cIilcbiAgICAgICAgICAgIDogU3RyaW5nKGNyKSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIC8vIGZhbGxiYWNrIGZvciBvYmplY3RzIHdpdGggdGV4dFxuICAgICAgcmV0dXJuIHJlcyBhcyBhbnkgYXMgeyB0ZXh0OiBzdHJpbmcgfTtcbiAgICB9LFxuICB9O1xufVxuXG5mdW5jdGlvbiBidWlsZE1vZHVsZVJlc291cmNlcygpOiBSZXNvdXJjZTx1bmRlZmluZWQ+W10ge1xuICByZXR1cm4gbW9kdWxlUmVnaXN0cnkubGlzdFJlc291cmNlcygpLm1hcCh0b1Jlc291cmNlKTtcbn1cblxuZXhwb3J0IGNvbnN0IHJlc291cmNlczogUmVzb3VyY2U8dW5kZWZpbmVkPltdID0gW1xuICB7XG4gICAgbmFtZTogXCJjb2RleC1wcm9tcHQtaW5kZXhcIixcbiAgICB1cmk6IFwiY29kZXg6Ly9wcm9tcHRzL2luZGV4XCIsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICBcIkVudW1lcmF0ZSBhdmFpbGFibGUgLmNvZGV4IHByb21wdCBmaWxlcyB3aXRoIHRpdGxlcyBhbmQgZGVzY3JpcHRpb25zLlwiLFxuICAgIG1pbWVUeXBlOiBcImFwcGxpY2F0aW9uL2pzb25cIixcbiAgICBsb2FkOiBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCByb290ID0gZ2V0V29ya3NwYWNlUm9vdCgpO1xuICAgICAgY29uc3QgcHJvbXB0cyA9IGRpc2NvdmVyRG9jUHJvbXB0cyhyb290KS5tYXAoKHByb21wdCkgPT4gKHtcbiAgICAgICAgbmFtZTogcHJvbXB0Lm5hbWUsXG4gICAgICAgIHRpdGxlOiBwcm9tcHQudGl0bGUsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBwcm9tcHQuZGVzY3JpcHRpb24sXG4gICAgICAgIHBhdGg6IHByb21wdC5hYnNvbHV0ZVBhdGgsXG4gICAgICB9KSk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0ZXh0OiBKU09OLnN0cmluZ2lmeSh7IHByb21wdHMgfSwgbnVsbCwgMiksXG4gICAgICAgIG1pbWVUeXBlOiBcImFwcGxpY2F0aW9uL2pzb25cIixcbiAgICAgIH07XG4gICAgfSxcbiAgfSxcbiAge1xuICAgIG5hbWU6IFwiY29kZXgtb2JqZWN0LXByb21wdHNcIixcbiAgICB1cmk6IFwiY29kZXg6Ly9wcm9tcHRzL29iamVjdHNcIixcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgIFwiUHJvdmlkZXMgdGhlIHJlc29sdmVkIHByb21wdCBjb250ZW50IGZvciBlYWNoIGRvY3VtZW50ZWQgb2JqZWN0IHdvcmtmbG93LlwiLFxuICAgIG1pbWVUeXBlOiBcImFwcGxpY2F0aW9uL2pzb25cIixcbiAgICBsb2FkOiBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBlbnRyaWVzID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgIGJ1aWxkT2JqZWN0UHJvbXB0cygpLm1hcChhc3luYyAocHJvbXB0KSA9PiAoe1xuICAgICAgICAgIG5hbWU6IHByb21wdC5uYW1lLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiBwcm9tcHQuZGVzY3JpcHRpb24sXG4gICAgICAgICAgY29udGVudDogYXdhaXQgcHJvbXB0LmxvYWQoe30gYXMgbmV2ZXIpLFxuICAgICAgICB9KSlcbiAgICAgICk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0ZXh0OiBKU09OLnN0cmluZ2lmeSh7IHByb21wdHM6IGVudHJpZXMgfSwgbnVsbCwgMiksXG4gICAgICAgIG1pbWVUeXBlOiBcImFwcGxpY2F0aW9uL2pzb25cIixcbiAgICAgIH07XG4gICAgfSxcbiAgfSxcbiAgLi4uYnVpbGRNb2R1bGVSZXNvdXJjZXMoKSxcbl07XG4iLCJpbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IHsgZ2V0V29ya3NwYWNlUm9vdCwgcmVzb2x2ZUluV29ya3NwYWNlIH0gZnJvbSBcIi4uL3dvcmtzcGFjZVwiO1xuaW1wb3J0IHR5cGUgeyBQcm9tcHRSZXNvdXJjZVRlbXBsYXRlIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbmV4cG9ydCBjb25zdCBjb2RleFByb21wdFRlbXBsYXRlczogUHJvbXB0UmVzb3VyY2VUZW1wbGF0ZVtdID0gW107XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZENvZGV4UHJvbXB0VGVtcGxhdGVzKCk6IFByb21wdFJlc291cmNlVGVtcGxhdGVbXSB7XG4gIGNvbnN0IHJvb3QgPSBnZXRXb3Jrc3BhY2VSb290KCk7XG4gIGNvbnN0IHRlbXBsYXRlczogUHJvbXB0UmVzb3VyY2VUZW1wbGF0ZVtdID0gW1xuICAgIHtcbiAgICAgIG5hbWU6IFwiY29kZXgtcHJvbXB0XCIsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgXCJMb2FkIGEgLmNvZGV4IHByb21wdCBmaWxlIGJ5IG5hbWUgKHdpdGhvdXQgZXh0ZW5zaW9uKSBhcyBtYXJrZG93bi5cIixcbiAgICAgIHVyaVRlbXBsYXRlOiBcImNvZGV4LXByb21wdDovL3tuYW1lfVwiLFxuICAgICAgbWltZVR5cGU6IFwidGV4dC9tYXJrZG93blwiLFxuICAgICAgYXJndW1lbnRzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcIm5hbWVcIixcbiAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgIFwiTmFtZSBvZiB0aGUgcHJvbXB0IGZpbGUgaW5zaWRlIC5jb2RleC9wcm9tcHRzICh3aXRob3V0IC5tZCkuXCIsXG4gICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgICAgbG9hZDogYXN5bmMgKHsgbmFtZSB9KSA9PiB7XG4gICAgICAgIGNvbnN0IHByb21wdFBhdGggPSByZXNvbHZlSW5Xb3Jrc3BhY2UoXG4gICAgICAgICAgcm9vdCxcbiAgICAgICAgICBwYXRoLmpvaW4oXCIuY29kZXhcIiwgXCJwcm9tcHRzXCIsIGAke25hbWV9Lm1kYClcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKHByb21wdFBhdGgpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBQcm9tcHQgLmNvZGV4L3Byb21wdHMvJHtuYW1lfS5tZCBub3QgZm91bmRgKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB0ZXh0ID0gZnMucmVhZEZpbGVTeW5jKHByb21wdFBhdGgsIFwidXRmOFwiKTtcbiAgICAgICAgcmV0dXJuIHsgdGV4dCwgdXJpOiBgY29kZXgtcHJvbXB0Oi8vLyR7bmFtZX1gIH07XG4gICAgICB9LFxuICAgIH0sXG4gIF07XG5cbiAgY29kZXhQcm9tcHRUZW1wbGF0ZXMuc3BsaWNlKDAsIGNvZGV4UHJvbXB0VGVtcGxhdGVzLmxlbmd0aCwgLi4udGVtcGxhdGVzKTtcbiAgcmV0dXJuIGNvZGV4UHJvbXB0VGVtcGxhdGVzO1xufVxuIiwiaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB0eXBlIHsgRGVjb3JhdGlvblJlc291cmNlVGVtcGxhdGUgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IGdldFdvcmtzcGFjZVJvb3QsIHJlYWRXb3Jrc3BhY2VGaWxlIH0gZnJvbSBcIi4uL3dvcmtzcGFjZVwiO1xuXG5leHBvcnQgY29uc3QgZGVjb3JhdGlvblJlc291cmNlVGVtcGxhdGVzOiBEZWNvcmF0aW9uUmVzb3VyY2VUZW1wbGF0ZVtdID0gW107XG5cbmZ1bmN0aW9uIG1ha2VMb2FkZXIodHlwZTogXCJzcmNcIiB8IFwidGVzdHNcIiB8IFwid29ya2RvY3NcIikge1xuICByZXR1cm4gYXN5bmMgKHsgcGF0aDogcmVsYXRpdmUgfTogeyBwYXRoOiBzdHJpbmcgfSkgPT4ge1xuICAgIGNvbnN0IHJvb3QgPSBnZXRXb3Jrc3BhY2VSb290KCk7XG4gICAgY29uc3QgdGFyZ2V0ID0gcGF0aC5qb2luKHR5cGUsIHJlbGF0aXZlKTtcbiAgICBjb25zdCB0ZXh0ID0gYXdhaXQgcmVhZFdvcmtzcGFjZUZpbGUocm9vdCwgdGFyZ2V0KTtcbiAgICByZXR1cm4geyB0ZXh0IH07XG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZERlY29yYXRpb25SZXNvdXJjZVRlbXBsYXRlcygpOiBEZWNvcmF0aW9uUmVzb3VyY2VUZW1wbGF0ZVtdIHtcbiAgY29uc3QgdGVtcGxhdGVzOiBEZWNvcmF0aW9uUmVzb3VyY2VUZW1wbGF0ZVtdID0gW1xuICAgIHtcbiAgICAgIG5hbWU6IFwicmVhZC1jb2RlLWZyb20tc291cmNlXCIsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgXCJSZWFkIGEgZmlsZSBmcm9tIHRoZSA8YmFzZV9wYXRoPi9zcmMgdHJlZSBieSByZWxhdGl2ZSBwYXRoLlwiLFxuICAgICAgbWltZVR5cGU6IFwidGV4dC9wbGFpblwiLFxuICAgICAgdXJpVGVtcGxhdGU6IFwiZnJvbS1zb3VyY2U6Ly9zcmMve3BhdGh9XCIsXG4gICAgICBhcmd1bWVudHM6IFtcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwicGF0aFwiLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgXCJQYXRoIHVuZGVyIDxiYXNlX3BhdGg+L3NyYyB0byBsb2FkLCBlLmcuICdkZWNvcmF0aW9uL3R5cGVzLnRzJ1wiLFxuICAgICAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICAgIGxvYWQ6IG1ha2VMb2FkZXIoXCJzcmNcIiksXG4gICAgfSxcbiAgICB7XG4gICAgICBuYW1lOiBcInJlYWQtdGVzdC1mcm9tLXNvdXJjZVwiLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgIFwiUmVhZCBhIGZpbGUgZnJvbSB0aGUgPGJhc2VfcGF0aD4vdGVzdHMgdHJlZSBieSByZWxhdGl2ZSBwYXRoLlwiLFxuICAgICAgbWltZVR5cGU6IFwidGV4dC9wbGFpblwiLFxuICAgICAgdXJpVGVtcGxhdGU6IFwiZnJvbS1zb3VyY2U6Ly90ZXN0cy97cGF0aH1cIixcbiAgICAgIGFyZ3VtZW50czogW1xuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJwYXRoXCIsXG4gICAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgICBcIlBhdGggdW5kZXIgPGJhc2VfcGF0aD4vdGVzdHMgdG8gbG9hZCwgZS5nLiAnZGVjb3JhdGlvbi90ZXN0cy90eXBlcy50ZXN0LnRzJ1wiLFxuICAgICAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICAgIGxvYWQ6IG1ha2VMb2FkZXIoXCJ0ZXN0c1wiKSxcbiAgICB9LFxuICAgIHtcbiAgICAgIG5hbWU6IFwicmVhZC1kb2MtZnJvbS1zb3VyY2VcIixcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICBcIlJlYWQgYSBmaWxlIGZyb20gdGhlIDxiYXNlX3BhdGg+L3dvcmtkb2NzIHRyZWUgYnkgcmVsYXRpdmUgcGF0aC5cIixcbiAgICAgIG1pbWVUeXBlOiBcInRleHQvcGxhaW5cIixcbiAgICAgIHVyaVRlbXBsYXRlOiBcImZyb20tc291cmNlOi8vd29ya2RvY3Mve3BhdGh9XCIsXG4gICAgICBhcmd1bWVudHM6IFtcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwicGF0aFwiLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgXCJQYXRoIHVuZGVyIDxiYXNlX3BhdGg+L3dvcmtkb2NzIHRvIGxvYWQsIGUuZy4gJ2RlY29yYXRpb24vd29ya2RvY3MvdHV0b3JpYWxzL2Zvci1kZXZlbG9wZXJzLm1kJ1wiLFxuICAgICAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICAgIGxvYWQ6IG1ha2VMb2FkZXIoXCJ3b3JrZG9jc1wiKSxcbiAgICB9LFxuICBdO1xuXG4gIGRlY29yYXRpb25SZXNvdXJjZVRlbXBsYXRlcy5zcGxpY2UoXG4gICAgMCxcbiAgICBkZWNvcmF0aW9uUmVzb3VyY2VUZW1wbGF0ZXMubGVuZ3RoLFxuICAgIC4uLnRlbXBsYXRlc1xuICApO1xuICByZXR1cm4gZGVjb3JhdGlvblJlc291cmNlVGVtcGxhdGVzO1xufVxuIiwiaW1wb3J0IHsgV29ya3NwYWNlUmVzb3VyY2VUZW1wbGF0ZSB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgZ2V0V29ya3NwYWNlUm9vdCwgcmVhZFdvcmtzcGFjZUZpbGUgfSBmcm9tIFwiLi4vd29ya3NwYWNlXCI7XG5cbmV4cG9ydCBjb25zdCB3b3Jrc3BhY2VSZXNvdXJjZVRlbXBsYXRlczogV29ya3NwYWNlUmVzb3VyY2VUZW1wbGF0ZVtdID0gW107XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFdvcmtzcGFjZVJlc291cmNlVGVtcGxhdGVzKCk6IFdvcmtzcGFjZVJlc291cmNlVGVtcGxhdGVbXSB7XG4gIGNvbnN0IHJvb3QgPSBnZXRXb3Jrc3BhY2VSb290KCk7XG4gIGNvbnN0IHNoYXJlZEFyZ3VtZW50cyA9IFtcbiAgICB7XG4gICAgICBuYW1lOiBcInBhdGhcIixcbiAgICAgIGRlc2NyaXB0aW9uOiBcIlBhdGggcmVsYXRpdmUgdG8gdGhlIHdvcmtzcGFjZSByb290XCIsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICB9LFxuICBdIGFzIGNvbnN0O1xuXG4gIGNvbnN0IHRlbXBsYXRlczogV29ya3NwYWNlUmVzb3VyY2VUZW1wbGF0ZVtdID0gW1xuICAgIHtcbiAgICAgIG5hbWU6IFwidnNjb2RlLXdvcmtzcGFjZS1maWxlXCIsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgXCJFeHBvc2Ugd29ya3NwYWNlIGZpbGVzIHRvIFZpc3VhbCBTdHVkaW8gQ29kZSB2aWEgdnNjb2RlOi8vIFVSSXNcIixcbiAgICAgIHVyaVRlbXBsYXRlOiBcInZzY29kZTovL3dvcmtzcGFjZS97cGF0aH1cIixcbiAgICAgIG1pbWVUeXBlOiBcInRleHQvcGxhaW5cIixcbiAgICAgIGFyZ3VtZW50czogc2hhcmVkQXJndW1lbnRzLFxuICAgICAgbG9hZDogYXN5bmMgKGFyZ3M6IHsgcGF0aDogc3RyaW5nIH0pID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgcmVhZFdvcmtzcGFjZUZpbGUocm9vdCwgYXJncy5wYXRoKTtcbiAgICAgICAgICByZXR1cm4geyB0ZXh0OiBTdHJpbmcodGV4dCkgfTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgLy8gcHJvcGFnYXRlIGFzLWlzIGZvciB0ZXN0cyB0byBhc3NlcnQgZXJyb3JzXG4gICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0sXG4gICAge1xuICAgICAgbmFtZTogXCJjdXJzb3Itd29ya3NwYWNlLWZpbGVcIixcbiAgICAgIGRlc2NyaXB0aW9uOiBcIkV4cG9zZSB3b3Jrc3BhY2UgZmlsZXMgdG8gQ3Vyc29yIHZpYSBjdXJzb3I6Ly8gVVJJc1wiLFxuICAgICAgdXJpVGVtcGxhdGU6IFwiY3Vyc29yOi8vd29ya3NwYWNlL3twYXRofVwiLFxuICAgICAgbWltZVR5cGU6IFwidGV4dC9wbGFpblwiLFxuICAgICAgYXJndW1lbnRzOiBzaGFyZWRBcmd1bWVudHMsXG4gICAgICBsb2FkOiBhc3luYyAoYXJnczogeyBwYXRoOiBzdHJpbmcgfSkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHRleHQgPSBhd2FpdCByZWFkV29ya3NwYWNlRmlsZShyb290LCBhcmdzLnBhdGgpO1xuICAgICAgICAgIHJldHVybiB7IHRleHQ6IFN0cmluZyh0ZXh0KSB9O1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSxcbiAgICB7XG4gICAgICBuYW1lOiBcImNvcGlsb3Qtd29ya3NwYWNlLWZpbGVcIixcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICBcIkV4cG9zZSB3b3Jrc3BhY2UgZmlsZXMgdG8gR2l0SHViIENvcGlsb3QgdmlhIGNvcGlsb3Q6Ly8gVVJJc1wiLFxuICAgICAgdXJpVGVtcGxhdGU6IFwiY29waWxvdDovL3dvcmtzcGFjZS97cGF0aH1cIixcbiAgICAgIG1pbWVUeXBlOiBcInRleHQvcGxhaW5cIixcbiAgICAgIGFyZ3VtZW50czogc2hhcmVkQXJndW1lbnRzLFxuICAgICAgbG9hZDogYXN5bmMgKGFyZ3M6IHsgcGF0aDogc3RyaW5nIH0pID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgcmVhZFdvcmtzcGFjZUZpbGUocm9vdCwgYXJncy5wYXRoKTtcbiAgICAgICAgICByZXR1cm4geyB0ZXh0OiBTdHJpbmcodGV4dCkgfTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0sXG4gIF07XG5cbiAgd29ya3NwYWNlUmVzb3VyY2VUZW1wbGF0ZXMuc3BsaWNlKFxuICAgIDAsXG4gICAgd29ya3NwYWNlUmVzb3VyY2VUZW1wbGF0ZXMubGVuZ3RoLFxuICAgIC4uLnRlbXBsYXRlc1xuICApO1xuICByZXR1cm4gd29ya3NwYWNlUmVzb3VyY2VUZW1wbGF0ZXM7XG59XG5cbiIsImltcG9ydCB7XG4gIGJ1aWxkQ29kZXhQcm9tcHRUZW1wbGF0ZXMsXG4gIGNvZGV4UHJvbXB0VGVtcGxhdGVzLFxufSBmcm9tIFwiLi9jb2RleC10ZW1wbGF0ZXNcIjtcbmltcG9ydCB7XG4gIGJ1aWxkRGVjb3JhdGlvblJlc291cmNlVGVtcGxhdGVzLFxuICBkZWNvcmF0aW9uUmVzb3VyY2VUZW1wbGF0ZXMsXG59IGZyb20gXCIuL3Jlc291cmNlLXRlbXBsYXRlc1wiO1xuaW1wb3J0IHtcbiAgYnVpbGRXb3Jrc3BhY2VSZXNvdXJjZVRlbXBsYXRlcyxcbiAgd29ya3NwYWNlUmVzb3VyY2VUZW1wbGF0ZXMsXG59IGZyb20gXCIuL3dvcmtzcGFjZS10ZW1wbGF0ZXNcIjtcbmltcG9ydCB0eXBlIHsgVGVtcGxhdGVBc3NldCB9IGZyb20gXCIuLi8uLi90eXBlc1wiO1xuaW1wb3J0IHsgbW9kdWxlUmVnaXN0cnkgfSBmcm9tIFwiLi4vbW9kdWxlUmVnaXN0cnlcIjtcblxuZXhwb3J0IHtcbiAgYnVpbGRDb2RleFByb21wdFRlbXBsYXRlcyxcbiAgY29kZXhQcm9tcHRUZW1wbGF0ZXMsXG59IGZyb20gXCIuL2NvZGV4LXRlbXBsYXRlc1wiO1xuZXhwb3J0IHtcbiAgYnVpbGREZWNvcmF0aW9uUmVzb3VyY2VUZW1wbGF0ZXMsXG4gIGRlY29yYXRpb25SZXNvdXJjZVRlbXBsYXRlcyxcbn0gZnJvbSBcIi4vcmVzb3VyY2UtdGVtcGxhdGVzXCI7XG5leHBvcnQge1xuICBidWlsZFdvcmtzcGFjZVJlc291cmNlVGVtcGxhdGVzLFxuICB3b3Jrc3BhY2VSZXNvdXJjZVRlbXBsYXRlcyxcbn0gZnJvbSBcIi4vd29ya3NwYWNlLXRlbXBsYXRlc1wiO1xuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRSZXNvdXJjZVRlbXBsYXRlcygpIHtcbiAgY29uc3QgbW9kdWxlVGVtcGxhdGVzID0gbW9kdWxlUmVnaXN0cnkubGlzdFRlbXBsYXRlcygpLm1hcCgodGVtcGxhdGUpID0+ICh7XG4gICAgbmFtZTogdGVtcGxhdGUuaWQsXG4gICAgZGVzY3JpcHRpb246IHRlbXBsYXRlLmRlc2NyaXB0aW9uID8/IHRlbXBsYXRlLnRpdGxlLFxuICAgIG1pbWVUeXBlOiBcInRleHQvbWFya2Rvd25cIixcbiAgICB1cmlUZW1wbGF0ZTogYG1vZHVsZS10ZW1wbGF0ZTovLyR7dGVtcGxhdGUuaWR9YCxcbiAgICBhcmd1bWVudHM6ICh0ZW1wbGF0ZS5wbGFjZWhvbGRlcnMgPz8gW10pLm1hcCgobmFtZSkgPT4gKHtcbiAgICAgIG5hbWUsXG4gICAgICBkZXNjcmlwdGlvbjogYFZhbHVlIGZvciAke25hbWV9YCxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgIH0pKSxcbiAgICBsb2FkOiBhc3luYyAoKSA9PiAoe1xuICAgICAgdGV4dDpcbiAgICAgICAgdHlwZW9mICh0ZW1wbGF0ZSBhcyBhbnkpLmNvbnRlbnQgPT09IFwic3RyaW5nXCJcbiAgICAgICAgICA/ICh0ZW1wbGF0ZSBhcyBhbnkpLmNvbnRlbnRcbiAgICAgICAgICA6IGAjICR7dGVtcGxhdGUuZGVzY3JpcHRpb24gPz8gdGVtcGxhdGUudGl0bGUgPz8gdGVtcGxhdGUuaWR9XFxuXFxuTm8gdGVtcGxhdGUgY29udGVudCBhdmFpbGFibGUgZm9yICR7dGVtcGxhdGUuaWR9YCxcbiAgICB9KSxcbiAgfSkpO1xuXG4gIGNvbnN0IGFsbCA9IFtcbiAgICAuLi5idWlsZFdvcmtzcGFjZVJlc291cmNlVGVtcGxhdGVzKCksXG4gICAgLi4uYnVpbGRDb2RleFByb21wdFRlbXBsYXRlcygpLFxuICAgIC4uLmJ1aWxkRGVjb3JhdGlvblJlc291cmNlVGVtcGxhdGVzKCksXG4gICAgLi4ubW9kdWxlVGVtcGxhdGVzLFxuICBdO1xuXG4gIC8vIE5vcm1hbGlzZSBhbGwgbG9hZGVycyB0byBhbHdheXMgcmV0dXJuIHsgdGV4dDogc3RyaW5nIH1cbiAgZnVuY3Rpb24gbm9ybWFsaXNlUmVzdWx0KHJlczogYW55KSB7XG4gICAgaWYgKHJlcyA9PSBudWxsKSByZXR1cm4geyB0ZXh0OiBcIlwiIH07XG4gICAgaWYgKHR5cGVvZiByZXMgPT09IFwic3RyaW5nXCIpIHJldHVybiB7IHRleHQ6IHJlcyB9O1xuICAgIGlmICh0eXBlb2YgcmVzLnRleHQgPT09IFwic3RyaW5nXCIpIHJldHVybiByZXM7XG4gICAgLy8gaGFuZGxlIGxlZ2FjeSBDb250ZW50UmVzdWx0IHNoYXBlcyB3aXRoIGNvbnRlbnQgb3IgY29udGVudCBhcnJheVxuICAgIGlmIChBcnJheS5pc0FycmF5KHJlcy5jb250ZW50KSkge1xuICAgICAgY29uc3QgcGFydHMgPSByZXMuY29udGVudFxuICAgICAgICAubWFwKChjOiBhbnkpID0+IChjICYmIHR5cGVvZiBjLnRleHQgPT09IFwic3RyaW5nXCIgPyBjLnRleHQgOiBTdHJpbmcoYykpKVxuICAgICAgICAuam9pbihcIlxcblwiKTtcbiAgICAgIHJldHVybiB7IHRleHQ6IHBhcnRzIH07XG4gICAgfVxuICAgIGlmIChyZXMuY29udGVudCAmJiB0eXBlb2YgcmVzLmNvbnRlbnQudGV4dCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgcmV0dXJuIHsgdGV4dDogcmVzLmNvbnRlbnQudGV4dCB9O1xuICAgIH1cbiAgICAvLyBmYWxsYmFjazogc3RyaW5naWZ5XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiB7IHRleHQ6IEpTT04uc3RyaW5naWZ5KHJlcykgfTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiB7IHRleHQ6IFN0cmluZyhyZXMpIH07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGFsbC5tYXAoKHQpID0+ICh7XG4gICAgLi4udCxcbiAgICBsb2FkOiBhc3luYyAoYXJnczogYW55KSA9PiB7XG4gICAgICBjb25zdCByYXcgPSBhd2FpdCAodC5sb2FkIGFzIGFueSkoYXJncyk7XG4gICAgICByZXR1cm4gbm9ybWFsaXNlUmVzdWx0KHJhdyk7XG4gICAgfSxcbiAgfSkpO1xufVxuXG5leHBvcnQgY29uc3QgdGVtcGxhdGVMaXN0ID0gYnVpbGRSZXNvdXJjZVRlbXBsYXRlcygpO1xuIiwiaW1wb3J0IHsgTWV0YWRhdGEgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRpb25cIjtcblxuLyoqXG4gKiBAY29uc3QgVkVSU0lPTlxuICogQG5hbWUgVkVSU0lPTlxuICogQGRlc2NyaXB0aW9uIFJlcHJlc2VudHMgdGhlIGN1cnJlbnQgdmVyc2lvbiBvZiB0aGUgdHMtd29ya3NwYWNlIG1vZHVsZS5cbiAqIEBzdW1tYXJ5IFRoZSBhY3R1YWwgdmVyc2lvbiBudW1iZXIgaXMgcmVwbGFjZWQgZHVyaW5nIHRoZSBidWlsZCBwcm9jZXNzLlxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuZXhwb3J0IGNvbnN0IFZFUlNJT04gPSBcIiMjVkVSU0lPTiMjXCI7XG5leHBvcnQgY29uc3QgUEFDS0FHRV9OQU1FID0gXCIjI1BBQ0tBR0VfTkFNRSMjXCI7XG5cbnRyeSB7XG4gIE1ldGFkYXRhLnJlZ2lzdGVyTGlicmFyeShQQUNLQUdFX05BTUUsIFZFUlNJT04pO1xufSBjYXRjaCAoZXJyb3IpIHtcbiAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IgJiYgZXJyb3IubWVzc2FnZS5pbmNsdWRlcyhcImFscmVhZHlcIikpIHtcbiAgICAvLyBJZ25vcmUgZHVwbGljYXRlIHJlZ2lzdHJhdGlvbiBkdXJpbmcgdGVzdHMvYnVuZGxpbmcgY2hlY2tzLlxuICB9IGVsc2Uge1xuICAgIHRocm93IGVycm9yO1xuICB9XG59XG4iLCJpbXBvcnQgdHlwZSB7IEZhc3RNQ1AgfSBmcm9tIFwiZmFzdG1jcFwiO1xuaW1wb3J0IHsgUEFDS0FHRV9OQU1FIGFzIFBLRywgVkVSU0lPTiBhcyBWIH0gZnJvbSBcIi4uL21ldGFkYXRhXCI7XG5pbXBvcnQge1xuICBidWlsZERvY1Byb21wdHMsXG4gIGJ1aWxkUHJvbXB0cyxcbiAgYnVpbGREb2N1bWVudGF0aW9uUGF5bG9hZCxcbiAgZGlzY292ZXJEb2NQcm9tcHRzLFxuICBsb2FkUHJvbXB0cyxcbiAgcHJvbXB0TGlzdCxcbiAgcmVmcmVzaFByb21wdHMsXG4gIHNlbGVjdFByb21wdCxcbiAgREVGQVVMVF9QUk9NUFRfTkFNRSxcbn0gZnJvbSBcIi4vcHJvbXB0c1wiO1xuaW1wb3J0IHsgcmVzb3VyY2VzIH0gZnJvbSBcIi4vcmVzb3VyY2VzXCI7XG5pbXBvcnQge1xuICBidWlsZERlY29yYXRpb25SZXNvdXJjZVRlbXBsYXRlcyxcbiAgYnVpbGRSZXNvdXJjZVRlbXBsYXRlcyxcbiAgZGVjb3JhdGlvblJlc291cmNlVGVtcGxhdGVzLFxuICB0ZW1wbGF0ZUxpc3QsXG4gIHdvcmtzcGFjZVJlc291cmNlVGVtcGxhdGVzLFxufSBmcm9tIFwiLi90ZW1wbGF0ZXNcIjtcbmltcG9ydCB7IHRvb2xMaXN0LCB0b29scyB9IGZyb20gXCIuL3Rvb2xzXCI7XG5pbXBvcnQge1xuICBfX3Jlc2V0V29ya3NwYWNlUm9vdCxcbiAgZ2V0V29ya3NwYWNlUm9vdCxcbiAgc2V0V29ya3NwYWNlUm9vdCxcbn0gZnJvbSBcIi4vd29ya3NwYWNlXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBlbnJpY2gobWNwOiBGYXN0TUNQKTogRmFzdE1DUCB7XG4gIGNvbnN0IHByb21wdEVudHJpZXMgPSBsb2FkUHJvbXB0cygpO1xuICBmb3IgKGNvbnN0IHByb21wdCBvZiBwcm9tcHRFbnRyaWVzKSB7XG4gICAgbWNwLmFkZFByb21wdChwcm9tcHQgYXMgYW55KTtcbiAgfVxuXG4gIGZvciAoY29uc3QgdG9vbCBvZiB0b29sTGlzdCkge1xuICAgIG1jcC5hZGRUb29sKHRvb2wgYXMgYW55KTtcbiAgfVxuXG4gIGNvbnN0IHRlbXBsYXRlcyA9IGJ1aWxkUmVzb3VyY2VUZW1wbGF0ZXMoKTtcbiAgZm9yIChjb25zdCB0ZW1wbGF0ZSBvZiB0ZW1wbGF0ZXMpIHtcbiAgICBtY3AuYWRkUmVzb3VyY2VUZW1wbGF0ZSh0ZW1wbGF0ZSBhcyBhbnkpO1xuICB9XG5cbiAgZm9yIChjb25zdCByZXNvdXJjZSBvZiByZXNvdXJjZXMpIHtcbiAgICBjb25zdCBhZGRSZXNvdXJjZSA9IChtY3AgYXMgdW5rbm93biBhcyB7IGFkZFJlc291cmNlPzogKHJlczogdW5rbm93bikgPT4gdm9pZCB9KS5hZGRSZXNvdXJjZTtcbiAgICBpZiAodHlwZW9mIGFkZFJlc291cmNlID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIGFkZFJlc291cmNlLmNhbGwobWNwLCByZXNvdXJjZSBhcyBhbnkpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBtY3A7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGVucmljaDtcbmV4cG9ydCBjb25zdCBQQUNLQUdFX05BTUUgPSBQS0c7XG5leHBvcnQgY29uc3QgVkVSU0lPTiA9IFY7XG5cbmV4cG9ydCB7XG4gIHRvb2xzLFxuICB0b29sTGlzdCxcbiAgYnVpbGREb2NQcm9tcHRzLFxuICBidWlsZFByb21wdHMsXG4gIGJ1aWxkRGVjb3JhdGlvblJlc291cmNlVGVtcGxhdGVzLFxuICBidWlsZFJlc291cmNlVGVtcGxhdGVzLFxuICBidWlsZERvY3VtZW50YXRpb25QYXlsb2FkLFxuICBkZWNvcmF0aW9uUmVzb3VyY2VUZW1wbGF0ZXMsXG4gIGRpc2NvdmVyRG9jUHJvbXB0cyxcbiAgREVGQVVMVF9QUk9NUFRfTkFNRSxcbiAgcHJvbXB0TGlzdCxcbiAgcmVmcmVzaFByb21wdHMsXG4gIHJlc291cmNlcyxcbiAgc2VsZWN0UHJvbXB0LFxuICB0ZW1wbGF0ZUxpc3QsXG4gIHdvcmtzcGFjZVJlc291cmNlVGVtcGxhdGVzLFxuICBnZXRXb3Jrc3BhY2VSb290LFxuICBzZXRXb3Jrc3BhY2VSb290LFxuICBfX3Jlc2V0V29ya3NwYWNlUm9vdCxcbn07XG4iLCIvLyBOZXc6IHZhbGlkYXRpb24gZW50cnlwb2ludCBmb3IgbW9kdWxlIHN0cnVjdHVyZVxuaW1wb3J0IGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcblxuZXhwb3J0IHR5cGUgVmFsaWRhdGlvbklzc3VlID0ge1xuICBtb2R1bGU6IHN0cmluZztcbiAgcGF0aDogc3RyaW5nO1xuICB0eXBlOlxuICAgIHwgXCJtaXNzaW5nLWZvbGRlclwiXG4gICAgfCBcIm1pc3NpbmctZXhwb3J0XCJcbiAgICB8IFwiZW1wdHktbGlzdFwiXG4gICAgfCBcImRpc2FibGVkXCJcbiAgICB8IFwib3RoZXJcIjtcbiAgZGV0YWlsPzogc3RyaW5nO1xufTtcblxuZXhwb3J0IHR5cGUgVmFsaWRhdGlvblJlcG9ydCA9IHtcbiAgb2s6IGJvb2xlYW47XG4gIG1vZHVsZXNDaGVja2VkOiBudW1iZXI7XG4gIGlzc3VlczogVmFsaWRhdGlvbklzc3VlW107XG59O1xuXG5jb25zdCBSRVFVSVJFRF9TVUJGT0xERVJTID0gW1wicHJvbXB0c1wiLCBcInJlc291cmNlc1wiLCBcInRlbXBsYXRlc1wiLCBcInRvb2xzXCJdO1xuXG5leHBvcnQgZnVuY3Rpb24gZmluZE1vZHVsZURpcnMocmVwb1Jvb3Q6IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgY29uc3QgbW9kdWxlc1BhdGggPSBwYXRoLnJlc29sdmUocmVwb1Jvb3QsIFwic3JjXCIsIFwibW9kdWxlc1wiKTtcbiAgaWYgKCFmcy5leGlzdHNTeW5jKG1vZHVsZXNQYXRoKSB8fCAhZnMuc3RhdFN5bmMobW9kdWxlc1BhdGgpLmlzRGlyZWN0b3J5KCkpIHtcbiAgICByZXR1cm4gW107XG4gIH1cbiAgcmV0dXJuIGZzXG4gICAgLnJlYWRkaXJTeW5jKG1vZHVsZXNQYXRoLCB7IHdpdGhGaWxlVHlwZXM6IHRydWUgfSlcbiAgICAuZmlsdGVyKChkKSA9PiBkLmlzRGlyZWN0b3J5KCkpXG4gICAgLm1hcCgoZCkgPT4gcGF0aC5qb2luKG1vZHVsZXNQYXRoLCBkLm5hbWUpKTtcbn1cblxuZnVuY3Rpb24gaGFzSW5kZXhFeHBvcnQoZm9sZGVyUGF0aDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGNvbnN0IGNhbmRpZGF0ZXMgPSBbXG4gICAgXCJpbmRleC50c1wiLFxuICAgIFwiaW5kZXgudHN4XCIsXG4gICAgXCJpbmRleC5qc1wiLFxuICAgIFwiaW5kZXguY2pzXCIsXG4gICAgXCJpbmRleC5tanNcIixcbiAgXTtcbiAgZm9yIChjb25zdCBjIG9mIGNhbmRpZGF0ZXMpIHtcbiAgICBpZiAoZnMuZXhpc3RzU3luYyhwYXRoLmpvaW4oZm9sZGVyUGF0aCwgYykpKSByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZU1vZHVsZXMocmVwb1Jvb3Q6IHN0cmluZyk6IFZhbGlkYXRpb25SZXBvcnQge1xuICBjb25zdCBkaXJzID0gZmluZE1vZHVsZURpcnMocmVwb1Jvb3QpO1xuICBjb25zdCBpc3N1ZXM6IFZhbGlkYXRpb25Jc3N1ZVtdID0gW107XG5cbiAgZm9yIChjb25zdCBtb2R1bGVEaXIgb2YgZGlycykge1xuICAgIGNvbnN0IG1vZHVsZU5hbWUgPSBwYXRoLmJhc2VuYW1lKG1vZHVsZURpcik7XG4gICAgZm9yIChjb25zdCBzdWIgb2YgUkVRVUlSRURfU1VCRk9MREVSUykge1xuICAgICAgY29uc3Qgc3ViUGF0aCA9IHBhdGguam9pbihtb2R1bGVEaXIsIHN1Yik7XG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoc3ViUGF0aCkgfHwgIWZzLnN0YXRTeW5jKHN1YlBhdGgpLmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgICAgaXNzdWVzLnB1c2goe1xuICAgICAgICAgIG1vZHVsZTogbW9kdWxlTmFtZSxcbiAgICAgICAgICBwYXRoOiBzdWJQYXRoLFxuICAgICAgICAgIHR5cGU6IFwibWlzc2luZy1mb2xkZXJcIixcbiAgICAgICAgICBkZXRhaWw6IGBSZXF1aXJlZCBmb2xkZXIgJyR7c3VifScgaXMgbWlzc2luZyBpbiBtb2R1bGUgJyR7bW9kdWxlTmFtZX0nYCxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgLy8gSWYgZm9sZGVyIGV4aXN0cywgY2hlY2sgZm9yIGluZGV4IGV4cG9ydFxuICAgICAgaWYgKCFoYXNJbmRleEV4cG9ydChzdWJQYXRoKSkge1xuICAgICAgICBpc3N1ZXMucHVzaCh7XG4gICAgICAgICAgbW9kdWxlOiBtb2R1bGVOYW1lLFxuICAgICAgICAgIHBhdGg6IHN1YlBhdGgsXG4gICAgICAgICAgdHlwZTogXCJtaXNzaW5nLWV4cG9ydFwiLFxuICAgICAgICAgIGRldGFpbDogYE5vIGluZGV4IGV4cG9ydCBmb3VuZCBpbiAnJHtzdWJQYXRofScuIEV4cGVjdGVkIG9uZSBvZiBpbmRleC50cywgaW5kZXguanMsIGV0Yy5gLFxuICAgICAgICB9KTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICAvLyBPcHRpb25hbGx5IGluc3BlY3QgdGhlIGluZGV4IGZpbGUgdG8gc2VlIGlmIGl0IGV4cG9ydHMgYSBsaXN0IChsaWdodHdlaWdodCBjaGVjaylcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGluZGV4RmlsZSA9IGNhbmRpZGF0ZXNGaW5kaW5nSW5kZXgoc3ViUGF0aCk7XG4gICAgICAgIGlmIChpbmRleEZpbGUpIHtcbiAgICAgICAgICBjb25zdCBjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKGluZGV4RmlsZSwgXCJ1dGY4XCIpO1xuICAgICAgICAgIC8vIGNydWRlIGhldXJpc3RpY3M6IGxvb2sgZm9yIGBleHBvcnQgY29uc3QgbmFtZSA9IFtgIG9yIGBleHBvcnQgY29uc3QgbmFtZTogVHlwZVtdID0gW2AsXG4gICAgICAgICAgLy8gb3IgYW55IG5hbWVkIGV4cG9ydCBsaWtlIGBleHBvcnQgeyBzb21ldGhpbmcgfWAgd2hpY2ggaW1wbGllcyBleHBvcnRzIGV4aXN0LlxuICAgICAgICAgIGNvbnN0IGV4cG9ydExpc3RQYXR0ZXJuID1cbiAgICAgICAgICAgIC9leHBvcnRcXHMrKGNvbnN0fGxldHx2YXIpXFxzK1tcXHckXSsoPzpcXHMqOlxccypbXj1dKyk/XFxzKj1cXHMqXFxbLztcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAhZXhwb3J0TGlzdFBhdHRlcm4udGVzdChjb250ZW50KSAmJlxuICAgICAgICAgICAgIS9leHBvcnRcXHMrXFx7Ly50ZXN0KGNvbnRlbnQpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBpc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgIG1vZHVsZTogbW9kdWxlTmFtZSxcbiAgICAgICAgICAgICAgcGF0aDogaW5kZXhGaWxlLFxuICAgICAgICAgICAgICB0eXBlOiBcImVtcHR5LWxpc3RcIixcbiAgICAgICAgICAgICAgZGV0YWlsOiBgSW5kZXggZmlsZSBkb2VzIG5vdCBhcHBlYXIgdG8gZXhwb3J0IGEgbGlzdCBvZiBhc3NldHM6ICR7cGF0aC5iYXNlbmFtZShpbmRleEZpbGUpfWAsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICAgIGlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICBtb2R1bGU6IG1vZHVsZU5hbWUsXG4gICAgICAgICAgcGF0aDogc3ViUGF0aCxcbiAgICAgICAgICB0eXBlOiBcIm90aGVyXCIsXG4gICAgICAgICAgZGV0YWlsOiBgRXJyb3IgcmVhZGluZyBpbmRleCBmaWxlOiAke2Vyci5tZXNzYWdlfWAsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgb2s6IGlzc3Vlcy5sZW5ndGggPT09IDAsXG4gICAgbW9kdWxlc0NoZWNrZWQ6IGRpcnMubGVuZ3RoLFxuICAgIGlzc3VlcyxcbiAgfTtcbn1cblxuZnVuY3Rpb24gY2FuZGlkYXRlc0ZpbmRpbmdJbmRleChmb2xkZXJQYXRoOiBzdHJpbmcpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCBjYW5kaWRhdGVzID0gW1xuICAgIFwiaW5kZXgudHNcIixcbiAgICBcImluZGV4LnRzeFwiLFxuICAgIFwiaW5kZXguanNcIixcbiAgICBcImluZGV4LmNqc1wiLFxuICAgIFwiaW5kZXgubWpzXCIsXG4gIF07XG4gIGZvciAoY29uc3QgYyBvZiBjYW5kaWRhdGVzKSB7XG4gICAgY29uc3QgZnVsbCA9IHBhdGguam9pbihmb2xkZXJQYXRoLCBjKTtcbiAgICBpZiAoZnMuZXhpc3RzU3luYyhmdWxsKSkgcmV0dXJuIGZ1bGw7XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLy8gQ0xJIGhlbHBlclxuaWYgKHJlcXVpcmUubWFpbiA9PT0gbW9kdWxlKSB7XG4gIGNvbnN0IHJlcG9Sb290ID0gcHJvY2Vzcy5jd2QoKTtcbiAgY29uc3QgcmVwb3J0ID0gdmFsaWRhdGVNb2R1bGVzKHJlcG9Sb290KTtcbiAgaWYgKCFyZXBvcnQub2spIHtcbiAgICBjb25zb2xlLmVycm9yKFxuICAgICAgXCJNb2R1bGUgdmFsaWRhdGlvbiBmYWlsZWQ6XFxuXCIsXG4gICAgICBKU09OLnN0cmluZ2lmeShyZXBvcnQsIG51bGwsIDIpXG4gICAgKTtcbiAgICBwcm9jZXNzLmV4aXQoMik7XG4gIH1cbiAgY29uc29sZS5sb2coXCJNb2R1bGUgdmFsaWRhdGlvbiBwYXNzZWRcIik7XG4gIHByb2Nlc3MuZXhpdCgwKTtcbn1cbiIsIi8vIEFnZ3JlZ2F0b3I6IGltcG9ydCBtb2R1bGUgaW5kZXggZmlsZXMgYW5kIG1lcmdlIGV4cG9ydGVkIGFycmF5cyB3aXRoIHByb3ZlbmFuY2UgKyBkdXBsaWNhdGUgZGV0ZWN0aW9uXG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IHsgcGF0aFRvRmlsZVVSTCB9IGZyb20gXCJ1cmxcIjtcbmltcG9ydCB7IGZpbmRNb2R1bGVEaXJzIH0gZnJvbSBcIi4vdmFsaWRhdGlvblwiO1xuXG5leHBvcnQgdHlwZSBQcm92ZW5hbmNlID0geyBtb2R1bGVOYW1lOiBzdHJpbmc7IG1vZHVsZVBhdGg6IHN0cmluZyB9O1xuZXhwb3J0IHR5cGUgQWdncmVnYXRpb25Db25mbGljdCA9IHtcbiAga2V5OiBzdHJpbmc7XG4gIGV4aXN0aW5nOiBQcm92ZW5hbmNlO1xuICBpbmNvbWluZzogUHJvdmVuYW5jZTtcbn07XG5cbmV4cG9ydCB0eXBlIEFnZ3JlZ2F0aW9uUmVzdWx0PFQgPSBhbnk+ID0ge1xuICBwcm9tcHRzOiBBcnJheTxUICYgeyBwcm92ZW5hbmNlOiBQcm92ZW5hbmNlIH0+O1xuICByZXNvdXJjZXM6IEFycmF5PFQgJiB7IHByb3ZlbmFuY2U6IFByb3ZlbmFuY2UgfT47XG4gIHRlbXBsYXRlczogQXJyYXk8VCAmIHsgcHJvdmVuYW5jZTogUHJvdmVuYW5jZSB9PjtcbiAgdG9vbHM6IEFycmF5PFQgJiB7IHByb3ZlbmFuY2U6IFByb3ZlbmFuY2UgfT47XG4gIGNvbmZsaWN0czogQWdncmVnYXRpb25Db25mbGljdFtdO1xufTtcblxuY29uc3QgU1VCRk9MREVSUyA9IFtcInByb21wdHNcIiwgXCJyZXNvdXJjZXNcIiwgXCJ0ZW1wbGF0ZXNcIiwgXCJ0b29sc1wiXTtcbmNvbnN0IElOREVYX0NBTkRJREFURVMgPSBbXG4gIFwiaW5kZXgudHNcIixcbiAgXCJpbmRleC50c3hcIixcbiAgXCJpbmRleC5qc1wiLFxuICBcImluZGV4LmNqc1wiLFxuICBcImluZGV4Lm1qc1wiLFxuXTtcblxuZnVuY3Rpb24gZmluZEluZGV4RmlsZShmb2xkZXI6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGZvciAoY29uc3QgYyBvZiBJTkRFWF9DQU5ESURBVEVTKSB7XG4gICAgY29uc3QgZiA9IHBhdGguam9pbihmb2xkZXIsIGMpO1xuICAgIGlmIChmcy5leGlzdHNTeW5jKGYpKSByZXR1cm4gZjtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBtYWtlS2V5Rm9ySXRlbShpdGVtOiBhbnkpOiBzdHJpbmcge1xuICBpZiAoIWl0ZW0pIHJldHVybiBKU09OLnN0cmluZ2lmeShpdGVtKTtcbiAgaWYgKHR5cGVvZiBpdGVtID09PSBcInN0cmluZ1wiKSByZXR1cm4gYHN0cjoke2l0ZW19YDtcbiAgaWYgKHR5cGVvZiBpdGVtID09PSBcIm51bWJlclwiKSByZXR1cm4gYG51bToke2l0ZW19YDtcbiAgaWYgKGl0ZW0uaWQpIHJldHVybiBgaWQ6JHtpdGVtLmlkfWA7XG4gIGlmIChpdGVtLm5hbWUpIHJldHVybiBgbmFtZToke2l0ZW0ubmFtZX1gO1xuICAvLyBmYWxsYmFjayB0byBzdGFibGUgc3RyaW5nXG4gIHRyeSB7XG4gICAgcmV0dXJuIGBvYmo6JHtKU09OLnN0cmluZ2lmeShpdGVtKX1gO1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGBvYmo6JHtTdHJpbmcoaXRlbSl9YDtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBsb2FkQXJyYXlGcm9tSW5kZXgoXG4gIGZpbGVQYXRoOiBzdHJpbmdcbik6IFByb21pc2U8YW55W10gfCB1bmRlZmluZWQ+IHtcbiAgLy8gUHJlZmVyIGEgZmFzdCwgc3RhdGljIHBhcnNlIG9mIHRoZSBmaXJzdCBhcnJheSBsaXRlcmFsIGZvdW5kIGluIHRoZSBmaWxlLlxuICB0cnkge1xuICAgIGNvbnN0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoZmlsZVBhdGgsIFwidXRmOFwiKTtcbiAgICBjb25zdCBzdGFydCA9IGNvbnRlbnQuaW5kZXhPZihcIltcIik7XG4gICAgaWYgKHN0YXJ0ICE9PSAtMSkge1xuICAgICAgbGV0IGRlcHRoID0gMDtcbiAgICAgIGxldCBlbmQgPSAtMTtcbiAgICAgIGZvciAobGV0IGkgPSBzdGFydDsgaSA8IGNvbnRlbnQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgY2ggPSBjb250ZW50W2ldO1xuICAgICAgICBpZiAoY2ggPT09IFwiW1wiKSBkZXB0aCsrO1xuICAgICAgICBlbHNlIGlmIChjaCA9PT0gXCJdXCIpIHtcbiAgICAgICAgICBkZXB0aC0tO1xuICAgICAgICAgIGlmIChkZXB0aCA9PT0gMCkge1xuICAgICAgICAgICAgZW5kID0gaTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGVuZCAhPT0gLTEpIHtcbiAgICAgICAgY29uc3QgYXJyVGV4dCA9IGNvbnRlbnQuc2xpY2Uoc3RhcnQsIGVuZCArIDEpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHJldHVybiBKU09OLnBhcnNlKGFyclRleHQpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgLy8gTm9ybWFsaXplIFRTIG9iamVjdCBsaXRlcmFscyB0byBKU09OOlxuICAgICAgICAgIC8vIC0gY29udmVydCBzaW5nbGUgcXVvdGVzIHRvIGRvdWJsZSBxdW90ZXNcbiAgICAgICAgICAvLyAtIHF1b3RlIHVucXVvdGVkIG9iamVjdCBrZXlzXG4gICAgICAgICAgLy8gLSBzdHJpcCB0cmFpbGluZyBjb21tYXNcbiAgICAgICAgICBjb25zdCBub3JtYWxpemVkID0gYXJyVGV4dFxuICAgICAgICAgICAgLy8gdW5pZnkgcXVvdGVzIGluIHN0cmluZyBsaXRlcmFsc1xuICAgICAgICAgICAgLnJlcGxhY2UoLycoPzpcXFxcJ3xbXiddKSonL2csIChtKSA9PiBtLnJlcGxhY2UoLycvZywgJ1wiJykpXG4gICAgICAgICAgICAvLyBxdW90ZSB1bnF1b3RlZCBrZXlzIGFmdGVyIHsgb3IgLFxuICAgICAgICAgICAgLnJlcGxhY2UoLyhbXFx7LF1cXHMqKShbQS1aYS16XyRdW1xcdyRdKikoXFxzKjopL2csICckMVwiJDJcIiQzJylcbiAgICAgICAgICAgIC8vIHJlbW92ZSB0cmFpbGluZyBjb21tYXMgYmVmb3JlIF0gb3IgfVxuICAgICAgICAgICAgLnJlcGxhY2UoLywoXFxzKltcXH1cXF1dKS9nLCAnJDEnKTtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIEpTT04ucGFyc2Uobm9ybWFsaXplZCk7XG4gICAgICAgICAgfSBjYXRjaCAoZTIpIHtcbiAgICAgICAgICAgIC8vIGZhbGx0aHJvdWdoIHRvIGltcG9ydCBhdHRlbXB0IGJlbG93XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgLy8gaWdub3JlIHN0YXRpYyBwYXJzZSBlcnJvcnMgYW5kIGZhbGwgYmFjayB0byBpbXBvcnRcbiAgfVxuXG4gIHRyeSB7XG4gICAgY29uc3QgZmlsZVVybCA9IHBhdGhUb0ZpbGVVUkwoZmlsZVBhdGgpLmhyZWY7XG4gICAgY29uc3QgbW9kID0gYXdhaXQgaW1wb3J0KGZpbGVVcmwpO1xuICAgIC8vIEZpbmQgZmlyc3QgZXhwb3J0IHRoYXQgaXMgYW4gYXJyYXlcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhtb2QpKSB7XG4gICAgICBjb25zdCB2YWwgPSAobW9kIGFzIGFueSlba2V5XTtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbCkpIHJldHVybiB2YWw7XG4gICAgfVxuICAgIC8vIGRlZmF1bHQgZXhwb3J0IGNoZWNrXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoKG1vZCBhcyBhbnkpLmRlZmF1bHQpKSByZXR1cm4gKG1vZCBhcyBhbnkpLmRlZmF1bHQ7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgLy8gZmFsbGJhY2s6IGlmIGltcG9ydCBmYWlscywgdHJ5IHRvIHN0YXRpYy1wYXJzZSBhZ2FpbiAoYWxyZWFkeSBhdHRlbXB0ZWQpIGFuZCBmaW5hbGx5IHJldHVybiB1bmRlZmluZWRcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhZ2dyZWdhdGVNb2R1bGVzKFxuICByZXBvUm9vdDogc3RyaW5nXG4pOiBQcm9taXNlPEFnZ3JlZ2F0aW9uUmVzdWx0PiB7XG4gIGNvbnN0IGRpcnMgPSBmaW5kTW9kdWxlRGlycyhyZXBvUm9vdCk7XG4gIGNvbnN0IG1hc3RlciA9IHtcbiAgICBwcm9tcHRzOiBbXSBhcyBhbnlbXSxcbiAgICByZXNvdXJjZXM6IFtdIGFzIGFueVtdLFxuICAgIHRlbXBsYXRlczogW10gYXMgYW55W10sXG4gICAgdG9vbHM6IFtdIGFzIGFueVtdLFxuICAgIGNvbmZsaWN0czogW10gYXMgQWdncmVnYXRpb25Db25mbGljdFtdLFxuICB9O1xuXG4gIC8vIG1hcHMgdG8gZGV0ZWN0IGR1cGxpY2F0ZXMgcGVyIHR5cGVcbiAgY29uc3QgbWFwczogUmVjb3JkPHN0cmluZywgTWFwPHN0cmluZywgUHJvdmVuYW5jZT4+ID0ge1xuICAgIHByb21wdHM6IG5ldyBNYXAoKSxcbiAgICByZXNvdXJjZXM6IG5ldyBNYXAoKSxcbiAgICB0ZW1wbGF0ZXM6IG5ldyBNYXAoKSxcbiAgICB0b29sczogbmV3IE1hcCgpLFxuICB9O1xuXG4gIGZvciAoY29uc3QgbW9kdWxlRGlyIG9mIGRpcnMpIHtcbiAgICBjb25zdCBtb2R1bGVOYW1lID0gcGF0aC5iYXNlbmFtZShtb2R1bGVEaXIpO1xuICAgIGZvciAoY29uc3Qgc3ViIG9mIFNVQkZPTERFUlMpIHtcbiAgICAgIGNvbnN0IGZvbGRlciA9IHBhdGguam9pbihtb2R1bGVEaXIsIHN1Yik7XG4gICAgICBjb25zdCBpbmRleEZpbGUgPSBmaW5kSW5kZXhGaWxlKGZvbGRlcik7XG4gICAgICBpZiAoIWluZGV4RmlsZSkgY29udGludWU7XG4gICAgICBsZXQgYXJyOiBhbnlbXSB8IHVuZGVmaW5lZDtcbiAgICAgIHRyeSB7XG4gICAgICAgIGFyciA9IGF3YWl0IGxvYWRBcnJheUZyb21JbmRleChpbmRleEZpbGUpO1xuICAgICAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAgICAgLy8gc2tpcCBtb2R1bGUgb24gaW1wb3J0IGVycm9yIGJ1dCByZWNvcmQgYXMgY29uZmxpY3QtbGlrZSBpc3N1ZVxuICAgICAgICBtYXN0ZXIuY29uZmxpY3RzLnB1c2goe1xuICAgICAgICAgIGtleTogYGltcG9ydC1lcnJvcjoke21vZHVsZU5hbWV9OiR7c3VifWAsXG4gICAgICAgICAgZXhpc3Rpbmc6IHsgbW9kdWxlTmFtZSwgbW9kdWxlUGF0aDogbW9kdWxlRGlyIH0sXG4gICAgICAgICAgaW5jb21pbmc6IHsgbW9kdWxlTmFtZSwgbW9kdWxlUGF0aDogbW9kdWxlRGlyIH0sXG4gICAgICAgIH0pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmICghYXJyIHx8ICFBcnJheS5pc0FycmF5KGFycikpIGNvbnRpbnVlO1xuXG4gICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgYXJyKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IG1ha2VLZXlGb3JJdGVtKGl0ZW0pO1xuICAgICAgICBjb25zdCBwcm92ZW5hbmNlID0geyBtb2R1bGVOYW1lLCBtb2R1bGVQYXRoOiBtb2R1bGVEaXIgfTtcbiAgICAgICAgY29uc3QgbWFwID0gbWFwc1tzdWJdO1xuICAgICAgICBpZiAobWFwLmhhcyhrZXkpKSB7XG4gICAgICAgICAgLy8gcmVjb3JkIGNvbmZsaWN0IGRldGVybWluaXN0aWNhbGx5IChleGlzdGluZyB2cyBpbmNvbWluZylcbiAgICAgICAgICBjb25zdCBleGlzdGluZyA9IG1hcC5nZXQoa2V5KSE7XG4gICAgICAgICAgbWFzdGVyLmNvbmZsaWN0cy5wdXNoKHsga2V5LCBleGlzdGluZywgaW5jb21pbmc6IHByb3ZlbmFuY2UgfSk7XG4gICAgICAgICAgLy8gc2tpcCBhZGRpbmcgZHVwbGljYXRlXG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgbWFwLnNldChrZXksIHByb3ZlbmFuY2UpO1xuICAgICAgICAobWFzdGVyIGFzIGFueSlbc3ViXS5wdXNoKHsgLi4uaXRlbSwgcHJvdmVuYW5jZSB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbWFzdGVyO1xufVxuXG4vLyBGb3IgY29tcGF0aWJpbGl0eSB3aXRoIENvbW1vbkpTIGNhbGwgc2l0ZXMgKG5vdCBleHBvcnRlZCBieSBFU00pLCBwcm92aWRlIGEgc3luYyB3cmFwcGVyXG5leHBvcnQgZnVuY3Rpb24gYWdncmVnYXRlTW9kdWxlc1N5bmMocmVwb1Jvb3Q6IHN0cmluZykge1xuICAvLyBzeW5jaHJvbm91cyB3cmFwcGVyIHRoYXQgcnVucyB0aGUgYXN5bmMgZnVuY3Rpb24gYW5kIGJsb2NrcyDigJQgc3VpdGFibGUgZm9yIHNtYWxsIG1vZHVsZSBzZXRzXG4gIGNvbnN0IHAgPSBhZ2dyZWdhdGVNb2R1bGVzKHJlcG9Sb290KTtcbiAgbGV0IHJlc3VsdDogYW55O1xuICBsZXQgZG9uZSA9IGZhbHNlO1xuICBwLnRoZW4oKHIpID0+IHtcbiAgICByZXN1bHQgPSByO1xuICAgIGRvbmUgPSB0cnVlO1xuICB9KS5jYXRjaCgoZSkgPT4ge1xuICAgIHRocm93IGU7XG4gIH0pO1xuICAvLyBzcGluLXdhaXQgKGFjY2VwdGFibGUgaW4gc21hbGwgZGV2IHNjcmlwdHMpXG4gIGNvbnN0IHVudGlsID0gRGF0ZS5ub3coKSArIDUwMDA7XG4gIHdoaWxlICghZG9uZSAmJiBEYXRlLm5vdygpIDwgdW50aWwpIHt9XG4gIGlmICghZG9uZSlcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBcImFnZ3JlZ2F0ZU1vZHVsZXNTeW5jOiB0aW1lb3V0IHdhaXRpbmcgZm9yIGFzeW5jIGFnZ3JlZ2F0aW9uXCJcbiAgICApO1xuICByZXR1cm4gcmVzdWx0IGFzIEFnZ3JlZ2F0aW9uUmVzdWx0O1xufVxuIiwiaW1wb3J0IHsgYWdncmVnYXRlTW9kdWxlcyB9IGZyb20gXCIuL2FnZ3JlZ2F0ZU1vZHVsZXNcIjtcbmltcG9ydCB7IGxvYWRQcm9tcHRzLCBwcm9tcHRMaXN0IH0gZnJvbSBcIi4vcHJvbXB0c1wiO1xuaW1wb3J0IHsgdG9vbExpc3QgfSBmcm9tIFwiLi90b29sc1wiO1xuaW1wb3J0IHsgcmVzb3VyY2VzIH0gZnJvbSBcIi4vcmVzb3VyY2VzXCI7XG5pbXBvcnQgeyBidWlsZFJlc291cmNlVGVtcGxhdGVzIH0gZnJvbSBcIi4vdGVtcGxhdGVzXCI7XG5cbmV4cG9ydCB0eXBlIEZhc3RNQ1BMaWtlID0ge1xuICBhZGRQcm9tcHQ6IChwOiBhbnkpID0+IHZvaWQ7XG4gIGFkZFRvb2w6ICh0OiBhbnkpID0+IHZvaWQ7XG4gIGFkZFJlc291cmNlOiAocjogYW55KSA9PiB2b2lkO1xuICBhZGRSZXNvdXJjZVRlbXBsYXRlOiAodDogYW55KSA9PiB2b2lkO1xufTtcblxuLyoqXG4gKiBBZ2dyZWdhdGUgbW9kdWxlIGFzc2V0cyBhbmQgcmVnaXN0ZXIgdGhlbSBvbiB0aGUgcHJvdmlkZWQgRmFzdE1DUC1saWtlIHNlcnZlci5cbiAqIEZhbGxzIGJhY2sgdG8gYnVpbHQtaW4gbGlzdHMgaWYgYWdncmVnYXRpb24geWllbGRzIG5vbmUuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBFbnJpY2hDb3JlV2l0aEFnZ3JlZ2F0aW9uKFxuICBzZXJ2ZXI6IEZhc3RNQ1BMaWtlLFxuICByZXBvUm9vdCA9IHByb2Nlc3MuY3dkKClcbikge1xuICAvLyBGaXJzdCByZWdpc3RlciBidWlsdC1pbiBwcm9tcHRzL3Rvb2xzL3Jlc291cmNlcy90ZW1wbGF0ZXMgKGxlZ2FjeSBiZWhhdmlvcilcbiAgdHJ5IHtcbiAgICBsb2FkUHJvbXB0cygpO1xuICAgIGZvciAoY29uc3QgcHJvbXB0IG9mIHByb21wdExpc3QpIHNlcnZlci5hZGRQcm9tcHQocHJvbXB0IGFzIGFueSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBpZ25vcmUgaWYgbG9hZFByb21wdHMgbm90IGF2YWlsYWJsZSBvciBmYWlsc1xuICB9XG5cbiAgdHJ5IHtcbiAgICBmb3IgKGNvbnN0IHRvb2wgb2YgdG9vbExpc3QpIHNlcnZlci5hZGRUb29sKHRvb2wgYXMgYW55KTtcbiAgfSBjYXRjaCAoZSkge31cblxuICB0cnkge1xuICAgIGZvciAoY29uc3QgcmVzb3VyY2Ugb2YgcmVzb3VyY2VzKSBzZXJ2ZXIuYWRkUmVzb3VyY2UocmVzb3VyY2UgYXMgYW55KTtcbiAgfSBjYXRjaCAoZSkge31cblxuICB0cnkge1xuICAgIGNvbnN0IHRlbXBsYXRlcyA9IGJ1aWxkUmVzb3VyY2VUZW1wbGF0ZXMoKTtcbiAgICBmb3IgKGNvbnN0IHRlbXBsYXRlIG9mIHRlbXBsYXRlcylcbiAgICAgIHNlcnZlci5hZGRSZXNvdXJjZVRlbXBsYXRlKHRlbXBsYXRlIGFzIGFueSk7XG4gIH0gY2F0Y2ggKGUpIHt9XG5cbiAgLy8gTm93IGFnZ3JlZ2F0ZSBtb2R1bGVzIGFuZCByZWdpc3RlciBhZ2dyZWdhdGVkIGFzc2V0cyB3aXRoIHByb3ZlbmFuY2VcbiAgY29uc3QgYWdnID0gYXdhaXQgYWdncmVnYXRlTW9kdWxlcyhyZXBvUm9vdCk7XG5cbiAgZm9yIChjb25zdCBwIG9mIGFnZy5wcm9tcHRzKSB7XG4gICAgc2VydmVyLmFkZFByb21wdChwKTtcbiAgfVxuICBmb3IgKGNvbnN0IHQgb2YgYWdnLnRvb2xzKSB7XG4gICAgc2VydmVyLmFkZFRvb2wodCk7XG4gIH1cbiAgZm9yIChjb25zdCByIG9mIGFnZy5yZXNvdXJjZXMpIHtcbiAgICBzZXJ2ZXIuYWRkUmVzb3VyY2Uocik7XG4gIH1cbiAgZm9yIChjb25zdCB0cGwgb2YgYWdnLnRlbXBsYXRlcykge1xuICAgIHNlcnZlci5hZGRSZXNvdXJjZVRlbXBsYXRlKHRwbCk7XG4gIH1cblxuICAvLyByZXR1cm4gYWdncmVnYXRpb24gc3VtbWFyeSBmb3IgY2FsbGluZyB0ZXN0cy9DSVxuICByZXR1cm4ge1xuICAgIG1vZHVsZXNDaGVja2VkOiBhZ2cucHJvbXB0cy5jb25jYXQoYWdnLnRvb2xzKS5sZW5ndGgsXG4gICAgY29uZmxpY3RzOiBhZ2cuY29uZmxpY3RzLFxuICB9O1xufVxuIiwiaW1wb3J0IHsgRmFzdE1DUCB9IGZyb20gXCJmYXN0bWNwXCI7XG5pbXBvcnQgeyBsb2FkUHJvbXB0cywgcHJvbXB0TGlzdCB9IGZyb20gXCIuL3Byb21wdHNcIjtcbmltcG9ydCB7IHRvb2xMaXN0IH0gZnJvbSBcIi4vdG9vbHNcIjtcbmltcG9ydCB7IHJlc291cmNlcyB9IGZyb20gXCIuL3Jlc291cmNlc1wiO1xuaW1wb3J0IHsgYnVpbGRSZXNvdXJjZVRlbXBsYXRlcyB9IGZyb20gXCIuL3RlbXBsYXRlc1wiO1xuXG5leHBvcnQgKiBmcm9tIFwiLi9tY3AtbW9kdWxlXCI7XG5leHBvcnQgeyBkZWZhdWx0IH0gZnJvbSBcIi4vbWNwLW1vZHVsZVwiO1xuXG5leHBvcnQgeyB2YWxpZGF0ZU1vZHVsZXMgfSBmcm9tIFwiLi92YWxpZGF0aW9uXCI7XG5leHBvcnQgeyBhZ2dyZWdhdGVNb2R1bGVzLCBhZ2dyZWdhdGVNb2R1bGVzU3luYyB9IGZyb20gXCIuL2FnZ3JlZ2F0ZU1vZHVsZXNcIjtcbmV4cG9ydCB7IEVucmljaENvcmVXaXRoQWdncmVnYXRpb24gfSBmcm9tIFwiLi9mYXN0bWNwLXdpcmluZ1wiO1xuXG5leHBvcnQgZnVuY3Rpb24gRW5yaWNoQ29yZShzZXJ2ZXI6IEZhc3RNQ1ApIHtcbiAgbG9hZFByb21wdHMoKTtcbiAgZm9yIChjb25zdCBwcm9tcHQgb2YgcHJvbXB0TGlzdCkge1xuICAgIHNlcnZlci5hZGRQcm9tcHQocHJvbXB0IGFzIGFueSk7XG4gIH1cbiAgZm9yIChjb25zdCB0b29sIG9mIHRvb2xMaXN0KSB7XG4gICAgc2VydmVyLmFkZFRvb2wodG9vbCBhcyBhbnkpO1xuICB9XG4gIGZvciAoY29uc3QgcmVzb3VyY2Ugb2YgcmVzb3VyY2VzKSB7XG4gICAgc2VydmVyLmFkZFJlc291cmNlKHJlc291cmNlIGFzIGFueSk7XG4gIH1cbiAgY29uc3QgdGVtcGxhdGVzID0gYnVpbGRSZXNvdXJjZVRlbXBsYXRlcygpO1xuICBmb3IgKGNvbnN0IHRlbXBsYXRlIG9mIHRlbXBsYXRlcykge1xuICAgIHNlcnZlci5hZGRSZXNvdXJjZVRlbXBsYXRlKHRlbXBsYXRlIGFzIGFueSk7XG4gIH1cbn1cbiIsImltcG9ydCBmcyBmcm9tIFwibm9kZTpmc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHsgZ2V0V29ya3NwYWNlUm9vdCB9IGZyb20gXCIuLi9tY3Avd29ya3NwYWNlXCI7XG5cbmV4cG9ydCBjb25zdCBSRVFVSVJFRF9NT0RVTEVfRk9MREVSUyA9IFtcbiAgXCJwcm9tcHRzXCIsXG4gIFwicmVzb3VyY2VzXCIsXG4gIFwidGVtcGxhdGVzXCIsXG4gIFwidG9vbHNcIixcbl0gYXMgY29uc3Q7XG5cbmV4cG9ydCB0eXBlIE1vZHVsZUZvbGRlciA9ICh0eXBlb2YgUkVRVUlSRURfTU9EVUxFX0ZPTERFUlMpW251bWJlcl07XG5cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlTW9kdWxlc1Jvb3Qod29ya3NwYWNlUm9vdCA9IGdldFdvcmtzcGFjZVJvb3QoKSk6IHN0cmluZyB7XG4gIHJldHVybiBwYXRoLnJlc29sdmUod29ya3NwYWNlUm9vdCwgXCJzcmMvbW9kdWxlc1wiKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGxpc3RNb2R1bGVEaXJlY3Rvcmllcyh3b3Jrc3BhY2VSb290ID0gZ2V0V29ya3NwYWNlUm9vdCgpKTogc3RyaW5nW10ge1xuICBjb25zdCByb290ID0gcmVzb2x2ZU1vZHVsZXNSb290KHdvcmtzcGFjZVJvb3QpO1xuICBpZiAoIWZzLmV4aXN0c1N5bmMocm9vdCkpIHJldHVybiBbXTtcblxuICByZXR1cm4gZnNcbiAgICAucmVhZGRpclN5bmMocm9vdClcbiAgICAubWFwKChlbnRyeSkgPT4gKHtcbiAgICAgIGVudHJ5LFxuICAgICAgYWJzb2x1dGU6IHBhdGguam9pbihyb290LCBlbnRyeSksXG4gICAgfSkpXG4gICAgLmZpbHRlcigoeyBhYnNvbHV0ZSB9KSA9PiBmcy5zdGF0U3luYyhhYnNvbHV0ZSkuaXNEaXJlY3RvcnkoKSlcbiAgICAubWFwKCh7IGVudHJ5IH0pID0+IGVudHJ5KVxuICAgIC5zb3J0KCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlTW9kdWxlUGF0aChcbiAgbW9kdWxlTmFtZTogc3RyaW5nLFxuICB3b3Jrc3BhY2VSb290ID0gZ2V0V29ya3NwYWNlUm9vdCgpXG4pOiBzdHJpbmcge1xuICByZXR1cm4gcGF0aC5qb2luKHJlc29sdmVNb2R1bGVzUm9vdCh3b3Jrc3BhY2VSb290KSwgbW9kdWxlTmFtZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlTW9kdWxlRm9sZGVyUGF0aChcbiAgbW9kdWxlTmFtZTogc3RyaW5nLFxuICBmb2xkZXI6IE1vZHVsZUZvbGRlcixcbiAgd29ya3NwYWNlUm9vdCA9IGdldFdvcmtzcGFjZVJvb3QoKVxuKTogc3RyaW5nIHtcbiAgcmV0dXJuIHBhdGguam9pbihyZXNvbHZlTW9kdWxlUGF0aChtb2R1bGVOYW1lLCB3b3Jrc3BhY2VSb290KSwgZm9sZGVyKTtcbn1cbiIsIi8qIGlzdGFuYnVsIGlnbm9yZSBmaWxlICovXG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IHsgTWNwTW9kdWxlIH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gVXRpbGl0eSBjbGFzcyBmb3IgQ0xJIG9wZXJhdGlvbnNcbiAqIEBzdW1tYXJ5IEEgc3RhdGljIHV0aWxpdHkgY2xhc3MgdGhhdCBwcm92aWRlcyBtZXRob2RzIGZvciBsb2FkaW5nIG1vZHVsZXMsIHJldHJpZXZpbmcgcGFja2FnZSBpbmZvcm1hdGlvbiwgYW5kIGluaXRpYWxpemluZyBDTEkgY29tbWFuZHNcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gSW5pdGlhbGl6ZSBhIENvbW1hbmQgb2JqZWN0IHdpdGggcGFja2FnZSBpbmZvcm1hdGlvblxuICogY29uc3QgY29tbWFuZCA9IG5ldyBDb21tYW5kKCk7XG4gKiBDTElVdGlscy5pbml0aWFsaXplKGNvbW1hbmQsICcuL3BhdGgvdG8vcGFja2FnZScpO1xuICpcbiAqIC8vIExvYWQgYSBDTEkgbW9kdWxlIGZyb20gYSBmaWxlXG4gKiBjb25zdCBtb2R1bGUgPSBhd2FpdCBDTElVdGlscy5sb2FkRnJvbUZpbGUoJy4vcGF0aC90by9jbGktbW9kdWxlLmpzJyk7XG4gKlxuICogQGNsYXNzIE1jcFV0aWxzXG4gKi9cbmV4cG9ydCBjbGFzcyBNY3BVdGlscyB7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRHluYW1pY2FsbHkgaW1wb3J0cyBhIG1vZHVsZSBmaWxlXG4gICAqIEBzdW1tYXJ5IExvYWRzIGEgSmF2YVNjcmlwdCBmaWxlIGFuZCByZXR1cm5zIGl0IGFzIGEgQ2xpTW9kdWxlLCBoYW5kbGluZyBib3RoIEVTTSBhbmQgQ29tbW9uSlMgZm9ybWF0c1xuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcGF0aCBUaGUgZmlsZSBwYXRoIHRvIHRoZSBtb2R1bGUgdG8gbG9hZFxuICAgKiBAcmV0dXJuIHtQcm9taXNlPE1jcE1vZHVsZT59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBsb2FkZWQgQ2xpTW9kdWxlXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgbG9hZEZyb21GaWxlKHBhdGg6IHN0cmluZyk6IFByb21pc2U8TWNwTW9kdWxlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBNY3BVdGlscy5ub3JtYWxpemVJbXBvcnQoaW1wb3J0KHBhdGgpKTtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBGYWlsZWQgdG8gbG9hZCBmcm9tICR7cGF0aH06ICR7ZSBpbnN0YW5jZW9mIEVycm9yID8gZS5tZXNzYWdlIDogZX1gXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTm9ybWFsaXplcyBtb2R1bGUgaW1wb3J0cyB0byBoYW5kbGUgYm90aCBFU00gYW5kIENvbW1vbkpTIGZvcm1hdHNcbiAgICogQHN1bW1hcnkgUHJvcGVybHkgaW1wb3J0cyBKYXZhU2NyaXB0IGZpbGVzIHJlZ2FyZGxlc3Mgb2YgdGhlaXIgbW9kdWxlIGZvcm1hdCBieSBoYW5kbGluZyB0aGUgRVNNIHdyYXBwZXIgZm9yIENvbW1vbkpTIG1vZHVsZXNcbiAgICpcbiAgICogQHRlbXBsYXRlIFQgVGhlIHR5cGUgb2YgdGhlIGltcG9ydGVkIG1vZHVsZVxuICAgKiBAcGFyYW0ge1Byb21pc2U8VD59IGltcG9ydFByb21pc2UgVGhlIHByb21pc2UgcmV0dXJuZWQgYnkgdGhlIGR5bmFtaWMgaW1wb3J0XG4gICAqIEByZXR1cm4ge1Byb21pc2U8VD59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBub3JtYWxpemVkIG1vZHVsZVxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgc3RhdGljIGFzeW5jIG5vcm1hbGl6ZUltcG9ydDxUPihpbXBvcnRQcm9taXNlOiBQcm9taXNlPFQ+KTogUHJvbWlzZTxUPiB7XG4gICAgLy8gQ29tbW9uSlMncyBgbW9kdWxlLmV4cG9ydHNgIGlzIHdyYXBwZWQgYXMgYGRlZmF1bHRgIGluIEVTTW9kdWxlLlxuICAgIHJldHVybiBpbXBvcnRQcm9taXNlLnRoZW4oXG4gICAgICAobTogdW5rbm93bikgPT4gKChtIGFzIHsgZGVmYXVsdDogVCB9KS5kZWZhdWx0IHx8IG0pIGFzIFRcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgYW5kIHBhcnNlcyB0aGUgcGFja2FnZS5qc29uIGZpbGVcbiAgICogQHN1bW1hcnkgUmVhZHMgdGhlIHBhY2thZ2UuanNvbiBmaWxlIGZyb20gdGhlIHNwZWNpZmllZCBwYXRoIGFuZCBwYXJzZXMgaXQgaW50byBhIEphdmFTY3JpcHQgb2JqZWN0XG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBiYXNlUGF0aCBUaGUgYmFzZSBwYXRoIHdoZXJlIHRoZSBwYWNrYWdlLmpzb24gZmlsZSBpcyBsb2NhdGVkXG4gICAqIEByZXR1cm4ge1JlY29yZDxzdHJpbmcsIHVua25vd24+fSBUaGUgcGFyc2VkIHBhY2thZ2UuanNvbiBjb250ZW50IGFzIGFuIG9iamVjdFxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0UGFja2FnZShiYXNlUGF0aDogc3RyaW5nKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gSlNPTi5wYXJzZShcbiAgICAgICAgZnMucmVhZEZpbGVTeW5jKHBhdGguam9pbihiYXNlUGF0aCwgXCJwYWNrYWdlLmpzb25cIiksIFwidXRmOFwiKVxuICAgICAgKTtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byByZWFkIHZlcnNpb24gZnJvbSAke2Jhc2VQYXRofTogJHtlfWApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0dXJucyB0aGUgdmVyc2lvbiBmcm9tIHBhY2thZ2UuanNvblxuICAgKiBAc3VtbWFyeSBSZXRyaWV2ZXMgdGhlIHZlcnNpb24gZmllbGQgZnJvbSB0aGUgcGFja2FnZS5qc29uIGZpbGUgYXQgdGhlIHNwZWNpZmllZCBwYXRoXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBiYXNlUGF0aCBUaGUgYmFzZSBwYXRoIHdoZXJlIHRoZSBwYWNrYWdlLmpzb24gZmlsZSBpcyBsb2NhdGVkXG4gICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIHBhY2thZ2UgdmVyc2lvbiBzdHJpbmdcbiAgICovXG4gIHN0YXRpYyBwYWNrYWdlVmVyc2lvbihiYXNlUGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gTWNwVXRpbHMuZ2V0UGFja2FnZShiYXNlUGF0aClbXCJ2ZXJzaW9uXCJdIGFzIHN0cmluZztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0dXJucyB0aGUgbmFtZSBmcm9tIHBhY2thZ2UuanNvblxuICAgKiBAc3VtbWFyeSBSZXRyaWV2ZXMgdGhlIG5hbWUgZmllbGQgZnJvbSB0aGUgcGFja2FnZS5qc29uIGZpbGUgYXQgdGhlIHNwZWNpZmllZCBwYXRoIGFuZCBleHRyYWN0cyB0aGUgcGFja2FnZSBuYW1lIHdpdGhvdXQgdGhlIHNjb3BlXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBiYXNlUGF0aCBUaGUgYmFzZSBwYXRoIHdoZXJlIHRoZSBwYWNrYWdlLmpzb24gZmlsZSBpcyBsb2NhdGVkXG4gICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIHBhY2thZ2UgbmFtZSB3aXRob3V0IHRoZSBzY29wZSAoZS5nLiwgXCJjbGlcIiBmcm9tIFwiQGRlY2FmLXRzL2NsaVwiKVxuICAgKi9cbiAgc3RhdGljIHBhY2thZ2VOYW1lKGJhc2VQYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IG5hbWUgPSAoTWNwVXRpbHMuZ2V0UGFja2FnZShiYXNlUGF0aClbXCJuYW1lXCJdIGFzIHN0cmluZykuc3BsaXQoXCIvXCIpO1xuICAgIHJldHVybiBuYW1lW25hbWUubGVuZ3RoIC0gMV07XG4gIH1cbn1cblxuZXhwb3J0ICogZnJvbSBcIi4vdXRpbHMvbW9kdWxlUGF0aHNcIjtcbiIsImltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBNQ1BfRklMRV9OQU1FIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBNY3BVdGlscyB9IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQgeyBGYXN0TUNQIH0gZnJvbSBcImZhc3RtY3BcIjtcbmltcG9ydCB7IExvZ2dlZENsYXNzIH0gZnJvbSBcIkBkZWNhZi10cy9sb2dnaW5nXCI7XG5pbXBvcnQgeyBWRVJTSU9OIH0gZnJvbSBcIi4vbWV0YWRhdGFcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gVXRpbGl0eSBjbGFzcyB0byBoYW5kbGUgQ0xJIGZ1bmN0aW9uYWxpdHkgZnJvbSBhbGwgRGVjYWYgbW9kdWxlc1xuICogQHN1bW1hcnkgVGhpcyBjbGFzcyBwcm92aWRlcyBhIHdyYXBwZXIgYXJvdW5kIENvbW1hbmRlci5qcyB0byBoYW5kbGUgQ0xJIGNvbW1hbmRzIGZyb20gZGlmZmVyZW50IERlY2FmIG1vZHVsZXMuXG4gKiBJdCBjcmF3bHMgdGhlIGZpbGVzeXN0ZW0gdG8gZmluZCBDTEkgbW9kdWxlcywgbG9hZHMgdGhlbSwgYW5kIHJlZ2lzdGVycyB0aGVpciBjb21tYW5kcy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW2Jhc2VQYXRoXSBUaGUgYmFzZSBwYXRoIHRvIGxvb2sgZm9yIG1vZHVsZXMgaW4uIERlZmF1bHRzIHRvIGAuL2BcbiAqIEBwYXJhbSB7bnVtYmVyfSBbY3Jhd2xMZXZlbHNdIE51bWJlciBvZiBmb2xkZXIgbGV2ZWxzIHRvIGNyYXdsIHRvIGZpbmQgbW9kdWxlcyBmcm9tIHRoZSBiYXNlUGF0aC4gRGVmYXVsdHMgdG8gNFxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBDcmVhdGUgYSBuZXcgQ0xJIHdyYXBwZXIgYW5kIHJ1biBpdCB3aXRoIGN1c3RvbSBvcHRpb25zXG4gKiBjb25zdCBjbGkgPSBuZXcgQ2xpV3JhcHBlcignLi9zcmMnLCAyKTtcbiAqIGNsaS5ydW4ocHJvY2Vzcy5hcmd2KS50aGVuKCgpID0+IHtcbiAqICAgY29uc29sZS5sb2coJ0NMSSBjb21tYW5kcyBleGVjdXRlZCBzdWNjZXNzZnVsbHknKTtcbiAqIH0pO1xuICpcbiAqIEBjbGFzcyBNY3BXcmFwcGVyXG4gKi9cbmV4cG9ydCBjbGFzcyBNY3BXcmFwcGVyIGV4dGVuZHMgTG9nZ2VkQ2xhc3Mge1xuICBwcml2YXRlIF9tY3A/OiBGYXN0TUNQO1xuICBwcml2YXRlIG1vZHVsZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcbiAgcHJpdmF0ZSByZWFkb25seSByb290UGF0aDogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgYmFzZVBhdGg6IHN0cmluZyA9IFwiLi9cIixcbiAgICBwcml2YXRlIGNyYXdsTGV2ZWxzID0gNFxuICApIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMucm9vdFBhdGggPSBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCBcIi4uXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgYW5kIGluaXRpYWxpemVzIHRoZSBDb21tYW5kZXIgQ29tbWFuZCBvYmplY3RcbiAgICogQHN1bW1hcnkgTGF6eS1sb2FkcyB0aGUgQ29tbWFuZCBvYmplY3QsIGluaXRpYWxpemluZyBpdCB3aXRoIHRoZSBwYWNrYWdlIG5hbWUsIGRlc2NyaXB0aW9uLCBhbmQgdmVyc2lvblxuICAgKiBAcmV0dXJuIHtGYXN0TUNQfSBUaGUgaW5pdGlhbGl6ZWQgQ29tbWFuZCBvYmplY3RcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgZ2V0IG1jcCgpIHtcbiAgICBpZiAoIXRoaXMuX21jcCkge1xuICAgICAgdGhpcy5fbWNwID0gbmV3IEZhc3RNQ1Aoe1xuICAgICAgICBuYW1lOiBcImRlY2FmLXRzIE1DUCBzZXJ2ZXJcIixcbiAgICAgICAgaW5zdHJ1Y3Rpb25zOiBcIlwiLFxuICAgICAgICB2ZXJzaW9uOiBWRVJTSU9OIGFzIGFueSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fbWNwO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMb2FkcyBhbmQgcmVnaXN0ZXJzIGFuIG1jcCBleHRlbnNpb24gbW9kdWxlIGZyb20gYSBmaWxlXG4gICAqIEBzdW1tYXJ5IER5bmFtaWNhbGx5IGltcG9ydHMgYW4gbWNwIGV4dGVuc2lvbiBtb2R1bGUgZnJvbSB0aGUgc3BlY2lmaWVkIGZpbGUgcGF0aCwgaW5pdGlhbGl6ZXMgaXQsIGFuZCByZWdpc3RlcnMgaXQgaW4gdGhlIG1vZHVsZXMgY29sbGVjdGlvblxuICAgKlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBsb2FkKFxuICAgIHNlcnZlcjogRmFzdE1DUCxcbiAgICBmaWxlUGF0aDogc3RyaW5nXG4gICk6IFByb21pc2U8eyBtY3A6IEZhc3RNQ1A7IHBhY2thZ2U6IHN0cmluZzsgdmVyc2lvbjogc3RyaW5nIH0+IHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5sb2FkKTtcblxuICAgIGxldCBwa2c6IHN0cmluZywgdmVyc2lvbjogc3RyaW5nLCBlbnJpY2g6IGFueTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgTWNwVXRpbHMubG9hZEZyb21GaWxlKGZpbGVQYXRoKTtcbiAgICAgIHBrZyA9IHJlcy5QQUNLQUdFX05BTUU7XG4gICAgICB2ZXJzaW9uID0gcmVzLlZFUlNJT047XG4gICAgICBlbnJpY2ggPSByZXMuZW5yaWNoO1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigoZSBhcyBhbnkpLm1lc3NhZ2UgfHwgKGUgYXMgYW55KSk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBsb2cuaW5mbyhgRW5yaWNoaW5nIG1jcCBzZXJ2ZXIgd2l0aCBtb2R1bGUgJHtwa2d9IHYke3ZlcnNpb259YCk7XG4gICAgICBjb25zdCByZXN1bHQgPSBlbnJpY2goc2VydmVyKTtcbiAgICAgIHNlcnZlciA9IHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UgPyBhd2FpdCByZXN1bHQgOiByZXN1bHQ7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgZmFpbGVkIHRvIGVucmljaCBtY3Agd2l0aCBtb2R1bGUgJHtwa2cgfHwgXCJ1bm5hbWVkXCJ9IHVuZGVyICR7ZmlsZVBhdGh9OiAke2UgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IGV9YFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIG1jcDogc2VydmVyLFxuICAgICAgcGFja2FnZTogcGtnLFxuICAgICAgdmVyc2lvbjogdmVyc2lvbixcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBGaW5kcyBhbmQgbG9hZHMgYWxsIENMSSBtb2R1bGVzIGluIHRoZSBiYXNlUGF0aFxuICAgKiBAc3VtbWFyeSBVc2VzIHRoZSBjcmF3bCBtZXRob2QgdG8gZmluZCBhbGwgQ0xJIG1vZHVsZXMgaW4gdGhlIHNwZWNpZmllZCBiYXNlIHBhdGgsXG4gICAqIHRoZW4gbG9hZHMgYW5kIHJlZ2lzdGVycyBlYWNoIG1vZHVsZSBhcyBhIHN1YmNvbW1hbmRcbiAgICpcbiAgICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBhbGwgbW9kdWxlcyBhcmUgbG9hZGVkXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENsaVdyYXBwZXJcbiAgICogICBwYXJ0aWNpcGFudCBGaWxlc3lzdGVtXG4gICAqICAgcGFydGljaXBhbnQgTW9kdWxlXG4gICAqXG4gICAqICAgQ2xpV3JhcHBlci0+PkZpbGVzeXN0ZW06IEpvaW4gYmFzZVBhdGggd2l0aCBjd2RcbiAgICogICBDbGlXcmFwcGVyLT4+Q2xpV3JhcHBlcjogY3Jhd2woYmFzZVBhdGgsIGNyYXdsTGV2ZWxzKVxuICAgKiAgIENsaVdyYXBwZXItLT4+Q2xpV3JhcHBlcjogbW9kdWxlc1tdXG4gICAqICAgbG9vcCBGb3IgZWFjaCBtb2R1bGVcbiAgICogICAgIGFsdCBOb3QgQGRlY2FmLXRzL2NsaVxuICAgKiAgICAgICBDbGlXcmFwcGVyLT4+Q2xpV3JhcHBlcjogbG9hZChtb2R1bGUsIGN3ZClcbiAgICogICAgICAgQ2xpV3JhcHBlci0tPj5DbGlXcmFwcGVyOiBuYW1lXG4gICAqICAgICAgIENsaVdyYXBwZXItPj5DbGlXcmFwcGVyOiBDaGVjayBpZiBjb21tYW5kIGV4aXN0c1xuICAgKiAgICAgICBhbHQgQ29tbWFuZCBkb2Vzbid0IGV4aXN0XG4gICAqICAgICAgICAgQ2xpV3JhcHBlci0+PkNvbW1hbmQ6IGNvbW1hbmQobmFtZSkuYWRkQ29tbWFuZChtb2R1bGVzW25hbWVdKVxuICAgKiAgICAgICBlbmRcbiAgICogICAgIGVuZFxuICAgKiAgIGVuZFxuICAgKiAgIENsaVdyYXBwZXItPj5Db25zb2xlOiBMb2cgbG9hZGVkIG1vZHVsZXNcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgYm9vdCgpIHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5ib290KTtcbiAgICBsZXQgc2VydmVyID0gdGhpcy5tY3A7XG4gICAgLy8gZGlzY292ZXIgbW9kdWxlcyBieSBjcmF3bGluZyBiYXNlUGF0aFxuICAgIGNvbnN0IG1vZHVsZUZpbGVzID0gdGhpcy5jcmF3bChcbiAgICAgIHBhdGgucmVzb2x2ZSh0aGlzLmJhc2VQYXRoKSxcbiAgICAgIHRoaXMuY3Jhd2xMZXZlbHNcbiAgICApO1xuICAgIGZvciAoY29uc3QgbW9kdWxlRmlsZSBvZiBtb2R1bGVGaWxlcykge1xuICAgICAgaWYgKG1vZHVsZUZpbGUuaW5jbHVkZXMoXCJAZGVjYWYtdHMvbWNwXCIpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgdGhpcy5sb2FkKHNlcnZlciwgbW9kdWxlRmlsZSk7XG4gICAgICAgIHNlcnZlciA9IHJlcy5tY3A7XG4gICAgICAgIHRoaXMubW9kdWxlc1tyZXMucGFja2FnZV0gPSBtb2R1bGVGaWxlO1xuICAgICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgICBsb2cuZXJyb3IoXG4gICAgICAgICAgYEZhaWxlZCB0byBsb2FkIE1DUCBjb25maWdzIGZvciAke21vZHVsZUZpbGV9OiAke2UgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IGV9YFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zb2xlLmxvZyhcbiAgICAgIGBsb2FkZWQgbW9kdWxlczpcXG4ke09iamVjdC5rZXlzKHRoaXMubW9kdWxlcylcbiAgICAgICAgLm1hcCgoaykgPT4gYC0gJHtrfWApXG4gICAgICAgIC5qb2luKFwiXFxuXCIpfWBcbiAgICApO1xuICAgIHJldHVybiBzZXJ2ZXI7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlY3Vyc2l2ZWx5IHNlYXJjaGVzIGZvciBDTEkgbW9kdWxlIGZpbGVzIGluIHRoZSBkaXJlY3Rvcnkgc3RydWN0dXJlXG4gICAqIEBzdW1tYXJ5IENyYXdscyB0aGUgYmFzZVBhdGggdXAgdG8gdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgZm9sZGVyIGxldmVscyB0byBmaW5kIGZpbGVzIG5hbWVkIGFjY29yZGluZyB0byBDTElfRklMRV9OQU1FXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBiYXNlUGF0aCBUaGUgYWJzb2x1dGUgYmFzZSBwYXRoIHRvIHN0YXJ0IHNlYXJjaGluZyBpblxuICAgKiBAcGFyYW0ge251bWJlcn0gW2xldmVscz0yXSBUaGUgbWF4aW11bSBudW1iZXIgb2YgZGlyZWN0b3J5IGxldmVscyB0byBjcmF3bFxuICAgKiBAcmV0dXJuIHtzdHJpbmdbXX0gQW4gYXJyYXkgb2YgZmlsZSBwYXRocyB0byBDTEkgbW9kdWxlc1xuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBjcmF3bChiYXNlUGF0aDogc3RyaW5nLCBsZXZlbHM6IG51bWJlciA9IDIpIHtcbiAgICBpZiAobGV2ZWxzIDw9IDApIHJldHVybiBbXTtcbiAgICByZXR1cm4gZnMucmVhZGRpclN5bmMoYmFzZVBhdGgpLnJlZHVjZSgoYWNjdW06IHN0cmluZ1tdLCBmaWxlKSA9PiB7XG4gICAgICBmaWxlID0gcGF0aC5qb2luKGJhc2VQYXRoLCBmaWxlKTtcbiAgICAgIGlmIChmcy5zdGF0U3luYyhmaWxlKS5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICAgIGFjY3VtLnB1c2goLi4udGhpcy5jcmF3bChmaWxlLCBsZXZlbHMgLSAxKSk7XG4gICAgICB9IGVsc2UgaWYgKGZpbGUubWF0Y2gobmV3IFJlZ0V4cChgJHtNQ1BfRklMRV9OQU1FfS5bY21dP2pzJGAsIFwiZ21cIikpKSB7XG4gICAgICAgIGFjY3VtLnB1c2goZmlsZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYWNjdW07XG4gICAgfSwgW10pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBFeGVjdXRlcyB0aGUgQ0xJIHdpdGggdGhlIHByb3ZpZGVkIGFyZ3VtZW50c1xuICAgKiBAc3VtbWFyeSBCb290cyB0aGUgQ0xJIGJ5IGxvYWRpbmcgYWxsIG1vZHVsZXMsIHRoZW4gcGFyc2VzIGFuZCBleGVjdXRlcyB0aGUgY29tbWFuZCBzcGVjaWZpZWQgaW4gdGhlIGFyZ3VtZW50c1xuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBbYXJncz1wcm9jZXNzLmFyZ3ZdIENvbW1hbmQgbGluZSBhcmd1bWVudHMgdG8gcGFyc2UgYW5kIGV4ZWN1dGVcbiAgICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgY29tbWFuZCBleGVjdXRpb24gaXMgY29tcGxldGVcbiAgICpcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQ2xpZW50XG4gICAqICAgcGFydGljaXBhbnQgQ2xpV3JhcHBlclxuICAgKiAgIHBhcnRpY2lwYW50IENvbW1hbmRcbiAgICpcbiAgICogICBDbGllbnQtPj5DbGlXcmFwcGVyOiBydW4oYXJncylcbiAgICogICBDbGlXcmFwcGVyLT4+Q2xpV3JhcHBlcjogYm9vdCgpXG4gICAqICAgTm90ZSBvdmVyIENsaVdyYXBwZXI6IExvYWRzIGFsbCBtb2R1bGVzXG4gICAqICAgQ2xpV3JhcHBlci0+PkNvbW1hbmQ6IHBhcnNlQXN5bmMoYXJncylcbiAgICogICBDb21tYW5kLS0+PkNsaVdyYXBwZXI6IHJlc3VsdFxuICAgKiAgIENsaVdyYXBwZXItLT4+Q2xpZW50OiByZXN1bHRcbiAgICovXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgYXN5bmMgcnVuKGFyZ3M6IHN0cmluZ1tdID0gcHJvY2Vzcy5hcmd2KSB7XG4gICAgY29uc3Qgc2VydmVyID0gYXdhaXQgdGhpcy5ib290KCk7XG4gICAgYXdhaXQgc2VydmVyLnN0YXJ0KHsgdHJhbnNwb3J0VHlwZTogXCJzdGRpb1wiIH0pO1xuICB9XG59XG4iXSwibmFtZXMiOlsicHJvbXB0cyIsInJlc291cmNlcyIsInRlbXBsYXRlcyIsInoiLCJhcHBseVBhdGNoIiwiY3JlYXRlVHdvRmlsZXNQYXRjaCIsInRvb2xMaXN0IiwidG9vbHMiLCJtb2R1bGVQYWNrYWdlIiwiZGVjb3JhdGlvbk1vZHVsZSIsIm1jcE1vZHVsZSIsInRlbXBsYXRlTW9kdWxlIiwic3Bhd25TeW5jIiwiY29yZVRvb2xMaXN0IiwiVkVSU0lPTiIsIlBBQ0tBR0VfTkFNRSIsIk1ldGFkYXRhIiwiUEtHIiwiViIsInBhdGhUb0ZpbGVVUkwiLCJwYXRoIiwiZnMiLCJMb2dnZWRDbGFzcyIsIkZhc3RNQ1AiXSwibWFwcGluZ3MiOiI7Ozs7OztJQUFBOzs7Ozs7SUFNRztBQUNJLFVBQU0sYUFBYSxHQUFHO0FBR3RCLFVBQU0sa0JBQWtCLEdBQUc7VUFDckIsa0JBQWtCLEdBQUcsQ0FBQyxlQUFlLEVBQUUsZ0JBQWdCO0FBQzdELFVBQU0sbUJBQW1CLEdBQUc7QUFDNUIsVUFBTSxtQkFBbUIsR0FBRztJQUNqQyxJQUFBO0lBQ0UsUUFBQSxFQUFFLEVBQUUsUUFBUTtJQUNaLFFBQUEsT0FBTyxFQUFFLG9CQUFvQjtJQUM3QixRQUFBLFlBQVksRUFDVixvTUFBb007SUFDdk0sS0FBQTtJQUNELElBQUE7SUFDRSxRQUFBLEVBQUUsRUFBRSxRQUFRO0lBQ1osUUFBQSxPQUFPLEVBQUUsUUFBUTtJQUNqQixRQUFBLFlBQVksRUFDVixpTEFBaUw7SUFDcEwsS0FBQTtJQUNELElBQUE7SUFDRSxRQUFBLEVBQUUsRUFBRSxTQUFTO0lBQ2IsUUFBQSxPQUFPLEVBQUUsZ0JBQWdCO0lBQ3pCLFFBQUEsWUFBWSxFQUNWLGlNQUFpTTtJQUNwTSxLQUFBOzs7SUMzQkgsSUFBSSxhQUFhLEdBQUcsdUJBQXVCLEVBQUU7SUFDN0MsSUFBSSxhQUEyRDtJQUV6RCxNQUFPLGNBQWUsU0FBUSxLQUFLLENBQUE7SUFDdkMsSUFBQSxXQUFBLENBQVksT0FBZSxFQUFBO1lBQ3pCLEtBQUssQ0FBQyxPQUFPLENBQUM7SUFDZCxRQUFBLElBQUksQ0FBQyxJQUFJLEdBQUcsZ0JBQWdCO1FBQzlCO0lBQ0Q7SUFFRCxTQUFTLHVCQUF1QixHQUFBO1FBQzlC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
|