@nlabs/lex 1.48.7 → 1.49.1

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 (105) hide show
  1. package/.storybook/main.ts +9 -2
  2. package/.vscode/settings.json +1 -6
  3. package/README.md +249 -0
  4. package/eslint.config.mjs +24 -0
  5. package/examples/lex.config.js +18 -8
  6. package/examples/serverless-example/README.md +109 -0
  7. package/examples/serverless-example/dist/handlers/echo.js +15 -0
  8. package/examples/serverless-example/dist/handlers/graphql.js +137 -0
  9. package/examples/serverless-example/dist/handlers/hello.js +15 -0
  10. package/examples/serverless-example/dist/handlers/test.js +17 -0
  11. package/examples/serverless-example/dist/handlers/websocket.js +14 -0
  12. package/examples/serverless-example/lex.config.mjs +74 -0
  13. package/jest.config.mjs +13 -12
  14. package/{dist → lib}/LexConfig.d.ts +7 -6
  15. package/lib/LexConfig.js +268 -0
  16. package/lib/commands/ai/ai.js +303 -0
  17. package/{dist → lib}/commands/build/build.d.ts +3 -0
  18. package/lib/commands/build/build.js +494 -0
  19. package/{dist → lib}/commands/clean/clean.js +1 -1
  20. package/lib/commands/compile/compile.js +241 -0
  21. package/lib/commands/copy/copy.js +38 -0
  22. package/{dist → lib}/commands/create/create.js +1 -1
  23. package/{dist → lib}/commands/dev/dev.d.ts +2 -0
  24. package/lib/commands/dev/dev.js +286 -0
  25. package/{dist → lib}/commands/init/init.js +1 -1
  26. package/lib/commands/lint/lint.js +962 -0
  27. package/{dist → lib}/commands/migrate/migrate.js +1 -1
  28. package/lib/commands/publish/publish.js +104 -0
  29. package/lib/commands/serverless/serverless.d.ts +17 -0
  30. package/lib/commands/serverless/serverless.js +662 -0
  31. package/lib/commands/storybook/storybook.js +249 -0
  32. package/lib/commands/test/test.js +428 -0
  33. package/lib/commands/update/update.js +128 -0
  34. package/{dist → lib}/create/changelog.js +1 -1
  35. package/{dist → lib}/index.d.ts +1 -0
  36. package/{dist → lib}/index.js +2 -1
  37. package/lib/lex.js +73 -0
  38. package/lib/utils/aiService.d.ts +9 -0
  39. package/lib/utils/aiService.js +299 -0
  40. package/{dist → lib}/utils/app.d.ts +3 -0
  41. package/lib/utils/app.js +296 -0
  42. package/{dist → lib}/utils/file.d.ts +7 -3
  43. package/lib/utils/file.js +229 -0
  44. package/lib/utils/translations.d.ts +1 -0
  45. package/lib/utils/translations.js +74 -0
  46. package/package.json +60 -54
  47. package/postcss.config.js +5 -3
  48. package/tsconfig.build.json +2 -2
  49. package/webpack.config.js +229 -39
  50. package/dist/LexConfig.js +0 -287
  51. package/dist/commands/ai/ai.js +0 -303
  52. package/dist/commands/build/build.js +0 -404
  53. package/dist/commands/compile/compile.js +0 -234
  54. package/dist/commands/copy/copy.js +0 -38
  55. package/dist/commands/dev/dev.js +0 -74
  56. package/dist/commands/lint/lint.js +0 -993
  57. package/dist/commands/publish/publish.js +0 -104
  58. package/dist/commands/storybook/storybook.js +0 -249
  59. package/dist/commands/test/test.js +0 -429
  60. package/dist/commands/update/update.js +0 -132
  61. package/dist/lex.js +0 -70
  62. package/dist/utils/aiService.d.ts +0 -9
  63. package/dist/utils/aiService.js +0 -299
  64. package/dist/utils/app.js +0 -267
  65. package/dist/utils/file.js +0 -185
  66. package/emptyModule.js +0 -0
  67. package/eslint.config.js +0 -3
  68. /package/{dist → lib}/Button.stories.d.ts +0 -0
  69. /package/{dist → lib}/commands/ai/ai.d.ts +0 -0
  70. /package/{dist → lib}/commands/ai/index.d.ts +0 -0
  71. /package/{dist → lib}/commands/ai/index.js +0 -0
  72. /package/{dist → lib}/commands/clean/clean.d.ts +0 -0
  73. /package/{dist → lib}/commands/compile/compile.d.ts +0 -0
  74. /package/{dist → lib}/commands/config/config.d.ts +0 -0
  75. /package/{dist → lib}/commands/config/config.js +0 -0
  76. /package/{dist → lib}/commands/copy/copy.d.ts +0 -0
  77. /package/{dist → lib}/commands/create/create.d.ts +0 -0
  78. /package/{dist → lib}/commands/init/init.d.ts +0 -0
  79. /package/{dist → lib}/commands/link/link.d.ts +0 -0
  80. /package/{dist → lib}/commands/link/link.js +0 -0
  81. /package/{dist → lib}/commands/lint/autofix.d.ts +0 -0
  82. /package/{dist → lib}/commands/lint/lint.d.ts +0 -0
  83. /package/{dist → lib}/commands/migrate/migrate.d.ts +0 -0
  84. /package/{dist → lib}/commands/publish/publish.d.ts +0 -0
  85. /package/{dist → lib}/commands/storybook/storybook.d.ts +0 -0
  86. /package/{dist → lib}/commands/test/test.d.ts +0 -0
  87. /package/{dist → lib}/commands/update/update.d.ts +0 -0
  88. /package/{dist → lib}/commands/upgrade/upgrade.d.ts +0 -0
  89. /package/{dist → lib}/commands/upgrade/upgrade.js +0 -0
  90. /package/{dist → lib}/commands/versions/versions.d.ts +0 -0
  91. /package/{dist → lib}/commands/versions/versions.js +0 -0
  92. /package/{dist → lib}/create/changelog.d.ts +0 -0
  93. /package/{dist → lib}/lex.d.ts +0 -0
  94. /package/{dist → lib}/storybook/index.d.ts +0 -0
  95. /package/{dist → lib}/storybook/index.js +0 -0
  96. /package/{dist → lib}/test-react/index.d.ts +0 -0
  97. /package/{dist → lib}/test-react/index.js +0 -0
  98. /package/{dist → lib}/types.d.ts +0 -0
  99. /package/{dist → lib}/types.js +0 -0
  100. /package/{dist → lib}/utils/deepMerge.d.ts +0 -0
  101. /package/{dist → lib}/utils/deepMerge.js +0 -0
  102. /package/{dist → lib}/utils/log.d.ts +0 -0
  103. /package/{dist → lib}/utils/log.js +0 -0
  104. /package/{dist → lib}/utils/reactShim.d.ts +0 -0
  105. /package/{dist → lib}/utils/reactShim.js +0 -0
@@ -0,0 +1,303 @@
1
+ import chalk from "chalk";
2
+ import { Command } from "commander";
3
+ import { readFileSync } from "fs";
4
+ import { sync as globSync } from "glob";
5
+ import { LexConfig } from "../../LexConfig.js";
6
+ import { callAIService } from "../../utils/aiService.js";
7
+ import { log } from "../../utils/log.js";
8
+ if (process.env.CURSOR_EXTENSION === "true" || process.env.CURSOR_TERMINAL === "true" || process.env.CURSOR_APP === "true" || process.env.PATH?.includes("cursor") || process.env.CURSOR_SESSION_ID) {
9
+ process.env.CURSOR_IDE = "true";
10
+ }
11
+ const getFileContext = (filePath) => {
12
+ try {
13
+ const content = readFileSync(filePath, "utf-8");
14
+ return `File: ${filePath}
15
+
16
+ ${content}`;
17
+ } catch (_error) {
18
+ return `Error reading file: ${filePath}`;
19
+ }
20
+ };
21
+ const getProjectContext = async (options) => {
22
+ const { file, task, context } = options;
23
+ if (context === false) {
24
+ return "";
25
+ }
26
+ let projectContext = "";
27
+ if (file) {
28
+ projectContext += getFileContext(file);
29
+ }
30
+ switch (task) {
31
+ case "generate":
32
+ const files = globSync("src/**/*.{ts,tsx,js,jsx}", {
33
+ cwd: process.cwd(),
34
+ ignore: ["**/node_modules/**", "**/dist/**", "**/*.test.*", "**/*.spec.*"],
35
+ maxDepth: 3
36
+ });
37
+ projectContext += `
38
+
39
+ Project structure:
40
+ ${files.join("\n")}`;
41
+ break;
42
+ case "test":
43
+ if (file) {
44
+ const testConfig = getFileContext("jest.config.js");
45
+ projectContext += `
46
+
47
+ Test configuration:
48
+ ${testConfig}`;
49
+ }
50
+ break;
51
+ case "optimize":
52
+ const webpackConfig = getFileContext("webpack.config.js");
53
+ projectContext += `
54
+
55
+ Webpack configuration:
56
+ ${webpackConfig}`;
57
+ break;
58
+ default:
59
+ break;
60
+ }
61
+ return projectContext;
62
+ };
63
+ const constructPrompt = (options, projectContext) => {
64
+ const { task = "help", prompt = "" } = options;
65
+ const taskInstructions = {
66
+ generate: "Generate code according to the following request. Make sure it follows best practices and is well documented:",
67
+ explain: "Explain the following code in detail, including any patterns, potential issues, and improvement suggestions:",
68
+ test: "Generate comprehensive unit tests for the following code:",
69
+ optimize: "Analyze the following code/configuration and suggest optimization improvements:",
70
+ help: "Provide guidance on the following development question:",
71
+ ask: "Provide guidance on the following development question:",
72
+ analyze: "Analyze the following code:"
73
+ };
74
+ const taskInstruction = taskInstructions[task] || taskInstructions.help;
75
+ let fullPrompt = `${taskInstruction}
76
+
77
+ ${prompt}`;
78
+ if (projectContext) {
79
+ fullPrompt += `
80
+
81
+ ===CONTEXT===
82
+ ${projectContext}`;
83
+ }
84
+ return fullPrompt;
85
+ };
86
+ const displayResponse = (response, options) => {
87
+ const { task = "help", quiet = false } = options;
88
+ let content = "";
89
+ if (typeof response === "string") {
90
+ content = response;
91
+ } else if (response.choices?.[0]?.message?.content) {
92
+ content = response.choices[0].message.content;
93
+ } else if (response.content) {
94
+ content = response.content;
95
+ } else {
96
+ content = "No response received from AI model";
97
+ }
98
+ const cleanedContent = cleanResponse(content, options);
99
+ switch (task) {
100
+ case "generate":
101
+ log("\nGenerated Code:\n", "success", quiet);
102
+ log(cleanedContent, "default", quiet);
103
+ break;
104
+ case "explain":
105
+ log("\nCode Explanation:\n", "success", quiet);
106
+ log(cleanedContent, "default", quiet);
107
+ break;
108
+ case "test":
109
+ log("\nGenerated Tests:\n", "success", quiet);
110
+ log(cleanedContent, "default", quiet);
111
+ break;
112
+ case "optimize":
113
+ log("\nOptimization Suggestions:\n", "success", quiet);
114
+ log(cleanedContent, "default", quiet);
115
+ break;
116
+ default:
117
+ log("\nAI Response:\n", "success", quiet);
118
+ log(cleanedContent, "default", quiet);
119
+ break;
120
+ }
121
+ };
122
+ const cleanResponse = (content, options) => {
123
+ const { prompt = "", task = "help" } = options;
124
+ if (!content) {
125
+ return content;
126
+ }
127
+ let cleanedContent = content;
128
+ const taskInstructions = {
129
+ generate: "Generate code according to the following request. Make sure it follows best practices and is well documented:",
130
+ explain: "Explain the following code in detail, including any patterns, potential issues, and improvement suggestions:",
131
+ test: "Generate comprehensive unit tests for the following code:",
132
+ optimize: "Analyze the following code/configuration and suggest optimization improvements:",
133
+ help: "Provide guidance on the following development question:",
134
+ ask: "Provide guidance on the following development question:",
135
+ analyze: "Analyze the following code:"
136
+ };
137
+ const instruction = taskInstructions[task] || "";
138
+ if (instruction && cleanedContent.includes(instruction)) {
139
+ cleanedContent = cleanedContent.replace(instruction, "").trim();
140
+ }
141
+ if (prompt && cleanedContent.includes(prompt)) {
142
+ cleanedContent = cleanedContent.replace(prompt, "").trim();
143
+ }
144
+ if (cleanedContent.includes("===CONTEXT===")) {
145
+ cleanedContent = cleanedContent.split("===CONTEXT===")[0].trim();
146
+ }
147
+ if (!cleanedContent) {
148
+ return content;
149
+ }
150
+ return cleanedContent;
151
+ };
152
+ const getProviderAuth = (provider) => {
153
+ if (process.cwd().includes("reaktor")) {
154
+ return "cursor-auth";
155
+ }
156
+ if (process.env.AI_API_KEY) {
157
+ return process.env.AI_API_KEY;
158
+ }
159
+ if (provider === "none" && process.env.CURSOR_IDE === "true") {
160
+ return "cursor-auth";
161
+ }
162
+ switch (provider) {
163
+ case "openai":
164
+ return process.env.OPENAI_API_KEY;
165
+ case "anthropic":
166
+ return process.env.ANTHROPIC_API_KEY;
167
+ case "cursor":
168
+ return "cursor-auth";
169
+ case "copilot":
170
+ return process.env.GITHUB_TOKEN;
171
+ case "none":
172
+ return void 0;
173
+ default:
174
+ return void 0;
175
+ }
176
+ };
177
+ const detectCursorIDE = () => {
178
+ if (process.env.CURSOR_IDE === "true") {
179
+ return true;
180
+ }
181
+ const possibleCursorSignals = [
182
+ process.env.CURSOR_EXTENSION === "true",
183
+ process.env.CURSOR_TERMINAL === "true",
184
+ process.env.CURSOR_APP === "true",
185
+ process.env.PATH?.includes("cursor"),
186
+ !!process.env.CURSOR_SESSION_ID
187
+ ];
188
+ const isCursorIDE = possibleCursorSignals.some((signal) => signal);
189
+ if (isCursorIDE) {
190
+ process.env.CURSOR_IDE = "true";
191
+ }
192
+ return isCursorIDE;
193
+ };
194
+ const aiFunction = async (options) => {
195
+ try {
196
+ const config = LexConfig.config || {};
197
+ const aiConfig = config.ai || {};
198
+ const provider = options.provider || aiConfig.provider || "none";
199
+ if (provider === "none" && !process.env.CURSOR_EXTENSION) {
200
+ log(`${chalk.red("Error:")} No AI provider configured.`, "error");
201
+ return { error: "No AI provider configured" };
202
+ }
203
+ const task = options.task || "ask";
204
+ const validTasks = ["explain", "generate", "test", "analyze", "ask"];
205
+ if (!validTasks.includes(task)) {
206
+ log(`${chalk.red("Error:")} Invalid task "${task}". Valid tasks are: ${validTasks.join(", ")}`, "error");
207
+ return { error: `Invalid task "${task}"` };
208
+ }
209
+ const { prompt } = options;
210
+ if (!prompt) {
211
+ log(`${chalk.red("Error:")} No prompt provided. Use --prompt "Your prompt here"`, "error");
212
+ return { error: "No prompt provided" };
213
+ }
214
+ let context = "";
215
+ if (options.file) {
216
+ try {
217
+ const fs = await import("fs/promises");
218
+ const glob = await import("glob");
219
+ const files = await glob.glob(options.file);
220
+ if (files.length === 0) {
221
+ log(`${chalk.yellow("Warning:")} No files found matching "${options.file}"`, "warning");
222
+ } else {
223
+ for (const file of files) {
224
+ const content = await fs.readFile(file, "utf8");
225
+ context += `
226
+ ===FILE: ${file}===
227
+ ${content}
228
+ `;
229
+ }
230
+ }
231
+ } catch (error) {
232
+ log(`${chalk.yellow("Warning:")} Error reading file: ${error.message}`, "warning");
233
+ }
234
+ }
235
+ if (options.dir) {
236
+ try {
237
+ const { execaSync } = await import("execa");
238
+ const result = execaSync("find", [options.dir, "-type", "f", "|", "sort"]);
239
+ context += `
240
+ ===Project structure:===
241
+ ${result.stdout}
242
+ `;
243
+ } catch (error) {
244
+ log(`${chalk.yellow("Warning:")} Error reading directory: ${error.message}`, "warning");
245
+ }
246
+ }
247
+ let formattedPrompt = "";
248
+ switch (task) {
249
+ case "explain":
250
+ formattedPrompt = `Explain the following code:
251
+ ${prompt}`;
252
+ break;
253
+ case "generate":
254
+ formattedPrompt = `Generate code according to the following request:
255
+ ${prompt}`;
256
+ break;
257
+ case "test":
258
+ formattedPrompt = `Generate comprehensive unit tests:
259
+ ${prompt}`;
260
+ break;
261
+ case "analyze":
262
+ formattedPrompt = `Analyze the following code:
263
+ ${prompt}`;
264
+ break;
265
+ case "ask":
266
+ formattedPrompt = `Provide guidance on the following development question:
267
+ ${prompt}`;
268
+ break;
269
+ }
270
+ if (context) {
271
+ formattedPrompt += `
272
+ ===CONTEXT===
273
+ ${context}`;
274
+ }
275
+ if ((provider === "cursor" || process.env.CURSOR_EXTENSION) && task === "generate") {
276
+ log("Using Cursor IDE for code generation...", "info");
277
+ log("Note: For full code generation capabilities, please use Cursor IDE directly with Cmd+L or Cmd+K.", "info");
278
+ log("The CLI integration has limited capabilities for code generation.", "warning");
279
+ } else if (provider === "cursor" || process.env.CURSOR_EXTENSION) {
280
+ log("Using Cursor IDE for AI assistance...", "info");
281
+ log("Note: This is a limited integration. For full AI capabilities, use Cursor IDE directly.", "info");
282
+ } else {
283
+ log(`Using ${provider} for AI assistance...`, "info");
284
+ }
285
+ const response = await callAIService(formattedPrompt, options.quiet || false);
286
+ log(`
287
+ ${response}`, "success");
288
+ return { response };
289
+ } catch (error) {
290
+ log(`${chalk.red("Error:")} ${error.message}`, "error");
291
+ return { error: error.message };
292
+ }
293
+ };
294
+ const ai = new Command("ai").description("Use AI to help with development tasks").option("--provider <provider>", "AI provider to use (openai, anthropic, cursor)").option("--task <task>", "Task to perform (explain, generate, test, analyze, ask)").option("--prompt <prompt>", "Prompt to send to AI").option("--file <file>", "File to analyze").option("--dir <dir>", "Directory to analyze").action(async (options) => {
295
+ await aiFunction(options);
296
+ });
297
+ var ai_default = ai;
298
+ export {
299
+ ai,
300
+ aiFunction,
301
+ ai_default as default
302
+ };
303
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2NvbW1hbmRzL2FpL2FpLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIENvcHlyaWdodCAoYykgMjAxOC1QcmVzZW50LCBOaXRyb2dlbiBMYWJzLCBJbmMuXG4gKiBDb3B5cmlnaHRzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS4gU2VlIHRoZSBhY2NvbXBhbnlpbmcgTElDRU5TRSBmaWxlIGZvciB0ZXJtcy5cbiAqL1xuaW1wb3J0IGNoYWxrIGZyb20gJ2NoYWxrJztcbmltcG9ydCB7Q29tbWFuZH0gZnJvbSAnY29tbWFuZGVyJztcbmltcG9ydCB7cmVhZEZpbGVTeW5jfSBmcm9tICdmcyc7XG5pbXBvcnQge3N5bmMgYXMgZ2xvYlN5bmN9IGZyb20gJ2dsb2InO1xuXG5pbXBvcnQge0xleENvbmZpZ30gZnJvbSAnLi4vLi4vTGV4Q29uZmlnLmpzJztcbmltcG9ydCB7Y2FsbEFJU2VydmljZX0gZnJvbSAnLi4vLi4vdXRpbHMvYWlTZXJ2aWNlLmpzJztcbmltcG9ydCB7bG9nfSBmcm9tICcuLi8uLi91dGlscy9sb2cuanMnO1xuXG5pZihwcm9jZXNzLmVudi5DVVJTT1JfRVhURU5TSU9OID09PSAndHJ1ZScgfHxcbiAgcHJvY2Vzcy5lbnYuQ1VSU09SX1RFUk1JTkFMID09PSAndHJ1ZScgfHxcbiAgcHJvY2Vzcy5lbnYuQ1VSU09SX0FQUCA9PT0gJ3RydWUnIHx8XG4gIHByb2Nlc3MuZW52LlBBVEg/LmluY2x1ZGVzKCdjdXJzb3InKSB8fFxuICBwcm9jZXNzLmVudi5DVVJTT1JfU0VTU0lPTl9JRCkge1xuICBwcm9jZXNzLmVudi5DVVJTT1JfSURFID0gJ3RydWUnO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFJT3B0aW9ucyB7XG4gIHJlYWRvbmx5IGNsaU5hbWU/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGNvbnRleHQ/OiBib29sZWFuO1xuICByZWFkb25seSBmaWxlPzogc3RyaW5nO1xuICByZWFkb25seSBsZXhDb25maWc/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IG1vZGVsPzogc3RyaW5nO1xuICByZWFkb25seSBwcm9tcHQ/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHF1aWV0PzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgdGFzaz86ICdnZW5lcmF0ZScgfCAnZXhwbGFpbicgfCAndGVzdCcgfCAnb3B0aW1pemUnIHwgJ2hlbHAnIHwgJ2FzaycgfCAnYW5hbHl6ZSc7XG4gIHJlYWRvbmx5IGRlYnVnPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgcHJvdmlkZXI/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGRpcj86IHN0cmluZztcbn1cblxuY29uc3QgZ2V0RmlsZUNvbnRleHQgPSAoZmlsZVBhdGg6IHN0cmluZyk6IHN0cmluZyA9PiB7XG4gIHRyeSB7XG4gICAgY29uc3QgY29udGVudCA9IHJlYWRGaWxlU3luYyhmaWxlUGF0aCwgJ3V0Zi04Jyk7XG4gICAgcmV0dXJuIGBGaWxlOiAke2ZpbGVQYXRofVxcblxcbiR7Y29udGVudH1gO1xuICB9IGNhdGNoIChfZXJyb3IpIHtcbiAgICByZXR1cm4gYEVycm9yIHJlYWRpbmcgZmlsZTogJHtmaWxlUGF0aH1gO1xuICB9XG59O1xuXG5jb25zdCBnZXRQcm9qZWN0Q29udGV4dCA9IGFzeW5jIChvcHRpb25zOiBBSU9wdGlvbnMpOiBQcm9taXNlPHN0cmluZz4gPT4ge1xuICBjb25zdCB7ZmlsZSwgdGFzaywgY29udGV4dH0gPSBvcHRpb25zO1xuXG4gIGlmKGNvbnRleHQgPT09IGZhbHNlKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgbGV0IHByb2plY3RDb250ZXh0ID0gJyc7XG5cbiAgaWYoZmlsZSkge1xuICAgIHByb2plY3RDb250ZXh0ICs9IGdldEZpbGVDb250ZXh0KGZpbGUpO1xuICB9XG5cbiAgc3dpdGNoKHRhc2spIHtcbiAgICBjYXNlICdnZW5lcmF0ZSc6XG4gICAgICBjb25zdCBmaWxlcyA9IGdsb2JTeW5jKCdzcmMvKiovKi57dHMsdHN4LGpzLGpzeH0nLCB7XG4gICAgICAgIGN3ZDogcHJvY2Vzcy5jd2QoKSxcbiAgICAgICAgaWdub3JlOiBbJyoqL25vZGVfbW9kdWxlcy8qKicsICcqKi9kaXN0LyoqJywgJyoqLyoudGVzdC4qJywgJyoqLyouc3BlYy4qJ10sXG4gICAgICAgIG1heERlcHRoOiAzXG4gICAgICB9KTtcbiAgICAgIHByb2plY3RDb250ZXh0ICs9IGBcXG5cXG5Qcm9qZWN0IHN0cnVjdHVyZTpcXG4ke2ZpbGVzLmpvaW4oJ1xcbicpfWA7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3Rlc3QnOlxuICAgICAgaWYoZmlsZSkge1xuICAgICAgICBjb25zdCB0ZXN0Q29uZmlnID0gZ2V0RmlsZUNvbnRleHQoJ2plc3QuY29uZmlnLmpzJyk7XG4gICAgICAgIHByb2plY3RDb250ZXh0ICs9IGBcXG5cXG5UZXN0IGNvbmZpZ3VyYXRpb246XFxuJHt0ZXN0Q29uZmlnfWA7XG4gICAgICB9XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ29wdGltaXplJzpcbiAgICAgIGNvbnN0IHdlYnBhY2tDb25maWcgPSBnZXRGaWxlQ29udGV4dCgnd2VicGFjay5jb25maWcuanMnKTtcbiAgICAgIHByb2plY3RDb250ZXh0ICs9IGBcXG5cXG5XZWJwYWNrIGNvbmZpZ3VyYXRpb246XFxuJHt3ZWJwYWNrQ29uZmlnfWA7XG4gICAgICBicmVhaztcblxuICAgIGRlZmF1bHQ6XG4gICAgICBicmVhaztcbiAgfVxuXG4gIHJldHVybiBwcm9qZWN0Q29udGV4dDtcbn07XG5cbmNvbnN0IGNvbnN0cnVjdFByb21wdCA9IChvcHRpb25zOiBBSU9wdGlvbnMsIHByb2plY3RDb250ZXh0OiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICBjb25zdCB7dGFzayA9ICdoZWxwJywgcHJvbXB0ID0gJyd9ID0gb3B0aW9ucztcblxuICBjb25zdCB0YXNrSW5zdHJ1Y3Rpb25zOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAgIGdlbmVyYXRlOiAnR2VuZXJhdGUgY29kZSBhY2NvcmRpbmcgdG8gdGhlIGZvbGxvd2luZyByZXF1ZXN0LiBNYWtlIHN1cmUgaXQgZm9sbG93cyBiZXN0IHByYWN0aWNlcyBhbmQgaXMgd2VsbCBkb2N1bWVudGVkOicsXG4gICAgZXhwbGFpbjogJ0V4cGxhaW4gdGhlIGZvbGxvd2luZyBjb2RlIGluIGRldGFpbCwgaW5jbHVkaW5nIGFueSBwYXR0ZXJucywgcG90ZW50aWFsIGlzc3VlcywgYW5kIGltcHJvdmVtZW50IHN1Z2dlc3Rpb25zOicsXG4gICAgdGVzdDogJ0dlbmVyYXRlIGNvbXByZWhlbnNpdmUgdW5pdCB0ZXN0cyBmb3IgdGhlIGZvbGxvd2luZyBjb2RlOicsXG4gICAgb3B0aW1pemU6ICdBbmFseXplIHRoZSBmb2xsb3dpbmcgY29kZS9jb25maWd1cmF0aW9uIGFuZCBzdWdnZXN0IG9wdGltaXphdGlvbiBpbXByb3ZlbWVudHM6JyxcbiAgICBoZWxwOiAnUHJvdmlkZSBndWlkYW5jZSBvbiB0aGUgZm9sbG93aW5nIGRldmVsb3BtZW50IHF1ZXN0aW9uOicsXG4gICAgYXNrOiAnUHJvdmlkZSBndWlkYW5jZSBvbiB0aGUgZm9sbG93aW5nIGRldmVsb3BtZW50IHF1ZXN0aW9uOicsXG4gICAgYW5hbHl6ZTogJ0FuYWx5emUgdGhlIGZvbGxvd2luZyBjb2RlOidcbiAgfTtcblxuICBjb25zdCB0YXNrSW5zdHJ1Y3Rpb24gPSB0YXNrSW5zdHJ1Y3Rpb25zW3Rhc2tdIHx8IHRhc2tJbnN0cnVjdGlvbnMuaGVscDtcblxuICBsZXQgZnVsbFByb21wdCA9IGAke3Rhc2tJbnN0cnVjdGlvbn1cXG5cXG4ke3Byb21wdH1gO1xuXG4gIGlmKHByb2plY3RDb250ZXh0KSB7XG4gICAgZnVsbFByb21wdCArPSBgXFxuXFxuPT09Q09OVEVYVD09PVxcbiR7cHJvamVjdENvbnRleHR9YDtcbiAgfVxuXG4gIHJldHVybiBmdWxsUHJvbXB0O1xufTtcblxuY29uc3QgZGlzcGxheVJlc3BvbnNlID0gKHJlc3BvbnNlOiBhbnksIG9wdGlvbnM6IEFJT3B0aW9ucyk6IHZvaWQgPT4ge1xuICBjb25zdCB7dGFzayA9ICdoZWxwJywgcXVpZXQgPSBmYWxzZX0gPSBvcHRpb25zO1xuXG4gIGxldCBjb250ZW50ID0gJyc7XG5cbiAgaWYodHlwZW9mIHJlc3BvbnNlID09PSAnc3RyaW5nJykge1xuICAgIGNvbnRlbnQgPSByZXNwb25zZTtcbiAgfSBlbHNlIGlmKHJlc3BvbnNlLmNob2ljZXM/LlswXT8ubWVzc2FnZT8uY29udGVudCkge1xuICAgIGNvbnRlbnQgPSByZXNwb25zZS5jaG9pY2VzWzBdLm1lc3NhZ2UuY29udGVudDtcbiAgfSBlbHNlIGlmKHJlc3BvbnNlLmNvbnRlbnQpIHtcbiAgICBjb250ZW50ID0gcmVzcG9uc2UuY29udGVudDtcbiAgfSBlbHNlIHtcbiAgICBjb250ZW50ID0gJ05vIHJlc3BvbnNlIHJlY2VpdmVkIGZyb20gQUkgbW9kZWwnO1xuICB9XG5cbiAgY29uc3QgY2xlYW5lZENvbnRlbnQgPSBjbGVhblJlc3BvbnNlKGNvbnRlbnQsIG9wdGlvbnMpO1xuXG4gIHN3aXRjaCh0YXNrKSB7XG4gICAgY2FzZSAnZ2VuZXJhdGUnOlxuICAgICAgbG9nKCdcXG5HZW5lcmF0ZWQgQ29kZTpcXG4nLCAnc3VjY2VzcycsIHF1aWV0KTtcbiAgICAgIGxvZyhjbGVhbmVkQ29udGVudCwgJ2RlZmF1bHQnLCBxdWlldCk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ2V4cGxhaW4nOlxuICAgICAgbG9nKCdcXG5Db2RlIEV4cGxhbmF0aW9uOlxcbicsICdzdWNjZXNzJywgcXVpZXQpO1xuICAgICAgbG9nKGNsZWFuZWRDb250ZW50LCAnZGVmYXVsdCcsIHF1aWV0KTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAndGVzdCc6XG4gICAgICBsb2coJ1xcbkdlbmVyYXRlZCBUZXN0czpcXG4nLCAnc3VjY2VzcycsIHF1aWV0KTtcbiAgICAgIGxvZyhjbGVhbmVkQ29udGVudCwgJ2RlZmF1bHQnLCBxdWlldCk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ29wdGltaXplJzpcbiAgICAgIGxvZygnXFxuT3B0aW1pemF0aW9uIFN1Z2dlc3Rpb25zOlxcbicsICdzdWNjZXNzJywgcXVpZXQpO1xuICAgICAgbG9nKGNsZWFuZWRDb250ZW50LCAnZGVmYXVsdCcsIHF1aWV0KTtcbiAgICAgIGJyZWFrO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIGxvZygnXFxuQUkgUmVzcG9uc2U6XFxuJywgJ3N1Y2Nlc3MnLCBxdWlldCk7XG4gICAgICBsb2coY2xlYW5lZENvbnRlbnQsICdkZWZhdWx0JywgcXVpZXQpO1xuICAgICAgYnJlYWs7XG4gIH1cbn07XG5cbmNvbnN0IGNsZWFuUmVzcG9uc2UgPSAoY29udGVudDogc3RyaW5nLCBvcHRpb25zOiBBSU9wdGlvbnMpOiBzdHJpbmcgPT4ge1xuICBjb25zdCB7cHJvbXB0ID0gJycsIHRhc2sgPSAnaGVscCd9ID0gb3B0aW9ucztcblxuICBpZighY29udGVudCkge1xuICAgIHJldHVybiBjb250ZW50O1xuICB9XG5cbiAgbGV0IGNsZWFuZWRDb250ZW50ID0gY29udGVudDtcblxuICBjb25zdCB0YXNrSW5zdHJ1Y3Rpb25zOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAgIGdlbmVyYXRlOiAnR2VuZXJhdGUgY29kZSBhY2NvcmRpbmcgdG8gdGhlIGZvbGxvd2luZyByZXF1ZXN0LiBNYWtlIHN1cmUgaXQgZm9sbG93cyBiZXN0IHByYWN0aWNlcyBhbmQgaXMgd2VsbCBkb2N1bWVudGVkOicsXG4gICAgZXhwbGFpbjogJ0V4cGxhaW4gdGhlIGZvbGxvd2luZyBjb2RlIGluIGRldGFpbCwgaW5jbHVkaW5nIGFueSBwYXR0ZXJucywgcG90ZW50aWFsIGlzc3VlcywgYW5kIGltcHJvdmVtZW50IHN1Z2dlc3Rpb25zOicsXG4gICAgdGVzdDogJ0dlbmVyYXRlIGNvbXByZWhlbnNpdmUgdW5pdCB0ZXN0cyBmb3IgdGhlIGZvbGxvd2luZyBjb2RlOicsXG4gICAgb3B0aW1pemU6ICdBbmFseXplIHRoZSBmb2xsb3dpbmcgY29kZS9jb25maWd1cmF0aW9uIGFuZCBzdWdnZXN0IG9wdGltaXphdGlvbiBpbXByb3ZlbWVudHM6JyxcbiAgICBoZWxwOiAnUHJvdmlkZSBndWlkYW5jZSBvbiB0aGUgZm9sbG93aW5nIGRldmVsb3BtZW50IHF1ZXN0aW9uOicsXG4gICAgYXNrOiAnUHJvdmlkZSBndWlkYW5jZSBvbiB0aGUgZm9sbG93aW5nIGRldmVsb3BtZW50IHF1ZXN0aW9uOicsXG4gICAgYW5hbHl6ZTogJ0FuYWx5emUgdGhlIGZvbGxvd2luZyBjb2RlOidcbiAgfTtcblxuICBjb25zdCBpbnN0cnVjdGlvbiA9IHRhc2tJbnN0cnVjdGlvbnNbdGFza10gfHwgJyc7XG5cbiAgaWYoaW5zdHJ1Y3Rpb24gJiYgY2xlYW5lZENvbnRlbnQuaW5jbHVkZXMoaW5zdHJ1Y3Rpb24pKSB7XG4gICAgY2xlYW5lZENvbnRlbnQgPSBjbGVhbmVkQ29udGVudC5yZXBsYWNlKGluc3RydWN0aW9uLCAnJykudHJpbSgpO1xuICB9XG5cbiAgaWYocHJvbXB0ICYmIGNsZWFuZWRDb250ZW50LmluY2x1ZGVzKHByb21wdCkpIHtcbiAgICBjbGVhbmVkQ29udGVudCA9IGNsZWFuZWRDb250ZW50LnJlcGxhY2UocHJvbXB0LCAnJykudHJpbSgpO1xuICB9XG5cbiAgaWYoY2xlYW5lZENvbnRlbnQuaW5jbHVkZXMoJz09PUNPTlRFWFQ9PT0nKSkge1xuICAgIGNsZWFuZWRDb250ZW50ID0gY2xlYW5lZENvbnRlbnQuc3BsaXQoJz09PUNPTlRFWFQ9PT0nKVswXS50cmltKCk7XG4gIH1cblxuICBpZighY2xlYW5lZENvbnRlbnQpIHtcbiAgICByZXR1cm4gY29udGVudDtcbiAgfVxuXG4gIHJldHVybiBjbGVhbmVkQ29udGVudDtcbn07XG5cbmNvbnN0IGdldFByb3ZpZGVyQXV0aCA9IChwcm92aWRlcjogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkID0+IHtcbiAgaWYocHJvY2Vzcy5jd2QoKS5pbmNsdWRlcygncmVha3RvcicpKSB7XG4gICAgcmV0dXJuICdjdXJzb3ItYXV0aCc7XG4gIH1cblxuICBpZihwcm9jZXNzLmVudi5BSV9BUElfS0VZKSB7XG4gICAgcmV0dXJuIHByb2Nlc3MuZW52LkFJX0FQSV9LRVk7XG4gIH1cblxuICBpZihwcm92aWRlciA9PT0gJ25vbmUnICYmIHByb2Nlc3MuZW52LkNVUlNPUl9JREUgPT09ICd0cnVlJykge1xuICAgIHJldHVybiAnY3Vyc29yLWF1dGgnO1xuICB9XG5cbiAgc3dpdGNoKHByb3ZpZGVyKSB7XG4gICAgY2FzZSAnb3BlbmFpJzpcbiAgICAgIHJldHVybiBwcm9jZXNzLmVudi5PUEVOQUlfQVBJX0tFWTtcbiAgICBjYXNlICdhbnRocm9waWMnOlxuICAgICAgcmV0dXJuIHByb2Nlc3MuZW52LkFOVEhST1BJQ19BUElfS0VZO1xuICAgIGNhc2UgJ2N1cnNvcic6XG4gICAgICByZXR1cm4gJ2N1cnNvci1hdXRoJztcbiAgICBjYXNlICdjb3BpbG90JzpcbiAgICAgIHJldHVybiBwcm9jZXNzLmVudi5HSVRIVUJfVE9LRU47XG4gICAgY2FzZSAnbm9uZSc6XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59O1xuXG5jb25zdCBkZXRlY3RDdXJzb3JJREUgPSAoKTogYm9vbGVhbiA9PiB7XG4gIGlmKHByb2Nlc3MuZW52LkNVUlNPUl9JREUgPT09ICd0cnVlJykge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgY29uc3QgcG9zc2libGVDdXJzb3JTaWduYWxzID0gW1xuICAgIHByb2Nlc3MuZW52LkNVUlNPUl9FWFRFTlNJT04gPT09ICd0cnVlJyxcbiAgICBwcm9jZXNzLmVudi5DVVJTT1JfVEVSTUlOQUwgPT09ICd0cnVlJyxcbiAgICBwcm9jZXNzLmVudi5DVVJTT1JfQVBQID09PSAndHJ1ZScsXG4gICAgcHJvY2Vzcy5lbnYuUEFUSD8uaW5jbHVkZXMoJ2N1cnNvcicpLFxuICAgICEhcHJvY2Vzcy5lbnYuQ1VSU09SX1NFU1NJT05fSURcbiAgXTtcblxuICBjb25zdCBpc0N1cnNvcklERSA9IHBvc3NpYmxlQ3Vyc29yU2lnbmFscy5zb21lKChzaWduYWwpID0+IHNpZ25hbCk7XG5cbiAgaWYoaXNDdXJzb3JJREUpIHtcbiAgICBwcm9jZXNzLmVudi5DVVJTT1JfSURFID0gJ3RydWUnO1xuICB9XG5cbiAgcmV0dXJuIGlzQ3Vyc29ySURFO1xufTtcblxuZXhwb3J0IGNvbnN0IGFpRnVuY3Rpb24gPSBhc3luYyAob3B0aW9uczogQUlPcHRpb25zKTogUHJvbWlzZTxhbnk+ID0+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCBjb25maWcgPSBMZXhDb25maWcuY29uZmlnIHx8IHt9O1xuICAgIGNvbnN0IGFpQ29uZmlnID0gY29uZmlnLmFpIHx8IHt9O1xuICAgIGNvbnN0IHByb3ZpZGVyID0gb3B0aW9ucy5wcm92aWRlciB8fCBhaUNvbmZpZy5wcm92aWRlciB8fCAnbm9uZSc7XG5cbiAgICBpZihwcm92aWRlciA9PT0gJ25vbmUnICYmICFwcm9jZXNzLmVudi5DVVJTT1JfRVhURU5TSU9OKSB7XG4gICAgICBsb2coYCR7Y2hhbGsucmVkKCdFcnJvcjonKX0gTm8gQUkgcHJvdmlkZXIgY29uZmlndXJlZC5gLCAnZXJyb3InKTtcbiAgICAgIHJldHVybiB7ZXJyb3I6ICdObyBBSSBwcm92aWRlciBjb25maWd1cmVkJ307XG4gICAgfVxuXG4gICAgY29uc3QgdGFzayA9IG9wdGlvbnMudGFzayB8fCAnYXNrJztcbiAgICBjb25zdCB2YWxpZFRhc2tzID0gWydleHBsYWluJywgJ2dlbmVyYXRlJywgJ3Rlc3QnLCAnYW5hbHl6ZScsICdhc2snXTtcblxuICAgIGlmKCF2YWxpZFRhc2tzLmluY2x1ZGVzKHRhc2spKSB7XG4gICAgICBsb2coYCR7Y2hhbGsucmVkKCdFcnJvcjonKX0gSW52YWxpZCB0YXNrIFwiJHt0YXNrfVwiLiBWYWxpZCB0YXNrcyBhcmU6ICR7dmFsaWRUYXNrcy5qb2luKCcsICcpfWAsICdlcnJvcicpO1xuICAgICAgcmV0dXJuIHtlcnJvcjogYEludmFsaWQgdGFzayBcIiR7dGFza31cImB9O1xuICAgIH1cblxuICAgIGNvbnN0IHtwcm9tcHR9ID0gb3B0aW9ucztcblxuICAgIGlmKCFwcm9tcHQpIHtcbiAgICAgIGxvZyhgJHtjaGFsay5yZWQoJ0Vycm9yOicpfSBObyBwcm9tcHQgcHJvdmlkZWQuIFVzZSAtLXByb21wdCBcIllvdXIgcHJvbXB0IGhlcmVcImAsICdlcnJvcicpO1xuICAgICAgcmV0dXJuIHtlcnJvcjogJ05vIHByb21wdCBwcm92aWRlZCd9O1xuICAgIH1cblxuICAgIGxldCBjb250ZXh0ID0gJyc7XG5cbiAgICBpZihvcHRpb25zLmZpbGUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGZzID0gYXdhaXQgaW1wb3J0KCdmcy9wcm9taXNlcycpO1xuICAgICAgICBjb25zdCBnbG9iID0gYXdhaXQgaW1wb3J0KCdnbG9iJyk7XG4gICAgICAgIGNvbnN0IGZpbGVzID0gYXdhaXQgZ2xvYi5nbG9iKG9wdGlvbnMuZmlsZSk7XG5cbiAgICAgICAgaWYoZmlsZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgbG9nKGAke2NoYWxrLnllbGxvdygnV2FybmluZzonKX0gTm8gZmlsZXMgZm91bmQgbWF0Y2hpbmcgXCIke29wdGlvbnMuZmlsZX1cImAsICd3YXJuaW5nJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZm9yKGNvbnN0IGZpbGUgb2YgZmlsZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbnRlbnQgPSBhd2FpdCBmcy5yZWFkRmlsZShmaWxlLCAndXRmOCcpO1xuICAgICAgICAgICAgY29udGV4dCArPSBgXFxuPT09RklMRTogJHtmaWxlfT09PVxcbiR7Y29udGVudH1cXG5gO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgbG9nKGAke2NoYWxrLnllbGxvdygnV2FybmluZzonKX0gRXJyb3IgcmVhZGluZyBmaWxlOiAke2Vycm9yLm1lc3NhZ2V9YCwgJ3dhcm5pbmcnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZihvcHRpb25zLmRpcikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3Qge2V4ZWNhU3luY30gPSBhd2FpdCBpbXBvcnQoJ2V4ZWNhJyk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGV4ZWNhU3luYygnZmluZCcsIFtvcHRpb25zLmRpciwgJy10eXBlJywgJ2YnLCAnfCcsICdzb3J0J10pO1xuICAgICAgICBjb250ZXh0ICs9IGBcXG49PT1Qcm9qZWN0IHN0cnVjdHVyZTo9PT1cXG4ke3Jlc3VsdC5zdGRvdXR9XFxuYDtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGxvZyhgJHtjaGFsay55ZWxsb3coJ1dhcm5pbmc6Jyl9IEVycm9yIHJlYWRpbmcgZGlyZWN0b3J5OiAke2Vycm9yLm1lc3NhZ2V9YCwgJ3dhcm5pbmcnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBsZXQgZm9ybWF0dGVkUHJvbXB0ID0gJyc7XG5cbiAgICBzd2l0Y2godGFzaykge1xuICAgICAgY2FzZSAnZXhwbGFpbic6XG4gICAgICAgIGZvcm1hdHRlZFByb21wdCA9IGBFeHBsYWluIHRoZSBmb2xsb3dpbmcgY29kZTpcXG4ke3Byb21wdH1gO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2dlbmVyYXRlJzpcbiAgICAgICAgZm9ybWF0dGVkUHJvbXB0ID0gYEdlbmVyYXRlIGNvZGUgYWNjb3JkaW5nIHRvIHRoZSBmb2xsb3dpbmcgcmVxdWVzdDpcXG4ke3Byb21wdH1gO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3Rlc3QnOlxuICAgICAgICBmb3JtYXR0ZWRQcm9tcHQgPSBgR2VuZXJhdGUgY29tcHJlaGVuc2l2ZSB1bml0IHRlc3RzOlxcbiR7cHJvbXB0fWA7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYW5hbHl6ZSc6XG4gICAgICAgIGZvcm1hdHRlZFByb21wdCA9IGBBbmFseXplIHRoZSBmb2xsb3dpbmcgY29kZTpcXG4ke3Byb21wdH1gO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2Fzayc6XG4gICAgICAgIGZvcm1hdHRlZFByb21wdCA9IGBQcm92aWRlIGd1aWRhbmNlIG9uIHRoZSBmb2xsb3dpbmcgZGV2ZWxvcG1lbnQgcXVlc3Rpb246XFxuJHtwcm9tcHR9YDtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgaWYoY29udGV4dCkge1xuICAgICAgZm9ybWF0dGVkUHJvbXB0ICs9IGBcXG49PT1DT05URVhUPT09XFxuJHtjb250ZXh0fWA7XG4gICAgfVxuXG4gICAgaWYoKHByb3ZpZGVyID09PSAnY3Vyc29yJyB8fCBwcm9jZXNzLmVudi5DVVJTT1JfRVhURU5TSU9OKSAmJiB0YXNrID09PSAnZ2VuZXJhdGUnKSB7XG4gICAgICBsb2coJ1VzaW5nIEN1cnNvciBJREUgZm9yIGNvZGUgZ2VuZXJhdGlvbi4uLicsICdpbmZvJyk7XG4gICAgICBsb2coJ05vdGU6IEZvciBmdWxsIGNvZGUgZ2VuZXJhdGlvbiBjYXBhYmlsaXRpZXMsIHBsZWFzZSB1c2UgQ3Vyc29yIElERSBkaXJlY3RseSB3aXRoIENtZCtMIG9yIENtZCtLLicsICdpbmZvJyk7XG4gICAgICBsb2coJ1RoZSBDTEkgaW50ZWdyYXRpb24gaGFzIGxpbWl0ZWQgY2FwYWJpbGl0aWVzIGZvciBjb2RlIGdlbmVyYXRpb24uJywgJ3dhcm5pbmcnKTtcbiAgICB9IGVsc2UgaWYocHJvdmlkZXIgPT09ICdjdXJzb3InIHx8IHByb2Nlc3MuZW52LkNVUlNPUl9FWFRFTlNJT04pIHtcbiAgICAgIGxvZygnVXNpbmcgQ3Vyc29yIElERSBmb3IgQUkgYXNzaXN0YW5jZS4uLicsICdpbmZvJyk7XG4gICAgICBsb2coJ05vdGU6IFRoaXMgaXMgYSBsaW1pdGVkIGludGVncmF0aW9uLiBGb3IgZnVsbCBBSSBjYXBhYmlsaXRpZXMsIHVzZSBDdXJzb3IgSURFIGRpcmVjdGx5LicsICdpbmZvJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxvZyhgVXNpbmcgJHtwcm92aWRlcn0gZm9yIEFJIGFzc2lzdGFuY2UuLi5gLCAnaW5mbycpO1xuICAgIH1cblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgY2FsbEFJU2VydmljZShmb3JtYXR0ZWRQcm9tcHQsIG9wdGlvbnMucXVpZXQgfHwgZmFsc2UpO1xuXG4gICAgbG9nKGBcXG4ke3Jlc3BvbnNlfWAsICdzdWNjZXNzJyk7XG5cbiAgICByZXR1cm4ge3Jlc3BvbnNlfTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBsb2coYCR7Y2hhbGsucmVkKCdFcnJvcjonKX0gJHtlcnJvci5tZXNzYWdlfWAsICdlcnJvcicpO1xuICAgIHJldHVybiB7ZXJyb3I6IGVycm9yLm1lc3NhZ2V9O1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgYWkgPSBuZXcgQ29tbWFuZCgnYWknKVxuICAuZGVzY3JpcHRpb24oJ1VzZSBBSSB0byBoZWxwIHdpdGggZGV2ZWxvcG1lbnQgdGFza3MnKVxuICAub3B0aW9uKCctLXByb3ZpZGVyIDxwcm92aWRlcj4nLCAnQUkgcHJvdmlkZXIgdG8gdXNlIChvcGVuYWksIGFudGhyb3BpYywgY3Vyc29yKScpXG4gIC5vcHRpb24oJy0tdGFzayA8dGFzaz4nLCAnVGFzayB0byBwZXJmb3JtIChleHBsYWluLCBnZW5lcmF0ZSwgdGVzdCwgYW5hbHl6ZSwgYXNrKScpXG4gIC5vcHRpb24oJy0tcHJvbXB0IDxwcm9tcHQ+JywgJ1Byb21wdCB0byBzZW5kIHRvIEFJJylcbiAgLm9wdGlvbignLS1maWxlIDxmaWxlPicsICdGaWxlIHRvIGFuYWx5emUnKVxuICAub3B0aW9uKCctLWRpciA8ZGlyPicsICdEaXJlY3RvcnkgdG8gYW5hbHl6ZScpXG4gIC5hY3Rpb24oYXN5bmMgKG9wdGlvbnM6IEFJT3B0aW9ucykgPT4ge1xuICAgIGF3YWl0IGFpRnVuY3Rpb24ob3B0aW9ucyk7XG4gIH0pO1xuXG5leHBvcnQgZGVmYXVsdCBh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
@@ -3,11 +3,14 @@ export interface BuildOptions {
3
3
  readonly analyze?: boolean;
4
4
  readonly bundler?: 'webpack' | 'esbuild';
5
5
  readonly cliName?: string;
6
+ readonly entry?: string;
6
7
  readonly format?: string;
7
8
  readonly outputPath?: string;
8
9
  readonly quiet?: boolean;
9
10
  readonly remove?: boolean;
10
11
  readonly sourcePath?: string;
12
+ readonly test?: boolean;
13
+ readonly translations?: boolean;
11
14
  readonly variables?: string;
12
15
  readonly watch?: boolean;
13
16
  }