@nlabs/lex 1.49.4 → 1.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/.swcrc +35 -0
  2. package/README.md +43 -59
  3. package/__mocks__/chalk.js +19 -17
  4. package/config.json +32 -8
  5. package/examples/lex.config.js +110 -10
  6. package/index.cjs +1 -5
  7. package/lex.config.js +34 -7
  8. package/lib/Button.stories.js +99 -0
  9. package/lib/LexConfig.d.ts +60 -22
  10. package/lib/LexConfig.js +285 -244
  11. package/lib/commands/ai/ai.js +287 -288
  12. package/lib/commands/ai/index.js +8 -7
  13. package/lib/commands/build/build.d.ts +2 -2
  14. package/lib/commands/build/build.js +349 -458
  15. package/lib/commands/clean/clean.js +45 -33
  16. package/lib/commands/compile/compile.js +214 -227
  17. package/lib/commands/config/config.js +46 -42
  18. package/lib/commands/copy/copy.js +36 -35
  19. package/lib/commands/create/create.js +200 -121
  20. package/lib/commands/dev/dev.d.ts +2 -0
  21. package/lib/commands/dev/dev.js +259 -263
  22. package/lib/commands/init/init.js +108 -88
  23. package/lib/commands/link/link.js +18 -14
  24. package/lib/commands/lint/lint.js +735 -742
  25. package/lib/commands/migrate/migrate.js +49 -36
  26. package/lib/commands/publish/publish.js +116 -96
  27. package/lib/commands/serverless/serverless.js +611 -585
  28. package/lib/commands/storybook/storybook.js +242 -238
  29. package/lib/commands/test/test.d.ts +1 -1
  30. package/lib/commands/test/test.js +382 -394
  31. package/lib/commands/update/update.js +141 -120
  32. package/lib/commands/upgrade/upgrade.js +51 -44
  33. package/lib/commands/versions/versions.d.ts +1 -1
  34. package/lib/commands/versions/versions.js +36 -38
  35. package/lib/create/changelog.js +136 -125
  36. package/lib/index.js +40 -38
  37. package/lib/lex.js +95 -68
  38. package/lib/storybook/index.js +6 -1
  39. package/lib/test-react/index.js +7 -84
  40. package/lib/types.d.ts +1 -1
  41. package/lib/types.js +7 -1
  42. package/lib/utils/aiService.js +240 -227
  43. package/lib/utils/app.js +274 -273
  44. package/lib/utils/deepMerge.js +37 -23
  45. package/lib/utils/file.js +218 -215
  46. package/lib/utils/log.js +29 -27
  47. package/lib/utils/reactShim.js +7 -85
  48. package/lib/utils/translations.js +91 -65
  49. package/package.json +63 -64
  50. package/templates/typescript/DataLayer.js.txt +218 -0
  51. package/templates/typescript/DataLayer.test.js.txt +268 -0
  52. package/templates/typescript/DataLayer.test.ts.txt +269 -0
  53. package/templates/typescript/DataLayer.ts.txt +227 -0
  54. package/webpack.config.js +53 -26
  55. package/lib/commands/lint/autofix.d.ts +0 -2
@@ -1,241 +1,228 @@
1
- import { execa } from "execa";
2
- import { existsSync, lstatSync, readdirSync } from "fs";
3
- import { sync as globSync } from "glob";
4
- import { extname as pathExtname, join as pathJoin, resolve as pathResolve } from "path";
5
- import { LexConfig, getTypeScriptConfigPath } from "../../LexConfig.js";
6
- import { checkLinkedModules, copyConfiguredFiles, copyFiles, createSpinner, getFilesByExt, removeFiles } from "../../utils/app.js";
7
- import { getDirName, resolveBinaryPath } from "../../utils/file.js";
8
- import { log } from "../../utils/log.js";
9
- const hasFileType = (startPath, ext) => {
10
- if (!existsSync(startPath)) {
11
- return false;
12
- }
13
- const files = readdirSync(startPath);
14
- return files.some((file) => {
15
- const filename = pathJoin(startPath, file);
16
- const fileExt = pathExtname(filename);
17
- const stat = lstatSync(filename);
18
- if (stat.isDirectory()) {
19
- return hasFileType(filename, ext);
1
+ /**
2
+ * Copyright (c) 2018-Present, Nitrogen Labs, Inc.
3
+ * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms.
4
+ */ import { transform } from '@swc/core';
5
+ import { execa } from 'execa';
6
+ import { existsSync, lstatSync, readdirSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
7
+ import { sync as globSync } from 'glob';
8
+ import { extname as pathExtname, join as pathJoin, resolve as pathResolve, dirname } from 'path';
9
+ import { LexConfig, getTypeScriptConfigPath } from '../../LexConfig.js';
10
+ import { checkLinkedModules, copyConfiguredFiles, copyFiles, createSpinner, getFilesByExt, removeFiles } from '../../utils/app.js';
11
+ import { getDirName, resolveBinaryPath } from '../../utils/file.js';
12
+ import { log } from '../../utils/log.js';
13
+ export const hasFileType = (startPath, ext)=>{
14
+ if (!existsSync(startPath)) {
15
+ return false;
20
16
  }
21
- return ext.includes(fileExt);
22
- });
17
+ const files = readdirSync(startPath);
18
+ return files.some((file)=>{
19
+ const filename = pathJoin(startPath, file);
20
+ const fileExt = pathExtname(filename);
21
+ const stat = lstatSync(filename);
22
+ if (stat.isDirectory()) {
23
+ return hasFileType(filename, ext);
24
+ }
25
+ return ext.includes(fileExt);
26
+ });
23
27
  };
24
- const compile = async (cmd, callback = () => ({})) => {
25
- const {
26
- cliName = "Lex",
27
- config,
28
- outputPath,
29
- quiet,
30
- remove,
31
- sourcePath,
32
- watch
33
- } = cmd;
34
- const spinner = createSpinner(quiet);
35
- log(`${cliName} compiling...`, "info", quiet);
36
- await LexConfig.parseConfig(cmd);
37
- const { outputFullPath, sourceFullPath, useTypescript } = LexConfig.config;
38
- const outputDir = outputPath || outputFullPath;
39
- const sourceDir = sourcePath ? pathResolve(process.cwd(), `./${sourcePath}`) : sourceFullPath || "";
40
- const dirName = getDirName();
41
- const dirPath = pathResolve(dirName, "../..");
42
- checkLinkedModules();
43
- if (remove) {
44
- await removeFiles(outputDir);
45
- }
46
- if (useTypescript) {
47
- LexConfig.checkCompileTypescriptConfig();
48
- const typescriptPath = resolveBinaryPath("tsc", "typescript");
49
- if (!typescriptPath) {
50
- log(`
51
- ${cliName} Error: TypeScript binary not found in Lex's node_modules or monorepo root`, "error", quiet);
52
- log("Please reinstall Lex or check your installation.", "info", quiet);
53
- return 1;
28
+ export const compile = async (cmd, callback = ()=>({}))=>{
29
+ const { cliName = 'Lex', config, format = 'esm', outputPath, quiet, remove, sourcePath, watch } = cmd;
30
+ const spinner = createSpinner(quiet);
31
+ log(`${cliName} compiling...`, 'info', quiet);
32
+ await LexConfig.parseConfig(cmd);
33
+ const { outputFullPath, sourceFullPath, swc: swcConfig, useTypescript } = LexConfig.config;
34
+ const outputDir = outputPath || outputFullPath;
35
+ const sourceDir = sourcePath ? pathResolve(process.cwd(), `./${sourcePath}`) : sourceFullPath || '';
36
+ const dirName = getDirName();
37
+ const dirPath = pathResolve(dirName, '../..');
38
+ checkLinkedModules();
39
+ if (remove) {
40
+ await removeFiles(outputDir);
54
41
  }
55
- const typescriptOptions = config ? ["-p", config] : ["-p", getTypeScriptConfigPath("tsconfig.build.json")];
56
- spinner.start("Static type checking with Typescript...");
57
- try {
58
- await execa(typescriptPath, typescriptOptions, { encoding: "utf8" });
59
- spinner.succeed("Successfully completed type checking!");
60
- } catch (error) {
61
- log(`
62
- ${cliName} Error: ${error.message}`, "error", quiet);
63
- spinner.fail("Type checking failed.");
64
- callback(1);
65
- return 1;
42
+ if (useTypescript) {
43
+ LexConfig.checkCompileTypescriptConfig();
44
+ const typescriptPath = resolveBinaryPath('tsc', 'typescript');
45
+ if (!typescriptPath) {
46
+ log(`\n${cliName} Error: TypeScript binary not found in Lex's node_modules or monorepo root`, 'error', quiet);
47
+ log('Please reinstall Lex or check your installation.', 'info', quiet);
48
+ return 1;
49
+ }
50
+ const typescriptOptions = config ? [
51
+ '-p',
52
+ config
53
+ ] : [
54
+ '-p',
55
+ getTypeScriptConfigPath('tsconfig.build.json')
56
+ ];
57
+ spinner.start('Static type checking with Typescript...');
58
+ try {
59
+ await execa(typescriptPath, typescriptOptions, {
60
+ encoding: 'utf8'
61
+ });
62
+ spinner.succeed('Successfully completed type checking!');
63
+ } catch (error) {
64
+ log(`\n${cliName} Error: ${error.message}`, 'error', quiet);
65
+ spinner.fail('Type checking failed.');
66
+ callback(1);
67
+ return 1;
68
+ }
66
69
  }
67
- }
68
- const globOptions = {
69
- cwd: sourceDir,
70
- dot: false,
71
- nodir: true,
72
- nosort: true
73
- };
74
- const tsFiles = globSync(`${sourceDir}/**/!(*.spec|*.test|*.integration).ts*`, globOptions);
75
- const jsFiles = globSync(`${sourceDir}/**/!(*.spec|*.test|*.integration).js`, globOptions);
76
- const sourceFiles = [...tsFiles, ...jsFiles];
77
- const esbuildConfig = LexConfig.config.esbuild || {};
78
- const isProduction = process.env.NODE_ENV === "production";
79
- let shouldMinify;
80
- if (typeof esbuildConfig.minify === "boolean") {
81
- shouldMinify = esbuildConfig.minify;
82
- } else {
83
- shouldMinify = isProduction;
84
- }
85
- const esbuildPath = resolveBinaryPath("esbuild", "esbuild");
86
- if (!esbuildPath) {
87
- log(`
88
- ${cliName} Error: esbuild binary not found in Lex's node_modules or monorepo root`, "error", quiet);
89
- log("Please reinstall Lex or check your installation.", "info", quiet);
90
- return 1;
91
- }
92
- const esbuildOptions = [
93
- ...sourceFiles,
94
- "--color=true",
95
- `--format=${esbuildConfig.format || "esm"}`,
96
- `--outdir=${outputDir}`,
97
- `--platform=${esbuildConfig.platform || "node"}`,
98
- `--sourcemap=${esbuildConfig.sourcemap || "inline"}`,
99
- `--target=${esbuildConfig.target || "node20"}`
100
- ];
101
- if (shouldMinify) {
102
- esbuildOptions.push("--minify");
103
- }
104
- if (esbuildConfig.treeShaking !== false) {
105
- esbuildOptions.push("--tree-shaking=true");
106
- }
107
- if (esbuildConfig.drop && esbuildConfig.drop.length > 0) {
108
- esbuildConfig.drop.forEach((item) => {
109
- esbuildOptions.push(`--drop:${item}`);
110
- });
111
- }
112
- if (esbuildConfig.pure && esbuildConfig.pure.length > 0) {
113
- esbuildConfig.pure.forEach((item) => {
114
- esbuildOptions.push(`--pure:${item}`);
115
- });
116
- }
117
- if (esbuildConfig.legalComments) {
118
- esbuildOptions.push(`--legal-comments=${esbuildConfig.legalComments}`);
119
- }
120
- if (esbuildConfig.banner) {
121
- Object.entries(esbuildConfig.banner).forEach(([type, content]) => {
122
- esbuildOptions.push(`--banner:${type}=${content}`);
123
- });
124
- }
125
- if (esbuildConfig.footer) {
126
- Object.entries(esbuildConfig.footer).forEach(([type, content]) => {
127
- esbuildOptions.push(`--footer:${type}=${content}`);
128
- });
129
- }
130
- if (esbuildConfig.define) {
131
- Object.entries(esbuildConfig.define).forEach(([key, value]) => {
132
- esbuildOptions.push(`--define:${key}=${value}`);
133
- });
134
- }
135
- if (watch) {
136
- esbuildOptions.push("--watch");
137
- }
138
- const cssFiles = getFilesByExt(".css", LexConfig.config);
139
- if (cssFiles.length) {
140
- const postcssPath = resolveBinaryPath("postcss", "postcss-cli");
141
- if (!postcssPath) {
142
- log(`
143
- ${cliName} Error: PostCSS binary not found in Lex's node_modules or monorepo root`, "error", quiet);
144
- log("Please reinstall Lex or check your installation.", "info", quiet);
145
- return 1;
70
+ const globOptions = {
71
+ cwd: sourceDir,
72
+ dot: false,
73
+ nodir: true,
74
+ nosort: true
75
+ };
76
+ const tsFiles = globSync(`${sourceDir}/**/!(*.spec|*.test|*.integration).ts*`, globOptions);
77
+ const jsFiles = globSync(`${sourceDir}/**/!(*.spec|*.test|*.integration).js`, globOptions);
78
+ const sourceFiles = [
79
+ ...tsFiles,
80
+ ...jsFiles
81
+ ];
82
+ const cssFiles = getFilesByExt('.css', LexConfig.config);
83
+ if (cssFiles.length) {
84
+ const postcssPath = resolveBinaryPath('postcss', 'postcss-cli');
85
+ if (!postcssPath) {
86
+ log(`\n${cliName} Error: PostCSS binary not found in Lex's node_modules or monorepo root`, 'error', quiet);
87
+ log('Please reinstall Lex or check your installation.', 'info', quiet);
88
+ return 1;
89
+ }
90
+ const postcssOptions = [
91
+ `${sourceDir}/**/**.css`,
92
+ '--base',
93
+ sourceDir,
94
+ '--dir',
95
+ outputDir,
96
+ '--config',
97
+ pathResolve(dirName, '../../postcss.config.js')
98
+ ];
99
+ try {
100
+ await execa(postcssPath, postcssOptions, {
101
+ encoding: 'utf8'
102
+ });
103
+ spinner.succeed(`Successfully formatted ${cssFiles.length} css files!`);
104
+ } catch (error) {
105
+ log(`\n${cliName} Error: ${error.message}`, 'error', quiet);
106
+ spinner.fail('Failed formatting css.');
107
+ callback(1);
108
+ return 1;
109
+ }
146
110
  }
147
- const postcssOptions = [
148
- `${sourceDir}/**/**.css`,
149
- "--base",
150
- sourceDir,
151
- "--dir",
152
- outputDir,
153
- "--config",
154
- pathResolve(dirName, "../../postcss.config.js")
111
+ const gifFiles = getFilesByExt('.gif', LexConfig.config);
112
+ const jpgFiles = getFilesByExt('.jpg', LexConfig.config);
113
+ const pngFiles = getFilesByExt('.png', LexConfig.config);
114
+ const svgFiles = getFilesByExt('.svg', LexConfig.config);
115
+ const imageFiles = [
116
+ ...gifFiles,
117
+ ...jpgFiles,
118
+ ...pngFiles,
119
+ ...svgFiles
155
120
  ];
156
- try {
157
- await execa(postcssPath, postcssOptions, { encoding: "utf8" });
158
- spinner.succeed(`Successfully formatted ${cssFiles.length} css files!`);
159
- } catch (error) {
160
- log(`
161
- ${cliName} Error: ${error.message}`, "error", quiet);
162
- spinner.fail("Failed formatting css.");
163
- callback(1);
164
- return 1;
121
+ if (imageFiles.length) {
122
+ try {
123
+ await copyFiles(imageFiles, 'image', spinner, LexConfig.config);
124
+ } catch (error) {
125
+ log(`\n${cliName} Error: ${error.message}`, 'error', quiet);
126
+ spinner.fail('Failed to move images to output directory.');
127
+ callback(1);
128
+ return 1;
129
+ }
165
130
  }
166
- }
167
- const gifFiles = getFilesByExt(".gif", LexConfig.config);
168
- const jpgFiles = getFilesByExt(".jpg", LexConfig.config);
169
- const pngFiles = getFilesByExt(".png", LexConfig.config);
170
- const svgFiles = getFilesByExt(".svg", LexConfig.config);
171
- const imageFiles = [...gifFiles, ...jpgFiles, ...pngFiles, ...svgFiles];
172
- if (imageFiles.length) {
173
- try {
174
- await copyFiles(imageFiles, "image", spinner, LexConfig.config);
175
- } catch (error) {
176
- log(`
177
- ${cliName} Error: ${error.message}`, "error", quiet);
178
- spinner.fail("Failed to move images to output directory.");
179
- callback(1);
180
- return 1;
131
+ const ttfFiles = getFilesByExt('.ttf', LexConfig.config);
132
+ const otfFiles = getFilesByExt('.otf', LexConfig.config);
133
+ const woffFiles = getFilesByExt('.woff', LexConfig.config);
134
+ const woff2Files = getFilesByExt('.woff2', LexConfig.config);
135
+ const fontFiles = [
136
+ ...ttfFiles,
137
+ ...otfFiles,
138
+ ...woffFiles,
139
+ ...woff2Files
140
+ ];
141
+ if (fontFiles.length) {
142
+ try {
143
+ await copyFiles(fontFiles, 'font', spinner, LexConfig.config);
144
+ } catch (error) {
145
+ log(`\n${cliName} Error: ${error.message}`, 'error', quiet);
146
+ spinner.fail('Failed to move fonts to output directory.');
147
+ callback(1);
148
+ return 1;
149
+ }
181
150
  }
182
- }
183
- const ttfFiles = getFilesByExt(".ttf", LexConfig.config);
184
- const otfFiles = getFilesByExt(".otf", LexConfig.config);
185
- const woffFiles = getFilesByExt(".woff", LexConfig.config);
186
- const woff2Files = getFilesByExt(".woff2", LexConfig.config);
187
- const fontFiles = [...ttfFiles, ...otfFiles, ...woffFiles, ...woff2Files];
188
- if (fontFiles.length) {
189
- try {
190
- await copyFiles(fontFiles, "font", spinner, LexConfig.config);
191
- } catch (error) {
192
- log(`
193
- ${cliName} Error: ${error.message}`, "error", quiet);
194
- spinner.fail("Failed to move fonts to output directory.");
195
- callback(1);
196
- return 1;
151
+ const mdFiles = getFilesByExt('.md', LexConfig.config);
152
+ if (mdFiles.length) {
153
+ try {
154
+ await copyFiles(mdFiles, 'documents', spinner, LexConfig.config);
155
+ } catch (error) {
156
+ log(`\n${cliName} Error: ${error.message}`, 'error', quiet);
157
+ spinner.fail('Failed to move docs to output directory.');
158
+ callback(1);
159
+ return 1;
160
+ }
197
161
  }
198
- }
199
- const mdFiles = getFilesByExt(".md", LexConfig.config);
200
- if (mdFiles.length) {
162
+ spinner.start(watch ? 'Watching for changes...' : 'Compiling with SWC...');
201
163
  try {
202
- await copyFiles(mdFiles, "documents", spinner, LexConfig.config);
164
+ // Compile each file with SWC
165
+ for (const file of sourceFiles){
166
+ const sourcePath = pathResolve(sourceDir, file);
167
+ const outputPath = pathResolve(outputDir, file.replace(/\.(ts|tsx)$/, '.js'));
168
+ // Ensure output directory exists
169
+ const outputDirPath = dirname(outputPath);
170
+ if (!existsSync(outputDirPath)) {
171
+ mkdirSync(outputDirPath, {
172
+ recursive: true
173
+ });
174
+ }
175
+ const sourceCode = readFileSync(sourcePath, 'utf8');
176
+ const isTSX = file.endsWith('.tsx');
177
+ // Merge SWC config with command-specific overrides
178
+ const swcOptions = {
179
+ filename: file,
180
+ ...swcConfig,
181
+ jsc: {
182
+ ...swcConfig?.jsc,
183
+ parser: {
184
+ decorators: swcConfig?.jsc?.parser?.decorators ?? true,
185
+ dynamicImport: swcConfig?.jsc?.parser?.dynamicImport ?? true,
186
+ syntax: 'typescript',
187
+ tsx: isTSX
188
+ },
189
+ target: swcConfig?.jsc?.target ?? 'es2020',
190
+ transform: isTSX ? {
191
+ ...swcConfig?.jsc?.transform,
192
+ react: {
193
+ runtime: 'automatic',
194
+ ...swcConfig?.jsc?.transform?.react
195
+ }
196
+ } : swcConfig?.jsc?.transform
197
+ },
198
+ module: {
199
+ ...swcConfig?.module,
200
+ type: format === 'cjs' ? 'commonjs' : swcConfig?.module?.type || 'es6'
201
+ }
202
+ };
203
+ const result = await transform(sourceCode, swcOptions);
204
+ writeFileSync(outputPath, result.code);
205
+ }
206
+ spinner.succeed('Compile completed successfully!');
203
207
  } catch (error) {
204
- log(`
205
- ${cliName} Error: ${error.message}`, "error", quiet);
206
- spinner.fail("Failed to move docs to output directory.");
207
- callback(1);
208
- return 1;
208
+ log(`\n${cliName} Error: ${error.message}`, 'error', quiet);
209
+ if (!quiet) {
210
+ console.error(error);
211
+ }
212
+ spinner.fail('Code compiling failed.');
213
+ callback(1);
214
+ return 1;
209
215
  }
210
- }
211
- spinner.start(watch ? "Watching for changes..." : "Compiling with ESBuild...");
212
- try {
213
- await execa(esbuildPath, esbuildOptions, { encoding: "utf8" });
214
- spinner.succeed("Compile completed successfully!");
215
- } catch (error) {
216
- log(`
217
- ${cliName} Error: ${error.message}`, "error", quiet);
218
- if (!quiet) {
219
- console.error(error);
216
+ try {
217
+ await copyConfiguredFiles(spinner, LexConfig.config, quiet);
218
+ } catch (copyError) {
219
+ log(`\n${cliName} Error: Failed to copy configured files: ${copyError.message}`, 'error', quiet);
220
+ spinner.fail('Failed to copy configured files.');
221
+ callback(1);
222
+ return 1;
220
223
  }
221
- spinner.fail("Code compiling failed.");
222
- callback(1);
223
- return 1;
224
- }
225
- try {
226
- await copyConfiguredFiles(spinner, LexConfig.config, quiet);
227
- } catch (copyError) {
228
- log(`
229
- ${cliName} Error: Failed to copy configured files: ${copyError.message}`, "error", quiet);
230
- spinner.fail("Failed to copy configured files.");
231
- callback(1);
232
- return 1;
233
- }
234
- callback(0);
235
- return 0;
236
- };
237
- export {
238
- compile,
239
- hasFileType
224
+ callback(0);
225
+ return 0;
240
226
  };
241
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2NvbW1hbmRzL2NvbXBpbGUvY29tcGlsZS50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTgtUHJlc2VudCwgTml0cm9nZW4gTGFicywgSW5jLlxuICogQ29weXJpZ2h0cyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSB0aGUgYWNjb21wYW55aW5nIExJQ0VOU0UgZmlsZSBmb3IgdGVybXMuXG4gKi9cbmltcG9ydCB7ZXhlY2F9IGZyb20gJ2V4ZWNhJztcbmltcG9ydCB7ZXhpc3RzU3luYywgbHN0YXRTeW5jLCByZWFkZGlyU3luY30gZnJvbSAnZnMnO1xuaW1wb3J0IHtzeW5jIGFzIGdsb2JTeW5jfSBmcm9tICdnbG9iJztcbmltcG9ydCB7ZXh0bmFtZSBhcyBwYXRoRXh0bmFtZSwgam9pbiBhcyBwYXRoSm9pbiwgcmVzb2x2ZSBhcyBwYXRoUmVzb2x2ZX0gZnJvbSAncGF0aCc7XG5cbmltcG9ydCB7TGV4Q29uZmlnLCBnZXRUeXBlU2NyaXB0Q29uZmlnUGF0aH0gZnJvbSAnLi4vLi4vTGV4Q29uZmlnLmpzJztcbmltcG9ydCB7Y2hlY2tMaW5rZWRNb2R1bGVzLCBjb3B5Q29uZmlndXJlZEZpbGVzLCBjb3B5RmlsZXMsIGNyZWF0ZVNwaW5uZXIsIGdldEZpbGVzQnlFeHQsIHJlbW92ZUZpbGVzfSBmcm9tICcuLi8uLi91dGlscy9hcHAuanMnO1xuaW1wb3J0IHtnZXREaXJOYW1lLCByZXNvbHZlQmluYXJ5UGF0aH0gZnJvbSAnLi4vLi4vdXRpbHMvZmlsZS5qcyc7XG5pbXBvcnQge2xvZ30gZnJvbSAnLi4vLi4vdXRpbHMvbG9nLmpzJztcblxuZXhwb3J0IGNvbnN0IGhhc0ZpbGVUeXBlID0gKHN0YXJ0UGF0aDogc3RyaW5nLCBleHQ6IHN0cmluZ1tdKTogYm9vbGVhbiA9PiB7XG4gIGlmKCFleGlzdHNTeW5jKHN0YXJ0UGF0aCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBmaWxlczogc3RyaW5nW10gPSByZWFkZGlyU3luYyhzdGFydFBhdGgpO1xuXG4gIHJldHVybiBmaWxlcy5zb21lKChmaWxlOiBzdHJpbmcpID0+IHtcbiAgICBjb25zdCBmaWxlbmFtZTogc3RyaW5nID0gcGF0aEpvaW4oc3RhcnRQYXRoLCBmaWxlKTtcbiAgICBjb25zdCBmaWxlRXh0OiBzdHJpbmcgPSBwYXRoRXh0bmFtZShmaWxlbmFtZSk7XG4gICAgY29uc3Qgc3RhdCA9IGxzdGF0U3luYyhmaWxlbmFtZSk7XG5cbiAgICBpZihzdGF0LmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgIHJldHVybiBoYXNGaWxlVHlwZShmaWxlbmFtZSwgZXh0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gZXh0LmluY2x1ZGVzKGZpbGVFeHQpO1xuICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBjb21waWxlID0gYXN5bmMgKGNtZDogYW55LCBjYWxsYmFjazogYW55ID0gKCkgPT4gKHt9KSk6IFByb21pc2U8bnVtYmVyPiA9PiB7XG4gIGNvbnN0IHtcbiAgICBjbGlOYW1lID0gJ0xleCcsXG4gICAgY29uZmlnLFxuICAgIG91dHB1dFBhdGgsXG4gICAgcXVpZXQsXG4gICAgcmVtb3ZlLFxuICAgIHNvdXJjZVBhdGgsXG4gICAgd2F0Y2hcbiAgfSA9IGNtZDtcblxuICBjb25zdCBzcGlubmVyID0gY3JlYXRlU3Bpbm5lcihxdWlldCk7XG5cbiAgbG9nKGAke2NsaU5hbWV9IGNvbXBpbGluZy4uLmAsICdpbmZvJywgcXVpZXQpO1xuXG4gIGF3YWl0IExleENvbmZpZy5wYXJzZUNvbmZpZyhjbWQpO1xuXG4gIGNvbnN0IHtvdXRwdXRGdWxsUGF0aCwgc291cmNlRnVsbFBhdGgsIHVzZVR5cGVzY3JpcHR9ID0gTGV4Q29uZmlnLmNvbmZpZztcbiAgY29uc3Qgb3V0cHV0RGlyOiBzdHJpbmcgPSBvdXRwdXRQYXRoIHx8IG91dHB1dEZ1bGxQYXRoO1xuICBjb25zdCBzb3VyY2VEaXI6IHN0cmluZyA9IHNvdXJjZVBhdGggPyBwYXRoUmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCBgLi8ke3NvdXJjZVBhdGh9YCkgOiBzb3VyY2VGdWxsUGF0aCB8fCAnJztcbiAgY29uc3QgZGlyTmFtZSA9IGdldERpck5hbWUoKTtcbiAgY29uc3QgZGlyUGF0aDogc3RyaW5nID0gcGF0aFJlc29sdmUoZGlyTmFtZSwgJy4uLy4uJyk7XG5cbiAgY2hlY2tMaW5rZWRNb2R1bGVzKCk7XG5cbiAgaWYocmVtb3ZlKSB7XG4gICAgYXdhaXQgcmVtb3ZlRmlsZXMob3V0cHV0RGlyKTtcbiAgfVxuXG4gIGlmKHVzZVR5cGVzY3JpcHQpIHtcbiAgICBMZXhDb25maWcuY2hlY2tDb21waWxlVHlwZXNjcmlwdENvbmZpZygpO1xuXG4gICAgY29uc3QgdHlwZXNjcmlwdFBhdGg6IHN0cmluZyA9IHJlc29sdmVCaW5hcnlQYXRoKCd0c2MnLCAndHlwZXNjcmlwdCcpO1xuXG4gICAgaWYoIXR5cGVzY3JpcHRQYXRoKSB7XG4gICAgICBsb2coYFxcbiR7Y2xpTmFtZX0gRXJyb3I6IFR5cGVTY3JpcHQgYmluYXJ5IG5vdCBmb3VuZCBpbiBMZXgncyBub2RlX21vZHVsZXMgb3IgbW9ub3JlcG8gcm9vdGAsICdlcnJvcicsIHF1aWV0KTtcbiAgICAgIGxvZygnUGxlYXNlIHJlaW5zdGFsbCBMZXggb3IgY2hlY2sgeW91ciBpbnN0YWxsYXRpb24uJywgJ2luZm8nLCBxdWlldCk7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG5cbiAgICBjb25zdCB0eXBlc2NyaXB0T3B0aW9uczogc3RyaW5nW10gPSBjb25maWcgP1xuICAgICAgWyctcCcsIGNvbmZpZ10gOlxuICAgICAgWyctcCcsIGdldFR5cGVTY3JpcHRDb25maWdQYXRoKCd0c2NvbmZpZy5idWlsZC5qc29uJyldO1xuXG4gICAgc3Bpbm5lci5zdGFydCgnU3RhdGljIHR5cGUgY2hlY2tpbmcgd2l0aCBUeXBlc2NyaXB0Li4uJyk7XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgZXhlY2EodHlwZXNjcmlwdFBhdGgsIHR5cGVzY3JpcHRPcHRpb25zLCB7ZW5jb2Rpbmc6ICd1dGY4J30pO1xuXG4gICAgICBzcGlubmVyLnN1Y2NlZWQoJ1N1Y2Nlc3NmdWxseSBjb21wbGV0ZWQgdHlwZSBjaGVja2luZyEnKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nKGBcXG4ke2NsaU5hbWV9IEVycm9yOiAke2Vycm9yLm1lc3NhZ2V9YCwgJ2Vycm9yJywgcXVpZXQpO1xuXG4gICAgICBzcGlubmVyLmZhaWwoJ1R5cGUgY2hlY2tpbmcgZmFpbGVkLicpO1xuXG4gICAgICBjYWxsYmFjaygxKTtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGdsb2JPcHRpb25zID0ge1xuICAgIGN3ZDogc291cmNlRGlyLFxuICAgIGRvdDogZmFsc2UsXG4gICAgbm9kaXI6IHRydWUsXG4gICAgbm9zb3J0OiB0cnVlXG4gIH07XG4gIGNvbnN0IHRzRmlsZXM6IHN0cmluZ1tdID0gZ2xvYlN5bmMoYCR7c291cmNlRGlyfS8qKi8hKCouc3BlY3wqLnRlc3R8Ki5pbnRlZ3JhdGlvbikudHMqYCwgZ2xvYk9wdGlvbnMpO1xuICBjb25zdCBqc0ZpbGVzOiBzdHJpbmdbXSA9IGdsb2JTeW5jKGAke3NvdXJjZURpcn0vKiovISgqLnNwZWN8Ki50ZXN0fCouaW50ZWdyYXRpb24pLmpzYCwgZ2xvYk9wdGlvbnMpO1xuICBjb25zdCBzb3VyY2VGaWxlczogc3RyaW5nW10gPSBbLi4udHNGaWxlcywgLi4uanNGaWxlc107XG4gIGNvbnN0IGVzYnVpbGRDb25maWcgPSBMZXhDb25maWcuY29uZmlnLmVzYnVpbGQgfHwge307XG4gIGNvbnN0IGlzUHJvZHVjdGlvbiA9IHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAncHJvZHVjdGlvbic7XG4gIGxldCBzaG91bGRNaW5pZnk6IGJvb2xlYW47XG5cbiAgaWYodHlwZW9mIGVzYnVpbGRDb25maWcubWluaWZ5ID09PSAnYm9vbGVhbicpIHtcbiAgICBzaG91bGRNaW5pZnkgPSBlc2J1aWxkQ29uZmlnLm1pbmlmeTtcbiAgfSBlbHNlIHtcbiAgICBzaG91bGRNaW5pZnkgPSBpc1Byb2R1Y3Rpb247XG4gIH1cblxuICBjb25zdCBlc2J1aWxkUGF0aDogc3RyaW5nID0gcmVzb2x2ZUJpbmFyeVBhdGgoJ2VzYnVpbGQnLCAnZXNidWlsZCcpO1xuXG4gIGlmKCFlc2J1aWxkUGF0aCkge1xuICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBFcnJvcjogZXNidWlsZCBiaW5hcnkgbm90IGZvdW5kIGluIExleCdzIG5vZGVfbW9kdWxlcyBvciBtb25vcmVwbyByb290YCwgJ2Vycm9yJywgcXVpZXQpO1xuICAgIGxvZygnUGxlYXNlIHJlaW5zdGFsbCBMZXggb3IgY2hlY2sgeW91ciBpbnN0YWxsYXRpb24uJywgJ2luZm8nLCBxdWlldCk7XG4gICAgcmV0dXJuIDE7XG4gIH1cblxuICBjb25zdCBlc2J1aWxkT3B0aW9uczogc3RyaW5nW10gPSBbXG4gICAgLi4uc291cmNlRmlsZXMsXG4gICAgJy0tY29sb3I9dHJ1ZScsXG4gICAgYC0tZm9ybWF0PSR7ZXNidWlsZENvbmZpZy5mb3JtYXQgfHwgJ2VzbSd9YCxcbiAgICBgLS1vdXRkaXI9JHtvdXRwdXREaXJ9YCxcbiAgICBgLS1wbGF0Zm9ybT0ke2VzYnVpbGRDb25maWcucGxhdGZvcm0gfHwgJ25vZGUnfWAsXG4gICAgYC0tc291cmNlbWFwPSR7ZXNidWlsZENvbmZpZy5zb3VyY2VtYXAgfHwgJ2lubGluZSd9YCxcbiAgICBgLS10YXJnZXQ9JHtlc2J1aWxkQ29uZmlnLnRhcmdldCB8fCAnbm9kZTIwJ31gXG4gIF07XG5cbiAgaWYoc2hvdWxkTWluaWZ5KSB7XG4gICAgZXNidWlsZE9wdGlvbnMucHVzaCgnLS1taW5pZnknKTtcbiAgfVxuXG4gIGlmKGVzYnVpbGRDb25maWcudHJlZVNoYWtpbmcgIT09IGZhbHNlKSB7XG4gICAgZXNidWlsZE9wdGlvbnMucHVzaCgnLS10cmVlLXNoYWtpbmc9dHJ1ZScpO1xuICB9XG5cbiAgaWYoZXNidWlsZENvbmZpZy5kcm9wICYmIGVzYnVpbGRDb25maWcuZHJvcC5sZW5ndGggPiAwKSB7XG4gICAgZXNidWlsZENvbmZpZy5kcm9wLmZvckVhY2goKGl0ZW0pID0+IHtcbiAgICAgIGVzYnVpbGRPcHRpb25zLnB1c2goYC0tZHJvcDoke2l0ZW19YCk7XG4gICAgfSk7XG4gIH1cblxuICBpZihlc2J1aWxkQ29uZmlnLnB1cmUgJiYgZXNidWlsZENvbmZpZy5wdXJlLmxlbmd0aCA+IDApIHtcbiAgICBlc2J1aWxkQ29uZmlnLnB1cmUuZm9yRWFjaCgoaXRlbSkgPT4ge1xuICAgICAgZXNidWlsZE9wdGlvbnMucHVzaChgLS1wdXJlOiR7aXRlbX1gKTtcbiAgICB9KTtcbiAgfVxuXG4gIGlmKGVzYnVpbGRDb25maWcubGVnYWxDb21tZW50cykge1xuICAgIGVzYnVpbGRPcHRpb25zLnB1c2goYC0tbGVnYWwtY29tbWVudHM9JHtlc2J1aWxkQ29uZmlnLmxlZ2FsQ29tbWVudHN9YCk7XG4gIH1cblxuICBpZihlc2J1aWxkQ29uZmlnLmJhbm5lcikge1xuICAgIE9iamVjdC5lbnRyaWVzKGVzYnVpbGRDb25maWcuYmFubmVyKS5mb3JFYWNoKChbdHlwZSwgY29udGVudF0pID0+IHtcbiAgICAgIGVzYnVpbGRPcHRpb25zLnB1c2goYC0tYmFubmVyOiR7dHlwZX09JHtjb250ZW50fWApO1xuICAgIH0pO1xuICB9XG5cbiAgaWYoZXNidWlsZENvbmZpZy5mb290ZXIpIHtcbiAgICBPYmplY3QuZW50cmllcyhlc2J1aWxkQ29uZmlnLmZvb3RlcikuZm9yRWFjaCgoW3R5cGUsIGNvbnRlbnRdKSA9PiB7XG4gICAgICBlc2J1aWxkT3B0aW9ucy5wdXNoKGAtLWZvb3Rlcjoke3R5cGV9PSR7Y29udGVudH1gKTtcbiAgICB9KTtcbiAgfVxuXG4gIGlmKGVzYnVpbGRDb25maWcuZGVmaW5lKSB7XG4gICAgT2JqZWN0LmVudHJpZXMoZXNidWlsZENvbmZpZy5kZWZpbmUpLmZvckVhY2goKFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgZXNidWlsZE9wdGlvbnMucHVzaChgLS1kZWZpbmU6JHtrZXl9PSR7dmFsdWV9YCk7XG4gICAgfSk7XG4gIH1cblxuICBpZih3YXRjaCkge1xuICAgIGVzYnVpbGRPcHRpb25zLnB1c2goJy0td2F0Y2gnKTtcbiAgfVxuXG4gIGNvbnN0IGNzc0ZpbGVzOiBzdHJpbmdbXSA9IGdldEZpbGVzQnlFeHQoJy5jc3MnLCBMZXhDb25maWcuY29uZmlnKTtcblxuICBpZihjc3NGaWxlcy5sZW5ndGgpIHtcbiAgICBjb25zdCBwb3N0Y3NzUGF0aDogc3RyaW5nID0gcmVzb2x2ZUJpbmFyeVBhdGgoJ3Bvc3Rjc3MnLCAncG9zdGNzcy1jbGknKTtcblxuICAgIGlmKCFwb3N0Y3NzUGF0aCkge1xuICAgICAgbG9nKGBcXG4ke2NsaU5hbWV9IEVycm9yOiBQb3N0Q1NTIGJpbmFyeSBub3QgZm91bmQgaW4gTGV4J3Mgbm9kZV9tb2R1bGVzIG9yIG1vbm9yZXBvIHJvb3RgLCAnZXJyb3InLCBxdWlldCk7XG4gICAgICBsb2coJ1BsZWFzZSByZWluc3RhbGwgTGV4IG9yIGNoZWNrIHlvdXIgaW5zdGFsbGF0aW9uLicsICdpbmZvJywgcXVpZXQpO1xuICAgICAgcmV0dXJuIDE7XG4gICAgfVxuXG4gICAgY29uc3QgcG9zdGNzc09wdGlvbnM6IHN0cmluZ1tdID0gW1xuICAgICAgYCR7c291cmNlRGlyfS8qKi8qKi5jc3NgLFxuICAgICAgJy0tYmFzZScsXG4gICAgICBzb3VyY2VEaXIsXG4gICAgICAnLS1kaXInLFxuICAgICAgb3V0cHV0RGlyLFxuICAgICAgJy0tY29uZmlnJyxcbiAgICAgIHBhdGhSZXNvbHZlKGRpck5hbWUsICcuLi8uLi9wb3N0Y3NzLmNvbmZpZy5qcycpXG4gICAgXTtcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCBleGVjYShwb3N0Y3NzUGF0aCwgcG9zdGNzc09wdGlvbnMsIHtlbmNvZGluZzogJ3V0ZjgnfSk7XG4gICAgICBzcGlubmVyLnN1Y2NlZWQoYFN1Y2Nlc3NmdWxseSBmb3JtYXR0ZWQgJHtjc3NGaWxlcy5sZW5ndGh9IGNzcyBmaWxlcyFgKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nKGBcXG4ke2NsaU5hbWV9IEVycm9yOiAke2Vycm9yLm1lc3NhZ2V9YCwgJ2Vycm9yJywgcXVpZXQpO1xuXG4gICAgICBzcGlubmVyLmZhaWwoJ0ZhaWxlZCBmb3JtYXR0aW5nIGNzcy4nKTtcblxuICAgICAgY2FsbGJhY2soMSk7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBnaWZGaWxlczogc3RyaW5nW10gPSBnZXRGaWxlc0J5RXh0KCcuZ2lmJywgTGV4Q29uZmlnLmNvbmZpZyk7XG4gIGNvbnN0IGpwZ0ZpbGVzOiBzdHJpbmdbXSA9IGdldEZpbGVzQnlFeHQoJy5qcGcnLCBMZXhDb25maWcuY29uZmlnKTtcbiAgY29uc3QgcG5nRmlsZXM6IHN0cmluZ1tdID0gZ2V0RmlsZXNCeUV4dCgnLnBuZycsIExleENvbmZpZy5jb25maWcpO1xuICBjb25zdCBzdmdGaWxlczogc3RyaW5nW10gPSBnZXRGaWxlc0J5RXh0KCcuc3ZnJywgTGV4Q29uZmlnLmNvbmZpZyk7XG4gIGNvbnN0IGltYWdlRmlsZXM6IHN0cmluZ1tdID0gWy4uLmdpZkZpbGVzLCAuLi5qcGdGaWxlcywgLi4ucG5nRmlsZXMsIC4uLnN2Z0ZpbGVzXTtcblxuICBpZihpbWFnZUZpbGVzLmxlbmd0aCkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBjb3B5RmlsZXMoaW1hZ2VGaWxlcywgJ2ltYWdlJywgc3Bpbm5lciwgTGV4Q29uZmlnLmNvbmZpZyk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBFcnJvcjogJHtlcnJvci5tZXNzYWdlfWAsICdlcnJvcicsIHF1aWV0KTtcblxuICAgICAgc3Bpbm5lci5mYWlsKCdGYWlsZWQgdG8gbW92ZSBpbWFnZXMgdG8gb3V0cHV0IGRpcmVjdG9yeS4nKTtcblxuICAgICAgY2FsbGJhY2soMSk7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG4gIH1cblxuICBjb25zdCB0dGZGaWxlczogc3RyaW5nW10gPSBnZXRGaWxlc0J5RXh0KCcudHRmJywgTGV4Q29uZmlnLmNvbmZpZyk7XG4gIGNvbnN0IG90ZkZpbGVzOiBzdHJpbmdbXSA9IGdldEZpbGVzQnlFeHQoJy5vdGYnLCBMZXhDb25maWcuY29uZmlnKTtcbiAgY29uc3Qgd29mZkZpbGVzOiBzdHJpbmdbXSA9IGdldEZpbGVzQnlFeHQoJy53b2ZmJywgTGV4Q29uZmlnLmNvbmZpZyk7XG4gIGNvbnN0IHdvZmYyRmlsZXM6IHN0cmluZ1tdID0gZ2V0RmlsZXNCeUV4dCgnLndvZmYyJywgTGV4Q29uZmlnLmNvbmZpZyk7XG4gIGNvbnN0IGZvbnRGaWxlczogc3RyaW5nW10gPSBbLi4udHRmRmlsZXMsIC4uLm90ZkZpbGVzLCAuLi53b2ZmRmlsZXMsIC4uLndvZmYyRmlsZXNdO1xuXG4gIGlmKGZvbnRGaWxlcy5sZW5ndGgpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgY29weUZpbGVzKGZvbnRGaWxlcywgJ2ZvbnQnLCBzcGlubmVyLCBMZXhDb25maWcuY29uZmlnKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nKGBcXG4ke2NsaU5hbWV9IEVycm9yOiAke2Vycm9yLm1lc3NhZ2V9YCwgJ2Vycm9yJywgcXVpZXQpO1xuXG4gICAgICBzcGlubmVyLmZhaWwoJ0ZhaWxlZCB0byBtb3ZlIGZvbnRzIHRvIG91dHB1dCBkaXJlY3RvcnkuJyk7XG5cbiAgICAgIGNhbGxiYWNrKDEpO1xuICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgbWRGaWxlczogc3RyaW5nW10gPSBnZXRGaWxlc0J5RXh0KCcubWQnLCBMZXhDb25maWcuY29uZmlnKTtcblxuICBpZihtZEZpbGVzLmxlbmd0aCkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBjb3B5RmlsZXMobWRGaWxlcywgJ2RvY3VtZW50cycsIHNwaW5uZXIsIExleENvbmZpZy5jb25maWcpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2coYFxcbiR7Y2xpTmFtZX0gRXJyb3I6ICR7ZXJyb3IubWVzc2FnZX1gLCAnZXJyb3InLCBxdWlldCk7XG5cbiAgICAgIHNwaW5uZXIuZmFpbCgnRmFpbGVkIHRvIG1vdmUgZG9jcyB0byBvdXRwdXQgZGlyZWN0b3J5LicpO1xuXG4gICAgICBjYWxsYmFjaygxKTtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgfVxuXG4gIHNwaW5uZXIuc3RhcnQod2F0Y2ggPyAnV2F0Y2hpbmcgZm9yIGNoYW5nZXMuLi4nIDogJ0NvbXBpbGluZyB3aXRoIEVTQnVpbGQuLi4nKTtcblxuICB0cnkge1xuICAgIGF3YWl0IGV4ZWNhKGVzYnVpbGRQYXRoLCBlc2J1aWxkT3B0aW9ucywge2VuY29kaW5nOiAndXRmOCd9KTtcblxuICAgIHNwaW5uZXIuc3VjY2VlZCgnQ29tcGlsZSBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5IScpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBFcnJvcjogJHtlcnJvci5tZXNzYWdlfWAsICdlcnJvcicsIHF1aWV0KTtcblxuICAgIGlmKCFxdWlldCkge1xuICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgfVxuXG4gICAgc3Bpbm5lci5mYWlsKCdDb2RlIGNvbXBpbGluZyBmYWlsZWQuJyk7XG5cbiAgICBjYWxsYmFjaygxKTtcbiAgICByZXR1cm4gMTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgYXdhaXQgY29weUNvbmZpZ3VyZWRGaWxlcyhzcGlubmVyLCBMZXhDb25maWcuY29uZmlnLCBxdWlldCk7XG4gIH0gY2F0Y2ggKGNvcHlFcnJvcikge1xuICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBFcnJvcjogRmFpbGVkIHRvIGNvcHkgY29uZmlndXJlZCBmaWxlczogJHtjb3B5RXJyb3IubWVzc2FnZX1gLCAnZXJyb3InLCBxdWlldCk7XG5cbiAgICBzcGlubmVyLmZhaWwoJ0ZhaWxlZCB0byBjb3B5IGNvbmZpZ3VyZWQgZmlsZXMuJyk7XG5cbiAgICBjYWxsYmFjaygxKTtcbiAgICByZXR1cm4gMTtcbiAgfVxuXG4gIGNhbGxiYWNrKDApO1xuICByZXR1cm4gMDtcbn07Il0sCiAgIm1hcHBpbmdzIjogIkFBSUEsU0FBUSxhQUFZO0FBQ3BCLFNBQVEsWUFBWSxXQUFXLG1CQUFrQjtBQUNqRCxTQUFRLFFBQVEsZ0JBQWU7QUFDL0IsU0FBUSxXQUFXLGFBQWEsUUFBUSxVQUFVLFdBQVcsbUJBQWtCO0FBRS9FLFNBQVEsV0FBVywrQkFBOEI7QUFDakQsU0FBUSxvQkFBb0IscUJBQXFCLFdBQVcsZUFBZSxlQUFlLG1CQUFrQjtBQUM1RyxTQUFRLFlBQVkseUJBQXdCO0FBQzVDLFNBQVEsV0FBVTtBQUVYLE1BQU0sY0FBYyxDQUFDLFdBQW1CLFFBQTJCO0FBQ3hFLE1BQUcsQ0FBQyxXQUFXLFNBQVMsR0FBRztBQUN6QixXQUFPO0FBQUEsRUFDVDtBQUVBLFFBQU0sUUFBa0IsWUFBWSxTQUFTO0FBRTdDLFNBQU8sTUFBTSxLQUFLLENBQUMsU0FBaUI7QUFDbEMsVUFBTSxXQUFtQixTQUFTLFdBQVcsSUFBSTtBQUNqRCxVQUFNLFVBQWtCLFlBQVksUUFBUTtBQUM1QyxVQUFNLE9BQU8sVUFBVSxRQUFRO0FBRS9CLFFBQUcsS0FBSyxZQUFZLEdBQUc7QUFDckIsYUFBTyxZQUFZLFVBQVUsR0FBRztBQUFBLElBQ2xDO0FBRUEsV0FBTyxJQUFJLFNBQVMsT0FBTztBQUFBLEVBQzdCLENBQUM7QUFDSDtBQUVPLE1BQU0sVUFBVSxPQUFPLEtBQVUsV0FBZ0IsT0FBTyxDQUFDLE9BQXdCO0FBQ3RGLFFBQU07QUFBQSxJQUNKLFVBQVU7QUFBQSxJQUNWO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxFQUNGLElBQUk7QUFFSixRQUFNLFVBQVUsY0FBYyxLQUFLO0FBRW5DLE1BQUksR0FBRyxPQUFPLGlCQUFpQixR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
227
+
228
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21tYW5kcy9jb21waWxlL2NvbXBpbGUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTgtUHJlc2VudCwgTml0cm9nZW4gTGFicywgSW5jLlxuICogQ29weXJpZ2h0cyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSB0aGUgYWNjb21wYW55aW5nIExJQ0VOU0UgZmlsZSBmb3IgdGVybXMuXG4gKi9cbmltcG9ydCB7dHJhbnNmb3JtfSBmcm9tICdAc3djL2NvcmUnO1xuaW1wb3J0IHtleGVjYX0gZnJvbSAnZXhlY2EnO1xuaW1wb3J0IHtleGlzdHNTeW5jLCBsc3RhdFN5bmMsIHJlYWRkaXJTeW5jLCByZWFkRmlsZVN5bmMsIHdyaXRlRmlsZVN5bmMsIG1rZGlyU3luY30gZnJvbSAnZnMnO1xuaW1wb3J0IHtzeW5jIGFzIGdsb2JTeW5jfSBmcm9tICdnbG9iJztcbmltcG9ydCB7ZXh0bmFtZSBhcyBwYXRoRXh0bmFtZSwgam9pbiBhcyBwYXRoSm9pbiwgcmVzb2x2ZSBhcyBwYXRoUmVzb2x2ZSwgZGlybmFtZX0gZnJvbSAncGF0aCc7XG5cbmltcG9ydCB7TGV4Q29uZmlnLCBnZXRUeXBlU2NyaXB0Q29uZmlnUGF0aH0gZnJvbSAnLi4vLi4vTGV4Q29uZmlnLmpzJztcbmltcG9ydCB7Y2hlY2tMaW5rZWRNb2R1bGVzLCBjb3B5Q29uZmlndXJlZEZpbGVzLCBjb3B5RmlsZXMsIGNyZWF0ZVNwaW5uZXIsIGdldEZpbGVzQnlFeHQsIHJlbW92ZUZpbGVzfSBmcm9tICcuLi8uLi91dGlscy9hcHAuanMnO1xuaW1wb3J0IHtnZXREaXJOYW1lLCByZXNvbHZlQmluYXJ5UGF0aH0gZnJvbSAnLi4vLi4vdXRpbHMvZmlsZS5qcyc7XG5pbXBvcnQge2xvZ30gZnJvbSAnLi4vLi4vdXRpbHMvbG9nLmpzJztcblxuZXhwb3J0IGNvbnN0IGhhc0ZpbGVUeXBlID0gKHN0YXJ0UGF0aDogc3RyaW5nLCBleHQ6IHN0cmluZ1tdKTogYm9vbGVhbiA9PiB7XG4gIGlmKCFleGlzdHNTeW5jKHN0YXJ0UGF0aCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBmaWxlczogc3RyaW5nW10gPSByZWFkZGlyU3luYyhzdGFydFBhdGgpO1xuXG4gIHJldHVybiBmaWxlcy5zb21lKChmaWxlOiBzdHJpbmcpID0+IHtcbiAgICBjb25zdCBmaWxlbmFtZTogc3RyaW5nID0gcGF0aEpvaW4oc3RhcnRQYXRoLCBmaWxlKTtcbiAgICBjb25zdCBmaWxlRXh0OiBzdHJpbmcgPSBwYXRoRXh0bmFtZShmaWxlbmFtZSk7XG4gICAgY29uc3Qgc3RhdCA9IGxzdGF0U3luYyhmaWxlbmFtZSk7XG5cbiAgICBpZihzdGF0LmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgIHJldHVybiBoYXNGaWxlVHlwZShmaWxlbmFtZSwgZXh0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gZXh0LmluY2x1ZGVzKGZpbGVFeHQpO1xuICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBjb21waWxlID0gYXN5bmMgKGNtZDogYW55LCBjYWxsYmFjazogYW55ID0gKCkgPT4gKHt9KSk6IFByb21pc2U8bnVtYmVyPiA9PiB7XG4gIGNvbnN0IHtcbiAgICBjbGlOYW1lID0gJ0xleCcsXG4gICAgY29uZmlnLFxuICAgIGZvcm1hdCA9ICdlc20nLFxuICAgIG91dHB1dFBhdGgsXG4gICAgcXVpZXQsXG4gICAgcmVtb3ZlLFxuICAgIHNvdXJjZVBhdGgsXG4gICAgd2F0Y2hcbiAgfSA9IGNtZDtcblxuICBjb25zdCBzcGlubmVyID0gY3JlYXRlU3Bpbm5lcihxdWlldCk7XG5cbiAgbG9nKGAke2NsaU5hbWV9IGNvbXBpbGluZy4uLmAsICdpbmZvJywgcXVpZXQpO1xuXG4gIGF3YWl0IExleENvbmZpZy5wYXJzZUNvbmZpZyhjbWQpO1xuXG4gIGNvbnN0IHtvdXRwdXRGdWxsUGF0aCwgc291cmNlRnVsbFBhdGgsIHN3Yzogc3djQ29uZmlnLCB1c2VUeXBlc2NyaXB0fSA9IExleENvbmZpZy5jb25maWc7XG4gIGNvbnN0IG91dHB1dERpcjogc3RyaW5nID0gb3V0cHV0UGF0aCB8fCBvdXRwdXRGdWxsUGF0aDtcbiAgY29uc3Qgc291cmNlRGlyOiBzdHJpbmcgPSBzb3VyY2VQYXRoID8gcGF0aFJlc29sdmUocHJvY2Vzcy5jd2QoKSwgYC4vJHtzb3VyY2VQYXRofWApIDogc291cmNlRnVsbFBhdGggfHwgJyc7XG4gIGNvbnN0IGRpck5hbWUgPSBnZXREaXJOYW1lKCk7XG4gIGNvbnN0IGRpclBhdGg6IHN0cmluZyA9IHBhdGhSZXNvbHZlKGRpck5hbWUsICcuLi8uLicpO1xuXG4gIGNoZWNrTGlua2VkTW9kdWxlcygpO1xuXG4gIGlmKHJlbW92ZSkge1xuICAgIGF3YWl0IHJlbW92ZUZpbGVzKG91dHB1dERpcik7XG4gIH1cblxuICBpZih1c2VUeXBlc2NyaXB0KSB7XG4gICAgTGV4Q29uZmlnLmNoZWNrQ29tcGlsZVR5cGVzY3JpcHRDb25maWcoKTtcblxuICAgIGNvbnN0IHR5cGVzY3JpcHRQYXRoOiBzdHJpbmcgPSByZXNvbHZlQmluYXJ5UGF0aCgndHNjJywgJ3R5cGVzY3JpcHQnKTtcblxuICAgIGlmKCF0eXBlc2NyaXB0UGF0aCkge1xuICAgICAgbG9nKGBcXG4ke2NsaU5hbWV9IEVycm9yOiBUeXBlU2NyaXB0IGJpbmFyeSBub3QgZm91bmQgaW4gTGV4J3Mgbm9kZV9tb2R1bGVzIG9yIG1vbm9yZXBvIHJvb3RgLCAnZXJyb3InLCBxdWlldCk7XG4gICAgICBsb2coJ1BsZWFzZSByZWluc3RhbGwgTGV4IG9yIGNoZWNrIHlvdXIgaW5zdGFsbGF0aW9uLicsICdpbmZvJywgcXVpZXQpO1xuICAgICAgcmV0dXJuIDE7XG4gICAgfVxuXG4gICAgY29uc3QgdHlwZXNjcmlwdE9wdGlvbnM6IHN0cmluZ1tdID0gY29uZmlnID9cbiAgICAgIFsnLXAnLCBjb25maWddIDpcbiAgICAgIFsnLXAnLCBnZXRUeXBlU2NyaXB0Q29uZmlnUGF0aCgndHNjb25maWcuYnVpbGQuanNvbicpXTtcblxuICAgIHNwaW5uZXIuc3RhcnQoJ1N0YXRpYyB0eXBlIGNoZWNraW5nIHdpdGggVHlwZXNjcmlwdC4uLicpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGV4ZWNhKHR5cGVzY3JpcHRQYXRoLCB0eXBlc2NyaXB0T3B0aW9ucywge2VuY29kaW5nOiAndXRmOCd9KTtcblxuICAgICAgc3Bpbm5lci5zdWNjZWVkKCdTdWNjZXNzZnVsbHkgY29tcGxldGVkIHR5cGUgY2hlY2tpbmchJyk7XG4gICAgfSBjYXRjaChlcnJvcikge1xuICAgICAgbG9nKGBcXG4ke2NsaU5hbWV9IEVycm9yOiAke2Vycm9yLm1lc3NhZ2V9YCwgJ2Vycm9yJywgcXVpZXQpO1xuXG4gICAgICBzcGlubmVyLmZhaWwoJ1R5cGUgY2hlY2tpbmcgZmFpbGVkLicpO1xuXG4gICAgICBjYWxsYmFjaygxKTtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGdsb2JPcHRpb25zID0ge1xuICAgIGN3ZDogc291cmNlRGlyLFxuICAgIGRvdDogZmFsc2UsXG4gICAgbm9kaXI6IHRydWUsXG4gICAgbm9zb3J0OiB0cnVlXG4gIH07XG4gIGNvbnN0IHRzRmlsZXM6IHN0cmluZ1tdID0gZ2xvYlN5bmMoYCR7c291cmNlRGlyfS8qKi8hKCouc3BlY3wqLnRlc3R8Ki5pbnRlZ3JhdGlvbikudHMqYCwgZ2xvYk9wdGlvbnMpO1xuICBjb25zdCBqc0ZpbGVzOiBzdHJpbmdbXSA9IGdsb2JTeW5jKGAke3NvdXJjZURpcn0vKiovISgqLnNwZWN8Ki50ZXN0fCouaW50ZWdyYXRpb24pLmpzYCwgZ2xvYk9wdGlvbnMpO1xuICBjb25zdCBzb3VyY2VGaWxlczogc3RyaW5nW10gPSBbLi4udHNGaWxlcywgLi4uanNGaWxlc107XG5cbiAgY29uc3QgY3NzRmlsZXM6IHN0cmluZ1tdID0gZ2V0RmlsZXNCeUV4dCgnLmNzcycsIExleENvbmZpZy5jb25maWcpO1xuXG4gIGlmKGNzc0ZpbGVzLmxlbmd0aCkge1xuICAgIGNvbnN0IHBvc3Rjc3NQYXRoOiBzdHJpbmcgPSByZXNvbHZlQmluYXJ5UGF0aCgncG9zdGNzcycsICdwb3N0Y3NzLWNsaScpO1xuXG4gICAgaWYoIXBvc3Rjc3NQYXRoKSB7XG4gICAgICBsb2coYFxcbiR7Y2xpTmFtZX0gRXJyb3I6IFBvc3RDU1MgYmluYXJ5IG5vdCBmb3VuZCBpbiBMZXgncyBub2RlX21vZHVsZXMgb3IgbW9ub3JlcG8gcm9vdGAsICdlcnJvcicsIHF1aWV0KTtcbiAgICAgIGxvZygnUGxlYXNlIHJlaW5zdGFsbCBMZXggb3IgY2hlY2sgeW91ciBpbnN0YWxsYXRpb24uJywgJ2luZm8nLCBxdWlldCk7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG5cbiAgICBjb25zdCBwb3N0Y3NzT3B0aW9uczogc3RyaW5nW10gPSBbXG4gICAgICBgJHtzb3VyY2VEaXJ9LyoqLyoqLmNzc2AsXG4gICAgICAnLS1iYXNlJyxcbiAgICAgIHNvdXJjZURpcixcbiAgICAgICctLWRpcicsXG4gICAgICBvdXRwdXREaXIsXG4gICAgICAnLS1jb25maWcnLFxuICAgICAgcGF0aFJlc29sdmUoZGlyTmFtZSwgJy4uLy4uL3Bvc3Rjc3MuY29uZmlnLmpzJylcbiAgICBdO1xuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGV4ZWNhKHBvc3Rjc3NQYXRoLCBwb3N0Y3NzT3B0aW9ucywge2VuY29kaW5nOiAndXRmOCd9KTtcbiAgICAgIHNwaW5uZXIuc3VjY2VlZChgU3VjY2Vzc2Z1bGx5IGZvcm1hdHRlZCAke2Nzc0ZpbGVzLmxlbmd0aH0gY3NzIGZpbGVzIWApO1xuICAgIH0gY2F0Y2goZXJyb3IpIHtcbiAgICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBFcnJvcjogJHtlcnJvci5tZXNzYWdlfWAsICdlcnJvcicsIHF1aWV0KTtcblxuICAgICAgc3Bpbm5lci5mYWlsKCdGYWlsZWQgZm9ybWF0dGluZyBjc3MuJyk7XG5cbiAgICAgIGNhbGxiYWNrKDEpO1xuICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgZ2lmRmlsZXM6IHN0cmluZ1tdID0gZ2V0RmlsZXNCeUV4dCgnLmdpZicsIExleENvbmZpZy5jb25maWcpO1xuICBjb25zdCBqcGdGaWxlczogc3RyaW5nW10gPSBnZXRGaWxlc0J5RXh0KCcuanBnJywgTGV4Q29uZmlnLmNvbmZpZyk7XG4gIGNvbnN0IHBuZ0ZpbGVzOiBzdHJpbmdbXSA9IGdldEZpbGVzQnlFeHQoJy5wbmcnLCBMZXhDb25maWcuY29uZmlnKTtcbiAgY29uc3Qgc3ZnRmlsZXM6IHN0cmluZ1tdID0gZ2V0RmlsZXNCeUV4dCgnLnN2ZycsIExleENvbmZpZy5jb25maWcpO1xuICBjb25zdCBpbWFnZUZpbGVzOiBzdHJpbmdbXSA9IFsuLi5naWZGaWxlcywgLi4uanBnRmlsZXMsIC4uLnBuZ0ZpbGVzLCAuLi5zdmdGaWxlc107XG5cbiAgaWYoaW1hZ2VGaWxlcy5sZW5ndGgpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgY29weUZpbGVzKGltYWdlRmlsZXMsICdpbWFnZScsIHNwaW5uZXIsIExleENvbmZpZy5jb25maWcpO1xuICAgIH0gY2F0Y2goZXJyb3IpIHtcbiAgICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBFcnJvcjogJHtlcnJvci5tZXNzYWdlfWAsICdlcnJvcicsIHF1aWV0KTtcblxuICAgICAgc3Bpbm5lci5mYWlsKCdGYWlsZWQgdG8gbW92ZSBpbWFnZXMgdG8gb3V0cHV0IGRpcmVjdG9yeS4nKTtcblxuICAgICAgY2FsbGJhY2soMSk7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG4gIH1cblxuICBjb25zdCB0dGZGaWxlczogc3RyaW5nW10gPSBnZXRGaWxlc0J5RXh0KCcudHRmJywgTGV4Q29uZmlnLmNvbmZpZyk7XG4gIGNvbnN0IG90ZkZpbGVzOiBzdHJpbmdbXSA9IGdldEZpbGVzQnlFeHQoJy5vdGYnLCBMZXhDb25maWcuY29uZmlnKTtcbiAgY29uc3Qgd29mZkZpbGVzOiBzdHJpbmdbXSA9IGdldEZpbGVzQnlFeHQoJy53b2ZmJywgTGV4Q29uZmlnLmNvbmZpZyk7XG4gIGNvbnN0IHdvZmYyRmlsZXM6IHN0cmluZ1tdID0gZ2V0RmlsZXNCeUV4dCgnLndvZmYyJywgTGV4Q29uZmlnLmNvbmZpZyk7XG4gIGNvbnN0IGZvbnRGaWxlczogc3RyaW5nW10gPSBbLi4udHRmRmlsZXMsIC4uLm90ZkZpbGVzLCAuLi53b2ZmRmlsZXMsIC4uLndvZmYyRmlsZXNdO1xuXG4gIGlmKGZvbnRGaWxlcy5sZW5ndGgpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgY29weUZpbGVzKGZvbnRGaWxlcywgJ2ZvbnQnLCBzcGlubmVyLCBMZXhDb25maWcuY29uZmlnKTtcbiAgICB9IGNhdGNoKGVycm9yKSB7XG4gICAgICBsb2coYFxcbiR7Y2xpTmFtZX0gRXJyb3I6ICR7ZXJyb3IubWVzc2FnZX1gLCAnZXJyb3InLCBxdWlldCk7XG5cbiAgICAgIHNwaW5uZXIuZmFpbCgnRmFpbGVkIHRvIG1vdmUgZm9udHMgdG8gb3V0cHV0IGRpcmVjdG9yeS4nKTtcblxuICAgICAgY2FsbGJhY2soMSk7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBtZEZpbGVzOiBzdHJpbmdbXSA9IGdldEZpbGVzQnlFeHQoJy5tZCcsIExleENvbmZpZy5jb25maWcpO1xuXG4gIGlmKG1kRmlsZXMubGVuZ3RoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGNvcHlGaWxlcyhtZEZpbGVzLCAnZG9jdW1lbnRzJywgc3Bpbm5lciwgTGV4Q29uZmlnLmNvbmZpZyk7XG4gICAgfSBjYXRjaChlcnJvcikge1xuICAgICAgbG9nKGBcXG4ke2NsaU5hbWV9IEVycm9yOiAke2Vycm9yLm1lc3NhZ2V9YCwgJ2Vycm9yJywgcXVpZXQpO1xuXG4gICAgICBzcGlubmVyLmZhaWwoJ0ZhaWxlZCB0byBtb3ZlIGRvY3MgdG8gb3V0cHV0IGRpcmVjdG9yeS4nKTtcblxuICAgICAgY2FsbGJhY2soMSk7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG4gIH1cblxuICBzcGlubmVyLnN0YXJ0KHdhdGNoID8gJ1dhdGNoaW5nIGZvciBjaGFuZ2VzLi4uJyA6ICdDb21waWxpbmcgd2l0aCBTV0MuLi4nKTtcblxuICB0cnkge1xuICAgIC8vIENvbXBpbGUgZWFjaCBmaWxlIHdpdGggU1dDXG4gICAgZm9yKGNvbnN0IGZpbGUgb2Ygc291cmNlRmlsZXMpIHtcbiAgICAgIGNvbnN0IHNvdXJjZVBhdGggPSBwYXRoUmVzb2x2ZShzb3VyY2VEaXIsIGZpbGUpO1xuICAgICAgY29uc3Qgb3V0cHV0UGF0aCA9IHBhdGhSZXNvbHZlKG91dHB1dERpciwgZmlsZS5yZXBsYWNlKC9cXC4odHN8dHN4KSQvLCAnLmpzJykpO1xuXG4gICAgICAvLyBFbnN1cmUgb3V0cHV0IGRpcmVjdG9yeSBleGlzdHNcbiAgICAgIGNvbnN0IG91dHB1dERpclBhdGggPSBkaXJuYW1lKG91dHB1dFBhdGgpO1xuICAgICAgaWYoIWV4aXN0c1N5bmMob3V0cHV0RGlyUGF0aCkpIHtcbiAgICAgICAgbWtkaXJTeW5jKG91dHB1dERpclBhdGgsIHtyZWN1cnNpdmU6IHRydWV9KTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc291cmNlQ29kZSA9IHJlYWRGaWxlU3luYyhzb3VyY2VQYXRoLCAndXRmOCcpO1xuXG4gICAgICBjb25zdCBpc1RTWCA9IGZpbGUuZW5kc1dpdGgoJy50c3gnKTtcblxuICAgICAgLy8gTWVyZ2UgU1dDIGNvbmZpZyB3aXRoIGNvbW1hbmQtc3BlY2lmaWMgb3ZlcnJpZGVzXG4gICAgICBjb25zdCBzd2NPcHRpb25zID0ge1xuICAgICAgICBmaWxlbmFtZTogZmlsZSxcbiAgICAgICAgLi4uc3djQ29uZmlnLFxuICAgICAgICBqc2M6IHtcbiAgICAgICAgICAuLi5zd2NDb25maWc/LmpzYyxcbiAgICAgICAgICBwYXJzZXI6IHtcbiAgICAgICAgICAgIGRlY29yYXRvcnM6IHN3Y0NvbmZpZz8uanNjPy5wYXJzZXI/LmRlY29yYXRvcnMgPz8gdHJ1ZSxcbiAgICAgICAgICAgIGR5bmFtaWNJbXBvcnQ6IHN3Y0NvbmZpZz8uanNjPy5wYXJzZXI/LmR5bmFtaWNJbXBvcnQgPz8gdHJ1ZSxcbiAgICAgICAgICAgIHN5bnRheDogJ3R5cGVzY3JpcHQnIGFzIGNvbnN0LFxuICAgICAgICAgICAgdHN4OiBpc1RTWFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdGFyZ2V0OiBzd2NDb25maWc/LmpzYz8udGFyZ2V0ID8/ICdlczIwMjAnLFxuICAgICAgICAgIHRyYW5zZm9ybTogaXNUU1ggPyB7XG4gICAgICAgICAgICAuLi5zd2NDb25maWc/LmpzYz8udHJhbnNmb3JtLFxuICAgICAgICAgICAgcmVhY3Q6IHtcbiAgICAgICAgICAgICAgcnVudGltZTogJ2F1dG9tYXRpYycgYXMgY29uc3QsXG4gICAgICAgICAgICAgIC4uLnN3Y0NvbmZpZz8uanNjPy50cmFuc2Zvcm0/LnJlYWN0XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSA6IHN3Y0NvbmZpZz8uanNjPy50cmFuc2Zvcm1cbiAgICAgICAgfSxcbiAgICAgICAgbW9kdWxlOiB7XG4gICAgICAgICAgLi4uc3djQ29uZmlnPy5tb2R1bGUsXG4gICAgICAgICAgdHlwZTogZm9ybWF0ID09PSAnY2pzJyA/ICdjb21tb25qcycgYXMgY29uc3QgOiAoc3djQ29uZmlnPy5tb2R1bGU/LnR5cGUgYXMgJ2VzNicgfHwgJ2VzNicpXG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRyYW5zZm9ybShzb3VyY2VDb2RlLCBzd2NPcHRpb25zKTtcblxuICAgICAgd3JpdGVGaWxlU3luYyhvdXRwdXRQYXRoLCByZXN1bHQuY29kZSk7XG4gICAgfVxuXG4gICAgc3Bpbm5lci5zdWNjZWVkKCdDb21waWxlIGNvbXBsZXRlZCBzdWNjZXNzZnVsbHkhJyk7XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICBsb2coYFxcbiR7Y2xpTmFtZX0gRXJyb3I6ICR7ZXJyb3IubWVzc2FnZX1gLCAnZXJyb3InLCBxdWlldCk7XG5cbiAgICBpZighcXVpZXQpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgIH1cblxuICAgIHNwaW5uZXIuZmFpbCgnQ29kZSBjb21waWxpbmcgZmFpbGVkLicpO1xuXG4gICAgY2FsbGJhY2soMSk7XG4gICAgcmV0dXJuIDE7XG4gIH1cblxuICB0cnkge1xuICAgIGF3YWl0IGNvcHlDb25maWd1cmVkRmlsZXMoc3Bpbm5lciwgTGV4Q29uZmlnLmNvbmZpZywgcXVpZXQpO1xuICB9IGNhdGNoKGNvcHlFcnJvcikge1xuICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBFcnJvcjogRmFpbGVkIHRvIGNvcHkgY29uZmlndXJlZCBmaWxlczogJHtjb3B5RXJyb3IubWVzc2FnZX1gLCAnZXJyb3InLCBxdWlldCk7XG5cbiAgICBzcGlubmVyLmZhaWwoJ0ZhaWxlZCB0byBjb3B5IGNvbmZpZ3VyZWQgZmlsZXMuJyk7XG5cbiAgICBjYWxsYmFjaygxKTtcbiAgICByZXR1cm4gMTtcbiAgfVxuXG4gIGNhbGxiYWNrKDApO1xuICByZXR1cm4gMDtcbn07Il0sIm5hbWVzIjpbInRyYW5zZm9ybSIsImV4ZWNhIiwiZXhpc3RzU3luYyIsImxzdGF0U3luYyIsInJlYWRkaXJTeW5jIiwicmVhZEZpbGVTeW5jIiwid3JpdGVGaWxlU3luYyIsIm1rZGlyU3luYyIsInN5bmMiLCJnbG9iU3luYyIsImV4dG5hbWUiLCJwYXRoRXh0bmFtZSIsImpvaW4iLCJwYXRoSm9pbiIsInJlc29sdmUiLCJwYXRoUmVzb2x2ZSIsImRpcm5hbWUiLCJMZXhDb25maWciLCJnZXRUeXBlU2NyaXB0Q29uZmlnUGF0aCIsImNoZWNrTGlua2VkTW9kdWxlcyIsImNvcHlDb25maWd1cmVkRmlsZXMiLCJjb3B5RmlsZXMiLCJjcmVhdGVTcGlubmVyIiwiZ2V0RmlsZXNCeUV4dCIsInJlbW92ZUZpbGVzIiwiZ2V0RGlyTmFtZSIsInJlc29sdmVCaW5hcnlQYXRoIiwibG9nIiwiaGFzRmlsZVR5cGUiLCJzdGFydFBhdGgiLCJleHQiLCJmaWxlcyIsInNvbWUiLCJmaWxlIiwiZmlsZW5hbWUiLCJmaWxlRXh0Iiwic3RhdCIsImlzRGlyZWN0b3J5IiwiaW5jbHVkZXMiLCJjb21waWxlIiwiY21kIiwiY2FsbGJhY2siLCJjbGlOYW1lIiwiY29uZmlnIiwiZm9ybWF0Iiwib3V0cHV0UGF0aCIsInF1aWV0IiwicmVtb3ZlIiwic291cmNlUGF0aCIsIndhdGNoIiwic3Bpbm5lciIsInBhcnNlQ29uZmlnIiwib3V0cHV0RnVsbFBhdGgiLCJzb3VyY2VGdWxsUGF0aCIsInN3YyIsInN3Y0NvbmZpZyIsInVzZVR5cGVzY3JpcHQiLCJvdXRwdXREaXIiLCJzb3VyY2VEaXIiLCJwcm9jZXNzIiwiY3dkIiwiZGlyTmFtZSIsImRpclBhdGgiLCJjaGVja0NvbXBpbGVUeXBlc2NyaXB0Q29uZmlnIiwidHlwZXNjcmlwdFBhdGgiLCJ0eXBlc2NyaXB0T3B0aW9ucyIsInN0YXJ0IiwiZW5jb2RpbmciLCJzdWNjZWVkIiwiZXJyb3IiLCJtZXNzYWdlIiwiZmFpbCIsImdsb2JPcHRpb25zIiwiZG90Iiwibm9kaXIiLCJub3NvcnQiLCJ0c0ZpbGVzIiwianNGaWxlcyIsInNvdXJjZUZpbGVzIiwiY3NzRmlsZXMiLCJsZW5ndGgiLCJwb3N0Y3NzUGF0aCIsInBvc3Rjc3NPcHRpb25zIiwiZ2lmRmlsZXMiLCJqcGdGaWxlcyIsInBuZ0ZpbGVzIiwic3ZnRmlsZXMiLCJpbWFnZUZpbGVzIiwidHRmRmlsZXMiLCJvdGZGaWxlcyIsIndvZmZGaWxlcyIsIndvZmYyRmlsZXMiLCJmb250RmlsZXMiLCJtZEZpbGVzIiwicmVwbGFjZSIsIm91dHB1dERpclBhdGgiLCJyZWN1cnNpdmUiLCJzb3VyY2VDb2RlIiwiaXNUU1giLCJlbmRzV2l0aCIsInN3Y09wdGlvbnMiLCJqc2MiLCJwYXJzZXIiLCJkZWNvcmF0b3JzIiwiZHluYW1pY0ltcG9ydCIsInN5bnRheCIsInRzeCIsInRhcmdldCIsInJlYWN0IiwicnVudGltZSIsIm1vZHVsZSIsInR5cGUiLCJyZXN1bHQiLCJjb2RlIiwiY29u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