@qelos/aidev 0.5.3 → 0.6.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.
@@ -403,16 +403,16 @@ async function checkNeedsClarification(task, config, provider, runners) {
403
403
  logger_1.logger.warn('No AI runner available — skipping clarification check');
404
404
  return null;
405
405
  }
406
- const clarificationPrompt = `You are a senior software developer reviewing a task.
407
- Determine if the following task has enough information to implement without further clarification.
408
-
409
- Task name: ${task.name}
410
- Task description: ${task.description || '(no description)'}
411
-
412
- Respond with valid JSON only:
413
- {
414
- "clear": true|false,
415
- "question": "question to ask if not clear, or null"
406
+ const clarificationPrompt = `You are a senior software developer reviewing a task.
407
+ Determine if the following task has enough information to implement without further clarification.
408
+
409
+ Task name: ${task.name}
410
+ Task description: ${task.description || '(no description)'}
411
+
412
+ Respond with valid JSON only:
413
+ {
414
+ "clear": true|false,
415
+ "question": "question to ask if not clear, or null"
416
416
  }`;
417
417
  for (const runner of availableRunners) {
418
418
  const result = await runner.run(clarificationPrompt);
@@ -440,30 +440,30 @@ Respond with valid JSON only:
440
440
  return null;
441
441
  }
442
442
  function buildConflictResolutionPrompt(task, conflictFiles, context) {
443
- return `You are resolving merge conflicts in a software development task branch.
444
-
445
- The task branch has fallen behind the base branch and has merge conflicts that need to be resolved.
446
-
447
- ## Task context (DO NOT break this — the task must still work after conflict resolution)
448
-
449
- Task: ${task.name}
450
-
451
- Description:
452
- ${task.description || '(no description provided)'}
453
- ${context}
454
-
455
- ## Merge conflicts
456
-
457
- The following files have merge conflicts with conflict markers (<<<<<<< HEAD, =======, >>>>>>> ...):
458
- ${conflictFiles.map((f) => `- ${f}`).join('\n')}
459
-
460
- ## Instructions
461
-
462
- 1. Open each conflicting file and resolve the conflict markers
463
- 2. Keep BOTH the task's changes AND the base branch updates where possible
464
- 3. If the base branch changed something the task also changed, prefer the task's intent but make sure it works with the new base branch code
465
- 4. Remove all conflict markers (<<<<<<< HEAD, =======, >>>>>>> ...)
466
- 5. Make sure the code compiles and is consistent after resolution
443
+ return `You are resolving merge conflicts in a software development task branch.
444
+
445
+ The task branch has fallen behind the base branch and has merge conflicts that need to be resolved.
446
+
447
+ ## Task context (DO NOT break this — the task must still work after conflict resolution)
448
+
449
+ Task: ${task.name}
450
+
451
+ Description:
452
+ ${task.description || '(no description provided)'}
453
+ ${context}
454
+
455
+ ## Merge conflicts
456
+
457
+ The following files have merge conflicts with conflict markers (<<<<<<< HEAD, =======, >>>>>>> ...):
458
+ ${conflictFiles.map((f) => `- ${f}`).join('\n')}
459
+
460
+ ## Instructions
461
+
462
+ 1. Open each conflicting file and resolve the conflict markers
463
+ 2. Keep BOTH the task's changes AND the base branch updates where possible
464
+ 3. If the base branch changed something the task also changed, prefer the task's intent but make sure it works with the new base branch code
465
+ 4. Remove all conflict markers (<<<<<<< HEAD, =======, >>>>>>> ...)
466
+ 5. Make sure the code compiles and is consistent after resolution
467
467
  6. Do NOT make any changes beyond what is needed to resolve the conflicts`;
468
468
  }
469
469
  async function resolveConflictsWithAI(task, config, provider, runners, context, hooks, vm, branchName) {
@@ -731,14 +731,14 @@ async function implementTask(task, branchName, branchExists, config, provider, r
731
731
  logger_1.logger.success(`Task implemented: branch ${branchName} pushed`);
732
732
  }
733
733
  function buildImplementPrompt(task, context) {
734
- return `You are implementing a software development task. Make the necessary code changes to complete the task described below.
735
-
736
- Task: ${task.name}
737
-
738
- Description:
739
- ${task.description || '(no description provided)'}
740
- ${context}
741
-
734
+ return `You are implementing a software development task. Make the necessary code changes to complete the task described below.
735
+
736
+ Task: ${task.name}
737
+
738
+ Description:
739
+ ${task.description || '(no description provided)'}
740
+ ${context}
741
+
742
742
  Please implement the required changes. Focus on correctness and follow the existing code style in the project.`;
743
743
  }
744
744
  async function analyzeAndPlan(task, context, runners) {
@@ -747,28 +747,28 @@ async function analyzeAndPlan(task, context, runners) {
747
747
  logger_1.logger.error('No AI runner available for task analysis');
748
748
  return null;
749
749
  }
750
- const analysisPrompt = `You are a senior software architect breaking down a development task into smaller, sequential implementation steps.
751
-
752
- Task name: ${task.name}
753
-
754
- Description:
755
- ${task.description || '(no description provided)'}
756
- ${context}
757
-
758
- Analyze this task and break it into smaller, independently implementable sub-tasks that should be executed sequentially. Each sub-task should be a coherent unit of work that can be committed separately.
759
-
760
- Respond with valid JSON only — no markdown fences, no extra text:
761
- {
762
- "instructions": "Detailed implementation instructions in markdown covering the full task — architecture decisions, key files to modify, edge cases to handle, testing approach",
763
- "subtasks": [
764
- {
765
- "id": 1,
766
- "title": "Short title for the sub-task",
767
- "description": "Detailed description of what to implement in this step, including specific files and functions to change"
768
- }
769
- ]
770
- }
771
-
750
+ const analysisPrompt = `You are a senior software architect breaking down a development task into smaller, sequential implementation steps.
751
+
752
+ Task name: ${task.name}
753
+
754
+ Description:
755
+ ${task.description || '(no description provided)'}
756
+ ${context}
757
+
758
+ Analyze this task and break it into smaller, independently implementable sub-tasks that should be executed sequentially. Each sub-task should be a coherent unit of work that can be committed separately.
759
+
760
+ Respond with valid JSON only — no markdown fences, no extra text:
761
+ {
762
+ "instructions": "Detailed implementation instructions in markdown covering the full task — architecture decisions, key files to modify, edge cases to handle, testing approach",
763
+ "subtasks": [
764
+ {
765
+ "id": 1,
766
+ "title": "Short title for the sub-task",
767
+ "description": "Detailed description of what to implement in this step, including specific files and functions to change"
768
+ }
769
+ ]
770
+ }
771
+
772
772
  Keep sub-tasks focused: 2-6 sub-tasks is ideal. Order them by dependency (foundation first).`;
773
773
  logger_1.logger.info('Analyzing task and creating implementation plan...');
774
774
  const result = await runner.run(analysisPrompt);
@@ -820,31 +820,31 @@ async function splitFailedSubtask(parentTask, plan, failedSubtask, runners) {
820
820
  const diagnostics = failedSubtask.lastError && failedSubtask.lastError !== '__git__'
821
821
  ? failedSubtask.lastError
822
822
  : '(no diagnostics captured)';
823
- const splitPrompt = `You are a senior software architect helping recover a stalled implementation step by splitting it into exactly two smaller, sequential sub-tasks.
824
-
825
- Overall task: ${parentTask.name}
826
- ${parentTask.description ? `\nTask description:\n${parentTask.description}\n` : ''}
827
- ## Surrounding plan
828
- ${siblings || '(no sibling sub-tasks)'}
829
-
830
- ## Failed sub-task
831
- ID: ${formatSubtaskId(failedSubtask.id)}
832
- Title: ${failedSubtask.title}
833
- Description: ${failedSubtask.description}
834
-
835
- ## Previous failure diagnostics
836
- ${diagnostics}
837
-
838
- Split the failed sub-task above into exactly two smaller, independently implementable sub-tasks that together achieve the original goal. Each new sub-task should be a coherent unit of work that can be committed separately, ordered by dependency (foundation first). Take the diagnostics into account so the split actually addresses what broke.
839
-
840
- Respond with valid JSON only — no markdown fences, no extra text:
841
- {
842
- "subtasks": [
843
- { "title": "Short title for the first new sub-task", "description": "Detailed description of what to implement in this step" },
844
- { "title": "Short title for the second new sub-task", "description": "Detailed description of what to implement in this step" }
845
- ]
846
- }
847
-
823
+ const splitPrompt = `You are a senior software architect helping recover a stalled implementation step by splitting it into exactly two smaller, sequential sub-tasks.
824
+
825
+ Overall task: ${parentTask.name}
826
+ ${parentTask.description ? `\nTask description:\n${parentTask.description}\n` : ''}
827
+ ## Surrounding plan
828
+ ${siblings || '(no sibling sub-tasks)'}
829
+
830
+ ## Failed sub-task
831
+ ID: ${formatSubtaskId(failedSubtask.id)}
832
+ Title: ${failedSubtask.title}
833
+ Description: ${failedSubtask.description}
834
+
835
+ ## Previous failure diagnostics
836
+ ${diagnostics}
837
+
838
+ Split the failed sub-task above into exactly two smaller, independently implementable sub-tasks that together achieve the original goal. Each new sub-task should be a coherent unit of work that can be committed separately, ordered by dependency (foundation first). Take the diagnostics into account so the split actually addresses what broke.
839
+
840
+ Respond with valid JSON only — no markdown fences, no extra text:
841
+ {
842
+ "subtasks": [
843
+ { "title": "Short title for the first new sub-task", "description": "Detailed description of what to implement in this step" },
844
+ { "title": "Short title for the second new sub-task", "description": "Detailed description of what to implement in this step" }
845
+ ]
846
+ }
847
+
848
848
  Exactly two entries — no more, no fewer.`;
849
849
  logger_1.logger.info(`Splitting failed sub-task ${formatSubtaskId(failedSubtask.id)} into two smaller steps...`);
850
850
  const result = await runner.run(splitPrompt);
@@ -899,20 +899,20 @@ async function executeSubTask(subtask, task, plan, config, runners, reviewContex
899
899
  const retrySection = previousError && previousError !== '__git__'
900
900
  ? `\n## Previous attempt failure diagnostics\nThis step failed on a previous attempt. Diagnostics below — please take them into account and avoid repeating the same failure.\n\n${previousError}\n`
901
901
  : '';
902
- const prompt = `You are implementing step ${subtask.id} of a multi-step task.
903
-
904
- Overall task: ${task.name}
905
- ${task.description ? `\nTask description:\n${task.description}` : ''}
906
-
907
- ## Full implementation instructions
908
- ${instructions}
909
- ${reviewContext || ''}${retrySection}
910
- ## Progress
911
- ${completedSteps || '(no steps completed yet)'}
912
-
913
- ## Current step: ${subtask.id}. ${subtask.title}
914
- ${subtask.description}
915
-
902
+ const prompt = `You are implementing step ${subtask.id} of a multi-step task.
903
+
904
+ Overall task: ${task.name}
905
+ ${task.description ? `\nTask description:\n${task.description}` : ''}
906
+
907
+ ## Full implementation instructions
908
+ ${instructions}
909
+ ${reviewContext || ''}${retrySection}
910
+ ## Progress
911
+ ${completedSteps || '(no steps completed yet)'}
912
+
913
+ ## Current step: ${subtask.id}. ${subtask.title}
914
+ ${subtask.description}
915
+
916
916
  Implement ONLY this step. Focus on correctness and follow the existing code style.`;
917
917
  let implemented = false;
918
918
  let previousNotes = '';
@@ -1191,29 +1191,29 @@ function buildCompletionComment(branch, prUrl, config) {
1191
1191
  function buildNonCodePrompt(task, context) {
1192
1192
  const hasComments = context.trim().length > 0;
1193
1193
  if (hasComments) {
1194
- return `Task: ${task.name}
1195
-
1196
- Original description:
1197
- ${task.description || '(no description provided)'}
1198
- ${context}
1199
-
1200
- ⚠️ CRITICAL: This is a FOLLOW-UP request. The conversation above contains new comments from the user.
1201
- YOUR PRIMARY TASK is to address the LATEST comment at the bottom of the conversation - this is the user's current request.
1202
- The latest comment may:
1203
- - Ask for something completely different from the original task
1204
- - Request modifications to what was already done
1205
- - Add new requirements
1206
-
1207
- DO NOT repeat what was already done. DO NOT re-execute the original task unless explicitly asked.
1208
- Focus ENTIRELY on addressing the latest comment as your main instruction.
1209
-
1194
+ return `Task: ${task.name}
1195
+
1196
+ Original description:
1197
+ ${task.description || '(no description provided)'}
1198
+ ${context}
1199
+
1200
+ ⚠️ CRITICAL: This is a FOLLOW-UP request. The conversation above contains new comments from the user.
1201
+ YOUR PRIMARY TASK is to address the LATEST comment at the bottom of the conversation - this is the user's current request.
1202
+ The latest comment may:
1203
+ - Ask for something completely different from the original task
1204
+ - Request modifications to what was already done
1205
+ - Add new requirements
1206
+
1207
+ DO NOT repeat what was already done. DO NOT re-execute the original task unless explicitly asked.
1208
+ Focus ENTIRELY on addressing the latest comment as your main instruction.
1209
+
1210
1210
  Please provide a clear, detailed response to the LATEST comment. Your response will be posted as a comment on the task ticket, so write it as a direct answer or explanation addressed to the person who wrote the latest comment.`;
1211
1211
  }
1212
- return `Task: ${task.name}
1213
-
1214
- Description:
1215
- ${task.description || '(no description provided)'}
1216
-
1212
+ return `Task: ${task.name}
1213
+
1214
+ Description:
1215
+ ${task.description || '(no description provided)'}
1216
+
1217
1217
  Please provide a clear, detailed response to this task. Your response will be posted as a comment on the task ticket, so write it as a direct answer or explanation addressed to the person who created the task.`;
1218
1218
  }
1219
1219
  function buildNonCodeCompletionComment(config, agentResponse) {
@@ -1523,22 +1523,22 @@ async function implementReviewTask(task, branchName, config, provider, runners,
1523
1523
  logger_1.logger.success(`Review comments addressed for: ${task.name}`);
1524
1524
  }
1525
1525
  function buildReviewPrompt(task, threads) {
1526
- let prompt = `You are addressing code review comments on a pull request for a software development task.
1527
-
1528
- Task: ${task.name}
1529
-
1530
- Description:
1531
- ${task.description || '(no description provided)'}
1532
-
1533
- ## Unresolved Code Review Threads
1534
-
1535
- The following review threads need to be addressed. For each thread, either:
1536
- - Fix the code as requested (make the changes directly in the files)
1537
- - Or, if it's a discussion/question that doesn't require code changes, output a REPLY block:
1538
- <!-- AIDEV-REPLY thread_id -->Your reply here<!-- /AIDEV-REPLY -->
1539
-
1540
- Replace "thread_id" with the actual thread ID shown below.
1541
-
1526
+ let prompt = `You are addressing code review comments on a pull request for a software development task.
1527
+
1528
+ Task: ${task.name}
1529
+
1530
+ Description:
1531
+ ${task.description || '(no description provided)'}
1532
+
1533
+ ## Unresolved Code Review Threads
1534
+
1535
+ The following review threads need to be addressed. For each thread, either:
1536
+ - Fix the code as requested (make the changes directly in the files)
1537
+ - Or, if it's a discussion/question that doesn't require code changes, output a REPLY block:
1538
+ <!-- AIDEV-REPLY thread_id -->Your reply here<!-- /AIDEV-REPLY -->
1539
+
1540
+ Replace "thread_id" with the actual thread ID shown below.
1541
+
1542
1542
  `;
1543
1543
  for (const thread of threads) {
1544
1544
  const location = thread.line
@@ -1550,12 +1550,12 @@ Replace "thread_id" with the actual thread ID shown below.
1550
1550
  }
1551
1551
  prompt += '\n';
1552
1552
  }
1553
- prompt += `## Instructions
1554
-
1555
- 1. Read each review thread carefully
1556
- 2. For code change requests: make the fix directly in the relevant file(s)
1557
- 3. For questions or discussions: output a REPLY block with a clear, helpful response
1558
- 4. You may handle multiple threads — some with code fixes, others with replies
1553
+ prompt += `## Instructions
1554
+
1555
+ 1. Read each review thread carefully
1556
+ 2. For code change requests: make the fix directly in the relevant file(s)
1557
+ 3. For questions or discussions: output a REPLY block with a clear, helpful response
1558
+ 4. You may handle multiple threads — some with code fixes, others with replies
1559
1559
  5. Focus on correctness and follow the existing code style`;
1560
1560
  return prompt;
1561
1561
  }
@@ -1,4 +1,17 @@
1
- export declare function buildUnixCronLine(cronExpr: string, cwd: string, nodeBin: string, aidevBin: string): string;
1
+ /**
2
+ * Quotes an arg for embedding inside a single-quoted shell command
3
+ * (e.g. inside `zsh -c '…'`). Inside the outer single quotes the inner
4
+ * string is parsed as shell, so we use double quotes and escape `\ $ ` "`.
5
+ * Single quotes are not supported (would close the outer quote).
6
+ */
7
+ export declare function shQuoteForCron(s: string): string;
8
+ /** Tokenises a shell-style arg string we generated (unquoted or double-quoted). */
9
+ export declare function tokenizeShellArgs(s: string): string[];
10
+ /** Quotes an arg for embedding into a Windows schtasks /tr command string. */
11
+ export declare function cmdQuoteForSchtasks(s: string): string;
12
+ export declare function buildUnixCronLine(cronExpr: string, cwd: string, nodeBin: string, aidevBin: string, extraArgs?: string[]): string;
13
+ /** Extracts the extra args (after `aidev run`) from an existing cron line. */
14
+ export declare function extractUnixCronArgs(line: string): string[];
2
15
  export type LaunchdSchedule = {
3
16
  key: 'StartInterval';
4
17
  seconds: number;
@@ -12,7 +25,9 @@ export type LaunchdSchedule = {
12
25
  * Supports the same subset as cronToSchtasksArgs.
13
26
  */
14
27
  export declare function cronToLaunchdSchedule(cron: string): LaunchdSchedule | null;
15
- export declare function buildLaunchAgentPlist(label: string, nodeBin: string, aidevBin: string, cwd: string, schedule: LaunchdSchedule): string;
28
+ export declare function buildLaunchAgentPlist(label: string, nodeBin: string, aidevBin: string, cwd: string, schedule: LaunchdSchedule, extraArgs?: string[]): string;
29
+ /** Extracts the user-supplied extra args from an existing LaunchAgent plist. */
30
+ export declare function extractLaunchAgentArgs(xml: string): string[];
16
31
  /**
17
32
  * Converts a cron expression to schtasks /sc + /mo + /st arguments.
18
33
  * Supports the subset used by the preset list.
@@ -22,7 +37,7 @@ export declare function cronToSchtasksArgs(cron: string): string[] | null;
22
37
  export declare function windowsTaskName(cwd: string, cronExpr?: string): string;
23
38
  /** Extracts the launchd schedule object from a plist XML string. */
24
39
  export declare function extractLaunchdSchedule(xml: string): LaunchdSchedule | null;
25
- export declare function scheduleSetCommand(cronExpr?: string): Promise<void>;
40
+ export declare function scheduleSetCommand(cronExpr?: string, extraArgs?: string[]): Promise<void>;
26
41
  export declare function scheduleGetCommand(): Promise<void>;
27
42
  export declare function scheduleRemoveCommand(id?: number): Promise<void>;
28
43
  export declare function scheduleFixCommand(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"schedule.d.ts","sourceRoot":"","sources":["../../src/commands/schedule.ts"],"names":[],"mappings":"AA4DA,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAG1G;AAoJD,MAAM,MAAM,eAAe,GACvB;IAAE,GAAG,EAAE,eAAe,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,GAAG,EAAE,uBAAuB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnE;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAiB1E;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,eAAe,GACxB,MAAM,CAiDR;AAsKD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAiBhE;AAED,wFAAwF;AACxF,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAKtE;AAqID,oEAAoE;AACpE,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAc1E;AAkFD,wBAAsB,kBAAkB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKzE;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAIxD;AAED,wBAAsB,qBAAqB,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAItE;AAED,wBAAgB,kBAAkB,IAAI,IAAI,CAIzC"}
1
+ {"version":3,"file":"schedule.d.ts","sourceRoot":"","sources":["../../src/commands/schedule.ts"],"names":[],"mappings":"AAgDA;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAMhD;AAED,mFAAmF;AACnF,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAYrD;AAED,8EAA8E;AAC9E,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAGrD;AAgBD,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,SAAS,GAAE,MAAM,EAAO,GACvB,MAAM,CAIR;AAED,8EAA8E;AAC9E,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAM1D;AAiKD,MAAM,MAAM,eAAe,GACvB;IAAE,GAAG,EAAE,eAAe,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,GAAG,EAAE,uBAAuB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnE;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAiB1E;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,eAAe,EACzB,SAAS,GAAE,MAAM,EAAO,GACvB,MAAM,CAkDR;AAiDD,gFAAgF;AAChF,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAO5D;AA2HD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAiBhE;AAED,wFAAwF;AACxF,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAKtE;AAsID,oEAAoE;AACpE,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAc1E;AAkFD,wBAAsB,kBAAkB,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,SAAS,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAKnG;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAIxD;AAED,wBAAsB,qBAAqB,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAItE;AAED,wBAAgB,kBAAkB,IAAI,IAAI,CAIzC"}