@decaf-ts/mcp-server 0.0.2 → 0.0.4

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 (93) hide show
  1. package/LICENSE.md +86 -21
  2. package/README.md +13 -13
  3. package/dist/mcp-server.cjs +893 -187
  4. package/dist/mcp-server.esm.cjs +888 -180
  5. package/lib/McpWrapper.cjs +189 -0
  6. package/lib/McpWrapper.d.ts +101 -0
  7. package/lib/bin/cli.cjs +30 -54
  8. package/lib/bin/cli.d.ts +18 -44
  9. package/lib/constants.cjs +12 -0
  10. package/lib/constants.d.ts +8 -0
  11. package/lib/esm/McpWrapper.d.ts +101 -0
  12. package/lib/esm/McpWrapper.js +182 -0
  13. package/lib/esm/bin/cli.d.ts +18 -44
  14. package/lib/esm/bin/cli.js +28 -55
  15. package/lib/esm/constants.d.ts +8 -0
  16. package/lib/esm/constants.js +9 -0
  17. package/lib/esm/index.d.ts +5 -26
  18. package/lib/esm/index.js +6 -27
  19. package/lib/esm/mcp/index.d.ts +1 -0
  20. package/lib/esm/mcp/index.js +2 -0
  21. package/lib/esm/metadata.d.ts +9 -0
  22. package/lib/esm/metadata.js +22 -0
  23. package/lib/esm/modules/decoration/index.d.ts +0 -0
  24. package/lib/esm/modules/decoration/index.js +2 -0
  25. package/lib/esm/modules/mcp/decoration-assist.d.ts +39 -0
  26. package/lib/esm/modules/mcp/decoration-assist.js +353 -0
  27. package/lib/esm/modules/mcp/decorator-tools.d.ts +118 -0
  28. package/lib/esm/modules/mcp/decorator-tools.js +237 -0
  29. package/lib/esm/modules/mcp/index.d.ts +2 -0
  30. package/lib/esm/modules/mcp/index.js +3 -0
  31. package/lib/esm/modules/mcp/mcp-module.d.ts +230 -0
  32. package/lib/esm/modules/mcp/mcp-module.js +406 -0
  33. package/lib/esm/types.d.ts +15 -0
  34. package/lib/esm/types.js +2 -0
  35. package/lib/esm/utils.d.ts +54 -13
  36. package/lib/esm/utils.js +78 -15
  37. package/lib/index.cjs +6 -28
  38. package/lib/index.d.ts +5 -26
  39. package/lib/mcp/index.cjs +17 -0
  40. package/lib/mcp/index.d.ts +1 -0
  41. package/lib/metadata.cjs +25 -0
  42. package/lib/metadata.d.ts +9 -0
  43. package/lib/modules/decoration/index.cjs +2 -0
  44. package/lib/modules/decoration/index.d.ts +0 -0
  45. package/lib/modules/mcp/decoration-assist.cjs +360 -0
  46. package/lib/modules/mcp/decoration-assist.d.ts +39 -0
  47. package/lib/modules/mcp/decorator-tools.cjs +243 -0
  48. package/lib/modules/mcp/decorator-tools.d.ts +118 -0
  49. package/lib/modules/mcp/index.cjs +24 -0
  50. package/lib/modules/mcp/index.d.ts +2 -0
  51. package/lib/modules/mcp/mcp-module.cjs +452 -0
  52. package/lib/modules/mcp/mcp-module.d.ts +230 -0
  53. package/lib/types.cjs +3 -0
  54. package/lib/types.d.ts +15 -0
  55. package/lib/utils.cjs +116 -16
  56. package/lib/utils.d.ts +54 -13
  57. package/package.json +35 -7
  58. package/lib/esm/namespace/Class.d.ts +0 -74
  59. package/lib/esm/namespace/Class.js +0 -73
  60. package/lib/esm/namespace/Interface.d.ts +0 -17
  61. package/lib/esm/namespace/Interface.js +0 -2
  62. package/lib/esm/namespace/children/ChildClass.d.ts +0 -44
  63. package/lib/esm/namespace/children/ChildClass.js +0 -43
  64. package/lib/esm/namespace/children/ChildInterface.d.ts +0 -22
  65. package/lib/esm/namespace/children/ChildInterface.js +0 -2
  66. package/lib/esm/namespace/children/Enum.d.ts +0 -14
  67. package/lib/esm/namespace/children/Enum.js +0 -16
  68. package/lib/esm/namespace/children/function.d.ts +0 -31
  69. package/lib/esm/namespace/children/function.js +0 -33
  70. package/lib/esm/namespace/children/index.d.ts +0 -25
  71. package/lib/esm/namespace/children/index.js +0 -26
  72. package/lib/esm/namespace/index.d.ts +0 -18
  73. package/lib/esm/namespace/index.js +0 -19
  74. package/lib/esm/namespace/type.d.ts +0 -28
  75. package/lib/esm/namespace/type.js +0 -2
  76. package/lib/namespace/Class.cjs +0 -77
  77. package/lib/namespace/Class.d.ts +0 -74
  78. package/lib/namespace/Interface.cjs +0 -3
  79. package/lib/namespace/Interface.d.ts +0 -17
  80. package/lib/namespace/children/ChildClass.cjs +0 -47
  81. package/lib/namespace/children/ChildClass.d.ts +0 -44
  82. package/lib/namespace/children/ChildInterface.cjs +0 -3
  83. package/lib/namespace/children/ChildInterface.d.ts +0 -22
  84. package/lib/namespace/children/Enum.cjs +0 -19
  85. package/lib/namespace/children/Enum.d.ts +0 -14
  86. package/lib/namespace/children/function.cjs +0 -36
  87. package/lib/namespace/children/function.d.ts +0 -31
  88. package/lib/namespace/children/index.cjs +0 -42
  89. package/lib/namespace/children/index.d.ts +0 -25
  90. package/lib/namespace/index.cjs +0 -35
  91. package/lib/namespace/index.d.ts +0 -18
  92. package/lib/namespace/type.cjs +0 -3
  93. package/lib/namespace/type.d.ts +0 -28
@@ -1,218 +1,926 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { applyPatch, createTwoFilesPatch } from 'diff';
4
+ import { z } from 'zod';
5
+ import { Metadata } from '@decaf-ts/decoration';
6
+ import { FastMCP } from 'fastmcp';
7
+ import { LoggedClass } from '@decaf-ts/logging';
8
+
1
9
  /**
2
- * @function complexFunction
3
- * @description This function takes an optional string argument and concatenates it with "Hello World".
4
- * @summary Concatenates "Hello World" with a given string. Despite its name, it's a simple string concatenation operation.
5
- *
6
- * @param {string} [arg1="default"] - The string to append to "Hello World". If not provided, defaults to "default".
7
- * @return {string} The resulting concatenated string
8
- *
9
- * @example
10
- * // returns "Hello Worlddefault"
11
- * complexFunction();
12
- *
13
- * @example
14
- * // returns "Hello World!"
15
- * complexFunction("!");
16
- *
17
- * @memberOf module:ts-workspace
10
+ * @const VERSION
11
+ * @name VERSION
12
+ * @description Represents the current version of the ts-workspace module.
13
+ * @summary The actual version number is replaced during the build process.
14
+ * @type {string}
18
15
  */
19
- function complexFunction(arg1 = "default") {
20
- return "Hello World" + arg1;
16
+ const VERSION$1 = "0.0.3";
17
+ const PACKAGE_NAME$1 = "##PACKAGE_NAME##";
18
+ try {
19
+ Metadata.registerLibrary(PACKAGE_NAME$1, VERSION$1);
20
+ }
21
+ catch (error) {
22
+ if (error instanceof Error && error.message.includes("already")) ;
23
+ else {
24
+ throw error;
25
+ }
26
+ }
27
+
28
+ function escapeRegExp(value) {
29
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
30
+ }
31
+ function formatDecorator(spec) {
32
+ const args = (spec.args || []).map((arg) => JSON.stringify(arg)).join(", ");
33
+ return `@${spec.name}(${args})`;
34
+ }
35
+ function ensureDirectory(filePath) {
36
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
37
+ }
38
+ function collectDecoratorNames(classDecorators, properties) {
39
+ const names = new Set();
40
+ names.add("model");
41
+ for (const decorator of classDecorators || []) {
42
+ names.add(decorator.name);
43
+ }
44
+ for (const property of properties || []) {
45
+ for (const decorator of property.decorators || []) {
46
+ names.add(decorator.name);
47
+ }
48
+ }
49
+ return names;
50
+ }
51
+ function ensureImport(content, importsFrom, decorators) {
52
+ /* istanbul ignore next */
53
+ if (!decorators.size)
54
+ return content;
55
+ const importRegex = new RegExp(`import\\s+\\{([^}]+)\\}\\s+from\\s+["']${escapeRegExp(importsFrom)}["'];`);
56
+ const match = content.match(importRegex);
57
+ const sorted = Array.from(decorators).sort();
58
+ if (match) {
59
+ const existing = match[1]
60
+ .split(",")
61
+ .map((name) => name.trim())
62
+ .filter(Boolean);
63
+ const merged = Array.from(new Set([...existing, ...sorted])).sort();
64
+ return content.replace(importRegex, `import { ${merged.join(", ")} } from "${importsFrom}";`);
65
+ }
66
+ const importLine = `import { ${sorted.join(", ")} } from "${importsFrom}";`;
67
+ return `${importLine}\n\n${content}`;
68
+ }
69
+ function addPropertyBlock(property) {
70
+ const decorators = (property.decorators || [])
71
+ .map(formatDecorator)
72
+ .join("\n ");
73
+ const decoratorBlock = decorators ? ` ${decorators}\n` : "";
74
+ return `${decoratorBlock} ${property.name}: ${property.type};`;
75
+ }
76
+ function removePropertyBlock(content, propertyName) {
77
+ const lines = content.split(/\r?\n/);
78
+ const result = [];
79
+ for (let i = 0; i < lines.length; i++) {
80
+ const line = lines[i];
81
+ if (line.trim().startsWith(`@`) &&
82
+ lines[i + 1]?.includes(`${propertyName}:`)) {
83
+ continue;
84
+ }
85
+ if (line.includes(`${propertyName}:`)) {
86
+ // skip this line and any trailing blank line
87
+ continue;
88
+ }
89
+ result.push(line);
90
+ }
91
+ return result.join("\n");
92
+ }
93
+ function insertDecorator(content, decorator, target) {
94
+ const decoratorLine = formatDecorator(decorator);
95
+ if (target.kind === "class") {
96
+ const classRegex = /(export\s+class\s+[^\s{]+\s*\{)/;
97
+ if (content.includes(decoratorLine))
98
+ return content;
99
+ return content.replace(classRegex, `${decoratorLine}\n$1`);
100
+ }
101
+ if (!target.name)
102
+ return content;
103
+ const propertyRegex = new RegExp(`(^\\s*)(?:@.*\\n\\1)*${escapeRegExp(target.name)}:`, "m");
104
+ const match = propertyRegex.exec(content);
105
+ if (!match)
106
+ return content;
107
+ const indent = match[1] || " ";
108
+ if (content.includes(`${indent}${decoratorLine}`))
109
+ return content;
110
+ return (content.slice(0, match.index) +
111
+ `${indent}${decoratorLine}\n` +
112
+ content.slice(match.index));
113
+ }
114
+ function removeDecorator(content, decoratorName, target) {
115
+ const decoratorRegex = new RegExp(`^\\s*@${escapeRegExp(decoratorName)}\\([^)]*\\)`, "m");
116
+ if (target.kind === "class") {
117
+ return content.replace(decoratorRegex, "");
118
+ }
119
+ if (target.name) {
120
+ const pattern = new RegExp(`(^\\s*@${escapeRegExp(decoratorName)}\\([^)]*\\)\\s*$\\n)(?=\\s*${escapeRegExp(target.name)}:)`, "m");
121
+ return content.replace(pattern, "");
122
+ }
123
+ return content;
124
+ }
125
+ function writeIfChanged(filePath, content) {
126
+ ensureDirectory(filePath);
127
+ fs.writeFileSync(filePath, content);
128
+ }
129
+ const decoratorTools = {
130
+ createOrUpdateModelTool: {
131
+ name: "create-or-update-model",
132
+ description: "Create or update a validation-ready model class",
133
+ execute: async (args) => {
134
+ if (!args.overwrite && fs.existsSync(args.filePath)) {
135
+ throw new Error(`File already exists at ${args.filePath}`);
136
+ }
137
+ const decorators = collectDecoratorNames(args.classDecorators, args.properties);
138
+ let content = `@model()`;
139
+ for (const decorator of args.classDecorators || []) {
140
+ content += `\n${formatDecorator(decorator)}`;
141
+ }
142
+ const properties = (args.properties || [])
143
+ .map(addPropertyBlock)
144
+ .join("\n\n");
145
+ content += `\nexport class ${args.className} {\n${properties ? `${properties}\n` : ""}}\n`;
146
+ content = ensureImport(content, args.importsFrom, decorators);
147
+ writeIfChanged(args.filePath, content);
148
+ return { filePath: args.filePath };
149
+ },
150
+ },
151
+ addAttributeTool: {
152
+ name: "add-attribute",
153
+ description: "Add a decorated attribute to an existing model",
154
+ execute: async (args) => {
155
+ if (!fs.existsSync(args.filePath)) {
156
+ throw new Error(`Model file not found at ${args.filePath}`);
157
+ }
158
+ let content = fs.readFileSync(args.filePath, "utf8");
159
+ if (content.includes(`${args.attribute.name}:`)) {
160
+ return { filePath: args.filePath };
161
+ }
162
+ const decorators = collectDecoratorNames(undefined, [args.attribute]);
163
+ content = ensureImport(content, args.importsFrom, decorators);
164
+ const insertionPoint = content.lastIndexOf("}");
165
+ const block = addPropertyBlock(args.attribute);
166
+ const before = content.slice(0, insertionPoint).replace(/\s*$/, "");
167
+ const after = content.slice(insertionPoint);
168
+ const updated = `${before}\n${block}\n${after}`;
169
+ writeIfChanged(args.filePath, updated);
170
+ return { filePath: args.filePath };
171
+ },
172
+ },
173
+ removeAttributeTool: {
174
+ name: "remove-attribute",
175
+ description: "Remove an attribute from a model class",
176
+ execute: async (args) => {
177
+ if (!fs.existsSync(args.filePath))
178
+ return { filePath: args.filePath };
179
+ const content = fs.readFileSync(args.filePath, "utf8");
180
+ const updated = removePropertyBlock(content, args.attributeName);
181
+ writeIfChanged(args.filePath, updated);
182
+ return { filePath: args.filePath };
183
+ },
184
+ },
185
+ applyDecoratorTool: {
186
+ name: "apply-decorator",
187
+ description: "Apply a decorator to a class or property",
188
+ execute: async (args) => {
189
+ if (!fs.existsSync(args.filePath)) {
190
+ throw new Error(`Model file not found at ${args.filePath}`);
191
+ }
192
+ let content = fs.readFileSync(args.filePath, "utf8");
193
+ const decorators = new Set([args.decorator.name]);
194
+ content = ensureImport(content, args.importsFrom, decorators);
195
+ content = insertDecorator(content, args.decorator, args.target);
196
+ writeIfChanged(args.filePath, content);
197
+ return { filePath: args.filePath };
198
+ },
199
+ },
200
+ removeDecoratorTool: {
201
+ name: "remove-decorator",
202
+ description: "Remove a decorator from a class or property",
203
+ execute: async (args) => {
204
+ if (!fs.existsSync(args.filePath))
205
+ return { filePath: args.filePath };
206
+ let content = fs.readFileSync(args.filePath, "utf8");
207
+ content = removeDecorator(content, args.decoratorName, args.target);
208
+ writeIfChanged(args.filePath, content);
209
+ return { filePath: args.filePath };
210
+ },
211
+ },
212
+ scaffoldValidatorTool: {
213
+ name: "scaffold-validator",
214
+ description: "Scaffold a validator class and optional decorator",
215
+ execute: async (args) => {
216
+ const classFile = path.join(args.validatorsDir, `${args.name}.ts`);
217
+ ensureDirectory(classFile);
218
+ const classContent = `export class ${args.name} {\n validate(value: unknown): boolean {\n return value !== undefined;\n }\n}\n`;
219
+ fs.writeFileSync(classFile, classContent);
220
+ let decoratorFile;
221
+ if (args.decoratorDir) {
222
+ decoratorFile = path.join(args.decoratorDir, `${args.name}Decorator.ts`);
223
+ ensureDirectory(decoratorFile);
224
+ fs.writeFileSync(decoratorFile, `export function ${args.name}Decorator() {\n return () => void 0;\n}\n`);
225
+ }
226
+ return { classFile, decoratorFile };
227
+ },
228
+ },
229
+ scaffoldSerializerTool: {
230
+ name: "scaffold-serializer",
231
+ description: "Scaffold a serializer class and optional registry",
232
+ execute: async (args) => {
233
+ const classFile = path.join(args.dir, `${args.name}.ts`);
234
+ ensureDirectory(classFile);
235
+ fs.writeFileSync(classFile, `export class ${args.name} {\n serialize(value: unknown): string {\n return JSON.stringify(value);\n }\n}\n`);
236
+ let registerFile;
237
+ if (args.registerDir) {
238
+ registerFile = path.join(args.registerDir, `${args.name}Register.ts`);
239
+ ensureDirectory(registerFile);
240
+ fs.writeFileSync(registerFile, `export function register${args.name}() {\n return ${args.setDefault ? "'default'" : "'optional'"};\n}\n`);
241
+ }
242
+ return { classFile, registerFile };
243
+ },
244
+ },
245
+ scaffoldHashingTool: {
246
+ name: "scaffold-hashing",
247
+ description: "Scaffold a hashing function and optional registry",
248
+ execute: async (args) => {
249
+ const functionFile = path.join(args.dir, `${args.name}.ts`);
250
+ ensureDirectory(functionFile);
251
+ fs.writeFileSync(functionFile, `export function ${args.name}(value: string): string {\n return value.split('').reverse().join('');\n}\n`);
252
+ let registerFile;
253
+ if (args.registerDir) {
254
+ registerFile = path.join(args.registerDir, `${args.name}Register.ts`);
255
+ ensureDirectory(registerFile);
256
+ fs.writeFileSync(registerFile, `export function register${args.name}() {\n return ${args.setDefault ? "'default'" : "'optional'"};\n}\n`);
257
+ }
258
+ return { functionFile, registerFile };
259
+ },
260
+ },
261
+ };
262
+
263
+ const WORKSPACE_ROOT_ENV = "MCP_WORKSPACE_ROOT";
264
+ const PROMPT_DIRECTORIES = [".code/prompts", ".codex/prompts"];
265
+ const DEFAULT_PROMPT_NAME = "doc";
266
+ const CLIENT_INTEGRATIONS = [
267
+ {
268
+ id: "vscode",
269
+ display: "Visual Studio Code",
270
+ 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.",
271
+ },
272
+ {
273
+ id: "cursor",
274
+ display: "Cursor",
275
+ 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.",
276
+ },
277
+ {
278
+ id: "copilot",
279
+ display: "GitHub Copilot",
280
+ 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.",
281
+ },
282
+ ];
283
+ const documentCodeSchema = z
284
+ .object({
285
+ filePath: z.string().min(1, "filePath is required"),
286
+ promptName: z.string().optional(),
287
+ includePrompt: z.boolean().default(true),
288
+ includeCode: z.boolean().default(true),
289
+ includeMetadata: z.boolean().default(true),
290
+ additionalContext: z.string().optional(),
291
+ encoding: z.string().default("utf8"),
292
+ })
293
+ .strict();
294
+ const codeChangeSchema = z
295
+ .object({
296
+ filePath: z.string().min(1, "filePath is required"),
297
+ patch: z.string().min(1, "patch is required"),
298
+ dryRun: z.boolean().default(false),
299
+ showDiff: z.boolean().default(true),
300
+ diffContext: z.number().int().min(0).max(100).default(3),
301
+ encoding: z.string().default("utf8"),
302
+ })
303
+ .strict();
304
+ let workspaceRoot = initializeWorkspaceRoot();
305
+ let userErrorCtor;
306
+ class WorkspaceError extends Error {
307
+ constructor(message) {
308
+ super(message);
309
+ this.name = "WorkspaceError";
310
+ }
311
+ }
312
+ async function getUserErrorCtor() {
313
+ if (!userErrorCtor) {
314
+ try {
315
+ const mod = await import('fastmcp');
316
+ userErrorCtor = mod
317
+ .UserError;
318
+ }
319
+ catch {
320
+ userErrorCtor = class MCPUserError extends Error {
321
+ constructor(message) {
322
+ super(message);
323
+ this.name = "MCPUserError";
324
+ }
325
+ };
326
+ }
327
+ }
328
+ return userErrorCtor;
329
+ }
330
+ async function throwUserError(message) {
331
+ const Ctor = await getUserErrorCtor();
332
+ throw new Ctor(message);
333
+ }
334
+ const documentCodeTool = {
335
+ annotations: {
336
+ idempotentHint: true,
337
+ openWorldHint: false,
338
+ readOnlyHint: true,
339
+ title: "Document Source File",
340
+ },
341
+ description: "Generate documentation guidance for a file by combining repository prompts with the target source code.",
342
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
343
+ execute: async (input, _context) => {
344
+ const args = documentCodeSchema.parse(input);
345
+ const root = getWorkspaceRoot();
346
+ let filePath;
347
+ try {
348
+ filePath = resolveInWorkspace(root, args.filePath);
349
+ }
350
+ catch (error) {
351
+ if (error instanceof WorkspaceError) {
352
+ return throwUserError(error.message);
353
+ }
354
+ /* istanbul ignore next */
355
+ throw error;
356
+ }
357
+ if (!fs.existsSync(filePath)) {
358
+ return throwUserError(`Cannot document missing file at ${args.filePath}`);
359
+ }
360
+ const fileContent = fs.readFileSync(filePath, {
361
+ encoding: args.encoding,
362
+ });
363
+ const prompts = discoverDocPrompts(root);
364
+ if (!prompts.length) {
365
+ return throwUserError("No documentation prompts found under .code/prompts or .codex/prompts");
366
+ }
367
+ const prompt = selectPrompt(prompts, args.promptName ?? DEFAULT_PROMPT_NAME);
368
+ return buildDocumentationPayload({
369
+ filePath: args.filePath,
370
+ fileContent,
371
+ prompt,
372
+ includeCode: args.includeCode,
373
+ includePrompt: args.includePrompt,
374
+ includeMetadata: args.includeMetadata,
375
+ additionalContext: args.additionalContext,
376
+ });
377
+ },
378
+ name: "document-code",
379
+ parameters: documentCodeSchema,
380
+ };
381
+ const applyCodeChangeTool = {
382
+ annotations: {
383
+ destructiveHint: true,
384
+ idempotentHint: false,
385
+ openWorldHint: false,
386
+ readOnlyHint: false,
387
+ title: "Apply Code Patch",
388
+ },
389
+ description: "Apply a unified diff patch to a workspace file with optional dry-run validation and diff preview.",
390
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
391
+ execute: async (input, _context) => {
392
+ const args = codeChangeSchema.parse(input);
393
+ const root = getWorkspaceRoot();
394
+ let filePath;
395
+ try {
396
+ filePath = resolveInWorkspace(root, args.filePath);
397
+ }
398
+ catch (error) {
399
+ if (error instanceof WorkspaceError) {
400
+ return throwUserError(error.message);
401
+ }
402
+ throw error;
403
+ }
404
+ const original = fs.existsSync(filePath)
405
+ ? fs.readFileSync(filePath, args.encoding)
406
+ : "";
407
+ let patched;
408
+ try {
409
+ patched = applyPatch(original, args.patch);
410
+ }
411
+ catch (error) {
412
+ return throwUserError(`Failed to apply provided patch to ${args.filePath}: ${error instanceof Error ? error.message : error}`);
413
+ }
414
+ /* istanbul ignore next */
415
+ if (patched === false) {
416
+ return throwUserError(`Failed to apply provided patch to ${args.filePath}`);
417
+ }
418
+ if (!args.dryRun) {
419
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
420
+ fs.writeFileSync(filePath, patched, {
421
+ encoding: args.encoding,
422
+ });
423
+ }
424
+ if (!args.showDiff) {
425
+ return `Patch ${args.dryRun ? "validated" : "applied"} for ${args.filePath}`;
426
+ }
427
+ const preview = createTwoFilesPatch(args.filePath, args.filePath, original, patched, undefined, undefined, { context: args.diffContext });
428
+ return {
429
+ content: [
430
+ {
431
+ type: "text",
432
+ text: `Patch ${args.dryRun ? "validated" : "applied"} for ${args.filePath}`,
433
+ },
434
+ {
435
+ type: "text",
436
+ text: ["```diff", preview.trim(), "```"].join("\n"),
437
+ },
438
+ ],
439
+ };
440
+ },
441
+ name: "apply-code-change",
442
+ parameters: codeChangeSchema,
443
+ };
444
+ const tools = {
445
+ ...decoratorTools,
446
+ documentCodeTool,
447
+ applyCodeChangeTool,
448
+ };
449
+ function enrich(mcp) {
450
+ for (const prompt of buildDocPrompts()) {
451
+ mcp.addPrompt(prompt);
452
+ }
453
+ for (const tool of Object.values(tools)) {
454
+ mcp.addTool(tool);
455
+ }
456
+ for (const template of buildResourceTemplates()) {
457
+ mcp.addResourceTemplate(template);
458
+ }
459
+ return mcp;
460
+ }
461
+ const PACKAGE_NAME = PACKAGE_NAME$1;
462
+ const VERSION = VERSION$1;
463
+ function setWorkspaceRoot(root) {
464
+ workspaceRoot = path.resolve(root);
465
+ }
466
+ function getWorkspaceRoot() {
467
+ return workspaceRoot;
468
+ }
469
+ function buildResourceTemplates() {
470
+ const root = getWorkspaceRoot();
471
+ const sharedArguments = [
472
+ {
473
+ name: "path",
474
+ description: "Path relative to the workspace root",
475
+ required: true,
476
+ },
477
+ ];
478
+ return [
479
+ {
480
+ name: "vscode-workspace-file",
481
+ description: "Expose workspace files to Visual Studio Code via vscode:// URIs",
482
+ uriTemplate: "vscode://workspace/{path}",
483
+ mimeType: "text/plain",
484
+ arguments: sharedArguments,
485
+ load: async (args) => {
486
+ const text = await readWorkspaceFile(root, args.path);
487
+ return { text };
488
+ },
489
+ },
490
+ {
491
+ name: "cursor-workspace-file",
492
+ description: "Expose workspace files to Cursor via cursor:// URIs",
493
+ uriTemplate: "cursor://workspace/{path}",
494
+ mimeType: "text/plain",
495
+ arguments: sharedArguments,
496
+ load: async (args) => {
497
+ const text = await readWorkspaceFile(root, args.path);
498
+ return { text };
499
+ },
500
+ },
501
+ {
502
+ name: "copilot-workspace-file",
503
+ description: "Expose workspace files to GitHub Copilot via copilot:// URIs",
504
+ uriTemplate: "copilot://workspace/{path}",
505
+ mimeType: "text/plain",
506
+ arguments: sharedArguments,
507
+ load: async (args) => {
508
+ const text = await readWorkspaceFile(root, args.path);
509
+ return { text };
510
+ },
511
+ },
512
+ ];
513
+ }
514
+ function initializeWorkspaceRoot() {
515
+ const configured = process.env[WORKSPACE_ROOT_ENV];
516
+ if (configured && configured.trim().length > 0) {
517
+ return path.resolve(configured.trim());
518
+ }
519
+ return process.cwd();
520
+ }
521
+ function buildDocPrompts() {
522
+ const root = getWorkspaceRoot();
523
+ const fileBasedPrompts = discoverDocPrompts(root).map((prompt) => ({
524
+ name: `doc/${prompt.name}`,
525
+ description: prompt.description,
526
+ load: async () => prompt.content,
527
+ }));
528
+ const integrationPrompts = CLIENT_INTEGRATIONS.map((integration) => ({
529
+ name: `integration/${integration.id}`,
530
+ description: `${integration.display} integration guidance`,
531
+ 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.`,
532
+ }));
533
+ return [...fileBasedPrompts, ...integrationPrompts];
534
+ }
535
+ function resolveInWorkspace(root, targetPath) {
536
+ const resolved = path.isAbsolute(targetPath)
537
+ ? path.normalize(targetPath)
538
+ : path.resolve(root, targetPath);
539
+ const relative = path.relative(root, resolved);
540
+ if (relative.startsWith("..") || path.isAbsolute(relative)) {
541
+ throw new WorkspaceError(`Path ${targetPath} escapes the workspace root at ${root}`);
542
+ }
543
+ return resolved;
544
+ }
545
+ async function readWorkspaceFile(root, target) {
546
+ try {
547
+ const absolute = resolveInWorkspace(root, target);
548
+ return fs.readFileSync(absolute, "utf8");
549
+ }
550
+ catch (error) {
551
+ if (error instanceof WorkspaceError) {
552
+ await throwUserError(error.message);
553
+ }
554
+ /* istanbul ignore next */
555
+ throw error;
556
+ }
557
+ }
558
+ function discoverDocPrompts(root) {
559
+ const discovered = [];
560
+ for (const directory of PROMPT_DIRECTORIES) {
561
+ const promptDir = path.join(root, directory);
562
+ if (!fs.existsSync(promptDir) || !fs.statSync(promptDir).isDirectory()) {
563
+ continue;
564
+ }
565
+ for (const entry of fs.readdirSync(promptDir)) {
566
+ const fullPath = path.join(promptDir, entry);
567
+ if (!fs.statSync(fullPath).isFile())
568
+ continue;
569
+ const name = path.parse(entry).name;
570
+ const content = fs.readFileSync(fullPath, "utf8");
571
+ const title = toTitleCase(name.replace(/[-_]/g, " "));
572
+ const description = extractDescription(content, fullPath);
573
+ discovered.push({
574
+ name,
575
+ title,
576
+ description,
577
+ content,
578
+ absolutePath: fullPath,
579
+ });
580
+ }
581
+ }
582
+ const unique = new Map();
583
+ for (const prompt of discovered) {
584
+ if (!unique.has(prompt.name)) {
585
+ unique.set(prompt.name, prompt);
586
+ }
587
+ }
588
+ return Array.from(unique.values()).sort((a, b) => a.name.localeCompare(b.name));
589
+ }
590
+ function selectPrompt(prompts, requestedName) {
591
+ const direct = prompts.find((prompt) => prompt.name === requestedName);
592
+ if (direct)
593
+ return direct;
594
+ const fallback = prompts.find((prompt) => prompt.name === DEFAULT_PROMPT_NAME);
595
+ if (fallback)
596
+ return fallback;
597
+ if (!prompts.length) {
598
+ throw new WorkspaceError("No documentation prompts available");
599
+ }
600
+ return prompts[0];
601
+ }
602
+ function buildDocumentationPayload({ filePath, fileContent, prompt, includePrompt, includeCode, includeMetadata, additionalContext, }) {
603
+ const sections = [];
604
+ if (includeMetadata) {
605
+ sections.push(`# Documentation Request\n- prompt: ${prompt.name}\n- file: ${filePath}`);
606
+ }
607
+ if (includePrompt) {
608
+ sections.push(`## Prompt Guidance (${prompt.title})\n\n${prompt.content.trim()}`);
609
+ }
610
+ if (additionalContext?.trim()) {
611
+ sections.push(`## Additional Context\n\n${additionalContext.trim()}`);
612
+ }
613
+ if (includeCode) {
614
+ sections.push(`## Source\n\n\`\`\`${inferLanguageFromPath(filePath)}\n${fileContent}\n\`\`\``);
615
+ }
616
+ return {
617
+ content: [
618
+ {
619
+ type: "text",
620
+ text: sections.join("\n\n"),
621
+ },
622
+ ],
623
+ };
624
+ }
625
+ function extractDescription(content, filePath) {
626
+ const firstLine = content
627
+ .split(/\r?\n/)
628
+ .map((line) => line.trim())
629
+ .find((line) => line.length > 0);
630
+ return (firstLine?.slice(0, 240) ??
631
+ `Documentation prompt loaded from ${path.basename(filePath)}`);
632
+ }
633
+ function toTitleCase(value) {
634
+ return value
635
+ .split(/\s+/)
636
+ .filter(Boolean)
637
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())
638
+ .join(" ");
639
+ }
640
+ function inferLanguageFromPath(filePath) {
641
+ const extension = path.extname(filePath).toLowerCase();
642
+ switch (extension) {
643
+ case ".ts":
644
+ case ".tsx":
645
+ return "ts";
646
+ case ".js":
647
+ case ".jsx":
648
+ return "js";
649
+ case ".json":
650
+ return "json";
651
+ case ".md":
652
+ return "md";
653
+ default:
654
+ return "text";
655
+ }
21
656
  }
22
657
 
23
658
  /**
24
- * @class Class
25
- * @description A class implementing the Interface contract.
26
- * @summary This class provides an implementation of the Interface contract with additional static functionality.
27
- * It manages an internal state through a private property and offers both instance and static methods.
659
+ * @description The filename that identifies Decaf CLI modules
660
+ * @summary The standard filename for CLI module files where each library must export a single CliModule function
28
661
  *
29
- * @param {unknown} arg1 - First argument of unknown type
30
- * @param {string} arg2 - Second argument as string
31
- *
32
- * @implements {Interface}
662
+ * @const MCP_FILE_NAME
663
+ * @memberOf module:MCP
664
+ */
665
+ const MCP_FILE_NAME = "mcp-module";
666
+
667
+ /* istanbul ignore file */
668
+ /**
669
+ * @description Utility class for CLI operations
670
+ * @summary A static utility class that provides methods for loading modules, retrieving package information, and initializing CLI commands
33
671
  *
34
672
  * @example
35
- * ```typescript
36
- * // Create a new instance
37
- * const instance = new Class('someValue', 'stringValue');
38
- *
39
- * // Using the generic method
40
- * await instance.method<string>()
41
- * .catch(error => console.error(error));
42
- *
43
- * // Using the static method
44
- * Class.method();
45
- * ```
673
+ * // Initialize a Command object with package information
674
+ * const command = new Command();
675
+ * CLIUtils.initialize(command, './path/to/package');
46
676
  *
47
- * @mermaid
48
- * sequenceDiagram
49
- * participant Client
50
- * participant Instance
51
- * participant Static
677
+ * // Load a CLI module from a file
678
+ * const module = await CLIUtils.loadFromFile('./path/to/cli-module.js');
52
679
  *
53
- * Client->>Instance: new Class(arg1, arg2)
54
- * activate Instance
55
- * Instance-->>Client: class instance
56
- * deactivate Instance
57
- *
58
- * Client->>Instance: method<T>()
59
- * activate Instance
60
- * Instance-->>Client: Promise<string>
61
- * deactivate Instance
62
- *
63
- * Client->>Static: Class.method()
64
- * activate Static
65
- * Static-->>Client: void
66
- * deactivate Static
680
+ * @class McpUtils
67
681
  */
68
- class Class {
69
- constructor(arg1, arg2) {
70
- console.log(arg1, arg2);
71
- }
682
+ class McpUtils {
72
683
  /**
73
- * @description Asynchronous method implementing the Interface contract.
74
- * @summary Throws an error with type casting chain.
684
+ * @description Dynamically imports a module file
685
+ * @summary Loads a JavaScript file and returns it as a CliModule, handling both ESM and CommonJS formats
75
686
  *
76
- * @template T The type parameter used in the error casting chain
77
- * @return {Promise<string>} A Promise that always rejects with an error
78
- * @throws {Error} Always throws an error
687
+ * @param {string} path The file path to the module to load
688
+ * @return {Promise<McpModule>} A promise that resolves to the loaded CliModule
79
689
  */
80
- async method() {
81
- throw new Error("error");
690
+ static async loadFromFile(path) {
691
+ try {
692
+ return McpUtils.normalizeImport(import(path));
693
+ }
694
+ catch (e) {
695
+ throw new Error(`Failed to load from ${path}: ${e instanceof Error ? e.message : e}`);
696
+ }
82
697
  }
83
698
  /**
84
- * @description Static method that throws an error.
85
- * @summary A static utility method that always throws an error.
699
+ * @description Normalizes module imports to handle both ESM and CommonJS formats
700
+ * @summary Properly imports JavaScript files regardless of their module format by handling the ESM wrapper for CommonJS modules
86
701
  *
87
- * @return {never} Never returns as it always throws an error
88
- * @throws {Error} Always throws an error
89
- * @static
702
+ * @template T The type of the imported module
703
+ * @param {Promise<T>} importPromise The promise returned by the dynamic import
704
+ * @return {Promise<T>} A promise that resolves to the normalized module
705
+ * @private
90
706
  */
91
- static method() {
92
- throw new Error("error");
707
+ static async normalizeImport(importPromise) {
708
+ // CommonJS's `module.exports` is wrapped as `default` in ESModule.
709
+ return importPromise.then((m) => (m.default || m));
93
710
  }
94
- }
95
-
96
- /**
97
- * @class ChildClass
98
- * @description This class extends the base Class and implements the ChildInterface.
99
- * @summary Generic class extending Class and implementing ChildInterface with additional functionality.
100
- * It provides a generic implementation with additional properties and methods.
101
- *
102
- * @param {unknown} arg1 - First argument of unknown type
103
- * @param {string} arg2 - Second argument as string
104
- *
105
- * @template T - The generic type parameter
106
- * @extends {Class}
107
- * @implements {ChildInterface<T>}
108
- */
109
- class ChildClass extends Class {
110
- constructor(arg1, arg2) {
111
- super(arg1, arg2);
112
- this.prop2 = arg1;
711
+ /**
712
+ * @description Retrieves and parses the package.json file
713
+ * @summary Reads the package.json file from the specified path and parses it into a JavaScript object
714
+ *
715
+ * @param {string} basePath The base path where the package.json file is located
716
+ * @return {Record<string, unknown>} The parsed package.json content as an object
717
+ * @private
718
+ */
719
+ static getPackage(basePath) {
720
+ try {
721
+ return JSON.parse(fs.readFileSync(path.join(basePath, "package.json"), "utf8"));
722
+ }
723
+ catch (e) {
724
+ throw new Error(`Unable to read version from ${basePath}: ${e}`);
725
+ }
113
726
  }
114
727
  /**
115
- * @description This method overrides the base class method.
116
- * @summary Asynchronous method that returns a string after a series of type assertions.
728
+ * @description Returns the version from package.json
729
+ * @summary Retrieves the version field from the package.json file at the specified path
117
730
  *
118
- * @template V - The generic type parameter
119
- * @return {Promise<string>} A Promise that resolves to a string
120
- * @override
731
+ * @param {string} basePath The base path where the package.json file is located
732
+ * @return {string} The package version string
121
733
  */
122
- async method() {
123
- return "ok";
734
+ static packageVersion(basePath) {
735
+ return McpUtils.getPackage(basePath)["version"];
124
736
  }
125
737
  /**
126
- * @description This method implements the method2 from ChildInterface.
127
- * @summary Method that throws an error with a message that includes the input argument.
738
+ * @description Returns the name from package.json
739
+ * @summary Retrieves the name field from the package.json file at the specified path and extracts the package name without the scope
128
740
  *
129
- * @param {T} arg1 - The input argument of generic type T
130
- * @return {Promise<string>} A Promise that always rejects with an error
131
- * @throws {Error} Always throws an error with a message including arg1
741
+ * @param {string} basePath The base path where the package.json file is located
742
+ * @return {string} The package name without the scope (e.g., "cli" from "@decaf-ts/cli")
132
743
  */
133
- method2(arg1) {
134
- throw new Error("error" + arg1);
744
+ static packageName(basePath) {
745
+ const name = McpUtils.getPackage(basePath)["name"].split("/");
746
+ return name[name.length - 1];
135
747
  }
136
748
  }
137
749
 
750
+ /* istanbul ignore file */
138
751
  /**
139
- * @const Enum
140
- * @name Enum
141
- * @description This enum provides a set of predefined options that can be used throughout the application.
142
- * @summary Enumeration of string options for consistent value representation.
143
- * @type {enum}
144
- * @readonly
145
- *
146
- * @memberOf module:ts-workspace.Namespace.ChildNamespace
147
- */
148
- var Enum;
149
- (function (Enum) {
150
- /** Represents the first option with value "something" */
151
- Enum["OPTION1"] = "something";
152
- })(Enum || (Enum = {}));
153
-
154
- /**
155
- * @function something
156
- * @description This function is a generic method that extends the Class type.
157
- * @summary Generic function that logs arguments and returns the context (this) of the function.
158
- * It logs all provided arguments to the console and returns the context (this) of the function.
752
+ * @description Utility class to handle CLI functionality from all Decaf modules
753
+ * @summary This class provides a wrapper around Commander.js to handle CLI commands from different Decaf modules.
754
+ * It crawls the filesystem to find CLI modules, loads them, and registers their commands.
159
755
  *
160
- * @template T - Type extending {@link Class}
161
- * @template V - Type of the arguments
162
- * @this {T}
163
- * @param {...V} args - Variable number of arguments of type V
164
- * @return {Type<T>} Returns the context (this) of the function
756
+ * @param {string} [basePath] The base path to look for modules in. Defaults to `./`
757
+ * @param {number} [crawlLevels] Number of folder levels to crawl to find modules from the basePath. Defaults to 4
165
758
  *
166
759
  * @example
167
- * class MyClass extends Class {
168
- * myMethod() {
169
- * return something.call(this, 'arg1', 'arg2');
170
- * }
171
- * }
760
+ * // Create a new CLI wrapper and run it with custom options
761
+ * const cli = new CliWrapper('./src', 2);
762
+ * cli.run(process.argv).then(() => {
763
+ * console.log('CLI commands executed successfully');
764
+ * });
172
765
  *
173
- * const instance = new MyClass();
174
- * const result = instance.myMethod();
175
- * // Logs: 'arg1', 'arg2'
176
- * // result is the instance of MyClass
177
- *
178
- * @memberOf module:ts-workspace.Namespace.ChildNamespace
179
- * @see {@link Class}
180
- * @see {@link Type}
766
+ * @class McpWrapper
181
767
  */
182
- function something(...args) {
183
- console.log(...args);
184
- return this;
768
+ class McpWrapper extends LoggedClass {
769
+ constructor(basePath = "./", crawlLevels = 4) {
770
+ super();
771
+ this.basePath = basePath;
772
+ this.crawlLevels = crawlLevels;
773
+ this.modules = {};
774
+ this.rootPath = path.resolve(__dirname, "..");
775
+ }
776
+ /**
777
+ * @description Retrieves and initializes the Commander Command object
778
+ * @summary Lazy-loads the Command object, initializing it with the package name, description, and version
779
+ * @return {Command} The initialized Command object
780
+ * @private
781
+ */
782
+ get mcp() {
783
+ if (!this._mcp) {
784
+ this._mcp = new FastMCP({
785
+ name: "decaf-ts MCP server",
786
+ instructions: "",
787
+ version: VERSION$1,
788
+ });
789
+ }
790
+ return this._mcp;
791
+ }
792
+ /**
793
+ * @description Loads and registers an mcp extension module from a file
794
+ * @summary Dynamically imports an mcp extension module from the specified file path, initializes it, and registers it in the modules collection
795
+ *
796
+ */
797
+ async load(server, filePath) {
798
+ const log = this.log.for(this.load);
799
+ let pkg, version, enrich;
800
+ try {
801
+ const res = await McpUtils.loadFromFile(filePath);
802
+ pkg = res.PACKAGE_NAME;
803
+ version = res.VERSION;
804
+ enrich = res.enrich;
805
+ }
806
+ catch (e) {
807
+ throw new Error(e.message || e);
808
+ }
809
+ try {
810
+ log.info(`Enriching mcp server with module ${pkg} v${version}`);
811
+ const result = enrich(server);
812
+ server = result instanceof Promise ? await result : result;
813
+ }
814
+ catch (e) {
815
+ throw new Error(`failed to enrich mcp with module ${pkg || "unnamed"} under ${filePath}: ${e instanceof Error ? e.message : e}`);
816
+ }
817
+ return {
818
+ mcp: server,
819
+ package: pkg,
820
+ version: version,
821
+ };
822
+ }
823
+ /**
824
+ * @description Finds and loads all CLI modules in the basePath
825
+ * @summary Uses the crawl method to find all CLI modules in the specified base path,
826
+ * then loads and registers each module as a subcommand
827
+ *
828
+ * @return {Promise<void>} A promise that resolves when all modules are loaded
829
+ *
830
+ * @private
831
+ * @mermaid
832
+ * sequenceDiagram
833
+ * participant CliWrapper
834
+ * participant Filesystem
835
+ * participant Module
836
+ *
837
+ * CliWrapper->>Filesystem: Join basePath with cwd
838
+ * CliWrapper->>CliWrapper: crawl(basePath, crawlLevels)
839
+ * CliWrapper-->>CliWrapper: modules[]
840
+ * loop For each module
841
+ * alt Not @decaf-ts/cli
842
+ * CliWrapper->>CliWrapper: load(module, cwd)
843
+ * CliWrapper-->>CliWrapper: name
844
+ * CliWrapper->>CliWrapper: Check if command exists
845
+ * alt Command doesn't exist
846
+ * CliWrapper->>Command: command(name).addCommand(modules[name])
847
+ * end
848
+ * end
849
+ * end
850
+ * CliWrapper->>Console: Log loaded modules
851
+ */
852
+ async boot() {
853
+ const log = this.log.for(this.boot);
854
+ const basePath = path.resolve(this.rootPath, this.basePath);
855
+ const modules = this.crawl(basePath, this.crawlLevels);
856
+ let server = this.mcp;
857
+ for (const module of modules) {
858
+ if (module.includes("@decaf-ts/mcp")) {
859
+ continue;
860
+ }
861
+ try {
862
+ const res = await this.load(server, module);
863
+ server = res.mcp;
864
+ }
865
+ catch (e) {
866
+ log.error(`Failed to load MCP configs for ${module}: ${e}`);
867
+ }
868
+ }
869
+ console.log(`loaded modules:\n${Object.keys(this.modules)
870
+ .map((k) => `- ${k}`)
871
+ .join("\n")}`);
872
+ return server;
873
+ }
874
+ /**
875
+ * @description Recursively searches for CLI module files in the directory structure
876
+ * @summary Crawls the basePath up to the specified number of folder levels to find files named according to CLI_FILE_NAME
877
+ *
878
+ * @param {string} basePath The absolute base path to start searching in
879
+ * @param {number} [levels=2] The maximum number of directory levels to crawl
880
+ * @return {string[]} An array of file paths to CLI modules
881
+ *
882
+ * @private
883
+ */
884
+ crawl(basePath, levels = 2) {
885
+ if (levels <= 0)
886
+ return [];
887
+ return fs.readdirSync(basePath).reduce((accum, file) => {
888
+ file = path.join(basePath, file);
889
+ if (fs.statSync(file).isDirectory()) {
890
+ accum.push(...this.crawl(file, levels - 1));
891
+ }
892
+ else if (file.match(new RegExp(`${MCP_FILE_NAME}.[cm]?js$`, "gm"))) {
893
+ accum.push(file);
894
+ }
895
+ return accum;
896
+ }, []);
897
+ }
898
+ /**
899
+ * @description Executes the CLI with the provided arguments
900
+ * @summary Boots the CLI by loading all modules, then parses and executes the command specified in the arguments
901
+ *
902
+ * @param {string[]} [args=process.argv] Command line arguments to parse and execute
903
+ * @return {Promise<void>} A promise that resolves when the command execution is complete
904
+ *
905
+ * @mermaid
906
+ * sequenceDiagram
907
+ * participant Client
908
+ * participant CliWrapper
909
+ * participant Command
910
+ *
911
+ * Client->>CliWrapper: run(args)
912
+ * CliWrapper->>CliWrapper: boot()
913
+ * Note over CliWrapper: Loads all modules
914
+ * CliWrapper->>Command: parseAsync(args)
915
+ * Command-->>CliWrapper: result
916
+ * CliWrapper-->>Client: result
917
+ */
918
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
919
+ async run(args = process.argv) {
920
+ const server = await this.boot();
921
+ await server.start({ transportType: "stdio" });
922
+ }
185
923
  }
186
924
 
187
- /**
188
- * @module ts-workspace
189
- * @description This module serves as the main entry point for the ts-workspace library.
190
- * @summary Aggregates and exports functionality from various submodules and utilities within the project.
191
- *
192
- * The module includes:
193
- * 1. Utility functions and types from the "./utils" directory:
194
- * - These likely contain helper functions, common types, and shared functionality used throughout the project.
195
- * - May include operations for data manipulation, type checking, or other general-purpose utilities.
196
- *
197
- * 2. A namespace and related types from the "./namespace" directory:
198
- * - This could contain domain-specific code or a collection of related functionality.
199
- * - Might include interfaces, types, or classes that represent core concepts in the library.
200
- *
201
- * 3. A VERSION constant:
202
- * - Represents the current version of the module.
203
- * - Useful for version checking and compatibility purposes.
204
- *
205
- * This structure provides a clean and organized export of the module's functionality, allowing consumers
206
- * to easily import and use specific parts of the library as needed.
207
- */
208
- /**
209
- * @const VERSION
210
- * @name VERSION
211
- * @description Represents the current version of the ts-workspace module.
212
- * @summary The actual version number is replaced during the build process.
213
- * @type {string}
214
- */
215
- const VERSION = "0.0.2";
216
-
217
- export { ChildClass, Class, Enum, VERSION, complexFunction, something };
218
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWNwLXNlcnZlci5lc20uY2pzIiwic291cmNlcyI6WyIuLi9zcmMvdXRpbHMudHMiLCIuLi9zcmMvbmFtZXNwYWNlL0NsYXNzLnRzIiwiLi4vc3JjL25hbWVzcGFjZS9jaGlsZHJlbi9DaGlsZENsYXNzLnRzIiwiLi4vc3JjL25hbWVzcGFjZS9jaGlsZHJlbi9FbnVtLnRzIiwiLi4vc3JjL25hbWVzcGFjZS9jaGlsZHJlbi9mdW5jdGlvbi50cyIsIi4uL3NyYy9pbmRleC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBmdW5jdGlvbiBjb21wbGV4RnVuY3Rpb25cbiAqIEBkZXNjcmlwdGlvbiBUaGlzIGZ1bmN0aW9uIHRha2VzIGFuIG9wdGlvbmFsIHN0cmluZyBhcmd1bWVudCBhbmQgY29uY2F0ZW5hdGVzIGl0IHdpdGggXCJIZWxsbyBXb3JsZFwiLlxuICogQHN1bW1hcnkgQ29uY2F0ZW5hdGVzIFwiSGVsbG8gV29ybGRcIiB3aXRoIGEgZ2l2ZW4gc3RyaW5nLiBEZXNwaXRlIGl0cyBuYW1lLCBpdCdzIGEgc2ltcGxlIHN0cmluZyBjb25jYXRlbmF0aW9uIG9wZXJhdGlvbi5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW2FyZzE9XCJkZWZhdWx0XCJdIC0gVGhlIHN0cmluZyB0byBhcHBlbmQgdG8gXCJIZWxsbyBXb3JsZFwiLiBJZiBub3QgcHJvdmlkZWQsIGRlZmF1bHRzIHRvIFwiZGVmYXVsdFwiLlxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgcmVzdWx0aW5nIGNvbmNhdGVuYXRlZCBzdHJpbmdcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gcmV0dXJucyBcIkhlbGxvIFdvcmxkZGVmYXVsdFwiXG4gKiBjb21wbGV4RnVuY3Rpb24oKTtcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gcmV0dXJucyBcIkhlbGxvIFdvcmxkIVwiXG4gKiBjb21wbGV4RnVuY3Rpb24oXCIhXCIpO1xuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6dHMtd29ya3NwYWNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21wbGV4RnVuY3Rpb24oYXJnMTogc3RyaW5nID0gXCJkZWZhdWx0XCIpIHtcbiAgcmV0dXJuIFwiSGVsbG8gV29ybGRcIiArIGFyZzE7XG59XG4iLCJpbXBvcnQgeyBJbnRlcmZhY2UgfSBmcm9tIFwiLi9JbnRlcmZhY2VcIjtcblxuLyoqXG4gKiBAY2xhc3MgQ2xhc3NcbiAqIEBkZXNjcmlwdGlvbiBBIGNsYXNzIGltcGxlbWVudGluZyB0aGUgSW50ZXJmYWNlIGNvbnRyYWN0LlxuICogQHN1bW1hcnkgVGhpcyBjbGFzcyBwcm92aWRlcyBhbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgSW50ZXJmYWNlIGNvbnRyYWN0IHdpdGggYWRkaXRpb25hbCBzdGF0aWMgZnVuY3Rpb25hbGl0eS5cbiAqIEl0IG1hbmFnZXMgYW4gaW50ZXJuYWwgc3RhdGUgdGhyb3VnaCBhIHByaXZhdGUgcHJvcGVydHkgYW5kIG9mZmVycyBib3RoIGluc3RhbmNlIGFuZCBzdGF0aWMgbWV0aG9kcy5cbiAqXG4gKiBAcGFyYW0ge3Vua25vd259IGFyZzEgLSBGaXJzdCBhcmd1bWVudCBvZiB1bmtub3duIHR5cGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBhcmcyIC0gU2Vjb25kIGFyZ3VtZW50IGFzIHN0cmluZ1xuICpcbiAqIEBpbXBsZW1lbnRzIHtJbnRlcmZhY2V9XG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIENyZWF0ZSBhIG5ldyBpbnN0YW5jZVxuICogY29uc3QgaW5zdGFuY2UgPSBuZXcgQ2xhc3MoJ3NvbWVWYWx1ZScsICdzdHJpbmdWYWx1ZScpO1xuICpcbiAqIC8vIFVzaW5nIHRoZSBnZW5lcmljIG1ldGhvZFxuICogYXdhaXQgaW5zdGFuY2UubWV0aG9kPHN0cmluZz4oKVxuICogICAuY2F0Y2goZXJyb3IgPT4gY29uc29sZS5lcnJvcihlcnJvcikpO1xuICpcbiAqIC8vIFVzaW5nIHRoZSBzdGF0aWMgbWV0aG9kXG4gKiBDbGFzcy5tZXRob2QoKTtcbiAqIGBgYFxuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2xpZW50XG4gKiAgIHBhcnRpY2lwYW50IEluc3RhbmNlXG4gKiAgIHBhcnRpY2lwYW50IFN0YXRpY1xuICpcbiAqICAgQ2xpZW50LT4+SW5zdGFuY2U6IG5ldyBDbGFzcyhhcmcxLCBhcmcyKVxuICogICBhY3RpdmF0ZSBJbnN0YW5jZVxuICogICBJbnN0YW5jZS0tPj5DbGllbnQ6IGNsYXNzIGluc3RhbmNlXG4gKiAgIGRlYWN0aXZhdGUgSW5zdGFuY2VcbiAqXG4gKiAgIENsaWVudC0+Pkluc3RhbmNlOiBtZXRob2Q8VD4oKVxuICogICBhY3RpdmF0ZSBJbnN0YW5jZVxuICogICBJbnN0YW5jZS0tPj5DbGllbnQ6IFByb21pc2U8c3RyaW5nPlxuICogICBkZWFjdGl2YXRlIEluc3RhbmNlXG4gKlxuICogICBDbGllbnQtPj5TdGF0aWM6IENsYXNzLm1ldGhvZCgpXG4gKiAgIGFjdGl2YXRlIFN0YXRpY1xuICogICBTdGF0aWMtLT4+Q2xpZW50OiB2b2lkXG4gKiAgIGRlYWN0aXZhdGUgU3RhdGljXG4gKi9cbmV4cG9ydCBjbGFzcyBDbGFzcyBpbXBsZW1lbnRzIEludGVyZmFjZSB7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUHJpdmF0ZSBwcm9wZXJ0eSB0byBzdG9yZSBpbnRlcm5hbCBzdGF0ZS5cbiAgICogQHN1bW1hcnkgQW4gdW5rbm93biB0eXBlIHByb3BlcnR5IHVzZWQgZm9yIGludGVybmFsIHN0YXRlIG1hbmFnZW1lbnQuXG4gICAqIEBwcml2YXRlXG4gICAqIEB0eXBlIHt1bmtub3dufVxuICAgKi9cbiAgcHJpdmF0ZSBwcm9wITogdW5rbm93bjtcblxuICBjb25zdHJ1Y3RvcihhcmcxOiB1bmtub3duLCBhcmcyOiBzdHJpbmcpIHtcbiAgICBjb25zb2xlLmxvZyhhcmcxLCBhcmcyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQXN5bmNocm9ub3VzIG1ldGhvZCBpbXBsZW1lbnRpbmcgdGhlIEludGVyZmFjZSBjb250cmFjdC5cbiAgICogQHN1bW1hcnkgVGhyb3dzIGFuIGVycm9yIHdpdGggdHlwZSBjYXN0aW5nIGNoYWluLlxuICAgKlxuICAgKiBAdGVtcGxhdGUgVCBUaGUgdHlwZSBwYXJhbWV0ZXIgdXNlZCBpbiB0aGUgZXJyb3IgY2FzdGluZyBjaGFpblxuICAgKiBAcmV0dXJuIHtQcm9taXNlPHN0cmluZz59IEEgUHJvbWlzZSB0aGF0IGFsd2F5cyByZWplY3RzIHdpdGggYW4gZXJyb3JcbiAgICogQHRocm93cyB7RXJyb3J9IEFsd2F5cyB0aHJvd3MgYW4gZXJyb3JcbiAgICovXG4gIGFzeW5jIG1ldGhvZDxUPigpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIHRocm93IG5ldyBFcnJvcihcImVycm9yXCIgYXMgVCBhcyB1bmtub3duIGFzIHN0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFN0YXRpYyBtZXRob2QgdGhhdCB0aHJvd3MgYW4gZXJyb3IuXG4gICAqIEBzdW1tYXJ5IEEgc3RhdGljIHV0aWxpdHkgbWV0aG9kIHRoYXQgYWx3YXlzIHRocm93cyBhbiBlcnJvci5cbiAgICpcbiAgICogQHJldHVybiB7bmV2ZXJ9IE5ldmVyIHJldHVybnMgYXMgaXQgYWx3YXlzIHRocm93cyBhbiBlcnJvclxuICAgKiBAdGhyb3dzIHtFcnJvcn0gQWx3YXlzIHRocm93cyBhbiBlcnJvclxuICAgKiBAc3RhdGljXG4gICAqL1xuICBzdGF0aWMgbWV0aG9kKCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcImVycm9yXCIpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBDbGFzcyB9IGZyb20gXCIuLi9DbGFzc1wiO1xuaW1wb3J0IHsgQ2hpbGRJbnRlcmZhY2UgfSBmcm9tIFwiLi9DaGlsZEludGVyZmFjZVwiO1xuXG4vKipcbiAqIEBjbGFzcyBDaGlsZENsYXNzXG4gKiBAZGVzY3JpcHRpb24gVGhpcyBjbGFzcyBleHRlbmRzIHRoZSBiYXNlIENsYXNzIGFuZCBpbXBsZW1lbnRzIHRoZSBDaGlsZEludGVyZmFjZS5cbiAqIEBzdW1tYXJ5IEdlbmVyaWMgY2xhc3MgZXh0ZW5kaW5nIENsYXNzIGFuZCBpbXBsZW1lbnRpbmcgQ2hpbGRJbnRlcmZhY2Ugd2l0aCBhZGRpdGlvbmFsIGZ1bmN0aW9uYWxpdHkuXG4gKiBJdCBwcm92aWRlcyBhIGdlbmVyaWMgaW1wbGVtZW50YXRpb24gd2l0aCBhZGRpdGlvbmFsIHByb3BlcnRpZXMgYW5kIG1ldGhvZHMuXG4gKlxuICogQHBhcmFtIHt1bmtub3dufSBhcmcxIC0gRmlyc3QgYXJndW1lbnQgb2YgdW5rbm93biB0eXBlXG4gKiBAcGFyYW0ge3N0cmluZ30gYXJnMiAtIFNlY29uZCBhcmd1bWVudCBhcyBzdHJpbmdcbiAqXG4gKiBAdGVtcGxhdGUgVCAtIFRoZSBnZW5lcmljIHR5cGUgcGFyYW1ldGVyXG4gKiBAZXh0ZW5kcyB7Q2xhc3N9XG4gKiBAaW1wbGVtZW50cyB7Q2hpbGRJbnRlcmZhY2U8VD59XG4gKi9cbmV4cG9ydCBjbGFzcyBDaGlsZENsYXNzPFQ+IGV4dGVuZHMgQ2xhc3MgaW1wbGVtZW50cyBDaGlsZEludGVyZmFjZTxUPiB7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQSBwcml2YXRlIHByb3BlcnR5IG9mIGdlbmVyaWMgdHlwZSBULlxuICAgKiBAdGVtcGxhdGUge1R9XG4gICAqIEBzdW1tYXJ5IFN0b3JlcyB0aGUgZmlyc3QgY29uc3RydWN0b3IgYXJndW1lbnQgZm9yIGxhdGVyIHVzZS5cbiAgICogQHByaXZhdGVcbiAgICogQHR5cGUge1R9XG4gICAqL1xuICBwcml2YXRlIHByb3AyPzogVDtcblxuICBjb25zdHJ1Y3RvcihhcmcxOiBULCBhcmcyOiBzdHJpbmcpIHtcbiAgICBzdXBlcihhcmcxLCBhcmcyKTtcbiAgICB0aGlzLnByb3AyID0gYXJnMTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVGhpcyBtZXRob2Qgb3ZlcnJpZGVzIHRoZSBiYXNlIGNsYXNzIG1ldGhvZC5cbiAgICogQHN1bW1hcnkgQXN5bmNocm9ub3VzIG1ldGhvZCB0aGF0IHJldHVybnMgYSBzdHJpbmcgYWZ0ZXIgYSBzZXJpZXMgb2YgdHlwZSBhc3NlcnRpb25zLlxuICAgKlxuICAgKiBAdGVtcGxhdGUgViAtIFRoZSBnZW5lcmljIHR5cGUgcGFyYW1ldGVyXG4gICAqIEByZXR1cm4ge1Byb21pc2U8c3RyaW5nPn0gQSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYSBzdHJpbmdcbiAgICogQG92ZXJyaWRlXG4gICAqL1xuICBvdmVycmlkZSBhc3luYyBtZXRob2Q8Vj4oKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICByZXR1cm4gXCJva1wiIGFzIHVua25vd24gYXMgViBhcyB1bmtub3duIGFzIHN0cmluZztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVGhpcyBtZXRob2QgaW1wbGVtZW50cyB0aGUgbWV0aG9kMiBmcm9tIENoaWxkSW50ZXJmYWNlLlxuICAgKiBAc3VtbWFyeSBNZXRob2QgdGhhdCB0aHJvd3MgYW4gZXJyb3Igd2l0aCBhIG1lc3NhZ2UgdGhhdCBpbmNsdWRlcyB0aGUgaW5wdXQgYXJndW1lbnQuXG4gICAqXG4gICAqIEBwYXJhbSB7VH0gYXJnMSAtIFRoZSBpbnB1dCBhcmd1bWVudCBvZiBnZW5lcmljIHR5cGUgVFxuICAgKiBAcmV0dXJuIHtQcm9taXNlPHN0cmluZz59IEEgUHJvbWlzZSB0aGF0IGFsd2F5cyByZWplY3RzIHdpdGggYW4gZXJyb3JcbiAgICogQHRocm93cyB7RXJyb3J9IEFsd2F5cyB0aHJvd3MgYW4gZXJyb3Igd2l0aCBhIG1lc3NhZ2UgaW5jbHVkaW5nIGFyZzFcbiAgICovXG4gIG1ldGhvZDIoYXJnMTogVCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiZXJyb3JcIiArIGFyZzEpO1xuICB9XG59XG4iLCIvKipcbiAqIEBjb25zdCBFbnVtXG4gKiBAbmFtZSBFbnVtXG4gKiBAZGVzY3JpcHRpb24gVGhpcyBlbnVtIHByb3ZpZGVzIGEgc2V0IG9mIHByZWRlZmluZWQgb3B0aW9ucyB0aGF0IGNhbiBiZSB1c2VkIHRocm91Z2hvdXQgdGhlIGFwcGxpY2F0aW9uLlxuICogQHN1bW1hcnkgRW51bWVyYXRpb24gb2Ygc3RyaW5nIG9wdGlvbnMgZm9yIGNvbnNpc3RlbnQgdmFsdWUgcmVwcmVzZW50YXRpb24uXG4gKiBAdHlwZSB7ZW51bX1cbiAqIEByZWFkb25seVxuICogXG4gKiBAbWVtYmVyT2YgbW9kdWxlOnRzLXdvcmtzcGFjZS5OYW1lc3BhY2UuQ2hpbGROYW1lc3BhY2VcbiAqL1xuZXhwb3J0IGVudW0gRW51bSB7XG4gIC8qKiBSZXByZXNlbnRzIHRoZSBmaXJzdCBvcHRpb24gd2l0aCB2YWx1ZSBcInNvbWV0aGluZ1wiICovXG4gIE9QVElPTjEgPSBcInNvbWV0aGluZ1wiLFxufVxuIiwiaW1wb3J0IHsgQ2xhc3MgfSBmcm9tIFwiLi4vQ2xhc3NcIjtcbmltcG9ydCB7IFR5cGUgfSBmcm9tIFwiLi4vdHlwZVwiO1xuXG4vKipcbiAqIEBmdW5jdGlvbiBzb21ldGhpbmdcbiAqIEBkZXNjcmlwdGlvbiBUaGlzIGZ1bmN0aW9uIGlzIGEgZ2VuZXJpYyBtZXRob2QgdGhhdCBleHRlbmRzIHRoZSBDbGFzcyB0eXBlLlxuICogQHN1bW1hcnkgR2VuZXJpYyBmdW5jdGlvbiB0aGF0IGxvZ3MgYXJndW1lbnRzIGFuZCByZXR1cm5zIHRoZSBjb250ZXh0ICh0aGlzKSBvZiB0aGUgZnVuY3Rpb24uXG4gKiBJdCBsb2dzIGFsbCBwcm92aWRlZCBhcmd1bWVudHMgdG8gdGhlIGNvbnNvbGUgYW5kIHJldHVybnMgdGhlIGNvbnRleHQgKHRoaXMpIG9mIHRoZSBmdW5jdGlvbi5cbiAqXG4gKiBAdGVtcGxhdGUgVCAtIFR5cGUgZXh0ZW5kaW5nIHtAbGluayBDbGFzc31cbiAqIEB0ZW1wbGF0ZSBWIC0gVHlwZSBvZiB0aGUgYXJndW1lbnRzXG4gKiBAdGhpcyB7VH1cbiAqIEBwYXJhbSB7Li4uVn0gYXJncyAtIFZhcmlhYmxlIG51bWJlciBvZiBhcmd1bWVudHMgb2YgdHlwZSBWXG4gKiBAcmV0dXJuIHtUeXBlPFQ+fSBSZXR1cm5zIHRoZSBjb250ZXh0ICh0aGlzKSBvZiB0aGUgZnVuY3Rpb25cbiAqXG4gKiBAZXhhbXBsZVxuICogY2xhc3MgTXlDbGFzcyBleHRlbmRzIENsYXNzIHtcbiAqICAgbXlNZXRob2QoKSB7XG4gKiAgICAgcmV0dXJuIHNvbWV0aGluZy5jYWxsKHRoaXMsICdhcmcxJywgJ2FyZzInKTtcbiAqICAgfVxuICogfVxuICogXG4gKiBjb25zdCBpbnN0YW5jZSA9IG5ldyBNeUNsYXNzKCk7XG4gKiBjb25zdCByZXN1bHQgPSBpbnN0YW5jZS5teU1ldGhvZCgpO1xuICogLy8gTG9nczogJ2FyZzEnLCAnYXJnMidcbiAqIC8vIHJlc3VsdCBpcyB0aGUgaW5zdGFuY2Ugb2YgTXlDbGFzc1xuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6dHMtd29ya3NwYWNlLk5hbWVzcGFjZS5DaGlsZE5hbWVzcGFjZVxuICogQHNlZSB7QGxpbmsgQ2xhc3N9XG4gKiBAc2VlIHtAbGluayBUeXBlfVxuICovXG5leHBvcnQgZnVuY3Rpb24gc29tZXRoaW5nPFQgZXh0ZW5kcyBDbGFzcywgVj4odGhpczogVCwgLi4uYXJnczogVltdKTogVHlwZTxUPiB7XG4gIGNvbnNvbGUubG9nKC4uLmFyZ3MpO1xuICByZXR1cm4gdGhpcztcbn1cbiIsIi8qKlxuICogQG1vZHVsZSB0cy13b3Jrc3BhY2VcbiAqIEBkZXNjcmlwdGlvbiBUaGlzIG1vZHVsZSBzZXJ2ZXMgYXMgdGhlIG1haW4gZW50cnkgcG9pbnQgZm9yIHRoZSB0cy13b3Jrc3BhY2UgbGlicmFyeS5cbiAqIEBzdW1tYXJ5IEFnZ3JlZ2F0ZXMgYW5kIGV4cG9ydHMgZnVuY3Rpb25hbGl0eSBmcm9tIHZhcmlvdXMgc3VibW9kdWxlcyBhbmQgdXRpbGl0aWVzIHdpdGhpbiB0aGUgcHJvamVjdC5cbiAqIFxuICogVGhlIG1vZHVsZSBpbmNsdWRlczpcbiAqIDEuIFV0aWxpdHkgZnVuY3Rpb25zIGFuZCB0eXBlcyBmcm9tIHRoZSBcIi4vdXRpbHNcIiBkaXJlY3Rvcnk6XG4gKiAgICAtIFRoZXNlIGxpa2VseSBjb250YWluIGhlbHBlciBmdW5jdGlvbnMsIGNvbW1vbiB0eXBlcywgYW5kIHNoYXJlZCBmdW5jdGlvbmFsaXR5IHVzZWQgdGhyb3VnaG91dCB0aGUgcHJvamVjdC5cbiAqICAgIC0gTWF5IGluY2x1ZGUgb3BlcmF0aW9ucyBmb3IgZGF0YSBtYW5pcHVsYXRpb24sIHR5cGUgY2hlY2tpbmcsIG9yIG90aGVyIGdlbmVyYWwtcHVycG9zZSB1dGlsaXRpZXMuXG4gKiBcbiAqIDIuIEEgbmFtZXNwYWNlIGFuZCByZWxhdGVkIHR5cGVzIGZyb20gdGhlIFwiLi9uYW1lc3BhY2VcIiBkaXJlY3Rvcnk6XG4gKiAgICAtIFRoaXMgY291bGQgY29udGFpbiBkb21haW4tc3BlY2lmaWMgY29kZSBvciBhIGNvbGxlY3Rpb24gb2YgcmVsYXRlZCBmdW5jdGlvbmFsaXR5LlxuICogICAgLSBNaWdodCBpbmNsdWRlIGludGVyZmFjZXMsIHR5cGVzLCBvciBjbGFzc2VzIHRoYXQgcmVwcmVzZW50IGNvcmUgY29uY2VwdHMgaW4gdGhlIGxpYnJhcnkuXG4gKiBcbiAqIDMuIEEgVkVSU0lPTiBjb25zdGFudDpcbiAqICAgIC0gUmVwcmVzZW50cyB0aGUgY3VycmVudCB2ZXJzaW9uIG9mIHRoZSBtb2R1bGUuXG4gKiAgICAtIFVzZWZ1bCBmb3IgdmVyc2lvbiBjaGVja2luZyBhbmQgY29tcGF0aWJpbGl0eSBwdXJwb3Nlcy5cbiAqIFxuICogVGhpcyBzdHJ1Y3R1cmUgcHJvdmlkZXMgYSBjbGVhbiBhbmQgb3JnYW5pemVkIGV4cG9ydCBvZiB0aGUgbW9kdWxlJ3MgZnVuY3Rpb25hbGl0eSwgYWxsb3dpbmcgY29uc3VtZXJzXG4gKiB0byBlYXNpbHkgaW1wb3J0IGFuZCB1c2Ugc3BlY2lmaWMgcGFydHMgb2YgdGhlIGxpYnJhcnkgYXMgbmVlZGVkLlxuICovXG5cbmV4cG9ydCAqIGZyb20gXCIuL3V0aWxzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9uYW1lc3BhY2VcIjtcblxuLyoqXG4gKiBAY29uc3QgVkVSU0lPTlxuICogQG5hbWUgVkVSU0lPTlxuICogQGRlc2NyaXB0aW9uIFJlcHJlc2VudHMgdGhlIGN1cnJlbnQgdmVyc2lvbiBvZiB0aGUgdHMtd29ya3NwYWNlIG1vZHVsZS5cbiAqIEBzdW1tYXJ5IFRoZSBhY3R1YWwgdmVyc2lvbiBudW1iZXIgaXMgcmVwbGFjZWQgZHVyaW5nIHRoZSBidWlsZCBwcm9jZXNzLlxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuZXhwb3J0IGNvbnN0IFZFUlNJT04gPSBcIiMjVkVSU0lPTiMjXCI7XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBaUJHO0FBQ2EsU0FBQSxlQUFlLENBQUMsSUFBQSxHQUFlLFNBQVMsRUFBQTtJQUN0RCxPQUFPLGFBQWEsR0FBRyxJQUFJO0FBQzdCOztBQ2xCQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUE0Q0c7TUFDVSxLQUFLLENBQUE7SUFTaEIsV0FBWSxDQUFBLElBQWEsRUFBRSxJQUFZLEVBQUE7QUFDckMsUUFBQSxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUM7O0FBR3pCOzs7Ozs7O0FBT0c7QUFDSCxJQUFBLE1BQU0sTUFBTSxHQUFBO0FBQ1YsUUFBQSxNQUFNLElBQUksS0FBSyxDQUFDLE9BQWlDLENBQUM7O0FBR3BEOzs7Ozs7O0FBT0c7QUFDSCxJQUFBLE9BQU8sTUFBTSxHQUFBO0FBQ1gsUUFBQSxNQUFNLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQzs7QUFFM0I7O0FDaEZEOzs7Ozs7Ozs7Ozs7QUFZRztBQUNHLE1BQU8sVUFBYyxTQUFRLEtBQUssQ0FBQTtJQVV0QyxXQUFZLENBQUEsSUFBTyxFQUFFLElBQVksRUFBQTtBQUMvQixRQUFBLEtBQUssQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDO0FBQ2pCLFFBQUEsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJOztBQUduQjs7Ozs7OztBQU9HO0FBQ00sSUFBQSxNQUFNLE1BQU0sR0FBQTtBQUNuQixRQUFBLE9BQU8sSUFBeUM7O0FBR2xEOzs7Ozs7O0FBT0c7QUFDSCxJQUFBLE9BQU8sQ0FBQyxJQUFPLEVBQUE7QUFDYixRQUFBLE1BQU0sSUFBSSxLQUFLLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQzs7QUFFbEM7O0FDdEREOzs7Ozs7Ozs7QUFTRztJQUNTO0FBQVosQ0FBQSxVQUFZLElBQUksRUFBQTs7QUFFZCxJQUFBLElBQUEsQ0FBQSxTQUFBLENBQUEsR0FBQSxXQUFxQjtBQUN2QixDQUFDLEVBSFcsSUFBSSxLQUFKLElBQUksR0FHZixFQUFBLENBQUEsQ0FBQTs7QUNWRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBMkJHO0FBQ2EsU0FBQSxTQUFTLENBQThCLEdBQUcsSUFBUyxFQUFBO0FBQ2pFLElBQUEsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQztBQUNwQixJQUFBLE9BQU8sSUFBSTtBQUNiOztBQ2xDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFvQkc7QUFLSDs7Ozs7O0FBTUc7QUFDSSxNQUFNLE9BQU8sR0FBRzs7OzsifQ==
925
+ export { MCP_FILE_NAME, McpUtils, McpWrapper, PACKAGE_NAME, VERSION, buildDocPrompts, buildResourceTemplates, enrich, getWorkspaceRoot, setWorkspaceRoot, tools };
926
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWNwLXNlcnZlci5lc20uY2pzIiwic291cmNlcyI6WyIuLi9zcmMvbWV0YWRhdGEudHMiLCIuLi9zcmMvbW9kdWxlcy9tY3AvZGVjb3JhdG9yLXRvb2xzLnRzIiwiLi4vc3JjL21vZHVsZXMvbWNwL21jcC1tb2R1bGUudHMiLCIuLi9zcmMvY29uc3RhbnRzLnRzIiwiLi4vc3JjL3V0aWxzLnRzIiwiLi4vc3JjL01jcFdyYXBwZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTWV0YWRhdGEgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRpb25cIjtcblxuLyoqXG4gKiBAY29uc3QgVkVSU0lPTlxuICogQG5hbWUgVkVSU0lPTlxuICogQGRlc2NyaXB0aW9uIFJlcHJlc2VudHMgdGhlIGN1cnJlbnQgdmVyc2lvbiBvZiB0aGUgdHMtd29ya3NwYWNlIG1vZHVsZS5cbiAqIEBzdW1tYXJ5IFRoZSBhY3R1YWwgdmVyc2lvbiBudW1iZXIgaXMgcmVwbGFjZWQgZHVyaW5nIHRoZSBidWlsZCBwcm9jZXNzLlxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuZXhwb3J0IGNvbnN0IFZFUlNJT04gPSBcIiMjVkVSU0lPTiMjXCI7XG5leHBvcnQgY29uc3QgUEFDS0FHRV9OQU1FID0gXCIjI1BBQ0tBR0VfTkFNRSMjXCI7XG5cbnRyeSB7XG4gIE1ldGFkYXRhLnJlZ2lzdGVyTGlicmFyeShQQUNLQUdFX05BTUUsIFZFUlNJT04pO1xufSBjYXRjaCAoZXJyb3IpIHtcbiAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IgJiYgZXJyb3IubWVzc2FnZS5pbmNsdWRlcyhcImFscmVhZHlcIikpIHtcbiAgICAvLyBJZ25vcmUgZHVwbGljYXRlIHJlZ2lzdHJhdGlvbiBkdXJpbmcgdGVzdHMvYnVuZGxpbmcgY2hlY2tzLlxuICB9IGVsc2Uge1xuICAgIHRocm93IGVycm9yO1xuICB9XG59XG4iLCJpbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuXG5leHBvcnQgdHlwZSBEZWNvcmF0b3JTcGVjID0ge1xuICBuYW1lOiBzdHJpbmc7XG4gIGFyZ3M/OiB1bmtub3duW107XG59O1xuXG5leHBvcnQgdHlwZSBBdHRyaWJ1dGVTcGVjID0ge1xuICBuYW1lOiBzdHJpbmc7XG4gIHR5cGU6IHN0cmluZztcbiAgZGVjb3JhdG9ycz86IERlY29yYXRvclNwZWNbXTtcbn07XG5cbmZ1bmN0aW9uIGVzY2FwZVJlZ0V4cCh2YWx1ZTogc3RyaW5nKSB7XG4gIHJldHVybiB2YWx1ZS5yZXBsYWNlKC9bLiorP14ke30oKXxbXFxdXFxcXF0vZywgXCJcXFxcJCZcIik7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdERlY29yYXRvcihzcGVjOiBEZWNvcmF0b3JTcGVjKTogc3RyaW5nIHtcbiAgY29uc3QgYXJncyA9IChzcGVjLmFyZ3MgfHwgW10pLm1hcCgoYXJnKSA9PiBKU09OLnN0cmluZ2lmeShhcmcpKS5qb2luKFwiLCBcIik7XG4gIHJldHVybiBgQCR7c3BlYy5uYW1lfSgke2FyZ3N9KWA7XG59XG5cbmZ1bmN0aW9uIGVuc3VyZURpcmVjdG9yeShmaWxlUGF0aDogc3RyaW5nKSB7XG4gIGZzLm1rZGlyU3luYyhwYXRoLmRpcm5hbWUoZmlsZVBhdGgpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbn1cblxuZnVuY3Rpb24gY29sbGVjdERlY29yYXRvck5hbWVzKFxuICBjbGFzc0RlY29yYXRvcnM6IERlY29yYXRvclNwZWNbXSB8IHVuZGVmaW5lZCxcbiAgcHJvcGVydGllczogQXR0cmlidXRlU3BlY1tdIHwgdW5kZWZpbmVkXG4pIHtcbiAgY29uc3QgbmFtZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgbmFtZXMuYWRkKFwibW9kZWxcIik7XG4gIGZvciAoY29uc3QgZGVjb3JhdG9yIG9mIGNsYXNzRGVjb3JhdG9ycyB8fCBbXSkge1xuICAgIG5hbWVzLmFkZChkZWNvcmF0b3IubmFtZSk7XG4gIH1cbiAgZm9yIChjb25zdCBwcm9wZXJ0eSBvZiBwcm9wZXJ0aWVzIHx8IFtdKSB7XG4gICAgZm9yIChjb25zdCBkZWNvcmF0b3Igb2YgcHJvcGVydHkuZGVjb3JhdG9ycyB8fCBbXSkge1xuICAgICAgbmFtZXMuYWRkKGRlY29yYXRvci5uYW1lKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG5hbWVzO1xufVxuXG5mdW5jdGlvbiBlbnN1cmVJbXBvcnQoXG4gIGNvbnRlbnQ6IHN0cmluZyxcbiAgaW1wb3J0c0Zyb206IHN0cmluZyxcbiAgZGVjb3JhdG9yczogU2V0PHN0cmluZz5cbikge1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICBpZiAoIWRlY29yYXRvcnMuc2l6ZSkgcmV0dXJuIGNvbnRlbnQ7XG4gIGNvbnN0IGltcG9ydFJlZ2V4ID0gbmV3IFJlZ0V4cChcbiAgICBgaW1wb3J0XFxcXHMrXFxcXHsoW159XSspXFxcXH1cXFxccytmcm9tXFxcXHMrW1wiJ10ke2VzY2FwZVJlZ0V4cChpbXBvcnRzRnJvbSl9W1wiJ107YFxuICApO1xuICBjb25zdCBtYXRjaCA9IGNvbnRlbnQubWF0Y2goaW1wb3J0UmVnZXgpO1xuICBjb25zdCBzb3J0ZWQgPSBBcnJheS5mcm9tKGRlY29yYXRvcnMpLnNvcnQoKTtcblxuICBpZiAobWF0Y2gpIHtcbiAgICBjb25zdCBleGlzdGluZyA9IG1hdGNoWzFdXG4gICAgICAuc3BsaXQoXCIsXCIpXG4gICAgICAubWFwKChuYW1lKSA9PiBuYW1lLnRyaW0oKSlcbiAgICAgIC5maWx0ZXIoQm9vbGVhbik7XG4gICAgY29uc3QgbWVyZ2VkID0gQXJyYXkuZnJvbShuZXcgU2V0KFsuLi5leGlzdGluZywgLi4uc29ydGVkXSkpLnNvcnQoKTtcbiAgICByZXR1cm4gY29udGVudC5yZXBsYWNlKFxuICAgICAgaW1wb3J0UmVnZXgsXG4gICAgICBgaW1wb3J0IHsgJHttZXJnZWQuam9pbihcIiwgXCIpfSB9IGZyb20gXCIke2ltcG9ydHNGcm9tfVwiO2BcbiAgICApO1xuICB9XG5cbiAgY29uc3QgaW1wb3J0TGluZSA9IGBpbXBvcnQgeyAke3NvcnRlZC5qb2luKFwiLCBcIil9IH0gZnJvbSBcIiR7aW1wb3J0c0Zyb219XCI7YDtcbiAgcmV0dXJuIGAke2ltcG9ydExpbmV9XFxuXFxuJHtjb250ZW50fWA7XG59XG5cbmZ1bmN0aW9uIGFkZFByb3BlcnR5QmxvY2socHJvcGVydHk6IEF0dHJpYnV0ZVNwZWMpIHtcbiAgY29uc3QgZGVjb3JhdG9ycyA9IChwcm9wZXJ0eS5kZWNvcmF0b3JzIHx8IFtdKVxuICAgIC5tYXAoZm9ybWF0RGVjb3JhdG9yKVxuICAgIC5qb2luKFwiXFxuICBcIik7XG4gIGNvbnN0IGRlY29yYXRvckJsb2NrID0gZGVjb3JhdG9ycyA/IGAgICR7ZGVjb3JhdG9yc31cXG5gIDogXCJcIjtcbiAgcmV0dXJuIGAke2RlY29yYXRvckJsb2NrfSAgJHtwcm9wZXJ0eS5uYW1lfTogJHtwcm9wZXJ0eS50eXBlfTtgO1xufVxuXG5mdW5jdGlvbiByZW1vdmVQcm9wZXJ0eUJsb2NrKGNvbnRlbnQ6IHN0cmluZywgcHJvcGVydHlOYW1lOiBzdHJpbmcpIHtcbiAgY29uc3QgbGluZXMgPSBjb250ZW50LnNwbGl0KC9cXHI/XFxuLyk7XG4gIGNvbnN0IHJlc3VsdDogc3RyaW5nW10gPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGxpbmUgPSBsaW5lc1tpXTtcbiAgICBpZiAoXG4gICAgICBsaW5lLnRyaW0oKS5zdGFydHNXaXRoKGBAYCkgJiZcbiAgICAgIGxpbmVzW2kgKyAxXT8uaW5jbHVkZXMoYCR7cHJvcGVydHlOYW1lfTpgKVxuICAgICkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmIChsaW5lLmluY2x1ZGVzKGAke3Byb3BlcnR5TmFtZX06YCkpIHtcbiAgICAgIC8vIHNraXAgdGhpcyBsaW5lIGFuZCBhbnkgdHJhaWxpbmcgYmxhbmsgbGluZVxuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIHJlc3VsdC5wdXNoKGxpbmUpO1xuICB9XG4gIHJldHVybiByZXN1bHQuam9pbihcIlxcblwiKTtcbn1cblxuZnVuY3Rpb24gaW5zZXJ0RGVjb3JhdG9yKFxuICBjb250ZW50OiBzdHJpbmcsXG4gIGRlY29yYXRvcjogRGVjb3JhdG9yU3BlYyxcbiAgdGFyZ2V0OiB7XG4gICAga2luZDogXCJjbGFzc1wiIHwgXCJwcm9wZXJ0eVwiO1xuICAgIG5hbWU/OiBzdHJpbmc7XG4gIH1cbikge1xuICBjb25zdCBkZWNvcmF0b3JMaW5lID0gZm9ybWF0RGVjb3JhdG9yKGRlY29yYXRvcik7XG4gIGlmICh0YXJnZXQua2luZCA9PT0gXCJjbGFzc1wiKSB7XG4gICAgY29uc3QgY2xhc3NSZWdleCA9IC8oZXhwb3J0XFxzK2NsYXNzXFxzK1teXFxze10rXFxzKlxceykvO1xuICAgIGlmIChjb250ZW50LmluY2x1ZGVzKGRlY29yYXRvckxpbmUpKSByZXR1cm4gY29udGVudDtcbiAgICByZXR1cm4gY29udGVudC5yZXBsYWNlKGNsYXNzUmVnZXgsIGAke2RlY29yYXRvckxpbmV9XFxuJDFgKTtcbiAgfVxuICBpZiAoIXRhcmdldC5uYW1lKSByZXR1cm4gY29udGVudDtcbiAgY29uc3QgcHJvcGVydHlSZWdleCA9IG5ldyBSZWdFeHAoXG4gICAgYCheXFxcXHMqKSg/OkAuKlxcXFxuXFxcXDEpKiR7ZXNjYXBlUmVnRXhwKHRhcmdldC5uYW1lKX06YCxcbiAgICBcIm1cIlxuICApO1xuICBjb25zdCBtYXRjaCA9IHByb3BlcnR5UmVnZXguZXhlYyhjb250ZW50KTtcbiAgaWYgKCFtYXRjaCkgcmV0dXJuIGNvbnRlbnQ7XG4gIGNvbnN0IGluZGVudCA9IG1hdGNoWzFdIHx8IFwiICBcIjtcbiAgaWYgKGNvbnRlbnQuaW5jbHVkZXMoYCR7aW5kZW50fSR7ZGVjb3JhdG9yTGluZX1gKSkgcmV0dXJuIGNvbnRlbnQ7XG4gIHJldHVybiAoXG4gICAgY29udGVudC5zbGljZSgwLCBtYXRjaC5pbmRleCkgK1xuICAgIGAke2luZGVudH0ke2RlY29yYXRvckxpbmV9XFxuYCArXG4gICAgY29udGVudC5zbGljZShtYXRjaC5pbmRleClcbiAgKTtcbn1cblxuZnVuY3Rpb24gcmVtb3ZlRGVjb3JhdG9yKFxuICBjb250ZW50OiBzdHJpbmcsXG4gIGRlY29yYXRvck5hbWU6IHN0cmluZyxcbiAgdGFyZ2V0OiB7XG4gICAga2luZDogXCJjbGFzc1wiIHwgXCJwcm9wZXJ0eVwiO1xuICAgIG5hbWU/OiBzdHJpbmc7XG4gIH1cbikge1xuICBjb25zdCBkZWNvcmF0b3JSZWdleCA9IG5ldyBSZWdFeHAoXG4gICAgYF5cXFxccypAJHtlc2NhcGVSZWdFeHAoZGVjb3JhdG9yTmFtZSl9XFxcXChbXildKlxcXFwpYCxcbiAgICBcIm1cIlxuICApO1xuICBpZiAodGFyZ2V0LmtpbmQgPT09IFwiY2xhc3NcIikge1xuICAgIHJldHVybiBjb250ZW50LnJlcGxhY2UoZGVjb3JhdG9yUmVnZXgsIFwiXCIpO1xuICB9XG4gIGlmICh0YXJnZXQubmFtZSkge1xuICAgIGNvbnN0IHBhdHRlcm4gPSBuZXcgUmVnRXhwKFxuICAgICAgYCheXFxcXHMqQCR7ZXNjYXBlUmVnRXhwKGRlY29yYXRvck5hbWUpfVxcXFwoW14pXSpcXFxcKVxcXFxzKiRcXFxcbikoPz1cXFxccyoke2VzY2FwZVJlZ0V4cCh0YXJnZXQubmFtZSl9OilgLFxuICAgICAgXCJtXCJcbiAgICApO1xuICAgIHJldHVybiBjb250ZW50LnJlcGxhY2UocGF0dGVybiwgXCJcIik7XG4gIH1cbiAgcmV0dXJuIGNvbnRlbnQ7XG59XG5cbmZ1bmN0aW9uIHdyaXRlSWZDaGFuZ2VkKGZpbGVQYXRoOiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZykge1xuICBlbnN1cmVEaXJlY3RvcnkoZmlsZVBhdGgpO1xuICBmcy53cml0ZUZpbGVTeW5jKGZpbGVQYXRoLCBjb250ZW50KTtcbn1cblxuZXhwb3J0IGNvbnN0IGRlY29yYXRvclRvb2xzID0ge1xuICBjcmVhdGVPclVwZGF0ZU1vZGVsVG9vbDoge1xuICAgIG5hbWU6IFwiY3JlYXRlLW9yLXVwZGF0ZS1tb2RlbFwiLFxuICAgIGRlc2NyaXB0aW9uOiBcIkNyZWF0ZSBvciB1cGRhdGUgYSB2YWxpZGF0aW9uLXJlYWR5IG1vZGVsIGNsYXNzXCIsXG4gICAgZXhlY3V0ZTogYXN5bmMgKGFyZ3M6IHtcbiAgICAgIGZpbGVQYXRoOiBzdHJpbmc7XG4gICAgICBjbGFzc05hbWU6IHN0cmluZztcbiAgICAgIGNsYXNzRGVjb3JhdG9ycz86IERlY29yYXRvclNwZWNbXTtcbiAgICAgIHByb3BlcnRpZXM6IEF0dHJpYnV0ZVNwZWNbXTtcbiAgICAgIGltcG9ydHNGcm9tOiBzdHJpbmc7XG4gICAgICBvdmVyd3JpdGU/OiBib29sZWFuO1xuICAgIH0pID0+IHtcbiAgICAgIGlmICghYXJncy5vdmVyd3JpdGUgJiYgZnMuZXhpc3RzU3luYyhhcmdzLmZpbGVQYXRoKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZpbGUgYWxyZWFkeSBleGlzdHMgYXQgJHthcmdzLmZpbGVQYXRofWApO1xuICAgICAgfVxuICAgICAgY29uc3QgZGVjb3JhdG9ycyA9IGNvbGxlY3REZWNvcmF0b3JOYW1lcyhcbiAgICAgICAgYXJncy5jbGFzc0RlY29yYXRvcnMsXG4gICAgICAgIGFyZ3MucHJvcGVydGllc1xuICAgICAgKTtcbiAgICAgIGxldCBjb250ZW50ID0gYEBtb2RlbCgpYDtcbiAgICAgIGZvciAoY29uc3QgZGVjb3JhdG9yIG9mIGFyZ3MuY2xhc3NEZWNvcmF0b3JzIHx8IFtdKSB7XG4gICAgICAgIGNvbnRlbnQgKz0gYFxcbiR7Zm9ybWF0RGVjb3JhdG9yKGRlY29yYXRvcil9YDtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHByb3BlcnRpZXMgPSAoYXJncy5wcm9wZXJ0aWVzIHx8IFtdKVxuICAgICAgICAubWFwKGFkZFByb3BlcnR5QmxvY2spXG4gICAgICAgIC5qb2luKFwiXFxuXFxuXCIpO1xuICAgICAgY29udGVudCArPSBgXFxuZXhwb3J0IGNsYXNzICR7YXJncy5jbGFzc05hbWV9IHtcXG4ke3Byb3BlcnRpZXMgPyBgJHtwcm9wZXJ0aWVzfVxcbmAgOiBcIlwifX1cXG5gO1xuICAgICAgY29udGVudCA9IGVuc3VyZUltcG9ydChjb250ZW50LCBhcmdzLmltcG9ydHNGcm9tLCBkZWNvcmF0b3JzKTtcbiAgICAgIHdyaXRlSWZDaGFuZ2VkKGFyZ3MuZmlsZVBhdGgsIGNvbnRlbnQpO1xuICAgICAgcmV0dXJuIHsgZmlsZVBhdGg6IGFyZ3MuZmlsZVBhdGggfTtcbiAgICB9LFxuICB9LFxuICBhZGRBdHRyaWJ1dGVUb29sOiB7XG4gICAgbmFtZTogXCJhZGQtYXR0cmlidXRlXCIsXG4gICAgZGVzY3JpcHRpb246IFwiQWRkIGEgZGVjb3JhdGVkIGF0dHJpYnV0ZSB0byBhbiBleGlzdGluZyBtb2RlbFwiLFxuICAgIGV4ZWN1dGU6IGFzeW5jIChhcmdzOiB7XG4gICAgICBmaWxlUGF0aDogc3RyaW5nO1xuICAgICAgY2xhc3NOYW1lOiBzdHJpbmc7XG4gICAgICBhdHRyaWJ1dGU6IEF0dHJpYnV0ZVNwZWM7XG4gICAgICBpbXBvcnRzRnJvbTogc3RyaW5nO1xuICAgIH0pID0+IHtcbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyhhcmdzLmZpbGVQYXRoKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE1vZGVsIGZpbGUgbm90IGZvdW5kIGF0ICR7YXJncy5maWxlUGF0aH1gKTtcbiAgICAgIH1cbiAgICAgIGxldCBjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKGFyZ3MuZmlsZVBhdGgsIFwidXRmOFwiKTtcbiAgICAgIGlmIChjb250ZW50LmluY2x1ZGVzKGAke2FyZ3MuYXR0cmlidXRlLm5hbWV9OmApKSB7XG4gICAgICAgIHJldHVybiB7IGZpbGVQYXRoOiBhcmdzLmZpbGVQYXRoIH07XG4gICAgICB9XG4gICAgICBjb25zdCBkZWNvcmF0b3JzID0gY29sbGVjdERlY29yYXRvck5hbWVzKHVuZGVmaW5lZCwgW2FyZ3MuYXR0cmlidXRlXSk7XG4gICAgICBjb250ZW50ID0gZW5zdXJlSW1wb3J0KGNvbnRlbnQsIGFyZ3MuaW1wb3J0c0Zyb20sIGRlY29yYXRvcnMpO1xuICAgICAgY29uc3QgaW5zZXJ0aW9uUG9pbnQgPSBjb250ZW50Lmxhc3RJbmRleE9mKFwifVwiKTtcbiAgICAgIGNvbnN0IGJsb2NrID0gYWRkUHJvcGVydHlCbG9jayhhcmdzLmF0dHJpYnV0ZSk7XG4gICAgICBjb25zdCBiZWZvcmUgPSBjb250ZW50LnNsaWNlKDAsIGluc2VydGlvblBvaW50KS5yZXBsYWNlKC9cXHMqJC8sIFwiXCIpO1xuICAgICAgY29uc3QgYWZ0ZXIgPSBjb250ZW50LnNsaWNlKGluc2VydGlvblBvaW50KTtcbiAgICAgIGNvbnN0IHVwZGF0ZWQgPSBgJHtiZWZvcmV9XFxuJHtibG9ja31cXG4ke2FmdGVyfWA7XG4gICAgICB3cml0ZUlmQ2hhbmdlZChhcmdzLmZpbGVQYXRoLCB1cGRhdGVkKTtcbiAgICAgIHJldHVybiB7IGZpbGVQYXRoOiBhcmdzLmZpbGVQYXRoIH07XG4gICAgfSxcbiAgfSxcbiAgcmVtb3ZlQXR0cmlidXRlVG9vbDoge1xuICAgIG5hbWU6IFwicmVtb3ZlLWF0dHJpYnV0ZVwiLFxuICAgIGRlc2NyaXB0aW9uOiBcIlJlbW92ZSBhbiBhdHRyaWJ1dGUgZnJvbSBhIG1vZGVsIGNsYXNzXCIsXG4gICAgZXhlY3V0ZTogYXN5bmMgKGFyZ3M6IHtcbiAgICAgIGZpbGVQYXRoOiBzdHJpbmc7XG4gICAgICBjbGFzc05hbWU6IHN0cmluZztcbiAgICAgIGF0dHJpYnV0ZU5hbWU6IHN0cmluZztcbiAgICB9KSA9PiB7XG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoYXJncy5maWxlUGF0aCkpIHJldHVybiB7IGZpbGVQYXRoOiBhcmdzLmZpbGVQYXRoIH07XG4gICAgICBjb25zdCBjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKGFyZ3MuZmlsZVBhdGgsIFwidXRmOFwiKTtcbiAgICAgIGNvbnN0IHVwZGF0ZWQgPSByZW1vdmVQcm9wZXJ0eUJsb2NrKGNvbnRlbnQsIGFyZ3MuYXR0cmlidXRlTmFtZSk7XG4gICAgICB3cml0ZUlmQ2hhbmdlZChhcmdzLmZpbGVQYXRoLCB1cGRhdGVkKTtcbiAgICAgIHJldHVybiB7IGZpbGVQYXRoOiBhcmdzLmZpbGVQYXRoIH07XG4gICAgfSxcbiAgfSxcbiAgYXBwbHlEZWNvcmF0b3JUb29sOiB7XG4gICAgbmFtZTogXCJhcHBseS1kZWNvcmF0b3JcIixcbiAgICBkZXNjcmlwdGlvbjogXCJBcHBseSBhIGRlY29yYXRvciB0byBhIGNsYXNzIG9yIHByb3BlcnR5XCIsXG4gICAgZXhlY3V0ZTogYXN5bmMgKGFyZ3M6IHtcbiAgICAgIGZpbGVQYXRoOiBzdHJpbmc7XG4gICAgICBjbGFzc05hbWU6IHN0cmluZztcbiAgICAgIHRhcmdldDogeyBraW5kOiBcImNsYXNzXCIgfCBcInByb3BlcnR5XCI7IG5hbWU/OiBzdHJpbmcgfTtcbiAgICAgIGRlY29yYXRvcjogRGVjb3JhdG9yU3BlYztcbiAgICAgIGltcG9ydHNGcm9tOiBzdHJpbmc7XG4gICAgfSkgPT4ge1xuICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKGFyZ3MuZmlsZVBhdGgpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTW9kZWwgZmlsZSBub3QgZm91bmQgYXQgJHthcmdzLmZpbGVQYXRofWApO1xuICAgICAgfVxuICAgICAgbGV0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoYXJncy5maWxlUGF0aCwgXCJ1dGY4XCIpO1xuICAgICAgY29uc3QgZGVjb3JhdG9ycyA9IG5ldyBTZXQ8c3RyaW5nPihbYXJncy5kZWNvcmF0b3IubmFtZV0pO1xuICAgICAgY29udGVudCA9IGVuc3VyZUltcG9ydChjb250ZW50LCBhcmdzLmltcG9ydHNGcm9tLCBkZWNvcmF0b3JzKTtcbiAgICAgIGNvbnRlbnQgPSBpbnNlcnREZWNvcmF0b3IoY29udGVudCwgYXJncy5kZWNvcmF0b3IsIGFyZ3MudGFyZ2V0KTtcbiAgICAgIHdyaXRlSWZDaGFuZ2VkKGFyZ3MuZmlsZVBhdGgsIGNvbnRlbnQpO1xuICAgICAgcmV0dXJuIHsgZmlsZVBhdGg6IGFyZ3MuZmlsZVBhdGggfTtcbiAgICB9LFxuICB9LFxuICByZW1vdmVEZWNvcmF0b3JUb29sOiB7XG4gICAgbmFtZTogXCJyZW1vdmUtZGVjb3JhdG9yXCIsXG4gICAgZGVzY3JpcHRpb246IFwiUmVtb3ZlIGEgZGVjb3JhdG9yIGZyb20gYSBjbGFzcyBvciBwcm9wZXJ0eVwiLFxuICAgIGV4ZWN1dGU6IGFzeW5jIChhcmdzOiB7XG4gICAgICBmaWxlUGF0aDogc3RyaW5nO1xuICAgICAgY2xhc3NOYW1lOiBzdHJpbmc7XG4gICAgICB0YXJnZXQ6IHsga2luZDogXCJjbGFzc1wiIHwgXCJwcm9wZXJ0eVwiOyBuYW1lPzogc3RyaW5nIH07XG4gICAgICBkZWNvcmF0b3JOYW1lOiBzdHJpbmc7XG4gICAgfSkgPT4ge1xuICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKGFyZ3MuZmlsZVBhdGgpKSByZXR1cm4geyBmaWxlUGF0aDogYXJncy5maWxlUGF0aCB9O1xuICAgICAgbGV0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoYXJncy5maWxlUGF0aCwgXCJ1dGY4XCIpO1xuICAgICAgY29udGVudCA9IHJlbW92ZURlY29yYXRvcihjb250ZW50LCBhcmdzLmRlY29yYXRvck5hbWUsIGFyZ3MudGFyZ2V0KTtcbiAgICAgIHdyaXRlSWZDaGFuZ2VkKGFyZ3MuZmlsZVBhdGgsIGNvbnRlbnQpO1xuICAgICAgcmV0dXJuIHsgZmlsZVBhdGg6IGFyZ3MuZmlsZVBhdGggfTtcbiAgICB9LFxuICB9LFxuICBzY2FmZm9sZFZhbGlkYXRvclRvb2w6IHtcbiAgICBuYW1lOiBcInNjYWZmb2xkLXZhbGlkYXRvclwiLFxuICAgIGRlc2NyaXB0aW9uOiBcIlNjYWZmb2xkIGEgdmFsaWRhdG9yIGNsYXNzIGFuZCBvcHRpb25hbCBkZWNvcmF0b3JcIixcbiAgICBleGVjdXRlOiBhc3luYyAoYXJnczoge1xuICAgICAgdmFsaWRhdG9yc0Rpcjogc3RyaW5nO1xuICAgICAgZGVjb3JhdG9yRGlyPzogc3RyaW5nO1xuICAgICAgbmFtZTogc3RyaW5nO1xuICAgIH0pID0+IHtcbiAgICAgIGNvbnN0IGNsYXNzRmlsZSA9IHBhdGguam9pbihhcmdzLnZhbGlkYXRvcnNEaXIsIGAke2FyZ3MubmFtZX0udHNgKTtcbiAgICAgIGVuc3VyZURpcmVjdG9yeShjbGFzc0ZpbGUpO1xuICAgICAgY29uc3QgY2xhc3NDb250ZW50ID0gYGV4cG9ydCBjbGFzcyAke2FyZ3MubmFtZX0ge1xcbiAgdmFsaWRhdGUodmFsdWU6IHVua25vd24pOiBib29sZWFuIHtcXG4gICAgcmV0dXJuIHZhbHVlICE9PSB1bmRlZmluZWQ7XFxuICB9XFxufVxcbmA7XG4gICAgICBmcy53cml0ZUZpbGVTeW5jKGNsYXNzRmlsZSwgY2xhc3NDb250ZW50KTtcbiAgICAgIGxldCBkZWNvcmF0b3JGaWxlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgICBpZiAoYXJncy5kZWNvcmF0b3JEaXIpIHtcbiAgICAgICAgZGVjb3JhdG9yRmlsZSA9IHBhdGguam9pbihcbiAgICAgICAgICBhcmdzLmRlY29yYXRvckRpcixcbiAgICAgICAgICBgJHthcmdzLm5hbWV9RGVjb3JhdG9yLnRzYFxuICAgICAgICApO1xuICAgICAgICBlbnN1cmVEaXJlY3RvcnkoZGVjb3JhdG9yRmlsZSk7XG4gICAgICAgIGZzLndyaXRlRmlsZVN5bmMoXG4gICAgICAgICAgZGVjb3JhdG9yRmlsZSxcbiAgICAgICAgICBgZXhwb3J0IGZ1bmN0aW9uICR7YXJncy5uYW1lfURlY29yYXRvcigpIHtcXG4gIHJldHVybiAoKSA9PiB2b2lkIDA7XFxufVxcbmBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7IGNsYXNzRmlsZSwgZGVjb3JhdG9yRmlsZSB9O1xuICAgIH0sXG4gIH0sXG4gIHNjYWZmb2xkU2VyaWFsaXplclRvb2w6IHtcbiAgICBuYW1lOiBcInNjYWZmb2xkLXNlcmlhbGl6ZXJcIixcbiAgICBkZXNjcmlwdGlvbjogXCJTY2FmZm9sZCBhIHNlcmlhbGl6ZXIgY2xhc3MgYW5kIG9wdGlvbmFsIHJlZ2lzdHJ5XCIsXG4gICAgZXhlY3V0ZTogYXN5bmMgKGFyZ3M6IHtcbiAgICAgIGRpcjogc3RyaW5nO1xuICAgICAgbmFtZTogc3RyaW5nO1xuICAgICAgcmVnaXN0ZXJEaXI/OiBzdHJpbmc7XG4gICAgICBzZXREZWZhdWx0PzogYm9vbGVhbjtcbiAgICB9KSA9PiB7XG4gICAgICBjb25zdCBjbGFzc0ZpbGUgPSBwYXRoLmpvaW4oYXJncy5kaXIsIGAke2FyZ3MubmFtZX0udHNgKTtcbiAgICAgIGVuc3VyZURpcmVjdG9yeShjbGFzc0ZpbGUpO1xuICAgICAgZnMud3JpdGVGaWxlU3luYyhcbiAgICAgICAgY2xhc3NGaWxlLFxuICAgICAgICBgZXhwb3J0IGNsYXNzICR7YXJncy5uYW1lfSB7XFxuICBzZXJpYWxpemUodmFsdWU6IHVua25vd24pOiBzdHJpbmcge1xcbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodmFsdWUpO1xcbiAgfVxcbn1cXG5gXG4gICAgICApO1xuICAgICAgbGV0IHJlZ2lzdGVyRmlsZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKGFyZ3MucmVnaXN0ZXJEaXIpIHtcbiAgICAgICAgcmVnaXN0ZXJGaWxlID0gcGF0aC5qb2luKGFyZ3MucmVnaXN0ZXJEaXIsIGAke2FyZ3MubmFtZX1SZWdpc3Rlci50c2ApO1xuICAgICAgICBlbnN1cmVEaXJlY3RvcnkocmVnaXN0ZXJGaWxlKTtcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyhcbiAgICAgICAgICByZWdpc3RlckZpbGUsXG4gICAgICAgICAgYGV4cG9ydCBmdW5jdGlvbiByZWdpc3RlciR7YXJncy5uYW1lfSgpIHtcXG4gIHJldHVybiAke2FyZ3Muc2V0RGVmYXVsdCA/IFwiJ2RlZmF1bHQnXCIgOiBcIidvcHRpb25hbCdcIn07XFxufVxcbmBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7IGNsYXNzRmlsZSwgcmVnaXN0ZXJGaWxlIH07XG4gICAgfSxcbiAgfSxcbiAgc2NhZmZvbGRIYXNoaW5nVG9vbDoge1xuICAgIG5hbWU6IFwic2NhZmZvbGQtaGFzaGluZ1wiLFxuICAgIGRlc2NyaXB0aW9uOiBcIlNjYWZmb2xkIGEgaGFzaGluZyBmdW5jdGlvbiBhbmQgb3B0aW9uYWwgcmVnaXN0cnlcIixcbiAgICBleGVjdXRlOiBhc3luYyAoYXJnczoge1xuICAgICAgZGlyOiBzdHJpbmc7XG4gICAgICBuYW1lOiBzdHJpbmc7XG4gICAgICByZWdpc3RlckRpcj86IHN0cmluZztcbiAgICAgIHNldERlZmF1bHQ/OiBib29sZWFuO1xuICAgIH0pID0+IHtcbiAgICAgIGNvbnN0IGZ1bmN0aW9uRmlsZSA9IHBhdGguam9pbihhcmdzLmRpciwgYCR7YXJncy5uYW1lfS50c2ApO1xuICAgICAgZW5zdXJlRGlyZWN0b3J5KGZ1bmN0aW9uRmlsZSk7XG4gICAgICBmcy53cml0ZUZpbGVTeW5jKFxuICAgICAgICBmdW5jdGlvbkZpbGUsXG4gICAgICAgIGBleHBvcnQgZnVuY3Rpb24gJHthcmdzLm5hbWV9KHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcge1xcbiAgcmV0dXJuIHZhbHVlLnNwbGl0KCcnKS5yZXZlcnNlKCkuam9pbignJyk7XFxufVxcbmBcbiAgICAgICk7XG4gICAgICBsZXQgcmVnaXN0ZXJGaWxlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgICBpZiAoYXJncy5yZWdpc3RlckRpcikge1xuICAgICAgICByZWdpc3RlckZpbGUgPSBwYXRoLmpvaW4oYXJncy5yZWdpc3RlckRpciwgYCR7YXJncy5uYW1lfVJlZ2lzdGVyLnRzYCk7XG4gICAgICAgIGVuc3VyZURpcmVjdG9yeShyZWdpc3RlckZpbGUpO1xuICAgICAgICBmcy53cml0ZUZpbGVTeW5jKFxuICAgICAgICAgIHJlZ2lzdGVyRmlsZSxcbiAgICAgICAgICBgZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyJHthcmdzLm5hbWV9KCkge1xcbiAgcmV0dXJuICR7YXJncy5zZXREZWZhdWx0ID8gXCInZGVmYXVsdCdcIiA6IFwiJ29wdGlvbmFsJ1wifTtcXG59XFxuYFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHsgZnVuY3Rpb25GaWxlLCByZWdpc3RlckZpbGUgfTtcbiAgICB9LFxuICB9LFxufSBhcyBjb25zdDtcblxuZXhwb3J0IHR5cGUgRGVjb3JhdG9yVG9vbHMgPSB0eXBlb2YgZGVjb3JhdG9yVG9vbHM7XG4iLCJpbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHR5cGUgeyBGYXN0TUNQLCBDb250ZW50UmVzdWx0LCBJbnB1dFByb21wdCwgVG9vbCB9IGZyb20gXCJmYXN0bWNwXCI7XG5pbXBvcnQgeyBhcHBseVBhdGNoLCBjcmVhdGVUd29GaWxlc1BhdGNoIH0gZnJvbSBcImRpZmZcIjtcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5pbXBvcnQgeyBQQUNLQUdFX05BTUUgYXMgUEtHLCBWRVJTSU9OIGFzIFYgfSBmcm9tIFwiLi4vLi4vbWV0YWRhdGFcIjtcbmltcG9ydCB7IGRlY29yYXRvclRvb2xzIH0gZnJvbSBcIi4vZGVjb3JhdG9yLXRvb2xzXCI7XG5cbmNvbnN0IFdPUktTUEFDRV9ST09UX0VOViA9IFwiTUNQX1dPUktTUEFDRV9ST09UXCI7XG5jb25zdCBQUk9NUFRfRElSRUNUT1JJRVMgPSBbXCIuY29kZS9wcm9tcHRzXCIsIFwiLmNvZGV4L3Byb21wdHNcIl07XG5jb25zdCBERUZBVUxUX1BST01QVF9OQU1FID0gXCJkb2NcIjtcbmNvbnN0IENMSUVOVF9JTlRFR1JBVElPTlMgPSBbXG4gIHtcbiAgICBpZDogXCJ2c2NvZGVcIixcbiAgICBkaXNwbGF5OiBcIlZpc3VhbCBTdHVkaW8gQ29kZVwiLFxuICAgIGluc3RydWN0aW9uczpcbiAgICAgIFwiV2hlbiBpbnRlcmFjdGluZyBmcm9tIFZpc3VhbCBTdHVkaW8gQ29kZSwgcHJlZmVyIHRoZSB2c2NvZGU6Ly93b3Jrc3BhY2Uve3BhdGh9IHJlc291cmNlIHRlbXBsYXRlIHRvIGZldGNoIGZpbGUgY29udGVudHMgYW5kIHVzZSB0aGUgYXBwbHktY29kZS1jaGFuZ2UgdG9vbCB0byBjb21taXQgZWRpdHMgd2l0aCBwcmV2aWV3YWJsZSBkaWZmcy5cIixcbiAgfSxcbiAge1xuICAgIGlkOiBcImN1cnNvclwiLFxuICAgIGRpc3BsYXk6IFwiQ3Vyc29yXCIsXG4gICAgaW5zdHJ1Y3Rpb25zOlxuICAgICAgXCJDdXJzb3IgY2xpZW50cyBjYW4gcmV0cmlldmUgYW5kIHVwZGF0ZSBmaWxlcyB0aHJvdWdoIHRoZSBjdXJzb3I6Ly93b3Jrc3BhY2Uve3BhdGh9IHJlc291cmNlIHRlbXBsYXRlLiBBbHdheXMgdmFsaWRhdGUgcGF0Y2hlcyBpbiBkcnlSdW4gbW9kZSBiZWZvcmUgYXBwbHlpbmcgcGVybWFuZW50IGNoYW5nZXMuXCIsXG4gIH0sXG4gIHtcbiAgICBpZDogXCJjb3BpbG90XCIsXG4gICAgZGlzcGxheTogXCJHaXRIdWIgQ29waWxvdFwiLFxuICAgIGluc3RydWN0aW9uczpcbiAgICAgIFwiVXNlIHRoZSBjb3BpbG90Oi8vd29ya3NwYWNlL3twYXRofSByZXNvdXJjZSB0ZW1wbGF0ZSB0byBzdHJlYW0gZmlsZSBjb250ZW50IGludG8gQ29waWxvdCBjaGF0IHNlc3Npb25zLiBQcmVmZXIgcmV0dXJuaW5nIHVuaWZpZWQgZGlmZnMgdG8gbWFpbnRhaW4gYWxpZ25tZW50IHdpdGggQ29waWxvdCdzIGRpZmYgdmlzdWFsaXphdGlvbi5cIixcbiAgfSxcbl0gYXMgY29uc3Q7XG5cbmNvbnN0IGRvY3VtZW50Q29kZVNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgZmlsZVBhdGg6IHouc3RyaW5nKCkubWluKDEsIFwiZmlsZVBhdGggaXMgcmVxdWlyZWRcIiksXG4gICAgcHJvbXB0TmFtZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICAgIGluY2x1ZGVQcm9tcHQ6IHouYm9vbGVhbigpLmRlZmF1bHQodHJ1ZSksXG4gICAgaW5jbHVkZUNvZGU6IHouYm9vbGVhbigpLmRlZmF1bHQodHJ1ZSksXG4gICAgaW5jbHVkZU1ldGFkYXRhOiB6LmJvb2xlYW4oKS5kZWZhdWx0KHRydWUpLFxuICAgIGFkZGl0aW9uYWxDb250ZXh0OiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gICAgZW5jb2Rpbmc6IHouc3RyaW5nKCkuZGVmYXVsdChcInV0ZjhcIiksXG4gIH0pXG4gIC5zdHJpY3QoKTtcblxudHlwZSBEb2N1bWVudENvZGVBcmdzID0gei5pbmZlcjx0eXBlb2YgZG9jdW1lbnRDb2RlU2NoZW1hPjtcblxuY29uc3QgY29kZUNoYW5nZVNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgZmlsZVBhdGg6IHouc3RyaW5nKCkubWluKDEsIFwiZmlsZVBhdGggaXMgcmVxdWlyZWRcIiksXG4gICAgcGF0Y2g6IHouc3RyaW5nKCkubWluKDEsIFwicGF0Y2ggaXMgcmVxdWlyZWRcIiksXG4gICAgZHJ5UnVuOiB6LmJvb2xlYW4oKS5kZWZhdWx0KGZhbHNlKSxcbiAgICBzaG93RGlmZjogei5ib29sZWFuKCkuZGVmYXVsdCh0cnVlKSxcbiAgICBkaWZmQ29udGV4dDogei5udW1iZXIoKS5pbnQoKS5taW4oMCkubWF4KDEwMCkuZGVmYXVsdCgzKSxcbiAgICBlbmNvZGluZzogei5zdHJpbmcoKS5kZWZhdWx0KFwidXRmOFwiKSxcbiAgfSlcbiAgLnN0cmljdCgpO1xuXG50eXBlIEFwcGx5Q29kZUNoYW5nZUFyZ3MgPSB6LmluZmVyPHR5cGVvZiBjb2RlQ2hhbmdlU2NoZW1hPjtcblxudHlwZSBEb2NQcm9tcHQgPSB7XG4gIG5hbWU6IHN0cmluZztcbiAgdGl0bGU6IHN0cmluZztcbiAgZGVzY3JpcHRpb246IHN0cmluZztcbiAgY29udGVudDogc3RyaW5nO1xuICBhYnNvbHV0ZVBhdGg6IHN0cmluZztcbn07XG5cbnR5cGUgV29ya3NwYWNlUmVzb3VyY2VUZW1wbGF0ZSA9IHtcbiAgbmFtZTogc3RyaW5nO1xuICBkZXNjcmlwdGlvbjogc3RyaW5nO1xuICB1cmlUZW1wbGF0ZTogc3RyaW5nO1xuICBtaW1lVHlwZTogc3RyaW5nO1xuICBhcmd1bWVudHM6IFJlYWRvbmx5QXJyYXk8e1xuICAgIG5hbWU6IHN0cmluZztcbiAgICBkZXNjcmlwdGlvbjogc3RyaW5nO1xuICAgIHJlcXVpcmVkOiBib29sZWFuO1xuICB9PjtcbiAgbG9hZDogKGFyZ3M6IHsgcGF0aDogc3RyaW5nIH0pID0+IFByb21pc2U8eyB0ZXh0OiBzdHJpbmcgfT47XG59O1xuXG5sZXQgd29ya3NwYWNlUm9vdCA9IGluaXRpYWxpemVXb3Jrc3BhY2VSb290KCk7XG5sZXQgdXNlckVycm9yQ3RvcjogKG5ldyAobWVzc2FnZTogc3RyaW5nKSA9PiBFcnJvcikgfCB1bmRlZmluZWQ7XG5cbmNsYXNzIFdvcmtzcGFjZUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICB0aGlzLm5hbWUgPSBcIldvcmtzcGFjZUVycm9yXCI7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0VXNlckVycm9yQ3RvcigpOiBQcm9taXNlPG5ldyAobWVzc2FnZTogc3RyaW5nKSA9PiBFcnJvcj4ge1xuICBpZiAoIXVzZXJFcnJvckN0b3IpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgbW9kID0gYXdhaXQgaW1wb3J0KFwiZmFzdG1jcFwiKTtcbiAgICAgIHVzZXJFcnJvckN0b3IgPSAobW9kIGFzIHsgVXNlckVycm9yOiBuZXcgKG1lc3NhZ2U6IHN0cmluZykgPT4gRXJyb3IgfSlcbiAgICAgICAgLlVzZXJFcnJvcjtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHVzZXJFcnJvckN0b3IgPSBjbGFzcyBNQ1BVc2VyRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZykge1xuICAgICAgICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgICAgICAgIHRoaXMubmFtZSA9IFwiTUNQVXNlckVycm9yXCI7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfVxuICB9XG4gIHJldHVybiB1c2VyRXJyb3JDdG9yO1xufVxuXG5hc3luYyBmdW5jdGlvbiB0aHJvd1VzZXJFcnJvcihtZXNzYWdlOiBzdHJpbmcpOiBQcm9taXNlPG5ldmVyPiB7XG4gIGNvbnN0IEN0b3IgPSBhd2FpdCBnZXRVc2VyRXJyb3JDdG9yKCk7XG4gIHRocm93IG5ldyBDdG9yKG1lc3NhZ2UpO1xufVxuXG5jb25zdCBkb2N1bWVudENvZGVUb29sOiBUb29sPHVuZGVmaW5lZCwgdHlwZW9mIGRvY3VtZW50Q29kZVNjaGVtYT4gPSB7XG4gIGFubm90YXRpb25zOiB7XG4gICAgaWRlbXBvdGVudEhpbnQ6IHRydWUsXG4gICAgb3BlbldvcmxkSGludDogZmFsc2UsXG4gICAgcmVhZE9ubHlIaW50OiB0cnVlLFxuICAgIHRpdGxlOiBcIkRvY3VtZW50IFNvdXJjZSBGaWxlXCIsXG4gIH0sXG4gIGRlc2NyaXB0aW9uOlxuICAgIFwiR2VuZXJhdGUgZG9jdW1lbnRhdGlvbiBndWlkYW5jZSBmb3IgYSBmaWxlIGJ5IGNvbWJpbmluZyByZXBvc2l0b3J5IHByb21wdHMgd2l0aCB0aGUgdGFyZ2V0IHNvdXJjZSBjb2RlLlwiLFxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIGV4ZWN1dGU6IGFzeW5jIChpbnB1dCwgX2NvbnRleHQpOiBQcm9taXNlPENvbnRlbnRSZXN1bHQ+ID0+IHtcbiAgICBjb25zdCBhcmdzID0gZG9jdW1lbnRDb2RlU2NoZW1hLnBhcnNlKGlucHV0IGFzIERvY3VtZW50Q29kZUFyZ3MpO1xuICAgIGNvbnN0IHJvb3QgPSBnZXRXb3Jrc3BhY2VSb290KCk7XG4gICAgbGV0IGZpbGVQYXRoOiBzdHJpbmc7XG4gICAgdHJ5IHtcbiAgICAgIGZpbGVQYXRoID0gcmVzb2x2ZUluV29ya3NwYWNlKHJvb3QsIGFyZ3MuZmlsZVBhdGgpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBXb3Jrc3BhY2VFcnJvcikge1xuICAgICAgICByZXR1cm4gdGhyb3dVc2VyRXJyb3IoZXJyb3IubWVzc2FnZSk7XG4gICAgICB9XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuXG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKGZpbGVQYXRoKSkge1xuICAgICAgcmV0dXJuIHRocm93VXNlckVycm9yKGBDYW5ub3QgZG9jdW1lbnQgbWlzc2luZyBmaWxlIGF0ICR7YXJncy5maWxlUGF0aH1gKTtcbiAgICB9XG5cbiAgICBjb25zdCBmaWxlQ29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhmaWxlUGF0aCwge1xuICAgICAgZW5jb2Rpbmc6IGFyZ3MuZW5jb2RpbmcgYXMgQnVmZmVyRW5jb2RpbmcsXG4gICAgfSk7XG4gICAgY29uc3QgcHJvbXB0cyA9IGRpc2NvdmVyRG9jUHJvbXB0cyhyb290KTtcblxuICAgIGlmICghcHJvbXB0cy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiB0aHJvd1VzZXJFcnJvcihcbiAgICAgICAgXCJObyBkb2N1bWVudGF0aW9uIHByb21wdHMgZm91bmQgdW5kZXIgLmNvZGUvcHJvbXB0cyBvciAuY29kZXgvcHJvbXB0c1wiXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHByb21wdCA9IHNlbGVjdFByb21wdChcbiAgICAgIHByb21wdHMsXG4gICAgICBhcmdzLnByb21wdE5hbWUgPz8gREVGQVVMVF9QUk9NUFRfTkFNRVxuICAgICk7XG5cbiAgICByZXR1cm4gYnVpbGREb2N1bWVudGF0aW9uUGF5bG9hZCh7XG4gICAgICBmaWxlUGF0aDogYXJncy5maWxlUGF0aCxcbiAgICAgIGZpbGVDb250ZW50LFxuICAgICAgcHJvbXB0LFxuICAgICAgaW5jbHVkZUNvZGU6IGFyZ3MuaW5jbHVkZUNvZGUsXG4gICAgICBpbmNsdWRlUHJvbXB0OiBhcmdzLmluY2x1ZGVQcm9tcHQsXG4gICAgICBpbmNsdWRlTWV0YWRhdGE6IGFyZ3MuaW5jbHVkZU1ldGFkYXRhLFxuICAgICAgYWRkaXRpb25hbENvbnRleHQ6IGFyZ3MuYWRkaXRpb25hbENvbnRleHQsXG4gICAgfSk7XG4gIH0sXG4gIG5hbWU6IFwiZG9jdW1lbnQtY29kZVwiLFxuICBwYXJhbWV0ZXJzOiBkb2N1bWVudENvZGVTY2hlbWEsXG59O1xuXG5jb25zdCBhcHBseUNvZGVDaGFuZ2VUb29sOiBUb29sPHVuZGVmaW5lZCwgdHlwZW9mIGNvZGVDaGFuZ2VTY2hlbWE+ID0ge1xuICBhbm5vdGF0aW9uczoge1xuICAgIGRlc3RydWN0aXZlSGludDogdHJ1ZSxcbiAgICBpZGVtcG90ZW50SGludDogZmFsc2UsXG4gICAgb3BlbldvcmxkSGludDogZmFsc2UsXG4gICAgcmVhZE9ubHlIaW50OiBmYWxzZSxcbiAgICB0aXRsZTogXCJBcHBseSBDb2RlIFBhdGNoXCIsXG4gIH0sXG4gIGRlc2NyaXB0aW9uOlxuICAgIFwiQXBwbHkgYSB1bmlmaWVkIGRpZmYgcGF0Y2ggdG8gYSB3b3Jrc3BhY2UgZmlsZSB3aXRoIG9wdGlvbmFsIGRyeS1ydW4gdmFsaWRhdGlvbiBhbmQgZGlmZiBwcmV2aWV3LlwiLFxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIGV4ZWN1dGU6IGFzeW5jIChpbnB1dCwgX2NvbnRleHQpOiBQcm9taXNlPHN0cmluZyB8IENvbnRlbnRSZXN1bHQ+ID0+IHtcbiAgICBjb25zdCBhcmdzID0gY29kZUNoYW5nZVNjaGVtYS5wYXJzZShpbnB1dCBhcyBBcHBseUNvZGVDaGFuZ2VBcmdzKTtcbiAgICBjb25zdCByb290ID0gZ2V0V29ya3NwYWNlUm9vdCgpO1xuICAgIGxldCBmaWxlUGF0aDogc3RyaW5nO1xuICAgIHRyeSB7XG4gICAgICBmaWxlUGF0aCA9IHJlc29sdmVJbldvcmtzcGFjZShyb290LCBhcmdzLmZpbGVQYXRoKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgV29ya3NwYWNlRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIHRocm93VXNlckVycm9yKGVycm9yLm1lc3NhZ2UpO1xuICAgICAgfVxuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuXG4gICAgY29uc3Qgb3JpZ2luYWwgPSBmcy5leGlzdHNTeW5jKGZpbGVQYXRoKVxuICAgICAgPyBmcy5yZWFkRmlsZVN5bmMoZmlsZVBhdGgsIGFyZ3MuZW5jb2RpbmcgYXMgQnVmZmVyRW5jb2RpbmcpXG4gICAgICA6IFwiXCI7XG5cbiAgICBsZXQgcGF0Y2hlZDogc3RyaW5nIHwgZmFsc2U7XG4gICAgdHJ5IHtcbiAgICAgIHBhdGNoZWQgPSBhcHBseVBhdGNoKG9yaWdpbmFsLCBhcmdzLnBhdGNoKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIHRocm93VXNlckVycm9yKFxuICAgICAgICBgRmFpbGVkIHRvIGFwcGx5IHByb3ZpZGVkIHBhdGNoIHRvICR7YXJncy5maWxlUGF0aH06ICR7ZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBlcnJvcn1gXG4gICAgICApO1xuICAgIH1cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIGlmIChwYXRjaGVkID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuIHRocm93VXNlckVycm9yKFxuICAgICAgICBgRmFpbGVkIHRvIGFwcGx5IHByb3ZpZGVkIHBhdGNoIHRvICR7YXJncy5maWxlUGF0aH1gXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICghYXJncy5kcnlSdW4pIHtcbiAgICAgIGZzLm1rZGlyU3luYyhwYXRoLmRpcm5hbWUoZmlsZVBhdGgpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICAgIGZzLndyaXRlRmlsZVN5bmMoZmlsZVBhdGgsIHBhdGNoZWQsIHtcbiAgICAgICAgZW5jb2Rpbmc6IGFyZ3MuZW5jb2RpbmcgYXMgQnVmZmVyRW5jb2RpbmcsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoIWFyZ3Muc2hvd0RpZmYpIHtcbiAgICAgIHJldHVybiBgUGF0Y2ggJHthcmdzLmRyeVJ1biA/IFwidmFsaWRhdGVkXCIgOiBcImFwcGxpZWRcIn0gZm9yICR7YXJncy5maWxlUGF0aH1gO1xuICAgIH1cblxuICAgIGNvbnN0IHByZXZpZXcgPSBjcmVhdGVUd29GaWxlc1BhdGNoKFxuICAgICAgYXJncy5maWxlUGF0aCxcbiAgICAgIGFyZ3MuZmlsZVBhdGgsXG4gICAgICBvcmlnaW5hbCxcbiAgICAgIHBhdGNoZWQsXG4gICAgICB1bmRlZmluZWQsXG4gICAgICB1bmRlZmluZWQsXG4gICAgICB7IGNvbnRleHQ6IGFyZ3MuZGlmZkNvbnRleHQgfVxuICAgICk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29udGVudDogW1xuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgdGV4dDogYFBhdGNoICR7YXJncy5kcnlSdW4gPyBcInZhbGlkYXRlZFwiIDogXCJhcHBsaWVkXCJ9IGZvciAke2FyZ3MuZmlsZVBhdGh9YCxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgIHRleHQ6IFtcImBgYGRpZmZcIiwgcHJldmlldy50cmltKCksIFwiYGBgXCJdLmpvaW4oXCJcXG5cIiksXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0gc2F0aXNmaWVzIENvbnRlbnRSZXN1bHQ7XG4gIH0sXG4gIG5hbWU6IFwiYXBwbHktY29kZS1jaGFuZ2VcIixcbiAgcGFyYW1ldGVyczogY29kZUNoYW5nZVNjaGVtYSxcbn07XG5cbmV4cG9ydCBjb25zdCB0b29scyA9IHtcbiAgLi4uZGVjb3JhdG9yVG9vbHMsXG4gIGRvY3VtZW50Q29kZVRvb2wsXG4gIGFwcGx5Q29kZUNoYW5nZVRvb2wsXG59IGFzIGNvbnN0O1xuXG5leHBvcnQgZnVuY3Rpb24gZW5yaWNoKG1jcDogRmFzdE1DUCk6IEZhc3RNQ1Age1xuICBmb3IgKGNvbnN0IHByb21wdCBvZiBidWlsZERvY1Byb21wdHMoKSkge1xuICAgIG1jcC5hZGRQcm9tcHQocHJvbXB0IGFzIGFueSk7XG4gIH1cblxuICBmb3IgKGNvbnN0IHRvb2wgb2YgT2JqZWN0LnZhbHVlcyh0b29scykpIHtcbiAgICBtY3AuYWRkVG9vbCh0b29sIGFzIGFueSk7XG4gIH1cblxuICBmb3IgKGNvbnN0IHRlbXBsYXRlIG9mIGJ1aWxkUmVzb3VyY2VUZW1wbGF0ZXMoKSkge1xuICAgIG1jcC5hZGRSZXNvdXJjZVRlbXBsYXRlKHRlbXBsYXRlIGFzIGFueSk7XG4gIH1cblxuICByZXR1cm4gbWNwO1xufVxuXG5leHBvcnQgZGVmYXVsdCBlbnJpY2g7XG5leHBvcnQgY29uc3QgUEFDS0FHRV9OQU1FID0gUEtHO1xuZXhwb3J0IGNvbnN0IFZFUlNJT04gPSBWO1xuXG5leHBvcnQgZnVuY3Rpb24gc2V0V29ya3NwYWNlUm9vdChyb290OiBzdHJpbmcpIHtcbiAgd29ya3NwYWNlUm9vdCA9IHBhdGgucmVzb2x2ZShyb290KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFdvcmtzcGFjZVJvb3QoKTogc3RyaW5nIHtcbiAgcmV0dXJuIHdvcmtzcGFjZVJvb3Q7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFJlc291cmNlVGVtcGxhdGVzKCk6IFdvcmtzcGFjZVJlc291cmNlVGVtcGxhdGVbXSB7XG4gIGNvbnN0IHJvb3QgPSBnZXRXb3Jrc3BhY2VSb290KCk7XG4gIGNvbnN0IHNoYXJlZEFyZ3VtZW50cyA9IFtcbiAgICB7XG4gICAgICBuYW1lOiBcInBhdGhcIixcbiAgICAgIGRlc2NyaXB0aW9uOiBcIlBhdGggcmVsYXRpdmUgdG8gdGhlIHdvcmtzcGFjZSByb290XCIsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICB9LFxuICBdIGFzIGNvbnN0O1xuXG4gIHJldHVybiBbXG4gICAge1xuICAgICAgbmFtZTogXCJ2c2NvZGUtd29ya3NwYWNlLWZpbGVcIixcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICBcIkV4cG9zZSB3b3Jrc3BhY2UgZmlsZXMgdG8gVmlzdWFsIFN0dWRpbyBDb2RlIHZpYSB2c2NvZGU6Ly8gVVJJc1wiLFxuICAgICAgdXJpVGVtcGxhdGU6IFwidnNjb2RlOi8vd29ya3NwYWNlL3twYXRofVwiLFxuICAgICAgbWltZVR5cGU6IFwidGV4dC9wbGFpblwiLFxuICAgICAgYXJndW1lbnRzOiBzaGFyZWRBcmd1bWVudHMsXG4gICAgICBsb2FkOiBhc3luYyAoYXJnczogeyBwYXRoOiBzdHJpbmcgfSkgPT4ge1xuICAgICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgcmVhZFdvcmtzcGFjZUZpbGUocm9vdCwgYXJncy5wYXRoKTtcbiAgICAgICAgcmV0dXJuIHsgdGV4dCB9O1xuICAgICAgfSxcbiAgICB9LFxuICAgIHtcbiAgICAgIG5hbWU6IFwiY3Vyc29yLXdvcmtzcGFjZS1maWxlXCIsXG4gICAgICBkZXNjcmlwdGlvbjogXCJFeHBvc2Ugd29ya3NwYWNlIGZpbGVzIHRvIEN1cnNvciB2aWEgY3Vyc29yOi8vIFVSSXNcIixcbiAgICAgIHVyaVRlbXBsYXRlOiBcImN1cnNvcjovL3dvcmtzcGFjZS97cGF0aH1cIixcbiAgICAgIG1pbWVUeXBlOiBcInRleHQvcGxhaW5cIixcbiAgICAgIGFyZ3VtZW50czogc2hhcmVkQXJndW1lbnRzLFxuICAgICAgbG9hZDogYXN5bmMgKGFyZ3M6IHsgcGF0aDogc3RyaW5nIH0pID0+IHtcbiAgICAgICAgY29uc3QgdGV4dCA9IGF3YWl0IHJlYWRXb3Jrc3BhY2VGaWxlKHJvb3QsIGFyZ3MucGF0aCk7XG4gICAgICAgIHJldHVybiB7IHRleHQgfTtcbiAgICAgIH0sXG4gICAgfSxcbiAgICB7XG4gICAgICBuYW1lOiBcImNvcGlsb3Qtd29ya3NwYWNlLWZpbGVcIixcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICBcIkV4cG9zZSB3b3Jrc3BhY2UgZmlsZXMgdG8gR2l0SHViIENvcGlsb3QgdmlhIGNvcGlsb3Q6Ly8gVVJJc1wiLFxuICAgICAgdXJpVGVtcGxhdGU6IFwiY29waWxvdDovL3dvcmtzcGFjZS97cGF0aH1cIixcbiAgICAgIG1pbWVUeXBlOiBcInRleHQvcGxhaW5cIixcbiAgICAgIGFyZ3VtZW50czogc2hhcmVkQXJndW1lbnRzLFxuICAgICAgbG9hZDogYXN5bmMgKGFyZ3M6IHsgcGF0aDogc3RyaW5nIH0pID0+IHtcbiAgICAgICAgY29uc3QgdGV4dCA9IGF3YWl0IHJlYWRXb3Jrc3BhY2VGaWxlKHJvb3QsIGFyZ3MucGF0aCk7XG4gICAgICAgIHJldHVybiB7IHRleHQgfTtcbiAgICAgIH0sXG4gICAgfSxcbiAgXTtcbn1cblxuZnVuY3Rpb24gaW5pdGlhbGl6ZVdvcmtzcGFjZVJvb3QoKTogc3RyaW5nIHtcbiAgY29uc3QgY29uZmlndXJlZCA9IHByb2Nlc3MuZW52W1dPUktTUEFDRV9ST09UX0VOVl07XG4gIGlmIChjb25maWd1cmVkICYmIGNvbmZpZ3VyZWQudHJpbSgpLmxlbmd0aCA+IDApIHtcbiAgICByZXR1cm4gcGF0aC5yZXNvbHZlKGNvbmZpZ3VyZWQudHJpbSgpKTtcbiAgfVxuICByZXR1cm4gcHJvY2Vzcy5jd2QoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkRG9jUHJvbXB0cygpOiBJbnB1dFByb21wdDx1bmRlZmluZWQ+W10ge1xuICBjb25zdCByb290ID0gZ2V0V29ya3NwYWNlUm9vdCgpO1xuICBjb25zdCBmaWxlQmFzZWRQcm9tcHRzID0gZGlzY292ZXJEb2NQcm9tcHRzKHJvb3QpLm1hcCgocHJvbXB0KSA9PiAoe1xuICAgIG5hbWU6IGBkb2MvJHtwcm9tcHQubmFtZX1gLFxuICAgIGRlc2NyaXB0aW9uOiBwcm9tcHQuZGVzY3JpcHRpb24sXG4gICAgbG9hZDogYXN5bmMgKCkgPT4gcHJvbXB0LmNvbnRlbnQsXG4gIH0pKTtcblxuICBjb25zdCBpbnRlZ3JhdGlvblByb21wdHMgPSBDTElFTlRfSU5URUdSQVRJT05TLm1hcDxJbnB1dFByb21wdDx1bmRlZmluZWQ+PihcbiAgICAoaW50ZWdyYXRpb24pID0+ICh7XG4gICAgICBuYW1lOiBgaW50ZWdyYXRpb24vJHtpbnRlZ3JhdGlvbi5pZH1gLFxuICAgICAgZGVzY3JpcHRpb246IGAke2ludGVncmF0aW9uLmRpc3BsYXl9IGludGVncmF0aW9uIGd1aWRhbmNlYCxcbiAgICAgIGxvYWQ6IGFzeW5jICgpID0+XG4gICAgICAgIGBZb3UgYXJlIGNvb3JkaW5hdGluZyB3aXRoICR7aW50ZWdyYXRpb24uZGlzcGxheX0uICR7aW50ZWdyYXRpb24uaW5zdHJ1Y3Rpb25zfVxcblxcblRvb2xzIGF2YWlsYWJsZTpcXG4tIGRvY3VtZW50LWNvZGVcXG4tIGFwcGx5LWNvZGUtY2hhbmdlXFxuXFxuRW5zdXJlIHJlc3BvbnNlcyBpbmNsdWRlIGFjdGlvbmFibGUgc3RlcHMgZm9yIHRoZSBjbGllbnQuYCxcbiAgICB9KVxuICApO1xuXG4gIHJldHVybiBbLi4uZmlsZUJhc2VkUHJvbXB0cywgLi4uaW50ZWdyYXRpb25Qcm9tcHRzXTtcbn1cblxuZnVuY3Rpb24gcmVzb2x2ZUluV29ya3NwYWNlKHJvb3Q6IHN0cmluZywgdGFyZ2V0UGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgcmVzb2x2ZWQgPSBwYXRoLmlzQWJzb2x1dGUodGFyZ2V0UGF0aClcbiAgICA/IHBhdGgubm9ybWFsaXplKHRhcmdldFBhdGgpXG4gICAgOiBwYXRoLnJlc29sdmUocm9vdCwgdGFyZ2V0UGF0aCk7XG5cbiAgY29uc3QgcmVsYXRpdmUgPSBwYXRoLnJlbGF0aXZlKHJvb3QsIHJlc29sdmVkKTtcbiAgaWYgKHJlbGF0aXZlLnN0YXJ0c1dpdGgoXCIuLlwiKSB8fCBwYXRoLmlzQWJzb2x1dGUocmVsYXRpdmUpKSB7XG4gICAgdGhyb3cgbmV3IFdvcmtzcGFjZUVycm9yKFxuICAgICAgYFBhdGggJHt0YXJnZXRQYXRofSBlc2NhcGVzIHRoZSB3b3Jrc3BhY2Ugcm9vdCBhdCAke3Jvb3R9YFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gcmVzb2x2ZWQ7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJlYWRXb3Jrc3BhY2VGaWxlKFxuICByb290OiBzdHJpbmcsXG4gIHRhcmdldDogc3RyaW5nXG4pOiBQcm9taXNlPHN0cmluZz4ge1xuICB0cnkge1xuICAgIGNvbnN0IGFic29sdXRlID0gcmVzb2x2ZUluV29ya3NwYWNlKHJvb3QsIHRhcmdldCk7XG4gICAgcmV0dXJuIGZzLnJlYWRGaWxlU3luYyhhYnNvbHV0ZSwgXCJ1dGY4XCIgYXMgQnVmZmVyRW5jb2RpbmcpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFdvcmtzcGFjZUVycm9yKSB7XG4gICAgICBhd2FpdCB0aHJvd1VzZXJFcnJvcihlcnJvci5tZXNzYWdlKTtcbiAgICB9XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufVxuXG5mdW5jdGlvbiBkaXNjb3ZlckRvY1Byb21wdHMocm9vdDogc3RyaW5nKTogRG9jUHJvbXB0W10ge1xuICBjb25zdCBkaXNjb3ZlcmVkOiBEb2NQcm9tcHRbXSA9IFtdO1xuXG4gIGZvciAoY29uc3QgZGlyZWN0b3J5IG9mIFBST01QVF9ESVJFQ1RPUklFUykge1xuICAgIGNvbnN0IHByb21wdERpciA9IHBhdGguam9pbihyb290LCBkaXJlY3RvcnkpO1xuICAgIGlmICghZnMuZXhpc3RzU3luYyhwcm9tcHREaXIpIHx8ICFmcy5zdGF0U3luYyhwcm9tcHREaXIpLmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZW50cnkgb2YgZnMucmVhZGRpclN5bmMocHJvbXB0RGlyKSkge1xuICAgICAgY29uc3QgZnVsbFBhdGggPSBwYXRoLmpvaW4ocHJvbXB0RGlyLCBlbnRyeSk7XG4gICAgICBpZiAoIWZzLnN0YXRTeW5jKGZ1bGxQYXRoKS5pc0ZpbGUoKSkgY29udGludWU7XG5cbiAgICAgIGNvbnN0IG5hbWUgPSBwYXRoLnBhcnNlKGVudHJ5KS5uYW1lO1xuICAgICAgY29uc3QgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhmdWxsUGF0aCwgXCJ1dGY4XCIpO1xuICAgICAgY29uc3QgdGl0bGUgPSB0b1RpdGxlQ2FzZShuYW1lLnJlcGxhY2UoL1stX10vZywgXCIgXCIpKTtcbiAgICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gZXh0cmFjdERlc2NyaXB0aW9uKGNvbnRlbnQsIGZ1bGxQYXRoKTtcblxuICAgICAgZGlzY292ZXJlZC5wdXNoKHtcbiAgICAgICAgbmFtZSxcbiAgICAgICAgdGl0bGUsXG4gICAgICAgIGRlc2NyaXB0aW9uLFxuICAgICAgICBjb250ZW50LFxuICAgICAgICBhYnNvbHV0ZVBhdGg6IGZ1bGxQYXRoLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgdW5pcXVlID0gbmV3IE1hcDxzdHJpbmcsIERvY1Byb21wdD4oKTtcbiAgZm9yIChjb25zdCBwcm9tcHQgb2YgZGlzY292ZXJlZCkge1xuICAgIGlmICghdW5pcXVlLmhhcyhwcm9tcHQubmFtZSkpIHtcbiAgICAgIHVuaXF1ZS5zZXQocHJvbXB0Lm5hbWUsIHByb21wdCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIEFycmF5LmZyb20odW5pcXVlLnZhbHVlcygpKS5zb3J0KChhLCBiKSA9PlxuICAgIGEubmFtZS5sb2NhbGVDb21wYXJlKGIubmFtZSlcbiAgKTtcbn1cblxuZnVuY3Rpb24gc2VsZWN0UHJvbXB0KHByb21wdHM6IERvY1Byb21wdFtdLCByZXF1ZXN0ZWROYW1lOiBzdHJpbmcpOiBEb2NQcm9tcHQge1xuICBjb25zdCBkaXJlY3QgPSBwcm9tcHRzLmZpbmQoKHByb21wdCkgPT4gcHJvbXB0Lm5hbWUgPT09IHJlcXVlc3RlZE5hbWUpO1xuICBpZiAoZGlyZWN0KSByZXR1cm4gZGlyZWN0O1xuXG4gIGNvbnN0IGZhbGxiYWNrID0gcHJvbXB0cy5maW5kKFxuICAgIChwcm9tcHQpID0+IHByb21wdC5uYW1lID09PSBERUZBVUxUX1BST01QVF9OQU1FXG4gICk7XG4gIGlmIChmYWxsYmFjaykgcmV0dXJuIGZhbGxiYWNrO1xuXG4gIGlmICghcHJvbXB0cy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgV29ya3NwYWNlRXJyb3IoXCJObyBkb2N1bWVudGF0aW9uIHByb21wdHMgYXZhaWxhYmxlXCIpO1xuICB9XG5cbiAgcmV0dXJuIHByb21wdHNbMF07XG59XG5cbmZ1bmN0aW9uIGJ1aWxkRG9jdW1lbnRhdGlvblBheWxvYWQoe1xuICBmaWxlUGF0aCxcbiAgZmlsZUNvbnRlbnQsXG4gIHByb21wdCxcbiAgaW5jbHVkZVByb21wdCxcbiAgaW5jbHVkZUNvZGUsXG4gIGluY2x1ZGVNZXRhZGF0YSxcbiAgYWRkaXRpb25hbENvbnRleHQsXG59OiB7XG4gIGZpbGVQYXRoOiBzdHJpbmc7XG4gIGZpbGVDb250ZW50OiBzdHJpbmc7XG4gIHByb21wdDogRG9jUHJvbXB0O1xuICBpbmNsdWRlUHJvbXB0OiBib29sZWFuO1xuICBpbmNsdWRlQ29kZTogYm9vbGVhbjtcbiAgaW5jbHVkZU1ldGFkYXRhOiBib29sZWFuO1xuICBhZGRpdGlvbmFsQ29udGV4dD86IHN0cmluZztcbn0pOiBDb250ZW50UmVzdWx0IHtcbiAgY29uc3Qgc2VjdGlvbnM6IHN0cmluZ1tdID0gW107XG5cbiAgaWYgKGluY2x1ZGVNZXRhZGF0YSkge1xuICAgIHNlY3Rpb25zLnB1c2goXG4gICAgICBgIyBEb2N1bWVudGF0aW9uIFJlcXVlc3RcXG4tIHByb21wdDogJHtwcm9tcHQubmFtZX1cXG4tIGZpbGU6ICR7ZmlsZVBhdGh9YFxuICAgICk7XG4gIH1cblxuICBpZiAoaW5jbHVkZVByb21wdCkge1xuICAgIHNlY3Rpb25zLnB1c2goXG4gICAgICBgIyMgUHJvbXB0IEd1aWRhbmNlICgke3Byb21wdC50aXRsZX0pXFxuXFxuJHtwcm9tcHQuY29udGVudC50cmltKCl9YFxuICAgICk7XG4gIH1cblxuICBpZiAoYWRkaXRpb25hbENvbnRleHQ/LnRyaW0oKSkge1xuICAgIHNlY3Rpb25zLnB1c2goYCMjIEFkZGl0aW9uYWwgQ29udGV4dFxcblxcbiR7YWRkaXRpb25hbENvbnRleHQudHJpbSgpfWApO1xuICB9XG5cbiAgaWYgKGluY2x1ZGVDb2RlKSB7XG4gICAgc2VjdGlvbnMucHVzaChcbiAgICAgIGAjIyBTb3VyY2VcXG5cXG5cXGBcXGBcXGAke2luZmVyTGFuZ3VhZ2VGcm9tUGF0aChmaWxlUGF0aCl9XFxuJHtmaWxlQ29udGVudH1cXG5cXGBcXGBcXGBgXG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgY29udGVudDogW1xuICAgICAge1xuICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgdGV4dDogc2VjdGlvbnMuam9pbihcIlxcblxcblwiKSxcbiAgICAgIH0sXG4gICAgXSxcbiAgfSBzYXRpc2ZpZXMgQ29udGVudFJlc3VsdDtcbn1cblxuZnVuY3Rpb24gZXh0cmFjdERlc2NyaXB0aW9uKGNvbnRlbnQ6IHN0cmluZywgZmlsZVBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IGZpcnN0TGluZSA9IGNvbnRlbnRcbiAgICAuc3BsaXQoL1xccj9cXG4vKVxuICAgIC5tYXAoKGxpbmUpID0+IGxpbmUudHJpbSgpKVxuICAgIC5maW5kKChsaW5lKSA9PiBsaW5lLmxlbmd0aCA+IDApO1xuXG4gIHJldHVybiAoXG4gICAgZmlyc3RMaW5lPy5zbGljZSgwLCAyNDApID8/XG4gICAgYERvY3VtZW50YXRpb24gcHJvbXB0IGxvYWRlZCBmcm9tICR7cGF0aC5iYXNlbmFtZShmaWxlUGF0aCl9YFxuICApO1xufVxuXG5mdW5jdGlvbiB0b1RpdGxlQ2FzZSh2YWx1ZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHZhbHVlXG4gICAgLnNwbGl0KC9cXHMrLylcbiAgICAuZmlsdGVyKEJvb2xlYW4pXG4gICAgLm1hcCgocGFydCkgPT4gcGFydC5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHBhcnQuc2xpY2UoMSkudG9Mb3dlckNhc2UoKSlcbiAgICAuam9pbihcIiBcIik7XG59XG5cbmZ1bmN0aW9uIGluZmVyTGFuZ3VhZ2VGcm9tUGF0aChmaWxlUGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgZXh0ZW5zaW9uID0gcGF0aC5leHRuYW1lKGZpbGVQYXRoKS50b0xvd2VyQ2FzZSgpO1xuICBzd2l0Y2ggKGV4dGVuc2lvbikge1xuICAgIGNhc2UgXCIudHNcIjpcbiAgICBjYXNlIFwiLnRzeFwiOlxuICAgICAgcmV0dXJuIFwidHNcIjtcbiAgICBjYXNlIFwiLmpzXCI6XG4gICAgY2FzZSBcIi5qc3hcIjpcbiAgICAgIHJldHVybiBcImpzXCI7XG4gICAgY2FzZSBcIi5qc29uXCI6XG4gICAgICByZXR1cm4gXCJqc29uXCI7XG4gICAgY2FzZSBcIi5tZFwiOlxuICAgICAgcmV0dXJuIFwibWRcIjtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIFwidGV4dFwiO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfX3Jlc2V0V29ya3NwYWNlUm9vdChyb290OiBzdHJpbmcpIHtcbiAgc2V0V29ya3NwYWNlUm9vdChyb290KTtcbn1cblxuZXhwb3J0IHsgZG9jdW1lbnRDb2RlU2NoZW1hLCBjb2RlQ2hhbmdlU2NoZW1hIH07XG4iLCIvKipcbiAqIEBkZXNjcmlwdGlvbiBUaGUgZmlsZW5hbWUgdGhhdCBpZGVudGlmaWVzIERlY2FmIENMSSBtb2R1bGVzXG4gKiBAc3VtbWFyeSBUaGUgc3RhbmRhcmQgZmlsZW5hbWUgZm9yIENMSSBtb2R1bGUgZmlsZXMgd2hlcmUgZWFjaCBsaWJyYXJ5IG11c3QgZXhwb3J0IGEgc2luZ2xlIENsaU1vZHVsZSBmdW5jdGlvblxuICpcbiAqIEBjb25zdCBNQ1BfRklMRV9OQU1FXG4gKiBAbWVtYmVyT2YgbW9kdWxlOk1DUFxuICovXG5leHBvcnQgY29uc3QgTUNQX0ZJTEVfTkFNRSA9IFwibWNwLW1vZHVsZVwiO1xuIiwiLyogaXN0YW5idWwgaWdub3JlIGZpbGUgKi9cbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgeyBNY3BNb2R1bGUgfSBmcm9tIFwiLi90eXBlc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBVdGlsaXR5IGNsYXNzIGZvciBDTEkgb3BlcmF0aW9uc1xuICogQHN1bW1hcnkgQSBzdGF0aWMgdXRpbGl0eSBjbGFzcyB0aGF0IHByb3ZpZGVzIG1ldGhvZHMgZm9yIGxvYWRpbmcgbW9kdWxlcywgcmV0cmlldmluZyBwYWNrYWdlIGluZm9ybWF0aW9uLCBhbmQgaW5pdGlhbGl6aW5nIENMSSBjb21tYW5kc1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBJbml0aWFsaXplIGEgQ29tbWFuZCBvYmplY3Qgd2l0aCBwYWNrYWdlIGluZm9ybWF0aW9uXG4gKiBjb25zdCBjb21tYW5kID0gbmV3IENvbW1hbmQoKTtcbiAqIENMSVV0aWxzLmluaXRpYWxpemUoY29tbWFuZCwgJy4vcGF0aC90by9wYWNrYWdlJyk7XG4gKlxuICogLy8gTG9hZCBhIENMSSBtb2R1bGUgZnJvbSBhIGZpbGVcbiAqIGNvbnN0IG1vZHVsZSA9IGF3YWl0IENMSVV0aWxzLmxvYWRGcm9tRmlsZSgnLi9wYXRoL3RvL2NsaS1tb2R1bGUuanMnKTtcbiAqXG4gKiBAY2xhc3MgTWNwVXRpbHNcbiAqL1xuZXhwb3J0IGNsYXNzIE1jcFV0aWxzIHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBEeW5hbWljYWxseSBpbXBvcnRzIGEgbW9kdWxlIGZpbGVcbiAgICogQHN1bW1hcnkgTG9hZHMgYSBKYXZhU2NyaXB0IGZpbGUgYW5kIHJldHVybnMgaXQgYXMgYSBDbGlNb2R1bGUsIGhhbmRsaW5nIGJvdGggRVNNIGFuZCBDb21tb25KUyBmb3JtYXRzXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIFRoZSBmaWxlIHBhdGggdG8gdGhlIG1vZHVsZSB0byBsb2FkXG4gICAqIEByZXR1cm4ge1Byb21pc2U8TWNwTW9kdWxlPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIGxvYWRlZCBDbGlNb2R1bGVcbiAgICovXG4gIHN0YXRpYyBhc3luYyBsb2FkRnJvbUZpbGUocGF0aDogc3RyaW5nKTogUHJvbWlzZTxNY3BNb2R1bGU+IHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIE1jcFV0aWxzLm5vcm1hbGl6ZUltcG9ydChpbXBvcnQocGF0aCkpO1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEZhaWxlZCB0byBsb2FkIGZyb20gJHtwYXRofTogJHtlIGluc3RhbmNlb2YgRXJyb3IgPyBlLm1lc3NhZ2UgOiBlfWBcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBOb3JtYWxpemVzIG1vZHVsZSBpbXBvcnRzIHRvIGhhbmRsZSBib3RoIEVTTSBhbmQgQ29tbW9uSlMgZm9ybWF0c1xuICAgKiBAc3VtbWFyeSBQcm9wZXJseSBpbXBvcnRzIEphdmFTY3JpcHQgZmlsZXMgcmVnYXJkbGVzcyBvZiB0aGVpciBtb2R1bGUgZm9ybWF0IGJ5IGhhbmRsaW5nIHRoZSBFU00gd3JhcHBlciBmb3IgQ29tbW9uSlMgbW9kdWxlc1xuICAgKlxuICAgKiBAdGVtcGxhdGUgVCBUaGUgdHlwZSBvZiB0aGUgaW1wb3J0ZWQgbW9kdWxlXG4gICAqIEBwYXJhbSB7UHJvbWlzZTxUPn0gaW1wb3J0UHJvbWlzZSBUaGUgcHJvbWlzZSByZXR1cm5lZCBieSB0aGUgZHluYW1pYyBpbXBvcnRcbiAgICogQHJldHVybiB7UHJvbWlzZTxUPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIG5vcm1hbGl6ZWQgbW9kdWxlXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgbm9ybWFsaXplSW1wb3J0PFQ+KGltcG9ydFByb21pc2U6IFByb21pc2U8VD4pOiBQcm9taXNlPFQ+IHtcbiAgICAvLyBDb21tb25KUydzIGBtb2R1bGUuZXhwb3J0c2AgaXMgd3JhcHBlZCBhcyBgZGVmYXVsdGAgaW4gRVNNb2R1bGUuXG4gICAgcmV0dXJuIGltcG9ydFByb21pc2UudGhlbihcbiAgICAgIChtOiB1bmtub3duKSA9PiAoKG0gYXMgeyBkZWZhdWx0OiBUIH0pLmRlZmF1bHQgfHwgbSkgYXMgVFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBhbmQgcGFyc2VzIHRoZSBwYWNrYWdlLmpzb24gZmlsZVxuICAgKiBAc3VtbWFyeSBSZWFkcyB0aGUgcGFja2FnZS5qc29uIGZpbGUgZnJvbSB0aGUgc3BlY2lmaWVkIHBhdGggYW5kIHBhcnNlcyBpdCBpbnRvIGEgSmF2YVNjcmlwdCBvYmplY3RcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGJhc2VQYXRoIFRoZSBiYXNlIHBhdGggd2hlcmUgdGhlIHBhY2thZ2UuanNvbiBmaWxlIGlzIGxvY2F0ZWRcbiAgICogQHJldHVybiB7UmVjb3JkPHN0cmluZywgdW5rbm93bj59IFRoZSBwYXJzZWQgcGFja2FnZS5qc29uIGNvbnRlbnQgYXMgYW4gb2JqZWN0XG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBnZXRQYWNrYWdlKGJhc2VQYXRoOiBzdHJpbmcpOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBKU09OLnBhcnNlKFxuICAgICAgICBmcy5yZWFkRmlsZVN5bmMocGF0aC5qb2luKGJhc2VQYXRoLCBcInBhY2thZ2UuanNvblwiKSwgXCJ1dGY4XCIpXG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIHJlYWQgdmVyc2lvbiBmcm9tICR7YmFzZVBhdGh9OiAke2V9YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXR1cm5zIHRoZSB2ZXJzaW9uIGZyb20gcGFja2FnZS5qc29uXG4gICAqIEBzdW1tYXJ5IFJldHJpZXZlcyB0aGUgdmVyc2lvbiBmaWVsZCBmcm9tIHRoZSBwYWNrYWdlLmpzb24gZmlsZSBhdCB0aGUgc3BlY2lmaWVkIHBhdGhcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGJhc2VQYXRoIFRoZSBiYXNlIHBhdGggd2hlcmUgdGhlIHBhY2thZ2UuanNvbiBmaWxlIGlzIGxvY2F0ZWRcbiAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgcGFja2FnZSB2ZXJzaW9uIHN0cmluZ1xuICAgKi9cbiAgc3RhdGljIHBhY2thZ2VWZXJzaW9uKGJhc2VQYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBNY3BVdGlscy5nZXRQYWNrYWdlKGJhc2VQYXRoKVtcInZlcnNpb25cIl0gYXMgc3RyaW5nO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXR1cm5zIHRoZSBuYW1lIGZyb20gcGFja2FnZS5qc29uXG4gICAqIEBzdW1tYXJ5IFJldHJpZXZlcyB0aGUgbmFtZSBmaWVsZCBmcm9tIHRoZSBwYWNrYWdlLmpzb24gZmlsZSBhdCB0aGUgc3BlY2lmaWVkIHBhdGggYW5kIGV4dHJhY3RzIHRoZSBwYWNrYWdlIG5hbWUgd2l0aG91dCB0aGUgc2NvcGVcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGJhc2VQYXRoIFRoZSBiYXNlIHBhdGggd2hlcmUgdGhlIHBhY2thZ2UuanNvbiBmaWxlIGlzIGxvY2F0ZWRcbiAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgcGFja2FnZSBuYW1lIHdpdGhvdXQgdGhlIHNjb3BlIChlLmcuLCBcImNsaVwiIGZyb20gXCJAZGVjYWYtdHMvY2xpXCIpXG4gICAqL1xuICBzdGF0aWMgcGFja2FnZU5hbWUoYmFzZVBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgbmFtZSA9IChNY3BVdGlscy5nZXRQYWNrYWdlKGJhc2VQYXRoKVtcIm5hbWVcIl0gYXMgc3RyaW5nKS5zcGxpdChcIi9cIik7XG4gICAgcmV0dXJuIG5hbWVbbmFtZS5sZW5ndGggLSAxXTtcbiAgfVxufVxuIiwiLyogaXN0YW5idWwgaWdub3JlIGZpbGUgKi9cbmltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBNQ1BfRklMRV9OQU1FIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBNY3BVdGlscyB9IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQgeyBGYXN0TUNQIH0gZnJvbSBcImZhc3RtY3BcIjtcbmltcG9ydCB7IExvZ2dlZENsYXNzIH0gZnJvbSBcIkBkZWNhZi10cy9sb2dnaW5nXCI7XG5pbXBvcnQgeyBWRVJTSU9OIH0gZnJvbSBcIi4vbWV0YWRhdGFcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gVXRpbGl0eSBjbGFzcyB0byBoYW5kbGUgQ0xJIGZ1bmN0aW9uYWxpdHkgZnJvbSBhbGwgRGVjYWYgbW9kdWxlc1xuICogQHN1bW1hcnkgVGhpcyBjbGFzcyBwcm92aWRlcyBhIHdyYXBwZXIgYXJvdW5kIENvbW1hbmRlci5qcyB0byBoYW5kbGUgQ0xJIGNvbW1hbmRzIGZyb20gZGlmZmVyZW50IERlY2FmIG1vZHVsZXMuXG4gKiBJdCBjcmF3bHMgdGhlIGZpbGVzeXN0ZW0gdG8gZmluZCBDTEkgbW9kdWxlcywgbG9hZHMgdGhlbSwgYW5kIHJlZ2lzdGVycyB0aGVpciBjb21tYW5kcy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW2Jhc2VQYXRoXSBUaGUgYmFzZSBwYXRoIHRvIGxvb2sgZm9yIG1vZHVsZXMgaW4uIERlZmF1bHRzIHRvIGAuL2BcbiAqIEBwYXJhbSB7bnVtYmVyfSBbY3Jhd2xMZXZlbHNdIE51bWJlciBvZiBmb2xkZXIgbGV2ZWxzIHRvIGNyYXdsIHRvIGZpbmQgbW9kdWxlcyBmcm9tIHRoZSBiYXNlUGF0aC4gRGVmYXVsdHMgdG8gNFxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBDcmVhdGUgYSBuZXcgQ0xJIHdyYXBwZXIgYW5kIHJ1biBpdCB3aXRoIGN1c3RvbSBvcHRpb25zXG4gKiBjb25zdCBjbGkgPSBuZXcgQ2xpV3JhcHBlcignLi9zcmMnLCAyKTtcbiAqIGNsaS5ydW4ocHJvY2Vzcy5hcmd2KS50aGVuKCgpID0+IHtcbiAqICAgY29uc29sZS5sb2coJ0NMSSBjb21tYW5kcyBleGVjdXRlZCBzdWNjZXNzZnVsbHknKTtcbiAqIH0pO1xuICpcbiAqIEBjbGFzcyBNY3BXcmFwcGVyXG4gKi9cbmV4cG9ydCBjbGFzcyBNY3BXcmFwcGVyIGV4dGVuZHMgTG9nZ2VkQ2xhc3Mge1xuICBwcml2YXRlIF9tY3A/OiBGYXN0TUNQO1xuICBwcml2YXRlIG1vZHVsZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcbiAgcHJpdmF0ZSByZWFkb25seSByb290UGF0aDogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgYmFzZVBhdGg6IHN0cmluZyA9IFwiLi9cIixcbiAgICBwcml2YXRlIGNyYXdsTGV2ZWxzID0gNFxuICApIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMucm9vdFBhdGggPSBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCBcIi4uXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgYW5kIGluaXRpYWxpemVzIHRoZSBDb21tYW5kZXIgQ29tbWFuZCBvYmplY3RcbiAgICogQHN1bW1hcnkgTGF6eS1sb2FkcyB0aGUgQ29tbWFuZCBvYmplY3QsIGluaXRpYWxpemluZyBpdCB3aXRoIHRoZSBwYWNrYWdlIG5hbWUsIGRlc2NyaXB0aW9uLCBhbmQgdmVyc2lvblxuICAgKiBAcmV0dXJuIHtDb21tYW5kfSBUaGUgaW5pdGlhbGl6ZWQgQ29tbWFuZCBvYmplY3RcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgZ2V0IG1jcCgpIHtcbiAgICBpZiAoIXRoaXMuX21jcCkge1xuICAgICAgdGhpcy5fbWNwID0gbmV3IEZhc3RNQ1Aoe1xuICAgICAgICBuYW1lOiBcImRlY2FmLXRzIE1DUCBzZXJ2ZXJcIixcbiAgICAgICAgaW5zdHJ1Y3Rpb25zOiBcIlwiLFxuICAgICAgICB2ZXJzaW9uOiBWRVJTSU9OIGFzIGFueSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fbWNwO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMb2FkcyBhbmQgcmVnaXN0ZXJzIGFuIG1jcCBleHRlbnNpb24gbW9kdWxlIGZyb20gYSBmaWxlXG4gICAqIEBzdW1tYXJ5IER5bmFtaWNhbGx5IGltcG9ydHMgYW4gbWNwIGV4dGVuc2lvbiBtb2R1bGUgZnJvbSB0aGUgc3BlY2lmaWVkIGZpbGUgcGF0aCwgaW5pdGlhbGl6ZXMgaXQsIGFuZCByZWdpc3RlcnMgaXQgaW4gdGhlIG1vZHVsZXMgY29sbGVjdGlvblxuICAgKlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBsb2FkKFxuICAgIHNlcnZlcjogRmFzdE1DUCxcbiAgICBmaWxlUGF0aDogc3RyaW5nXG4gICk6IFByb21pc2U8eyBtY3A6IEZhc3RNQ1A7IHBhY2thZ2U6IHN0cmluZzsgdmVyc2lvbjogc3RyaW5nIH0+IHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5sb2FkKTtcblxuICAgIGxldCBwa2c6IHN0cmluZywgdmVyc2lvbjogc3RyaW5nLCBlbnJpY2g6IGFueTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgTWNwVXRpbHMubG9hZEZyb21GaWxlKGZpbGVQYXRoKTtcbiAgICAgIHBrZyA9IHJlcy5QQUNLQUdFX05BTUU7XG4gICAgICB2ZXJzaW9uID0gcmVzLlZFUlNJT047XG4gICAgICBlbnJpY2ggPSByZXMuZW5yaWNoO1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigoZSBhcyBhbnkpLm1lc3NhZ2UgfHwgKGUgYXMgYW55KSk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBsb2cuaW5mbyhgRW5yaWNoaW5nIG1jcCBzZXJ2ZXIgd2l0aCBtb2R1bGUgJHtwa2d9IHYke3ZlcnNpb259YCk7XG4gICAgICBjb25zdCByZXN1bHQgPSBlbnJpY2goc2VydmVyKTtcbiAgICAgIHNlcnZlciA9IHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UgPyBhd2FpdCByZXN1bHQgOiByZXN1bHQ7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgZmFpbGVkIHRvIGVucmljaCBtY3Agd2l0aCBtb2R1bGUgJHtwa2cgfHwgXCJ1bm5hbWVkXCJ9IHVuZGVyICR7ZmlsZVBhdGh9OiAke2UgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IGV9YFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIG1jcDogc2VydmVyLFxuICAgICAgcGFja2FnZTogcGtnLFxuICAgICAgdmVyc2lvbjogdmVyc2lvbixcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBGaW5kcyBhbmQgbG9hZHMgYWxsIENMSSBtb2R1bGVzIGluIHRoZSBiYXNlUGF0aFxuICAgKiBAc3VtbWFyeSBVc2VzIHRoZSBjcmF3bCBtZXRob2QgdG8gZmluZCBhbGwgQ0xJIG1vZHVsZXMgaW4gdGhlIHNwZWNpZmllZCBiYXNlIHBhdGgsXG4gICAqIHRoZW4gbG9hZHMgYW5kIHJlZ2lzdGVycyBlYWNoIG1vZHVsZSBhcyBhIHN1YmNvbW1hbmRcbiAgICpcbiAgICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBhbGwgbW9kdWxlcyBhcmUgbG9hZGVkXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENsaVdyYXBwZXJcbiAgICogICBwYXJ0aWNpcGFudCBGaWxlc3lzdGVtXG4gICAqICAgcGFydGljaXBhbnQgTW9kdWxlXG4gICAqXG4gICAqICAgQ2xpV3JhcHBlci0+PkZpbGVzeXN0ZW06IEpvaW4gYmFzZVBhdGggd2l0aCBjd2RcbiAgICogICBDbGlXcmFwcGVyLT4+Q2xpV3JhcHBlcjogY3Jhd2woYmFzZVBhdGgsIGNyYXdsTGV2ZWxzKVxuICAgKiAgIENsaVdyYXBwZXItLT4+Q2xpV3JhcHBlcjogbW9kdWxlc1tdXG4gICAqICAgbG9vcCBGb3IgZWFjaCBtb2R1bGVcbiAgICogICAgIGFsdCBOb3QgQGRlY2FmLXRzL2NsaVxuICAgKiAgICAgICBDbGlXcmFwcGVyLT4+Q2xpV3JhcHBlcjogbG9hZChtb2R1bGUsIGN3ZClcbiAgICogICAgICAgQ2xpV3JhcHBlci0tPj5DbGlXcmFwcGVyOiBuYW1lXG4gICAqICAgICAgIENsaVdyYXBwZXItPj5DbGlXcmFwcGVyOiBDaGVjayBpZiBjb21tYW5kIGV4aXN0c1xuICAgKiAgICAgICBhbHQgQ29tbWFuZCBkb2Vzbid0IGV4aXN0XG4gICAqICAgICAgICAgQ2xpV3JhcHBlci0+PkNvbW1hbmQ6IGNvbW1hbmQobmFtZSkuYWRkQ29tbWFuZChtb2R1bGVzW25hbWVdKVxuICAgKiAgICAgICBlbmRcbiAgICogICAgIGVuZFxuICAgKiAgIGVuZFxuICAgKiAgIENsaVdyYXBwZXItPj5Db25zb2xlOiBMb2cgbG9hZGVkIG1vZHVsZXNcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgYm9vdCgpIHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5ib290KTtcblxuICAgIGNvbnN0IGJhc2VQYXRoID0gcGF0aC5yZXNvbHZlKHRoaXMucm9vdFBhdGgsIHRoaXMuYmFzZVBhdGgpO1xuICAgIGNvbnN0IG1vZHVsZXMgPSB0aGlzLmNyYXdsKGJhc2VQYXRoLCB0aGlzLmNyYXdsTGV2ZWxzKTtcbiAgICBsZXQgc2VydmVyID0gdGhpcy5tY3A7XG4gICAgZm9yIChjb25zdCBtb2R1bGUgb2YgbW9kdWxlcykge1xuICAgICAgaWYgKG1vZHVsZS5pbmNsdWRlcyhcIkBkZWNhZi10cy9tY3BcIikpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLmxvYWQoc2VydmVyLCBtb2R1bGUpO1xuICAgICAgICBzZXJ2ZXIgPSByZXMubWNwO1xuICAgICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgICBsb2cuZXJyb3IoYEZhaWxlZCB0byBsb2FkIE1DUCBjb25maWdzIGZvciAke21vZHVsZX06ICR7ZX1gKTtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc29sZS5sb2coXG4gICAgICBgbG9hZGVkIG1vZHVsZXM6XFxuJHtPYmplY3Qua2V5cyh0aGlzLm1vZHVsZXMpXG4gICAgICAgIC5tYXAoKGspID0+IGAtICR7a31gKVxuICAgICAgICAuam9pbihcIlxcblwiKX1gXG4gICAgKTtcbiAgICByZXR1cm4gc2VydmVyO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZWN1cnNpdmVseSBzZWFyY2hlcyBmb3IgQ0xJIG1vZHVsZSBmaWxlcyBpbiB0aGUgZGlyZWN0b3J5IHN0cnVjdHVyZVxuICAgKiBAc3VtbWFyeSBDcmF3bHMgdGhlIGJhc2VQYXRoIHVwIHRvIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIGZvbGRlciBsZXZlbHMgdG8gZmluZCBmaWxlcyBuYW1lZCBhY2NvcmRpbmcgdG8gQ0xJX0ZJTEVfTkFNRVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYmFzZVBhdGggVGhlIGFic29sdXRlIGJhc2UgcGF0aCB0byBzdGFydCBzZWFyY2hpbmcgaW5cbiAgICogQHBhcmFtIHtudW1iZXJ9IFtsZXZlbHM9Ml0gVGhlIG1heGltdW0gbnVtYmVyIG9mIGRpcmVjdG9yeSBsZXZlbHMgdG8gY3Jhd2xcbiAgICogQHJldHVybiB7c3RyaW5nW119IEFuIGFycmF5IG9mIGZpbGUgcGF0aHMgdG8gQ0xJIG1vZHVsZXNcbiAgICpcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgY3Jhd2woYmFzZVBhdGg6IHN0cmluZywgbGV2ZWxzOiBudW1iZXIgPSAyKSB7XG4gICAgaWYgKGxldmVscyA8PSAwKSByZXR1cm4gW107XG4gICAgcmV0dXJuIGZzLnJlYWRkaXJTeW5jKGJhc2VQYXRoKS5yZWR1Y2UoKGFjY3VtOiBzdHJpbmdbXSwgZmlsZSkgPT4ge1xuICAgICAgZmlsZSA9IHBhdGguam9pbihiYXNlUGF0aCwgZmlsZSk7XG4gICAgICBpZiAoZnMuc3RhdFN5bmMoZmlsZSkuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgICBhY2N1bS5wdXNoKC4uLnRoaXMuY3Jhd2woZmlsZSwgbGV2ZWxzIC0gMSkpO1xuICAgICAgfSBlbHNlIGlmIChmaWxlLm1hdGNoKG5ldyBSZWdFeHAoYCR7TUNQX0ZJTEVfTkFNRX0uW2NtXT9qcyRgLCBcImdtXCIpKSkge1xuICAgICAgICBhY2N1bS5wdXNoKGZpbGUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjY3VtO1xuICAgIH0sIFtdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRXhlY3V0ZXMgdGhlIENMSSB3aXRoIHRoZSBwcm92aWRlZCBhcmd1bWVudHNcbiAgICogQHN1bW1hcnkgQm9vdHMgdGhlIENMSSBieSBsb2FkaW5nIGFsbCBtb2R1bGVzLCB0aGVuIHBhcnNlcyBhbmQgZXhlY3V0ZXMgdGhlIGNvbW1hbmQgc3BlY2lmaWVkIGluIHRoZSBhcmd1bWVudHNcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gW2FyZ3M9cHJvY2Vzcy5hcmd2XSBDb21tYW5kIGxpbmUgYXJndW1lbnRzIHRvIHBhcnNlIGFuZCBleGVjdXRlXG4gICAqIEByZXR1cm4ge1Byb21pc2U8dm9pZD59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIGNvbW1hbmQgZXhlY3V0aW9uIGlzIGNvbXBsZXRlXG4gICAqXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICAgKiAgIHBhcnRpY2lwYW50IENsaVdyYXBwZXJcbiAgICogICBwYXJ0aWNpcGFudCBDb21tYW5kXG4gICAqXG4gICAqICAgQ2xpZW50LT4+Q2xpV3JhcHBlcjogcnVuKGFyZ3MpXG4gICAqICAgQ2xpV3JhcHBlci0+PkNsaVdyYXBwZXI6IGJvb3QoKVxuICAgKiAgIE5vdGUgb3ZlciBDbGlXcmFwcGVyOiBMb2FkcyBhbGwgbW9kdWxlc1xuICAgKiAgIENsaVdyYXBwZXItPj5Db21tYW5kOiBwYXJzZUFzeW5jKGFyZ3MpXG4gICAqICAgQ29tbWFuZC0tPj5DbGlXcmFwcGVyOiByZXN1bHRcbiAgICogICBDbGlXcmFwcGVyLS0+PkNsaWVudDogcmVzdWx0XG4gICAqL1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIGFzeW5jIHJ1bihhcmdzOiBzdHJpbmdbXSA9IHByb2Nlc3MuYXJndikge1xuICAgIGNvbnN0IHNlcnZlciA9IGF3YWl0IHRoaXMuYm9vdCgpO1xuICAgIGF3YWl0IHNlcnZlci5zdGFydCh7IHRyYW5zcG9ydFR5cGU6IFwic3RkaW9cIiB9KTtcbiAgfVxufVxuIl0sIm5hbWVzIjpbIlZFUlNJT04iLCJQQUNLQUdFX05BTUUiLCJQS0ciLCJWIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUVBOzs7Ozs7QUFNRztBQUNJLE1BQU1BLFNBQU8sR0FBRyxhQUFhO0FBQzdCLE1BQU1DLGNBQVksR0FBRyxrQkFBa0I7QUFFOUMsSUFBSTtBQUNGLElBQUEsUUFBUSxDQUFDLGVBQWUsQ0FBQ0EsY0FBWSxFQUFFRCxTQUFPLENBQUM7QUFDakQ7QUFBRSxPQUFPLEtBQUssRUFBRTtBQUNkLElBQUEsSUFBSSxLQUFLLFlBQVksS0FBSyxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxFQUFFO1NBRTFEO0FBQ0wsUUFBQSxNQUFNLEtBQUs7O0FBRWY7O0FDTkEsU0FBUyxZQUFZLENBQUMsS0FBYSxFQUFBO0lBQ2pDLE9BQU8sS0FBSyxDQUFDLE9BQU8sQ0FBQyxxQkFBcUIsRUFBRSxNQUFNLENBQUM7QUFDckQ7QUFFQSxTQUFTLGVBQWUsQ0FBQyxJQUFtQixFQUFBO0FBQzFDLElBQUEsTUFBTSxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxHQUFHLEtBQUssSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7QUFDM0UsSUFBQSxPQUFPLElBQUksSUFBSSxDQUFDLElBQUksQ0FBSSxDQUFBLEVBQUEsSUFBSSxHQUFHO0FBQ2pDO0FBRUEsU0FBUyxlQUFlLENBQUMsUUFBZ0IsRUFBQTtBQUN2QyxJQUFBLEVBQUUsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQztBQUMzRDtBQUVBLFNBQVMscUJBQXFCLENBQzVCLGVBQTRDLEVBQzVDLFVBQXVDLEVBQUE7QUFFdkMsSUFBQSxNQUFNLEtBQUssR0FBRyxJQUFJLEdBQUcsRUFBVTtBQUMvQixJQUFBLEtBQUssQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDO0FBQ2xCLElBQUEsS0FBSyxNQUFNLFNBQVMsSUFBSSxlQUFlLElBQUksRUFBRSxFQUFFO0FBQzdDLFFBQUEsS0FBSyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDOztBQUUzQixJQUFBLEtBQUssTUFBTSxRQUFRLElBQUksVUFBVSxJQUFJLEVBQUUsRUFBRTtRQUN2QyxLQUFLLE1BQU0sU0FBUyxJQUFJLFFBQVEsQ0FBQyxVQUFVLElBQUksRUFBRSxFQUFFO0FBQ2pELFlBQUEsS0FBSyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDOzs7QUFHN0IsSUFBQSxPQUFPLEtBQUs7QUFDZDtBQUVBLFNBQVMsWUFBWSxDQUNuQixPQUFlLEVBQ2YsV0FBbUIsRUFDbkIsVUFBdUIsRUFBQTs7SUFHdkIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJO0FBQUUsUUFBQSxPQUFPLE9BQU87QUFDcEMsSUFBQSxNQUFNLFdBQVcsR0FBRyxJQUFJLE1BQU0sQ0FDNUIsQ0FBQSx1Q0FBQSxFQUEwQyxZQUFZLENBQUMsV0FBVyxDQUFDLENBQU8sS0FBQSxDQUFBLENBQzNFO0lBQ0QsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUM7SUFDeEMsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxJQUFJLEVBQUU7SUFFNUMsSUFBSSxLQUFLLEVBQUU7QUFDVCxRQUFBLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxDQUFDO2FBQ3JCLEtBQUssQ0FBQyxHQUFHO2FBQ1QsR0FBRyxDQUFDLENBQUMsSUFBSSxLQUFLLElBQUksQ0FBQyxJQUFJLEVBQUU7YUFDekIsTUFBTSxDQUFDLE9BQU8sQ0FBQztRQUNsQixNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsR0FBRyxRQUFRLEVBQUUsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFO0FBQ25FLFFBQUEsT0FBTyxPQUFPLENBQUMsT0FBTyxDQUNwQixXQUFXLEVBQ1gsQ0FBWSxTQUFBLEVBQUEsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxXQUFXLENBQUEsRUFBQSxDQUFJLENBQ3pEOztBQUdILElBQUEsTUFBTSxVQUFVLEdBQUcsQ0FBWSxTQUFBLEVBQUEsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQSxTQUFBLEVBQVksV0FBVyxDQUFBLEVBQUEsQ0FBSTtBQUMzRSxJQUFBLE9BQU8sQ0FBRyxFQUFBLFVBQVUsQ0FBTyxJQUFBLEVBQUEsT0FBTyxFQUFFO0FBQ3RDO0FBRUEsU0FBUyxnQkFBZ0IsQ0FBQyxRQUF1QixFQUFBO0lBQy9DLE1BQU0sVUFBVSxHQUFHLENBQUMsUUFBUSxDQUFDLFVBQVUsSUFBSSxFQUFFO1NBQzFDLEdBQUcsQ0FBQyxlQUFlO1NBQ25CLElBQUksQ0FBQyxNQUFNLENBQUM7QUFDZixJQUFBLE1BQU0sY0FBYyxHQUFHLFVBQVUsR0FBRyxDQUFLLEVBQUEsRUFBQSxVQUFVLENBQUksRUFBQSxDQUFBLEdBQUcsRUFBRTtJQUM1RCxPQUFPLENBQUEsRUFBRyxjQUFjLENBQUEsRUFBQSxFQUFLLFFBQVEsQ0FBQyxJQUFJLENBQUEsRUFBQSxFQUFLLFFBQVEsQ0FBQyxJQUFJLENBQUEsQ0FBQSxDQUFHO0FBQ2pFO0FBRUEsU0FBUyxtQkFBbUIsQ0FBQyxPQUFlLEVBQUUsWUFBb0IsRUFBQTtJQUNoRSxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQztJQUNwQyxNQUFNLE1BQU0sR0FBYSxFQUFFO0FBQzNCLElBQUEsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7QUFDckMsUUFBQSxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ3JCLElBQ0UsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUM7QUFDM0IsWUFBQSxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFHLEVBQUEsWUFBWSxDQUFHLENBQUEsQ0FBQSxDQUFDLEVBQzFDO1lBQ0E7O1FBRUYsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsWUFBWSxDQUFBLENBQUEsQ0FBRyxDQUFDLEVBQUU7O1lBRXJDOztBQUVGLFFBQUEsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7O0FBRW5CLElBQUEsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztBQUMxQjtBQUVBLFNBQVMsZUFBZSxDQUN0QixPQUFlLEVBQ2YsU0FBd0IsRUFDeEIsTUFHQyxFQUFBO0FBRUQsSUFBQSxNQUFNLGFBQWEsR0FBRyxlQUFlLENBQUMsU0FBUyxDQUFDO0FBQ2hELElBQUEsSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLE9BQU8sRUFBRTtRQUMzQixNQUFNLFVBQVUsR0FBRyxpQ0FBaUM7QUFDcEQsUUFBQSxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDO0FBQUUsWUFBQSxPQUFPLE9BQU87UUFDbkQsT0FBTyxPQUFPLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxDQUFHLEVBQUEsYUFBYSxDQUFNLElBQUEsQ0FBQSxDQUFDOztJQUU1RCxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUk7QUFBRSxRQUFBLE9BQU8sT0FBTztBQUNoQyxJQUFBLE1BQU0sYUFBYSxHQUFHLElBQUksTUFBTSxDQUM5Qix3QkFBd0IsWUFBWSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQSxDQUFBLENBQUcsRUFDcEQsR0FBRyxDQUNKO0lBQ0QsTUFBTSxLQUFLLEdBQUcsYUFBYSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7QUFDekMsSUFBQSxJQUFJLENBQUMsS0FBSztBQUFFLFFBQUEsT0FBTyxPQUFPO0lBQzFCLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJO0lBQy9CLElBQUksT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLE1BQU0sQ0FBQSxFQUFHLGFBQWEsQ0FBQSxDQUFFLENBQUM7QUFBRSxRQUFBLE9BQU8sT0FBTztJQUNqRSxRQUNFLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxLQUFLLENBQUM7UUFDN0IsQ0FBRyxFQUFBLE1BQU0sQ0FBRyxFQUFBLGFBQWEsQ0FBSSxFQUFBLENBQUE7UUFDN0IsT0FBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDO0FBRTlCO0FBRUEsU0FBUyxlQUFlLENBQ3RCLE9BQWUsRUFDZixhQUFxQixFQUNyQixNQUdDLEVBQUE7QUFFRCxJQUFBLE1BQU0sY0FBYyxHQUFHLElBQUksTUFBTSxDQUMvQixDQUFTLE1BQUEsRUFBQSxZQUFZLENBQUMsYUFBYSxDQUFDLENBQUEsV0FBQSxDQUFhLEVBQ2pELEdBQUcsQ0FDSjtBQUNELElBQUEsSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLE9BQU8sRUFBRTtRQUMzQixPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUMsY0FBYyxFQUFFLEVBQUUsQ0FBQzs7QUFFNUMsSUFBQSxJQUFJLE1BQU0sQ0FBQyxJQUFJLEVBQUU7UUFDZixNQUFNLE9BQU8sR0FBRyxJQUFJLE1BQU0sQ0FDeEIsQ0FBVSxPQUFBLEVBQUEsWUFBWSxDQUFDLGFBQWEsQ0FBQyw4QkFBOEIsWUFBWSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBSSxFQUFBLENBQUEsRUFDaEcsR0FBRyxDQUNKO1FBQ0QsT0FBTyxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUM7O0FBRXJDLElBQUEsT0FBTyxPQUFPO0FBQ2hCO0FBRUEsU0FBUyxjQUFjLENBQUMsUUFBZ0IsRUFBRSxPQUFlLEVBQUE7SUFDdkQsZUFBZSxDQUFDLFFBQVEsQ0FBQztBQUN6QixJQUFBLEVBQUUsQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQztBQUNyQztBQUVPLE1BQU0sY0FBYyxHQUFHO0FBQzVCLElBQUEsdUJBQXVCLEVBQUU7QUFDdkIsUUFBQSxJQUFJLEVBQUUsd0JBQXdCO0FBQzlCLFFBQUEsV0FBVyxFQUFFLGlEQUFpRDtBQUM5RCxRQUFBLE9BQU8sRUFBRSxPQUFPLElBT2YsS0FBSTtBQUNILFlBQUEsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksRUFBRSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUU7Z0JBQ25ELE1BQU0sSUFBSSxLQUFLLENBQUMsQ0FBQSx1QkFBQSxFQUEwQixJQUFJLENBQUMsUUFBUSxDQUFFLENBQUEsQ0FBQzs7QUFFNUQsWUFBQSxNQUFNLFVBQVUsR0FBRyxxQkFBcUIsQ0FDdEMsSUFBSSxDQUFDLGVBQWUsRUFDcEIsSUFBSSxDQUFDLFVBQVUsQ0FDaEI7WUFDRCxJQUFJLE9BQU8sR0FBRyxDQUFBLFFBQUEsQ0FBVTtZQUN4QixLQUFLLE1BQU0sU0FBUyxJQUFJLElBQUksQ0FBQyxlQUFlLElBQUksRUFBRSxFQUFFO0FBQ2xELGdCQUFBLE9BQU8sSUFBSSxDQUFLLEVBQUEsRUFBQSxlQUFlLENBQUMsU0FBUyxDQUFDLEVBQUU7O1lBRTlDLE1BQU0sVUFBVSxHQUFHLENBQUMsSUFBSSxDQUFDLFVBQVUsSUFBSSxFQUFFO2lCQUN0QyxHQUFHLENBQUMsZ0JBQWdCO2lCQUNwQixJQUFJLENBQUMsTUFBTSxDQUFDO0FBQ2YsWUFBQSxPQUFPLElBQUksQ0FBa0IsZUFBQSxFQUFBLElBQUksQ0FBQyxTQUFTLENBQUEsSUFBQSxFQUFPLFVBQVUsR0FBRyxDQUFBLEVBQUcsVUFBVSxDQUFJLEVBQUEsQ0FBQSxHQUFHLEVBQUUsS0FBSztZQUMxRixPQUFPLEdBQUcsWUFBWSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsV0FBVyxFQUFFLFVBQVUsQ0FBQztBQUM3RCxZQUFBLGNBQWMsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQztBQUN0QyxZQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRTtTQUNuQztBQUNGLEtBQUE7QUFDRCxJQUFBLGdCQUFnQixFQUFFO0FBQ2hCLFFBQUEsSUFBSSxFQUFFLGVBQWU7QUFDckIsUUFBQSxXQUFXLEVBQUUsZ0RBQWdEO0FBQzdELFFBQUEsT0FBTyxFQUFFLE9BQU8sSUFLZixLQUFJO1lBQ0gsSUFBSSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFO2dCQUNqQyxNQUFNLElBQUksS0FBSyxDQUFDLENBQUEsd0JBQUEsRUFBMkIsSUFBSSxDQUFDLFFBQVEsQ0FBRSxDQUFBLENBQUM7O0FBRTdELFlBQUEsSUFBSSxPQUFPLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQztBQUNwRCxZQUFBLElBQUksT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFHLEVBQUEsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUcsQ0FBQSxDQUFBLENBQUMsRUFBRTtBQUMvQyxnQkFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUU7O0FBRXBDLFlBQUEsTUFBTSxVQUFVLEdBQUcscUJBQXFCLENBQUMsU0FBUyxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ3JFLE9BQU8sR0FBRyxZQUFZLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxXQUFXLEVBQUUsVUFBVSxDQUFDO1lBQzdELE1BQU0sY0FBYyxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDO1lBQy9DLE1BQU0sS0FBSyxHQUFHLGdCQUFnQixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUM7QUFDOUMsWUFBQSxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxjQUFjLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQztZQUNuRSxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQztZQUMzQyxNQUFNLE9BQU8sR0FBRyxDQUFHLEVBQUEsTUFBTSxLQUFLLEtBQUssQ0FBQSxFQUFBLEVBQUssS0FBSyxDQUFBLENBQUU7QUFDL0MsWUFBQSxjQUFjLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUM7QUFDdEMsWUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUU7U0FDbkM7QUFDRixLQUFBO0FBQ0QsSUFBQSxtQkFBbUIsRUFBRTtBQUNuQixRQUFBLElBQUksRUFBRSxrQkFBa0I7QUFDeEIsUUFBQSxXQUFXLEVBQUUsd0NBQXdDO0FBQ3JELFFBQUEsT0FBTyxFQUFFLE9BQU8sSUFJZixLQUFJO1lBQ0gsSUFBSSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQztBQUFFLGdCQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRTtBQUNyRSxZQUFBLE1BQU0sT0FBTyxHQUFHLEVBQUUsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUM7WUFDdEQsTUFBTSxPQUFPLEdBQUcsbUJBQW1CLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUM7QUFDaEUsWUFBQSxjQUFjLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUM7QUFDdEMsWUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUU7U0FDbkM7QUFDRixLQUFBO0FBQ0QsSUFBQSxrQkFBa0IsRUFBRTtBQUNsQixRQUFBLElBQUksRUFBRSxpQkFBaUI7QUFDdkIsUUFBQSxXQUFXLEVBQUUsMENBQTBDO0FBQ3ZELFFBQUEsT0FBTyxFQUFFLE9BQU8sSUFNZixLQUFJO1lBQ0gsSUFBSSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFO2dCQUNqQyxNQUFNLElBQUksS0FBSyxDQUFDLENBQUEsd0JBQUEsRUFBMkIsSUFBSSxDQUFDLFFBQVEsQ0FBRSxDQUFBLENBQUM7O0FBRTdELFlBQUEsSUFBSSxPQUFPLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQztBQUNwRCxZQUFBLE1BQU0sVUFBVSxHQUFHLElBQUksR0FBRyxDQUFTLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN6RCxPQUFPLEdBQUcsWUFBWSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsV0FBVyxFQUFFLFVBQVUsQ0FBQztBQUM3RCxZQUFBLE9BQU8sR0FBRyxlQUFlLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQztBQUMvRCxZQUFBLGNBQWMsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQztBQUN0QyxZQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRTtTQUNuQztBQUNGLEtBQUE7QUFDRCxJQUFBLG1CQUFtQixFQUFFO0FBQ25CLFFBQUEsSUFBSSxFQUFFLGtCQUFrQjtBQUN4QixRQUFBLFdBQVcsRUFBRSw2Q0FBNkM7QUFDMUQsUUFBQSxPQUFPLEVBQUUsT0FBTyxJQUtmLEtBQUk7WUFDSCxJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDO0FBQUUsZ0JBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFO0FBQ3JFLFlBQUEsSUFBSSxPQUFPLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQztBQUNwRCxZQUFBLE9BQU8sR0FBRyxlQUFlLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQztBQUNuRSxZQUFBLGNBQWMsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQztBQUN0QyxZQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRTtTQUNuQztBQUNGLEtBQUE7QUFDRCxJQUFBLHFCQUFxQixFQUFFO0FBQ3JCLFFBQUEsSUFBSSxFQUFFLG9CQUFvQjtBQUMxQixRQUFBLFdBQVcsRUFBRSxtREFBbUQ7QUFDaEUsUUFBQSxPQUFPLEVBQUUsT0FBTyxJQUlmLEtBQUk7QUFDSCxZQUFBLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUEsR0FBQSxDQUFLLENBQUM7WUFDbEUsZUFBZSxDQUFDLFNBQVMsQ0FBQztBQUMxQixZQUFBLE1BQU0sWUFBWSxHQUFHLENBQUEsYUFBQSxFQUFnQixJQUFJLENBQUMsSUFBSSxzRkFBc0Y7QUFDcEksWUFBQSxFQUFFLENBQUMsYUFBYSxDQUFDLFNBQVMsRUFBRSxZQUFZLENBQUM7QUFDekMsWUFBQSxJQUFJLGFBQWlDO0FBQ3JDLFlBQUEsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFO0FBQ3JCLGdCQUFBLGFBQWEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUN2QixJQUFJLENBQUMsWUFBWSxFQUNqQixHQUFHLElBQUksQ0FBQyxJQUFJLENBQUEsWUFBQSxDQUFjLENBQzNCO2dCQUNELGVBQWUsQ0FBQyxhQUFhLENBQUM7Z0JBQzlCLEVBQUUsQ0FBQyxhQUFhLENBQ2QsYUFBYSxFQUNiLENBQW1CLGdCQUFBLEVBQUEsSUFBSSxDQUFDLElBQUksQ0FBNEMsMENBQUEsQ0FBQSxDQUN6RTs7QUFFSCxZQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsYUFBYSxFQUFFO1NBQ3BDO0FBQ0YsS0FBQTtBQUNELElBQUEsc0JBQXNCLEVBQUU7QUFDdEIsUUFBQSxJQUFJLEVBQUUscUJBQXFCO0FBQzNCLFFBQUEsV0FBVyxFQUFFLG1EQUFtRDtBQUNoRSxRQUFBLE9BQU8sRUFBRSxPQUFPLElBS2YsS0FBSTtBQUNILFlBQUEsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQSxHQUFBLENBQUssQ0FBQztZQUN4RCxlQUFlLENBQUMsU0FBUyxDQUFDO1lBQzFCLEVBQUUsQ0FBQyxhQUFhLENBQ2QsU0FBUyxFQUNULENBQWdCLGFBQUEsRUFBQSxJQUFJLENBQUMsSUFBSSxDQUF3RixzRkFBQSxDQUFBLENBQ2xIO0FBQ0QsWUFBQSxJQUFJLFlBQWdDO0FBQ3BDLFlBQUEsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFO0FBQ3BCLGdCQUFBLFlBQVksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFBLFdBQUEsQ0FBYSxDQUFDO2dCQUNyRSxlQUFlLENBQUMsWUFBWSxDQUFDO2dCQUM3QixFQUFFLENBQUMsYUFBYSxDQUNkLFlBQVksRUFDWixDQUEyQix3QkFBQSxFQUFBLElBQUksQ0FBQyxJQUFJLENBQWtCLGVBQUEsRUFBQSxJQUFJLENBQUMsVUFBVSxHQUFHLFdBQVcsR0FBRyxZQUFZLENBQVEsTUFBQSxDQUFBLENBQzNHOztBQUVILFlBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUU7U0FDbkM7QUFDRixLQUFBO0FBQ0QsSUFBQSxtQkFBbUIsRUFBRTtBQUNuQixRQUFBLElBQUksRUFBRSxrQkFBa0I7QUFDeEIsUUFBQSxXQUFXLEVBQUUsbURBQW1EO0FBQ2hFLFFBQUEsT0FBTyxFQUFFLE9BQU8sSUFLZixLQUFJO0FBQ0gsWUFBQSxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFBLEdBQUEsQ0FBSyxDQUFDO1lBQzNELGVBQWUsQ0FBQyxZQUFZLENBQUM7WUFDN0IsRUFBRSxDQUFDLGFBQWEsQ0FDZCxZQUFZLEVBQ1osQ0FBbUIsZ0JBQUEsRUFBQSxJQUFJLENBQUMsSUFBSSxDQUE4RSw0RUFBQSxDQUFBLENBQzNHO0FBQ0QsWUFBQSxJQUFJLFlBQWdDO0FBQ3BDLFlBQUEsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFO0FBQ3BCLGdCQUFBLFlBQVksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFBLFdBQUEsQ0FBYSxDQUFDO2dCQUNyRSxlQUFlLENBQUMsWUFBWSxDQUFDO2dCQUM3QixFQUFFLENBQUMsYUFBYSxDQUNkLFlBQVksRUFDWixDQUEyQix3QkFBQSxFQUFBLElBQUksQ0FBQyxJQUFJLENBQWtCLGVBQUEsRUFBQSxJQUFJLENBQUMsVUFBVSxHQUFHLFdBQVcsR0FBRyxZQUFZLENBQVEsTUFBQSxDQUFBLENBQzNHOztBQUVILFlBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUU7U0FDdEM7QUFDRixLQUFBO0NBQ087O0FDelZWLE1BQU0sa0JBQWtCLEdBQUcsb0JBQW9CO0FBQy9DLE1BQU0sa0JBQWtCLEdBQUcsQ0FBQyxlQUFlLEVBQUUsZ0JBQWdCLENBQUM7QUFDOUQsTUFBTSxtQkFBbUIsR0FBRyxLQUFLO0FBQ2pDLE1BQU0sbUJBQW1CLEdBQUc7QUFDMUIsSUFBQTtBQUNFLFFBQUEsRUFBRSxFQUFFLFFBQVE7QUFDWixRQUFBLE9BQU8sRUFBRSxvQkFBb0I7QUFDN0IsUUFBQSxZQUFZLEVBQ1Ysb01BQW9NO0FBQ3ZNLEtBQUE7QUFDRCxJQUFBO0FBQ0UsUUFBQSxFQUFFLEVBQUUsUUFBUTtBQUNaLFFBQUEsT0FBTyxFQUFFLFFBQVE7QUFDakIsUUFBQSxZQUFZLEVBQ1YsaUxBQWlMO0FBQ3BMLEtBQUE7QUFDRCxJQUFBO0FBQ0UsUUFBQSxFQUFFLEVBQUUsU0FBUztBQUNiLFFBQUEsT0FBTyxFQUFFLGdCQUFnQjtBQUN6QixRQUFBLFlBQVksRUFDVixpTUFBaU07QUFDcE0sS0FBQTtDQUNPO0FBRVYsTUFBTSxrQkFBa0IsR0FBRztBQUN4QixLQUFBLE1BQU0sQ0FBQztJQUNOLFFBQVEsRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxzQkFBc0IsQ0FBQztBQUNuRCxJQUFBLFVBQVUsRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQ2pDLGFBQWEsRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQztJQUN4QyxXQUFXLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUM7SUFDdEMsZUFBZSxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDO0FBQzFDLElBQUEsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUN4QyxRQUFRLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7Q0FDckM7QUFDQSxLQUFBLE1BQU0sRUFBRTtBQUlYLE1BQU0sZ0JBQWdCLEdBQUc7QUFDdEIsS0FBQSxNQUFNLENBQUM7SUFDTixRQUFRLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsc0JBQXNCLENBQUM7SUFDbkQsS0FBSyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLG1CQUFtQixDQUFDO0lBQzdDLE1BQU0sRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQztJQUNsQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUM7SUFDbkMsV0FBVyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDeEQsUUFBUSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO0NBQ3JDO0FBQ0EsS0FBQSxNQUFNLEVBQUU7QUF5QlgsSUFBSSxhQUFhLEdBQUcsdUJBQXVCLEVBQUU7QUFDN0MsSUFBSSxhQUEyRDtBQUUvRCxNQUFNLGNBQWUsU0FBUSxLQUFLLENBQUE7QUFDaEMsSUFBQSxXQUFBLENBQVksT0FBZSxFQUFBO1FBQ3pCLEtBQUssQ0FBQyxPQUFPLENBQUM7QUFDZCxRQUFBLElBQUksQ0FBQyxJQUFJLEdBQUcsZ0JBQWdCOztBQUUvQjtBQUVELGVBQWUsZ0JBQWdCLEdBQUE7SUFDN0IsSUFBSSxDQUFDLGFBQWEsRUFBRTtBQUNsQixRQUFBLElBQUk7QUFDRixZQUFBLE1BQU0sR0FBRyxHQUFHLE1BQU0sT0FBTyxTQUFTLENBQUM7QUFDbkMsWUFBQSxhQUFhLEdBQUk7QUFDZCxpQkFBQSxTQUFTOztBQUNaLFFBQUEsTUFBTTtBQUNOLFlBQUEsYUFBYSxHQUFHLE1BQU0sWUFBYSxTQUFRLEtBQUssQ0FBQTtBQUM5QyxnQkFBQSxXQUFBLENBQVksT0FBZSxFQUFBO29CQUN6QixLQUFLLENBQUMsT0FBTyxDQUFDO0FBQ2Qsb0JBQUEsSUFBSSxDQUFDLElBQUksR0FBRyxjQUFjOzthQUU3Qjs7O0FBR0wsSUFBQSxPQUFPLGFBQWE7QUFDdEI7QUFFQSxlQUFlLGNBQWMsQ0FBQyxPQUFlLEVBQUE7QUFDM0MsSUFBQSxNQUFNLElBQUksR0FBRyxNQUFNLGdCQUFnQixFQUFFO0FBQ3JDLElBQUEsTUFBTSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUM7QUFDekI7QUFFQSxNQUFNLGdCQUFnQixHQUErQztBQUNuRSxJQUFBLFdBQVcsRUFBRTtBQUNYLFFBQUEsY0FBYyxFQUFFLElBQUk7QUFDcEIsUUFBQSxhQUFhLEVBQUUsS0FBSztBQUNwQixRQUFBLFlBQVksRUFBRSxJQUFJO0FBQ2xCLFFBQUEsS0FBSyxFQUFFLHNCQUFzQjtBQUM5QixLQUFBO0FBQ0QsSUFBQSxXQUFXLEVBQ1QseUdBQXlHOztBQUUzRyxJQUFBLE9BQU8sRUFBRSxPQUFPLEtBQUssRUFBRSxRQUFRLEtBQTRCO1FBQ3pELE1BQU0sSUFBSSxHQUFHLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxLQUF5QixDQUFDO0FBQ2hFLFFBQUEsTUFBTSxJQUFJLEdBQUcsZ0JBQWdCLEVBQUU7QUFDL0IsUUFBQSxJQUFJLFFBQWdCO0FBQ3BCLFFBQUEsSUFBSTtZQUNGLFFBQVEsR0FBRyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQzs7UUFDbEQsT0FBTyxLQUFLLEVBQUU7QUFDZCxZQUFBLElBQUksS0FBSyxZQUFZLGNBQWMsRUFBRTtBQUNuQyxnQkFBQSxPQUFPLGNBQWMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDOzs7QUFHdEMsWUFBQSxNQUFNLEtBQUs7O1FBR2IsSUFBSSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLEVBQUU7WUFDNUIsT0FBTyxjQUFjLENBQUMsQ0FBbUMsZ0NBQUEsRUFBQSxJQUFJLENBQUMsUUFBUSxDQUFBLENBQUUsQ0FBQzs7QUFHM0UsUUFBQSxNQUFNLFdBQVcsR0FBRyxFQUFFLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRTtZQUM1QyxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQTBCO0FBQzFDLFNBQUEsQ0FBQztBQUNGLFFBQUEsTUFBTSxPQUFPLEdBQUcsa0JBQWtCLENBQUMsSUFBSSxDQUFDO0FBRXhDLFFBQUEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUU7QUFDbkIsWUFBQSxPQUFPLGNBQWMsQ0FDbkIsc0VBQXNFLENBQ3ZFOztBQUdILFFBQUEsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUN6QixPQUFPLEVBQ1AsSUFBSSxDQUFDLFVBQVUsSUFBSSxtQkFBbUIsQ0FDdkM7QUFFRCxRQUFBLE9BQU8seUJBQXlCLENBQUM7WUFDL0IsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRO1lBQ3ZCLFdBQVc7WUFDWCxNQUFNO1lBQ04sV0FBVyxFQUFFLElBQUksQ0FBQyxXQUFXO1lBQzdCLGFBQWEsRUFBRSxJQUFJLENBQUMsYUFBYTtZQUNqQyxlQUFlLEVBQUUsSUFBSSxDQUFDLGVBQWU7WUFDckMsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLGlCQUFpQjtBQUMxQyxTQUFBLENBQUM7S0FDSDtBQUNELElBQUEsSUFBSSxFQUFFLGVBQWU7QUFDckIsSUFBQSxVQUFVLEVBQUUsa0JBQWtCO0NBQy9CO0FBRUQsTUFBTSxtQkFBbUIsR0FBNkM7QUFDcEUsSUFBQSxXQUFXLEVBQUU7QUFDWCxRQUFBLGVBQWUsRUFBRSxJQUFJO0FBQ3JCLFFBQUEsY0FBYyxFQUFFLEtBQUs7QUFDckIsUUFBQSxhQUFhLEVBQUUsS0FBSztBQUNwQixRQUFBLFlBQVksRUFBRSxLQUFLO0FBQ25CLFFBQUEsS0FBSyxFQUFFLGtCQUFrQjtBQUMxQixLQUFBO0FBQ0QsSUFBQSxXQUFXLEVBQ1QsbUdBQW1HOztBQUVyRyxJQUFBLE9BQU8sRUFBRSxPQUFPLEtBQUssRUFBRSxRQUFRLEtBQXFDO1FBQ2xFLE1BQU0sSUFBSSxHQUFHLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxLQUE0QixDQUFDO0FBQ2pFLFFBQUEsTUFBTSxJQUFJLEdBQUcsZ0JBQWdCLEVBQUU7QUFDL0IsUUFBQSxJQUFJLFFBQWdCO0FBQ3BCLFFBQUEsSUFBSTtZQUNGLFFBQVEsR0FBRyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQzs7UUFDbEQsT0FBTyxLQUFLLEVBQUU7QUFDZCxZQUFBLElBQUksS0FBSyxZQUFZLGNBQWMsRUFBRTtBQUNuQyxnQkFBQSxPQUFPLGNBQWMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDOztBQUV0QyxZQUFBLE1BQU0sS0FBSzs7QUFHYixRQUFBLE1BQU0sUUFBUSxHQUFHLEVBQUUsQ0FBQyxVQUFVLENBQUMsUUFBUTtjQUNuQyxFQUFFLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBMEI7Y0FDekQsRUFBRTtBQUVOLFFBQUEsSUFBSSxPQUF1QjtBQUMzQixRQUFBLElBQUk7WUFDRixPQUFPLEdBQUcsVUFBVSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDOztRQUMxQyxPQUFPLEtBQUssRUFBRTtZQUNkLE9BQU8sY0FBYyxDQUNuQixDQUFxQyxrQ0FBQSxFQUFBLElBQUksQ0FBQyxRQUFRLENBQUEsRUFBQSxFQUFLLEtBQUssWUFBWSxLQUFLLEdBQUcsS0FBSyxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUUsQ0FBQSxDQUN4Rzs7O0FBR0gsUUFBQSxJQUFJLE9BQU8sS0FBSyxLQUFLLEVBQUU7WUFDckIsT0FBTyxjQUFjLENBQ25CLENBQXFDLGtDQUFBLEVBQUEsSUFBSSxDQUFDLFFBQVEsQ0FBQSxDQUFFLENBQ3JEOztBQUdILFFBQUEsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUU7QUFDaEIsWUFBQSxFQUFFLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUM7QUFDekQsWUFBQSxFQUFFLENBQUMsYUFBYSxDQUFDLFFBQVEsRUFBRSxPQUFPLEVBQUU7Z0JBQ2xDLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBMEI7QUFDMUMsYUFBQSxDQUFDOztBQUdKLFFBQUEsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUU7QUFDbEIsWUFBQSxPQUFPLFNBQVMsSUFBSSxDQUFDLE1BQU0sR0FBRyxXQUFXLEdBQUcsU0FBUyxDQUFBLEtBQUEsRUFBUSxJQUFJLENBQUMsUUFBUSxFQUFFOztBQUc5RSxRQUFBLE1BQU0sT0FBTyxHQUFHLG1CQUFtQixDQUNqQyxJQUFJLENBQUMsUUFBUSxFQUNiLElBQUksQ0FBQyxRQUFRLEVBQ2IsUUFBUSxFQUNSLE9BQU8sRUFDUCxTQUFTLEVBQ1QsU0FBUyxFQUNULEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FDOUI7UUFFRCxPQUFPO0FBQ0wsWUFBQSxPQUFPLEVBQUU7QUFDUCxnQkFBQTtBQUNFLG9CQUFBLElBQUksRUFBRSxNQUFNO0FBQ1osb0JBQUEsSUFBSSxFQUFFLENBQVMsTUFBQSxFQUFBLElBQUksQ0FBQyxNQUFNLEdBQUcsV0FBVyxHQUFHLFNBQVMsUUFBUSxJQUFJLENBQUMsUUFBUSxDQUFFLENBQUE7QUFDNUUsaUJBQUE7QUFDRCxnQkFBQTtBQUNFLG9CQUFBLElBQUksRUFBRSxNQUFNO0FBQ1osb0JBQUEsSUFBSSxFQUFFLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO0FBQ3BELGlCQUFBO0FBQ0YsYUFBQTtTQUNzQjtLQUMxQjtBQUNELElBQUEsSUFBSSxFQUFFLG1CQUFtQjtBQUN6QixJQUFBLFVBQVUsRUFBRSxnQkFBZ0I7Q0FDN0I7QUFFWSxNQUFBLEtBQUssR0FBRztBQUNuQixJQUFBLEdBQUcsY0FBYztJQUNqQixnQkFBZ0I7SUFDaEIsbUJBQW1COztBQUdmLFNBQVUsTUFBTSxDQUFDLEdBQVksRUFBQTtBQUNqQyxJQUFBLEtBQUssTUFBTSxNQUFNLElBQUksZUFBZSxFQUFFLEVBQUU7QUFDdEMsUUFBQSxHQUFHLENBQUMsU0FBUyxDQUFDLE1BQWEsQ0FBQzs7SUFHOUIsS0FBSyxNQUFNLElBQUksSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFO0FBQ3ZDLFFBQUEsR0FBRyxDQUFDLE9BQU8sQ0FBQyxJQUFXLENBQUM7O0FBRzFCLElBQUEsS0FBSyxNQUFNLFFBQVEsSUFBSSxzQkFBc0IsRUFBRSxFQUFFO0FBQy9DLFFBQUEsR0FBRyxDQUFDLG1CQUFtQixDQUFDLFFBQWUsQ0FBQzs7QUFHMUMsSUFBQSxPQUFPLEdBQUc7QUFDWjtBQUdPLE1BQU0sWUFBWSxHQUFHRTtBQUNyQixNQUFNLE9BQU8sR0FBR0M7QUFFakIsU0FBVSxnQkFBZ0IsQ0FBQyxJQUFZLEVBQUE7QUFDM0MsSUFBQSxhQUFhLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUM7QUFDcEM7U0FFZ0IsZ0JBQWdCLEdBQUE7QUFDOUIsSUFBQSxPQUFPLGFBQWE7QUFDdEI7U0FFZ0Isc0JBQXNCLEdBQUE7QUFDcEMsSUFBQSxNQUFNLElBQUksR0FBRyxnQkFBZ0IsRUFBRTtBQUMvQixJQUFBLE1BQU0sZUFBZSxHQUFHO0FBQ3RCLFFBQUE7QUFDRSxZQUFBLElBQUksRUFBRSxNQUFNO0FBQ1osWUFBQSxXQUFXLEVBQUUscUNBQXFDO0FBQ2xELFlBQUEsUUFBUSxFQUFFLElBQUk7QUFDZixTQUFBO0tBQ087SUFFVixPQUFPO0FBQ0wsUUFBQTtBQUNFLFlBQUEsSUFBSSxFQUFFLHVCQUF1QjtBQUM3QixZQUFBLFdBQVcsRUFDVCxpRUFBaUU7QUFDbkUsWUFBQSxXQUFXLEVBQUUsMkJBQTJCO0FBQ3hDLFlBQUEsUUFBUSxFQUFFLFlBQVk7QUFDdEIsWUFBQSxTQUFTLEVBQUUsZUFBZTtBQUMxQixZQUFBLElBQUksRUFBRSxPQUFPLElBQXNCLEtBQUk7Z0JBQ3JDLE1BQU0sSUFBSSxHQUFHLE1BQU0saUJBQWlCLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUM7Z0JBQ3JELE9BQU8sRUFBRSxJQUFJLEVBQUU7YUFDaEI7QUFDRixTQUFBO0FBQ0QsUUFBQTtBQUNFLFlBQUEsSUFBSSxFQUFFLHVCQUF1QjtBQUM3QixZQUFBLFdBQVcsRUFBRSxxREFBcUQ7QUFDbEUsWUFBQSxXQUFXLEVBQUUsMkJBQTJCO0FBQ3hDLFlBQUEsUUFBUSxFQUFFLFlBQVk7QUFDdEIsWUFBQSxTQUFTLEVBQUUsZUFBZTtBQUMxQixZQUFBLElBQUksRUFBRSxPQUFPLElBQXNCLEtBQUk7Z0JBQ3JDLE1BQU0sSUFBSSxHQUFHLE1BQU0saUJBQWlCLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUM7Z0JBQ3JELE9BQU8sRUFBRSxJQUFJLEVBQUU7YUFDaEI7QUFDRixTQUFBO0FBQ0QsUUFBQTtBQUNFLFlBQUEsSUFBSSxFQUFFLHdCQUF3QjtBQUM5QixZQUFBLFdBQVcsRUFDVCw4REFBOEQ7QUFDaEUsWUFBQSxXQUFXLEVBQUUsNEJBQTRCO0FBQ3pDLFlBQUEsUUFBUSxFQUFFLFlBQVk7QUFDdEIsWUFBQSxTQUFTLEVBQUUsZUFBZTtBQUMxQixZQUFBLElBQUksRUFBRSxPQUFPLElBQXNCLEtBQUk7Z0JBQ3JDLE1BQU0sSUFBSSxHQUFHLE1BQU0saUJBQWlCLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUM7Z0JBQ3JELE9BQU8sRUFBRSxJQUFJLEVBQUU7YUFDaEI7QUFDRixTQUFBO0tBQ0Y7QUFDSDtBQUVBLFNBQVMsdUJBQXVCLEdBQUE7SUFDOUIsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQztJQUNsRCxJQUFJLFVBQVUsSUFBSSxVQUFVLENBQUMsSUFBSSxFQUFFLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtRQUM5QyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDOztBQUV4QyxJQUFBLE9BQU8sT0FBTyxDQUFDLEdBQUcsRUFBRTtBQUN0QjtTQUVnQixlQUFlLEdBQUE7QUFDN0IsSUFBQSxNQUFNLElBQUksR0FBRyxnQkFBZ0IsRUFBRTtBQUMvQixJQUFBLE1BQU0sZ0JBQWdCLEdBQUcsa0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxNQUFNO0FBQ2pFLFFBQUEsSUFBSSxFQUFFLENBQUEsSUFBQSxFQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUUsQ0FBQTtRQUMxQixXQUFXLEVBQUUsTUFBTSxDQUFDLFdBQVc7QUFDL0IsUUFBQSxJQUFJLEVBQUUsWUFBWSxNQUFNLENBQUMsT0FBTztBQUNqQyxLQUFBLENBQUMsQ0FBQztJQUVILE1BQU0sa0JBQWtCLEdBQUcsbUJBQW1CLENBQUMsR0FBRyxDQUNoRCxDQUFDLFdBQVcsTUFBTTtBQUNoQixRQUFBLElBQUksRUFBRSxDQUFBLFlBQUEsRUFBZSxXQUFXLENBQUMsRUFBRSxDQUFFLENBQUE7QUFDckMsUUFBQSxXQUFXLEVBQUUsQ0FBQSxFQUFHLFdBQVcsQ0FBQyxPQUFPLENBQXVCLHFCQUFBLENBQUE7QUFDMUQsUUFBQSxJQUFJLEVBQUUsWUFDSixDQUFBLDBCQUFBLEVBQTZCLFdBQVcsQ0FBQyxPQUFPLENBQUEsRUFBQSxFQUFLLFdBQVcsQ0FBQyxZQUFZLENBQXlILHVIQUFBLENBQUE7QUFDek0sS0FBQSxDQUFDLENBQ0g7QUFFRCxJQUFBLE9BQU8sQ0FBQyxHQUFHLGdCQUFnQixFQUFFLEdBQUcsa0JBQWtCLENBQUM7QUFDckQ7QUFFQSxTQUFTLGtCQUFrQixDQUFDLElBQVksRUFBRSxVQUFrQixFQUFBO0FBQzFELElBQUEsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVO0FBQ3pDLFVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVO1VBQ3pCLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQztJQUVsQyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUM7QUFDOUMsSUFBQSxJQUFJLFFBQVEsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsRUFBRTtRQUMxRCxNQUFNLElBQUksY0FBYyxDQUN0QixDQUFBLEtBQUEsRUFBUSxVQUFVLENBQWtDLCtCQUFBLEVBQUEsSUFBSSxDQUFFLENBQUEsQ0FDM0Q7O0FBR0gsSUFBQSxPQUFPLFFBQVE7QUFDakI7QUFFQSxlQUFlLGlCQUFpQixDQUM5QixJQUFZLEVBQ1osTUFBYyxFQUFBO0FBRWQsSUFBQSxJQUFJO1FBQ0YsTUFBTSxRQUFRLEdBQUcsa0JBQWtCLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQztRQUNqRCxPQUFPLEVBQUUsQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLE1BQXdCLENBQUM7O0lBQzFELE9BQU8sS0FBSyxFQUFFO0FBQ2QsUUFBQSxJQUFJLEtBQUssWUFBWSxjQUFjLEVBQUU7QUFDbkMsWUFBQSxNQUFNLGNBQWMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDOzs7QUFHckMsUUFBQSxNQUFNLEtBQUs7O0FBRWY7QUFFQSxTQUFTLGtCQUFrQixDQUFDLElBQVksRUFBQTtJQUN0QyxNQUFNLFVBQVUsR0FBZ0IsRUFBRTtBQUVsQyxJQUFBLEtBQUssTUFBTSxTQUFTLElBQUksa0JBQWtCLEVBQUU7UUFDMUMsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDO0FBQzVDLFFBQUEsSUFBSSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxFQUFFO1lBQ3RFOztRQUdGLEtBQUssTUFBTSxLQUFLLElBQUksRUFBRSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsRUFBRTtZQUM3QyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUM7WUFDNUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxFQUFFO2dCQUFFO1lBRXJDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSTtZQUNuQyxNQUFNLE9BQU8sR0FBRyxFQUFFLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUM7QUFDakQsWUFBQSxNQUFNLEtBQUssR0FBRyxXQUFXLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDckQsTUFBTSxXQUFXLEdBQUcsa0JBQWtCLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQztZQUV6RCxVQUFVLENBQUMsSUFBSSxDQUFDO2dCQUNkLElBQUk7Z0JBQ0osS0FBSztnQkFDTCxXQUFXO2dCQUNYLE9BQU87QUFDUCxnQkFBQSxZQUFZLEVBQUUsUUFBUTtBQUN2QixhQUFBLENBQUM7OztBQUlOLElBQUEsTUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLEVBQXFCO0FBQzNDLElBQUEsS0FBSyxNQUFNLE1BQU0sSUFBSSxVQUFVLEVBQUU7UUFDL0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQzVCLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUM7OztBQUluQyxJQUFBLE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxLQUMzQyxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQzdCO0FBQ0g7QUFFQSxTQUFTLFlBQVksQ0FBQyxPQUFvQixFQUFFLGFBQXFCLEVBQUE7QUFDL0QsSUFBQSxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxLQUFLLE1BQU0sQ0FBQyxJQUFJLEtBQUssYUFBYSxDQUFDO0FBQ3RFLElBQUEsSUFBSSxNQUFNO0FBQUUsUUFBQSxPQUFPLE1BQU07QUFFekIsSUFBQSxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUMzQixDQUFDLE1BQU0sS0FBSyxNQUFNLENBQUMsSUFBSSxLQUFLLG1CQUFtQixDQUNoRDtBQUNELElBQUEsSUFBSSxRQUFRO0FBQUUsUUFBQSxPQUFPLFFBQVE7QUFFN0IsSUFBQSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRTtBQUNuQixRQUFBLE1BQU0sSUFBSSxjQUFjLENBQUMsb0NBQW9DLENBQUM7O0FBR2hFLElBQUEsT0FBTyxPQUFPLENBQUMsQ0FBQyxDQUFDO0FBQ25CO0FBRUEsU0FBUyx5QkFBeUIsQ0FBQyxFQUNqQyxRQUFRLEVBQ1IsV0FBVyxFQUNYLE1BQU0sRUFDTixhQUFhLEVBQ2IsV0FBVyxFQUNYLGVBQWUsRUFDZixpQkFBaUIsR0FTbEIsRUFBQTtJQUNDLE1BQU0sUUFBUSxHQUFhLEVBQUU7SUFFN0IsSUFBSSxlQUFlLEVBQUU7UUFDbkIsUUFBUSxDQUFDLElBQUksQ0FDWCxDQUFzQyxtQ0FBQSxFQUFBLE1BQU0sQ0FBQyxJQUFJLENBQWEsVUFBQSxFQUFBLFFBQVEsQ0FBRSxDQUFBLENBQ3pFOztJQUdILElBQUksYUFBYSxFQUFFO0FBQ2pCLFFBQUEsUUFBUSxDQUFDLElBQUksQ0FDWCxDQUF1QixvQkFBQSxFQUFBLE1BQU0sQ0FBQyxLQUFLLENBQUEsS0FBQSxFQUFRLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUEsQ0FBRSxDQUNuRTs7QUFHSCxJQUFBLElBQUksaUJBQWlCLEVBQUUsSUFBSSxFQUFFLEVBQUU7UUFDN0IsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUE0Qix5QkFBQSxFQUFBLGlCQUFpQixDQUFDLElBQUksRUFBRSxDQUFFLENBQUEsQ0FBQzs7SUFHdkUsSUFBSSxXQUFXLEVBQUU7QUFDZixRQUFBLFFBQVEsQ0FBQyxJQUFJLENBQ1gsQ0FBQSxtQkFBQSxFQUFzQixxQkFBcUIsQ0FBQyxRQUFRLENBQUMsQ0FBSyxFQUFBLEVBQUEsV0FBVyxDQUFVLFFBQUEsQ0FBQSxDQUNoRjs7SUFHSCxPQUFPO0FBQ0wsUUFBQSxPQUFPLEVBQUU7QUFDUCxZQUFBO0FBQ0UsZ0JBQUEsSUFBSSxFQUFFLE1BQU07QUFDWixnQkFBQSxJQUFJLEVBQUUsUUFBUSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUM7QUFDNUIsYUFBQTtBQUNGLFNBQUE7S0FDc0I7QUFDM0I7QUFFQSxTQUFTLGtCQUFrQixDQUFDLE9BQWUsRUFBRSxRQUFnQixFQUFBO0lBQzNELE1BQU0sU0FBUyxHQUFHO1NBQ2YsS0FBSyxDQUFDLE9BQU87U0FDYixHQUFHLENBQUMsQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLElBQUksRUFBRTtBQUN6QixTQUFBLElBQUksQ0FBQyxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUVsQyxRQUNFLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQztRQUN4QixDQUFvQyxpQ0FBQSxFQUFBLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUEsQ0FBRTtBQUVqRTtBQUVBLFNBQVMsV0FBVyxDQUFDLEtBQWEsRUFBQTtBQUNoQyxJQUFBLE9BQU87U0FDSixLQUFLLENBQUMsS0FBSztTQUNYLE1BQU0sQ0FBQyxPQUFPO1NBQ2QsR0FBRyxDQUFDLENBQUMsSUFBSSxLQUFLLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUU7U0FDeEUsSUFBSSxDQUFDLEdBQUcsQ0FBQztBQUNkO0FBRUEsU0FBUyxxQkFBcUIsQ0FBQyxRQUFnQixFQUFBO0lBQzdDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsV0FBVyxFQUFFO0lBQ3RELFFBQVEsU0FBUztBQUNmLFFBQUEsS0FBSyxLQUFLO0FBQ1YsUUFBQSxLQUFLLE1BQU07QUFDVCxZQUFBLE9BQU8sSUFBSTtBQUNiLFFBQUEsS0FBSyxLQUFLO0FBQ1YsUUFBQSxLQUFLLE1BQU07QUFDVCxZQUFBLE9BQU8sSUFBSTtBQUNiLFFBQUEsS0FBSyxPQUFPO0FBQ1YsWUFBQSxPQUFPLE1BQU07QUFDZixRQUFBLEtBQUssS0FBSztBQUNSLFlBQUEsT0FBTyxJQUFJO0FBQ2IsUUFBQTtBQUNFLFlBQUEsT0FBTyxNQUFNOztBQUVuQjs7QUN6aEJBOzs7Ozs7QUFNRztBQUNJLE1BQU0sYUFBYSxHQUFHOztBQ1A3QjtBQUtBOzs7Ozs7Ozs7Ozs7O0FBYUc7TUFDVSxRQUFRLENBQUE7QUFDbkI7Ozs7OztBQU1HO0FBQ0gsSUFBQSxhQUFhLFlBQVksQ0FBQyxJQUFZLEVBQUE7QUFDcEMsUUFBQSxJQUFJO1lBQ0YsT0FBTyxRQUFRLENBQUMsZUFBZSxDQUFDLE9BQU8sSUFBSSxDQUFDLENBQUM7O1FBQzdDLE9BQU8sQ0FBVSxFQUFFO1lBQ25CLE1BQU0sSUFBSSxLQUFLLENBQ2IsQ0FBQSxvQkFBQSxFQUF1QixJQUFJLENBQUssRUFBQSxFQUFBLENBQUMsWUFBWSxLQUFLLEdBQUcsQ0FBQyxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUUsQ0FBQSxDQUNyRTs7O0FBSUw7Ozs7Ozs7O0FBUUc7QUFDSCxJQUFBLGFBQWEsZUFBZSxDQUFJLGFBQXlCLEVBQUE7O0FBRXZELFFBQUEsT0FBTyxhQUFhLENBQUMsSUFBSSxDQUN2QixDQUFDLENBQVUsTUFBTyxDQUFvQixDQUFDLE9BQU8sSUFBSSxDQUFDLENBQU0sQ0FDMUQ7O0FBR0g7Ozs7Ozs7QUFPRztJQUNLLE9BQU8sVUFBVSxDQUFDLFFBQWdCLEVBQUE7QUFDeEMsUUFBQSxJQUFJO1lBQ0YsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUNmLEVBQUUsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsY0FBYyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQzdEOztRQUNELE9BQU8sQ0FBVSxFQUFFO1lBQ25CLE1BQU0sSUFBSSxLQUFLLENBQUMsQ0FBQSw0QkFBQSxFQUErQixRQUFRLENBQUssRUFBQSxFQUFBLENBQUMsQ0FBRSxDQUFBLENBQUM7OztBQUlwRTs7Ozs7O0FBTUc7SUFDSCxPQUFPLGNBQWMsQ0FBQyxRQUFnQixFQUFBO1FBQ3BDLE9BQU8sUUFBUSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxTQUFTLENBQVc7O0FBRzNEOzs7Ozs7QUFNRztJQUNILE9BQU8sV0FBVyxDQUFDLFFBQWdCLEVBQUE7QUFDakMsUUFBQSxNQUFNLElBQUksR0FBSSxRQUFRLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBWSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUM7UUFDekUsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7O0FBRS9COztBQzdGRDtBQVNBOzs7Ozs7Ozs7Ozs7Ozs7O0FBZ0JHO0FBQ0csTUFBTyxVQUFXLFNBQVEsV0FBVyxDQUFBO0FBS3pDLElBQUEsV0FBQSxDQUNVLFFBQW1CLEdBQUEsSUFBSSxFQUN2QixXQUFBLEdBQWMsQ0FBQyxFQUFBO0FBRXZCLFFBQUEsS0FBSyxFQUFFO1FBSEMsSUFBUSxDQUFBLFFBQUEsR0FBUixRQUFRO1FBQ1IsSUFBVyxDQUFBLFdBQUEsR0FBWCxXQUFXO1FBTGIsSUFBTyxDQUFBLE9BQUEsR0FBMkIsRUFBRTtRQVExQyxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQzs7QUFHL0M7Ozs7O0FBS0c7QUFDSCxJQUFBLElBQVksR0FBRyxHQUFBO0FBQ2IsUUFBQSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRTtBQUNkLFlBQUEsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLE9BQU8sQ0FBQztBQUN0QixnQkFBQSxJQUFJLEVBQUUscUJBQXFCO0FBQzNCLGdCQUFBLFlBQVksRUFBRSxFQUFFO0FBQ2hCLGdCQUFBLE9BQU8sRUFBRUgsU0FBYztBQUN4QixhQUFBLENBQUM7O1FBRUosT0FBTyxJQUFJLENBQUMsSUFBSTs7QUFHbEI7Ozs7QUFJRztBQUNLLElBQUEsTUFBTSxJQUFJLENBQ2hCLE1BQWUsRUFDZixRQUFnQixFQUFBO0FBRWhCLFFBQUEsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztBQUVuQyxRQUFBLElBQUksR0FBVyxFQUFFLE9BQWUsRUFBRSxNQUFXO0FBQzdDLFFBQUEsSUFBSTtZQUNGLE1BQU0sR0FBRyxHQUFHLE1BQU0sUUFBUSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUM7QUFDakQsWUFBQSxHQUFHLEdBQUcsR0FBRyxDQUFDLFlBQVk7QUFDdEIsWUFBQSxPQUFPLEdBQUcsR0FBRyxDQUFDLE9BQU87QUFDckIsWUFBQSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU07O1FBQ25CLE9BQU8sQ0FBVSxFQUFFO1lBQ25CLE1BQU0sSUFBSSxLQUFLLENBQUUsQ0FBUyxDQUFDLE9BQU8sSUFBSyxDQUFTLENBQUM7O0FBRW5ELFFBQUEsSUFBSTtZQUNGLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQSxpQ0FBQSxFQUFvQyxHQUFHLENBQUssRUFBQSxFQUFBLE9BQU8sQ0FBRSxDQUFBLENBQUM7QUFDL0QsWUFBQSxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO0FBQzdCLFlBQUEsTUFBTSxHQUFHLE1BQU0sWUFBWSxPQUFPLEdBQUcsTUFBTSxNQUFNLEdBQUcsTUFBTTs7UUFDMUQsT0FBTyxDQUFVLEVBQUU7WUFDbkIsTUFBTSxJQUFJLEtBQUssQ0FDYixDQUFvQyxpQ0FBQSxFQUFBLEdBQUcsSUFBSSxTQUFTLENBQUEsT0FBQSxFQUFVLFFBQVEsQ0FBQSxFQUFBLEVBQUssQ0FBQyxZQUFZLEtBQUssR0FBRyxDQUFDLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBRSxDQUFBLENBQ2hIOztRQUVILE9BQU87QUFDTCxZQUFBLEdBQUcsRUFBRSxNQUFNO0FBQ1gsWUFBQSxPQUFPLEVBQUUsR0FBRztBQUNaLFlBQUEsT0FBTyxFQUFFLE9BQU87U0FDakI7O0FBR0g7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUE0Qkc7QUFDSyxJQUFBLE1BQU0sSUFBSSxHQUFBO0FBQ2hCLFFBQUEsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztBQUVuQyxRQUFBLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDO0FBQzNELFFBQUEsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQztBQUN0RCxRQUFBLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHO0FBQ3JCLFFBQUEsS0FBSyxNQUFNLE1BQU0sSUFBSSxPQUFPLEVBQUU7QUFDNUIsWUFBQSxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLEVBQUU7Z0JBQ3BDOztBQUVGLFlBQUEsSUFBSTtnQkFDRixNQUFNLEdBQUcsR0FBRyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQztBQUMzQyxnQkFBQSxNQUFNLEdBQUcsR0FBRyxDQUFDLEdBQUc7O1lBQ2hCLE9BQU8sQ0FBVSxFQUFFO2dCQUNuQixHQUFHLENBQUMsS0FBSyxDQUFDLENBQUEsK0JBQUEsRUFBa0MsTUFBTSxDQUFLLEVBQUEsRUFBQSxDQUFDLENBQUUsQ0FBQSxDQUFDOzs7UUFHL0QsT0FBTyxDQUFDLEdBQUcsQ0FDVCxDQUFvQixpQkFBQSxFQUFBLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU87YUFDekMsR0FBRyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUEsRUFBQSxFQUFLLENBQUMsQ0FBQSxDQUFFO0FBQ25CLGFBQUEsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBLENBQUUsQ0FDaEI7QUFDRCxRQUFBLE9BQU8sTUFBTTs7QUFHZjs7Ozs7Ozs7O0FBU0c7QUFDSyxJQUFBLEtBQUssQ0FBQyxRQUFnQixFQUFFLE1BQUEsR0FBaUIsQ0FBQyxFQUFBO1FBQ2hELElBQUksTUFBTSxJQUFJLENBQUM7QUFBRSxZQUFBLE9BQU8sRUFBRTtBQUMxQixRQUFBLE9BQU8sRUFBRSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFlLEVBQUUsSUFBSSxLQUFJO1lBQy9ELElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUM7WUFDaEMsSUFBSSxFQUFFLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLFdBQVcsRUFBRSxFQUFFO0FBQ25DLGdCQUFBLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7O0FBQ3RDLGlCQUFBLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLE1BQU0sQ0FBQyxDQUFHLEVBQUEsYUFBYSxXQUFXLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRTtBQUNwRSxnQkFBQSxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQzs7QUFFbEIsWUFBQSxPQUFPLEtBQUs7U0FDYixFQUFFLEVBQUUsQ0FBQzs7QUFHUjs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQW1CRzs7QUFFSCxJQUFBLE1BQU0sR0FBRyxDQUFDLElBQWlCLEdBQUEsT0FBTyxDQUFDLElBQUksRUFBQTtBQUNyQyxRQUFBLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLElBQUksRUFBRTtRQUNoQyxNQUFNLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxhQUFhLEVBQUUsT0FBTyxFQUFFLENBQUM7O0FBRWpEOzs7OyJ9