xit-wasm 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.
package/README.md ADDED
@@ -0,0 +1,156 @@
1
+ # xit-wasm
2
+
3
+ Versioned in-memory archives for TypeScript, backed by the **xit** version
4
+ control system compiled to WebAssembly. Pure in-memory by default, so it runs
5
+ identically in Node, Bun, Deno, and the browser.
6
+
7
+ ```ts
8
+ import { Archive } from "xit-wasm";
9
+
10
+ const a = await Archive.open(); // fresh repo
11
+ await a.write("manifest.json", encode({ v: 1 }));
12
+ await a.write("data/foo.json", encode({ x: 1 }));
13
+ await a.commit("initial");
14
+
15
+ await a.branch("feature");
16
+ await a.checkout("feature");
17
+ await a.write("data/foo.json", encode({ x: 2 }));
18
+ await a.commit("bump x");
19
+
20
+ await a.checkout("master");
21
+ await a.merge("feature"); // fast-forward
22
+
23
+ const bytes = await a.toBytes(); // serialize to a zip
24
+ // …round-trip…
25
+ const b = await Archive.open(bytes);
26
+ console.log(await b.log()); // CommitInfo[]
27
+ ```
28
+
29
+ ## What this is
30
+
31
+ A thin TypeScript surface over a slimmed-down build of [`xit`][xit] (Zig)
32
+ compiled to `wasm32-wasi`. Networking, the TUI, and the CLI are stripped; what
33
+ remains is the git/xit object model, the index/tree/pack/chunk machinery, and
34
+ the merge engine. We provide a pure in-memory `Host` that backs the wasm
35
+ filesystem with a JS map, so the public API has no `dirCreateFile` /
36
+ file-handle / wasm concept anywhere — just `archive.write(path, bytes)`,
37
+ `archive.commit(message)`, etc.
38
+
39
+ The on-disk shape inside an archive's zip stream is a real xit working
40
+ directory, including a `.xit/` subtree (single-file xitdb + content chunks).
41
+ Power users can unzip a `.甲` and find a fully-formed repo.
42
+
43
+ ## Credit and provenance
44
+
45
+ This package wraps **xit**, a brand-new version control system written in Zig
46
+ by **radarroark**. xit aims to be a worthy successor to git and is well worth
47
+ exploring on its own:
48
+
49
+ - **xit on GitHub**: <https://github.com/xit-vcs/xit>
50
+ - **radarroark on YouTube** (where most of xit's development is recorded
51
+ live): <https://www.youtube.com/@xeuxeuxeuxeu>
52
+
53
+ This package is a downstream WebAssembly binding maintained by
54
+ [rheophile10][me]. None of the version-control engine is original work here —
55
+ the Zig source we compile lives at <https://github.com/rheophile10/xit/tree/wasm-spike>,
56
+ a fork that strips the parts wasm doesn't need (networking, TUI, CLI) and
57
+ adds the C ABI exports the bindings call into. Any improvements to the
58
+ underlying engine should go upstream to <https://github.com/xit-vcs/xit>.
59
+
60
+ ## API
61
+
62
+ The headline class is `Archive`. Construction:
63
+
64
+ ```ts
65
+ const fresh = await Archive.open(); // new repo on `master`
66
+ const opened = await Archive.open(zipBytes); // existing repo from a .甲
67
+ ```
68
+
69
+ Content (no wasm round-trip — pure in-memory writes):
70
+
71
+ ```ts
72
+ await archive.write(path, content);
73
+ const bytes = await archive.read(path);
74
+ const paths = await archive.list();
75
+ await archive.remove(path);
76
+ ```
77
+
78
+ Version control (each call goes through wasm):
79
+
80
+ ```ts
81
+ const oid = await archive.commit(message, { author? });
82
+ const history = await archive.log({ limit? }); // CommitInfo[]
83
+ await archive.branch(name);
84
+ const { branches, current } = await archive.listBranches();
85
+ const name = await archive.currentBranch(); // string | null
86
+ await archive.checkout(branch);
87
+ const result = await archive.merge(branch, { message?, author? });
88
+ // MergeResult: { kind: "success", oid } | "fast_forward" | "nothing" | "conflict"
89
+ ```
90
+
91
+ Persistence:
92
+
93
+ ```ts
94
+ const bytes = await archive.toBytes(); // zip the working tree
95
+ await archive.close(); // release the wasm handle
96
+ ```
97
+
98
+ ## Loading the wasm module
99
+
100
+ The package ships `xit.wasm` next to its entry module. By default
101
+ `Archive.open()` resolves it via `new URL("../xit.wasm", import.meta.url)`,
102
+ which Just Works in Node and most modern bundlers. For environments where
103
+ that doesn't (some bundlers strip `import.meta.url`, browser deployments
104
+ fetching from a CDN, etc.) configure the source explicitly:
105
+
106
+ ```ts
107
+ import { setDefaultWasmSource } from "xit-wasm";
108
+
109
+ setDefaultWasmSource(new URL("https://cdn.example.com/xit.wasm"));
110
+ // or
111
+ setDefaultWasmSource(preloadedBytes);
112
+ ```
113
+
114
+ Or pass per-call:
115
+
116
+ ```ts
117
+ await Archive.open(bytes, { wasm: customSource });
118
+ ```
119
+
120
+ ## Filesystem interop
121
+
122
+ xit-wasm is intentionally fs-free. If you want to drive xit against a real
123
+ filesystem (CLI tools, tests against an unzipped tree), import the Node host:
124
+
125
+ ```ts
126
+ import { NodeHost } from "xit-wasm/node";
127
+ ```
128
+
129
+ This exists primarily for the smoke tests under `example/`; most consumers
130
+ should reach for `Archive` and let MemoryHost back it.
131
+
132
+ ## Status
133
+
134
+ Alpha. The headline ops (init / open / write / commit / log / branch /
135
+ checkout / merge / toBytes) work and are validated end-to-end against
136
+ native `git` for the `.git` repo kind. The default `.xit` repo kind round-
137
+ trips through xitdb. There is no networking; conflict resolution beyond
138
+ "detect and report" is not yet wired into the JS surface; performance has
139
+ not been profiled.
140
+
141
+ ## Building from source
142
+
143
+ ```sh
144
+ # 1. build the wasm (requires zig 0.16)
145
+ cd ../xit && zig build wasm
146
+
147
+ # 2. build the TS package + copy xit.wasm into place
148
+ cd ../xit-wasm-ts && npm install && npm run build
149
+ ```
150
+
151
+ ## License
152
+
153
+ MIT.
154
+
155
+ [xit]: https://github.com/xit-vcs/xit
156
+ [me]: https://github.com/rheophile10
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Archive — the headline API for xit-wasm-ts.
3
+ *
4
+ * - Pure in-memory by default (uses MemoryHost as the wasm fs backend).
5
+ * - Hides every host/file/wasm concept from consumers.
6
+ * - Persists via toBytes() → zip / open(zipBytes) → unzip.
7
+ *
8
+ * The "pleasant surprise" version control methods (commit, log, branch,
9
+ * merge, etc.) sit on the same Archive instance so any consumer who
10
+ * receives an opened archive finds them in their IDE without asking.
11
+ */
12
+ export interface CommitOptions {
13
+ /** Author/committer string in the conventional `Name <email>` form.
14
+ * Defaults to `"plastron <plastron@local>"` if not given. */
15
+ author?: string;
16
+ }
17
+ export interface LoadOptions {
18
+ /** Override how the wasm module is sourced. Useful in browsers (pass a
19
+ * URL or already-fetched Uint8Array). Defaults to a relative path
20
+ * resolved against the dev tree — set this in any non-dev environment. */
21
+ wasm?: WasmSource;
22
+ }
23
+ export type WasmSource = Uint8Array | URL | string | ArrayBuffer;
24
+ export interface CommitInfo {
25
+ oid: string;
26
+ parents: string[];
27
+ /** Unix timestamp in seconds — taken from the commit metadata. May be 0
28
+ * if the commit was created without an explicit timestamp. */
29
+ timestamp: number;
30
+ author: string;
31
+ message: string;
32
+ }
33
+ export interface BranchListing {
34
+ branches: string[];
35
+ /** Index into `branches` of the currently checked-out branch, or null if
36
+ * HEAD is detached or not on any of the listed refs. */
37
+ current: number | null;
38
+ }
39
+ export interface MergeOptions {
40
+ message?: string;
41
+ author?: string;
42
+ }
43
+ export type MergeResult = {
44
+ kind: "success";
45
+ oid: string;
46
+ } | {
47
+ kind: "fast_forward";
48
+ } | {
49
+ kind: "nothing";
50
+ } | {
51
+ kind: "conflict";
52
+ };
53
+ export interface SwitchResult {
54
+ kind: "success" | "conflict";
55
+ }
56
+ /** Configure where the wasm module is loaded from for any subsequent
57
+ * Archive.open() call that doesn't pass `opts.wasm`. Most consumers don't
58
+ * need this — the package ships its `xit.wasm` next to the entry module
59
+ * and the loader auto-resolves it via `import.meta.url`. Useful when:
60
+ *
61
+ * - You want to load from a CDN (`new URL("https://...")`).
62
+ * - You want to use a different wasm artifact (e.g. dev build).
63
+ * - Your bundler doesn't preserve `import.meta.url` and you need to
64
+ * fall back to a hand-supplied URL or pre-fetched bytes. */
65
+ export declare function setDefaultWasmSource(source: WasmSource): void;
66
+ export declare class Archive {
67
+ private host;
68
+ private memory;
69
+ private exports;
70
+ private repoHandle;
71
+ private dirtyAdded;
72
+ private dirtyRemoved;
73
+ /** Files prefixed with `.xit/` are repo internals — Archive content
74
+ * reads/writes never touch them. */
75
+ private static readonly INTERNAL_PREFIX;
76
+ private constructor();
77
+ /** Open an archive. With no `bytes`, creates a fresh in-memory repo
78
+ * (master branch, no commits). With `bytes`, unzips into memory and
79
+ * opens the existing repo. */
80
+ static open(bytes?: Uint8Array, opts?: LoadOptions): Promise<Archive>;
81
+ /** Write a file into the archive's working tree. Triggers no commit. */
82
+ write(path: string, content: Uint8Array): Promise<void>;
83
+ read(path: string): Promise<Uint8Array | null>;
84
+ /** List all content paths (excluding repo internals). */
85
+ list(): Promise<string[]>;
86
+ remove(path: string): Promise<void>;
87
+ /** Stage every dirty path and commit. Returns the new commit OID (hex). */
88
+ commit(message: string, opts?: CommitOptions): Promise<string>;
89
+ /** Walk commit history reachable from HEAD. Newest first. */
90
+ log(opts?: {
91
+ limit?: number;
92
+ }): Promise<CommitInfo[]>;
93
+ /** Create a new branch off the current HEAD. */
94
+ branch(name: string): Promise<void>;
95
+ /** Returns every branch name plus an index identifying the currently
96
+ * checked-out one (or null when HEAD is detached). */
97
+ listBranches(): Promise<BranchListing>;
98
+ /** Convenience: just the currently checked-out branch name, or null. */
99
+ currentBranch(): Promise<string | null>;
100
+ /** Switch the working tree to the named branch. */
101
+ checkout(branch: string): Promise<SwitchResult>;
102
+ /** Merge the named branch into the current HEAD. */
103
+ merge(branch: string, opts?: MergeOptions): Promise<MergeResult>;
104
+ /** Serialize the entire working tree (including repo internals) as a
105
+ * fflate zip. The result IS the .甲 byte stream. */
106
+ toBytes(): Promise<Uint8Array>;
107
+ /** Release the wasm-side repo handle. Subsequent calls fail. The host's
108
+ * in-memory tree is dropped. */
109
+ close(): Promise<void>;
110
+ /** Pattern shared by log/branch_list/merge: wasm allocates a result buffer,
111
+ * writes the size to a u32 out-parameter, returns the pointer. We copy
112
+ * the bytes out, free both, and hand them to a decoder. */
113
+ private callBufReturn;
114
+ private withBytes;
115
+ private callPathsBuf;
116
+ private callCommit;
117
+ }
118
+ //# sourceMappingURL=archive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../src/archive.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,363 @@
1
+ /**
2
+ * Archive — the headline API for xit-wasm-ts.
3
+ *
4
+ * - Pure in-memory by default (uses MemoryHost as the wasm fs backend).
5
+ * - Hides every host/file/wasm concept from consumers.
6
+ * - Persists via toBytes() → zip / open(zipBytes) → unzip.
7
+ *
8
+ * The "pleasant surprise" version control methods (commit, log, branch,
9
+ * merge, etc.) sit on the same Archive instance so any consumer who
10
+ * receives an opened archive finds them in their IDE without asking.
11
+ */
12
+ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
13
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
14
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
15
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
16
+ });
17
+ }
18
+ return path;
19
+ };
20
+ import { unzipSync, zipSync } from "fflate";
21
+ import { MemoryHost } from "./host-memory.js";
22
+ import { hostImports } from "./host.js";
23
+ /** Where the in-memory repo lives inside the wasm fs. Keep this stable —
24
+ * changing it would invalidate any existing .甲 archive. */
25
+ const REPO_PATH = "/";
26
+ /** Hex SHA-1 oid length. */
27
+ const OID_HEX = 40;
28
+ let defaultWasmSource;
29
+ /** Configure where the wasm module is loaded from for any subsequent
30
+ * Archive.open() call that doesn't pass `opts.wasm`. Most consumers don't
31
+ * need this — the package ships its `xit.wasm` next to the entry module
32
+ * and the loader auto-resolves it via `import.meta.url`. Useful when:
33
+ *
34
+ * - You want to load from a CDN (`new URL("https://...")`).
35
+ * - You want to use a different wasm artifact (e.g. dev build).
36
+ * - Your bundler doesn't preserve `import.meta.url` and you need to
37
+ * fall back to a hand-supplied URL or pre-fetched bytes. */
38
+ export function setDefaultWasmSource(source) {
39
+ defaultWasmSource = source;
40
+ }
41
+ /** Default location of `xit.wasm` shipped with the package. Resolves
42
+ * consistently from src (during dev) and from dist (after build) because
43
+ * the file lives at the package root, one level up from either entry. */
44
+ function bundledWasmUrl() {
45
+ return new URL("../xit.wasm", import.meta.url);
46
+ }
47
+ async function resolveWasmBytes(source) {
48
+ if (source instanceof Uint8Array)
49
+ return source;
50
+ if (source instanceof ArrayBuffer)
51
+ return new Uint8Array(source);
52
+ const ref = source instanceof URL ? source.toString() : source;
53
+ // Prefer fetch for http(s) and blob URLs (browser, Bun, modern Node);
54
+ // file:// and bare paths go through the Node fs path so we don't take a
55
+ // dependency on fetch supporting file URLs (Node only added that recently).
56
+ if (typeof globalThis.fetch === "function" && /^https?:|^blob:/.test(ref)) {
57
+ const r = await fetch(ref);
58
+ return new Uint8Array(await r.arrayBuffer());
59
+ }
60
+ // Fall back to Node fs only when actually running on Node. Browser
61
+ // bundlers that statically analyze a bare `import("node:fs/promises")`
62
+ // would emit it as a stub and warn even when this branch is
63
+ // unreachable; routing through a runtime-built specifier keeps the
64
+ // browser build clean. The Node-default `bundledWasmUrl()` uses
65
+ // `import.meta.url`, which resolves to an http(s) URL after Vite asset
66
+ // emission — so browsers take the fetch branch above and never reach
67
+ // this fallback.
68
+ const isNode = typeof globalThis.process !== "undefined"
69
+ && globalThis.process.versions != null
70
+ && typeof globalThis.process.versions.node === "string";
71
+ if (!isNode) {
72
+ throw new Error(`xit-wasm: cannot resolve wasm source "${ref}" — fetch is unavailable ` +
73
+ `and no Node fs is present. Pass opts.wasm as a Uint8Array, ArrayBuffer, ` +
74
+ `or http(s)/blob URL.`);
75
+ }
76
+ const nodeFsSpecifier = "node:fs/promises";
77
+ const fs = await import(__rewriteRelativeImportExtension(/* @vite-ignore */ nodeFsSpecifier));
78
+ if (ref.startsWith("file:")) {
79
+ return new Uint8Array(await fs.readFile(new URL(ref)));
80
+ }
81
+ return new Uint8Array(await fs.readFile(ref));
82
+ }
83
+ export class Archive {
84
+ host;
85
+ memory;
86
+ exports;
87
+ repoHandle;
88
+ dirtyAdded = new Set();
89
+ dirtyRemoved = new Set();
90
+ /** Files prefixed with `.xit/` are repo internals — Archive content
91
+ * reads/writes never touch them. */
92
+ static INTERNAL_PREFIX = ".xit/";
93
+ constructor(host, memory, exports, repoHandle) {
94
+ this.host = host;
95
+ this.memory = memory;
96
+ this.exports = exports;
97
+ this.repoHandle = repoHandle;
98
+ }
99
+ /** Open an archive. With no `bytes`, creates a fresh in-memory repo
100
+ * (master branch, no commits). With `bytes`, unzips into memory and
101
+ * opens the existing repo. */
102
+ static async open(bytes, opts = {}) {
103
+ const wasmSource = opts.wasm ?? defaultWasmSource ?? bundledWasmUrl();
104
+ const wasmBytes = await resolveWasmBytes(wasmSource);
105
+ // WebAssembly.compile expects a BufferSource over a non-shared ArrayBuffer.
106
+ // Make a fresh copy with a plain ArrayBuffer to satisfy strict typings.
107
+ const wasmCopy = new Uint8Array(wasmBytes.byteLength);
108
+ wasmCopy.set(wasmBytes);
109
+ const mod = await WebAssembly.compile(wasmCopy);
110
+ const host = new MemoryHost();
111
+ if (bytes) {
112
+ const tree = unzipSync(bytes);
113
+ const map = new Map();
114
+ for (const [name, content] of Object.entries(tree)) {
115
+ if (content.length === 0 && name.endsWith("/"))
116
+ continue; // skip dir markers
117
+ map.set(name, content);
118
+ }
119
+ host.bulkLoad(map);
120
+ }
121
+ let memory;
122
+ const inst = await WebAssembly.instantiate(mod, hostImports(host, () => memory));
123
+ const exports = inst.exports;
124
+ memory = exports.memory;
125
+ const enc = new TextEncoder();
126
+ const pathBytes = enc.encode(REPO_PATH);
127
+ const pathPtr = exports.xit_alloc(pathBytes.length);
128
+ if (pathPtr === 0)
129
+ throw new Error("xit-wasm: alloc failed for repo path");
130
+ new Uint8Array(memory.buffer, pathPtr, pathBytes.length).set(pathBytes);
131
+ const handle = bytes
132
+ ? exports.xit_repo_open(pathPtr, pathBytes.length)
133
+ : exports.xit_repo_init(pathPtr, pathBytes.length);
134
+ exports.xit_free(pathPtr, pathBytes.length);
135
+ if (handle < 0) {
136
+ throw new Error(`xit-wasm: ${bytes ? "xit_repo_open" : "xit_repo_init"} failed with code ${handle}`);
137
+ }
138
+ return new Archive(host, memory, exports, handle);
139
+ }
140
+ // ---- content ops (no wasm involvement) ----
141
+ /** Write a file into the archive's working tree. Triggers no commit. */
142
+ async write(path, content) {
143
+ if (path.startsWith(Archive.INTERNAL_PREFIX) || path.startsWith("/" + Archive.INTERNAL_PREFIX)) {
144
+ throw new Error(`Archive.write: path "${path}" is reserved for repo internals`);
145
+ }
146
+ this.host.putFile(path, content);
147
+ this.dirtyAdded.add(stripLeading(path));
148
+ this.dirtyRemoved.delete(stripLeading(path));
149
+ }
150
+ async read(path) {
151
+ return this.host.getFile(path);
152
+ }
153
+ /** List all content paths (excluding repo internals). */
154
+ async list() {
155
+ return this.host
156
+ .listFiles()
157
+ .filter((p) => !p.startsWith(Archive.INTERNAL_PREFIX));
158
+ }
159
+ async remove(path) {
160
+ const removed = this.host.removeFile(path);
161
+ if (!removed)
162
+ return;
163
+ const stripped = stripLeading(path);
164
+ this.dirtyRemoved.add(stripped);
165
+ this.dirtyAdded.delete(stripped);
166
+ }
167
+ // ---- version control ----
168
+ /** Stage every dirty path and commit. Returns the new commit OID (hex). */
169
+ async commit(message, opts = {}) {
170
+ const author = opts.author ?? "plastron <plastron@local>";
171
+ if (this.dirtyAdded.size > 0) {
172
+ this.callPathsBuf("xit_repo_add", Array.from(this.dirtyAdded));
173
+ }
174
+ if (this.dirtyRemoved.size > 0) {
175
+ this.callPathsBuf("xit_repo_remove", Array.from(this.dirtyRemoved));
176
+ }
177
+ const oid = this.callCommit(message, author);
178
+ this.dirtyAdded.clear();
179
+ this.dirtyRemoved.clear();
180
+ return oid;
181
+ }
182
+ /** Walk commit history reachable from HEAD. Newest first. */
183
+ async log(opts = {}) {
184
+ return this.callBufReturn((outSizePtr) => this.exports.xit_repo_log(this.repoHandle, opts.limit ?? 0, outSizePtr), (bytes) => decodeLog(bytes));
185
+ }
186
+ /** Create a new branch off the current HEAD. */
187
+ async branch(name) {
188
+ const enc = new TextEncoder();
189
+ const code = this.withBytes(enc.encode(name), (ptr, len) => this.exports.xit_repo_branch_add(this.repoHandle, ptr, len));
190
+ if (code < 0)
191
+ throw new Error(`xit-wasm: xit_repo_branch_add failed with code ${code}`);
192
+ }
193
+ /** Returns every branch name plus an index identifying the currently
194
+ * checked-out one (or null when HEAD is detached). */
195
+ async listBranches() {
196
+ return this.callBufReturn((outSizePtr) => this.exports.xit_repo_branch_list(this.repoHandle, outSizePtr), (bytes) => decodeBranches(bytes));
197
+ }
198
+ /** Convenience: just the currently checked-out branch name, or null. */
199
+ async currentBranch() {
200
+ const { branches, current } = await this.listBranches();
201
+ return current === null ? null : branches[current] ?? null;
202
+ }
203
+ /** Switch the working tree to the named branch. */
204
+ async checkout(branch) {
205
+ const enc = new TextEncoder();
206
+ const code = this.withBytes(enc.encode(branch), (ptr, len) => this.exports.xit_repo_switch(this.repoHandle, ptr, len));
207
+ if (code < 0)
208
+ throw new Error(`xit-wasm: xit_repo_switch failed with code ${code}`);
209
+ return { kind: code === 0 ? "success" : "conflict" };
210
+ }
211
+ /** Merge the named branch into the current HEAD. */
212
+ async merge(branch, opts = {}) {
213
+ const enc = new TextEncoder();
214
+ const message = opts.message ?? `merge ${branch}`;
215
+ const author = opts.author ?? "plastron <plastron@local>";
216
+ return this.callBufReturn((outSizePtr) => this.withBytes(enc.encode(branch), (bp, bl) => this.withBytes(enc.encode(message), (mp, ml) => this.withBytes(enc.encode(author), (ap, al) => this.exports.xit_repo_merge(this.repoHandle, bp, bl, mp, ml, ap, al, outSizePtr)))), (bytes) => decodeMergeResult(bytes));
217
+ }
218
+ /** Serialize the entire working tree (including repo internals) as a
219
+ * fflate zip. The result IS the .甲 byte stream. */
220
+ async toBytes() {
221
+ const tree = this.host.snapshot();
222
+ const files = {};
223
+ for (const [path, content] of tree)
224
+ files[path] = content;
225
+ return zipSync(files);
226
+ }
227
+ /** Release the wasm-side repo handle. Subsequent calls fail. The host's
228
+ * in-memory tree is dropped. */
229
+ async close() {
230
+ this.exports.xit_repo_close(this.repoHandle);
231
+ this.repoHandle = -1;
232
+ }
233
+ // ---- internal: marshalling helpers ----
234
+ /** Pattern shared by log/branch_list/merge: wasm allocates a result buffer,
235
+ * writes the size to a u32 out-parameter, returns the pointer. We copy
236
+ * the bytes out, free both, and hand them to a decoder. */
237
+ callBufReturn(call, decode) {
238
+ const outSizePtr = this.exports.xit_alloc(4);
239
+ if (outSizePtr === 0)
240
+ throw new Error("xit-wasm: alloc failed for out_size");
241
+ let dataPtr = 0;
242
+ let size = 0;
243
+ try {
244
+ dataPtr = call(outSizePtr);
245
+ if (dataPtr === 0)
246
+ throw new Error("xit-wasm: returned null buffer");
247
+ size = new DataView(this.memory.buffer, outSizePtr, 4).getUint32(0, true);
248
+ const copy = new Uint8Array(this.memory.buffer, dataPtr, size).slice();
249
+ return decode(copy);
250
+ }
251
+ finally {
252
+ if (dataPtr !== 0)
253
+ this.exports.xit_free(dataPtr, size);
254
+ this.exports.xit_free(outSizePtr, 4);
255
+ }
256
+ }
257
+ withBytes(bytes, fn) {
258
+ const ptr = this.exports.xit_alloc(bytes.length);
259
+ if (ptr === 0)
260
+ throw new Error("xit-wasm: alloc failed");
261
+ new Uint8Array(this.memory.buffer, ptr, bytes.length).set(bytes);
262
+ try {
263
+ return fn(ptr, bytes.length);
264
+ }
265
+ finally {
266
+ this.exports.xit_free(ptr, bytes.length);
267
+ }
268
+ }
269
+ callPathsBuf(fn, paths) {
270
+ const enc = new TextEncoder();
271
+ const buf = enc.encode(paths.join("\n"));
272
+ const code = this.withBytes(buf, (ptr, len) => this.exports[fn](this.repoHandle, ptr, len));
273
+ if (code < 0) {
274
+ throw new Error(`xit-wasm: ${fn} failed with code ${code}`);
275
+ }
276
+ }
277
+ callCommit(message, author) {
278
+ const enc = new TextEncoder();
279
+ const msgBytes = enc.encode(message);
280
+ const authorBytes = enc.encode(author);
281
+ const oidPtr = this.exports.xit_alloc(OID_HEX);
282
+ if (oidPtr === 0)
283
+ throw new Error("xit-wasm: alloc failed for oid");
284
+ try {
285
+ return this.withBytes(msgBytes, (mp, ml) => this.withBytes(authorBytes, (ap, al) => {
286
+ const code = this.exports.xit_repo_commit(this.repoHandle, mp, ml, ap, al, oidPtr, OID_HEX);
287
+ if (code < 0) {
288
+ throw new Error(`xit-wasm: xit_repo_commit failed with code ${code}`);
289
+ }
290
+ const oidBytes = new Uint8Array(this.memory.buffer, oidPtr, OID_HEX);
291
+ return new TextDecoder().decode(oidBytes);
292
+ }));
293
+ }
294
+ finally {
295
+ this.exports.xit_free(oidPtr, OID_HEX);
296
+ }
297
+ }
298
+ }
299
+ function stripLeading(p) {
300
+ return p.startsWith("/") ? p.slice(1) : p;
301
+ }
302
+ // =========================================================================
303
+ // Wire decoders (mirror the formats documented in xit/src/lib.zig).
304
+ // =========================================================================
305
+ const dec = new TextDecoder();
306
+ function decodeLog(buf) {
307
+ const dv = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
308
+ let p = 0;
309
+ const count = dv.getUint32(p, true);
310
+ p += 4;
311
+ const out = [];
312
+ for (let i = 0; i < count; i++) {
313
+ const oid = dec.decode(buf.subarray(p, p + OID_HEX));
314
+ p += OID_HEX;
315
+ const parentCount = dv.getUint32(p, true);
316
+ p += 4;
317
+ const parents = [];
318
+ for (let j = 0; j < parentCount; j++) {
319
+ parents.push(dec.decode(buf.subarray(p, p + OID_HEX)));
320
+ p += OID_HEX;
321
+ }
322
+ const timestamp = Number(dv.getBigUint64(p, true));
323
+ p += 8;
324
+ const authorLen = dv.getUint32(p, true);
325
+ p += 4;
326
+ const author = dec.decode(buf.subarray(p, p + authorLen));
327
+ p += authorLen;
328
+ const messageLen = dv.getUint32(p, true);
329
+ p += 4;
330
+ const message = dec.decode(buf.subarray(p, p + messageLen));
331
+ p += messageLen;
332
+ out.push({ oid, parents, timestamp, author, message });
333
+ }
334
+ return out;
335
+ }
336
+ function decodeBranches(buf) {
337
+ const dv = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
338
+ let p = 0;
339
+ const count = dv.getUint32(p, true);
340
+ p += 4;
341
+ const currentRaw = dv.getInt32(p, true);
342
+ p += 4;
343
+ const branches = [];
344
+ for (let i = 0; i < count; i++) {
345
+ const nameLen = dv.getUint32(p, true);
346
+ p += 4;
347
+ branches.push(dec.decode(buf.subarray(p, p + nameLen)));
348
+ p += nameLen;
349
+ }
350
+ return { branches, current: currentRaw < 0 ? null : currentRaw };
351
+ }
352
+ function decodeMergeResult(buf) {
353
+ const dv = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
354
+ const kind = dv.getUint32(0, true);
355
+ switch (kind) {
356
+ case 0: return { kind: "success", oid: dec.decode(buf.subarray(4, 4 + OID_HEX)) };
357
+ case 1: return { kind: "fast_forward" };
358
+ case 2: return { kind: "nothing" };
359
+ case 3: return { kind: "conflict" };
360
+ default: throw new Error(`xit-wasm: unexpected merge result kind ${kind}`);
361
+ }
362
+ }
363
+ //# sourceMappingURL=archive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archive.js","sourceRoot":"","sources":["../src/archive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;;;;;;;;;AAEH,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAE5C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC;4DAC4D;AAC5D,MAAM,SAAS,GAAG,GAAG,CAAC;AAEtB,4BAA4B;AAC5B,MAAM,OAAO,GAAG,EAAE,CAAC;AAoFnB,IAAI,iBAAyC,CAAC;AAE9C;;;;;;;;iEAQiE;AACjE,MAAM,UAAU,oBAAoB,CAAC,MAAkB;IACrD,iBAAiB,GAAG,MAAM,CAAC;AAC7B,CAAC;AAED;;0EAE0E;AAC1E,SAAS,cAAc;IACrB,OAAO,IAAI,GAAG,CAAC,aAAa,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACjD,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,MAAkB;IAChD,IAAI,MAAM,YAAY,UAAU;QAAE,OAAO,MAAM,CAAC;IAChD,IAAI,MAAM,YAAY,WAAW;QAAE,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;IAEjE,MAAM,GAAG,GAAG,MAAM,YAAY,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;IAE/D,sEAAsE;IACtE,wEAAwE;IACxE,4EAA4E;IAC5E,IAAI,OAAO,UAAU,CAAC,KAAK,KAAK,UAAU,IAAI,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1E,MAAM,CAAC,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3B,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,mEAAmE;IACnE,uEAAuE;IACvE,4DAA4D;IAC5D,mEAAmE;IACnE,gEAAgE;IAChE,uEAAuE;IACvE,qEAAqE;IACrE,iBAAiB;IACjB,MAAM,MAAM,GAAG,OAAO,UAAU,CAAC,OAAO,KAAK,WAAW;WACnD,UAAU,CAAC,OAAO,CAAC,QAAQ,IAAI,IAAI;WACnC,OAAO,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC;IAC1D,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,yCAAyC,GAAG,2BAA2B;YACvE,0EAA0E;YAC1E,sBAAsB,CACvB,CAAC;IACJ,CAAC;IACD,MAAM,eAAe,GAAG,kBAAkB,CAAC;IAC3C,MAAM,EAAE,GAAG,MAAM,MAAM,kCAAC,kBAAkB,CAAC,eAAe,EAAC,CAAC;IAC5D,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,OAAO,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,OAAO,OAAO;IACV,IAAI,CAAa;IACjB,MAAM,CAAqB;IAC3B,OAAO,CAAa;IACpB,UAAU,CAAS;IACnB,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IAEzC;yCACqC;IAC7B,MAAM,CAAU,eAAe,GAAG,OAAO,CAAC;IAElD,YACE,IAAgB,EAChB,MAA0B,EAC1B,OAAmB,EACnB,UAAkB;QAElB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;IAED;;mCAE+B;IAC/B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAkB,EAAE,OAAoB,EAAE;QAC1D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,IAAI,iBAAiB,IAAI,cAAc,EAAE,CAAC;QACtE,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC,UAAU,CAAC,CAAC;QACrD,4EAA4E;QAC5E,wEAAwE;QACxE,MAAM,QAAQ,GAAG,IAAI,UAAU,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACtD,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACxB,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAEhD,MAAM,IAAI,GAAG,IAAI,UAAU,EAAE,CAAC;QAC9B,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;YAC9B,MAAM,GAAG,GAAG,IAAI,GAAG,EAAsB,CAAC;YAC1C,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBACnD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;oBAAE,SAAS,CAAC,mBAAmB;gBAC7E,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACzB,CAAC;YACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;QAED,IAAI,MAA2B,CAAC;QAChC,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,WAAW,CAAC,GAAG,EAAE,WAAW,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;QACjF,MAAM,OAAO,GAAG,IAAI,CAAC,OAAgC,CAAC;QACtD,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAExB,MAAM,GAAG,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACxC,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACpD,IAAI,OAAO,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC3E,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAExE,MAAM,MAAM,GAAG,KAAK;YAClB,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,EAAE,SAAS,CAAC,MAAM,CAAC;YAClD,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;QAErD,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;QAE5C,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,aAAa,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,eAAe,qBAAqB,MAAM,EAAE,CACpF,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACpD,CAAC;IAED,8CAA8C;IAE9C,wEAAwE;IACxE,KAAK,CAAC,KAAK,CAAC,IAAY,EAAE,OAAmB;QAC3C,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;YAC/F,MAAM,IAAI,KAAK,CAAC,wBAAwB,IAAI,kCAAkC,CAAC,CAAC;QAClF,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACjC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;QACxC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAY;QACrB,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,yDAAyD;IACzD,KAAK,CAAC,IAAI;QACR,OAAO,IAAI,CAAC,IAAI;aACb,SAAS,EAAE;aACX,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,CAAC,OAAO;YAAE,OAAO;QACrB,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAChC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACnC,CAAC;IAED,4BAA4B;IAE5B,2EAA2E;IAC3E,KAAK,CAAC,MAAM,CAAC,OAAe,EAAE,OAAsB,EAAE;QACpD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,2BAA2B,CAAC;QAE1D,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC,YAAY,CAAC,cAAc,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QACjE,CAAC;QACD,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YAC/B,IAAI,CAAC,YAAY,CAAC,iBAAiB,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;QACtE,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAE7C,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACxB,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;QAC1B,OAAO,GAAG,CAAC;IACb,CAAC;IAED,6DAA6D;IAC7D,KAAK,CAAC,GAAG,CAAC,OAA2B,EAAE;QACrC,OAAO,IAAI,CAAC,aAAa,CACvB,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,IAAI,CAAC,EAAE,UAAU,CAAC,EACvF,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,CAC5B,CAAC;IACJ,CAAC;IAED,gDAAgD;IAChD,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,MAAM,GAAG,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CACzD,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,EAAE,GAAG,CAAC,CAC5D,CAAC;QACF,IAAI,IAAI,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,kDAAkD,IAAI,EAAE,CAAC,CAAC;IAC1F,CAAC;IAED;2DACuD;IACvD,KAAK,CAAC,YAAY;QAChB,OAAO,IAAI,CAAC,aAAa,CACvB,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,EAC9E,CAAC,KAAK,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,CACjC,CAAC;IACJ,CAAC;IAED,wEAAwE;IACxE,KAAK,CAAC,aAAa;QACjB,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;QACxD,OAAO,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;IAC7D,CAAC;IAED,mDAAmD;IACnD,KAAK,CAAC,QAAQ,CAAC,MAAc;QAC3B,MAAM,GAAG,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAC3D,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,EAAE,GAAG,CAAC,CACxD,CAAC;QACF,IAAI,IAAI,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,8CAA8C,IAAI,EAAE,CAAC,CAAC;QACpF,OAAO,EAAE,IAAI,EAAE,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC;IACvD,CAAC;IAED,oDAAoD;IACpD,KAAK,CAAC,KAAK,CAAC,MAAc,EAAE,OAAqB,EAAE;QACjD,MAAM,GAAG,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,SAAS,MAAM,EAAE,CAAC;QAClD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,2BAA2B,CAAC;QAE1D,OAAO,IAAI,CAAC,aAAa,CACvB,CAAC,UAAU,EAAE,EAAE,CACb,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAC5C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAC7C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAC5C,IAAI,CAAC,OAAO,CAAC,cAAc,CACzB,IAAI,CAAC,UAAU,EACf,EAAE,EACF,EAAE,EACF,EAAE,EACF,EAAE,EACF,EAAE,EACF,EAAE,EACF,UAAU,CACX,CACF,CACF,CACF,EACH,CAAC,KAAK,EAAE,EAAE,CAAC,iBAAiB,CAAC,KAAK,CAAC,CACpC,CAAC;IACJ,CAAC;IAED;wDACoD;IACpD,KAAK,CAAC,OAAO;QACX,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClC,MAAM,KAAK,GAA+B,EAAE,CAAC;QAC7C,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC;QAC1D,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC;IAED;qCACiC;IACjC,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC7C,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;IACvB,CAAC;IAED,0CAA0C;IAE1C;;gEAE4D;IACpD,aAAa,CACnB,IAAoC,EACpC,MAAgC;QAEhC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QAC7C,IAAI,UAAU,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QAC7E,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,IAAI,CAAC;YACH,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;YAC3B,IAAI,OAAO,KAAK,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;YACrE,IAAI,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;YAC1E,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;YACvE,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;gBAAS,CAAC;YACT,IAAI,OAAO,KAAK,CAAC;gBAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YACxD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAEO,SAAS,CAAI,KAAiB,EAAE,EAAmC;QACzE,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACjD,IAAI,GAAG,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QACzD,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACjE,IAAI,CAAC;YACH,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAEO,YAAY,CAClB,EAAsC,EACtC,KAAe;QAEf,MAAM,GAAG,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACzC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAC5C,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,EAAE,GAAG,CAAC,CAC5C,CAAC;QACF,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,aAAa,EAAE,qBAAqB,IAAI,EAAE,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAEO,UAAU,CAAC,OAAe,EAAE,MAAc;QAChD,MAAM,GAAG,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACvC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAC/C,IAAI,MAAM,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACpE,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CACzC,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE;gBACrC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,CACvC,IAAI,CAAC,UAAU,EACf,EAAE,EACF,EAAE,EACF,EAAE,EACF,EAAE,EACF,MAAM,EACN,OAAO,CACR,CAAC;gBACF,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;oBACb,MAAM,IAAI,KAAK,CAAC,8CAA8C,IAAI,EAAE,CAAC,CAAC;gBACxE,CAAC;gBACD,MAAM,QAAQ,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;gBACrE,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC5C,CAAC,CAAC,CACH,CAAC;QACJ,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;;AAGH,SAAS,YAAY,CAAC,CAAS;IAC7B,OAAO,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED,4EAA4E;AAC5E,oEAAoE;AACpE,4EAA4E;AAE5E,MAAM,GAAG,GAAG,IAAI,WAAW,EAAE,CAAC;AAE9B,SAAS,SAAS,CAAC,GAAe;IAChC,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;IACpE,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,MAAM,KAAK,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAAC,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,GAAG,GAAiB,EAAE,CAAC;IAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;QAAC,CAAC,IAAI,OAAO,CAAC;QACnE,MAAM,WAAW,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QAAC,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YAAC,CAAC,IAAI,OAAO,CAAC;QACvE,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;QAAC,CAAC,IAAI,CAAC,CAAC;QAC3D,MAAM,SAAS,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QAAC,CAAC,IAAI,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;QAAC,CAAC,IAAI,SAAS,CAAC;QAC1E,MAAM,UAAU,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QAAC,CAAC,IAAI,CAAC,CAAC;QACjD,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC;QAAC,CAAC,IAAI,UAAU,CAAC;QAC7E,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,cAAc,CAAC,GAAe;IACrC,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;IACpE,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,MAAM,KAAK,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAAC,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,UAAU,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAAC,CAAC,IAAI,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QAAC,CAAC,IAAI,CAAC,CAAC;QAC9C,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QAAC,CAAC,IAAI,OAAO,CAAC;IACxE,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC;AACnE,CAAC;AAED,SAAS,iBAAiB,CAAC,GAAe;IACxC,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;IACpE,MAAM,IAAI,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACnC,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;QAClF,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC;QACxC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACnC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;QACpC,OAAO,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,0CAA0C,IAAI,EAAE,CAAC,CAAC;IAC7E,CAAC;AACH,CAAC"}