aui-agent-builder 0.4.32 → 0.4.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/api-client/apollo-client.d.ts +64 -0
- package/dist/api-client/apollo-client.d.ts.map +1 -1
- package/dist/api-client/apollo-client.js +110 -21
- package/dist/api-client/apollo-client.js.map +1 -1
- package/dist/api-client/index.d.ts +11 -0
- package/dist/api-client/index.d.ts.map +1 -1
- package/dist/api-client/index.js +69 -28
- package/dist/api-client/index.js.map +1 -1
- package/dist/api-client/mock-db-client.d.ts +8 -0
- package/dist/api-client/mock-db-client.d.ts.map +1 -1
- package/dist/api-client/mock-db-client.js +33 -0
- package/dist/api-client/mock-db-client.js.map +1 -1
- package/dist/api-client/rag-client.d.ts +16 -0
- package/dist/api-client/rag-client.d.ts.map +1 -1
- package/dist/api-client/rag-client.js +56 -18
- package/dist/api-client/rag-client.js.map +1 -1
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +13 -5
- package/dist/commands/agents.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +46 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/mockdb-guide.d.ts +1 -1
- package/dist/commands/mockdb-guide.d.ts.map +1 -1
- package/dist/commands/mockdb-guide.js +29 -17
- package/dist/commands/mockdb-guide.js.map +1 -1
- package/dist/commands/mockdb.d.ts +6 -0
- package/dist/commands/mockdb.d.ts.map +1 -1
- package/dist/commands/mockdb.js +68 -24
- package/dist/commands/mockdb.js.map +1 -1
- package/dist/commands/push.js +49 -0
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/vault.d.ts +25 -0
- package/dist/commands/vault.d.ts.map +1 -0
- package/dist/commands/vault.js +220 -0
- package/dist/commands/vault.js.map +1 -0
- package/dist/config/index.d.ts +9 -9
- package/dist/config/index.js +4 -4
- package/dist/index.js +149 -23
- package/dist/index.js.map +1 -1
- package/dist/services/integration.service.d.ts +1 -1
- package/dist/services/integration.service.d.ts.map +1 -1
- package/dist/services/integration.service.js +4 -2
- package/dist/services/integration.service.js.map +1 -1
- package/dist/services/kb-identity.d.ts +54 -0
- package/dist/services/kb-identity.d.ts.map +1 -0
- package/dist/services/kb-identity.js +152 -0
- package/dist/services/kb-identity.js.map +1 -0
- package/dist/services/kb-view.service.d.ts.map +1 -1
- package/dist/services/kb-view.service.js +14 -3
- package/dist/services/kb-view.service.js.map +1 -1
- package/dist/services/mock-db.service.d.ts +22 -27
- package/dist/services/mock-db.service.d.ts.map +1 -1
- package/dist/services/mock-db.service.js +337 -179
- package/dist/services/mock-db.service.js.map +1 -1
- package/dist/services/vault.service.d.ts +58 -0
- package/dist/services/vault.service.d.ts.map +1 -0
- package/dist/services/vault.service.js +143 -0
- package/dist/services/vault.service.js.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/vault.d.ts +31 -0
- package/dist/types/vault.d.ts.map +1 -0
- package/dist/types/vault.js +10 -0
- package/dist/types/vault.js.map +1 -0
- package/dist/ui/views/VaultView.d.ts +19 -0
- package/dist/ui/views/VaultView.d.ts.map +1 -0
- package/dist/ui/views/VaultView.js +35 -0
- package/dist/ui/views/VaultView.js.map +1 -0
- package/dist/utils/fetch-with-timeout.d.ts +26 -0
- package/dist/utils/fetch-with-timeout.d.ts.map +1 -1
- package/dist/utils/fetch-with-timeout.js +172 -1
- package/dist/utils/fetch-with-timeout.js.map +1 -1
- package/dist/utils/json-output.d.ts +11 -0
- package/dist/utils/json-output.d.ts.map +1 -1
- package/dist/utils/json-output.js +19 -1
- package/dist/utils/json-output.js.map +1 -1
- package/package.json +1 -1
|
@@ -31,7 +31,10 @@
|
|
|
31
31
|
* wrapper, so existing test mocks of `node-fetch` continue to work
|
|
32
32
|
* unchanged. See `src/__tests__/helpers/mock-fetch.ts`.
|
|
33
33
|
*/
|
|
34
|
-
import nodeFetch from "node-fetch";
|
|
34
|
+
import nodeFetch, { Response } from "node-fetch";
|
|
35
|
+
import http from "node:http";
|
|
36
|
+
import https from "node:https";
|
|
37
|
+
import zlib from "node:zlib";
|
|
35
38
|
const DEFAULT_TIMEOUT_MS = 300_000;
|
|
36
39
|
export class FetchTimeoutError extends Error {
|
|
37
40
|
name = "FetchTimeoutError";
|
|
@@ -145,4 +148,172 @@ async function fetchWithTimeout(url, init) {
|
|
|
145
148
|
}
|
|
146
149
|
}
|
|
147
150
|
export default fetchWithTimeout;
|
|
151
|
+
// ─── Node 24.17.0+ premature-close recovery ──────────────────────────────
|
|
152
|
+
//
|
|
153
|
+
// Node v24.17.0 tightened how the core HTTP client treats a connection that
|
|
154
|
+
// closes without a clean end-of-stream: it now raises
|
|
155
|
+
// `ERR_STREAM_PREMATURE_CLOSE` even when every byte of the body actually
|
|
156
|
+
// arrived (curl and Node ≤24.16 / Node 20 accept the same response, returning
|
|
157
|
+
// HTTP 200). This deterministically breaks streamed GETs like
|
|
158
|
+
// `GET /api/network/v1/category` on that runtime while the server is healthy.
|
|
159
|
+
//
|
|
160
|
+
// The recovery below is intentionally narrow and SAFE on every Node version:
|
|
161
|
+
// • It is only ever entered from a caller's catch AFTER a premature-close
|
|
162
|
+
// error — older runtimes never raise it, so their code path is unchanged.
|
|
163
|
+
// • GET/HEAD only — idempotent reads. Writes are never re-sent.
|
|
164
|
+
// • It re-reads over a fresh `Connection: close` socket (no reuse, no gzip
|
|
165
|
+
// stream that could itself throw) and accepts the body ONLY when it can
|
|
166
|
+
// prove completeness (received bytes ≥ advertised Content-Length). A
|
|
167
|
+
// genuinely truncated body still fails loudly — we never hand back a
|
|
168
|
+
// partial payload as if it were whole.
|
|
169
|
+
/** Effective default timeout (env override honoured), for recovery callers. */
|
|
170
|
+
export function getDefaultTimeoutMs() {
|
|
171
|
+
return resolveTimeoutMs();
|
|
172
|
+
}
|
|
173
|
+
const PREMATURE_CLOSE_RE = /premature close|ERR_STREAM_PREMATURE_CLOSE|terminated|UND_ERR_SOCKET|UND_ERR_CONNECT|other side closed|socket hang up|ECONNRESET/i;
|
|
174
|
+
/**
|
|
175
|
+
* Whether an error is the "connection dropped before a clean end-of-stream"
|
|
176
|
+
* class — the signature of the Node 24.17.0 regression and of ordinary
|
|
177
|
+
* mid-flight socket drops. Inspects the message AND `error.cause` (the global
|
|
178
|
+
* `fetch`/undici path hides the real code as `TypeError: terminated` with the
|
|
179
|
+
* cause underneath) so it catches both the `node-fetch` and undici shapes.
|
|
180
|
+
*/
|
|
181
|
+
export function isPrematureClose(err) {
|
|
182
|
+
if (!err)
|
|
183
|
+
return false;
|
|
184
|
+
const e = err;
|
|
185
|
+
const haystack = [e.message, e.code, e.type, e.cause?.code, e.cause?.message]
|
|
186
|
+
.filter(Boolean)
|
|
187
|
+
.join(" ");
|
|
188
|
+
return PREMATURE_CLOSE_RE.test(haystack);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Normalise any header container (plain object or a Headers-like with
|
|
192
|
+
* `forEach`) into a plain `Record<string,string>`. Array values (e.g.
|
|
193
|
+
* `set-cookie`) are joined.
|
|
194
|
+
*/
|
|
195
|
+
export function normalizeHeaders(input) {
|
|
196
|
+
const out = {};
|
|
197
|
+
if (!input)
|
|
198
|
+
return out;
|
|
199
|
+
if (typeof input.forEach === "function") {
|
|
200
|
+
input.forEach((value, key) => {
|
|
201
|
+
out[key] = String(value);
|
|
202
|
+
});
|
|
203
|
+
return out;
|
|
204
|
+
}
|
|
205
|
+
for (const [key, value] of Object.entries(input)) {
|
|
206
|
+
if (value === undefined || value === null)
|
|
207
|
+
continue;
|
|
208
|
+
out[key] = Array.isArray(value) ? value.join(", ") : String(value);
|
|
209
|
+
}
|
|
210
|
+
return out;
|
|
211
|
+
}
|
|
212
|
+
function decodeBody(buf, encoding) {
|
|
213
|
+
const enc = (Array.isArray(encoding) ? encoding.join(",") : encoding ?? "")
|
|
214
|
+
.toLowerCase();
|
|
215
|
+
return new Promise((resolve, reject) => {
|
|
216
|
+
const cb = (e, r) => e ? reject(e) : resolve(r);
|
|
217
|
+
if (enc.includes("br"))
|
|
218
|
+
return zlib.brotliDecompress(buf, cb);
|
|
219
|
+
if (enc.includes("gzip"))
|
|
220
|
+
return zlib.gunzip(buf, cb);
|
|
221
|
+
if (enc.includes("deflate"))
|
|
222
|
+
return zlib.inflate(buf, cb);
|
|
223
|
+
resolve(buf);
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
const MAX_TOLERANT_REDIRECTS = 5;
|
|
227
|
+
/**
|
|
228
|
+
* Re-fetch an idempotent GET in a way that tolerates the Node 24.17.0
|
|
229
|
+
* premature-close, using a raw `http`/`https` request we fully control.
|
|
230
|
+
*
|
|
231
|
+
* Returns a `node-fetch` `Response` (body buffered) so callers can keep using
|
|
232
|
+
* `.text()` / `.json()` / `.ok` / `.status` exactly as before. Rejects when
|
|
233
|
+
* the body cannot be proven complete (real truncation), when redirects exceed
|
|
234
|
+
* the cap, or on timeout — callers then fall back to their normal error path.
|
|
235
|
+
*/
|
|
236
|
+
export function tolerantGet(url, headers, timeoutMs = getDefaultTimeoutMs(), redirectsLeft = MAX_TOLERANT_REDIRECTS) {
|
|
237
|
+
return new Promise((resolve, reject) => {
|
|
238
|
+
let parsed;
|
|
239
|
+
try {
|
|
240
|
+
parsed = new URL(url);
|
|
241
|
+
}
|
|
242
|
+
catch (e) {
|
|
243
|
+
reject(e);
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
const mod = parsed.protocol === "http:" ? http : https;
|
|
247
|
+
// Force a fresh, non-reused, EOF-framed connection. Drop any
|
|
248
|
+
// Accept-Encoding so the server is encouraged to send plain bytes (we
|
|
249
|
+
// still decode if it compresses anyway).
|
|
250
|
+
const reqHeaders = {
|
|
251
|
+
...headers,
|
|
252
|
+
connection: "close",
|
|
253
|
+
};
|
|
254
|
+
for (const k of Object.keys(reqHeaders)) {
|
|
255
|
+
if (k.toLowerCase() === "accept-encoding")
|
|
256
|
+
delete reqHeaders[k];
|
|
257
|
+
}
|
|
258
|
+
const req = mod.request(parsed, { method: "GET", headers: reqHeaders }, (res) => {
|
|
259
|
+
const status = res.statusCode ?? 0;
|
|
260
|
+
// Follow redirects the way node-fetch would (rare on these APIs).
|
|
261
|
+
if (status >= 300 &&
|
|
262
|
+
status < 400 &&
|
|
263
|
+
res.headers.location &&
|
|
264
|
+
redirectsLeft > 0) {
|
|
265
|
+
res.resume();
|
|
266
|
+
const next = new URL(res.headers.location, parsed).toString();
|
|
267
|
+
tolerantGet(next, headers, timeoutMs, redirectsLeft - 1).then(resolve, reject);
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
const chunks = [];
|
|
271
|
+
const expectedRaw = res.headers["content-length"];
|
|
272
|
+
const expected = expectedRaw != null ? Number(expectedRaw) : NaN;
|
|
273
|
+
let unclean = false;
|
|
274
|
+
let settled = false;
|
|
275
|
+
const finish = () => {
|
|
276
|
+
if (settled)
|
|
277
|
+
return;
|
|
278
|
+
const raw = Buffer.concat(chunks);
|
|
279
|
+
// Completeness gate. A clean `end` is always accepted. An unclean
|
|
280
|
+
// close is accepted ONLY when we received at least the advertised
|
|
281
|
+
// Content-Length; otherwise it's indistinguishable from truncation
|
|
282
|
+
// and must fail loudly.
|
|
283
|
+
if (unclean && !(Number.isFinite(expected) && raw.length >= expected)) {
|
|
284
|
+
settled = true;
|
|
285
|
+
reject(new Error(`Truncated response (${raw.length}` +
|
|
286
|
+
(Number.isFinite(expected) ? `/${expected}` : "") +
|
|
287
|
+
` bytes): GET ${url}`));
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
settled = true;
|
|
291
|
+
decodeBody(raw, res.headers["content-encoding"]).then((body) => {
|
|
292
|
+
resolve(new Response(body, {
|
|
293
|
+
status: status || 200,
|
|
294
|
+
statusText: res.statusMessage,
|
|
295
|
+
headers: normalizeHeaders(res.headers),
|
|
296
|
+
}));
|
|
297
|
+
}, reject);
|
|
298
|
+
};
|
|
299
|
+
res.on("data", (c) => chunks.push(c));
|
|
300
|
+
res.on("end", finish);
|
|
301
|
+
res.on("aborted", () => {
|
|
302
|
+
unclean = true;
|
|
303
|
+
});
|
|
304
|
+
res.on("error", () => {
|
|
305
|
+
unclean = true;
|
|
306
|
+
finish();
|
|
307
|
+
});
|
|
308
|
+
res.on("close", finish);
|
|
309
|
+
});
|
|
310
|
+
if (timeoutMs > 0) {
|
|
311
|
+
req.setTimeout(timeoutMs, () => {
|
|
312
|
+
req.destroy(new Error(`tolerant GET timed out after ${timeoutMs}ms: ${url}`));
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
req.on("error", reject);
|
|
316
|
+
req.end();
|
|
317
|
+
});
|
|
318
|
+
}
|
|
148
319
|
//# sourceMappingURL=fetch-with-timeout.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-with-timeout.js","sourceRoot":"","sources":["../../src/utils/fetch-with-timeout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"fetch-with-timeout.js","sourceRoot":"","sources":["../../src/utils/fetch-with-timeout.ts"],"names":[],"mappings":"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"}
|
|
@@ -49,6 +49,17 @@ export type JsonEnvelope<T = unknown> = JsonSuccessEnvelope<T> | JsonErrorEnvelo
|
|
|
49
49
|
export declare function outputJson<T>(data: T): void;
|
|
50
50
|
/**
|
|
51
51
|
* Write an error JSON envelope to stdout and exit with the given code.
|
|
52
|
+
*
|
|
53
|
+
* Uses a synchronous fd-1 write (not `process.stdout.write`) on purpose:
|
|
54
|
+
* `process.stdout.write` to a pipe is async, and the immediately-following
|
|
55
|
+
* `process.exit` can terminate the process before the buffer flushes —
|
|
56
|
+
* silently dropping the error envelope for non-interactive callers (the BFF,
|
|
57
|
+
* Claude Code, the spawned-subprocess test harness). `fs.writeSync` blocks
|
|
58
|
+
* until the bytes are handed to the OS, so the payload always lands before we
|
|
59
|
+
* exit while keeping this function's synchronous `never` contract intact.
|
|
60
|
+
* Error envelopes are small (well under the pipe buffer) so this never blocks
|
|
61
|
+
* meaningfully or risks EAGAIN. Best-effort: if the fd write throws, fall back
|
|
62
|
+
* to the async write so we never crash on the error path itself.
|
|
52
63
|
*/
|
|
53
64
|
export declare function outputJsonError(detail: JsonErrorDetail, exitCode?: number): never;
|
|
54
65
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json-output.d.ts","sourceRoot":"","sources":["../../src/utils/json-output.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;
|
|
1
|
+
{"version":3,"file":"json-output.d.ts","sourceRoot":"","sources":["../../src/utils/json-output.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAElD;AAED,wBAAgB,UAAU,IAAI,OAAO,CAEpC;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAG9C;AAED,MAAM,WAAW,mBAAmB,CAAC,CAAC,GAAG,OAAO;IAC9C,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE,CAAC,CAAC;CACT;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,eAAe,CAAC;CACxB;AAED,MAAM,MAAM,YAAY,CAAC,CAAC,GAAG,OAAO,IAAI,mBAAmB,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC;AAEnF;;GAEG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAG3C;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,EAAE,QAAQ,SAAI,GAAG,KAAK,CAS5E;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE/C"}
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* - Progress messages (spinners, status) go to stderr
|
|
11
11
|
* - Ink rendering is skipped entirely
|
|
12
12
|
*/
|
|
13
|
+
import { writeSync } from "node:fs";
|
|
13
14
|
let _jsonMode = false;
|
|
14
15
|
export function setJsonMode(enabled) {
|
|
15
16
|
_jsonMode = enabled;
|
|
@@ -40,10 +41,27 @@ export function outputJson(data) {
|
|
|
40
41
|
}
|
|
41
42
|
/**
|
|
42
43
|
* Write an error JSON envelope to stdout and exit with the given code.
|
|
44
|
+
*
|
|
45
|
+
* Uses a synchronous fd-1 write (not `process.stdout.write`) on purpose:
|
|
46
|
+
* `process.stdout.write` to a pipe is async, and the immediately-following
|
|
47
|
+
* `process.exit` can terminate the process before the buffer flushes —
|
|
48
|
+
* silently dropping the error envelope for non-interactive callers (the BFF,
|
|
49
|
+
* Claude Code, the spawned-subprocess test harness). `fs.writeSync` blocks
|
|
50
|
+
* until the bytes are handed to the OS, so the payload always lands before we
|
|
51
|
+
* exit while keeping this function's synchronous `never` contract intact.
|
|
52
|
+
* Error envelopes are small (well under the pipe buffer) so this never blocks
|
|
53
|
+
* meaningfully or risks EAGAIN. Best-effort: if the fd write throws, fall back
|
|
54
|
+
* to the async write so we never crash on the error path itself.
|
|
43
55
|
*/
|
|
44
56
|
export function outputJsonError(detail, exitCode = 1) {
|
|
45
57
|
const envelope = { success: false, error: detail };
|
|
46
|
-
|
|
58
|
+
const payload = JSON.stringify(envelope, null, 2) + "\n";
|
|
59
|
+
try {
|
|
60
|
+
writeSync(1, payload);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
process.stdout.write(payload);
|
|
64
|
+
}
|
|
47
65
|
process.exit(exitCode);
|
|
48
66
|
}
|
|
49
67
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json-output.js","sourceRoot":"","sources":["../../src/utils/json-output.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,IAAI,SAAS,GAAG,KAAK,CAAC;AAEtB,MAAM,UAAU,WAAW,CAAC,OAAgB;IAC1C,SAAS,GAAG,OAAO,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB;IAClC,IAAI,SAAS;QAAE,OAAO,KAAK,CAAC;IAC5B,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACvE,CAAC;AA2BD;;GAEG;AACH,MAAM,UAAU,UAAU,CAAI,IAAO;IACnC,MAAM,QAAQ,GAA2B,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACjE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACjE,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"json-output.js","sourceRoot":"","sources":["../../src/utils/json-output.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEpC,IAAI,SAAS,GAAG,KAAK,CAAC;AAEtB,MAAM,UAAU,WAAW,CAAC,OAAgB;IAC1C,SAAS,GAAG,OAAO,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB;IAClC,IAAI,SAAS;QAAE,OAAO,KAAK,CAAC;IAC5B,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACvE,CAAC;AA2BD;;GAEG;AACH,MAAM,UAAU,UAAU,CAAI,IAAO;IACnC,MAAM,QAAQ,GAA2B,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACjE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACjE,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,eAAe,CAAC,MAAuB,EAAE,QAAQ,GAAG,CAAC;IACnE,MAAM,QAAQ,GAAsB,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IACtE,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;IACzD,IAAI,CAAC;QACH,SAAS,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AACzB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,OAAe;IACvC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;AACvC,CAAC"}
|