@decaf-ts/mcp-server 0.0.4 → 0.3.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.
Files changed (210) hide show
  1. package/README.md +18 -2
  2. package/dist/mcp-server.cjs +1986 -340
  3. package/dist/mcp-server.esm.cjs +1960 -337
  4. package/lib/McpWrapper.cjs +9 -9
  5. package/lib/McpWrapper.d.ts +1 -1
  6. package/lib/bin/validate-modules.cjs +24 -0
  7. package/lib/bin/validate-modules.d.ts +2 -0
  8. package/lib/constants.cjs +22 -2
  9. package/lib/constants.d.ts +16 -0
  10. package/lib/esm/McpWrapper.d.ts +1 -1
  11. package/lib/esm/McpWrapper.js +9 -9
  12. package/lib/esm/bin/validate-modules.d.ts +2 -0
  13. package/lib/esm/bin/validate-modules.js +22 -0
  14. package/lib/esm/constants.d.ts +16 -0
  15. package/lib/esm/constants.js +21 -1
  16. package/lib/esm/mcp/aggregateModules.d.ts +26 -0
  17. package/lib/esm/mcp/aggregateModules.js +185 -0
  18. package/lib/esm/mcp/code.d.ts +23 -0
  19. package/lib/esm/mcp/code.js +70 -0
  20. package/lib/esm/mcp/decorator-tools.js +237 -0
  21. package/lib/esm/mcp/fastmcp-wiring.d.ts +14 -0
  22. package/lib/esm/mcp/fastmcp-wiring.js +56 -0
  23. package/lib/esm/mcp/index.d.ts +7 -1
  24. package/lib/esm/mcp/index.js +26 -2
  25. package/lib/esm/mcp/mcp-module.d.ts +11 -0
  26. package/lib/esm/mcp/mcp-module.js +31 -0
  27. package/lib/esm/mcp/moduleRegistry.d.ts +12 -0
  28. package/lib/esm/mcp/moduleRegistry.js +46 -0
  29. package/lib/esm/mcp/prompts/index.d.ts +4 -0
  30. package/lib/esm/mcp/prompts/index.js +7 -0
  31. package/lib/esm/mcp/prompts/prompts.d.ts +22 -0
  32. package/lib/esm/mcp/prompts/prompts.js +197 -0
  33. package/lib/esm/mcp/resources/index.d.ts +1 -0
  34. package/lib/esm/mcp/resources/index.js +2 -0
  35. package/lib/esm/mcp/resources/resources.d.ts +2 -0
  36. package/lib/esm/mcp/resources/resources.js +69 -0
  37. package/lib/esm/mcp/schemas.d.ts +53 -0
  38. package/lib/esm/mcp/schemas.js +97 -0
  39. package/lib/esm/mcp/templates/codex-templates.d.ts +3 -0
  40. package/lib/esm/mcp/templates/codex-templates.js +33 -0
  41. package/lib/esm/mcp/templates/index.d.ts +71 -0
  42. package/lib/esm/mcp/templates/index.js +66 -0
  43. package/lib/esm/mcp/templates/resource-templates.d.ts +3 -0
  44. package/lib/esm/mcp/templates/resource-templates.js +60 -0
  45. package/lib/esm/mcp/templates/workspace-templates.d.ts +3 -0
  46. package/lib/esm/mcp/templates/workspace-templates.js +66 -0
  47. package/lib/esm/mcp/tools/codex-tools.d.ts +5 -0
  48. package/lib/esm/mcp/tools/codex-tools.js +244 -0
  49. package/lib/esm/mcp/tools/generateMcpModule.d.ts +9 -0
  50. package/lib/esm/mcp/tools/generateMcpModule.js +133 -0
  51. package/lib/esm/mcp/tools/index.d.ts +321 -0
  52. package/lib/esm/mcp/tools/index.js +29 -0
  53. package/lib/esm/mcp/tools/tools.d.ts +10 -0
  54. package/lib/esm/mcp/tools/tools.js +273 -0
  55. package/lib/esm/mcp/types.d.ts +66 -0
  56. package/lib/esm/mcp/types.js +2 -0
  57. package/lib/esm/mcp/utils.d.ts +4 -0
  58. package/lib/esm/mcp/utils.js +46 -0
  59. package/lib/esm/mcp/validation/index.d.ts +13 -0
  60. package/lib/esm/mcp/validation/index.js +116 -0
  61. package/lib/esm/mcp/validation/scaffoldModule.d.ts +9 -0
  62. package/lib/esm/mcp/validation/scaffoldModule.js +88 -0
  63. package/lib/esm/mcp/workspace.d.ts +9 -0
  64. package/lib/esm/mcp/workspace.js +73 -0
  65. package/lib/esm/metadata.d.ts +1 -1
  66. package/lib/esm/metadata.js +1 -1
  67. package/lib/esm/modules/_template/index.d.ts +32 -0
  68. package/lib/esm/modules/_template/index.js +16 -0
  69. package/lib/esm/modules/_template/prompts/index.d.ts +6 -0
  70. package/lib/esm/modules/_template/prompts/index.js +9 -0
  71. package/lib/esm/modules/_template/resources/index.d.ts +6 -0
  72. package/lib/esm/modules/_template/resources/index.js +9 -0
  73. package/lib/esm/modules/_template/templates/index.d.ts +7 -0
  74. package/lib/esm/modules/_template/templates/index.js +10 -0
  75. package/lib/esm/modules/_template/tools/index.d.ts +6 -0
  76. package/lib/esm/modules/_template/tools/index.js +15 -0
  77. package/lib/esm/modules/decoration/index.d.ts +46 -0
  78. package/lib/esm/modules/decoration/index.js +10 -2
  79. package/lib/esm/modules/decoration/prompts/index.d.ts +1 -0
  80. package/lib/esm/modules/decoration/prompts/index.js +2 -0
  81. package/lib/esm/modules/decoration/resources/index.d.ts +7 -0
  82. package/lib/esm/modules/decoration/resources/index.js +10 -0
  83. package/lib/esm/modules/decoration/templates/index.d.ts +6 -0
  84. package/lib/esm/modules/decoration/templates/index.js +9 -0
  85. package/lib/esm/modules/decoration/tools/index.d.ts +26 -0
  86. package/lib/esm/modules/decoration/tools/index.js +7 -0
  87. package/lib/esm/modules/index.d.ts +2 -0
  88. package/lib/esm/modules/index.js +10 -0
  89. package/lib/esm/modules/mcp/decoration-assist.d.ts +3 -38
  90. package/lib/esm/modules/mcp/decoration-assist.js +5 -352
  91. package/lib/esm/modules/mcp/index.d.ts +6 -2
  92. package/lib/esm/modules/mcp/index.js +16 -3
  93. package/lib/esm/modules/mcp/prompts/index.d.ts +2 -0
  94. package/lib/esm/modules/mcp/prompts/index.js +9 -0
  95. package/lib/esm/modules/mcp/resources/index.d.ts +2 -0
  96. package/lib/esm/modules/mcp/resources/index.js +24 -0
  97. package/lib/esm/modules/mcp/templates/index.d.ts +2 -0
  98. package/lib/esm/modules/mcp/templates/index.js +28 -0
  99. package/lib/esm/modules/mcp/tools/index.d.ts +6 -0
  100. package/lib/esm/modules/mcp/tools/index.js +15 -0
  101. package/lib/esm/types.d.ts +41 -1
  102. package/lib/esm/types.js +1 -1
  103. package/lib/esm/utils/modulePaths.d.ts +6 -0
  104. package/lib/esm/utils/modulePaths.js +33 -0
  105. package/lib/esm/utils/moduleValidator.d.ts +14 -0
  106. package/lib/esm/utils/moduleValidator.js +176 -0
  107. package/lib/esm/utils.d.ts +1 -0
  108. package/lib/esm/utils.js +2 -1
  109. package/lib/mcp/aggregateModules.cjs +225 -0
  110. package/lib/mcp/aggregateModules.d.ts +26 -0
  111. package/lib/mcp/code.cjs +81 -0
  112. package/lib/mcp/code.d.ts +23 -0
  113. package/lib/mcp/decorator-tools.cjs +243 -0
  114. package/lib/mcp/fastmcp-wiring.cjs +59 -0
  115. package/lib/mcp/fastmcp-wiring.d.ts +14 -0
  116. package/lib/mcp/index.cjs +47 -12
  117. package/lib/mcp/index.d.ts +7 -1
  118. package/lib/mcp/mcp-module.cjs +53 -0
  119. package/lib/mcp/mcp-module.d.ts +11 -0
  120. package/lib/mcp/moduleRegistry.cjs +50 -0
  121. package/lib/mcp/moduleRegistry.d.ts +12 -0
  122. package/lib/mcp/prompts/index.cjs +25 -0
  123. package/lib/mcp/prompts/index.d.ts +4 -0
  124. package/lib/mcp/prompts/prompts.cjs +211 -0
  125. package/lib/mcp/prompts/prompts.d.ts +22 -0
  126. package/lib/mcp/resources/index.cjs +18 -0
  127. package/lib/mcp/resources/index.d.ts +1 -0
  128. package/lib/mcp/resources/resources.cjs +72 -0
  129. package/lib/mcp/resources/resources.d.ts +2 -0
  130. package/lib/mcp/schemas.cjs +100 -0
  131. package/lib/mcp/schemas.d.ts +53 -0
  132. package/lib/mcp/templates/codex-templates.cjs +40 -0
  133. package/lib/mcp/templates/codex-templates.d.ts +3 -0
  134. package/lib/mcp/templates/index.cjs +76 -0
  135. package/lib/mcp/templates/index.d.ts +71 -0
  136. package/lib/mcp/templates/resource-templates.cjs +67 -0
  137. package/lib/mcp/templates/resource-templates.d.ts +3 -0
  138. package/lib/mcp/templates/workspace-templates.cjs +70 -0
  139. package/lib/mcp/templates/workspace-templates.d.ts +3 -0
  140. package/lib/mcp/tools/codex-tools.cjs +250 -0
  141. package/lib/mcp/tools/codex-tools.d.ts +5 -0
  142. package/lib/mcp/tools/generateMcpModule.cjs +139 -0
  143. package/lib/mcp/tools/generateMcpModule.d.ts +9 -0
  144. package/lib/mcp/tools/index.cjs +46 -0
  145. package/lib/mcp/tools/index.d.ts +321 -0
  146. package/lib/mcp/tools/tools.cjs +282 -0
  147. package/lib/mcp/tools/tools.d.ts +10 -0
  148. package/lib/mcp/types.cjs +3 -0
  149. package/lib/mcp/types.d.ts +66 -0
  150. package/lib/mcp/utils.cjs +54 -0
  151. package/lib/mcp/utils.d.ts +4 -0
  152. package/lib/mcp/validation/index.cjs +123 -0
  153. package/lib/mcp/validation/index.d.ts +13 -0
  154. package/lib/mcp/validation/scaffoldModule.cjs +94 -0
  155. package/lib/mcp/validation/scaffoldModule.d.ts +9 -0
  156. package/lib/mcp/workspace.cjs +119 -0
  157. package/lib/mcp/workspace.d.ts +9 -0
  158. package/lib/metadata.cjs +1 -1
  159. package/lib/metadata.d.ts +1 -1
  160. package/lib/modules/_template/index.cjs +23 -0
  161. package/lib/modules/_template/index.d.ts +32 -0
  162. package/lib/modules/_template/prompts/index.cjs +12 -0
  163. package/lib/modules/_template/prompts/index.d.ts +6 -0
  164. package/lib/modules/_template/resources/index.cjs +12 -0
  165. package/lib/modules/_template/resources/index.d.ts +6 -0
  166. package/lib/modules/_template/templates/index.cjs +13 -0
  167. package/lib/modules/_template/templates/index.d.ts +7 -0
  168. package/lib/modules/_template/tools/index.cjs +18 -0
  169. package/lib/modules/_template/tools/index.d.ts +6 -0
  170. package/lib/modules/decoration/index.cjs +16 -1
  171. package/lib/modules/decoration/index.d.ts +46 -0
  172. package/lib/modules/decoration/prompts/index.cjs +5 -0
  173. package/lib/modules/decoration/prompts/index.d.ts +1 -0
  174. package/lib/modules/decoration/resources/index.cjs +13 -0
  175. package/lib/modules/decoration/resources/index.d.ts +7 -0
  176. package/lib/modules/decoration/templates/index.cjs +12 -0
  177. package/lib/modules/decoration/templates/index.d.ts +6 -0
  178. package/lib/modules/decoration/tools/index.cjs +10 -0
  179. package/lib/modules/decoration/tools/index.d.ts +26 -0
  180. package/lib/modules/index.cjs +13 -0
  181. package/lib/modules/index.d.ts +2 -0
  182. package/lib/modules/mcp/decoration-assist.cjs +8 -355
  183. package/lib/modules/mcp/decoration-assist.d.ts +3 -38
  184. package/lib/modules/mcp/index.cjs +21 -22
  185. package/lib/modules/mcp/index.d.ts +6 -2
  186. package/lib/modules/mcp/prompts/index.cjs +12 -0
  187. package/lib/modules/mcp/prompts/index.d.ts +2 -0
  188. package/lib/modules/mcp/resources/index.cjs +27 -0
  189. package/lib/modules/mcp/resources/index.d.ts +2 -0
  190. package/lib/modules/mcp/templates/index.cjs +31 -0
  191. package/lib/modules/mcp/templates/index.d.ts +2 -0
  192. package/lib/modules/mcp/tools/index.cjs +18 -0
  193. package/lib/modules/mcp/tools/index.d.ts +6 -0
  194. package/lib/types.cjs +1 -1
  195. package/lib/types.d.ts +41 -1
  196. package/lib/utils/modulePaths.cjs +43 -0
  197. package/lib/utils/modulePaths.d.ts +6 -0
  198. package/lib/utils/moduleValidator.cjs +184 -0
  199. package/lib/utils/moduleValidator.d.ts +14 -0
  200. package/lib/utils.cjs +5 -1
  201. package/lib/utils.d.ts +1 -0
  202. package/package.json +14 -13
  203. package/lib/esm/modules/mcp/decorator-tools.js +0 -237
  204. package/lib/esm/modules/mcp/mcp-module.d.ts +0 -230
  205. package/lib/esm/modules/mcp/mcp-module.js +0 -406
  206. package/lib/modules/mcp/decorator-tools.cjs +0 -243
  207. package/lib/modules/mcp/mcp-module.cjs +0 -452
  208. package/lib/modules/mcp/mcp-module.d.ts +0 -230
  209. /package/lib/esm/{modules/mcp → mcp}/decorator-tools.d.ts +0 -0
  210. /package/lib/{modules/mcp → mcp}/decorator-tools.d.ts +0 -0
@@ -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
- * @const VERSION
9
- * @name VERSION
10
- * @description Represents the current version of the ts-workspace module.
11
- * @summary The actual version number is replaced during the build process.
12
- * @type {string}
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 VERSION$1 = "0.0.3";
15
- const PACKAGE_NAME$1 = "##PACKAGE_NAME##";
16
- try {
17
- decoration.Metadata.registerLibrary(PACKAGE_NAME$1, VERSION$1);
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:///tmp/mcp-gen-y0kwu6/decoration",
114
+ "absolutePath": "/tmp/mcp-gen-y0kwu6/decoration"
115
+ }
116
+ ];
117
+
118
+ const templates$2 = [
119
+ {
120
+ "name": "readme-template",
121
+ "description": "README as guidance",
122
+ "uriTemplate": "file:///tmp/mcp-gen-y0kwu6/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
- catch (error) {
20
- if (error instanceof Error && error.message.includes("already")) ;
21
- else {
22
- throw error;
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
- const documentCodeSchema = zod.z
282
- .object({
283
- filePath: zod.z.string().min(1, "filePath is required"),
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
- async function getUserErrorCtor() {
311
- if (!userErrorCtor) {
312
- try {
313
- const mod = await import('fastmcp');
314
- userErrorCtor = mod
315
- .UserError;
316
- }
317
- catch {
318
- userErrorCtor = class MCPUserError extends Error {
319
- constructor(message) {
320
- super(message);
321
- this.name = "MCPUserError";
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
- async function throwUserError(message) {
329
- const Ctor = await getUserErrorCtor();
330
- throw new Ctor(message);
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 = documentCodeSchema.parse(input);
343
- const root = getWorkspaceRoot();
344
- let filePath;
345
- try {
346
- filePath = resolveInWorkspace(root, args.filePath);
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
- catch (error) {
349
- if (error instanceof WorkspaceError) {
350
- return throwUserError(error.message);
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 prompt = selectPrompt(prompts, args.promptName ?? DEFAULT_PROMPT_NAME);
366
- return buildDocumentationPayload({
367
- filePath: args.filePath,
368
- fileContent,
369
- prompt,
370
- includeCode: args.includeCode,
371
- includePrompt: args.includePrompt,
372
- includeMetadata: args.includeMetadata,
373
- additionalContext: args.additionalContext,
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 applyCodeChangeTool = {
380
- annotations: {
381
- destructiveHint: true,
382
- idempotentHint: false,
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 = codeChangeSchema.parse(input);
391
- const root = getWorkspaceRoot();
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
- fs.mkdirSync(path.dirname(filePath), { recursive: true });
418
- fs.writeFileSync(filePath, patched, {
419
- encoding: args.encoding,
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
- if (!args.showDiff) {
423
- return `Patch ${args.dryRun ? "validated" : "applied"} for ${args.filePath}`;
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 preview = diff.createTwoFilesPatch(args.filePath, args.filePath, original, patched, undefined, undefined, { context: args.diffContext });
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: `Patch ${args.dryRun ? "validated" : "applied"} for ${args.filePath}`,
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: ["```diff", preview.trim(), "```"].join("\n"),
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
- const tools = {
443
- ...decoratorTools,
444
- documentCodeTool,
445
- applyCodeChangeTool,
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
- function enrich(mcp) {
448
- for (const prompt of buildDocPrompts()) {
449
- mcp.addPrompt(prompt);
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
- for (const tool of Object.values(tools)) {
452
- mcp.addTool(tool);
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
- for (const template of buildResourceTemplates()) {
455
- mcp.addResourceTemplate(template);
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
- const PACKAGE_NAME = PACKAGE_NAME$1;
460
- const VERSION = VERSION$1;
461
- function setWorkspaceRoot(root) {
462
- workspaceRoot = path.resolve(root);
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 getWorkspaceRoot() {
465
- return workspaceRoot;
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
- function buildResourceTemplates() {
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
- return [
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
- const text = await readWorkspaceFile(root, args.path);
485
- return { text };
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
- const text = await readWorkspaceFile(root, args.path);
496
- return { text };
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
- const text = await readWorkspaceFile(root, args.path);
507
- return { text };
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
- function initializeWorkspaceRoot() {
513
- const configured = process.env[WORKSPACE_ROOT_ENV];
514
- if (configured && configured.trim().length > 0) {
515
- return path.resolve(configured.trim());
516
- }
517
- return process.cwd();
518
- }
519
- function buildDocPrompts() {
520
- const root = getWorkspaceRoot();
521
- const fileBasedPrompts = discoverDocPrompts(root).map((prompt) => ({
522
- name: `doc/${prompt.name}`,
523
- description: prompt.description,
524
- load: async () => prompt.content,
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 integrationPrompts = CLIENT_INTEGRATIONS.map((integration) => ({
527
- name: `integration/${integration.id}`,
528
- description: `${integration.display} integration guidance`,
529
- 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.`,
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
- function resolveInWorkspace(root, targetPath) {
534
- const resolved = path.isAbsolute(targetPath)
535
- ? path.normalize(targetPath)
536
- : path.resolve(root, targetPath);
537
- const relative = path.relative(root, resolved);
538
- if (relative.startsWith("..") || path.isAbsolute(relative)) {
539
- throw new WorkspaceError(`Path ${targetPath} escapes the workspace root at ${root}`);
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.2.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
- async function readWorkspaceFile(root, target) {
544
- try {
545
- const absolute = resolveInWorkspace(root, target);
546
- return fs.readFileSync(absolute, "utf8");
1870
+
1871
+ function enrich(mcp) {
1872
+ const promptEntries = loadPrompts();
1873
+ for (const prompt of promptEntries) {
1874
+ mcp.addPrompt(prompt);
547
1875
  }
548
- catch (error) {
549
- if (error instanceof WorkspaceError) {
550
- await throwUserError(error.message);
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 discoverDocPrompts(root) {
557
- const discovered = [];
558
- for (const directory of PROMPT_DIRECTORIES) {
559
- const promptDir = path.join(root, directory);
560
- if (!fs.existsSync(promptDir) || !fs.statSync(promptDir).isDirectory()) {
561
- continue;
562
- }
563
- for (const entry of fs.readdirSync(promptDir)) {
564
- const fullPath = path.join(promptDir, entry);
565
- if (!fs.statSync(fullPath).isFile())
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
- const name = path.parse(entry).name;
568
- const content = fs.readFileSync(fullPath, "utf8");
569
- const title = toTitleCase(name.replace(/[-_]/g, " "));
570
- const description = extractDescription(content, fullPath);
571
- discovered.push({
572
- name,
573
- title,
574
- description,
575
- content,
576
- absolutePath: fullPath,
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
- const unique = new Map();
581
- for (const prompt of discovered) {
582
- if (!unique.has(prompt.name)) {
583
- unique.set(prompt.name, prompt);
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 Array.from(unique.values()).sort((a, b) => a.name.localeCompare(b.name));
1994
+ return undefined;
587
1995
  }
588
- function selectPrompt(prompts, requestedName) {
589
- const direct = prompts.find((prompt) => prompt.name === requestedName);
590
- if (direct)
591
- return direct;
592
- const fallback = prompts.find((prompt) => prompt.name === DEFAULT_PROMPT_NAME);
593
- if (fallback)
594
- return fallback;
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
- return prompts[0];
2004
+ console.log("Module validation passed");
2005
+ process.exit(0);
599
2006
  }
600
- function buildDocumentationPayload({ filePath, fileContent, prompt, includePrompt, includeCode, includeMetadata, additionalContext, }) {
601
- const sections = [];
602
- if (includeMetadata) {
603
- sections.push(`# Documentation Request\n- prompt: ${prompt.name}\n- file: ${filePath}`);
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
- if (includePrompt) {
606
- sections.push(`## Prompt Guidance (${prompt.title})\n\n${prompt.content.trim()}`);
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
- if (additionalContext?.trim()) {
609
- sections.push(`## Additional Context\n\n${additionalContext.trim()}`);
2040
+ catch (e) {
2041
+ return `obj:${String(item)}`;
610
2042
  }
611
- if (includeCode) {
612
- sections.push(`## Source\n\n\`\`\`${inferLanguageFromPath(filePath)}\n${fileContent}\n\`\`\``);
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
- return {
615
- content: [
616
- {
617
- type: "text",
618
- text: sections.join("\n\n"),
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
- function extractDescription(content, filePath) {
624
- const firstLine = content
625
- .split(/\r?\n/)
626
- .map((line) => line.trim())
627
- .find((line) => line.length > 0);
628
- return (firstLine?.slice(0, 240) ??
629
- `Documentation prompt loaded from ${path.basename(filePath)}`);
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
- function toTitleCase(value) {
632
- return value
633
- .split(/\s+/)
634
- .filter(Boolean)
635
- .map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())
636
- .join(" ");
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
- function inferLanguageFromPath(filePath) {
639
- const extension = path.extname(filePath).toLowerCase();
640
- switch (extension) {
641
- case ".ts":
642
- case ".tsx":
643
- return "ts";
644
- case ".js":
645
- case ".jsx":
646
- return "js";
647
- case ".json":
648
- return "json";
649
- case ".md":
650
- return "md";
651
- default:
652
- return "text";
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
- * @description The filename that identifies Decaf CLI modules
658
- * @summary The standard filename for CLI module files where each library must export a single CliModule function
659
- *
660
- * @const MCP_FILE_NAME
661
- * @memberOf module:MCP
662
- */
663
- const MCP_FILE_NAME = "mcp-module";
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 {Command} The initialized Command object
2395
+ * @return {FastMCP} The initialized Command object
778
2396
  * @private
779
2397
  */
780
2398
  get mcp() {
@@ -849,19 +2467,20 @@
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
- for (const module of modules) {
856
- if (module.includes("@decaf-ts/mcp")) {
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, module);
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 ${module}: ${e}`);
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)
@@ -920,17 +2539,44 @@
920
2539
  }
921
2540
  }
922
2541
 
2542
+ exports.CLIENT_INTEGRATIONS = CLIENT_INTEGRATIONS;
2543
+ exports.DEFAULT_PROMPT_NAME = DEFAULT_PROMPT_NAME;
2544
+ exports.EnrichCore = EnrichCore;
2545
+ exports.EnrichCoreWithAggregation = EnrichCoreWithAggregation;
923
2546
  exports.MCP_FILE_NAME = MCP_FILE_NAME;
924
2547
  exports.McpUtils = McpUtils;
925
2548
  exports.McpWrapper = McpWrapper;
926
2549
  exports.PACKAGE_NAME = PACKAGE_NAME;
2550
+ exports.PROMPT_DIRECTORIES = PROMPT_DIRECTORIES;
2551
+ exports.REQUIRED_MODULE_FOLDERS = REQUIRED_MODULE_FOLDERS;
927
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;
928
2558
  exports.buildDocPrompts = buildDocPrompts;
2559
+ exports.buildDocumentationPayload = buildDocumentationPayload;
2560
+ exports.buildPrompts = buildPrompts;
929
2561
  exports.buildResourceTemplates = buildResourceTemplates;
2562
+ exports.decorationResourceTemplates = decorationResourceTemplates;
2563
+ exports.discoverDocPrompts = discoverDocPrompts;
930
2564
  exports.enrich = enrich;
931
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;
932
2574
  exports.setWorkspaceRoot = setWorkspaceRoot;
2575
+ exports.templateList = templateList;
2576
+ exports.toolList = toolList;
933
2577
  exports.tools = tools;
2578
+ exports.validateModules = validateModules;
2579
+ exports.workspaceResourceTemplates = workspaceResourceTemplates;
934
2580
 
935
2581
  }));
936
- //# 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+PkNvbnNvbGU6IExvZyBsb2FkZWQgbW9kdWxlc1xuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBib290KCkge1xuICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nLmZvcih0aGlzLmJvb3QpO1xuXG4gICAgY29uc3QgYmFzZVBhdGggPSBwYXRoLnJlc29sdmUodGhpcy5yb290UGF0aCwgdGhpcy5iYXNlUGF0aCk7XG4gICAgY29uc3QgbW9kdWxlcyA9IHRoaXMuY3Jhd2woYmFzZVBhdGgsIHRoaXMuY3Jhd2xMZXZlbHMpO1xuICAgIGxldCBzZXJ2ZXIgPSB0aGlzLm1jcDtcbiAgICBmb3IgKGNvbnN0IG1vZHVsZSBvZiBtb2R1bGVzKSB7XG4gICAgICBpZiAobW9kdWxlLmluY2x1ZGVzKFwiQGRlY2FmLXRzL21jcFwiKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMubG9hZChzZXJ2ZXIsIG1vZHVsZSk7XG4gICAgICAgIHNlcnZlciA9IHJlcy5tY3A7XG4gICAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICAgIGxvZy5lcnJvcihgRmFpbGVkIHRvIGxvYWQgTUNQIGNvbmZpZ3MgZm9yICR7bW9kdWxlfTogJHtlfWApO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zb2xlLmxvZyhcbiAgICAgIGBsb2FkZWQgbW9kdWxlczpcXG4ke09iamVjdC5rZXlzKHRoaXMubW9kdWxlcylcbiAgICAgICAgLm1hcCgoaykgPT4gYC0gJHtrfWApXG4gICAgICAgIC5qb2luKFwiXFxuXCIpfWBcbiAgICApO1xuICAgIHJldHVybiBzZXJ2ZXI7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlY3Vyc2l2ZWx5IHNlYXJjaGVzIGZvciBDTEkgbW9kdWxlIGZpbGVzIGluIHRoZSBkaXJlY3Rvcnkgc3RydWN0dXJlXG4gICAqIEBzdW1tYXJ5IENyYXdscyB0aGUgYmFzZVBhdGggdXAgdG8gdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgZm9sZGVyIGxldmVscyB0byBmaW5kIGZpbGVzIG5hbWVkIGFjY29yZGluZyB0byBDTElfRklMRV9OQU1FXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBiYXNlUGF0aCBUaGUgYWJzb2x1dGUgYmFzZSBwYXRoIHRvIHN0YXJ0IHNlYXJjaGluZyBpblxuICAgKiBAcGFyYW0ge251bWJlcn0gW2xldmVscz0yXSBUaGUgbWF4aW11bSBudW1iZXIgb2YgZGlyZWN0b3J5IGxldmVscyB0byBjcmF3bFxuICAgKiBAcmV0dXJuIHtzdHJpbmdbXX0gQW4gYXJyYXkgb2YgZmlsZSBwYXRocyB0byBDTEkgbW9kdWxlc1xuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBjcmF3bChiYXNlUGF0aDogc3RyaW5nLCBsZXZlbHM6IG51bWJlciA9IDIpIHtcbiAgICBpZiAobGV2ZWxzIDw9IDApIHJldHVybiBbXTtcbiAgICByZXR1cm4gZnMucmVhZGRpclN5bmMoYmFzZVBhdGgpLnJlZHVjZSgoYWNjdW06IHN0cmluZ1tdLCBmaWxlKSA9PiB7XG4gICAgICBmaWxlID0gcGF0aC5qb2luKGJhc2VQYXRoLCBmaWxlKTtcbiAgICAgIGlmIChmcy5zdGF0U3luYyhmaWxlKS5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICAgIGFjY3VtLnB1c2goLi4udGhpcy5jcmF3bChmaWxlLCBsZXZlbHMgLSAxKSk7XG4gICAgICB9IGVsc2UgaWYgKGZpbGUubWF0Y2gobmV3IFJlZ0V4cChgJHtNQ1BfRklMRV9OQU1FfS5bY21dP2pzJGAsIFwiZ21cIikpKSB7XG4gICAgICAgIGFjY3VtLnB1c2goZmlsZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYWNjdW07XG4gICAgfSwgW10pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBFeGVjdXRlcyB0aGUgQ0xJIHdpdGggdGhlIHByb3ZpZGVkIGFyZ3VtZW50c1xuICAgKiBAc3VtbWFyeSBCb290cyB0aGUgQ0xJIGJ5IGxvYWRpbmcgYWxsIG1vZHVsZXMsIHRoZW4gcGFyc2VzIGFuZCBleGVjdXRlcyB0aGUgY29tbWFuZCBzcGVjaWZpZWQgaW4gdGhlIGFyZ3VtZW50c1xuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBbYXJncz1wcm9jZXNzLmFyZ3ZdIENvbW1hbmQgbGluZSBhcmd1bWVudHMgdG8gcGFyc2UgYW5kIGV4ZWN1dGVcbiAgICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgY29tbWFuZCBleGVjdXRpb24gaXMgY29tcGxldGVcbiAgICpcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQ2xpZW50XG4gICAqICAgcGFydGljaXBhbnQgQ2xpV3JhcHBlclxuICAgKiAgIHBhcnRpY2lwYW50IENvbW1hbmRcbiAgICpcbiAgICogICBDbGllbnQtPj5DbGlXcmFwcGVyOiBydW4oYXJncylcbiAgICogICBDbGlXcmFwcGVyLT4+Q2xpV3JhcHBlcjogYm9vdCgpXG4gICAqICAgTm90ZSBvdmVyIENsaVdyYXBwZXI6IExvYWRzIGFsbCBtb2R1bGVzXG4gICAqICAgQ2xpV3JhcHBlci0+PkNvbW1hbmQ6IHBhcnNlQXN5bmMoYXJncylcbiAgICogICBDb21tYW5kLS0+PkNsaVdyYXBwZXI6IHJlc3VsdFxuICAgKiAgIENsaVdyYXBwZXItLT4+Q2xpZW50OiByZXN1bHRcbiAgICovXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgYXN5bmMgcnVuKGFyZ3M6IHN0cmluZ1tdID0gcHJvY2Vzcy5hcmd2KSB7XG4gICAgY29uc3Qgc2VydmVyID0gYXdhaXQgdGhpcy5ib290KCk7XG4gICAgYXdhaXQgc2VydmVyLnN0YXJ0KHsgdHJhbnNwb3J0VHlwZTogXCJzdGRpb1wiIH0pO1xuICB9XG59XG4iXSwibmFtZXMiOlsiVkVSU0lPTiIsIlBBQ0tBR0VfTkFNRSIsIk1ldGFkYXRhIiwieiIsImFwcGx5UGF0Y2giLCJjcmVhdGVUd29GaWxlc1BhdGNoIiwiUEtHIiwiViIsIkxvZ2dlZENsYXNzIiwiRmFzdE1DUCJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0lBRUE7Ozs7OztJQU1HO0lBQ0ksTUFBTUEsU0FBTyxHQUFHLGFBQWE7SUFDN0IsTUFBTUMsY0FBWSxHQUFHLGtCQUFrQjtJQUU5QyxJQUFJO0lBQ0YsSUFBQUMsbUJBQVEsQ0FBQyxlQUFlLENBQUNELGNBQVksRUFBRUQsU0FBTyxDQUFDO0lBQ2pEO0lBQUUsT0FBTyxLQUFLLEVBQUU7SUFDZCxJQUFBLElBQUksS0FBSyxZQUFZLEtBQUssSUFBSSxLQUFLLENB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
2582
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWNwLXNlcnZlci5janMiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb25zdGFudHMudHMiLCIuLi9zcmMvbWNwL3dvcmtzcGFjZS50cyIsIi4uL3NyYy9tb2R1bGVzL2RlY29yYXRpb24vcHJvbXB0cy9pbmRleC50cyIsIi4uL3NyYy9tb2R1bGVzL2RlY29yYXRpb24vcmVzb3VyY2VzL2luZGV4LnRzIiwiLi4vc3JjL21vZHVsZXMvZGVjb3JhdGlvbi90ZW1wbGF0ZXMvaW5kZXgudHMiLCIuLi9zcmMvbWNwL3NjaGVtYXMudHMiLCIuLi9zcmMvbWNwL3V0aWxzLnRzIiwiLi4vc3JjL21jcC9jb2RlLnRzIiwiLi4vc3JjL21jcC90b29scy90b29scy50cyIsIi4uL3NyYy9tb2R1bGVzL2RlY29yYXRpb24vdG9vbHMvaW5kZXgudHMiLCIuLi9zcmMvbW9kdWxlcy9kZWNvcmF0aW9uL2luZGV4LnRzIiwiLi4vc3JjL21vZHVsZXMvbWNwL3Byb21wdHMvaW5kZXgudHMiLCIuLi9zcmMvbW9kdWxlcy9tY3AvcmVzb3VyY2VzL2luZGV4LnRzIiwiLi4vc3JjL21vZHVsZXMvbWNwL3RlbXBsYXRlcy9pbmRleC50cyIsIi4uL3NyYy9tb2R1bGVzL21jcC90b29scy9pbmRleC50cyIsIi4uL3NyYy9tb2R1bGVzL21jcC9pbmRleC50cyIsIi4uL3NyYy9tb2R1bGVzL190ZW1wbGF0ZS9wcm9tcHRzL2luZGV4LnRzIiwiLi4vc3JjL21vZHVsZXMvX3RlbXBsYXRlL3Jlc291cmNlcy9pbmRleC50cyIsIi4uL3NyYy9tb2R1bGVzL190ZW1wbGF0ZS90ZW1wbGF0ZXMvaW5kZXgudHMiLCIuLi9zcmMvbW9kdWxlcy9fdGVtcGxhdGUvdG9vbHMvaW5kZXgudHMiLCIuLi9zcmMvbW9kdWxlcy9fdGVtcGxhdGUvaW5kZXgudHMiLCIuLi9zcmMvbW9kdWxlcy9pbmRleC50cyIsIi4uL3NyYy9tY3AvbW9kdWxlUmVnaXN0cnkudHMiLCIuLi9zcmMvbWNwL3Byb21wdHMvcHJvbXB0cy50cyIsIi4uL3NyYy9tY3AvcHJvbXB0cy9pbmRleC50cyIsIi4uL3NyYy9tY3AvZGVjb3JhdG9yLXRvb2xzLnRzIiwiLi4vc3JjL21jcC90b29scy9jb2RleC10b29scy50cyIsIi4uL3NyYy9tY3AvdmFsaWRhdGlvbi9zY2FmZm9sZE1vZHVsZS50cyIsIi4uL3NyYy9tY3AvdG9vbHMvZ2VuZXJhdGVNY3BNb2R1bGUudHMiLCIuLi9zcmMvbWNwL3Rvb2xzL2luZGV4LnRzIiwiLi4vc3JjL21jcC9yZXNvdXJjZXMvcmVzb3VyY2VzLnRzIiwiLi4vc3JjL21jcC90ZW1wbGF0ZXMvY29kZXgtdGVtcGxhdGVzLnRzIiwiLi4vc3JjL21jcC90ZW1wbGF0ZXMvcmVzb3VyY2UtdGVtcGxhdGVzLnRzIiwiLi4vc3JjL21jcC90ZW1wbGF0ZXMvd29ya3NwYWNlLXRlbXBsYXRlcy50cyIsIi4uL3NyYy9tY3AvdGVtcGxhdGVzL2luZGV4LnRzIiwiLi4vc3JjL21ldGFkYXRhLnRzIiwiLi4vc3JjL21jcC9tY3AtbW9kdWxlLnRzIiwiLi4vc3JjL21jcC92YWxpZGF0aW9uL2luZGV4LnRzIiwiLi4vc3JjL21jcC9hZ2dyZWdhdGVNb2R1bGVzLnRzIiwiLi4vc3JjL21jcC9mYXN0bWNwLXdpcmluZy50cyIsIi4uL3NyYy9tY3AvaW5kZXgudHMiLCIuLi9zcmMvdXRpbHMvbW9kdWxlUGF0aHMudHMiLCIuLi9zcmMvdXRpbHMudHMiLCIuLi9zcmMvTWNwV3JhcHBlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBkZXNjcmlwdGlvbiBUaGUgZmlsZW5hbWUgdGhhdCBpZGVudGlmaWVzIERlY2FmIENMSSBtb2R1bGVzXG4gKiBAc3VtbWFyeSBUaGUgc3RhbmRhcmQgZmlsZW5hbWUgZm9yIENMSSBtb2R1bGUgZmlsZXMgd2hlcmUgZWFjaCBsaWJyYXJ5IG11c3QgZXhwb3J0IGEgc2luZ2xlIENsaU1vZHVsZSBmdW5jdGlvblxuICpcbiAqIEBjb25zdCBNQ1BfRklMRV9OQU1FXG4gKiBAbWVtYmVyT2YgbW9kdWxlOk1DUFxuICovXG5leHBvcnQgY29uc3QgTUNQX0ZJTEVfTkFNRSA9IFwibWNwLW1vZHVsZVwiO1xuXG5cbmV4cG9ydCBjb25zdCBXT1JLU1BBQ0VfUk9PVF9FTlYgPSBcIk1DUF9XT1JLU1BBQ0VfUk9PVFwiO1xuZXhwb3J0IGNvbnN0IFBST01QVF9ESVJFQ1RPUklFUyA9IFtcIi5jb2RlL3Byb21wdHNcIiwgXCIuY29kZXgvcHJvbXB0c1wiXTtcbmV4cG9ydCBjb25zdCBERUZBVUxUX1BST01QVF9OQU1FID0gXCJkb2NcIjtcbmV4cG9ydCBjb25zdCBDTElFTlRfSU5URUdSQVRJT05TID0gW1xuICB7XG4gICAgaWQ6IFwidnNjb2RlXCIsXG4gICAgZGlzcGxheTogXCJWaXN1YWwgU3R1ZGlvIENvZGVcIixcbiAgICBpbnN0cnVjdGlvbnM6XG4gICAgICBcIldoZW4gaW50ZXJhY3RpbmcgZnJvbSBWaXN1YWwgU3R1ZGlvIENvZGUsIHByZWZlciB0aGUgdnNjb2RlOi8vd29ya3NwYWNlL3twYXRofSByZXNvdXJjZSB0ZW1wbGF0ZSB0byBmZXRjaCBmaWxlIGNvbnRlbnRzIGFuZCB1c2UgdGhlIGFwcGx5LWNvZGUtY2hhbmdlIHRvb2wgdG8gY29tbWl0IGVkaXRzIHdpdGggcHJldmlld2FibGUgZGlmZnMuXCIsXG4gIH0sXG4gIHtcbiAgICBpZDogXCJjdXJzb3JcIixcbiAgICBkaXNwbGF5OiBcIkN1cnNvclwiLFxuICAgIGluc3RydWN0aW9uczpcbiAgICAgIFwiQ3Vyc29yIGNsaWVudHMgY2FuIHJldHJpZXZlIGFuZCB1cGRhdGUgZmlsZXMgdGhyb3VnaCB0aGUgY3Vyc29yOi8vd29ya3NwYWNlL3twYXRofSByZXNvdXJjZSB0ZW1wbGF0ZS4gQWx3YXlzIHZhbGlkYXRlIHBhdGNoZXMgaW4gZHJ5UnVuIG1vZGUgYmVmb3JlIGFwcGx5aW5nIHBlcm1hbmVudCBjaGFuZ2VzLlwiLFxuICB9LFxuICB7XG4gICAgaWQ6IFwiY29waWxvdFwiLFxuICAgIGRpc3BsYXk6IFwiR2l0SHViIENvcGlsb3RcIixcbiAgICBpbnN0cnVjdGlvbnM6XG4gICAgICBcIlVzZSB0aGUgY29waWxvdDovL3dvcmtzcGFjZS97cGF0aH0gcmVzb3VyY2UgdGVtcGxhdGUgdG8gc3RyZWFtIGZpbGUgY29udGVudCBpbnRvIENvcGlsb3QgY2hhdCBzZXNzaW9ucy4gUHJlZmVyIHJldHVybmluZyB1bmlmaWVkIGRpZmZzIHRvIG1haW50YWluIGFsaWdubWVudCB3aXRoIENvcGlsb3QncyBkaWZmIHZpc3VhbGl6YXRpb24uXCIsXG4gIH0sXG5dIGFzIGNvbnN0O1xuIiwiaW1wb3J0IGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IFdPUktTUEFDRV9ST09UX0VOViB9IGZyb20gXCIuLi9jb25zdGFudHNcIjtcblxubGV0IHdvcmtzcGFjZVJvb3QgPSBpbml0aWFsaXplV29ya3NwYWNlUm9vdCgpO1xubGV0IHVzZXJFcnJvckN0b3I6IChuZXcgKG1lc3NhZ2U6IHN0cmluZykgPT4gRXJyb3IpIHwgdW5kZWZpbmVkO1xuXG5leHBvcnQgY2xhc3MgV29ya3NwYWNlRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZykge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIHRoaXMubmFtZSA9IFwiV29ya3NwYWNlRXJyb3JcIjtcbiAgfVxufVxuXG5mdW5jdGlvbiBpbml0aWFsaXplV29ya3NwYWNlUm9vdCgpOiBzdHJpbmcge1xuICBjb25zdCBjb25maWd1cmVkID0gcHJvY2Vzcy5lbnZbV09SS1NQQUNFX1JPT1RfRU5WXTtcbiAgaWYgKGNvbmZpZ3VyZWQgJiYgY29uZmlndXJlZC50cmltKCkubGVuZ3RoID4gMCkge1xuICAgIHJldHVybiBwYXRoLnJlc29sdmUoY29uZmlndXJlZC50cmltKCkpO1xuICB9XG4gIHJldHVybiBwcm9jZXNzLmN3ZCgpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRVc2VyRXJyb3JDdG9yKCk6IFByb21pc2U8bmV3IChtZXNzYWdlOiBzdHJpbmcpID0+IEVycm9yPiB7XG4gIGlmICghdXNlckVycm9yQ3Rvcikge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBtb2QgPSBhd2FpdCBpbXBvcnQoXCJmYXN0bWNwXCIpO1xuICAgICAgdXNlckVycm9yQ3RvciA9IChtb2QgYXMgeyBVc2VyRXJyb3I6IG5ldyAobWVzc2FnZTogc3RyaW5nKSA9PiBFcnJvciB9KVxuICAgICAgICAuVXNlckVycm9yO1xuICAgIH0gY2F0Y2gge1xuICAgICAgdXNlckVycm9yQ3RvciA9IGNsYXNzIE1DUFVzZXJFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgICAgICAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nKSB7XG4gICAgICAgICAgc3VwZXIobWVzc2FnZSk7XG4gICAgICAgICAgdGhpcy5uYW1lID0gXCJNQ1BVc2VyRXJyb3JcIjtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHVzZXJFcnJvckN0b3I7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB0aHJvd1VzZXJFcnJvcihtZXNzYWdlOiBzdHJpbmcpOiBQcm9taXNlPG5ldmVyPiB7XG4gIGNvbnN0IEN0b3IgPSBhd2FpdCBnZXRVc2VyRXJyb3JDdG9yKCk7XG4gIHRocm93IG5ldyBDdG9yKG1lc3NhZ2UpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2V0V29ya3NwYWNlUm9vdChyb290OiBzdHJpbmcpIHtcbiAgd29ya3NwYWNlUm9vdCA9IHBhdGgucmVzb2x2ZShyb290KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFdvcmtzcGFjZVJvb3QoKTogc3RyaW5nIHtcbiAgcmV0dXJuIHdvcmtzcGFjZVJvb3Q7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlSW5Xb3Jrc3BhY2Uocm9vdDogc3RyaW5nLCB0YXJnZXRQYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCByZXNvbHZlZCA9IHBhdGguaXNBYnNvbHV0ZSh0YXJnZXRQYXRoKVxuICAgID8gcGF0aC5ub3JtYWxpemUodGFyZ2V0UGF0aClcbiAgICA6IHBhdGgucmVzb2x2ZShyb290LCB0YXJnZXRQYXRoKTtcblxuICBjb25zdCByZWxhdGl2ZSA9IHBhdGgucmVsYXRpdmUocm9vdCwgcmVzb2x2ZWQpO1xuICBpZiAocmVsYXRpdmUuc3RhcnRzV2l0aChcIi4uXCIpIHx8IHBhdGguaXNBYnNvbHV0ZShyZWxhdGl2ZSkpIHtcbiAgICB0aHJvdyBuZXcgV29ya3NwYWNlRXJyb3IoXG4gICAgICBgUGF0aCAke3RhcmdldFBhdGh9IGVzY2FwZXMgdGhlIHdvcmtzcGFjZSByb290IGF0ICR7cm9vdH1gXG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiByZXNvbHZlZDtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlYWRXb3Jrc3BhY2VGaWxlKFxuICByb290OiBzdHJpbmcsXG4gIHRhcmdldDogc3RyaW5nXG4pOiBQcm9taXNlPHN0cmluZz4ge1xuICB0cnkge1xuICAgIGNvbnN0IGFic29sdXRlID0gcmVzb2x2ZUluV29ya3NwYWNlKHJvb3QsIHRhcmdldCk7XG4gICAgcmV0dXJuIGZzLnJlYWRGaWxlU3luYyhhYnNvbHV0ZSwgXCJ1dGY4XCIgYXMgQnVmZmVyRW5jb2RpbmcpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFdvcmtzcGFjZUVycm9yKSB7XG4gICAgICBhd2FpdCB0aHJvd1VzZXJFcnJvcihlcnJvci5tZXNzYWdlKTtcbiAgICB9XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gX19yZXNldFdvcmtzcGFjZVJvb3Qocm9vdDogc3RyaW5nKSB7XG4gIHNldFdvcmtzcGFjZVJvb3Qocm9vdCk7XG59XG4iLCJleHBvcnQgY29uc3QgcHJvbXB0cyA9IFtdIGFzIGNvbnN0O1xuIiwiZXhwb3J0IGNvbnN0IHJlc291cmNlcyA9IFtcbiAge1xuICAgIFwiaWRcIjogXCJkZWNvcmF0aW9uLnJlcG9cIixcbiAgICBcIm5hbWVcIjogXCJkZWNvcmF0aW9uIHJlcG9zaXRvcnlcIixcbiAgICBcImRlc2NyaXB0aW9uXCI6IFwiU291cmNlIHJlcG9zaXRvcnlcIixcbiAgICBcInVyaVwiOiBcImZpbGU6Ly8vdG1wL21jcC1nZW4teTBrd3U2L2RlY29yYXRpb25cIixcbiAgICBcImFic29sdXRlUGF0aFwiOiBcIi90bXAvbWNwLWdlbi15MGt3dTYvZGVjb3JhdGlvblwiXG4gIH1cbl0gYXMgY29uc3Q7XG4iLCJleHBvcnQgY29uc3QgdGVtcGxhdGVzID0gW1xuICB7XG4gICAgXCJuYW1lXCI6IFwicmVhZG1lLXRlbXBsYXRlXCIsXG4gICAgXCJkZXNjcmlwdGlvblwiOiBcIlJFQURNRSBhcyBndWlkYW5jZVwiLFxuICAgIFwidXJpVGVtcGxhdGVcIjogXCJmaWxlOi8vL3RtcC9tY3AtZ2VuLXkwa3d1Ni9kZWNvcmF0aW9uL1JFQURNRS5tZFwiLFxuICAgIFwibWltZVR5cGVcIjogXCJ0ZXh0L21hcmtkb3duXCJcbiAgfVxuXSBhcyBjb25zdDtcbiIsImltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5cbmV4cG9ydCBjb25zdCBhbmFseXplUmVwb1NjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgcmVwb1BhdGg6IHpcbiAgICAgIC5zdHJpbmcoKVxuICAgICAgLm1pbigxLCBcInJlcG9QYXRoIGlzIHJlcXVpcmVkXCIpXG4gICAgICAuZGVzY3JpYmUoXG4gICAgICAgIFwiUmVsYXRpdmUgb3IgYWJzb2x1dGUgcGF0aCB0byB0aGUgdGFyZ2V0IHJlcG9zaXRvcnkgaW5zaWRlIHRoaXMgbW9ub3JlcG8sIGUuZy4gJy4vZGVjb3JhdGlvbicuXCJcbiAgICAgICksXG4gICAgaW5jbHVkZVRlc3RzOiB6XG4gICAgICAuYm9vbGVhbigpXG4gICAgICAuZGVmYXVsdCh0cnVlKVxuICAgICAgLmRlc2NyaWJlKFxuICAgICAgICBcIklmIHRydWUsIGFuYWx5emUgdGhlIHRlc3RzIGRpcmVjdG9yeSAoaWYgcHJlc2VudCkgdG8gZGVyaXZlIGV4cGVjdGVkIGJlaGF2aW9ycy5cIlxuICAgICAgKSxcbiAgICBpbmNsdWRlRG9jczogelxuICAgICAgLmJvb2xlYW4oKVxuICAgICAgLmRlZmF1bHQodHJ1ZSlcbiAgICAgIC5kZXNjcmliZShcbiAgICAgICAgXCJJZiB0cnVlLCBhbmFseXplIFJFQURNRS5tZCBhbmQgZG9jcyBkaXJlY3RvcmllcyB0byBleHRyYWN0IGRvY3VtZW50ZWQgZmVhdHVyZXMuXCJcbiAgICAgICksXG4gIH0pXG4gIC5zdHJpY3QoKVxuICAuZGVzY3JpYmUoXG4gICAgXCJBbmFseXplIGEgbG9jYWwgcmVwb3NpdG9yeSAoZS5nLiAuL2RlY29yYXRpb24pIHRvIGV4dHJhY3QgQVBJcywgZmVhdHVyZXMsIHRlc3RzLCBhbmQgZG9jdW1lbnRhdGlvbiBjdWVzLlwiXG4gICk7XG5cbmV4cG9ydCBjb25zdCBlbnVtZXJhdGVDYXBhYmlsaXRpZXNTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIHJlcG9QYXRoOiB6XG4gICAgICAuc3RyaW5nKClcbiAgICAgIC5taW4oMSwgXCJyZXBvUGF0aCBpcyByZXF1aXJlZFwiKVxuICAgICAgLmRlc2NyaWJlKFxuICAgICAgICBcIlJlbGF0aXZlIG9yIGFic29sdXRlIHBhdGggdG8gdGhlIHRhcmdldCByZXBvc2l0b3J5IHRvIGVudW1lcmF0ZSBkZXZlbG9wZXItZmFjaW5nIGNhcGFiaWxpdGllcy5cIlxuICAgICAgKSxcbiAgfSlcbiAgLnN0cmljdCgpXG4gIC5kZXNjcmliZShcbiAgICBcIkVudW1lcmF0ZSB0aGUgY29tcGxldGUgc2V0IG9mIGNhcGFiaWxpdGllcyBhIGRldmVsb3BlciBpcyBleHBlY3RlZCB0byB1c2UgZnJvbSB0aGUgZ2l2ZW4gcmVwb3NpdG9yeS5cIlxuICApO1xuXG5leHBvcnQgY29uc3QgcGxhbkZlYXR1cmVTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIGZlYXR1cmU6IHpcbiAgICAgIC5zdHJpbmcoKVxuICAgICAgLm1pbig1LCBcImZlYXR1cmUgbXVzdCBkZXNjcmliZSB0aGUgZ29hbCBjbGVhcmx5XCIpXG4gICAgICAuZGVzY3JpYmUoXG4gICAgICAgIFwiTmF0dXJhbC1sYW5ndWFnZSBkZXNjcmlwdGlvbiBvZiBhIGRldmVsb3BlcidzIHJlcXVlc3RlZCBmZWF0dXJlIG9yIHRhc2sgdG8gaW1wbGVtZW50IHVzaW5nIHRoZSByZXBvc2l0b3J5IGFuZCBhdmFpbGFibGUgTUNQIHRvb2xzLlwiXG4gICAgICApLFxuICAgIHJlcG9QYXRoOiB6XG4gICAgICAuc3RyaW5nKClcbiAgICAgIC5kZWZhdWx0KFwiLi9kZWNvcmF0aW9uXCIpXG4gICAgICAuZGVzY3JpYmUoXG4gICAgICAgIFwiVGFyZ2V0IHJlcG9zaXRvcnkgcGF0aCBwcm92aWRpbmcgdGhlIGxpYnJhcnkgdG8gdXNlLCBlLmcuICcuL2RlY29yYXRpb24nLlwiXG4gICAgICApLFxuICB9KVxuICAuc3RyaWN0KClcbiAgLmRlc2NyaWJlKFxuICAgIFwiUGxhbiB3aGljaCBNQ1AgdG9vbHMgdG8gdXNlIGFuZCBpbiB3aGF0IHNlcXVlbmNlIHRvIGltcGxlbWVudCBhIHJlcXVlc3RlZCBmZWF0dXJlIHVzaW5nIHRoZSByZXBvc2l0b3J5LlwiXG4gICk7XG5cbmV4cG9ydCBjb25zdCBkb2N1bWVudENvZGVTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIGZpbGVQYXRoOiB6LnN0cmluZygpLm1pbigxLCBcImZpbGVQYXRoIGlzIHJlcXVpcmVkXCIpLFxuICAgIHByb21wdE5hbWU6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgICBpbmNsdWRlUHJvbXB0OiB6LmJvb2xlYW4oKS5kZWZhdWx0KHRydWUpLFxuICAgIGluY2x1ZGVDb2RlOiB6LmJvb2xlYW4oKS5kZWZhdWx0KHRydWUpLFxuICAgIGluY2x1ZGVNZXRhZGF0YTogei5ib29sZWFuKCkuZGVmYXVsdCh0cnVlKSxcbiAgICBhZGRpdGlvbmFsQ29udGV4dDogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICAgIGVuY29kaW5nOiB6LnN0cmluZygpLmRlZmF1bHQoXCJ1dGY4XCIpLFxuICB9KVxuICAuc3RyaWN0KCk7XG5cbmV4cG9ydCBjb25zdCBjb2RlQ2hhbmdlU2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICBmaWxlUGF0aDogei5zdHJpbmcoKS5taW4oMSwgXCJmaWxlUGF0aCBpcyByZXF1aXJlZFwiKSxcbiAgICBwYXRjaDogei5zdHJpbmcoKS5taW4oMSwgXCJwYXRjaCBpcyByZXF1aXJlZFwiKSxcbiAgICBkcnlSdW46IHouYm9vbGVhbigpLmRlZmF1bHQoZmFsc2UpLFxuICAgIHNob3dEaWZmOiB6LmJvb2xlYW4oKS5kZWZhdWx0KHRydWUpLFxuICAgIGRpZmZDb250ZXh0OiB6Lm51bWJlcigpLmludCgpLm1pbigwKS5tYXgoMTAwKS5kZWZhdWx0KDMpLFxuICAgIGVuY29kaW5nOiB6LnN0cmluZygpLmRlZmF1bHQoXCJ1dGY4XCIpLFxuICB9KVxuICAuc3RyaWN0KCk7XG5cbmNvbnN0IE9CSkVDVF9UWVBFUyA9IFtcbiAgXCJtb2R1bGVcIixcbiAgXCJmaWxlXCIsXG4gIFwiY2xhc3NcIixcbiAgXCJmdW5jdGlvblwiLFxuICBcImludGVyZmFjZVwiLFxuICBcImRlY29yYXRvclwiLFxuICBcImNvbnN0YW50XCIsXG5dIGFzIGNvbnN0O1xuXG5leHBvcnQgY29uc3QgZG9jdW1lbnRPYmplY3RTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIGJhc2VQYXRoOiB6LnN0cmluZygpLm1pbigxLCBcImJhc2VQYXRoIGlzIHJlcXVpcmVkXCIpLFxuICAgIG9iamVjdFR5cGU6IHouZW51bShPQkpFQ1RfVFlQRVMpLFxuICAgIHRhcmdldEZpbGU6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgICBpbmNsdWRlQ29udGVudDogei5ib29sZWFuKCkuZGVmYXVsdChmYWxzZSksXG4gIH0pXG4gIC5zdHJpY3QoKTtcblxuZXhwb3J0IGNvbnN0IGNvdmVyYWdlVGFza1NjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgYmFzZVBhdGg6IHouc3RyaW5nKCkubWluKDEsIFwiYmFzZVBhdGggaXMgcmVxdWlyZWRcIiksXG4gICAgY292ZXJhZ2U6IHpcbiAgICAgIC5udW1iZXIoKVxuICAgICAgLm1pbigwKVxuICAgICAgLm1heCgxMDApXG4gICAgICAuZGVmYXVsdCg5MClcbiAgICAgIC5kZXNjcmliZShcIlRhcmdldCBjb3ZlcmFnZSBwZXJjZW50YWdlXCIpLFxuICAgIGRyeVJ1bjogei5ib29sZWFuKCkuZGVmYXVsdChmYWxzZSksXG4gIH0pXG4gIC5zdHJpY3QoKTtcblxuZXhwb3J0IGNvbnN0IHJlYWRtZUltcHJvdmVtZW50U2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICBiYXNlUGF0aDogei5zdHJpbmcoKS5taW4oMSwgXCJiYXNlUGF0aCBpcyByZXF1aXJlZFwiKSxcbiAgICBpbmNsdWRlRXhhbXBsZXM6IHouYm9vbGVhbigpLmRlZmF1bHQodHJ1ZSksXG4gIH0pXG4gIC5zdHJpY3QoKTtcbiIsImltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBhbmFseXplUmVwbyB9IGZyb20gXCIuL2NvZGVcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIHJlYWRGaWxlU2FmZShcbiAgZmlsZVBhdGg6IHN0cmluZyxcbiAgZW5jb2Rpbmc6IEJ1ZmZlckVuY29kaW5nID0gXCJ1dGY4XCJcbik6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGZzLnJlYWRGaWxlU3luYyhmaWxlUGF0aCwgeyBlbmNvZGluZyB9KTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gbGlzdEZpbGVzUmVjdXJzaXZlKFxuICByb290OiBzdHJpbmcsXG4gIG1hdGNoZXI/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+Q2xpZW50OiByZXN1bHRcbiAgICovXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgYXN5bmMgcnVuKGFyZ3M6IHN0cmluZ1tdID0gcHJvY2Vzcy5hcmd2KSB7XG4gICAgY29uc3Qgc2VydmVyID0gYXdhaXQgdGhpcy5ib290KCk7XG4gICAgYXdhaXQgc2VydmVyLnN0YXJ0KHsgdHJhbnNwb3J0VHlwZTogXCJzdGRpb1wiIH0pO1xuICB9XG59XG4iXSwibmFtZXMiOlsicHJvbXB0cyIsInJlc291cmNlcyIsInRlbXBsYXRlcyIsInoiLCJhcHBseVBhdGNoIiwiY3JlYXRlVHdvRmlsZXNQYXRjaCIsInRvb2xMaXN0IiwidG9vbHMiLCJtb2R1bGVQYWNrYWdlIiwiZGVjb3JhdGlvbk1vZHVsZSIsIm1jcE1vZHVsZSIsInRlbXBsYXRlTW9kdWxlIiwic3Bhd25TeW5jIiwiY29yZVRvb2xMaXN0IiwiVkVSU0lPTiIsIlBBQ0tBR0VfTkFNRSIsIk1ldGFkYXRhIiwiUEtHIiwiViIsInBhdGhUb0ZpbGVVUkwiLCJwYXRoIiwiZnMiLCJMb2dnZWRDbGFzcyIsIkZhc3RNQ1AiXSwibWFwcGluZ3MiOiI7Ozs7OztJQUFBOzs7Ozs7SUFNRztBQUNJLFVBQU0sYUFBYSxHQUFHO0FBR3RCLFVBQU0sa0JBQWtCLEdBQUc7VUFDckIsa0JBQWtCLEdBQUcsQ0FBQyxlQUFlLEVBQUUsZ0JBQWdCO0FBQzdELFVBQU0sbUJBQW1CLEdBQUc7QUFDNUIsVUFBTSxtQkFBbUIsR0FBRztJQUNqQyxJQUFBO0lBQ0UsUUFBQSxFQUFFLEVBQUUsUUFBUTtJQUNaLFFBQUEsT0FBTyxFQUFFLG9CQUFvQjtJQUM3QixRQUFBLFlBQVksRUFDVixvTUFBb007SUFDdk0sS0FBQTtJQUNELElBQUE7SUFDRSxRQUFBLEVBQUUsRUFBRSxRQUFRO0lBQ1osUUFBQSxPQUFPLEVBQUUsUUFBUTtJQUNqQixRQUFBLFlBQVksRUFDVixpTEFBaUw7SUFDcEwsS0FBQTtJQUNELElBQUE7SUFDRSxRQUFBLEVBQUUsRUFBRSxTQUFTO0lBQ2IsUUFBQSxPQUFPLEVBQUUsZ0JBQWdCO0lBQ3pCLFFBQUEsWUFBWSxFQUNWLGlNQUFpTTtJQUNwTSxLQUFBOzs7SUMzQkgsSUFBSSxhQUFhLEdBQUcsdUJBQXVCLEVBQUU7SUFDN0MsSUFBSSxhQUEyRDtJQUV6RCxNQUFPLGNBQWUsU0FBUSxLQUFLLENBQUE7SUFDdkMsSUFBQSxXQUFBLENBQVksT0FBZSxFQUFBO1lBQ3pCLEtBQUssQ0FBQyxPQUFPLENBQUM7SUFDZCxRQUFBLElBQUksQ0FBQyxJQUFJLEdBQUcsZ0JBQWdCO1FBQzlCO0lBQ0Q7SUFFRCxTQUFTLHVCQUF1QixHQUFBO1FBQzlCLE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsa0JBQWtCLENBQUM7UUFDbEQsSUFBSSxVQUFVLElBQUksVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7WUFDOUMsT0FBTyxJQUFJLENBQUMs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