loopforge 1.0.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 (84) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +75 -0
  3. package/dist/adapter.d.ts +17 -0
  4. package/dist/adapter.d.ts.map +1 -0
  5. package/dist/adapter.js +228 -0
  6. package/dist/adapter.js.map +1 -0
  7. package/dist/backends/fs.d.ts +31 -0
  8. package/dist/backends/fs.d.ts.map +1 -0
  9. package/dist/backends/fs.js +308 -0
  10. package/dist/backends/fs.js.map +1 -0
  11. package/dist/backends/interface.d.ts +42 -0
  12. package/dist/backends/interface.d.ts.map +1 -0
  13. package/dist/backends/interface.js +7 -0
  14. package/dist/backends/interface.js.map +1 -0
  15. package/dist/builder.d.ts +17 -0
  16. package/dist/builder.d.ts.map +1 -0
  17. package/dist/builder.js +205 -0
  18. package/dist/builder.js.map +1 -0
  19. package/dist/cli.d.ts +7 -0
  20. package/dist/cli.d.ts.map +1 -0
  21. package/dist/cli.js +360 -0
  22. package/dist/cli.js.map +1 -0
  23. package/dist/engine.d.ts +42 -0
  24. package/dist/engine.d.ts.map +1 -0
  25. package/dist/engine.js +595 -0
  26. package/dist/engine.js.map +1 -0
  27. package/dist/generate-schema.d.ts +12 -0
  28. package/dist/generate-schema.d.ts.map +1 -0
  29. package/dist/generate-schema.js +278 -0
  30. package/dist/generate-schema.js.map +1 -0
  31. package/dist/index.d.ts +27 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +30 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/loop-compiler.d.ts +37 -0
  36. package/dist/loop-compiler.d.ts.map +1 -0
  37. package/dist/loop-compiler.js +1232 -0
  38. package/dist/loop-compiler.js.map +1 -0
  39. package/dist/policy.d.ts +44 -0
  40. package/dist/policy.d.ts.map +1 -0
  41. package/dist/policy.js +111 -0
  42. package/dist/policy.js.map +1 -0
  43. package/dist/protocol.d.ts +167 -0
  44. package/dist/protocol.d.ts.map +1 -0
  45. package/dist/protocol.js +198 -0
  46. package/dist/protocol.js.map +1 -0
  47. package/dist/replay.d.ts +19 -0
  48. package/dist/replay.d.ts.map +1 -0
  49. package/dist/replay.js +198 -0
  50. package/dist/replay.js.map +1 -0
  51. package/dist/tests/adapter.test.d.ts +2 -0
  52. package/dist/tests/adapter.test.d.ts.map +1 -0
  53. package/dist/tests/adapter.test.js +104 -0
  54. package/dist/tests/adapter.test.js.map +1 -0
  55. package/dist/tests/builder.test.d.ts +2 -0
  56. package/dist/tests/builder.test.d.ts.map +1 -0
  57. package/dist/tests/builder.test.js +122 -0
  58. package/dist/tests/builder.test.js.map +1 -0
  59. package/dist/tests/engine.test.d.ts +2 -0
  60. package/dist/tests/engine.test.d.ts.map +1 -0
  61. package/dist/tests/engine.test.js +200 -0
  62. package/dist/tests/engine.test.js.map +1 -0
  63. package/dist/tests/generate-schema.test.d.ts +8 -0
  64. package/dist/tests/generate-schema.test.d.ts.map +1 -0
  65. package/dist/tests/generate-schema.test.js +196 -0
  66. package/dist/tests/generate-schema.test.js.map +1 -0
  67. package/dist/tests/loop-compiler.test.d.ts +2 -0
  68. package/dist/tests/loop-compiler.test.d.ts.map +1 -0
  69. package/dist/tests/loop-compiler.test.js +387 -0
  70. package/dist/tests/loop-compiler.test.js.map +1 -0
  71. package/dist/tests/policy.test.d.ts +2 -0
  72. package/dist/tests/policy.test.d.ts.map +1 -0
  73. package/dist/tests/policy.test.js +59 -0
  74. package/dist/tests/policy.test.js.map +1 -0
  75. package/dist/tests/protocol.test.d.ts +2 -0
  76. package/dist/tests/protocol.test.d.ts.map +1 -0
  77. package/dist/tests/protocol.test.js +63 -0
  78. package/dist/tests/protocol.test.js.map +1 -0
  79. package/dist/tests/replay.test.d.ts +2 -0
  80. package/dist/tests/replay.test.d.ts.map +1 -0
  81. package/dist/tests/replay.test.js +194 -0
  82. package/dist/tests/replay.test.js.map +1 -0
  83. package/loop_policy.json +44 -0
  84. package/package.json +58 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 kyrielrving11
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,75 @@
1
+ # LoopForge
2
+
3
+ **Loop-Time Intelligence Layer** for AI coding agents. Per-iteration prompt compiler
4
+ with structured memory, constraint inheritance, and drift correction — maintains
5
+ cognitive stability across long-horizon agent loops.
6
+
7
+ Spec: [`../docs/loopforge-spec.md`](../docs/loopforge-spec.md)
8
+
9
+ ## Quick Start
10
+
11
+ ```bash
12
+ npm install loopforge
13
+
14
+ # CLI
15
+ npx loopforge init
16
+ npx loopforge compile '{"task":"Audit ERC20","loop_id":"audit","round":1,"goal_id":"audit"}'
17
+ npx loopforge status
18
+ ```
19
+
20
+ ```typescript
21
+ // Library API
22
+ import { createEngine, ReplayBackend, FSBackend } from "loopforge";
23
+
24
+ const engine = createEngine();
25
+ const result = engine.invokeLoopCompile({
26
+ task: "Audit ERC20 token",
27
+ mode: "loop_compile",
28
+ loop_id: "audit",
29
+ round: 1,
30
+ goal_id: "audit",
31
+ });
32
+ ```
33
+
34
+ ## 3 Modes
35
+
36
+ | Mode | When | Returns |
37
+ |------|------|---------|
38
+ | `loop_compile` | Every agent loop iteration | Compiled prompt + recompile level + health + advisories |
39
+ | `feedback` | After execution | Quality score → vault persistence |
40
+ | `review` | Audit prompt quality | Structural checks + constraint compliance |
41
+
42
+ ## Recompile Levels
43
+
44
+ - **L0 Fast Path** — goal unchanged, no new failures → reuse cached prompt
45
+ - **L1 Patch** — new constraints or repair signals → patch previous prompt
46
+ - **L2 Full Recompile** — round 1, goal changed, plan_source, strategy collapse → full build
47
+
48
+ ## CLI Commands
49
+
50
+ ```bash
51
+ loopforge init # Init vault
52
+ loopforge compile '<json>' # Compile prompt (or pipe via stdin)
53
+ loopforge feedback '<json>' # Record feedback
54
+ loopforge replay <loop-id> # Loop timeline
55
+ loopforge diff <loop-id> <a> <b> # Diff two rounds
56
+ loopforge review <loop-id> <rN> # Audit stored prompt
57
+ loopforge status # Vault health
58
+ ```
59
+
60
+ ## API Modules
61
+
62
+ | Module | Import | Purpose |
63
+ |--------|--------|---------|
64
+ | `loopforge` | Main entry | `handle`, `createEngine`, types |
65
+ | `loopforge/compiler` | `compileLoop`, `decideLevel` | Pure-function compiler |
66
+ | `loopforge/replay` | `ReplayBackend` | Time-travel audit queries |
67
+
68
+ ## Zero Dependencies
69
+
70
+ No runtime dependencies — Node.js stdlib only. TypeScript strict mode.
71
+ Tests use Node.js built-in test runner (`node:test`).
72
+
73
+ ## License
74
+
75
+ MIT
@@ -0,0 +1,17 @@
1
+ /** LoopForge-loop_compile — Sub-agent adapter (unified entry point).
2
+ *
3
+ * This is the single entry point when LoopForge is invoked as a sub-agent.
4
+ * It wraps the Engine, routes by mode, and always prepends a compact health line.
5
+ *
6
+ * Three modes (v1.0):
7
+ * loop_compile — Per-iteration prompt compiler (primary entry point)
8
+ * feedback — Record execution results → quality scoring → vault persistence
9
+ * review — Audit prompt quality (structural checks + constraint compliance)
10
+ *
11
+ * build is an internal path (loop_compile L2 delegation) — not an exposed mode.
12
+ */
13
+ import { type LoopForgeRequest } from "./protocol.js";
14
+ import { LoopForgeEngine } from "./engine.js";
15
+ export declare function handle(requestInput: string | Record<string, unknown> | LoopForgeRequest, engine?: LoopForgeEngine): string;
16
+ export declare function main(): void;
17
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAKL,KAAK,gBAAgB,EACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,eAAe,EAGhB,MAAM,aAAa,CAAC;AAiBrB,wBAAgB,MAAM,CACpB,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,gBAAgB,EACjE,MAAM,CAAC,EAAE,eAAe,GACvB,MAAM,CAwER;AAsJD,wBAAgB,IAAI,IAAI,IAAI,CA8B3B"}
@@ -0,0 +1,228 @@
1
+ /** LoopForge-loop_compile — Sub-agent adapter (unified entry point).
2
+ *
3
+ * This is the single entry point when LoopForge is invoked as a sub-agent.
4
+ * It wraps the Engine, routes by mode, and always prepends a compact health line.
5
+ *
6
+ * Three modes (v1.0):
7
+ * loop_compile — Per-iteration prompt compiler (primary entry point)
8
+ * feedback — Record execution results → quality scoring → vault persistence
9
+ * review — Audit prompt quality (structural checks + constraint compliance)
10
+ *
11
+ * build is an internal path (loop_compile L2 delegation) — not an exposed mode.
12
+ */
13
+ import { AgentStatus, makeVaultConfig, Mode, } from "./protocol.js";
14
+ import { createEngine, } from "./engine.js";
15
+ // ═══════════════════════════════════════════════════════════════════════════
16
+ // Mode mapping
17
+ // ═══════════════════════════════════════════════════════════════════════════
18
+ const MODE_MAP = {
19
+ loop_compile: Mode.LOOP_COMPILE,
20
+ feedback: Mode.FEEDBACK,
21
+ review: Mode.REVIEW,
22
+ build: Mode.BUILD,
23
+ };
24
+ // ═══════════════════════════════════════════════════════════════════════════
25
+ // Main entry point
26
+ // ═══════════════════════════════════════════════════════════════════════════
27
+ export function handle(requestInput, engine) {
28
+ // Parse request
29
+ let rawMode;
30
+ let rawData = null;
31
+ let request;
32
+ if (typeof requestInput === "string") {
33
+ rawData = JSON.parse(requestInput);
34
+ rawMode = rawData.mode ?? "build";
35
+ }
36
+ else if (isLoopForgeRequest(requestInput)) {
37
+ rawMode =
38
+ typeof requestInput.mode === "string"
39
+ ? requestInput.mode
40
+ : requestInput.mode;
41
+ request = requestInput;
42
+ rawData = null;
43
+ }
44
+ else {
45
+ rawData = requestInput;
46
+ rawMode = rawData.mode ?? "build";
47
+ }
48
+ if (rawData !== null) {
49
+ request = parseRequest(rawData);
50
+ }
51
+ else {
52
+ request = requestInput;
53
+ }
54
+ // Normalise mode for engine
55
+ const engineMode = MODE_MAP[rawMode];
56
+ if (!engineMode) {
57
+ return JSON.stringify({
58
+ health: "[PC: 0 records, normal]",
59
+ status: "error",
60
+ result: { mode: rawMode, error: `Unknown mode: ${rawMode}` },
61
+ }, null, 2);
62
+ }
63
+ if (rawData !== null) {
64
+ request.mode = engineMode;
65
+ }
66
+ // Inline input validation
67
+ const task = request.task || "";
68
+ if (!task.trim()) {
69
+ return JSON.stringify({
70
+ health: "[PC: 0 records, normal]",
71
+ status: "error",
72
+ result: { mode: rawMode, error: "Task is required." },
73
+ }, null, 2);
74
+ }
75
+ // Initialise engine
76
+ if (!engine) {
77
+ const skillsDir = request.vault_config?.skills_dir ?? "skills";
78
+ engine = createEngine(skillsDir);
79
+ }
80
+ // Execute via dedicated engine method
81
+ const result = routeToEngine(engine, request);
82
+ // Build compact health line
83
+ const healthLine = compactHealth(engine);
84
+ // Build and return response
85
+ return buildAgentResponse(result, healthLine, rawMode);
86
+ }
87
+ // ═══════════════════════════════════════════════════════════════════════════
88
+ // Helpers
89
+ // ═══════════════════════════════════════════════════════════════════════════
90
+ function routeToEngine(engine, request) {
91
+ const mode = request.mode;
92
+ if (mode === Mode.LOOP_COMPILE) {
93
+ return engine.invokeLoopCompile(request);
94
+ }
95
+ if (mode === Mode.FEEDBACK) {
96
+ return engine.invokeFeedback(request);
97
+ }
98
+ if (mode === Mode.REVIEW) {
99
+ return engine.handleReview(request);
100
+ }
101
+ if (mode === Mode.BUILD) {
102
+ return engine.invokeBuild(request);
103
+ }
104
+ return {
105
+ status: AgentStatus.ERROR,
106
+ response: null,
107
+ };
108
+ }
109
+ function isLoopForgeRequest(obj) {
110
+ return (typeof obj === "object" &&
111
+ obj !== null &&
112
+ "mode" in obj &&
113
+ typeof obj.mode === "string" &&
114
+ [Mode.LOOP_COMPILE, Mode.FEEDBACK, Mode.REVIEW, Mode.BUILD].includes(obj.mode));
115
+ }
116
+ function parseRequest(raw) {
117
+ // Normalise mode
118
+ const modeStr = raw.mode ?? "build";
119
+ const validModes = new Set(Object.values(Mode));
120
+ const mode = validModes.has(modeStr)
121
+ ? modeStr
122
+ : Mode.BUILD;
123
+ // Known LoopForgeRequest fields
124
+ const knownFields = new Set([
125
+ "task", "mode", "vault_config", "feedback", "skill_name", "task_id",
126
+ ]);
127
+ const base = {};
128
+ const extras = {};
129
+ for (const [key, value] of Object.entries(raw)) {
130
+ if (knownFields.has(key)) {
131
+ base[key] = value;
132
+ }
133
+ else {
134
+ extras[key] = value;
135
+ }
136
+ }
137
+ const req = {
138
+ task: base.task ?? "",
139
+ mode: mode,
140
+ vault_config: makeVaultConfig(base.vault_config),
141
+ feedback: base.feedback ?? null,
142
+ skill_name: base.skill_name ?? null,
143
+ task_id: base.task_id ?? null,
144
+ };
145
+ // Attach extras
146
+ Object.assign(req, extras);
147
+ return req;
148
+ }
149
+ function compactHealth(engine) {
150
+ const recordCount = engine.state?.quality_trend.length ?? 0;
151
+ const stalled = engine.state ? engine.shouldBreak() : false;
152
+ const status = stalled ? "STALLED" : "normal";
153
+ const parts = [`PC: ${recordCount} records`, status];
154
+ const m = engine._metrics ??
155
+ engine.metrics;
156
+ if (m) {
157
+ if (m.vaultWriteErrors)
158
+ parts.push(`write_err=${m.vaultWriteErrors}`);
159
+ if (m.vaultWriteTimeouts)
160
+ parts.push(`write_timeout=${m.vaultWriteTimeouts}`);
161
+ if (m.hydrateCacheMisses)
162
+ parts.push(`cache_miss=${m.hydrateCacheMisses}`);
163
+ }
164
+ return "[" + parts.join(", ") + "]";
165
+ }
166
+ function buildAgentResponse(result, healthLine, mode) {
167
+ let promptOrOverlay = null;
168
+ let analysis = null;
169
+ let techniqueUsed = null;
170
+ if (result.response) {
171
+ const r = result.response;
172
+ promptOrOverlay = r.prompt;
173
+ if (r.analysis) {
174
+ analysis = r.analysis;
175
+ techniqueUsed = r.analysis.technique;
176
+ }
177
+ }
178
+ // Inline output size guard
179
+ let promptText = promptOrOverlay || "";
180
+ if (promptText.length > 32_000) {
181
+ promptText = promptText.slice(0, 32_000) + "\n\n[truncated — exceeds 32KB]";
182
+ }
183
+ const payload = {
184
+ mode: mode || "unknown",
185
+ prompt_or_overlay: promptText,
186
+ analysis,
187
+ technique_used: techniqueUsed,
188
+ confidence: 0.0,
189
+ proactive_signals: [],
190
+ };
191
+ const output = {
192
+ health: healthLine,
193
+ status: result.status,
194
+ result: payload,
195
+ };
196
+ return JSON.stringify(output, null, 2);
197
+ }
198
+ // ═══════════════════════════════════════════════════════════════════════════
199
+ // CLI entry point
200
+ // ═══════════════════════════════════════════════════════════════════════════
201
+ export function main() {
202
+ const chunks = [];
203
+ process.stdin.on("data", (chunk) => chunks.push(chunk));
204
+ process.stdin.on("end", () => {
205
+ const raw = Buffer.concat(chunks).toString("utf-8");
206
+ if (!raw.trim()) {
207
+ process.stdout.write(JSON.stringify({ status: "error", error: "No input provided." }) + "\n");
208
+ process.exit(1);
209
+ }
210
+ try {
211
+ const output = handle(raw);
212
+ process.stdout.write(output + "\n");
213
+ }
214
+ catch (exc) {
215
+ process.stdout.write(JSON.stringify({
216
+ health: "[PC: 0 records, normal]",
217
+ status: "error",
218
+ result: { error: String(exc) },
219
+ }, null, 2) + "\n");
220
+ process.exit(1);
221
+ }
222
+ });
223
+ }
224
+ // Allow direct execution
225
+ if (process.argv[1] && import.meta.url.endsWith(process.argv[1].replace(/\\/g, "/"))) {
226
+ main();
227
+ }
228
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /** FSBackend — filesystem implementation of VaultBackend.
2
+ *
3
+ * Wraps Node.js fs for JSON vault read/write and Markdown lineage I/O.
4
+ * All file I/O is contained in this single module — engine.ts never
5
+ * touches the filesystem directly.
6
+ */
7
+ import type { VaultBackend, VaultEntry } from "./interface.js";
8
+ export declare function readLineageMd(loopId: string, roundNum: number, vaultPath?: string): {
9
+ full_prompt: string;
10
+ metadata: Record<string, unknown>;
11
+ } | null;
12
+ export declare function writeLineageMd(loopId: string, roundNum: number, content: string, metadata: Record<string, unknown>, vaultPath?: string): string | null;
13
+ export declare function scanLineageMd(loopId: string, vaultPath?: string): VaultEntry[];
14
+ export declare class FSBackend implements VaultBackend {
15
+ private readonly vaultPath;
16
+ private readonly globalVaultPath;
17
+ constructor(vaultPath?: string, globalVaultPath?: string);
18
+ readVault(): Record<string, unknown>;
19
+ writeVault(data: Record<string, unknown>): void;
20
+ queryEntries(opts?: {
21
+ prefix?: string;
22
+ taskIdPattern?: string;
23
+ feedbackOnly?: boolean;
24
+ }): VaultEntry[];
25
+ appendEntry(entry: VaultEntry): void;
26
+ appendEntries(entries: VaultEntry[]): number;
27
+ writeLineageMd(loopId: string, roundNum: number, content: string, metadata: Record<string, unknown>): string | null;
28
+ readLineageMd(loopId: string, roundNum: number): string | null;
29
+ scanLineageMd(loopId: string): VaultEntry[];
30
+ }
31
+ //# sourceMappingURL=fs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/backends/fs.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAsJ/D,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,GACjB;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG,IAAI,CAkBnE;AAED,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,GAAG,IAAI,CAef;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,GACjB,UAAU,EAAE,CAqDd;AAMD,qBAAa,SAAU,YAAW,YAAY;IAC5C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;gBAGvC,SAAS,SAAmC,EAC5C,eAAe,SAAqC;IAQtD,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAUpC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAQ/C,YAAY,CAAC,IAAI,CAAC,EAAE;QAClB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB,GAAG,UAAU,EAAE;IA+BhB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAQpC,aAAa,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,MAAM;IAW5C,cAAc,CACZ,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,MAAM,GAAG,IAAI;IAIhB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAK9D,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE;CAG5C"}