@lenne.tech/cli 0.0.125 → 1.0.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 (46) hide show
  1. package/bin/lt +145 -14
  2. package/build/commands/claude/install-commands.js +332 -0
  3. package/build/commands/claude/install-skills.js +626 -0
  4. package/build/commands/config/config.js +25 -0
  5. package/build/commands/config/help.js +167 -0
  6. package/build/commands/config/init.js +143 -0
  7. package/build/commands/config/show.js +68 -0
  8. package/build/commands/server/add-property.js +163 -46
  9. package/build/commands/server/create.js +66 -4
  10. package/build/commands/server/module.js +133 -20
  11. package/build/commands/server/object.js +23 -15
  12. package/build/extensions/config.js +157 -0
  13. package/build/extensions/server.js +194 -63
  14. package/build/interfaces/lt-config.interface.js +3 -0
  15. package/build/templates/claude-commands/code-cleanup.md +82 -0
  16. package/build/templates/claude-commands/mr-description-clipboard.md +48 -0
  17. package/build/templates/claude-commands/mr-description.md +33 -0
  18. package/build/templates/claude-commands/sec-review.md +62 -0
  19. package/build/templates/claude-commands/skill-optimize.md +140 -0
  20. package/build/templates/claude-commands/test-generate.md +45 -0
  21. package/build/templates/claude-skills/lt-cli/SKILL.md +190 -259
  22. package/build/templates/claude-skills/lt-cli/examples.md +433 -203
  23. package/build/templates/claude-skills/lt-cli/reference.md +400 -226
  24. package/build/templates/claude-skills/nest-server-generator/SKILL.md +1891 -0
  25. package/build/templates/claude-skills/nest-server-generator/configuration.md +279 -0
  26. package/build/templates/claude-skills/nest-server-generator/declare-keyword-warning.md +124 -0
  27. package/build/templates/claude-skills/nest-server-generator/description-management.md +217 -0
  28. package/build/templates/claude-skills/nest-server-generator/examples.md +886 -0
  29. package/build/templates/claude-skills/nest-server-generator/quality-review.md +855 -0
  30. package/build/templates/claude-skills/nest-server-generator/reference.md +471 -0
  31. package/build/templates/claude-skills/nest-server-generator/security-rules.md +358 -0
  32. package/build/templates/claude-skills/story-tdd/SKILL.md +1173 -0
  33. package/build/templates/claude-skills/story-tdd/code-quality.md +266 -0
  34. package/build/templates/claude-skills/story-tdd/database-indexes.md +173 -0
  35. package/build/templates/claude-skills/story-tdd/examples.md +1332 -0
  36. package/build/templates/claude-skills/story-tdd/reference.md +1180 -0
  37. package/build/templates/claude-skills/story-tdd/security-review.md +299 -0
  38. package/build/templates/nest-server-module/inputs/template-create.input.ts.ejs +1 -3
  39. package/build/templates/nest-server-module/inputs/template.input.ts.ejs +1 -1
  40. package/build/templates/nest-server-module/template.controller.ts.ejs +24 -13
  41. package/build/templates/nest-server-module/template.model.ts.ejs +2 -2
  42. package/build/templates/nest-server-module/template.module.ts.ejs +4 -0
  43. package/build/templates/nest-server-module/template.service.ts.ejs +6 -6
  44. package/build/templates/nest-server-object/template.object.ts.ejs +2 -2
  45. package/package.json +13 -11
  46. package/build/commands/claude/install-skill.js +0 -93
package/bin/lt CHANGED
@@ -2,20 +2,151 @@
2
2
 
3
3
 
4
4
  /* tslint:disable */
5
- // check if we're running in dev mode
6
- var devMode = require('fs').existsSync(`${__dirname}/../src`);
7
- // or want to "force" running the compiled version with --compiled-build
8
- var wantsCompiled = process.argv.indexOf('--compiled-build') >= 0;
9
-
10
- if (wantsCompiled || !devMode) {
11
- // this runs from the compiled javascript source
12
- require(`${__dirname}/../build/cli`).run(process.argv);
13
- } else {
14
- // this runs from the typescript source (for dev only)
15
- // hook into ts-node so we can run typescript on the fly
16
- require('ts-node').register({ project: `${__dirname}/../tsconfig.json` });
17
- // run the CLI with the current process arguments
18
- require(`${__dirname}/../src/cli`).run(process.argv);
5
+
6
+ // Handle case where current working directory no longer exists
7
+ try {
8
+ process.cwd();
9
+ } catch (err) {
10
+ // Current directory doesn't exist - offer interactive solutions
11
+ var fs = require('fs');
12
+ var path = require('path');
13
+ var os = require('os');
14
+ var readline = require('readline');
15
+
16
+ console.error('\nError: Current working directory no longer exists.');
17
+ console.error('The directory you were in has been deleted or is no longer accessible.\n');
18
+
19
+ // Try to find the next existing parent directory
20
+ var originalPath = process.env.PWD || process.env.OLDPWD || '';
21
+ var parentDir = null;
22
+
23
+ if (originalPath) {
24
+ var testPath = path.dirname(originalPath);
25
+ while (testPath && testPath !== '/' && testPath !== '.') {
26
+ try {
27
+ if (fs.existsSync(testPath) && fs.statSync(testPath).isDirectory()) {
28
+ parentDir = testPath;
29
+ break;
30
+ }
31
+ } catch (e) {
32
+ // Continue searching
33
+ }
34
+ testPath = path.dirname(testPath);
35
+ }
36
+ }
37
+
38
+ // Build options
39
+ var options = [];
40
+ if (parentDir) {
41
+ options.push({ key: '1', label: 'Change to nearest existing parent directory: ' + parentDir, action: parentDir });
42
+ }
43
+ options.push({ key: parentDir ? '2' : '1', label: 'Change to home directory: ' + os.homedir(), action: os.homedir() });
44
+ options.push({ key: parentDir ? '3' : '2', label: 'Enter a custom directory path', action: 'custom' });
45
+ options.push({ key: parentDir ? '4' : '3', label: 'Cancel and exit', action: 'exit' });
46
+
47
+ // Display options
48
+ console.log('Please choose an option:\n');
49
+ options.forEach(function(opt) {
50
+ console.log(' ' + opt.key + ') ' + opt.label);
51
+ });
52
+ console.log('');
53
+
54
+ // Read user input
55
+ var rl = readline.createInterface({
56
+ input: process.stdin,
57
+ output: process.stdout
58
+ });
59
+
60
+ rl.question('Enter your choice: ', function(answer) {
61
+ var choice = options.find(function(opt) { return opt.key === answer.trim(); });
62
+
63
+ if (!choice) {
64
+ console.error('\nInvalid choice. Exiting.\n');
65
+ rl.close();
66
+ process.exit(1);
67
+ return;
68
+ }
69
+
70
+ if (choice.action === 'exit') {
71
+ console.log('\nCancelled.\n');
72
+ rl.close();
73
+ process.exit(0);
74
+ return;
75
+ }
76
+
77
+ if (choice.action === 'custom') {
78
+ rl.question('Enter directory path (absolute or relative to ' + (parentDir || os.homedir()) + '): ', function(customPath) {
79
+ var targetPath = customPath.trim();
80
+
81
+ // If relative path, resolve it relative to parent or home
82
+ if (!path.isAbsolute(targetPath)) {
83
+ targetPath = path.resolve(parentDir || os.homedir(), targetPath);
84
+ }
85
+
86
+ try {
87
+ if (!fs.existsSync(targetPath)) {
88
+ console.error('\nError: Directory does not exist: ' + targetPath + '\n');
89
+ rl.close();
90
+ process.exit(1);
91
+ return;
92
+ }
93
+
94
+ process.chdir(targetPath);
95
+ console.log('\nChanged to: ' + targetPath + '\n');
96
+ rl.close();
97
+ continueExecution();
98
+ } catch (e) {
99
+ console.error('\nError: Cannot change to directory: ' + targetPath);
100
+ console.error(e.message + '\n');
101
+ rl.close();
102
+ process.exit(1);
103
+ }
104
+ });
105
+ return;
106
+ }
107
+
108
+ // Change to selected directory
109
+ try {
110
+ process.chdir(choice.action);
111
+ console.log('\nChanged to: ' + choice.action + '\n');
112
+ rl.close();
113
+ continueExecution();
114
+ } catch (e) {
115
+ console.error('\nError: Cannot change to directory: ' + choice.action);
116
+ console.error(e.message + '\n');
117
+ rl.close();
118
+ process.exit(1);
119
+ }
120
+ });
121
+
122
+ // Function to continue CLI execution after directory change
123
+ function continueExecution() {
124
+ runCLI();
125
+ }
126
+
127
+ // Don't continue execution here - wait for user choice
128
+ return;
129
+ }
130
+
131
+ // Normal execution path
132
+ runCLI();
133
+
134
+ function runCLI() {
135
+ // check if we're running in dev mode
136
+ var devMode = require('fs').existsSync(`${__dirname}/../src`);
137
+ // or want to "force" running the compiled version with --compiled-build
138
+ var wantsCompiled = process.argv.indexOf('--compiled-build') >= 0;
139
+
140
+ if (wantsCompiled || !devMode) {
141
+ // this runs from the compiled javascript source
142
+ require(`${__dirname}/../build/cli`).run(process.argv);
143
+ } else {
144
+ // this runs from the typescript source (for dev only)
145
+ // hook into ts-node so we can run typescript on the fly
146
+ require('ts-node').register({ project: `${__dirname}/../tsconfig.json` });
147
+ // run the CLI with the current process arguments
148
+ require(`${__dirname}/../src/cli`).run(process.argv);
149
+ }
19
150
  }
20
151
 
21
152
 
@@ -0,0 +1,332 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const os_1 = require("os");
13
+ const path_1 = require("path");
14
+ /**
15
+ * Get command description from .md frontmatter
16
+ */
17
+ function getCommandDescription(commandPath, filesystem) {
18
+ if (!filesystem.exists(commandPath)) {
19
+ return 'No description available';
20
+ }
21
+ const content = filesystem.read(commandPath);
22
+ const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
23
+ if (!frontmatterMatch) {
24
+ return 'No description available';
25
+ }
26
+ const frontmatter = frontmatterMatch[1];
27
+ const descMatch = frontmatter.match(/description:\s*([^\n]+)/);
28
+ return descMatch ? descMatch[1].trim() : 'No description available';
29
+ }
30
+ /**
31
+ * Compare semantic versions
32
+ * Returns true if sourceVersion >= targetVersion
33
+ */
34
+ function isVersionNewer(sourceVersion, targetVersion) {
35
+ const parseSemver = (version) => {
36
+ return version.split('.').map(n => parseInt(n, 10) || 0);
37
+ };
38
+ const source = parseSemver(sourceVersion);
39
+ const target = parseSemver(targetVersion);
40
+ // Compare major, minor, patch
41
+ for (let i = 0; i < 3; i++) {
42
+ if (source[i] > target[i]) {
43
+ return true;
44
+ }
45
+ if (source[i] < target[i]) {
46
+ return false;
47
+ }
48
+ }
49
+ // Versions are equal
50
+ return true;
51
+ }
52
+ /**
53
+ * Parse frontmatter from markdown file and extract version
54
+ */
55
+ function parseVersion(content) {
56
+ const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
57
+ if (!frontmatterMatch) {
58
+ return null;
59
+ }
60
+ const frontmatter = frontmatterMatch[1];
61
+ const versionMatch = frontmatter.match(/version:\s*([^\n]+)/);
62
+ return versionMatch ? versionMatch[1].trim() : null;
63
+ }
64
+ /**
65
+ * Install Claude Commands to ~/.claude/commands/ or .claude/commands/
66
+ */
67
+ const NewCommand = {
68
+ alias: ['commands', 'ic'],
69
+ description: 'Installs Claude Custom Commands to ~/.claude/commands/ or .claude/commands/ for Claude Code integration. Use --global for global installation, --project for project-specific installation.',
70
+ hidden: false,
71
+ name: 'install-commands',
72
+ run: (toolbox) => __awaiter(void 0, void 0, void 0, function* () {
73
+ var _a;
74
+ // Retrieve the tools we need
75
+ const { filesystem, parameters, print: { error, info, spin, success }, prompt, } = toolbox;
76
+ try {
77
+ // Get the CLI installation directory
78
+ const cliRoot = (0, path_1.join)(__dirname, '..', '..');
79
+ const commandsTemplateDir = (0, path_1.join)(cliRoot, 'templates', 'claude-commands');
80
+ // Check if claude-commands directory exists
81
+ if (!filesystem.exists(commandsTemplateDir)) {
82
+ error('Claude commands directory not found in CLI installation.');
83
+ info(`Expected location: ${commandsTemplateDir}`);
84
+ info('Please reinstall the CLI or report this issue.');
85
+ return;
86
+ }
87
+ // Get all available commands (*.md files, excluding README.md)
88
+ const allFiles = filesystem.list(commandsTemplateDir) || [];
89
+ const availableCommands = allFiles.filter(file => file.endsWith('.md') && file !== 'README.md');
90
+ if (availableCommands.length === 0) {
91
+ error('No commands found in CLI installation.');
92
+ return;
93
+ }
94
+ // Determine installation scope
95
+ const cwd = filesystem.cwd();
96
+ let scope = 'global';
97
+ let commandsDir = (0, path_1.join)((0, os_1.homedir)(), '.claude', 'commands');
98
+ const skipInteractive = parameters.options.y || parameters.options.yes || parameters.options['no-interactive'];
99
+ // Check if user specified scope
100
+ if (parameters.options.global) {
101
+ scope = 'global';
102
+ commandsDir = (0, path_1.join)((0, os_1.homedir)(), '.claude', 'commands');
103
+ }
104
+ else if (parameters.options.project) {
105
+ scope = 'project';
106
+ commandsDir = (0, path_1.join)(cwd, '.claude', 'commands');
107
+ }
108
+ else {
109
+ // Detect if we're in a project
110
+ let packageJsonPath = null;
111
+ let searchDir = cwd;
112
+ // Search up to 3 levels for package.json
113
+ for (let i = 0; i < 3; i++) {
114
+ const testPath = (0, path_1.join)(searchDir, 'package.json');
115
+ if (filesystem.exists(testPath)) {
116
+ packageJsonPath = testPath;
117
+ break;
118
+ }
119
+ const parent = (0, path_1.join)(searchDir, '..');
120
+ if (parent === searchDir)
121
+ break; // Reached root
122
+ searchDir = parent;
123
+ }
124
+ // If in a project, ask where to install
125
+ if (packageJsonPath && !skipInteractive) {
126
+ info('');
127
+ info(`Detected project at: ${searchDir}`);
128
+ const installToProject = yield prompt.confirm('Install commands to this project only? (No = install globally for all projects)', true);
129
+ scope = installToProject ? 'project' : 'global';
130
+ if (scope === 'project') {
131
+ commandsDir = (0, path_1.join)(searchDir, '.claude', 'commands');
132
+ }
133
+ }
134
+ else if (packageJsonPath && skipInteractive) {
135
+ // In non-interactive mode with project detected, default to global
136
+ scope = 'global';
137
+ }
138
+ }
139
+ // Create commands directory if it doesn't exist
140
+ if (!filesystem.exists(commandsDir)) {
141
+ filesystem.dir(commandsDir);
142
+ }
143
+ info('');
144
+ info('Available commands:');
145
+ info('');
146
+ // Show all available commands with descriptions
147
+ availableCommands.forEach(cmd => {
148
+ const cmdPath = (0, path_1.join)(commandsTemplateDir, cmd);
149
+ const desc = getCommandDescription(cmdPath, filesystem);
150
+ const cmdName = cmd.replace('.md', '');
151
+ info(` • /${cmdName}`);
152
+ info(` ${desc}`);
153
+ info('');
154
+ });
155
+ let commandsToInstall = [];
156
+ // Check if specific commands provided as parameters
157
+ if (parameters.first && parameters.first !== 'all') {
158
+ // Non-interactive mode: install specific command(s)
159
+ const requestedCommands = parameters.array || [parameters.first];
160
+ // Add .md extension if not present
161
+ const requestedWithExt = requestedCommands.map(c => c.endsWith('.md') ? c : `${c}.md`);
162
+ // Validate requested commands
163
+ const invalidCommands = requestedWithExt.filter(c => !availableCommands.includes(c));
164
+ if (invalidCommands.length > 0) {
165
+ error(`Invalid command(s): ${invalidCommands.map(c => c.replace('.md', '')).join(', ')}`);
166
+ info('');
167
+ info('Available commands:');
168
+ availableCommands.forEach(c => {
169
+ const cmdName = c.replace('.md', '');
170
+ info(` • ${cmdName}`);
171
+ });
172
+ return;
173
+ }
174
+ commandsToInstall = requestedWithExt;
175
+ }
176
+ else if (parameters.first === 'all' || skipInteractive) {
177
+ // Install all commands without prompting
178
+ commandsToInstall = availableCommands;
179
+ if (skipInteractive) {
180
+ info('Installing all commands (non-interactive mode)...');
181
+ }
182
+ }
183
+ else {
184
+ // Interactive mode: ask if user wants all or select individually
185
+ const installAll = yield prompt.confirm('Install all commands?', true);
186
+ if (installAll) {
187
+ commandsToInstall = availableCommands;
188
+ }
189
+ else {
190
+ // Ask for each command
191
+ info('');
192
+ info('Select which commands to install:');
193
+ info('');
194
+ for (const cmd of availableCommands) {
195
+ const cmdName = cmd.replace('.md', '');
196
+ const shouldInstall = yield prompt.confirm(`Install /${cmdName}?`, true);
197
+ if (shouldInstall) {
198
+ commandsToInstall.push(cmd);
199
+ }
200
+ }
201
+ if (commandsToInstall.length === 0) {
202
+ info('No commands selected. Installation cancelled.');
203
+ return;
204
+ }
205
+ }
206
+ }
207
+ const installSpinner = spin(`Installing ${commandsToInstall.length} command(s) to ${scope === 'global' ? '~/.claude/commands/' : '.claude/commands/'}...`);
208
+ let copiedCount = 0;
209
+ let skippedCount = 0;
210
+ let updatedCount = 0;
211
+ const skippedFiles = [];
212
+ // Install each command
213
+ for (const cmd of commandsToInstall) {
214
+ const sourcePath = (0, path_1.join)(commandsTemplateDir, cmd);
215
+ const targetPath = (0, path_1.join)(commandsDir, cmd);
216
+ const sourceContent = filesystem.read(sourcePath);
217
+ // Check if target file exists
218
+ if (filesystem.exists(targetPath)) {
219
+ const targetContent = filesystem.read(targetPath);
220
+ // Parse versions from both files
221
+ const sourceVersion = parseVersion(sourceContent);
222
+ const targetVersion = parseVersion(targetContent);
223
+ // If both have versions, compare them
224
+ if (sourceVersion && targetVersion) {
225
+ if (isVersionNewer(sourceVersion, targetVersion)) {
226
+ // Source is newer or equal, update
227
+ filesystem.write(targetPath, sourceContent);
228
+ updatedCount++;
229
+ copiedCount++;
230
+ }
231
+ else {
232
+ // Target is newer, skip
233
+ skippedCount++;
234
+ const reason = `local version ${targetVersion} is newer than ${sourceVersion}`;
235
+ skippedFiles.push({ file: cmd, reason });
236
+ }
237
+ }
238
+ else if (sourceVersion && !targetVersion) {
239
+ // Source has version, target doesn't - update
240
+ filesystem.write(targetPath, sourceContent);
241
+ updatedCount++;
242
+ copiedCount++;
243
+ }
244
+ else {
245
+ // No version info, always update (backward compatibility)
246
+ filesystem.write(targetPath, sourceContent);
247
+ updatedCount++;
248
+ copiedCount++;
249
+ }
250
+ }
251
+ else {
252
+ // Target doesn't exist, create new
253
+ filesystem.write(targetPath, sourceContent);
254
+ copiedCount++;
255
+ }
256
+ }
257
+ if (copiedCount === 0 && skippedCount === 0) {
258
+ installSpinner.fail();
259
+ error('No command files were processed.');
260
+ return;
261
+ }
262
+ if (copiedCount === 0 && skippedCount > 0) {
263
+ installSpinner.succeed('All selected commands are already up to date!');
264
+ info('');
265
+ info(`Skipped: ${skippedCount} file(s)`);
266
+ info(`Location: ${commandsDir}`);
267
+ return;
268
+ }
269
+ installSpinner.succeed(`Successfully installed ${commandsToInstall.length} command(s)!`);
270
+ info('');
271
+ if (updatedCount > 0 && skippedCount > 0) {
272
+ success(`Updated ${updatedCount} file(s), skipped ${skippedCount} file(s)`);
273
+ }
274
+ else if (updatedCount > 0) {
275
+ success(`Updated ${updatedCount} file(s)`);
276
+ }
277
+ else {
278
+ success(`Created ${copiedCount} file(s)`);
279
+ }
280
+ info('');
281
+ info('Installed commands:');
282
+ commandsToInstall.forEach(cmd => {
283
+ const cmdPath = (0, path_1.join)(commandsTemplateDir, cmd);
284
+ const desc = getCommandDescription(cmdPath, filesystem);
285
+ const cmdName = cmd.replace('.md', '');
286
+ info(` • /${cmdName}`);
287
+ info(` ${desc.substring(0, 80)}${desc.length > 80 ? '...' : ''}`);
288
+ });
289
+ info('');
290
+ info('These commands are now available in Claude Code!');
291
+ // Show first installed command as example
292
+ const firstCmd = (_a = commandsToInstall[0]) === null || _a === void 0 ? void 0 : _a.replace('.md', '');
293
+ info(`Use them by typing the command name with a leading slash, e.g., /${firstCmd || 'command-name'}`);
294
+ info('');
295
+ info('Examples:');
296
+ // Show up to 5 commands as examples (or all if less than 5)
297
+ const exampleCount = Math.min(commandsToInstall.length, 5);
298
+ for (let i = 0; i < exampleCount; i++) {
299
+ const cmd = commandsToInstall[i];
300
+ const cmdPath = (0, path_1.join)(commandsTemplateDir, cmd);
301
+ const desc = getCommandDescription(cmdPath, filesystem);
302
+ const cmdName = cmd.replace('.md', '');
303
+ info(` • /${cmdName} - ${desc}`);
304
+ }
305
+ info('');
306
+ info(`Location: ${commandsDir}`);
307
+ info(`Scope: ${scope === 'global' ? 'Global (all projects)' : 'Project-specific'}`);
308
+ if (skippedCount > 0) {
309
+ info('');
310
+ info(`Note: ${skippedCount} file(s) were skipped because your local versions are newer:`);
311
+ skippedFiles.forEach(({ file, reason }) => {
312
+ info(` • ${file} (${reason})`);
313
+ });
314
+ info('');
315
+ info('To force update, manually delete the files and run this command again.');
316
+ }
317
+ }
318
+ catch (err) {
319
+ error(`Failed to install command(s): ${err.message}`);
320
+ info('');
321
+ info('Troubleshooting:');
322
+ info(' • Ensure .claude directory exists and is writable');
323
+ info(' • Check file permissions');
324
+ info(' • Try running with sudo if permission issues persist');
325
+ return;
326
+ }
327
+ // For tests
328
+ return `claude install-commands`;
329
+ }),
330
+ };
331
+ exports.default = NewCommand;
332
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5zdGFsbC1jb21tYW5kcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21tYW5kcy9jbGF1ZGUvaW5zdGFsbC1jb21tYW5kcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztBQUNBLDJCQUE2QjtBQUM3QiwrQkFBNEI7QUFJNUI7O0dBRUc7QUFDSCxTQUFTLHFCQUFxQixDQUFDLFdBQW1CLEVBQUUsVUFBZTtJQUNqRSxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO1FBQ3BDLE9BQU8sMEJBQTBCLENBQUM7SUFDcEMsQ0FBQztJQUVELE1BQU0sT0FBTyxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDN0MsTUFBTSxnQkFBZ0IsR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLHVCQUF1QixDQUFDLENBQUM7SUFDaEUsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDdEIsT0FBTywwQkFBMEIsQ0FBQztJQUNwQyxDQUFDO0lBRUQsTUFBTSxXQUFXLEdBQUcsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDeEMsTUFBTSxTQUFTLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO0lBRS9ELE9BQU8sU0FBUyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLDBCQUEwQixDQUFDO0FBQ3RFLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFTLGNBQWMsQ0FBQyxhQUFxQixFQUFFLGFBQXFCO0lBQ2xFLE1BQU0sV0FBVyxHQUFHLENBQUMsT0FBZSxFQUFZLEVBQUU7UUFDaEQsT0FBTyxPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsRUFB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