@agent-relay/wrapper 2.0.32 → 2.0.34
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.
- package/dist/base-wrapper.d.ts.map +1 -1
- package/dist/base-wrapper.js +27 -7
- package/dist/base-wrapper.js.map +1 -1
- package/dist/client.d.ts +27 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +116 -0
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/opencode-api.d.ts +106 -0
- package/dist/opencode-api.d.ts.map +1 -0
- package/dist/opencode-api.js +219 -0
- package/dist/opencode-api.js.map +1 -0
- package/dist/opencode-wrapper.d.ts +157 -0
- package/dist/opencode-wrapper.d.ts.map +1 -0
- package/dist/opencode-wrapper.js +414 -0
- package/dist/opencode-wrapper.js.map +1 -0
- package/dist/relay-pty-orchestrator.d.ts.map +1 -1
- package/dist/relay-pty-orchestrator.js +18 -0
- package/dist/relay-pty-orchestrator.js.map +1 -1
- package/dist/wrapper-events.d.ts +489 -0
- package/dist/wrapper-events.d.ts.map +1 -0
- package/dist/wrapper-events.js +252 -0
- package/dist/wrapper-events.js.map +1 -0
- package/package.json +7 -6
- package/src/base-wrapper.ts +23 -7
- package/src/client.test.ts +92 -3
- package/src/client.ts +163 -0
- package/src/index.ts +29 -0
- package/src/opencode-api.test.ts +292 -0
- package/src/opencode-api.ts +285 -0
- package/src/opencode-wrapper.ts +513 -0
- package/src/relay-pty-orchestrator.test.ts +176 -0
- package/src/relay-pty-orchestrator.ts +20 -0
- package/src/wrapper-events.ts +395 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenCode HTTP API client
|
|
3
|
+
*
|
|
4
|
+
* Provides integration with opencode serve's HTTP API for:
|
|
5
|
+
* - Injecting text into the TUI input field (append-prompt)
|
|
6
|
+
* - Submitting prompts
|
|
7
|
+
* - Clearing prompts
|
|
8
|
+
* - Session management
|
|
9
|
+
*
|
|
10
|
+
* @see https://github.com/anomalyco/opencode
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* OpenCode HTTP API client for interacting with opencode serve
|
|
14
|
+
*/
|
|
15
|
+
export class OpenCodeApi {
|
|
16
|
+
baseUrl;
|
|
17
|
+
password;
|
|
18
|
+
timeout;
|
|
19
|
+
constructor(config = {}) {
|
|
20
|
+
// Priority: explicit config > OPENCODE_API_URL env > OPENCODE_PORT env > default
|
|
21
|
+
const defaultPort = process.env.OPENCODE_PORT ?? '4096';
|
|
22
|
+
const defaultUrl = process.env.OPENCODE_API_URL ?? `http://localhost:${defaultPort}`;
|
|
23
|
+
this.baseUrl = config.baseUrl ?? defaultUrl;
|
|
24
|
+
this.password = config.password ?? process.env.OPENCODE_SERVER_PASSWORD;
|
|
25
|
+
this.timeout = config.timeout ?? 5000;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Build authorization headers if password is set
|
|
29
|
+
*/
|
|
30
|
+
getHeaders() {
|
|
31
|
+
const headers = {
|
|
32
|
+
'Content-Type': 'application/json',
|
|
33
|
+
};
|
|
34
|
+
if (this.password) {
|
|
35
|
+
// Basic auth with 'opencode' as username
|
|
36
|
+
const auth = Buffer.from(`opencode:${this.password}`).toString('base64');
|
|
37
|
+
headers['Authorization'] = `Basic ${auth}`;
|
|
38
|
+
}
|
|
39
|
+
return headers;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Make a request to the opencode API
|
|
43
|
+
*/
|
|
44
|
+
async request(method, path, body) {
|
|
45
|
+
const controller = new AbortController();
|
|
46
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
47
|
+
try {
|
|
48
|
+
const response = await fetch(`${this.baseUrl}${path}`, {
|
|
49
|
+
method,
|
|
50
|
+
headers: this.getHeaders(),
|
|
51
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
52
|
+
signal: controller.signal,
|
|
53
|
+
});
|
|
54
|
+
clearTimeout(timeoutId);
|
|
55
|
+
if (!response.ok) {
|
|
56
|
+
return {
|
|
57
|
+
success: false,
|
|
58
|
+
error: `HTTP ${response.status}: ${response.statusText}`,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
const data = await response.json();
|
|
62
|
+
return { success: true, data };
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
clearTimeout(timeoutId);
|
|
66
|
+
if (error instanceof Error) {
|
|
67
|
+
if (error.name === 'AbortError') {
|
|
68
|
+
return { success: false, error: 'Request timeout' };
|
|
69
|
+
}
|
|
70
|
+
return { success: false, error: error.message };
|
|
71
|
+
}
|
|
72
|
+
return { success: false, error: 'Unknown error' };
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// =========================================================================
|
|
76
|
+
// Health Check
|
|
77
|
+
// =========================================================================
|
|
78
|
+
/**
|
|
79
|
+
* Check if opencode serve is running and accessible
|
|
80
|
+
*/
|
|
81
|
+
async isAvailable() {
|
|
82
|
+
try {
|
|
83
|
+
const response = await this.request('GET', '/config');
|
|
84
|
+
return response.success;
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Wait for opencode serve to become available
|
|
92
|
+
* @param maxWaitMs Maximum time to wait in milliseconds (default: 10000)
|
|
93
|
+
* @param intervalMs Check interval in milliseconds (default: 500)
|
|
94
|
+
*/
|
|
95
|
+
async waitForAvailable(maxWaitMs = 10000, intervalMs = 500) {
|
|
96
|
+
const startTime = Date.now();
|
|
97
|
+
while (Date.now() - startTime < maxWaitMs) {
|
|
98
|
+
if (await this.isAvailable()) {
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
await new Promise(resolve => setTimeout(resolve, intervalMs));
|
|
102
|
+
}
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
// =========================================================================
|
|
106
|
+
// TUI Control
|
|
107
|
+
// =========================================================================
|
|
108
|
+
/**
|
|
109
|
+
* Append text to the TUI input field
|
|
110
|
+
* This is the primary method for injecting relay messages into opencode
|
|
111
|
+
*/
|
|
112
|
+
async appendPrompt(text) {
|
|
113
|
+
return this.request('POST', '/tui/append-prompt', { text });
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Submit the current prompt
|
|
117
|
+
*/
|
|
118
|
+
async submitPrompt() {
|
|
119
|
+
return this.request('POST', '/tui/submit-prompt');
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Clear the current prompt
|
|
123
|
+
*/
|
|
124
|
+
async clearPrompt() {
|
|
125
|
+
return this.request('POST', '/tui/clear-prompt');
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Show a toast notification in the TUI
|
|
129
|
+
*/
|
|
130
|
+
async showToast(message, options) {
|
|
131
|
+
return this.request('POST', '/tui/show-toast', {
|
|
132
|
+
message,
|
|
133
|
+
variant: options?.variant ?? 'info',
|
|
134
|
+
duration: options?.duration ?? 3000,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Execute a TUI command
|
|
139
|
+
*/
|
|
140
|
+
async executeCommand(command) {
|
|
141
|
+
return this.request('POST', '/tui/execute-command', { command });
|
|
142
|
+
}
|
|
143
|
+
// =========================================================================
|
|
144
|
+
// Session Management
|
|
145
|
+
// =========================================================================
|
|
146
|
+
/**
|
|
147
|
+
* List all sessions
|
|
148
|
+
*/
|
|
149
|
+
async listSessions() {
|
|
150
|
+
return this.request('GET', '/session');
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Get the current session
|
|
154
|
+
*/
|
|
155
|
+
async getCurrentSession() {
|
|
156
|
+
return this.request('GET', '/session/current');
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Select a session in the TUI
|
|
160
|
+
*/
|
|
161
|
+
async selectSession(sessionId) {
|
|
162
|
+
return this.request('POST', '/tui/select-session', { sessionID: sessionId });
|
|
163
|
+
}
|
|
164
|
+
// =========================================================================
|
|
165
|
+
// Events (SSE)
|
|
166
|
+
// =========================================================================
|
|
167
|
+
/**
|
|
168
|
+
* Subscribe to opencode events via Server-Sent Events
|
|
169
|
+
* Returns an abort function to stop the subscription
|
|
170
|
+
*/
|
|
171
|
+
subscribeToEvents(onEvent, onError) {
|
|
172
|
+
const controller = new AbortController();
|
|
173
|
+
const connect = async () => {
|
|
174
|
+
try {
|
|
175
|
+
const response = await fetch(`${this.baseUrl}/event`, {
|
|
176
|
+
headers: this.getHeaders(),
|
|
177
|
+
signal: controller.signal,
|
|
178
|
+
});
|
|
179
|
+
if (!response.ok || !response.body) {
|
|
180
|
+
throw new Error(`SSE connection failed: ${response.status}`);
|
|
181
|
+
}
|
|
182
|
+
const reader = response.body.getReader();
|
|
183
|
+
const decoder = new TextDecoder();
|
|
184
|
+
let buffer = '';
|
|
185
|
+
while (true) {
|
|
186
|
+
const { done, value } = await reader.read();
|
|
187
|
+
if (done)
|
|
188
|
+
break;
|
|
189
|
+
buffer += decoder.decode(value, { stream: true });
|
|
190
|
+
const lines = buffer.split('\n');
|
|
191
|
+
buffer = lines.pop() ?? '';
|
|
192
|
+
for (const line of lines) {
|
|
193
|
+
if (line.startsWith('data: ')) {
|
|
194
|
+
try {
|
|
195
|
+
const data = JSON.parse(line.slice(6));
|
|
196
|
+
onEvent(data);
|
|
197
|
+
}
|
|
198
|
+
catch {
|
|
199
|
+
// Ignore parse errors
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
if (error instanceof Error && error.name !== 'AbortError') {
|
|
207
|
+
onError?.(error);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
connect();
|
|
212
|
+
return () => controller.abort();
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Default OpenCode API instance
|
|
217
|
+
*/
|
|
218
|
+
export const openCodeApi = new OpenCodeApi();
|
|
219
|
+
//# sourceMappingURL=opencode-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencode-api.js","sourceRoot":"","sources":["../src/opencode-api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenCodeWrapper - Wrapper for opencode CLI with HTTP API support
|
|
3
|
+
*
|
|
4
|
+
* This wrapper supports two modes of message injection:
|
|
5
|
+
* 1. HTTP API mode: Uses opencode serve's /tui/append-prompt endpoint
|
|
6
|
+
* 2. PTY fallback: Falls back to PTY-based injection when HTTP is unavailable
|
|
7
|
+
*
|
|
8
|
+
* The wrapper automatically detects which mode to use based on:
|
|
9
|
+
* - Whether `opencode serve` is running (checks localhost:4096)
|
|
10
|
+
* - Configuration options (httpApi.enabled, httpApi.fallbackToPty)
|
|
11
|
+
*
|
|
12
|
+
* Usage with HTTP API:
|
|
13
|
+
* ```
|
|
14
|
+
* const wrapper = new OpenCodeWrapper({
|
|
15
|
+
* name: 'MyAgent',
|
|
16
|
+
* command: 'opencode',
|
|
17
|
+
* httpApi: {
|
|
18
|
+
* enabled: true,
|
|
19
|
+
* baseUrl: 'http://localhost:4096',
|
|
20
|
+
* }
|
|
21
|
+
* });
|
|
22
|
+
* await wrapper.start();
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* @see https://github.com/anomalyco/opencode
|
|
26
|
+
*/
|
|
27
|
+
import { BaseWrapper, type BaseWrapperConfig } from './base-wrapper.js';
|
|
28
|
+
import { OpenCodeApi, type OpenCodeApiConfig } from './opencode-api.js';
|
|
29
|
+
export interface OpenCodeWrapperConfig extends BaseWrapperConfig {
|
|
30
|
+
/** HTTP API configuration */
|
|
31
|
+
httpApi?: OpenCodeApiConfig & {
|
|
32
|
+
/** Enable HTTP API mode (default: true when wrapping opencode) */
|
|
33
|
+
enabled?: boolean;
|
|
34
|
+
/** Fall back to PTY injection if HTTP is unavailable (default: true) */
|
|
35
|
+
fallbackToPty?: boolean;
|
|
36
|
+
/** Auto-start opencode serve if not running (default: false) */
|
|
37
|
+
autoStartServe?: boolean;
|
|
38
|
+
/** Wait for serve to be available in milliseconds (default: 5000) */
|
|
39
|
+
waitForServeMs?: number;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Wrapper for opencode CLI with HTTP API support
|
|
44
|
+
*/
|
|
45
|
+
export declare class OpenCodeWrapper extends BaseWrapper {
|
|
46
|
+
protected config: OpenCodeWrapperConfig;
|
|
47
|
+
private api;
|
|
48
|
+
private httpApiAvailable;
|
|
49
|
+
private process?;
|
|
50
|
+
private outputBuffer;
|
|
51
|
+
private parser;
|
|
52
|
+
private serveProcess?;
|
|
53
|
+
constructor(config: OpenCodeWrapperConfig);
|
|
54
|
+
start(): Promise<void>;
|
|
55
|
+
stop(): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Start in HTTP API mode
|
|
58
|
+
* In this mode, we don't spawn opencode ourselves - we communicate via HTTP API
|
|
59
|
+
*/
|
|
60
|
+
private startHttpMode;
|
|
61
|
+
/**
|
|
62
|
+
* Subscribe to opencode SSE events for output parsing
|
|
63
|
+
*/
|
|
64
|
+
private subscribeToEvents;
|
|
65
|
+
/**
|
|
66
|
+
* Start in PTY mode (fallback when HTTP is unavailable)
|
|
67
|
+
*/
|
|
68
|
+
private startPtyMode;
|
|
69
|
+
/**
|
|
70
|
+
* Handle output from opencode (either via SSE or PTY)
|
|
71
|
+
*/
|
|
72
|
+
private handleOutput;
|
|
73
|
+
/**
|
|
74
|
+
* Handle a parsed relay command
|
|
75
|
+
*/
|
|
76
|
+
private handleParsedCommand;
|
|
77
|
+
protected performInjection(content: string): Promise<void>;
|
|
78
|
+
/**
|
|
79
|
+
* Inject content via HTTP API
|
|
80
|
+
*/
|
|
81
|
+
private performHttpInjection;
|
|
82
|
+
/**
|
|
83
|
+
* Inject content via PTY stdin
|
|
84
|
+
*/
|
|
85
|
+
private performPtyInjection;
|
|
86
|
+
protected getCleanOutput(): string;
|
|
87
|
+
/**
|
|
88
|
+
* Auto-start opencode serve
|
|
89
|
+
*/
|
|
90
|
+
private startServe;
|
|
91
|
+
/**
|
|
92
|
+
* Process the message queue
|
|
93
|
+
* Override to use HTTP API's direct injection when available
|
|
94
|
+
*/
|
|
95
|
+
protected processMessageQueue(): Promise<void>;
|
|
96
|
+
/**
|
|
97
|
+
* Get the process ID (undefined in HTTP mode, defined in PTY mode)
|
|
98
|
+
*/
|
|
99
|
+
get pid(): number | undefined;
|
|
100
|
+
/**
|
|
101
|
+
* Log path (not applicable for OpenCodeWrapper)
|
|
102
|
+
*/
|
|
103
|
+
get logPath(): string | undefined;
|
|
104
|
+
/**
|
|
105
|
+
* Kill the wrapper (alias for stop())
|
|
106
|
+
*/
|
|
107
|
+
kill(): Promise<void>;
|
|
108
|
+
/**
|
|
109
|
+
* Write to the process stdin (PTY mode only)
|
|
110
|
+
*/
|
|
111
|
+
write(data: string): void;
|
|
112
|
+
/**
|
|
113
|
+
* Inject a task into the agent
|
|
114
|
+
* @param task - The task description to inject
|
|
115
|
+
* @param _from - The sender name (used for formatting)
|
|
116
|
+
* @returns true if injection succeeded
|
|
117
|
+
*/
|
|
118
|
+
injectTask(task: string, _from?: string): Promise<boolean>;
|
|
119
|
+
/**
|
|
120
|
+
* Get output lines (for compatibility with spawner)
|
|
121
|
+
*/
|
|
122
|
+
getOutput(limit?: number): string[];
|
|
123
|
+
/**
|
|
124
|
+
* Get raw output (for compatibility with spawner)
|
|
125
|
+
*/
|
|
126
|
+
getRawOutput(): string;
|
|
127
|
+
/**
|
|
128
|
+
* Wait until the wrapper is ready to receive messages
|
|
129
|
+
* In HTTP mode, this checks if the API is available
|
|
130
|
+
* In PTY mode, this waits for the process to start
|
|
131
|
+
*/
|
|
132
|
+
waitUntilReadyForMessages(timeoutMs?: number, _pollMs?: number): Promise<boolean>;
|
|
133
|
+
/**
|
|
134
|
+
* Wait until CLI is ready (alias for waitUntilReadyForMessages)
|
|
135
|
+
*/
|
|
136
|
+
waitUntilCliReady(timeoutMs?: number, pollMs?: number): Promise<boolean>;
|
|
137
|
+
/**
|
|
138
|
+
* Check if HTTP API mode is active
|
|
139
|
+
*/
|
|
140
|
+
get isHttpApiMode(): boolean;
|
|
141
|
+
/**
|
|
142
|
+
* Get the OpenCode API client for advanced operations
|
|
143
|
+
*/
|
|
144
|
+
get openCodeApi(): OpenCodeApi;
|
|
145
|
+
/**
|
|
146
|
+
* Switch to a specific session
|
|
147
|
+
*/
|
|
148
|
+
switchSession(sessionId: string): Promise<boolean>;
|
|
149
|
+
/**
|
|
150
|
+
* List available sessions
|
|
151
|
+
*/
|
|
152
|
+
listSessions(): Promise<{
|
|
153
|
+
id: string;
|
|
154
|
+
title?: string;
|
|
155
|
+
}[]>;
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=opencode-wrapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencode-wrapper.d.ts","sourceRoot":"","sources":["../src/opencode-wrapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAGH,OAAO,EAAE,WAAW,EAAE,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAIxE,MAAM,WAAW,qBAAsB,SAAQ,iBAAiB;IAC9D,6BAA6B;IAC7B,OAAO,CAAC,EAAE,iBAAiB,GAAG;QAC5B,kEAAkE;QAClE,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,wEAAwE;QACxE,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB,gEAAgE;QAChE,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,qEAAqE;QACrE,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;CACH;AAED;;GAEG;AACH,qBAAa,eAAgB,SAAQ,WAAW;IAC9C,UAAmB,MAAM,EAAE,qBAAqB,CAAC;IAGjD,OAAO,CAAC,GAAG,CAAc;IACzB,OAAO,CAAC,gBAAgB,CAAS;IAGjC,OAAO,CAAC,OAAO,CAAC,CAAe;IAC/B,OAAO,CAAC,YAAY,CAAM;IAG1B,OAAO,CAAC,MAAM,CAAe;IAG7B,OAAO,CAAC,YAAY,CAAC,CAAe;gBAExB,MAAM,EAAE,qBAAqB;IAsBnC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAqCtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB3B;;;OAGG;YACW,aAAa;IAa3B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAyBzB;;OAEG;YACW,YAAY;IAsC1B;;OAEG;IACH,OAAO,CAAC,YAAY;IAcpB;;OAEG;IACH,OAAO,CAAC,mBAAmB;cAeX,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQhE;;OAEG;YACW,oBAAoB;IAOlC;;OAEG;YACW,mBAAmB;IASjC,SAAS,CAAC,cAAc,IAAI,MAAM;IAQlC;;OAEG;YACW,UAAU;IAkBxB;;;OAGG;cACa,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAiDpD;;OAEG;IACH,IAAI,GAAG,IAAI,MAAM,GAAG,SAAS,CAE5B;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,MAAM,GAAG,SAAS,CAEhC;IAED;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B;;OAEG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAMzB;;;;;OAKG;IACG,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUhE;;OAEG;IACH,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE;IAKnC;;OAEG;IACH,YAAY,IAAI,MAAM;IAItB;;;;OAIG;IACG,yBAAyB,CAAC,SAAS,SAAQ,EAAE,OAAO,SAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAcnF;;OAEG;IACG,iBAAiB,CAAC,SAAS,SAAQ,EAAE,MAAM,SAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQ1E;;OAEG;IACH,IAAI,aAAa,IAAI,OAAO,CAE3B;IAED;;OAEG;IACH,IAAI,WAAW,IAAI,WAAW,CAE7B;IAED;;OAEG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUxD;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAShE"}
|