@ginkoai/cli 2.5.0 → 2.5.2

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 (104) hide show
  1. package/dist/analysis/deep-analyzer.js +7 -7
  2. package/dist/analysis/deep-analyzer.js.map +1 -1
  3. package/dist/analysis/project-analyzer.js +2 -2
  4. package/dist/analysis/project-analyzer.js.map +1 -1
  5. package/dist/commands/graph/init.d.ts.map +1 -1
  6. package/dist/commands/graph/init.js +2 -4
  7. package/dist/commands/graph/init.js.map +1 -1
  8. package/dist/commands/handoff.d.ts +1 -0
  9. package/dist/commands/handoff.d.ts.map +1 -1
  10. package/dist/commands/handoff.js +55 -9
  11. package/dist/commands/handoff.js.map +1 -1
  12. package/dist/commands/health.js +1 -0
  13. package/dist/commands/health.js.map +1 -1
  14. package/dist/commands/init.d.ts.map +1 -1
  15. package/dist/commands/init.js +134 -0
  16. package/dist/commands/init.js.map +1 -1
  17. package/dist/commands/migrate/status-migration.d.ts.map +1 -1
  18. package/dist/commands/migrate/status-migration.js +2 -4
  19. package/dist/commands/migrate/status-migration.js.map +1 -1
  20. package/dist/commands/pull/pull-command.d.ts.map +1 -1
  21. package/dist/commands/pull/pull-command.js +11 -1
  22. package/dist/commands/pull/pull-command.js.map +1 -1
  23. package/dist/commands/push/push-command.d.ts.map +1 -1
  24. package/dist/commands/push/push-command.js +10 -0
  25. package/dist/commands/push/push-command.js.map +1 -1
  26. package/dist/commands/sprint/index.d.ts.map +1 -1
  27. package/dist/commands/sprint/index.js +15 -0
  28. package/dist/commands/sprint/index.js.map +1 -1
  29. package/dist/commands/sprint/plan-check.d.ts +16 -0
  30. package/dist/commands/sprint/plan-check.d.ts.map +1 -0
  31. package/dist/commands/sprint/plan-check.js +122 -0
  32. package/dist/commands/sprint/plan-check.js.map +1 -0
  33. package/dist/commands/sprint/status.d.ts +1 -1
  34. package/dist/commands/sprint/status.d.ts.map +1 -1
  35. package/dist/commands/sprint/status.js +23 -1
  36. package/dist/commands/sprint/status.js.map +1 -1
  37. package/dist/commands/start/start-reflection.d.ts.map +1 -1
  38. package/dist/commands/start/start-reflection.js +28 -11
  39. package/dist/commands/start/start-reflection.js.map +1 -1
  40. package/dist/commands/sync/node-syncer.d.ts +3 -1
  41. package/dist/commands/sync/node-syncer.d.ts.map +1 -1
  42. package/dist/commands/sync/node-syncer.js +13 -2
  43. package/dist/commands/sync/node-syncer.js.map +1 -1
  44. package/dist/commands/sync/sprint-syncer.d.ts.map +1 -1
  45. package/dist/commands/sync/sprint-syncer.js +2 -4
  46. package/dist/commands/sync/sprint-syncer.js.map +1 -1
  47. package/dist/commands/sync/types.d.ts +1 -1
  48. package/dist/commands/sync/types.d.ts.map +1 -1
  49. package/dist/commands/task/status.d.ts.map +1 -1
  50. package/dist/commands/task/status.js +228 -0
  51. package/dist/commands/task/status.js.map +1 -1
  52. package/dist/index.js +1 -0
  53. package/dist/index.js.map +1 -1
  54. package/dist/lib/health-checker.d.ts.map +1 -1
  55. package/dist/lib/health-checker.js +80 -7
  56. package/dist/lib/health-checker.js.map +1 -1
  57. package/dist/lib/integration-warnings.d.ts +72 -0
  58. package/dist/lib/integration-warnings.d.ts.map +1 -0
  59. package/dist/lib/integration-warnings.js +273 -0
  60. package/dist/lib/integration-warnings.js.map +1 -0
  61. package/dist/lib/notification-hooks.js +1 -1
  62. package/dist/lib/notification-hooks.js.map +1 -1
  63. package/dist/lib/output-formatter.d.ts +1 -1
  64. package/dist/lib/output-formatter.d.ts.map +1 -1
  65. package/dist/lib/output-formatter.js +31 -1
  66. package/dist/lib/output-formatter.js.map +1 -1
  67. package/dist/lib/protected-manifest.d.ts +34 -0
  68. package/dist/lib/protected-manifest.d.ts.map +1 -0
  69. package/dist/lib/protected-manifest.js +112 -0
  70. package/dist/lib/protected-manifest.js.map +1 -0
  71. package/dist/lib/protection-hook.d.ts +35 -0
  72. package/dist/lib/protection-hook.d.ts.map +1 -0
  73. package/dist/lib/protection-hook.js +154 -0
  74. package/dist/lib/protection-hook.js.map +1 -0
  75. package/dist/lib/realtime-cursor.js +3 -3
  76. package/dist/lib/realtime-cursor.js.map +1 -1
  77. package/dist/lib/session-health.d.ts +75 -0
  78. package/dist/lib/session-health.d.ts.map +1 -0
  79. package/dist/lib/session-health.js +252 -0
  80. package/dist/lib/session-health.js.map +1 -0
  81. package/dist/lib/sprint-state.d.ts +82 -0
  82. package/dist/lib/sprint-state.d.ts.map +1 -0
  83. package/dist/lib/sprint-state.js +338 -0
  84. package/dist/lib/sprint-state.js.map +1 -0
  85. package/dist/lib/structural-safeguards.d.ts +26 -0
  86. package/dist/lib/structural-safeguards.d.ts.map +1 -0
  87. package/dist/lib/structural-safeguards.js +91 -0
  88. package/dist/lib/structural-safeguards.js.map +1 -0
  89. package/dist/lib/sync/scanner.d.ts.map +1 -1
  90. package/dist/lib/sync/scanner.js +3 -5
  91. package/dist/lib/sync/scanner.js.map +1 -1
  92. package/dist/lib/task-parser.d.ts +2 -0
  93. package/dist/lib/task-parser.d.ts.map +1 -1
  94. package/dist/lib/task-parser.js +30 -0
  95. package/dist/lib/task-parser.js.map +1 -1
  96. package/dist/templates/ai-instructions-template.d.ts +11 -0
  97. package/dist/templates/ai-instructions-template.d.ts.map +1 -1
  98. package/dist/templates/ai-instructions-template.js +184 -0
  99. package/dist/templates/ai-instructions-template.js.map +1 -1
  100. package/dist/templates/sprint-template.md +52 -0
  101. package/dist/utils/reference-parser.d.ts.map +1 -1
  102. package/dist/utils/reference-parser.js +3 -6
  103. package/dist/utils/reference-parser.js.map +1 -1
  104. package/package.json +2 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-health.d.ts","sourceRoot":"","sources":["../../src/lib/session-health.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA2BH,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,gBAAgB,GAAG,qBAAqB,CAAC;AAEvF,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,yCAAyC;IACzC,cAAc,EAAE,MAAM,CAAC;IACvB,iDAAiD;IACjD,cAAc,EAAE,MAAM,CAAC;IACvB,sDAAsD;IACtD,eAAe,EAAE,MAAM,CAAC;IACxB,mDAAmD;IACnD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,2DAA2D;IAC3D,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gEAAgE;IAChE,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAMD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,kBAAkB,EAAE,gBAOhC,CAAC;AAMF;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,EACvB,UAAU,GAAE,gBAAqC,GAChD,cAAc,CAkChB;AAwBD;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAoClF;AAED;;GAEG;AACH,wBAAsB,yBAAyB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAuCrF;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAepF;AAMD;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAQxF;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAEtE"}
@@ -0,0 +1,252 @@
1
+ /**
2
+ * @fileType: utility
3
+ * @status: current
4
+ * @updated: 2026-03-15
5
+ * @tags: [session-health, context-pressure, degradation, epic-025]
6
+ * @related: [context-metrics.ts, output-formatter.ts, health-checker.ts]
7
+ * @priority: high
8
+ * @complexity: low
9
+ * @dependencies: [fs-extra]
10
+ */
11
+ /**
12
+ * Session Health Tier Calculation (EPIC-025 Sprint 4)
13
+ *
14
+ * Calculates a health tier from session metrics (message count, duration)
15
+ * to surface context degradation risk to the human partner.
16
+ *
17
+ * The AI partner under cognitive load is the worst judge of its own
18
+ * degradation — EPIC-024 proved this at ~40 messages / ~200K tokens.
19
+ * The human needs the signal.
20
+ *
21
+ * Thresholds calibrated against EPIC-023/024 session data:
22
+ * - EPIC-024: First deployment failure at ~35 messages, serial bug fixing at ~45
23
+ * - EPIC-023: Context score drop at ~30 messages, CLI interop bugs at ~40
24
+ *
25
+ * Compression events: Claude Code does NOT emit hook events for /compact.
26
+ * Message count + duration remain the primary degradation signals.
27
+ */
28
+ import fs from 'fs-extra';
29
+ import path from 'path';
30
+ // =============================================================================
31
+ // Defaults
32
+ // =============================================================================
33
+ /**
34
+ * Default thresholds calibrated against EPIC-023/024 session data.
35
+ *
36
+ * EPIC-024 (262K token session):
37
+ * - Deployment failures began at ~35 messages
38
+ * - Serial bug fixing pattern at ~45 messages
39
+ * - Subagent collision at ~50 messages
40
+ *
41
+ * EPIC-023 (multi-session analysis):
42
+ * - Context score degradation at ~30 messages
43
+ * - CLI interop bugs surfaced at ~40 messages
44
+ * - E2E walkthrough late verification at ~45 messages
45
+ */
46
+ export const DEFAULT_THRESHOLDS = {
47
+ steadyMessages: 15,
48
+ verifyMessages: 35,
49
+ handoffMessages: 50,
50
+ steadyDurationMin: 60,
51
+ verifyDurationMin: 180,
52
+ handoffDurationMin: 300,
53
+ };
54
+ // =============================================================================
55
+ // Tier Calculation
56
+ // =============================================================================
57
+ /**
58
+ * Calculate health tier from message count and session duration.
59
+ *
60
+ * Uses the higher of message-based or duration-based tier
61
+ * (whichever indicates more pressure).
62
+ */
63
+ export function calculateHealthTier(messageCount, durationMinutes, thresholds = DEFAULT_THRESHOLDS) {
64
+ // Message-based tier
65
+ let messageTier = 'fresh';
66
+ if (messageCount >= thresholds.handoffMessages) {
67
+ messageTier = 'handoff-recommended';
68
+ }
69
+ else if (messageCount >= thresholds.verifyMessages) {
70
+ messageTier = 'verify-deploys';
71
+ }
72
+ else if (messageCount >= thresholds.steadyMessages) {
73
+ messageTier = 'steady';
74
+ }
75
+ // Duration-based tier
76
+ let durationTier = 'fresh';
77
+ if (durationMinutes >= thresholds.handoffDurationMin) {
78
+ durationTier = 'handoff-recommended';
79
+ }
80
+ else if (durationMinutes >= thresholds.verifyDurationMin) {
81
+ durationTier = 'verify-deploys';
82
+ }
83
+ else if (durationMinutes >= thresholds.steadyDurationMin) {
84
+ durationTier = 'steady';
85
+ }
86
+ // Use the higher (more concerning) tier
87
+ const tierOrder = ['fresh', 'steady', 'verify-deploys', 'handoff-recommended'];
88
+ const messageIdx = tierOrder.indexOf(messageTier);
89
+ const durationIdx = tierOrder.indexOf(durationTier);
90
+ const tier = tierOrder[Math.max(messageIdx, durationIdx)];
91
+ return {
92
+ tier,
93
+ icon: getTierIcon(tier),
94
+ label: getTierLabel(tier),
95
+ messageCount,
96
+ durationMinutes,
97
+ };
98
+ }
99
+ function getTierIcon(tier) {
100
+ switch (tier) {
101
+ case 'fresh': return '✅';
102
+ case 'steady': return '◐';
103
+ case 'verify-deploys': return '⚠️';
104
+ case 'handoff-recommended': return '🔄';
105
+ }
106
+ }
107
+ function getTierLabel(tier) {
108
+ switch (tier) {
109
+ case 'fresh': return 'fresh';
110
+ case 'steady': return 'steady';
111
+ case 'verify-deploys': return 'verify deploys';
112
+ case 'handoff-recommended': return 'handoff recommended';
113
+ }
114
+ }
115
+ // =============================================================================
116
+ // Session Metrics Extraction
117
+ // =============================================================================
118
+ /**
119
+ * Count messages in the current session from events JSONL.
120
+ */
121
+ export async function getSessionMessageCount(projectRoot) {
122
+ try {
123
+ const root = projectRoot || getProjectRoot();
124
+ const sessionsDir = path.join(root, '.ginko', 'sessions');
125
+ if (!await fs.pathExists(sessionsDir))
126
+ return 0;
127
+ const dirs = await fs.readdir(sessionsDir);
128
+ for (const dir of dirs) {
129
+ const eventsFile = path.join(sessionsDir, dir, 'current-events.jsonl');
130
+ if (await fs.pathExists(eventsFile)) {
131
+ const content = await fs.readFile(eventsFile, 'utf-8');
132
+ const lines = content.split('\n').filter(l => l.trim());
133
+ // Count message-type events
134
+ let count = 0;
135
+ for (const line of lines) {
136
+ try {
137
+ const event = JSON.parse(line);
138
+ if (event.type === 'message' || event.type === 'tool_call' ||
139
+ event.type === 'context_score' || event.type === 'task_complete' ||
140
+ event.type === 'task_start') {
141
+ count++;
142
+ }
143
+ }
144
+ catch {
145
+ // Skip malformed lines
146
+ }
147
+ }
148
+ return count || lines.length;
149
+ }
150
+ }
151
+ }
152
+ catch {
153
+ // Metric extraction failure returns 0
154
+ }
155
+ return 0;
156
+ }
157
+ /**
158
+ * Get session duration in minutes from session start timestamp.
159
+ */
160
+ export async function getSessionDurationMinutes(projectRoot) {
161
+ try {
162
+ const root = projectRoot || getProjectRoot();
163
+ const sessionsDir = path.join(root, '.ginko', 'sessions');
164
+ if (!await fs.pathExists(sessionsDir))
165
+ return 0;
166
+ const dirs = await fs.readdir(sessionsDir);
167
+ for (const dir of dirs) {
168
+ const eventsFile = path.join(sessionsDir, dir, 'current-events.jsonl');
169
+ if (await fs.pathExists(eventsFile)) {
170
+ const content = await fs.readFile(eventsFile, 'utf-8');
171
+ const lines = content.split('\n').filter(l => l.trim());
172
+ if (lines.length === 0)
173
+ return 0;
174
+ // Find earliest timestamp
175
+ let earliest = null;
176
+ for (const line of lines) {
177
+ try {
178
+ const event = JSON.parse(line);
179
+ if (event.timestamp) {
180
+ const ts = new Date(event.timestamp).getTime();
181
+ if (!earliest || ts < earliest)
182
+ earliest = ts;
183
+ }
184
+ }
185
+ catch {
186
+ // Skip malformed lines
187
+ }
188
+ }
189
+ if (earliest) {
190
+ return Math.round((Date.now() - earliest) / 60000);
191
+ }
192
+ }
193
+ }
194
+ }
195
+ catch {
196
+ // Duration extraction failure returns 0
197
+ }
198
+ return 0;
199
+ }
200
+ /**
201
+ * Load custom thresholds from .ginko/config.json if configured.
202
+ */
203
+ export async function loadThresholds(projectRoot) {
204
+ try {
205
+ const root = projectRoot || getProjectRoot();
206
+ const configFile = path.join(root, '.ginko', 'config.json');
207
+ if (await fs.pathExists(configFile)) {
208
+ const config = await fs.readJson(configFile);
209
+ if (config.healthThresholds) {
210
+ return { ...DEFAULT_THRESHOLDS, ...config.healthThresholds };
211
+ }
212
+ }
213
+ }
214
+ catch {
215
+ // Config load failure uses defaults
216
+ }
217
+ return DEFAULT_THRESHOLDS;
218
+ }
219
+ // =============================================================================
220
+ // Convenience
221
+ // =============================================================================
222
+ /**
223
+ * Get current session health tier (all-in-one).
224
+ */
225
+ export async function getCurrentHealthTier(projectRoot) {
226
+ const [messageCount, durationMinutes, thresholds] = await Promise.all([
227
+ getSessionMessageCount(projectRoot),
228
+ getSessionDurationMinutes(projectRoot),
229
+ loadThresholds(projectRoot),
230
+ ]);
231
+ return calculateHealthTier(messageCount, durationMinutes, thresholds);
232
+ }
233
+ /**
234
+ * Format health tier for status line display.
235
+ * Compact format: "12 msgs | ✅ fresh"
236
+ */
237
+ export function formatHealthForStatusLine(info) {
238
+ return `${info.messageCount} msgs | ${info.icon} ${info.label}`;
239
+ }
240
+ // =============================================================================
241
+ // Helpers
242
+ // =============================================================================
243
+ function getProjectRoot() {
244
+ try {
245
+ const { execSync } = require('child_process');
246
+ return execSync('git rev-parse --show-toplevel', { encoding: 'utf-8' }).trim();
247
+ }
248
+ catch {
249
+ return process.cwd();
250
+ }
251
+ }
252
+ //# sourceMappingURL=session-health.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-health.js","sourceRoot":"","sources":["../../src/lib/session-health.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * @fileType: utility
3
+ * @status: current
4
+ * @updated: 2026-03-15
5
+ * @tags: [sprint-state, cache, materialization, epic-025]
6
+ * @related: [task-parser.ts, sprint-loader.ts, ../commands/task/status.ts]
7
+ * @priority: high
8
+ * @complexity: medium
9
+ * @dependencies: [fs-extra, path]
10
+ */
11
+ export interface SprintStateTask {
12
+ title: string;
13
+ status: string;
14
+ knownIssues?: string[];
15
+ blockers?: string[];
16
+ modifiedFiles?: string[];
17
+ }
18
+ export interface SprintStateProgress {
19
+ complete: number;
20
+ total: number;
21
+ percentage: number;
22
+ }
23
+ export interface SprintState {
24
+ sprint: string;
25
+ epicId: string;
26
+ epicTitle: string;
27
+ sprintTitle: string;
28
+ progress: SprintStateProgress;
29
+ tasks: Record<string, SprintStateTask>;
30
+ knownIssues: string[];
31
+ blockers: string[];
32
+ lastDeployed: string | null;
33
+ lastUpdated: string;
34
+ lastUpdatedBy: string | null;
35
+ stale: boolean;
36
+ }
37
+ /**
38
+ * Materialize sprint state from graph to local cache.
39
+ *
40
+ * Uses getActiveSprint API to fetch current sprint data,
41
+ * then writes structured JSON to .ginko/sprint-state.json.
42
+ *
43
+ * @param projectRoot - Optional project root override
44
+ * @returns The materialized SprintState, or null if no active sprint
45
+ */
46
+ export declare function materializeSprintState(projectRoot?: string): Promise<SprintState | null>;
47
+ /**
48
+ * Read sprint state from local cache.
49
+ *
50
+ * @param projectRoot - Optional project root override
51
+ * @returns SprintState or null if cache doesn't exist
52
+ */
53
+ export declare function readSprintState(projectRoot?: string): Promise<SprintState | null>;
54
+ /**
55
+ * Check if cache is stale (>1 hour old).
56
+ */
57
+ export declare function isCacheStale(state: SprintState, thresholdMs?: number): boolean;
58
+ /**
59
+ * Push checkpoint data to a task node in the graph.
60
+ *
61
+ * @param taskId - Task ID
62
+ * @param checkpoint - Checkpoint data (knownIssues, blockers, modifiedFiles)
63
+ */
64
+ export declare function pushCheckpointToGraph(taskId: string, checkpoint: {
65
+ knownIssues?: string[];
66
+ blockers?: string[];
67
+ modifiedFiles?: string[];
68
+ lastDeployed?: string;
69
+ }): Promise<void>;
70
+ /**
71
+ * Get modified files from git since last task complete.
72
+ */
73
+ export declare function getModifiedFiles(): string[];
74
+ /**
75
+ * Format sprint state for CLI display.
76
+ */
77
+ export declare function formatSprintState(state: SprintState): string;
78
+ /**
79
+ * Format a compact sprint checkpoint for ginko start readiness message.
80
+ */
81
+ export declare function formatCheckpointSummary(state: SprintState): string;
82
+ //# sourceMappingURL=sprint-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sprint-state.d.ts","sourceRoot":"","sources":["../../src/lib/sprint-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAsBH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACvC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,EAAE,OAAO,CAAC;CAChB;AAuBD;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAqG7B;AAwBD;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAQ7B;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,WAAW,EAAE,WAAW,GAAE,MAAgB,GAAG,OAAO,CAIvF;AAMD;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE;IACV,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GACA,OAAO,CAAC,IAAI,CAAC,CAmCf;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAa3C;AAMD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAqD5D;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CA0BlE"}