spindb 0.50.8 → 0.51.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.
@@ -0,0 +1,441 @@
1
+ /**
2
+ * Branch Manager
3
+ *
4
+ * Database branching, Neon/Vercel-style but local and engine-agnostic. A
5
+ * "branch" is a copy-on-write fork of a container's data directory (instant and
6
+ * near-zero-space on filesystems that support reflinks — APFS, Btrfs, XFS with
7
+ * reflink, ZFS — and a full copy elsewhere) that records its parent so branches
8
+ * form a lineage tree.
9
+ *
10
+ * Live sources are handled with an auto stop -> snapshot -> restart cycle: a
11
+ * running source is briefly stopped so its on-disk state is consistent, the
12
+ * data dir is duplicated, and the source is restarted immediately to minimize
13
+ * downtime. This works uniformly across all engines and all platforms.
14
+ *
15
+ * The mechanical copy + config rewrite lives in
16
+ * `containerManager.copyContainerData()` (shared with `clone()`); this module
17
+ * owns the orchestration (stop/restart, lineage tree, reset, cascade delete)
18
+ * and the file-based engine path (SQLite/DuckDB copy the backing file and
19
+ * register a new entry rather than copying a server data dir).
20
+ */
21
+ import { existsSync } from 'fs';
22
+ import { mkdir, rm } from 'fs/promises';
23
+ import { join, extname } from 'path';
24
+ import { paths } from '../config/paths.js';
25
+ import { containerManager } from './container-manager.js';
26
+ import { processManager } from './process-manager.js';
27
+ import { startContainerWithRetry } from './start-with-retry.js';
28
+ import { cloneDirectory } from './cow-copy.js';
29
+ import { logDebug } from './error-handler.js';
30
+ import { getEngine } from '../engines/index.js';
31
+ import { sqliteRegistry } from '../engines/sqlite/registry.js';
32
+ import { duckdbRegistry } from '../engines/duckdb/registry.js';
33
+ import { Engine, isFileBasedEngine, isRemoteContainer } from '../types/index.js';
34
+ class BranchManager {
35
+ /**
36
+ * Create a branch of `source` named `name`.
37
+ *
38
+ * For server engines: if the source is running it is briefly stopped, its
39
+ * data directory is copy-on-write cloned, and the source is restarted. The
40
+ * branch is then started (unless `start: false`).
41
+ *
42
+ * For file-based engines (SQLite/DuckDB): the backing file is cloned and a
43
+ * new registry entry is added.
44
+ */
45
+ async createBranch(options) {
46
+ const { source, name, start = true, port, gitBranch } = options;
47
+ if (!containerManager.isValidName(name)) {
48
+ throw new Error('Branch name must be alphanumeric with hyphens/underscores only');
49
+ }
50
+ const sourceConfig = await containerManager.getConfig(source);
51
+ if (!sourceConfig) {
52
+ throw new Error(`Source container "${source}" not found`);
53
+ }
54
+ if (isRemoteContainer(sourceConfig)) {
55
+ throw new Error('Cannot branch a linked remote container. Use "spindb backup" to export data, then "spindb restore" to import it locally.');
56
+ }
57
+ const { engine } = sourceConfig;
58
+ if (await containerManager.exists(name, { engine })) {
59
+ throw new Error(`Container "${name}" already exists`);
60
+ }
61
+ if (isFileBasedEngine(engine)) {
62
+ return this.createFileBasedBranch({
63
+ source,
64
+ name,
65
+ engine: engine,
66
+ gitBranch,
67
+ });
68
+ }
69
+ return this.createServerBranch({
70
+ source,
71
+ sourceConfig,
72
+ name,
73
+ start,
74
+ port,
75
+ gitBranch,
76
+ });
77
+ }
78
+ async createServerBranch(opts) {
79
+ const { source, sourceConfig, name, start, port, gitBranch } = opts;
80
+ const { engine } = sourceConfig;
81
+ // Auto stop -> snapshot -> restart: stop a running source so its on-disk
82
+ // state is consistent before we clone it.
83
+ const sourceWasRunning = await processManager.isRunning(source, { engine });
84
+ if (sourceWasRunning) {
85
+ await this.stopServer(sourceConfig);
86
+ }
87
+ let result;
88
+ try {
89
+ result = await containerManager.copyContainerData({
90
+ sourceName: source,
91
+ targetName: name,
92
+ strategy: 'cow',
93
+ lineage: { branchParent: source },
94
+ port,
95
+ });
96
+ }
97
+ catch (error) {
98
+ // Bring the source back up before surfacing the failure.
99
+ if (sourceWasRunning) {
100
+ await this.startServer(sourceConfig).catch((restartError) => {
101
+ logDebug(`Failed to restart source "${source}" after failed branch: ${restartError}`);
102
+ });
103
+ }
104
+ throw error;
105
+ }
106
+ // Data is cloned — restart the source immediately to minimize its downtime.
107
+ let warning;
108
+ if (sourceWasRunning) {
109
+ try {
110
+ await this.startServer(sourceConfig);
111
+ }
112
+ catch (error) {
113
+ warning = `Source "${source}" failed to restart after branching: ${error.message}`;
114
+ logDebug(warning);
115
+ }
116
+ }
117
+ if (gitBranch) {
118
+ await containerManager.updateConfig(name, { gitBranch });
119
+ result.config.gitBranch = gitBranch;
120
+ }
121
+ let started = false;
122
+ if (start) {
123
+ try {
124
+ await this.startServer(result.config);
125
+ result.config.status = 'running';
126
+ started = true;
127
+ }
128
+ catch (error) {
129
+ const branchWarning = `Branch "${name}" was created but failed to start: ${error.message}`;
130
+ warning = warning ? `${warning}; ${branchWarning}` : branchWarning;
131
+ logDebug(branchWarning);
132
+ }
133
+ }
134
+ const connectionString = getEngine(engine).getConnectionString(result.config);
135
+ return {
136
+ config: result.config,
137
+ method: result.method,
138
+ started,
139
+ connectionString,
140
+ warning,
141
+ };
142
+ }
143
+ async createFileBasedBranch(opts) {
144
+ const { source, name, engine, gitBranch } = opts;
145
+ const sourceEntry = await this.fileRegistryGet(engine, source);
146
+ if (!sourceEntry) {
147
+ throw new Error(`Source container "${source}" not found in registry`);
148
+ }
149
+ if (!existsSync(sourceEntry.filePath)) {
150
+ throw new Error(`Source database file not found: ${sourceEntry.filePath}`);
151
+ }
152
+ const ext = extname(sourceEntry.filePath) ||
153
+ (engine === Engine.SQLite ? '.sqlite' : '.duckdb');
154
+ const targetDir = paths.getContainerPath(name, { engine });
155
+ const targetFile = join(targetDir, `${name}${ext}`);
156
+ await mkdir(targetDir, { recursive: true });
157
+ let method;
158
+ try {
159
+ method = (await cloneDirectory(sourceEntry.filePath, targetFile)).method;
160
+ const now = new Date().toISOString();
161
+ await this.addFileEntry(engine, {
162
+ name,
163
+ filePath: targetFile,
164
+ created: now,
165
+ lastVerified: now,
166
+ branchParent: source,
167
+ branchedAt: now,
168
+ ...(gitBranch ? { gitBranch } : {}),
169
+ });
170
+ }
171
+ catch (error) {
172
+ // Clean up the partially-created branch directory on failure.
173
+ await rm(targetDir, { recursive: true, force: true }).catch(() => { });
174
+ throw error;
175
+ }
176
+ const config = await containerManager.getConfig(name, { engine });
177
+ if (!config) {
178
+ throw new Error('Failed to read branched container config');
179
+ }
180
+ const connectionString = getEngine(engine).getConnectionString(config);
181
+ return { config, method, started: true, connectionString };
182
+ }
183
+ /**
184
+ * Build the branch lineage forest. Every container is a node; branches nest
185
+ * under their parent. Containers with no parent (or whose parent has been
186
+ * deleted) are roots.
187
+ */
188
+ async getBranchTree() {
189
+ const all = await containerManager.list();
190
+ const byName = new Map();
191
+ for (const c of all) {
192
+ byName.set(c.name, {
193
+ name: c.name,
194
+ engine: c.engine,
195
+ status: c.status,
196
+ port: c.port,
197
+ branchParent: c.branchParent,
198
+ branchedAt: c.branchedAt,
199
+ gitBranch: c.gitBranch,
200
+ children: [],
201
+ });
202
+ }
203
+ const roots = [];
204
+ for (const node of byName.values()) {
205
+ const parent = node.branchParent
206
+ ? byName.get(node.branchParent)
207
+ : undefined;
208
+ if (parent) {
209
+ parent.children.push(node);
210
+ }
211
+ else {
212
+ roots.push(node);
213
+ }
214
+ }
215
+ const sortRecursive = (nodes) => {
216
+ nodes.sort((a, b) => a.name.localeCompare(b.name));
217
+ for (const node of nodes)
218
+ sortRecursive(node.children);
219
+ };
220
+ sortRecursive(roots);
221
+ return roots;
222
+ }
223
+ /** Names of branches whose immediate parent is `name`. */
224
+ async childrenOf(name) {
225
+ const all = await containerManager.list();
226
+ return all.filter((c) => c.branchParent === name).map((c) => c.name);
227
+ }
228
+ /**
229
+ * Delete a branch. Refuses if the branch has children unless `cascade` is set,
230
+ * in which case the whole subtree is deleted (deepest first).
231
+ */
232
+ async deleteBranch(name, options = {}) {
233
+ const config = await containerManager.getConfig(name);
234
+ if (!config) {
235
+ throw new Error(`Container "${name}" not found`);
236
+ }
237
+ const all = await containerManager.list();
238
+ const children = all.filter((c) => c.branchParent === name);
239
+ if (children.length > 0 && !options.cascade) {
240
+ const childList = children.map((c) => `"${c.name}"`).join(', ');
241
+ throw new Error(`Branch "${name}" has ${children.length} child branch(es): ${childList}. ` +
242
+ `Use --cascade to delete them too, or delete/reset the children first.`);
243
+ }
244
+ const deleted = [];
245
+ if (options.cascade) {
246
+ for (const child of children) {
247
+ const childResult = await this.deleteBranch(child.name, {
248
+ cascade: true,
249
+ });
250
+ deleted.push(...childResult.deleted);
251
+ }
252
+ }
253
+ // Stop a running server branch before removing it.
254
+ if (!isFileBasedEngine(config.engine) && !isRemoteContainer(config)) {
255
+ const running = await processManager.isRunning(name, {
256
+ engine: config.engine,
257
+ });
258
+ if (running) {
259
+ await this.stopServer(config);
260
+ }
261
+ }
262
+ await containerManager.delete(name, { force: true });
263
+ deleted.push(name);
264
+ return { deleted };
265
+ }
266
+ /**
267
+ * Reset a branch: discard its divergence and re-fork from the parent's
268
+ * current state. Destructive — the branch's data is replaced by a fresh copy
269
+ * of the parent's data. The branch keeps its name, port, and git binding.
270
+ */
271
+ async resetBranch(name) {
272
+ const branchConfig = await containerManager.getConfig(name);
273
+ if (!branchConfig) {
274
+ throw new Error(`Container "${name}" not found`);
275
+ }
276
+ if (!branchConfig.branchParent) {
277
+ throw new Error(`"${name}" is not a branch (no parent to reset from).`);
278
+ }
279
+ const parentName = branchConfig.branchParent;
280
+ const parentConfig = await containerManager.getConfig(parentName);
281
+ if (!parentConfig) {
282
+ throw new Error(`Parent container "${parentName}" of branch "${name}" no longer exists; cannot reset.`);
283
+ }
284
+ const { engine } = branchConfig;
285
+ if (isFileBasedEngine(engine)) {
286
+ return this.resetFileBasedBranch(branchConfig, parentConfig);
287
+ }
288
+ const branchWasRunning = await processManager.isRunning(name, { engine });
289
+ if (branchWasRunning) {
290
+ await this.stopServer(branchConfig);
291
+ }
292
+ const parentWasRunning = await processManager.isRunning(parentName, {
293
+ engine,
294
+ });
295
+ if (parentWasRunning) {
296
+ await this.stopServer(parentConfig);
297
+ }
298
+ const preservedPort = branchConfig.port;
299
+ const preservedGitBranch = branchConfig.gitBranch;
300
+ let result;
301
+ try {
302
+ // Drop the diverged data dir, then re-copy the parent's current data
303
+ // into a fresh container that keeps the branch's port.
304
+ await rm(paths.getContainerPath(name, { engine }), {
305
+ recursive: true,
306
+ force: true,
307
+ });
308
+ result = await containerManager.copyContainerData({
309
+ sourceName: parentName,
310
+ targetName: name,
311
+ strategy: 'cow',
312
+ lineage: { branchParent: parentName },
313
+ port: preservedPort,
314
+ });
315
+ }
316
+ finally {
317
+ if (parentWasRunning) {
318
+ await this.startServer(parentConfig).catch((error) => {
319
+ logDebug(`Failed to restart parent "${parentName}" after reset: ${error}`);
320
+ });
321
+ }
322
+ }
323
+ // copyContainerData clears git binding — re-apply it.
324
+ if (preservedGitBranch) {
325
+ await containerManager.updateConfig(name, {
326
+ gitBranch: preservedGitBranch,
327
+ });
328
+ result.config.gitBranch = preservedGitBranch;
329
+ }
330
+ let started = false;
331
+ let warning;
332
+ if (branchWasRunning) {
333
+ try {
334
+ await this.startServer(result.config);
335
+ result.config.status = 'running';
336
+ started = true;
337
+ }
338
+ catch (error) {
339
+ warning = `Branch "${name}" was reset but failed to restart: ${error.message}`;
340
+ logDebug(warning);
341
+ }
342
+ }
343
+ const connectionString = getEngine(engine).getConnectionString(result.config);
344
+ return {
345
+ config: result.config,
346
+ method: result.method,
347
+ started,
348
+ connectionString,
349
+ warning,
350
+ };
351
+ }
352
+ async resetFileBasedBranch(branchConfig, parentConfig) {
353
+ const engine = branchConfig.engine;
354
+ const branchEntry = await this.fileRegistryGet(engine, branchConfig.name);
355
+ const parentEntry = await this.fileRegistryGet(engine, parentConfig.name);
356
+ if (!branchEntry || !parentEntry) {
357
+ throw new Error('Cannot reset: registry entry missing for branch or parent.');
358
+ }
359
+ if (!existsSync(parentEntry.filePath)) {
360
+ throw new Error(`Parent database file not found: ${parentEntry.filePath}`);
361
+ }
362
+ await rm(branchEntry.filePath, { force: true }).catch(() => { });
363
+ const { method } = await cloneDirectory(parentEntry.filePath, branchEntry.filePath);
364
+ const now = new Date().toISOString();
365
+ await this.updateFileEntry(engine, branchConfig.name, {
366
+ branchedAt: now,
367
+ lastVerified: now,
368
+ });
369
+ const config = await containerManager.getConfig(branchConfig.name, {
370
+ engine,
371
+ });
372
+ if (!config) {
373
+ throw new Error('Failed to read reset container config');
374
+ }
375
+ const connectionString = getEngine(engine).getConnectionString(config);
376
+ return { config, method, started: true, connectionString };
377
+ }
378
+ /** Rename a branch and repoint any children's `branchParent` to the new name. */
379
+ async renameBranch(oldName, newName) {
380
+ const config = await containerManager.rename(oldName, newName);
381
+ const all = await containerManager.list();
382
+ const children = all.filter((c) => c.branchParent === oldName);
383
+ for (const child of children) {
384
+ if (isFileBasedEngine(child.engine)) {
385
+ await this.updateFileEntry(child.engine, child.name, {
386
+ branchParent: newName,
387
+ });
388
+ }
389
+ else {
390
+ await containerManager.updateConfig(child.name, {
391
+ branchParent: newName,
392
+ });
393
+ }
394
+ }
395
+ return config;
396
+ }
397
+ /** Lineage info for a single branch: its parent and immediate children. */
398
+ async getBranchInfo(name) {
399
+ const config = await containerManager.getConfig(name);
400
+ if (!config) {
401
+ throw new Error(`Container "${name}" not found`);
402
+ }
403
+ const children = await this.childrenOf(name);
404
+ return { config, parent: config.branchParent, children };
405
+ }
406
+ // ---- server lifecycle helpers ----
407
+ async stopServer(config) {
408
+ const engine = getEngine(config.engine);
409
+ await engine.stop(config);
410
+ await containerManager.updateConfig(config.name, { status: 'stopped' });
411
+ }
412
+ async startServer(config) {
413
+ const engine = getEngine(config.engine);
414
+ await startContainerWithRetry(engine, config);
415
+ await containerManager.updateConfig(config.name, { status: 'running' });
416
+ }
417
+ // ---- file-based registry helpers ----
418
+ async fileRegistryGet(engine, name) {
419
+ return engine === Engine.SQLite
420
+ ? sqliteRegistry.get(name)
421
+ : duckdbRegistry.get(name);
422
+ }
423
+ async updateFileEntry(engine, name, updates) {
424
+ if (engine === Engine.SQLite) {
425
+ await sqliteRegistry.update(name, updates);
426
+ }
427
+ else {
428
+ await duckdbRegistry.update(name, updates);
429
+ }
430
+ }
431
+ async addFileEntry(engine, entry) {
432
+ if (engine === Engine.SQLite) {
433
+ await sqliteRegistry.add(entry);
434
+ }
435
+ else {
436
+ await duckdbRegistry.add(entry);
437
+ }
438
+ }
439
+ }
440
+ export const branchManager = new BranchManager();
441
+ //# sourceMappingURL=branch-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branch-manager.js","sourceRoot":"","sources":["../../core/branch-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAA;AAC/B,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACpC,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAClD,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAA;AAC5D,OAAO,EAAE,cAAc,EAAmB,MAAM,YAAY,CAAA;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAE3D,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AAoCvE,MAAM,aAAa;IACjB;;;;;;;;;OASG;IACH,KAAK,CAAC,YAAY,CAAC,OASlB;QACC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,OAAO,CAAA;QAE/D,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CACb,gEAAgE,CACjE,CAAA;QACH,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,gBAAgB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;QAC7D,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,qBAAqB,MAAM,aAAa,CAAC,CAAA;QAC3D,CAAC;QACD,IAAI,iBAAiB,CAAC,YAAY,CAAC,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CACb,0HAA0H,CAC3H,CAAA;QACH,CAAC;QAED,MAAM,EAAE,MAAM,EAAE,GAAG,YAAY,CAAA;QAC/B,IAAI,MAAM,gBAAgB,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;YACpD,MAAM,IAAI,KAAK,CAAC,cAAc,IAAI,kBAAkB,CAAC,CAAA;QACvD,CAAC;QAED,IAAI,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC,qBAAqB,CAAC;gBAChC,MAAM;gBACN,IAAI;gBACJ,MAAM,EAAE,MAAyB;gBACjC,SAAS;aACV,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,IAAI,CAAC,kBAAkB,CAAC;YAC7B,MAAM;YACN,YAAY;YACZ,IAAI;YACJ,KAAK;YACL,IAAI;YACJ,SAAS;SACV,CAAC,CAAA;IACJ,CAAC;IAEO,KAAK,CAAC,kBAAkB,CAAC,IAOhC;QACC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,IAAI,CAAA;QACnE,MAAM,EAAE,MAAM,EAAE,GAAG,YAAY,CAAA;QAE/B,yEAAyE;QACzE,0CAA0C;QAC1C,MAAM,gBAAgB,GAAG,MAAM,cAAc,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;QAC3E,IAAI,gBAAgB,EAAE,CAAC;YACrB,MAAM,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAA;QACrC,CAAC;QAED,IAAI,MAAuD,CAAA;QAC3D,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,gBAAgB,CAAC,iBAAiB,CAAC;gBAChD,UAAU,EAAE,MAAM;gBAClB,UAAU,EAAE,IAAI;gBAChB,QAAQ,EAAE,KAAK;gBACf,OAAO,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE;gBACjC,IAAI;aACL,CAAC,CAAA;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,yDAAyD;YACzD,IAAI,gBAAgB,EAAE,CAAC;gBACrB,MAAM,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,CAAC,YAAY,EAAE,EAAE;oBAC1D,QAAQ,CACN,6BAA6B,MAAM,0BAA0B,YAAY,EAAE,CAC5E,CAAA;gBACH,CAAC,CAAC,CAAA;YACJ,CAAC;YACD,MAAM,KAAK,CAAA;QACb,CAAC;QAED,4EAA4E;QAC5E,IAAI,OAA2B,CAAA;QAC/B,IAAI,gBAAgB,EAAE,CAAC;YACrB,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAA;YACtC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,GAAG,WAAW,MAAM,wCACxB,KAAe,CAAC,OACnB,EAAE,CAAA;gBACF,QAAQ,CAAC,OAAO,CAAC,CAAA;YACnB,CAAC;QACH,CAAC;QAED,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,gBAAgB,CAAC,YAAY,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,CAAA;YACxD,MAAM,CAAC,MAAM,CAAC,SAAS,GAAG,SAAS,CAAA;QACrC,CAAC;QAED,IAAI,OAAO,GAAG,KAAK,CAAA;QACnB,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;gBACrC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,SAAS,CAAA;gBAChC,OAAO,GAAG,IAAI,CAAA;YAChB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,aAAa,GAAG,WAAW,IAAI,sCAClC,KAAe,CAAC,OACnB,EAAE,CAAA;gBACF,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,KAAK,aAAa,EAAE,CAAC,CAAC,CAAC,aAAa,CAAA;gBAClE,QAAQ,CAAC,aAAa,CAAC,CAAA;YACzB,CAAC;QACH,CAAC;QAED,MAAM,gBAAgB,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,mBAAmB,CAC5D,MAAM,CAAC,MAAM,CACd,CAAA;QACD,OAAO;YACL,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,OAAO;YACP,gBAAgB;YAChB,OAAO;SACR,CAAA;IACH,CAAC;IAEO,KAAK,CAAC,qBAAqB,CAAC,IAKnC;QACC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAA;QAEhD,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAC9D,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,qBAAqB,MAAM,yBAAyB,CAAC,CAAA;QACvE,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,mCAAmC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAA;QAC5E,CAAC;QAED,MAAM,GAAG,GACP,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC;YAC7B,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;QACpD,MAAM,SAAS,GAAG,KAAK,CAAC,gBAAgB,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;QAC1D,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,GAAG,IAAI,GAAG,GAAG,EAAE,CAAC,CAAA;QAEnD,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAE3C,IAAI,MAAkB,CAAA;QACtB,IAAI,CAAC;YACH,MAAM,GAAG,CAAC,MAAM,cAAc,CAAC,WAAW,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,MAAM,CAAA;YACxE,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;YACpC,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE;gBAC9B,IAAI;gBACJ,QAAQ,EAAE,UAAU;gBACpB,OAAO,EAAE,GAAG;gBACZ,YAAY,EAAE,GAAG;gBACjB,YAAY,EAAE,MAAM;gBACpB,UAAU,EAAE,GAAG;gBACf,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACpC,CAAC,CAAA;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,8DAA8D;YAC9D,MAAM,EAAE,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;YACrE,MAAM,KAAK,CAAA;QACb,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;QACjE,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAA;QAC7D,CAAC;QACD,MAAM,gBAAgB,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAA;QACtE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAA;IAC5D,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,aAAa;QACjB,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,IAAI,EAAE,CAAA;QACzC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAsB,CAAA;QAC5C,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;YACpB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE;gBACjB,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,YAAY,EAAE,CAAC,CAAC,YAAY;gBAC5B,UAAU,EAAE,CAAC,CAAC,UAAU;gBACxB,SAAS,EAAE,CAAC,CAAC,SAAS;gBACtB,QAAQ,EAAE,EAAE;aACb,CAAC,CAAA;QACJ,CAAC;QAED,MAAM,KAAK,GAAiB,EAAE,CAAA;QAC9B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YACnC,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY;gBAC9B,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC;gBAC/B,CAAC,CAAC,SAAS,CAAA;YACb,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAC5B,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAClB,CAAC;QACH,CAAC;QAED,MAAM,aAAa,GAAG,CAAC,KAAmB,EAAQ,EAAE;YAClD,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;YAClD,KAAK,MAAM,IAAI,IAAI,KAAK;gBAAE,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QACxD,CAAC,CAAA;QACD,aAAa,CAAC,KAAK,CAAC,CAAA;QACpB,OAAO,KAAK,CAAA;IACd,CAAC;IAED,0DAA0D;IAC1D,KAAK,CAAC,UAAU,CAAC,IAAY;QAC3B,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,IAAI,EAAE,CAAA;QACzC,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;IACtE,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,YAAY,CAChB,IAAY,EACZ,UAAiC,EAAE;QAEnC,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QACrD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,cAAc,IAAI,aAAa,CAAC,CAAA;QAClD,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,IAAI,EAAE,CAAA;QACzC,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,KAAK,IAAI,CAAC,CAAA;QAC3D,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YAC5C,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAC/D,MAAM,IAAI,KAAK,CACb,WAAW,IAAI,SAAS,QAAQ,CAAC,MAAM,sBAAsB,SAAS,IAAI;gBACxE,uEAAuE,CAC1E,CAAA;QACH,CAAC;QAED,MAAM,OAAO,GAAa,EAAE,CAAA;QAC5B,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpB,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;gBAC7B,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE;oBACtD,OAAO,EAAE,IAAI;iBACd,CAAC,CAAA;gBACF,OAAO,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,OAAO,CAAC,CAAA;YACtC,CAAC;QACH,CAAC;QAED,mDAAmD;QACnD,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;YACpE,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,SAAS,CAAC,IAAI,EAAE;gBACnD,MAAM,EAAE,MAAM,CAAC,MAAM;aACtB,CAAC,CAAA;YACF,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;YAC/B,CAAC;QACH,CAAC;QAED,MAAM,gBAAgB,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;QACpD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAClB,OAAO,EAAE,OAAO,EAAE,CAAA;IACpB,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,WAAW,CAAC,IAAY;QAC5B,MAAM,YAAY,GAAG,MAAM,gBAAgB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QAC3D,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,cAAc,IAAI,aAAa,CAAC,CAAA;QAClD,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,IAAI,IAAI,8CAA8C,CAAC,CAAA;QACzE,CAAC;QACD,MAAM,UAAU,GAAG,YAAY,CAAC,YAAY,CAAA;QAC5C,MAAM,YAAY,GAAG,MAAM,gBAAgB,CAAC,SAAS,CAAC,UAAU,CAAC,CAAA;QACjE,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CACb,qBAAqB,UAAU,gBAAgB,IAAI,mCAAmC,CACvF,CAAA;QACH,CAAC;QAED,MAAM,EAAE,MAAM,EAAE,GAAG,YAAY,CAAA;QAC/B,IAAI,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC,oBAAoB,CAAC,YAAY,EAAE,YAAY,CAAC,CAAA;QAC9D,CAAC;QAED,MAAM,gBAAgB,GAAG,MAAM,cAAc,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;QACzE,IAAI,gBAAgB,EAAE,CAAC;YACrB,MAAM,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAA;QACrC,CAAC;QACD,MAAM,gBAAgB,GAAG,MAAM,cAAc,CAAC,SAAS,CAAC,UAAU,EAAE;YAClE,MAAM;SACP,CAAC,CAAA;QACF,IAAI,gBAAgB,EAAE,CAAC;YACrB,MAAM,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAA;QACrC,CAAC;QAED,MAAM,aAAa,GAAG,YAAY,CAAC,IAAI,CAAA;QACvC,MAAM,kBAAkB,GAAG,YAAY,CAAC,SAAS,CAAA;QAEjD,IAAI,MAAuD,CAAA;QAC3D,IAAI,CAAC;YACH,qEAAqE;YACrE,uDAAuD;YACvD,MAAM,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE;gBACjD,SAAS,EAAE,IAAI;gBACf,KAAK,EAAE,IAAI;aACZ,CAAC,CAAA;YACF,MAAM,GAAG,MAAM,gBAAgB,CAAC,iBAAiB,CAAC;gBAChD,UAAU,EAAE,UAAU;gBACtB,UAAU,EAAE,IAAI;gBAChB,QAAQ,EAAE,KAAK;gBACf,OAAO,EAAE,EAAE,YAAY,EAAE,UAAU,EAAE;gBACrC,IAAI,EAAE,aAAa;aACpB,CAAC,CAAA;QACJ,CAAC;gBAAS,CAAC;YACT,IAAI,gBAAgB,EAAE,CAAC;gBACrB,MAAM,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;oBACnD,QAAQ,CACN,6BAA6B,UAAU,kBAAkB,KAAK,EAAE,CACjE,CAAA;gBACH,CAAC,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QAED,sDAAsD;QACtD,IAAI,kBAAkB,EAAE,CAAC;YACvB,MAAM,gBAAgB,CAAC,YAAY,CAAC,IAAI,EAAE;gBACxC,SAAS,EAAE,kBAAkB;aAC9B,CAAC,CAAA;YACF,MAAM,CAAC,MAAM,CAAC,SAAS,GAAG,kBAAkB,CAAA;QAC9C,CAAC;QAED,IAAI,OAAO,GAAG,KAAK,CAAA;QACnB,IAAI,OAA2B,CAAA;QAC/B,IAAI,gBAAgB,EAAE,CAAC;YACrB,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;gBACrC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,SAAS,CAAA;gBAChC,OAAO,GAAG,IAAI,CAAA;YAChB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,GAAG,WAAW,IAAI,sCACtB,KAAe,CAAC,OACnB,EAAE,CAAA;gBACF,QAAQ,CAAC,OAAO,CAAC,CAAA;YACnB,CAAC;QACH,CAAC;QAED,MAAM,gBAAgB,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,mBAAmB,CAC5D,MAAM,CAAC,MAAM,CACd,CAAA;QACD,OAAO;YACL,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,OAAO;YACP,gBAAgB;YAChB,OAAO;SACR,CAAA;IACH,CAAC;IAEO,KAAK,CAAC,oBAAoB,CAChC,YAA6B,EAC7B,YAA6B;QAE7B,MAAM,MAAM,GAAG,YAAY,CAAC,MAAyB,CAAA;QACrD,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,YAAY,CAAC,IAAI,CAAC,CAAA;QACzE,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,YAAY,CAAC,IAAI,CAAC,CAAA;QACzE,IAAI,CAAC,WAAW,IAAI,CAAC,WAAW,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CACb,4DAA4D,CAC7D,CAAA;QACH,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,mCAAmC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAA;QAC5E,CAAC;QAED,MAAM,EAAE,CAAC,WAAW,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QAC/D,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,cAAc,CACrC,WAAW,CAAC,QAAQ,EACpB,WAAW,CAAC,QAAQ,CACrB,CAAA;QACD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;QACpC,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,YAAY,CAAC,IAAI,EAAE;YACpD,UAAU,EAAE,GAAG;YACf,YAAY,EAAE,GAAG;SAClB,CAAC,CAAA;QAEF,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,EAAE;YACjE,MAAM;SACP,CAAC,CAAA;QACF,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAA;QAC1D,CAAC;QACD,MAAM,gBAAgB,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAA;QACtE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAA;IAC5D,CAAC;IAED,iFAAiF;IACjF,KAAK,CAAC,YAAY,CAChB,OAAe,EACf,OAAe;QAEf,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QAE9D,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,IAAI,EAAE,CAAA;QACzC,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,KAAK,OAAO,CAAC,CAAA;QAC9D,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;YAC7B,IAAI,iBAAiB,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;gBACpC,MAAM,IAAI,CAAC,eAAe,CACxB,KAAK,CAAC,MAAyB,EAC/B,KAAK,CAAC,IAAI,EACV;oBACE,YAAY,EAAE,OAAO;iBACtB,CACF,CAAA;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,gBAAgB,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE;oBAC9C,YAAY,EAAE,OAAO;iBACtB,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAA;IACf,CAAC;IAED,2EAA2E;IAC3E,KAAK,CAAC,aAAa,CAAC,IAAY;QAK9B,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QACrD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,cAAc,IAAI,aAAa,CAAC,CAAA;QAClD,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;QAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,YAAY,EAAE,QAAQ,EAAE,CAAA;IAC1D,CAAC;IAED,qCAAqC;IAE7B,KAAK,CAAC,UAAU,CAAC,MAAuB;QAC9C,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QACvC,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACzB,MAAM,gBAAgB,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAA;IACzE,CAAC;IAEO,KAAK,CAAC,WAAW,CAAC,MAAuB;QAC/C,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QACvC,MAAM,uBAAuB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAC7C,MAAM,gBAAgB,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAA;IACzE,CAAC;IAED,wCAAwC;IAEhC,KAAK,CAAC,eAAe,CAAC,MAAuB,EAAE,IAAY;QACjE,OAAO,MAAM,KAAK,MAAM,CAAC,MAAM;YAC7B,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC;YAC1B,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAC9B,CAAC;IAEO,KAAK,CAAC,eAAe,CAC3B,MAAuB,EACvB,IAAY,EACZ,OAAwB;QAExB,IAAI,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC;YAC7B,MAAM,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QAC5C,CAAC;aAAM,CAAC;YACN,MAAM,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QAC5C,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,YAAY,CACxB,MAAuB,EACvB,KAQC;QAED,IAAI,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC;YAC7B,MAAM,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QACjC,CAAC;aAAM,CAAC;YACN,MAAM,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QACjC,CAAC;IACH,CAAC;CACF;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,aAAa,EAAE,CAAA"}