dartmind 17.0.0 → 17.3.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.
Files changed (60) hide show
  1. package/dist/cli/InteractiveModeV12.d.ts +4 -0
  2. package/dist/cli/InteractiveModeV12.d.ts.map +1 -1
  3. package/dist/cli/InteractiveModeV12.js +57 -1
  4. package/dist/cli/InteractiveModeV12.js.map +1 -1
  5. package/dist/cli/commands/SlashCommands.d.ts.map +1 -1
  6. package/dist/cli/commands/SlashCommands.js +21 -5
  7. package/dist/cli/commands/SlashCommands.js.map +1 -1
  8. package/dist/core/cost/__tests__/day1.test.d.ts +9 -0
  9. package/dist/core/cost/__tests__/day1.test.d.ts.map +1 -0
  10. package/dist/core/cost/__tests__/day1.test.js +284 -0
  11. package/dist/core/cost/__tests__/day1.test.js.map +1 -0
  12. package/dist/core/cost/__tests__/day2.test.d.ts +9 -0
  13. package/dist/core/cost/__tests__/day2.test.d.ts.map +1 -0
  14. package/dist/core/cost/__tests__/day2.test.js +414 -0
  15. package/dist/core/cost/__tests__/day2.test.js.map +1 -0
  16. package/dist/core/cost/__tests__/day3.test.d.ts +9 -0
  17. package/dist/core/cost/__tests__/day3.test.d.ts.map +1 -0
  18. package/dist/core/cost/__tests__/day3.test.js +415 -0
  19. package/dist/core/cost/__tests__/day3.test.js.map +1 -0
  20. package/dist/core/cost/__tests__/day4.test.d.ts +9 -0
  21. package/dist/core/cost/__tests__/day4.test.d.ts.map +1 -0
  22. package/dist/core/cost/__tests__/day4.test.js +354 -0
  23. package/dist/core/cost/__tests__/day4.test.js.map +1 -0
  24. package/dist/core/cost/context-scaler.d.ts +129 -0
  25. package/dist/core/cost/context-scaler.d.ts.map +1 -0
  26. package/dist/core/cost/context-scaler.js +336 -0
  27. package/dist/core/cost/context-scaler.js.map +1 -0
  28. package/dist/core/cost/index.d.ts +31 -0
  29. package/dist/core/cost/index.d.ts.map +1 -0
  30. package/dist/core/cost/index.js +103 -0
  31. package/dist/core/cost/index.js.map +1 -0
  32. package/dist/core/cost/integration.d.ts +144 -0
  33. package/dist/core/cost/integration.d.ts.map +1 -0
  34. package/dist/core/cost/integration.js +349 -0
  35. package/dist/core/cost/integration.js.map +1 -0
  36. package/dist/core/cost/model-router.d.ts +70 -0
  37. package/dist/core/cost/model-router.d.ts.map +1 -0
  38. package/dist/core/cost/model-router.js +319 -0
  39. package/dist/core/cost/model-router.js.map +1 -0
  40. package/dist/core/cost/prompt-cache.d.ts +98 -0
  41. package/dist/core/cost/prompt-cache.d.ts.map +1 -0
  42. package/dist/core/cost/prompt-cache.js +219 -0
  43. package/dist/core/cost/prompt-cache.js.map +1 -0
  44. package/dist/core/cost/reflex-layer.d.ts +48 -0
  45. package/dist/core/cost/reflex-layer.d.ts.map +1 -0
  46. package/dist/core/cost/reflex-layer.js +295 -0
  47. package/dist/core/cost/reflex-layer.js.map +1 -0
  48. package/dist/core/cost/response-cache.d.ts +139 -0
  49. package/dist/core/cost/response-cache.d.ts.map +1 -0
  50. package/dist/core/cost/response-cache.js +290 -0
  51. package/dist/core/cost/response-cache.js.map +1 -0
  52. package/dist/core/cost/tool-loader.d.ts +94 -0
  53. package/dist/core/cost/tool-loader.d.ts.map +1 -0
  54. package/dist/core/cost/tool-loader.js +233 -0
  55. package/dist/core/cost/tool-loader.js.map +1 -0
  56. package/dist/core/cost/types.d.ts +93 -0
  57. package/dist/core/cost/types.d.ts.map +1 -0
  58. package/dist/core/cost/types.js +29 -0
  59. package/dist/core/cost/types.js.map +1 -0
  60. package/package.json +1 -1
@@ -0,0 +1,349 @@
1
+ /**
2
+ * DartMind V17.3 - Cost Optimization Integration
3
+ *
4
+ * This file provides integration helpers to connect the cost optimization
5
+ * module with your existing code WITHOUT modifying core logic.
6
+ *
7
+ * USAGE:
8
+ * 1. Import this module
9
+ * 2. Call processInput() before sending to API
10
+ * 3. Use buildOptimizedRequest() to get API parameters
11
+ *
12
+ * @module cost/integration
13
+ * @version 17.3.0
14
+ */
15
+ import { tryReflex, shouldBypassReflex, checkModelOverride, } from './reflex-layer.js';
16
+ import { buildCachedSystemBlocks, calculateCacheMetrics, formatCacheMetrics, } from './prompt-cache.js';
17
+ import { routeToModel, DEFAULT_ROUTER_CONFIG, } from './model-router.js';
18
+ import { determineContextTier, checkTierOverride, DEFAULT_SCALER_CONFIG, } from './context-scaler.js';
19
+ import { DEFAULT_CONFIG, MODEL_IDS, MODEL_COSTS, } from './types.js';
20
+ // ═══════════════════════════════════════════════════════════════
21
+ // COST OPTIMIZER CLASS
22
+ // ═══════════════════════════════════════════════════════════════
23
+ export class CostOptimizer {
24
+ config;
25
+ routerConfig;
26
+ scalerConfig;
27
+ projectContext = '';
28
+ // Metrics tracking
29
+ reflexCount = 0;
30
+ apiCallCount = 0;
31
+ totalInputTokens = 0;
32
+ totalOutputTokens = 0;
33
+ totalCacheReadTokens = 0;
34
+ totalCost = 0;
35
+ totalSavings = 0;
36
+ modelCounts = { haiku: 0, sonnet: 0, opus: 0 };
37
+ tierCounts = { 0: 0, 1: 0, 2: 0, 3: 0, 4: 0 };
38
+ constructor(config = {}, routerConfig = {}, scalerConfig = {}) {
39
+ this.config = { ...DEFAULT_CONFIG, ...config };
40
+ this.routerConfig = { ...DEFAULT_ROUTER_CONFIG, ...routerConfig };
41
+ this.scalerConfig = { ...DEFAULT_SCALER_CONFIG, ...scalerConfig };
42
+ }
43
+ /**
44
+ * Set project context for caching.
45
+ * Call this once when project is loaded.
46
+ */
47
+ setProjectContext(context) {
48
+ this.projectContext = context;
49
+ }
50
+ /**
51
+ * Update configuration at runtime.
52
+ */
53
+ updateConfig(config) {
54
+ this.config = { ...this.config, ...config };
55
+ }
56
+ /**
57
+ * Update router configuration at runtime.
58
+ */
59
+ updateRouterConfig(config) {
60
+ this.routerConfig = { ...this.routerConfig, ...config };
61
+ }
62
+ /**
63
+ * Get current configuration.
64
+ */
65
+ getConfig() {
66
+ return { ...this.config };
67
+ }
68
+ /**
69
+ * Get current router configuration.
70
+ */
71
+ getRouterConfig() {
72
+ return { ...this.routerConfig };
73
+ }
74
+ /**
75
+ * Update scaler configuration at runtime.
76
+ */
77
+ updateScalerConfig(config) {
78
+ this.scalerConfig = { ...this.scalerConfig, ...config };
79
+ }
80
+ /**
81
+ * Get current scaler configuration.
82
+ */
83
+ getScalerConfig() {
84
+ return { ...this.scalerConfig };
85
+ }
86
+ /**
87
+ * Process user input through cost optimization layers.
88
+ * Call this BEFORE sending to Anthropic API.
89
+ *
90
+ * @param input - Raw user input
91
+ * @returns ProcessedInput with skip decision and optional local response
92
+ */
93
+ processInput(input) {
94
+ // ─────────────────────────────────────────────────────────
95
+ // Layer 1: Reflex - Check for local handling
96
+ // ─────────────────────────────────────────────────────────
97
+ if (this.config.enableReflexLayer && !shouldBypassReflex(input)) {
98
+ const reflex = tryReflex(input);
99
+ if (reflex.handled) {
100
+ this.reflexCount++;
101
+ this.log(`[Reflex] Handled locally: ${reflex.reason}`);
102
+ return {
103
+ skipAPI: true,
104
+ localResponse: reflex.response,
105
+ reason: reflex.reason,
106
+ query: input
107
+ };
108
+ }
109
+ }
110
+ // ─────────────────────────────────────────────────────────
111
+ // Check for tier override (/t0-/t4, /minimal, /focused, etc.)
112
+ // ─────────────────────────────────────────────────────────
113
+ const tierOverride = checkTierOverride(input);
114
+ if (tierOverride) {
115
+ // Still need to route to model, but use the overridden tier
116
+ const classification = this.config.enableModelRouting
117
+ ? routeToModel(tierOverride.query, this.routerConfig)
118
+ : undefined;
119
+ this.apiCallCount++;
120
+ const tier = determineContextTier(classification || { intent: 'unknown', model: 'sonnet', modelId: MODEL_IDS.sonnet, confidence: 0.5, reason: 'default' }, { ...this.scalerConfig, minTier: tierOverride.tier, maxTier: tierOverride.tier });
121
+ this.tierCounts[tier.tier]++;
122
+ this.log(`[Context] Tier override T${tierOverride.tier} (${tier.name})`);
123
+ return {
124
+ skipAPI: false,
125
+ query: tierOverride.query,
126
+ modelOverride: classification?.model,
127
+ classification,
128
+ contextTier: tier
129
+ };
130
+ }
131
+ // ─────────────────────────────────────────────────────────
132
+ // Check for model override (/haiku, /sonnet, /opus)
133
+ // ─────────────────────────────────────────────────────────
134
+ const override = checkModelOverride(input);
135
+ if (override) {
136
+ this.apiCallCount++;
137
+ return {
138
+ skipAPI: false,
139
+ query: override.query,
140
+ modelOverride: override.model
141
+ };
142
+ }
143
+ // ─────────────────────────────────────────────────────────
144
+ // Layer 2: Model Routing - Route to cheapest capable model
145
+ // Layer 3: Context Scaling - Right-size context for task
146
+ // ─────────────────────────────────────────────────────────
147
+ if (this.config.enableModelRouting) {
148
+ const classification = routeToModel(input, this.routerConfig);
149
+ this.apiCallCount++;
150
+ // Determine context tier based on classification
151
+ let contextTier;
152
+ if (this.config.enableContextScaling) {
153
+ contextTier = determineContextTier(classification, this.scalerConfig);
154
+ this.tierCounts[contextTier.tier]++;
155
+ this.log(`[Context] T${contextTier.tier} (${contextTier.name}) for ${classification.intent}`);
156
+ }
157
+ this.log(`[Router] ${classification.model.toUpperCase()} (${(classification.confidence * 100).toFixed(0)}%) - ${classification.intent}: ${classification.reason}`);
158
+ return {
159
+ skipAPI: false,
160
+ query: input,
161
+ modelOverride: classification.model,
162
+ classification,
163
+ contextTier
164
+ };
165
+ }
166
+ // ─────────────────────────────────────────────────────────
167
+ // Pass to API with default model (Sonnet)
168
+ // ─────────────────────────────────────────────────────────
169
+ this.apiCallCount++;
170
+ return {
171
+ skipAPI: false,
172
+ query: input
173
+ };
174
+ }
175
+ /**
176
+ * Build optimized request parameters for Anthropic API.
177
+ *
178
+ * @param modelOverride - Optional model override from processInput
179
+ * @returns Partial request config with system blocks and model
180
+ */
181
+ buildOptimizedRequest(modelOverride) {
182
+ // Build cached system blocks
183
+ const systemBlocks = this.config.enablePromptCaching
184
+ ? buildCachedSystemBlocks(this.projectContext)
185
+ : buildCachedSystemBlocks(this.projectContext, {
186
+ enableSystemPromptCache: false,
187
+ enableToolDefinitionsCache: false,
188
+ enableProjectContextCache: false
189
+ });
190
+ // Determine model
191
+ const model = modelOverride
192
+ ? MODEL_IDS[modelOverride]
193
+ : MODEL_IDS.sonnet; // Default to Sonnet (routing will be added in Day 2)
194
+ // Track model usage
195
+ const tier = modelOverride || 'sonnet';
196
+ this.modelCounts[tier]++;
197
+ return {
198
+ model,
199
+ system: systemBlocks
200
+ };
201
+ }
202
+ /**
203
+ * Process API response to extract cache metrics and track costs.
204
+ * Call this after receiving Anthropic API response.
205
+ */
206
+ processResponse(usage, model = 'sonnet') {
207
+ // Track tokens
208
+ this.totalInputTokens += usage.input_tokens;
209
+ this.totalOutputTokens += usage.output_tokens;
210
+ this.totalCacheReadTokens += usage.cache_read_input_tokens ?? 0;
211
+ // Calculate cost
212
+ const costs = MODEL_COSTS[model];
213
+ const inputCost = (usage.input_tokens / 1_000_000) * costs.input;
214
+ const outputCost = (usage.output_tokens / 1_000_000) * costs.output;
215
+ const requestCost = inputCost + outputCost;
216
+ this.totalCost += requestCost;
217
+ // Calculate cache savings
218
+ if (this.config.enablePromptCaching) {
219
+ const metrics = calculateCacheMetrics(usage, costs.input);
220
+ this.totalSavings += metrics.estimatedSavings;
221
+ this.log(`[Cache] ${formatCacheMetrics(metrics)}`);
222
+ }
223
+ this.log(`[Cost] Request: $${requestCost.toFixed(4)} | Total: $${this.totalCost.toFixed(4)}`);
224
+ }
225
+ /**
226
+ * Get current session metrics.
227
+ */
228
+ getMetrics() {
229
+ const totalRequests = this.reflexCount + this.apiCallCount;
230
+ const sonnetEquivalentCost = (this.totalInputTokens / 1_000_000) * MODEL_COSTS.sonnet.input +
231
+ (this.totalOutputTokens / 1_000_000) * MODEL_COSTS.sonnet.output;
232
+ return {
233
+ totalRequests,
234
+ totalCost: this.totalCost,
235
+ reflexCount: this.reflexCount,
236
+ cacheHitCount: this.totalCacheReadTokens > 0 ? 1 : 0, // Simplified
237
+ modelBreakdown: {
238
+ haiku: { count: this.modelCounts.haiku, tokens: 0, cost: 0 },
239
+ sonnet: { count: this.modelCounts.sonnet, tokens: 0, cost: 0 },
240
+ opus: { count: this.modelCounts.opus, tokens: 0, cost: 0 }
241
+ },
242
+ averageCostPerRequest: totalRequests > 0 ? this.totalCost / totalRequests : 0,
243
+ savingsVsAllSonnet: sonnetEquivalentCost - this.totalCost + this.totalSavings,
244
+ savingsPercent: sonnetEquivalentCost > 0
245
+ ? ((sonnetEquivalentCost - this.totalCost + this.totalSavings) / sonnetEquivalentCost) * 100
246
+ : 0
247
+ };
248
+ }
249
+ /**
250
+ * Format metrics for display.
251
+ */
252
+ formatMetrics() {
253
+ const m = this.getMetrics();
254
+ const reflexRate = m.totalRequests > 0 ? (m.reflexCount / m.totalRequests) * 100 : 0;
255
+ const tc = this.tierCounts;
256
+ return [
257
+ `Session Stats:`,
258
+ ` Total requests: ${m.totalRequests}`,
259
+ ` Reflex handled: ${m.reflexCount} (${reflexRate.toFixed(1)}%)`,
260
+ ` API calls: ${this.apiCallCount}`,
261
+ ` Total cost: $${m.totalCost.toFixed(4)}`,
262
+ ` Total savings: $${m.savingsVsAllSonnet.toFixed(4)} (${m.savingsPercent.toFixed(1)}%)`,
263
+ ` Avg cost/request: $${m.averageCostPerRequest.toFixed(4)}`,
264
+ ` Models: H:${this.modelCounts.haiku} S:${this.modelCounts.sonnet} O:${this.modelCounts.opus}`,
265
+ ` Tiers: T0:${tc[0]} T1:${tc[1]} T2:${tc[2]} T3:${tc[3]} T4:${tc[4]}`
266
+ ].join('\n');
267
+ }
268
+ /**
269
+ * Reset metrics (for new session).
270
+ */
271
+ resetMetrics() {
272
+ this.reflexCount = 0;
273
+ this.apiCallCount = 0;
274
+ this.totalInputTokens = 0;
275
+ this.totalOutputTokens = 0;
276
+ this.totalCacheReadTokens = 0;
277
+ this.totalCost = 0;
278
+ this.totalSavings = 0;
279
+ this.modelCounts = { haiku: 0, sonnet: 0, opus: 0 };
280
+ this.tierCounts = { 0: 0, 1: 0, 2: 0, 3: 0, 4: 0 };
281
+ }
282
+ /**
283
+ * Get tier counts for metrics.
284
+ */
285
+ getTierCounts() {
286
+ return { ...this.tierCounts };
287
+ }
288
+ /**
289
+ * Check if a specific optimization layer is enabled.
290
+ */
291
+ isLayerEnabled(layer) {
292
+ return !!this.config[layer];
293
+ }
294
+ /**
295
+ * Enable/disable a specific layer at runtime.
296
+ */
297
+ setLayerEnabled(layer, enabled) {
298
+ if (layer in this.config && typeof this.config[layer] === 'boolean') {
299
+ this.config[layer] = enabled;
300
+ }
301
+ }
302
+ log(message) {
303
+ if (this.config.debug) {
304
+ console.log(`[CostOptimizer] ${message}`);
305
+ }
306
+ }
307
+ }
308
+ // ═══════════════════════════════════════════════════════════════
309
+ // SINGLETON INSTANCE
310
+ // ═══════════════════════════════════════════════════════════════
311
+ /**
312
+ * Default cost optimizer instance for easy use.
313
+ * Configure with costOptimizer.updateConfig({ ... })
314
+ */
315
+ export const costOptimizer = new CostOptimizer({ debug: false });
316
+ // ═══════════════════════════════════════════════════════════════
317
+ // CONVENIENCE FUNCTIONS
318
+ // ═══════════════════════════════════════════════════════════════
319
+ /**
320
+ * Quick check if input should skip API (reflex handled).
321
+ */
322
+ export function shouldSkipAPI(input) {
323
+ if (!shouldBypassReflex(input)) {
324
+ const reflex = tryReflex(input);
325
+ return reflex.handled;
326
+ }
327
+ return false;
328
+ }
329
+ /**
330
+ * Get local response if available (for reflex-handled inputs).
331
+ */
332
+ export function getLocalResponse(input) {
333
+ if (!shouldBypassReflex(input)) {
334
+ const reflex = tryReflex(input);
335
+ if (reflex.handled) {
336
+ return reflex.response;
337
+ }
338
+ }
339
+ return undefined;
340
+ }
341
+ /**
342
+ * Estimate cost for a request before making it.
343
+ */
344
+ export function estimateRequestCost(inputTokens, outputTokens, model = 'sonnet') {
345
+ const costs = MODEL_COSTS[model];
346
+ return (inputTokens / 1_000_000) * costs.input +
347
+ (outputTokens / 1_000_000) * costs.output;
348
+ }
349
+ //# sourceMappingURL=integration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.js","sourceRoot":"","sources":["../../../src/core/cost/integration.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * DartMind V17.3 - Model Router
3
+ *
4
+ * PURPOSE: Route requests to the cheapest model that can handle them.
5
+ * COST IMPACT: 40-50% savings by using Haiku for 70% of requests
6
+ * QUALITY IMPACT: NONE (Sonnet for all code generation)
7
+ *
8
+ * ROUTING LOGIC:
9
+ * - Haiku ($0.80/1M): Read, explain, search, list, simple Q&A
10
+ * - Sonnet ($3.00/1M): Generate, refactor, fix bugs, write tests
11
+ * - Opus ($15.00/1M): Architecture, security (only if explicitly requested)
12
+ *
13
+ * SAFETY FEATURES:
14
+ * - Code generation ALWAYS goes to Sonnet (never Haiku)
15
+ * - Low confidence auto-escalates to more capable model
16
+ * - User can override with /haiku, /sonnet, /opus commands
17
+ *
18
+ * @module cost/model-router
19
+ * @version 17.3.0
20
+ */
21
+ import { ClassificationResult, ModelTier } from './types.js';
22
+ /**
23
+ * Classify user input to determine intent and model.
24
+ *
25
+ * @param input - User input string
26
+ * @returns Classification result with intent, model, and confidence
27
+ */
28
+ export declare function classifyTask(input: string): ClassificationResult;
29
+ export interface RouterConfig {
30
+ minHaikuConfidence: number;
31
+ minSonnetConfidence: number;
32
+ allowOpusEscalation: boolean;
33
+ }
34
+ export declare const DEFAULT_ROUTER_CONFIG: RouterConfig;
35
+ /**
36
+ * Apply confidence-based escalation rules.
37
+ * Low confidence tasks get escalated to more capable models.
38
+ */
39
+ export declare function applyEscalation(classification: ClassificationResult, config?: RouterConfig): ClassificationResult;
40
+ /**
41
+ * Route input to appropriate model.
42
+ * Combines classification and escalation.
43
+ *
44
+ * @param input - User input
45
+ * @param config - Router configuration
46
+ * @returns Final classification with model selection
47
+ */
48
+ export declare function routeToModel(input: string, config?: RouterConfig): ClassificationResult;
49
+ /**
50
+ * Estimate cost for a request based on model and tokens.
51
+ */
52
+ export declare function estimateCost(model: ModelTier, inputTokens: number, outputTokens?: number): number;
53
+ /**
54
+ * Format classification for logging.
55
+ */
56
+ export declare function formatClassification(result: ClassificationResult): string;
57
+ /**
58
+ * Get the model tier from a model ID string.
59
+ */
60
+ export declare function getModelTier(modelId: string): ModelTier;
61
+ /**
62
+ * Calculate potential savings compared to using Sonnet for everything.
63
+ */
64
+ export declare function calculateSavings(model: ModelTier, inputTokens: number, outputTokens: number): {
65
+ actualCost: number;
66
+ sonnetCost: number;
67
+ savings: number;
68
+ savingsPercent: number;
69
+ };
70
+ //# sourceMappingURL=model-router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-router.d.ts","sourceRoot":"","sources":["../../../src/core/cost/model-router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAEL,oBAAoB,EACpB,SAAS,EAGV,MAAM,YAAY,CAAC;AAmMpB;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,oBAAoB,CA6BhE;AAMD,MAAM,WAAW,YAAY;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAED,eAAO,MAAM,qBAAqB,EAAE,YAInC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,cAAc,EAAE,oBAAoB,EACpC,MAAM,GAAE,YAAoC,GAC3C,oBAAoB,CAwBtB;AAMD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,EACb,MAAM,GAAE,YAAoC,GAC3C,oBAAoB,CAQtB;AAMD;;GAEG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,SAAS,EAChB,WAAW,EAAE,MAAM,EACnB,YAAY,GAAE,MAAY,GACzB,MAAM,CAGR;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,CAQzE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAOvD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,SAAS,EAChB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GACnB;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAOrF"}