@goreal-ai/echo-pdk 0.1.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 (53) hide show
  1. package/dist/ai-judge/index.d.ts +177 -0
  2. package/dist/ai-judge/index.d.ts.map +1 -0
  3. package/dist/ai-judge/index.js +299 -0
  4. package/dist/ai-judge/index.js.map +1 -0
  5. package/dist/evaluator/evaluator.d.ts +136 -0
  6. package/dist/evaluator/evaluator.d.ts.map +1 -0
  7. package/dist/evaluator/evaluator.js +407 -0
  8. package/dist/evaluator/evaluator.js.map +1 -0
  9. package/dist/evaluator/index.d.ts +7 -0
  10. package/dist/evaluator/index.d.ts.map +1 -0
  11. package/dist/evaluator/index.js +8 -0
  12. package/dist/evaluator/index.js.map +1 -0
  13. package/dist/evaluator/operators.d.ts +105 -0
  14. package/dist/evaluator/operators.d.ts.map +1 -0
  15. package/dist/evaluator/operators.js +371 -0
  16. package/dist/evaluator/operators.js.map +1 -0
  17. package/dist/index.d.ts +115 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +388 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/parser/ast.d.ts +106 -0
  22. package/dist/parser/ast.d.ts.map +1 -0
  23. package/dist/parser/ast.js +260 -0
  24. package/dist/parser/ast.js.map +1 -0
  25. package/dist/parser/index.d.ts +8 -0
  26. package/dist/parser/index.d.ts.map +1 -0
  27. package/dist/parser/index.js +13 -0
  28. package/dist/parser/index.js.map +1 -0
  29. package/dist/parser/lexer.d.ts +199 -0
  30. package/dist/parser/lexer.d.ts.map +1 -0
  31. package/dist/parser/lexer.js +491 -0
  32. package/dist/parser/lexer.js.map +1 -0
  33. package/dist/parser/parser.d.ts +49 -0
  34. package/dist/parser/parser.d.ts.map +1 -0
  35. package/dist/parser/parser.js +615 -0
  36. package/dist/parser/parser.js.map +1 -0
  37. package/dist/plugins/index.d.ts +62 -0
  38. package/dist/plugins/index.d.ts.map +1 -0
  39. package/dist/plugins/index.js +170 -0
  40. package/dist/plugins/index.js.map +1 -0
  41. package/dist/renderer/index.d.ts +6 -0
  42. package/dist/renderer/index.d.ts.map +1 -0
  43. package/dist/renderer/index.js +5 -0
  44. package/dist/renderer/index.js.map +1 -0
  45. package/dist/renderer/renderer.d.ts +97 -0
  46. package/dist/renderer/renderer.d.ts.map +1 -0
  47. package/dist/renderer/renderer.js +243 -0
  48. package/dist/renderer/renderer.js.map +1 -0
  49. package/dist/types.d.ts +255 -0
  50. package/dist/types.d.ts.map +1 -0
  51. package/dist/types.js +9 -0
  52. package/dist/types.js.map +1 -0
  53. package/package.json +54 -0
package/dist/index.js ADDED
@@ -0,0 +1,388 @@
1
+ /**
2
+ * @fileoverview Echo PDK Core - Main entry point
3
+ *
4
+ * This is the main entry point for @goreal-ai/echo-pdk.
5
+ * It exports the createEcho factory function and all public types.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { createEcho } from '@goreal-ai/echo-pdk';
10
+ *
11
+ * const echo = createEcho({
12
+ * strict: false,
13
+ * aiProvider: {
14
+ * type: 'openai',
15
+ * apiKey: process.env.OPENAI_API_KEY,
16
+ * }
17
+ * });
18
+ *
19
+ * const result = await echo.render(template, { name: 'Alice' });
20
+ * ```
21
+ */
22
+ // Import submodules
23
+ import { parse } from './parser/parser.js';
24
+ import { evaluate } from './evaluator/evaluator.js';
25
+ import { render, formatErrors } from './renderer/renderer.js';
26
+ import { builtinOperators, getOperator } from './evaluator/operators.js';
27
+ import { createOpenAIProvider, withCache } from './ai-judge/index.js';
28
+ // Re-export utilities for advanced usage
29
+ export { parse } from './parser/parser.js';
30
+ export { evaluate, resolveVariable, } from './evaluator/evaluator.js';
31
+ export { render, renderTemplate, formatErrors } from './renderer/renderer.js';
32
+ export { builtinOperators, getOperator } from './evaluator/operators.js';
33
+ export { createTextNode, createVariableNode, createConditionalNode, createConditionExpr, createSectionNode, createImportNode, createIncludeNode, collectAiJudgeConditions, visitNode, visitNodes, prettyPrint, } from './parser/ast.js';
34
+ /**
35
+ * Environment variable name for API key.
36
+ */
37
+ const ENV_API_KEY = 'OPENAI_API_KEY';
38
+ const ENV_ECHO_API_KEY = 'ECHO_API_KEY';
39
+ /**
40
+ * Creates a new Echo instance with the given configuration.
41
+ *
42
+ * The Echo instance provides methods for parsing, validating, and rendering
43
+ * Echo templates with support for:
44
+ * - Variable interpolation: {{name}}, {{user.email}}
45
+ * - Conditionals: [#IF {{var}} #operator(arg)]...[END IF]
46
+ * - Sections: [#SECTION name="x"]...[END SECTION]
47
+ * - Includes: [#INCLUDE section_name]
48
+ * - AI-powered conditions: #ai_judge(question)
49
+ *
50
+ * @param config - Configuration options for the Echo instance
51
+ * @returns A configured Echo instance
52
+ *
53
+ * @example Basic usage
54
+ * ```typescript
55
+ * import { createEcho } from '@goreal-ai/echo-pdk';
56
+ *
57
+ * const echo = createEcho();
58
+ * const output = await echo.render('Hello {{name}}!', { name: 'World' });
59
+ * // Output: "Hello World!"
60
+ * ```
61
+ *
62
+ * @example With AI provider
63
+ * ```typescript
64
+ * const echo = createEcho({
65
+ * aiProvider: {
66
+ * type: 'openai',
67
+ * apiKey: process.env.OPENAI_API_KEY,
68
+ * model: 'gpt-4o-mini',
69
+ * }
70
+ * });
71
+ *
72
+ * const template = `
73
+ * [#IF {{content}} #ai_judge(Is this appropriate for children?)]
74
+ * Safe content: {{content}}
75
+ * [ELSE]
76
+ * Content flagged for review.
77
+ * [END IF]
78
+ * `;
79
+ *
80
+ * const output = await echo.render(template, { content: userContent });
81
+ * ```
82
+ *
83
+ * @example With plugins
84
+ * ```typescript
85
+ * const echo = createEcho();
86
+ *
87
+ * echo.loadPlugin({
88
+ * name: 'custom-operators',
89
+ * version: '1.0.0',
90
+ * operators: {
91
+ * isEmpty: {
92
+ * type: 'unary',
93
+ * handler: (value) => !value || value === '',
94
+ * description: 'Check if value is empty',
95
+ * }
96
+ * }
97
+ * });
98
+ * ```
99
+ */
100
+ export function createEcho(config = {}) {
101
+ // Custom operators registry (starts with built-in operators)
102
+ const operators = new Map();
103
+ // Register all built-in operators
104
+ for (const [name, definition] of Object.entries(builtinOperators)) {
105
+ operators.set(name, definition);
106
+ }
107
+ // Set up AI Judge operator if provider is configured
108
+ setupAiJudgeOperator(config, operators);
109
+ // Loaded plugins
110
+ const plugins = [];
111
+ // The Echo instance
112
+ const echo = {
113
+ /**
114
+ * Parse a template string into an AST.
115
+ */
116
+ parse(template) {
117
+ return parse(template);
118
+ },
119
+ /**
120
+ * Render a template with the given context.
121
+ */
122
+ async render(template, context) {
123
+ // Step 1: Parse
124
+ const parseResult = parse(template);
125
+ if (!parseResult.success || !parseResult.ast) {
126
+ const formattedErrors = formatErrors(template, parseResult.errors);
127
+ throw new Error(`Parse error:\n${formattedErrors}`);
128
+ }
129
+ // Step 2: Evaluate
130
+ const { ast: evaluatedAst } = await evaluate(parseResult.ast, context, config, operators);
131
+ // Step 3: Render
132
+ return render(evaluatedAst, {
133
+ context,
134
+ config,
135
+ trim: false,
136
+ collapseNewlines: true,
137
+ });
138
+ },
139
+ /**
140
+ * Validate a template for syntax and semantic errors.
141
+ */
142
+ validate(template) {
143
+ const errors = [];
144
+ const warnings = [];
145
+ // Step 1: Parse the template
146
+ const parseResult = parse(template);
147
+ if (!parseResult.success) {
148
+ return {
149
+ valid: false,
150
+ errors: parseResult.errors,
151
+ warnings: [],
152
+ };
153
+ }
154
+ // Step 2: Semantic validation
155
+ if (parseResult.ast) {
156
+ validateAst(parseResult.ast, errors, warnings, config, operators);
157
+ }
158
+ return {
159
+ valid: errors.length === 0,
160
+ errors,
161
+ warnings,
162
+ };
163
+ },
164
+ /**
165
+ * Load a language definition from a YAML file.
166
+ */
167
+ loadLanguage(_yamlPath) {
168
+ // TODO: Implement language loading
169
+ // This would load custom operator definitions from a YAML file
170
+ // For now, we use the built-in operators
171
+ throw new Error('Language loading not yet implemented. Use registerOperator() to add custom operators.');
172
+ },
173
+ /**
174
+ * Register a custom operator.
175
+ */
176
+ registerOperator(name, definition) {
177
+ operators.set(name, definition);
178
+ },
179
+ /**
180
+ * Load a plugin.
181
+ */
182
+ loadPlugin(plugin) {
183
+ // Validate plugin structure
184
+ if (!plugin.name || typeof plugin.name !== 'string') {
185
+ throw new Error('Plugin must have a name');
186
+ }
187
+ if (!plugin.version || typeof plugin.version !== 'string') {
188
+ throw new Error('Plugin must have a version');
189
+ }
190
+ plugins.push(plugin);
191
+ // Register plugin operators
192
+ if (plugin.operators) {
193
+ for (const [name, definition] of Object.entries(plugin.operators)) {
194
+ operators.set(name, definition);
195
+ }
196
+ }
197
+ // Call plugin's onLoad hook
198
+ if (plugin.onLoad) {
199
+ void plugin.onLoad();
200
+ }
201
+ },
202
+ };
203
+ // Load plugins specified in config
204
+ if (config.plugins && config.plugins.length > 0) {
205
+ // TODO: Implement plugin path loading
206
+ // For now, plugins must be loaded via loadPlugin()
207
+ console.warn('Plugin paths in config not yet supported. Use loadPlugin() instead.');
208
+ }
209
+ return echo;
210
+ }
211
+ /**
212
+ * Set up the AI Judge operator with the configured provider.
213
+ */
214
+ function setupAiJudgeOperator(config, operators) {
215
+ // Check for API key from config or environment
216
+ const apiKey = config.aiProvider?.apiKey ||
217
+ process.env[ENV_ECHO_API_KEY] ||
218
+ process.env[ENV_API_KEY];
219
+ if (!apiKey) {
220
+ // No API key - AI Judge will throw when used
221
+ return;
222
+ }
223
+ // Create the provider based on type
224
+ const providerType = config.aiProvider?.type ?? 'openai';
225
+ if (providerType !== 'openai') {
226
+ console.warn(`AI provider type '${providerType}' not yet supported. Using OpenAI.`);
227
+ }
228
+ try {
229
+ // Resolve the model (default to gpt-4o-mini)
230
+ const model = config.aiProvider?.model ?? 'gpt-4o-mini';
231
+ // Create OpenAI provider with caching
232
+ const provider = createOpenAIProvider({
233
+ type: 'openai',
234
+ apiKey,
235
+ model,
236
+ timeout: config.aiProvider?.timeout,
237
+ });
238
+ // Wrap with cache, including provider/model for cache key isolation
239
+ const cachedProvider = withCache(provider, {
240
+ providerType: providerType,
241
+ model,
242
+ });
243
+ // Register the AI Judge operator with the provider
244
+ operators.set('ai_judge', {
245
+ type: 'ai',
246
+ description: 'LLM-evaluated boolean condition',
247
+ example: '{{content}} #ai_judge(Is this appropriate?)',
248
+ handler: async (value, question) => {
249
+ if (typeof question !== 'string') {
250
+ throw new Error('AI Judge requires a question string as argument');
251
+ }
252
+ return cachedProvider.evaluate(value, question);
253
+ },
254
+ });
255
+ }
256
+ catch (error) {
257
+ // Provider creation failed - AI Judge will throw when used
258
+ console.warn('Failed to create AI provider:', error);
259
+ }
260
+ }
261
+ /**
262
+ * Validate the AST for semantic errors.
263
+ */
264
+ function validateAst(ast, errors, warnings, config, operators) {
265
+ const knownSections = new Set();
266
+ // First pass: collect section names
267
+ collectSectionNames(ast, knownSections);
268
+ // Second pass: validate
269
+ validateNodes(ast, errors, warnings, knownSections, config, operators);
270
+ }
271
+ /**
272
+ * Collect all section names from the AST.
273
+ */
274
+ function collectSectionNames(nodes, sections) {
275
+ for (const node of nodes) {
276
+ if (node.type === 'section') {
277
+ sections.add(node.name);
278
+ collectSectionNames(node.body, sections);
279
+ }
280
+ else if (node.type === 'conditional') {
281
+ collectSectionNames(node.consequent, sections);
282
+ if (node.alternate) {
283
+ if (Array.isArray(node.alternate)) {
284
+ collectSectionNames(node.alternate, sections);
285
+ }
286
+ else {
287
+ collectSectionNames([node.alternate], sections);
288
+ }
289
+ }
290
+ }
291
+ }
292
+ }
293
+ /**
294
+ * Validate AST nodes for semantic errors.
295
+ */
296
+ function validateNodes(nodes, errors, warnings, knownSections, config, operators) {
297
+ for (const node of nodes) {
298
+ switch (node.type) {
299
+ case 'conditional': {
300
+ // Check if operator exists in instance operators or built-in operators
301
+ const operatorName = node.condition.operator;
302
+ const operator = operators.get(operatorName) ?? getOperator(operatorName);
303
+ if (!operator) {
304
+ const error = {
305
+ code: 'UNKNOWN_OPERATOR',
306
+ message: `Unknown operator: #${operatorName}`,
307
+ location: node.location,
308
+ };
309
+ if (config.strict) {
310
+ errors.push(error);
311
+ }
312
+ else {
313
+ warnings.push(error);
314
+ }
315
+ }
316
+ // Recurse into branches
317
+ validateNodes(node.consequent, errors, warnings, knownSections, config, operators);
318
+ if (node.alternate) {
319
+ if (Array.isArray(node.alternate)) {
320
+ validateNodes(node.alternate, errors, warnings, knownSections, config, operators);
321
+ }
322
+ else {
323
+ validateNodes([node.alternate], errors, warnings, knownSections, config, operators);
324
+ }
325
+ }
326
+ break;
327
+ }
328
+ case 'include': {
329
+ // Check if section exists
330
+ if (!knownSections.has(node.name)) {
331
+ const error = {
332
+ code: 'UNKNOWN_SECTION',
333
+ message: `Unknown section: ${node.name}`,
334
+ location: node.location,
335
+ };
336
+ if (config.strict) {
337
+ errors.push(error);
338
+ }
339
+ else {
340
+ warnings.push(error);
341
+ }
342
+ }
343
+ break;
344
+ }
345
+ case 'section': {
346
+ // Recurse into section body
347
+ validateNodes(node.body, errors, warnings, knownSections, config, operators);
348
+ break;
349
+ }
350
+ case 'import': {
351
+ // Warn about imports (not yet fully supported)
352
+ warnings.push({
353
+ code: 'IMPORT_NOT_RESOLVED',
354
+ message: `Import will not be resolved: ${node.path}`,
355
+ location: node.location,
356
+ });
357
+ break;
358
+ }
359
+ }
360
+ }
361
+ }
362
+ /**
363
+ * Helper function for defining plugins with type safety.
364
+ *
365
+ * @param plugin - The plugin definition
366
+ * @returns The same plugin (for type inference)
367
+ *
368
+ * @example
369
+ * ```typescript
370
+ * import { definePlugin } from '@goreal-ai/echo-pdk';
371
+ *
372
+ * export default definePlugin({
373
+ * name: 'my-operators',
374
+ * version: '1.0.0',
375
+ * operators: {
376
+ * isEmpty: {
377
+ * type: 'unary',
378
+ * handler: (value) => !value,
379
+ * description: 'Check if value is empty'
380
+ * }
381
+ * }
382
+ * });
383
+ * ```
384
+ */
385
+ export function definePlugin(plugin) {
386
+ return plugin;
387
+ }
388
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * @fileoverview AST Utilities - Node creation and traversal
3
+ *
4
+ * This file provides utility functions for working with the Echo AST.
5
+ * Includes factory functions for creating nodes and visitor pattern helpers.
6
+ *
7
+ * IMPLEMENTATION GUIDE:
8
+ *
9
+ * 1. NODE FACTORIES
10
+ * Factory functions ensure consistent node creation with proper defaults.
11
+ *
12
+ * 2. VISITOR PATTERN
13
+ * Implement a visitor for AST traversal. This is the primary way to:
14
+ * - Collect AI judge conditions
15
+ * - Evaluate nodes
16
+ * - Transform the AST
17
+ *
18
+ * 3. AST UTILITIES
19
+ * - Clone nodes (deep copy)
20
+ * - Find nodes by type
21
+ * - Pretty print for debugging
22
+ */
23
+ import type { ASTNode, TextNode, VariableNode, ConditionalNode, SectionNode, ImportNode, IncludeNode, SourceLocation, ConditionExpr } from '../types.js';
24
+ /**
25
+ * Create a TextNode.
26
+ */
27
+ export declare function createTextNode(value: string, location: SourceLocation): TextNode;
28
+ /**
29
+ * Create a VariableNode.
30
+ */
31
+ export declare function createVariableNode(path: string, location: SourceLocation, defaultValue?: string): VariableNode;
32
+ /**
33
+ * Create a ConditionalNode.
34
+ */
35
+ export declare function createConditionalNode(condition: ConditionExpr, consequent: ASTNode[], location: SourceLocation, alternate?: ConditionalNode | ASTNode[]): ConditionalNode;
36
+ /**
37
+ * Create a ConditionExpr.
38
+ */
39
+ export declare function createConditionExpr(variable: string, operator: string, argument?: string | number | string[]): ConditionExpr;
40
+ /**
41
+ * Create a SectionNode.
42
+ */
43
+ export declare function createSectionNode(name: string, body: ASTNode[], location: SourceLocation): SectionNode;
44
+ /**
45
+ * Create an ImportNode.
46
+ */
47
+ export declare function createImportNode(path: string, location: SourceLocation): ImportNode;
48
+ /**
49
+ * Create an IncludeNode.
50
+ */
51
+ export declare function createIncludeNode(name: string, location: SourceLocation): IncludeNode;
52
+ /**
53
+ * Visitor interface for AST traversal.
54
+ * Implement this interface to walk the AST.
55
+ */
56
+ export interface ASTVisitor<T = void> {
57
+ visitText?(node: TextNode): T;
58
+ visitVariable?(node: VariableNode): T;
59
+ visitConditional?(node: ConditionalNode): T;
60
+ visitSection?(node: SectionNode): T;
61
+ visitImport?(node: ImportNode): T;
62
+ visitInclude?(node: IncludeNode): T;
63
+ }
64
+ /**
65
+ * Walk an AST node with a visitor.
66
+ *
67
+ * @param node - The AST node to visit
68
+ * @param visitor - The visitor implementation
69
+ * @returns The result from the visitor (if any)
70
+ */
71
+ export declare function visitNode<T>(node: ASTNode, visitor: ASTVisitor<T>): T | undefined;
72
+ /**
73
+ * Walk an array of AST nodes with a visitor.
74
+ *
75
+ * @param nodes - The AST nodes to visit
76
+ * @param visitor - The visitor implementation
77
+ * @returns Array of results from the visitor
78
+ */
79
+ export declare function visitNodes<T>(nodes: ASTNode[], visitor: ASTVisitor<T>): (T | undefined)[];
80
+ /**
81
+ * Collect all AI judge conditions from an AST.
82
+ * This is used for parallel optimization.
83
+ *
84
+ * @param ast - The AST to search
85
+ * @returns Array of AI judge conditions with their locations
86
+ */
87
+ export declare function collectAiJudgeConditions(ast: ASTNode[]): {
88
+ condition: ConditionExpr;
89
+ location: SourceLocation;
90
+ }[];
91
+ /**
92
+ * Deep clone an AST node.
93
+ *
94
+ * @param node - The node to clone
95
+ * @returns A deep copy of the node
96
+ */
97
+ export declare function cloneNode<T extends ASTNode>(node: T): T;
98
+ /**
99
+ * Pretty print an AST for debugging.
100
+ *
101
+ * @param ast - The AST to print
102
+ * @param indent - Current indentation level
103
+ * @returns Formatted string representation
104
+ */
105
+ export declare function prettyPrint(ast: ASTNode[], indent?: number): string;
106
+ //# sourceMappingURL=ast.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/parser/ast.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EACV,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,eAAe,EACf,WAAW,EACX,UAAU,EACV,WAAW,EACX,cAAc,EACd,aAAa,EACd,MAAM,aAAa,CAAC;AAMrB;;GAEG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,cAAc,GACvB,QAAQ,CAMV;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,cAAc,EACxB,YAAY,CAAC,EAAE,MAAM,GACpB,YAAY,CAOd;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,aAAa,EACxB,UAAU,EAAE,OAAO,EAAE,EACrB,QAAQ,EAAE,cAAc,EACxB,SAAS,CAAC,EAAE,eAAe,GAAG,OAAO,EAAE,GACtC,eAAe,CAQjB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,GACpC,aAAa,CAOf;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,OAAO,EAAE,EACf,QAAQ,EAAE,cAAc,GACvB,WAAW,CAOb;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,cAAc,GACvB,UAAU,CAMZ;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,cAAc,GACvB,WAAW,CAMb;AAMD;;;GAGG;AACH,MAAM,WAAW,UAAU,CAAC,CAAC,GAAG,IAAI;IAClC,SAAS,CAAC,CAAC,IAAI,EAAE,QAAQ,GAAG,CAAC,CAAC;IAC9B,aAAa,CAAC,CAAC,IAAI,EAAE,YAAY,GAAG,CAAC,CAAC;IACtC,gBAAgB,CAAC,CAAC,IAAI,EAAE,eAAe,GAAG,CAAC,CAAC;IAC5C,YAAY,CAAC,CAAC,IAAI,EAAE,WAAW,GAAG,CAAC,CAAC;IACpC,WAAW,CAAC,CAAC,IAAI,EAAE,UAAU,GAAG,CAAC,CAAC;IAClC,YAAY,CAAC,CAAC,IAAI,EAAE,WAAW,GAAG,CAAC,CAAC;CACrC;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,SAAS,CAoBjF;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAC1B,KAAK,EAAE,OAAO,EAAE,EAChB,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,GACrB,CAAC,CAAC,GAAG,SAAS,CAAC,EAAE,CAEnB;AAMD;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,OAAO,EAAE,GACb;IAAE,SAAS,EAAE,aAAa,CAAC;IAAC,QAAQ,EAAE,cAAc,CAAA;CAAE,EAAE,CAgC1D;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,OAAO,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,CAEvD;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,MAAM,SAAI,GAAG,MAAM,CA6C9D"}