@ecmaos/coreutils 0.3.0 → 0.4.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.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +68 -0
- package/dist/commands/cron.d.ts +4 -0
- package/dist/commands/cron.d.ts.map +1 -0
- package/dist/commands/cron.js +532 -0
- package/dist/commands/cron.js.map +1 -0
- package/dist/commands/env.d.ts +4 -0
- package/dist/commands/env.d.ts.map +1 -0
- package/dist/commands/env.js +129 -0
- package/dist/commands/env.js.map +1 -0
- package/dist/commands/head.d.ts.map +1 -1
- package/dist/commands/head.js +184 -77
- package/dist/commands/head.js.map +1 -1
- package/dist/commands/less.d.ts.map +1 -1
- package/dist/commands/less.js +1 -0
- package/dist/commands/less.js.map +1 -1
- package/dist/commands/man.d.ts.map +1 -1
- package/dist/commands/man.js +13 -1
- package/dist/commands/man.js.map +1 -1
- package/dist/commands/mount.d.ts +4 -0
- package/dist/commands/mount.d.ts.map +1 -0
- package/dist/commands/mount.js +1041 -0
- package/dist/commands/mount.js.map +1 -0
- package/dist/commands/open.d.ts +4 -0
- package/dist/commands/open.d.ts.map +1 -0
- package/dist/commands/open.js +74 -0
- package/dist/commands/open.js.map +1 -0
- package/dist/commands/play.d.ts +4 -0
- package/dist/commands/play.d.ts.map +1 -0
- package/dist/commands/play.js +231 -0
- package/dist/commands/play.js.map +1 -0
- package/dist/commands/tar.d.ts.map +1 -1
- package/dist/commands/tar.js +67 -17
- package/dist/commands/tar.js.map +1 -1
- package/dist/commands/umount.d.ts +4 -0
- package/dist/commands/umount.d.ts.map +1 -0
- package/dist/commands/umount.js +104 -0
- package/dist/commands/umount.js.map +1 -0
- package/dist/commands/video.d.ts +4 -0
- package/dist/commands/video.d.ts.map +1 -0
- package/dist/commands/video.js +250 -0
- package/dist/commands/video.js.map +1 -0
- package/dist/commands/view.d.ts +5 -0
- package/dist/commands/view.d.ts.map +1 -0
- package/dist/commands/view.js +830 -0
- package/dist/commands/view.js.map +1 -0
- package/dist/commands/web.d.ts +4 -0
- package/dist/commands/web.d.ts.map +1 -0
- package/dist/commands/web.js +348 -0
- package/dist/commands/web.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -2
- package/dist/index.js.map +1 -1
- package/package.json +11 -2
- package/src/commands/cron.ts +591 -0
- package/src/commands/env.ts +143 -0
- package/src/commands/head.ts +176 -77
- package/src/commands/less.ts +1 -0
- package/src/commands/man.ts +12 -1
- package/src/commands/mount.ts +1193 -0
- package/src/commands/open.ts +84 -0
- package/src/commands/play.ts +249 -0
- package/src/commands/tar.ts +62 -19
- package/src/commands/umount.ts +117 -0
- package/src/commands/video.ts +267 -0
- package/src/commands/view.ts +916 -0
- package/src/commands/web.ts +377 -0
- package/src/index.ts +29 -2
package/.turbo/turbo-build.log
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,73 @@
|
|
|
1
1
|
# @ecmaos/coreutils
|
|
2
2
|
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- c6d3ea8: Filesystem & Mount System
|
|
8
|
+
|
|
9
|
+
- Added fstab file processing and parsing utilities
|
|
10
|
+
- Implemented mount and umount commands with full filesystem support
|
|
11
|
+
- Changed environment variable prefix handling
|
|
12
|
+
- Enhanced filesystem configuration and mount management
|
|
13
|
+
|
|
14
|
+
Environment Management
|
|
15
|
+
|
|
16
|
+
- Added support for global /etc/env file
|
|
17
|
+
- Fixed env command argument handling
|
|
18
|
+
- New env command implementation in core/utils
|
|
19
|
+
|
|
20
|
+
Documentation & SEO
|
|
21
|
+
|
|
22
|
+
- Enhanced HTML metadata and SEO improvements
|
|
23
|
+
- Added AI and passkey tutorials
|
|
24
|
+
- Updated README with expanded documentation
|
|
25
|
+
- Added lighthouse performance report
|
|
26
|
+
- Updated project description
|
|
27
|
+
|
|
28
|
+
Bug Fixes & Enhancements
|
|
29
|
+
|
|
30
|
+
- Enhanced cron command with improved parsing and functionality
|
|
31
|
+
- Fixed readline bug in terminal
|
|
32
|
+
- Fixed less command first-line offset display issue
|
|
33
|
+
|
|
34
|
+
Miscellaneous
|
|
35
|
+
|
|
36
|
+
- Removed offers metadata from HTML
|
|
37
|
+
- Sorted package.json scripts
|
|
38
|
+
- Synced documentation across codebase
|
|
39
|
+
|
|
40
|
+
### Patch Changes
|
|
41
|
+
|
|
42
|
+
- Updated dependencies [c6d3ea8]
|
|
43
|
+
- @ecmaos/types@0.7.0
|
|
44
|
+
|
|
45
|
+
## 0.3.1
|
|
46
|
+
|
|
47
|
+
### Patch Changes
|
|
48
|
+
|
|
49
|
+
- d43d304: New Features:
|
|
50
|
+
|
|
51
|
+
- Cron/crontab system: Added scheduling system with crontab parsing and execution
|
|
52
|
+
- Web browser coreutil: New 'web' command for browsing functionality
|
|
53
|
+
- View coreutil: New 'view' command for multimedia viewing
|
|
54
|
+
- Coreutils migration: Migrated 'play' and 'video' commands from kernel to coreutils
|
|
55
|
+
|
|
56
|
+
Fixes:
|
|
57
|
+
|
|
58
|
+
- Shell command substitution parsing improvements
|
|
59
|
+
- Tar parsing improvements
|
|
60
|
+
- Web coreutil now loads credentialless
|
|
61
|
+
|
|
62
|
+
Maintenance:
|
|
63
|
+
|
|
64
|
+
- Updated documentation and types across various kernel components
|
|
65
|
+
- Enhanced coreutils and shell scripts
|
|
66
|
+
- Added 'open' and 'man' commands to coreutils
|
|
67
|
+
|
|
68
|
+
- Updated dependencies [d43d304]
|
|
69
|
+
- @ecmaos/types@0.6.1
|
|
70
|
+
|
|
3
71
|
## 0.3.0
|
|
4
72
|
|
|
5
73
|
### Minor Changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cron.d.ts","sourceRoot":"","sources":["../../src/commands/cron.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAW,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAiL/D,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,GAAG,eAAe,CA2Z/F"}
|
|
@@ -0,0 +1,532 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { TerminalCommand } from '../shared/terminal-command.js';
|
|
3
|
+
import { writelnStdout, writelnStderr } from '../shared/helpers.js';
|
|
4
|
+
import { parseCronExpression } from 'cron-schedule';
|
|
5
|
+
import cronstrue from 'cronstrue';
|
|
6
|
+
/**
|
|
7
|
+
* Parse a single crontab line
|
|
8
|
+
* @param line - The line to parse
|
|
9
|
+
* @returns Parsed entry or null if line is empty/comment
|
|
10
|
+
*/
|
|
11
|
+
function parseCrontabLine(line) {
|
|
12
|
+
const trimmed = line.trim();
|
|
13
|
+
// Skip empty lines and comments
|
|
14
|
+
if (trimmed === '' || trimmed.startsWith('#')) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
// Split by whitespace - cron expression is first 5 or 6 fields
|
|
18
|
+
const parts = trimmed.split(/\s+/);
|
|
19
|
+
if (parts.length < 6) {
|
|
20
|
+
// Need at least 5 fields for cron expression + command
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
// Standard format: minute hour day month weekday command (5 fields + command)
|
|
24
|
+
// Extended format: second minute hour day month weekday command (6 fields + command)
|
|
25
|
+
// We need to determine which format is being used
|
|
26
|
+
let expression;
|
|
27
|
+
let command;
|
|
28
|
+
// If we have exactly 6 parts, assume 5-field format (5 cron fields + 1 command word)
|
|
29
|
+
// This is the most common case
|
|
30
|
+
if (parts.length === 6) {
|
|
31
|
+
// 5-field format: minute hour day month weekday command
|
|
32
|
+
expression = parts.slice(0, 5).join(' ');
|
|
33
|
+
command = parts[5] || '';
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
// 7+ parts: could be 5-field with multi-word command or 6-field format
|
|
37
|
+
// Try 6-field format FIRST (if user wrote 6 fields, they probably meant 6 fields)
|
|
38
|
+
// Then fall back to 5-field if 6-field is invalid
|
|
39
|
+
const potential5Field = parts.slice(0, 5).join(' ');
|
|
40
|
+
const potential6Field = parts.slice(0, 6).join(' ');
|
|
41
|
+
let valid5Field = false;
|
|
42
|
+
let valid6Field = false;
|
|
43
|
+
// Try to validate 6-field format first
|
|
44
|
+
try {
|
|
45
|
+
parseCronExpression(potential6Field);
|
|
46
|
+
valid6Field = true;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// Not a valid 6-field expression
|
|
50
|
+
}
|
|
51
|
+
// Try to validate 5-field format
|
|
52
|
+
try {
|
|
53
|
+
parseCronExpression(potential5Field);
|
|
54
|
+
valid5Field = true;
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// Not a valid 5-field expression
|
|
58
|
+
}
|
|
59
|
+
// Prefer 6-field format if valid (user wrote 6 fields, so use them)
|
|
60
|
+
// Only use 5-field if 6-field is invalid
|
|
61
|
+
if (valid6Field) {
|
|
62
|
+
expression = potential6Field;
|
|
63
|
+
command = parts.slice(6).join(' ');
|
|
64
|
+
}
|
|
65
|
+
else if (valid5Field) {
|
|
66
|
+
expression = potential5Field;
|
|
67
|
+
command = parts.slice(5).join(' ');
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
// Neither format is valid, return null
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Validate the expression
|
|
75
|
+
try {
|
|
76
|
+
parseCronExpression(expression);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
command = command.trim();
|
|
82
|
+
return { expression, command };
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Parse a complete crontab file
|
|
86
|
+
* @param content - The crontab file content
|
|
87
|
+
* @returns Array of parsed crontab entries
|
|
88
|
+
*/
|
|
89
|
+
function parseCrontabFile(content) {
|
|
90
|
+
const lines = content.split('\n');
|
|
91
|
+
const entries = [];
|
|
92
|
+
for (let i = 0; i < lines.length; i++) {
|
|
93
|
+
const line = lines[i]?.trim();
|
|
94
|
+
if (!line)
|
|
95
|
+
continue;
|
|
96
|
+
const parsed = parseCrontabLine(line);
|
|
97
|
+
if (parsed) {
|
|
98
|
+
entries.push({
|
|
99
|
+
expression: parsed.expression,
|
|
100
|
+
command: parsed.command,
|
|
101
|
+
lineNumber: i + 1
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return entries;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Get human-readable description of a cron expression
|
|
109
|
+
* @param expression - The cron expression
|
|
110
|
+
* @returns Human-readable description or null if parsing fails
|
|
111
|
+
*/
|
|
112
|
+
function getHumanReadableDescription(expression) {
|
|
113
|
+
try {
|
|
114
|
+
return cronstrue.toString(expression, {
|
|
115
|
+
throwExceptionOnParseError: false,
|
|
116
|
+
verbose: false
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function printUsage(process, terminal) {
|
|
124
|
+
const usage = `Usage: cron [COMMAND] [OPTIONS]
|
|
125
|
+
|
|
126
|
+
Manage scheduled tasks (crontabs).
|
|
127
|
+
|
|
128
|
+
Options:
|
|
129
|
+
--help display this help and exit
|
|
130
|
+
|
|
131
|
+
Commands:
|
|
132
|
+
list List all active cron jobs
|
|
133
|
+
add <schedule> <cmd> Add a new cron job to user crontab
|
|
134
|
+
remove <id> Remove a cron job by ID
|
|
135
|
+
edit Open user crontab in editor
|
|
136
|
+
validate <expression> Validate a cron expression
|
|
137
|
+
next <expression> [N] Show next N execution times (default: 1)
|
|
138
|
+
test <expression> Test if expression matches current time
|
|
139
|
+
reload Reload crontabs from files
|
|
140
|
+
|
|
141
|
+
Examples:
|
|
142
|
+
cron list List all cron jobs
|
|
143
|
+
cron add "*/5 * * * *" "echo hello" Add job to run every 5 minutes
|
|
144
|
+
cron add "* * * * * *" "echo hello" Add job to run every second (6-field)
|
|
145
|
+
cron add "0 0 * * *" "echo daily" Add daily job at midnight
|
|
146
|
+
cron remove cron:user:1 Remove user cron job #1
|
|
147
|
+
cron validate "*/5 * * * *" Validate cron expression
|
|
148
|
+
cron next "*/5 * * * *" 5 Show next 5 execution times
|
|
149
|
+
cron test "*/5 * * * *" Test if expression matches now
|
|
150
|
+
|
|
151
|
+
Crontab format:
|
|
152
|
+
Both 5-field and 6-field cron expressions are supported:
|
|
153
|
+
|
|
154
|
+
5-field (standard): minute hour day month weekday command
|
|
155
|
+
Example: "*/5 * * * *" runs every 5 minutes
|
|
156
|
+
|
|
157
|
+
6-field (extended): second minute hour day month weekday command
|
|
158
|
+
Example: "* * * * * *" runs every second
|
|
159
|
+
Example: "0 */5 * * * *" runs every 5 minutes at :00 seconds`;
|
|
160
|
+
writelnStderr(process, terminal, usage);
|
|
161
|
+
}
|
|
162
|
+
export function createCommand(kernel, shell, terminal) {
|
|
163
|
+
return new TerminalCommand({
|
|
164
|
+
command: 'cron',
|
|
165
|
+
description: 'Manage scheduled tasks (crontabs)',
|
|
166
|
+
kernel,
|
|
167
|
+
shell,
|
|
168
|
+
terminal,
|
|
169
|
+
run: async (pid, argv) => {
|
|
170
|
+
const process = kernel.processes.get(pid);
|
|
171
|
+
if (argv.length === 0 || (argv.length > 0 && (argv[0] === '--help' || argv[0] === '-h'))) {
|
|
172
|
+
printUsage(process, terminal);
|
|
173
|
+
return 0;
|
|
174
|
+
}
|
|
175
|
+
const subcommand = argv[0];
|
|
176
|
+
try {
|
|
177
|
+
switch (subcommand) {
|
|
178
|
+
case 'list': {
|
|
179
|
+
const cronJobs = kernel.intervals.listCrons();
|
|
180
|
+
if (cronJobs.length === 0) {
|
|
181
|
+
await writelnStdout(process, terminal, 'No active cron jobs.');
|
|
182
|
+
return 0;
|
|
183
|
+
}
|
|
184
|
+
// Build a map of job names to expressions by parsing crontab files
|
|
185
|
+
const jobExpressions = new Map();
|
|
186
|
+
// Load system crontab entries
|
|
187
|
+
try {
|
|
188
|
+
const systemCrontabPath = '/etc/crontab';
|
|
189
|
+
if (await kernel.filesystem.fs.exists(systemCrontabPath)) {
|
|
190
|
+
const content = await kernel.filesystem.fs.readFile(systemCrontabPath, 'utf-8');
|
|
191
|
+
const entries = parseCrontabFile(content);
|
|
192
|
+
for (const entry of entries) {
|
|
193
|
+
const jobName = `cron:system:${entry.lineNumber}`;
|
|
194
|
+
jobExpressions.set(jobName, { expression: entry.expression, command: entry.command });
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
catch {
|
|
199
|
+
// Ignore errors loading system crontab
|
|
200
|
+
}
|
|
201
|
+
// Load user crontab entries
|
|
202
|
+
try {
|
|
203
|
+
const home = shell.env.get('HOME') ?? '/root';
|
|
204
|
+
const userCrontabPath = path.join(home, '.config', 'crontab');
|
|
205
|
+
if (await shell.context.fs.promises.exists(userCrontabPath)) {
|
|
206
|
+
const content = await shell.context.fs.promises.readFile(userCrontabPath, 'utf-8');
|
|
207
|
+
const entries = parseCrontabFile(content);
|
|
208
|
+
for (const entry of entries) {
|
|
209
|
+
const jobName = `cron:user:${entry.lineNumber}`;
|
|
210
|
+
jobExpressions.set(jobName, { expression: entry.expression, command: entry.command });
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
// Ignore errors loading user crontab
|
|
216
|
+
}
|
|
217
|
+
await writelnStdout(process, terminal, 'Active cron jobs:');
|
|
218
|
+
for (const jobName of cronJobs) {
|
|
219
|
+
const jobInfo = jobExpressions.get(jobName);
|
|
220
|
+
if (jobInfo) {
|
|
221
|
+
const description = getHumanReadableDescription(jobInfo.expression);
|
|
222
|
+
if (description) {
|
|
223
|
+
await writelnStdout(process, terminal, ` ${jobName}`);
|
|
224
|
+
await writelnStdout(process, terminal, ` Schedule: ${jobInfo.expression} (${description})`);
|
|
225
|
+
await writelnStdout(process, terminal, ` Command: ${jobInfo.command}`);
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
await writelnStdout(process, terminal, ` ${jobName}`);
|
|
229
|
+
await writelnStdout(process, terminal, ` Schedule: ${jobInfo.expression}`);
|
|
230
|
+
await writelnStdout(process, terminal, ` Command: ${jobInfo.command}`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
await writelnStdout(process, terminal, ` ${jobName}`);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return 0;
|
|
238
|
+
}
|
|
239
|
+
case 'add': {
|
|
240
|
+
if (argv.length < 3) {
|
|
241
|
+
await writelnStderr(process, terminal, 'cron add: missing arguments');
|
|
242
|
+
await writelnStderr(process, terminal, 'Usage: cron add <schedule> <command>');
|
|
243
|
+
return 1;
|
|
244
|
+
}
|
|
245
|
+
const schedule = argv[1];
|
|
246
|
+
if (!schedule) {
|
|
247
|
+
await writelnStderr(process, terminal, 'cron add: missing schedule');
|
|
248
|
+
await writelnStderr(process, terminal, 'Usage: cron add <schedule> <command>');
|
|
249
|
+
return 1;
|
|
250
|
+
}
|
|
251
|
+
const command = argv.slice(2).join(' ');
|
|
252
|
+
// Validate the cron expression
|
|
253
|
+
let humanReadable = null;
|
|
254
|
+
try {
|
|
255
|
+
parseCronExpression(schedule);
|
|
256
|
+
humanReadable = getHumanReadableDescription(schedule);
|
|
257
|
+
}
|
|
258
|
+
catch (error) {
|
|
259
|
+
await writelnStderr(process, terminal, `cron add: invalid cron expression: ${schedule}`);
|
|
260
|
+
return 1;
|
|
261
|
+
}
|
|
262
|
+
// Get user home directory
|
|
263
|
+
const home = shell.env.get('HOME') ?? '/root';
|
|
264
|
+
const configDir = path.join(home, '.config');
|
|
265
|
+
const crontabPath = path.join(configDir, 'crontab');
|
|
266
|
+
// Ensure .config directory exists
|
|
267
|
+
try {
|
|
268
|
+
if (!await shell.context.fs.promises.exists(configDir)) {
|
|
269
|
+
await shell.context.fs.promises.mkdir(configDir, { recursive: true });
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
catch (error) {
|
|
273
|
+
await writelnStderr(process, terminal, `cron add: failed to create .config directory: ${error}`);
|
|
274
|
+
return 1;
|
|
275
|
+
}
|
|
276
|
+
// Read existing crontab or create new
|
|
277
|
+
let crontabContent = '';
|
|
278
|
+
try {
|
|
279
|
+
if (await shell.context.fs.promises.exists(crontabPath)) {
|
|
280
|
+
crontabContent = await shell.context.fs.promises.readFile(crontabPath, 'utf-8');
|
|
281
|
+
if (!crontabContent.endsWith('\n') && crontabContent.length > 0) {
|
|
282
|
+
crontabContent += '\n';
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
catch (error) {
|
|
287
|
+
// File doesn't exist or can't be read, start fresh
|
|
288
|
+
crontabContent = '';
|
|
289
|
+
}
|
|
290
|
+
// Add new entry
|
|
291
|
+
crontabContent += `${schedule} ${command}\n`;
|
|
292
|
+
// Write back to file
|
|
293
|
+
try {
|
|
294
|
+
await shell.context.fs.promises.writeFile(crontabPath, crontabContent, { encoding: 'utf-8' });
|
|
295
|
+
}
|
|
296
|
+
catch (error) {
|
|
297
|
+
await writelnStderr(process, terminal, `cron add: failed to write crontab: ${error}`);
|
|
298
|
+
return 1;
|
|
299
|
+
}
|
|
300
|
+
await writelnStdout(process, terminal, `Added cron job: ${schedule} ${command}`);
|
|
301
|
+
if (humanReadable) {
|
|
302
|
+
await writelnStdout(process, terminal, ` Schedule: ${humanReadable}`);
|
|
303
|
+
}
|
|
304
|
+
await writelnStdout(process, terminal, 'Run "cron reload" to activate the new job.');
|
|
305
|
+
return 0;
|
|
306
|
+
}
|
|
307
|
+
case 'remove': {
|
|
308
|
+
if (argv.length < 2) {
|
|
309
|
+
await writelnStderr(process, terminal, 'cron remove: missing job ID');
|
|
310
|
+
await writelnStderr(process, terminal, 'Usage: cron remove <id>');
|
|
311
|
+
return 1;
|
|
312
|
+
}
|
|
313
|
+
const jobId = argv[1];
|
|
314
|
+
if (!jobId) {
|
|
315
|
+
await writelnStderr(process, terminal, 'cron remove: missing job ID');
|
|
316
|
+
return 1;
|
|
317
|
+
}
|
|
318
|
+
const handle = kernel.intervals.getCron(jobId);
|
|
319
|
+
if (!handle) {
|
|
320
|
+
await writelnStderr(process, terminal, `cron remove: job not found: ${jobId}`);
|
|
321
|
+
return 1;
|
|
322
|
+
}
|
|
323
|
+
kernel.intervals.clearCron(jobId);
|
|
324
|
+
// Also remove from crontab file if it's a user job
|
|
325
|
+
if (jobId.startsWith('cron:user:')) {
|
|
326
|
+
const home = shell.env.get('HOME') ?? '/root';
|
|
327
|
+
const crontabPath = path.join(home, '.config', 'crontab');
|
|
328
|
+
try {
|
|
329
|
+
if (await shell.context.fs.promises.exists(crontabPath)) {
|
|
330
|
+
const content = await shell.context.fs.promises.readFile(crontabPath, 'utf-8');
|
|
331
|
+
const lines = content.split('\n');
|
|
332
|
+
const lineNumber = parseInt(jobId.replace('cron:user:', ''), 10);
|
|
333
|
+
if (lineNumber > 0 && lineNumber <= lines.length) {
|
|
334
|
+
// Remove the line (1-indexed to 0-indexed)
|
|
335
|
+
const entries = parseCrontabFile(content);
|
|
336
|
+
const entryToRemove = entries.find((e) => e.lineNumber === lineNumber);
|
|
337
|
+
if (entryToRemove) {
|
|
338
|
+
const newLines = lines.filter((_, idx) => idx + 1 !== lineNumber);
|
|
339
|
+
await shell.context.fs.promises.writeFile(crontabPath, newLines.join('\n'), { encoding: 'utf-8' });
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
catch (error) {
|
|
345
|
+
// Continue even if file update fails
|
|
346
|
+
kernel.log.warn(`Failed to update crontab file: ${error}`);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
await writelnStdout(process, terminal, `Removed cron job: ${jobId}`);
|
|
350
|
+
return 0;
|
|
351
|
+
}
|
|
352
|
+
case 'edit': {
|
|
353
|
+
const home = shell.env.get('HOME') ?? '/root';
|
|
354
|
+
const crontabPath = path.join(home, '.config', 'crontab');
|
|
355
|
+
// Use view command to edit (or create if doesn't exist)
|
|
356
|
+
const result = await kernel.execute({
|
|
357
|
+
command: '/usr/bin/edit',
|
|
358
|
+
args: [crontabPath],
|
|
359
|
+
shell,
|
|
360
|
+
terminal
|
|
361
|
+
});
|
|
362
|
+
if (result === 0) {
|
|
363
|
+
await writelnStdout(process, terminal, 'Crontab edited. Run "cron reload" to apply changes.');
|
|
364
|
+
}
|
|
365
|
+
return result;
|
|
366
|
+
}
|
|
367
|
+
case 'validate': {
|
|
368
|
+
if (argv.length < 2) {
|
|
369
|
+
await writelnStderr(process, terminal, 'cron validate: missing expression');
|
|
370
|
+
await writelnStderr(process, terminal, 'Usage: cron validate <expression>');
|
|
371
|
+
return 1;
|
|
372
|
+
}
|
|
373
|
+
const expression = argv[1];
|
|
374
|
+
if (!expression) {
|
|
375
|
+
await writelnStderr(process, terminal, 'cron validate: missing expression');
|
|
376
|
+
return 1;
|
|
377
|
+
}
|
|
378
|
+
try {
|
|
379
|
+
parseCronExpression(expression);
|
|
380
|
+
const description = getHumanReadableDescription(expression);
|
|
381
|
+
await writelnStdout(process, terminal, `Valid cron expression: ${expression}`);
|
|
382
|
+
if (description) {
|
|
383
|
+
await writelnStdout(process, terminal, ` Description: ${description}`);
|
|
384
|
+
}
|
|
385
|
+
return 0;
|
|
386
|
+
}
|
|
387
|
+
catch (error) {
|
|
388
|
+
await writelnStderr(process, terminal, `Invalid cron expression: ${expression}`);
|
|
389
|
+
await writelnStderr(process, terminal, `Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
390
|
+
return 1;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
case 'next': {
|
|
394
|
+
if (argv.length < 2) {
|
|
395
|
+
await writelnStderr(process, terminal, 'cron next: missing expression');
|
|
396
|
+
await writelnStderr(process, terminal, 'Usage: cron next <expression> [count]');
|
|
397
|
+
return 1;
|
|
398
|
+
}
|
|
399
|
+
const expression = argv[1];
|
|
400
|
+
if (!expression) {
|
|
401
|
+
await writelnStderr(process, terminal, 'cron next: missing expression');
|
|
402
|
+
return 1;
|
|
403
|
+
}
|
|
404
|
+
const count = argv.length > 2 && argv[2] ? parseInt(argv[2], 10) : 1;
|
|
405
|
+
if (isNaN(count) || count < 1) {
|
|
406
|
+
await writelnStderr(process, terminal, 'cron next: invalid count (must be >= 1)');
|
|
407
|
+
return 1;
|
|
408
|
+
}
|
|
409
|
+
try {
|
|
410
|
+
const cron = parseCronExpression(expression);
|
|
411
|
+
const now = new Date();
|
|
412
|
+
const dates = cron.getNextDates(count, now);
|
|
413
|
+
const description = getHumanReadableDescription(expression);
|
|
414
|
+
await writelnStdout(process, terminal, `Next ${count} execution time(s) for "${expression}":`);
|
|
415
|
+
if (description) {
|
|
416
|
+
await writelnStdout(process, terminal, ` Schedule: ${description}`);
|
|
417
|
+
}
|
|
418
|
+
for (let i = 0; i < dates.length; i++) {
|
|
419
|
+
const date = dates[i];
|
|
420
|
+
if (date) {
|
|
421
|
+
await writelnStdout(process, terminal, ` ${i + 1}. ${date.toISOString()}`);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
return 0;
|
|
425
|
+
}
|
|
426
|
+
catch (error) {
|
|
427
|
+
await writelnStderr(process, terminal, `Invalid cron expression: ${expression}`);
|
|
428
|
+
await writelnStderr(process, terminal, `Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
429
|
+
return 1;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
case 'test': {
|
|
433
|
+
if (argv.length < 2) {
|
|
434
|
+
await writelnStderr(process, terminal, 'cron test: missing expression');
|
|
435
|
+
await writelnStderr(process, terminal, 'Usage: cron test <expression>');
|
|
436
|
+
return 1;
|
|
437
|
+
}
|
|
438
|
+
const expression = argv[1];
|
|
439
|
+
if (!expression) {
|
|
440
|
+
await writelnStderr(process, terminal, 'cron test: missing expression');
|
|
441
|
+
return 1;
|
|
442
|
+
}
|
|
443
|
+
try {
|
|
444
|
+
const cron = parseCronExpression(expression);
|
|
445
|
+
const now = new Date();
|
|
446
|
+
const matches = cron.matchDate(now);
|
|
447
|
+
const description = getHumanReadableDescription(expression);
|
|
448
|
+
if (matches) {
|
|
449
|
+
await writelnStdout(process, terminal, `Expression "${expression}" matches current time: ${now.toISOString()}`);
|
|
450
|
+
}
|
|
451
|
+
else {
|
|
452
|
+
await writelnStdout(process, terminal, `Expression "${expression}" does not match current time: ${now.toISOString()}`);
|
|
453
|
+
}
|
|
454
|
+
if (description) {
|
|
455
|
+
await writelnStdout(process, terminal, ` Schedule: ${description}`);
|
|
456
|
+
}
|
|
457
|
+
return 0;
|
|
458
|
+
}
|
|
459
|
+
catch (error) {
|
|
460
|
+
await writelnStderr(process, terminal, `Invalid cron expression: ${expression}`);
|
|
461
|
+
await writelnStderr(process, terminal, `Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
462
|
+
return 1;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
case 'reload': {
|
|
466
|
+
// Clear all existing cron jobs
|
|
467
|
+
const existingJobs = kernel.intervals.listCrons();
|
|
468
|
+
for (const jobName of existingJobs) {
|
|
469
|
+
kernel.intervals.clearCron(jobName);
|
|
470
|
+
}
|
|
471
|
+
// Reload system crontab
|
|
472
|
+
try {
|
|
473
|
+
const systemCrontabPath = '/etc/crontab';
|
|
474
|
+
if (await kernel.filesystem.fs.exists(systemCrontabPath)) {
|
|
475
|
+
const content = await kernel.filesystem.fs.readFile(systemCrontabPath, 'utf-8');
|
|
476
|
+
const entries = parseCrontabFile(content);
|
|
477
|
+
for (const entry of entries) {
|
|
478
|
+
const jobName = `cron:system:${entry.lineNumber}`;
|
|
479
|
+
kernel.intervals.setCron(jobName, entry.expression, async () => {
|
|
480
|
+
await kernel.shell.execute(entry.command);
|
|
481
|
+
}, {
|
|
482
|
+
errorHandler: (err) => {
|
|
483
|
+
kernel.log.error(`Cron job ${jobName} failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
484
|
+
}
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
catch (error) {
|
|
490
|
+
kernel.log.warn(`Failed to load system crontab: ${error}`);
|
|
491
|
+
}
|
|
492
|
+
// Reload user crontab
|
|
493
|
+
try {
|
|
494
|
+
const home = shell.env.get('HOME') ?? '/root';
|
|
495
|
+
const userCrontabPath = path.join(home, '.config', 'crontab');
|
|
496
|
+
if (await shell.context.fs.promises.exists(userCrontabPath)) {
|
|
497
|
+
const content = await shell.context.fs.promises.readFile(userCrontabPath, 'utf-8');
|
|
498
|
+
const entries = parseCrontabFile(content);
|
|
499
|
+
for (const entry of entries) {
|
|
500
|
+
const jobName = `cron:user:${entry.lineNumber}`;
|
|
501
|
+
// Ensure command is properly trimmed and preserved
|
|
502
|
+
const command = entry.command.trim();
|
|
503
|
+
kernel.intervals.setCron(jobName, entry.expression, async () => {
|
|
504
|
+
await kernel.shell.execute(command);
|
|
505
|
+
}, {
|
|
506
|
+
errorHandler: (err) => {
|
|
507
|
+
kernel.log.error(`Cron job ${jobName} failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
508
|
+
}
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
catch (error) {
|
|
514
|
+
kernel.log.warn(`Failed to load user crontab: ${error}`);
|
|
515
|
+
}
|
|
516
|
+
await writelnStdout(process, terminal, 'Crontabs reloaded.');
|
|
517
|
+
return 0;
|
|
518
|
+
}
|
|
519
|
+
default:
|
|
520
|
+
await writelnStderr(process, terminal, `cron: unknown command: ${subcommand}`);
|
|
521
|
+
await writelnStderr(process, terminal, "Try 'cron --help' for more information.");
|
|
522
|
+
return 1;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
catch (error) {
|
|
526
|
+
await writelnStderr(process, terminal, `cron: error: ${error instanceof Error ? error.message : String(error)}`);
|
|
527
|
+
return 1;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
//# sourceMappingURL=cron.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cron.js","sourceRoot":"","sources":["../../src/commands/cron.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAA;AAEvB,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAC/D,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AACnD,OAAO,SAAS,MAAM,WAAW,CAAA;AAQjC;;;;GAIG;AACH,SAAS,gBAAgB,CAAC,IAAY;IACpC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;IAE3B,gCAAgC;IAChC,IAAI,OAAO,KAAK,EAAE,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9C,OAAO,IAAI,CAAA;IACb,CAAC;IAED,+DAA+D;IAC/D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IAElC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,uDAAuD;QACvD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,8EAA8E;IAC9E,qFAAqF;IACrF,kDAAkD;IAClD,IAAI,UAAkB,CAAA;IACtB,IAAI,OAAe,CAAA;IAEnB,qFAAqF;IACrF,+BAA+B;IAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,wDAAwD;QACxD,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACxC,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IAC1B,CAAC;SAAM,CAAC;QACN,uEAAuE;QACvE,kFAAkF;QAClF,kDAAkD;QAClD,MAAM,eAAe,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACnD,MAAM,eAAe,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAEnD,IAAI,WAAW,GAAG,KAAK,CAAA;QACvB,IAAI,WAAW,GAAG,KAAK,CAAA;QAEvB,uCAAuC;QACvC,IAAI,CAAC;YACH,mBAAmB,CAAC,eAAe,CAAC,CAAA;YACpC,WAAW,GAAG,IAAI,CAAA;QACpB,CAAC;QAAC,MAAM,CAAC;YACP,iCAAiC;QACnC,CAAC;QAED,iCAAiC;QACjC,IAAI,CAAC;YACH,mBAAmB,CAAC,eAAe,CAAC,CAAA;YACpC,WAAW,GAAG,IAAI,CAAA;QACpB,CAAC;QAAC,MAAM,CAAC;YACP,iCAAiC;QACnC,CAAC;QAED,oEAAoE;QACpE,yCAAyC;QACzC,IAAI,WAAW,EAAE,CAAC;YAChB,UAAU,GAAG,eAAe,CAAA;YAC5B,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACpC,CAAC;aAAM,IAAI,WAAW,EAAE,CAAC;YACvB,UAAU,GAAG,eAAe,CAAA;YAC5B,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACpC,CAAC;aAAM,CAAC;YACN,uCAAuC;YACvC,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;IAED,0BAA0B;IAC1B,IAAI,CAAC;QACH,mBAAmB,CAAC,UAAU,CAAC,CAAA;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAA;IACxB,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,CAAA;AAChC,CAAC;AAED;;;;GAIG;AACH,SAAS,gBAAgB,CAAC,OAAe;IACvC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACjC,MAAM,OAAO,GAAmB,EAAE,CAAA;IAElC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAA;QAC7B,IAAI,CAAC,IAAI;YAAE,SAAQ;QACnB,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAA;QAErC,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC;gBACX,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,UAAU,EAAE,CAAC,GAAG,CAAC;aAClB,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;;;GAIG;AACH,SAAS,2BAA2B,CAAC,UAAkB;IACrD,IAAI,CAAC;QACH,OAAO,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE;YACpC,0BAA0B,EAAE,KAAK;YACjC,OAAO,EAAE,KAAK;SACf,CAAC,CAAA;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACX,CAAC;AACL,CAAC;AAED,SAAS,UAAU,CAAC,OAA4B,EAAE,QAAkB;IAClE,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iEAmCiD,CAAA;IAC/D,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAA;AACzC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAc,EAAE,KAAY,EAAE,QAAkB;IAC5E,OAAO,IAAI,eAAe,CAAC;QACzB,OAAO,EAAE,MAAM;QACf,WAAW,EAAE,mCAAmC;QAChD,MAAM;QACN,KAAK;QACL,QAAQ;QACR,GAAG,EAAE,KAAK,EAAE,GAAW,EAAE,IAAc,EAAE,EAAE;YACzC,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAwB,CAAA;YAEhE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,CAAC;gBACzF,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;gBAC7B,OAAO,CAAC,CAAA;YACV,CAAC;YAED,MAAM,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;YAE1B,IAAI,CAAC;gBACH,QAAQ,UAAU,EAAE,CAAC;oBACnB,KAAK,MAAM,CAAC,CAAC,CAAC;wBACZ,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,CAAA;wBAC7C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;4BAC1B,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,sBAAsB,CAAC,CAAA;4BAC9D,OAAO,CAAC,CAAA;wBACV,CAAC;wBAED,mEAAmE;wBACnE,MAAM,cAAc,GAAG,IAAI,GAAG,EAAmD,CAAA;wBAEjF,8BAA8B;wBAC9B,IAAI,CAAC;4BACH,MAAM,iBAAiB,GAAG,cAAc,CAAA;4BACxC,IAAI,MAAM,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,EAAE,CAAC;gCACzD,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAA;gCAC/E,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;gCACzC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;oCAC5B,MAAM,OAAO,GAAG,eAAe,KAAK,CAAC,UAAU,EAAE,CAAA;oCACjD,cAAc,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;gCACvF,CAAC;4BACH,CAAC;wBACH,CAAC;wBAAC,MAAM,CAAC;4BACP,uCAAuC;wBACzC,CAAC;wBAED,4BAA4B;wBAC5B,IAAI,CAAC;4BACH,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,OAAO,CAAA;4BAC7C,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,CAAA;4BAC7D,IAAI,MAAM,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE,CAAC;gCAC5D,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC,CAAA;gCAClF,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;gCACzC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;oCAC5B,MAAM,OAAO,GAAG,aAAa,KAAK,CAAC,UAAU,EAAE,CAAA;oCAC/C,cAAc,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;gCACvF,CAAC;4BACH,CAAC;wBACH,CAAC;wBAAC,MAAM,CAAC;4BACP,qCAAqC;wBACvC,CAAC;wBAED,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,mBAAmB,CAAC,CAAA;wBAC3D,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;4BAC/B,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;4BAC3C,IAAI,OAAO,EAAE,CAAC;gCACZ,MAAM,WAAW,GAAG,2BAA2B,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;gCACnE,IAAI,WAAW,EAAE,CAAC;oCAChB,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,OAAO,EAAE,CAAC,CAAA;oCACtD,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,iBAAiB,OAAO,CAAC,UAAU,KAAK,WAAW,GAAG,CAAC,CAAA;oCAC9F,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,gBAAgB,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;gCAC3E,CAAC;qCAAM,CAAC;oCACN,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,OAAO,EAAE,CAAC,CAAA;oCACtD,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,iBAAiB,OAAO,CAAC,UAAU,EAAE,CAAC,CAAA;oCAC7E,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,gBAAgB,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;gCAC3E,CAAC;4BACH,CAAC;iCAAM,CAAC;gCACN,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,OAAO,EAAE,CAAC,CAAA;4BACxD,CAAC;wBACH,CAAC;wBACD,OAAO,CAAC,CAAA;oBACV,CAAC;oBAED,KAAK,KAAK,CAAC,CAAC,CAAC;wBACX,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;4BACpB,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,6BAA6B,CAAC,CAAA;4BACrE,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,sCAAsC,CAAC,CAAA;4BAC9E,OAAO,CAAC,CAAA;wBACV,CAAC;wBAED,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;wBACxB,IAAI,CAAC,QAAQ,EAAE,CAAC;4BACd,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,4BAA4B,CAAC,CAAA;4BACpE,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,sCAAsC,CAAC,CAAA;4BAC9E,OAAO,CAAC,CAAA;wBACV,CAAC;wBACD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;wBAEvC,+BAA+B;wBAC/B,IAAI,aAAa,GAAkB,IAAI,CAAA;wBACvC,IAAI,CAAC;4BACH,mBAAmB,CAAC,QAAQ,CAAC,CAAA;4BAC7B,aAAa,GAAG,2BAA2B,CAAC,QAAQ,CAAC,CAAA;wBACvD,CAAC;wBAAC,OAAO,KAAK,EAAE,CAAC;4BACf,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,sCAAsC,QAAQ,EAAE,CAAC,CAAA;4BACxF,OAAO,CAAC,CAAA;wBACV,CAAC;wBAED,0BAA0B;wBAC1B,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,OAAO,CAAA;wBAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;wBAC5C,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;wBAEnD,kCAAkC;wBAClC,IAAI,CAAC;4BACH,IAAI,CAAC,MAAM,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;gCACvD,MAAM,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;4BACvE,CAAC;wBACH,CAAC;wBAAC,OAAO,KAAK,EAAE,CAAC;4BACf,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,iDAAiD,KAAK,EAAE,CAAC,CAAA;4BAChG,OAAO,CAAC,CAAA;wBACV,CAAC;wBAED,sCAAsC;wBACtC,IAAI,cAAc,GAAG,EAAE,CAAA;wBACvB,IAAI,CAAC;4BACH,IAAI,MAAM,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;gCACxD,cAAc,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;gCAC/E,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oCAChE,cAAc,IAAI,IAAI,CAAA;gCACxB,CAAC;4BACH,CAAC;wBACH,CAAC;wBAAC,OAAO,KAAK,EAAE,CAAC;4BACf,mDAAmD;4BACnD,cAAc,GAAG,EAAE,CAAA;wBACrB,CAAC;wBAED,gBAAgB;wBAChB,cAAc,IAAI,GAAG,QAAQ,IAAI,OAAO,IAAI,CAAA;wBAE5C,qBAAqB;wBACrB,IAAI,CAAC;4BACH,MAAM,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,WAAW,EAAE,cAAc,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAA;wBAC/F,CAAC;wBAAC,OAAO,KAAK,EAAE,CAAC;4BACf,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,sCAAsC,KAAK,EAAE,CAAC,CAAA;4BACrF,OAAO,CAAC,CAAA;wBACV,CAAC;wBAED,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,mBAAmB,QAAQ,IAAI,OAAO,EAAE,CAAC,CAAA;wBAChF,IAAI,aAAa,EAAE,CAAC;4BAClB,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,eAAe,aAAa,EAAE,CAAC,CAAA;wBACxE,CAAC;wBACD,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,4CAA4C,CAAC,CAAA;wBACpF,OAAO,CAAC,CAAA;oBACV,CAAC;oBAED,KAAK,QAAQ,CAAC,CAAC,CAAC;wBACd,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;4BACpB,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,6BAA6B,CAAC,CAAA;4BACrE,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,yBAAyB,CAAC,CAAA;4BACjE,OAAO,CAAC,CAAA;wBACV,CAAC;wBAED,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;wBACrB,IAAI,CAAC,KAAK,EAAE,CAAC;4BACX,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,6BAA6B,CAAC,CAAA;4BACrE,OAAO,CAAC,CAAA;wBACV,CAAC;wBAED,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;wBAE9C,IAAI,CAAC,MAAM,EAAE,CAAC;4BACZ,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,+BAA+B,KAAK,EAAE,CAAC,CAAA;4BAC9E,OAAO,CAAC,CAAA;wBACV,CAAC;wBAED,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;wBAEjC,mDAAmD;wBACnD,IAAI,KAAK,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;4BACnC,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,OAAO,CAAA;4BAC7C,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,CAAA;4BAEzD,IAAI,CAAC;gCACH,IAAI,MAAM,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;oCACxD,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;oCAC9E,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;oCACjC,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAA;oCAEhE,IAAI,UAAU,GAAG,CAAC,IAAI,UAAU,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;wCACjD,2CAA2C;wCAC3C,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;wCACzC,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAyB,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,UAAU,CAAC,CAAA;wCAE9F,IAAI,aAAa,EAAE,CAAC;4CAClB,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,KAAK,UAAU,CAAC,CAAA;4CACjE,MAAM,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,WAAW,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAA;wCACpG,CAAC;oCACH,CAAC;gCACH,CAAC;4BACH,CAAC;4BAAC,OAAO,KAAK,EAAE,CAAC;gCACf,qCAAqC;gCACrC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,kCAAkC,KAAK,EAAE,CAAC,CAAA;4BAC5D,CAAC;wBACH,CAAC;wBAED,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,qBAAqB,KAAK,EAAE,CAAC,CAAA;wBACpE,OAAO,CAAC,CAAA;oBACV,CAAC;oBAED,KAAK,MAAM,CAAC,CAAC,CAAC;wBACZ,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,OAAO,CAAA;wBAC7C,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,CAAA;wBAEzD,wDAAwD;wBACxD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC;4BAClC,OAAO,EAAE,eAAe;4BACxB,IAAI,EAAE,CAAC,WAAW,CAAC;4BACnB,KAAK;4BACL,QAAQ;yBACT,CAAC,CAAA;wBAEF,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;4BACjB,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,qDAAqD,CAAC,CAAA;wBAC/F,CAAC;wBAED,OAAO,MAAM,CAAA;oBACf,CAAC;oBAED,KAAK,UAAU,CAAC,CAAC,CAAC;wBAChB,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;4BACpB,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,mCAAmC,CAAC,CAAA;4BAC3E,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,mCAAmC,CAAC,CAAA;4BAC3E,OAAO,CAAC,CAAA;wBACV,CAAC;wBAED,MAAM,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;wBAC1B,IAAI,CAAC,UAAU,EAAE,CAAC;4BAChB,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,mCAAmC,CAAC,CAAA;4BAC3E,OAAO,CAAC,CAAA;wBACV,CAAC;wBACD,IAAI,CAAC;4BACH,mBAAmB,CAAC,UAAU,CAAC,CAAA;4BAC/B,MAAM,WAAW,GAAG,2BAA2B,CAAC,UAAU,CAAC,CAAA;4BAC3D,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,0BAA0B,UAAU,EAAE,CAAC,CAAA;4BAC9E,IAAI,WAAW,EAAE,CAAC;gCAChB,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,kBAAkB,WAAW,EAAE,CAAC,CAAA;4BACzE,CAAC;4BACD,OAAO,CAAC,CAAA;wBACV,CAAC;wBAAC,OAAO,KAAK,EAAE,CAAC;4BACf,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,4BAA4B,UAAU,EAAE,CAAC,CAAA;4BAChF,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;4BAC1G,OAAO,CAAC,CAAA;wBACV,CAAC;oBACH,CAAC;oBAED,KAAK,MAAM,CAAC,CAAC,CAAC;wBACZ,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;4BACpB,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,+BAA+B,CAAC,CAAA;4BACvE,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,uCAAuC,CAAC,CAAA;4BAC/E,OAAO,CAAC,CAAA;wBACV,CAAC;wBAED,MAAM,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;wBAC1B,IAAI,CAAC,UAAU,EAAE,CAAC;4BAChB,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,+BAA+B,CAAC,CAAA;4BACvE,OAAO,CAAC,CAAA;wBACV,CAAC;wBACD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;wBAEpE,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;4BAC9B,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,yCAAyC,CAAC,CAAA;4BACjF,OAAO,CAAC,CAAA;wBACV,CAAC;wBAED,IAAI,CAAC;4BACH,MAAM,IAAI,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAA;4BAC5C,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAA;4BACtB,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;4BAC3C,MAAM,WAAW,GAAG,2BAA2B,CAAC,UAAU,CAAC,CAAA;4BAE3D,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,KAAK,2BAA2B,UAAU,IAAI,CAAC,CAAA;4BAC9F,IAAI,WAAW,EAAE,CAAC;gCAChB,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,eAAe,WAAW,EAAE,CAAC,CAAA;4BACtE,CAAC;4BACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gCACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;gCACrB,IAAI,IAAI,EAAE,CAAC;oCACT,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC,CAAA;gCAC7E,CAAC;4BACH,CAAC;4BACD,OAAO,CAAC,CAAA;wBACV,CAAC;wBAAC,OAAO,KAAK,EAAE,CAAC;4BACf,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,4BAA4B,UAAU,EAAE,CAAC,CAAA;4BAChF,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;4BAC1G,OAAO,CAAC,CAAA;wBACV,CAAC;oBACH,CAAC;oBAED,KAAK,MAAM,CAAC,CAAC,CAAC;wBACZ,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;4BACpB,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,+BAA+B,CAAC,CAAA;4BACvE,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,+BAA+B,CAAC,CAAA;4BACvE,OAAO,CAAC,CAAA;wBACV,CAAC;wBAED,MAAM,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;wBAC1B,IAAI,CAAC,UAAU,EAAE,CAAC;4BAChB,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,+BAA+B,CAAC,CAAA;4BACvE,OAAO,CAAC,CAAA;wBACV,CAAC;wBACD,IAAI,CAAC;4BACH,MAAM,IAAI,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAA;4BAC5C,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAA;4BACtB,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;4BACnC,MAAM,WAAW,GAAG,2BAA2B,CAAC,UAAU,CAAC,CAAA;4BAE3D,IAAI,OAAO,EAAE,CAAC;gCACZ,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,eAAe,UAAU,2BAA2B,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC,CAAA;4BACjH,CAAC;iCAAM,CAAC;gCACN,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,eAAe,UAAU,kCAAkC,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC,CAAA;4BACxH,CAAC;4BACD,IAAI,WAAW,EAAE,CAAC;gCAChB,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,eAAe,WAAW,EAAE,CAAC,CAAA;4BACtE,CAAC;4BACD,OAAO,CAAC,CAAA;wBACV,CAAC;wBAAC,OAAO,KAAK,EAAE,CAAC;4BACf,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,4BAA4B,UAAU,EAAE,CAAC,CAAA;4BAChF,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;4BAC1G,OAAO,CAAC,CAAA;wBACV,CAAC;oBACH,CAAC;oBAED,KAAK,QAAQ,CAAC,CAAC,CAAC;wBACd,+BAA+B;wBAC/B,MAAM,YAAY,GAAG,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,CAAA;wBACjD,KAAK,MAAM,OAAO,IAAI,YAAY,EAAE,CAAC;4BACnC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;wBACrC,CAAC;wBAED,wBAAwB;wBACxB,IAAI,CAAC;4BACH,MAAM,iBAAiB,GAAG,cAAc,CAAA;4BACxC,IAAI,MAAM,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,EAAE,CAAC;gCACzD,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAA;gCAC/E,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;gCAEzC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;oCAC5B,MAAM,OAAO,GAAG,eAAe,KAAK,CAAC,UAAU,EAAE,CAAA;oCACjD,MAAM,CAAC,SAAS,CAAC,OAAO,CACtB,OAAO,EACP,KAAK,CAAC,UAAU,EAChB,KAAK,IAAI,EAAE;wCACT,MAAM,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;oCAC3C,CAAC,EACD;wCACE,YAAY,EAAE,CAAC,GAAY,EAAE,EAAE;4CAC7B,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,OAAO,YAAY,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;wCACrG,CAAC;qCACF,CACF,CAAA;gCACH,CAAC;4BACH,CAAC;wBACH,CAAC;wBAAC,OAAO,KAAK,EAAE,CAAC;4BACf,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,kCAAkC,KAAK,EAAE,CAAC,CAAA;wBAC5D,CAAC;wBAED,sBAAsB;wBACtB,IAAI,CAAC;4BACH,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,OAAO,CAAA;4BAC7C,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,CAAA;4BAE7D,IAAI,MAAM,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE,CAAC;gCAC5D,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC,CAAA;gCAClF,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;gCAEzC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;oCAC5B,MAAM,OAAO,GAAG,aAAa,KAAK,CAAC,UAAU,EAAE,CAAA;oCAC/C,mDAAmD;oCACnD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAA;oCACpC,MAAM,CAAC,SAAS,CAAC,OAAO,CACtB,OAAO,EACP,KAAK,CAAC,UAAU,EAChB,KAAK,IAAI,EAAE;wCACT,MAAM,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;oCACrC,CAAC,EACD;wCACE,YAAY,EAAE,CAAC,GAAY,EAAE,EAAE;4CAC7B,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,OAAO,YAAY,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;wCACrG,CAAC;qCACF,CACF,CAAA;gCACH,CAAC;4BACH,CAAC;wBACH,CAAC;wBAAC,OAAO,KAAK,EAAE,CAAC;4BACf,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,gCAAgC,KAAK,EAAE,CAAC,CAAA;wBAC1D,CAAC;wBAED,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,oBAAoB,CAAC,CAAA;wBAC5D,OAAO,CAAC,CAAA;oBACV,CAAC;oBAED;wBACE,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,0BAA0B,UAAU,EAAE,CAAC,CAAA;wBAC9E,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,yCAAyC,CAAC,CAAA;wBACjF,OAAO,CAAC,CAAA;gBACZ,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,gBAAgB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;gBAChH,OAAO,CAAC,CAAA;YACV,CAAC;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC"}
|