@ifc-lite/collab 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. package/LICENSE +373 -0
  2. package/README.md +92 -0
  3. package/dist/awareness/agent.d.ts +36 -0
  4. package/dist/awareness/agent.d.ts.map +1 -0
  5. package/dist/awareness/agent.js +39 -0
  6. package/dist/awareness/agent.js.map +1 -0
  7. package/dist/awareness/color.d.ts +31 -0
  8. package/dist/awareness/color.d.ts.map +1 -0
  9. package/dist/awareness/color.js +61 -0
  10. package/dist/awareness/color.js.map +1 -0
  11. package/dist/awareness/index.d.ts +6 -0
  12. package/dist/awareness/index.d.ts.map +1 -0
  13. package/dist/awareness/index.js +9 -0
  14. package/dist/awareness/index.js.map +1 -0
  15. package/dist/awareness/overlay.d.ts +59 -0
  16. package/dist/awareness/overlay.d.ts.map +1 -0
  17. package/dist/awareness/overlay.js +110 -0
  18. package/dist/awareness/overlay.js.map +1 -0
  19. package/dist/awareness/presence.d.ts +95 -0
  20. package/dist/awareness/presence.d.ts.map +1 -0
  21. package/dist/awareness/presence.js +114 -0
  22. package/dist/awareness/presence.js.map +1 -0
  23. package/dist/awareness/render.d.ts +58 -0
  24. package/dist/awareness/render.d.ts.map +1 -0
  25. package/dist/awareness/render.js +66 -0
  26. package/dist/awareness/render.js.map +1 -0
  27. package/dist/branch/branch-tree.d.ts +40 -0
  28. package/dist/branch/branch-tree.d.ts.map +1 -0
  29. package/dist/branch/branch-tree.js +66 -0
  30. package/dist/branch/branch-tree.js.map +1 -0
  31. package/dist/branch/branch.d.ts +44 -0
  32. package/dist/branch/branch.d.ts.map +1 -0
  33. package/dist/branch/branch.js +109 -0
  34. package/dist/branch/branch.js.map +1 -0
  35. package/dist/branch/history-automerge.d.ts +31 -0
  36. package/dist/branch/history-automerge.d.ts.map +1 -0
  37. package/dist/branch/history-automerge.js +237 -0
  38. package/dist/branch/history-automerge.js.map +1 -0
  39. package/dist/branch/history.d.ts +147 -0
  40. package/dist/branch/history.d.ts.map +1 -0
  41. package/dist/branch/history.js +223 -0
  42. package/dist/branch/history.js.map +1 -0
  43. package/dist/branch/index.d.ts +5 -0
  44. package/dist/branch/index.d.ts.map +1 -0
  45. package/dist/branch/index.js +8 -0
  46. package/dist/branch/index.js.map +1 -0
  47. package/dist/conflicts/detector.d.ts +52 -0
  48. package/dist/conflicts/detector.d.ts.map +1 -0
  49. package/dist/conflicts/detector.js +226 -0
  50. package/dist/conflicts/detector.js.map +1 -0
  51. package/dist/conflicts/index.d.ts +3 -0
  52. package/dist/conflicts/index.d.ts.map +1 -0
  53. package/dist/conflicts/index.js +6 -0
  54. package/dist/conflicts/index.js.map +1 -0
  55. package/dist/conflicts/ui-bridge.d.ts +80 -0
  56. package/dist/conflicts/ui-bridge.d.ts.map +1 -0
  57. package/dist/conflicts/ui-bridge.js +126 -0
  58. package/dist/conflicts/ui-bridge.js.map +1 -0
  59. package/dist/doc/entity.d.ts +84 -0
  60. package/dist/doc/entity.d.ts.map +1 -0
  61. package/dist/doc/entity.js +345 -0
  62. package/dist/doc/entity.js.map +1 -0
  63. package/dist/doc/geometry.d.ts +39 -0
  64. package/dist/doc/geometry.d.ts.map +1 -0
  65. package/dist/doc/geometry.js +99 -0
  66. package/dist/doc/geometry.js.map +1 -0
  67. package/dist/doc/index.d.ts +8 -0
  68. package/dist/doc/index.d.ts.map +1 -0
  69. package/dist/doc/index.js +11 -0
  70. package/dist/doc/index.js.map +1 -0
  71. package/dist/doc/migration-ifc4-to-ifc4x3.d.ts +21 -0
  72. package/dist/doc/migration-ifc4-to-ifc4x3.d.ts.map +1 -0
  73. package/dist/doc/migration-ifc4-to-ifc4x3.js +55 -0
  74. package/dist/doc/migration-ifc4-to-ifc4x3.js.map +1 -0
  75. package/dist/doc/relationship.d.ts +27 -0
  76. package/dist/doc/relationship.d.ts.map +1 -0
  77. package/dist/doc/relationship.js +110 -0
  78. package/dist/doc/relationship.js.map +1 -0
  79. package/dist/doc/schema-version.d.ts +47 -0
  80. package/dist/doc/schema-version.d.ts.map +1 -0
  81. package/dist/doc/schema-version.js +41 -0
  82. package/dist/doc/schema-version.js.map +1 -0
  83. package/dist/doc/schema.d.ts +131 -0
  84. package/dist/doc/schema.d.ts.map +1 -0
  85. package/dist/doc/schema.js +117 -0
  86. package/dist/doc/schema.js.map +1 -0
  87. package/dist/doc/units.d.ts +45 -0
  88. package/dist/doc/units.d.ts.map +1 -0
  89. package/dist/doc/units.js +120 -0
  90. package/dist/doc/units.js.map +1 -0
  91. package/dist/federation/bridge.d.ts +34 -0
  92. package/dist/federation/bridge.d.ts.map +1 -0
  93. package/dist/federation/bridge.js +52 -0
  94. package/dist/federation/bridge.js.map +1 -0
  95. package/dist/federation/index.d.ts +4 -0
  96. package/dist/federation/index.d.ts.map +1 -0
  97. package/dist/federation/index.js +7 -0
  98. package/dist/federation/index.js.map +1 -0
  99. package/dist/federation/resolver.d.ts +58 -0
  100. package/dist/federation/resolver.d.ts.map +1 -0
  101. package/dist/federation/resolver.js +43 -0
  102. package/dist/federation/resolver.js.map +1 -0
  103. package/dist/federation/session.d.ts +79 -0
  104. package/dist/federation/session.d.ts.map +1 -0
  105. package/dist/federation/session.js +126 -0
  106. package/dist/federation/session.js.map +1 -0
  107. package/dist/geometry/blob-store.d.ts +106 -0
  108. package/dist/geometry/blob-store.d.ts.map +1 -0
  109. package/dist/geometry/blob-store.js +266 -0
  110. package/dist/geometry/blob-store.js.map +1 -0
  111. package/dist/geometry/csg.d.ts +63 -0
  112. package/dist/geometry/csg.d.ts.map +1 -0
  113. package/dist/geometry/csg.js +101 -0
  114. package/dist/geometry/csg.js.map +1 -0
  115. package/dist/geometry/determinism.d.ts +45 -0
  116. package/dist/geometry/determinism.d.ts.map +1 -0
  117. package/dist/geometry/determinism.js +92 -0
  118. package/dist/geometry/determinism.js.map +1 -0
  119. package/dist/geometry/gc.d.ts +63 -0
  120. package/dist/geometry/gc.d.ts.map +1 -0
  121. package/dist/geometry/gc.js +109 -0
  122. package/dist/geometry/gc.js.map +1 -0
  123. package/dist/geometry/index.d.ts +6 -0
  124. package/dist/geometry/index.d.ts.map +1 -0
  125. package/dist/geometry/index.js +9 -0
  126. package/dist/geometry/index.js.map +1 -0
  127. package/dist/geometry/parametric.d.ts +92 -0
  128. package/dist/geometry/parametric.d.ts.map +1 -0
  129. package/dist/geometry/parametric.js +200 -0
  130. package/dist/geometry/parametric.js.map +1 -0
  131. package/dist/index.d.ts +27 -0
  132. package/dist/index.d.ts.map +1 -0
  133. package/dist/index.js +46 -0
  134. package/dist/index.js.map +1 -0
  135. package/dist/mutations/bind.d.ts +56 -0
  136. package/dist/mutations/bind.d.ts.map +1 -0
  137. package/dist/mutations/bind.js +68 -0
  138. package/dist/mutations/bind.js.map +1 -0
  139. package/dist/mutations/index.d.ts +2 -0
  140. package/dist/mutations/index.d.ts.map +1 -0
  141. package/dist/mutations/index.js +5 -0
  142. package/dist/mutations/index.js.map +1 -0
  143. package/dist/perf/benchmark.d.ts +25 -0
  144. package/dist/perf/benchmark.d.ts.map +1 -0
  145. package/dist/perf/benchmark.js +97 -0
  146. package/dist/perf/benchmark.js.map +1 -0
  147. package/dist/perf/index.d.ts +3 -0
  148. package/dist/perf/index.d.ts.map +1 -0
  149. package/dist/perf/index.js +6 -0
  150. package/dist/perf/index.js.map +1 -0
  151. package/dist/perf/latency.d.ts +39 -0
  152. package/dist/perf/latency.d.ts.map +1 -0
  153. package/dist/perf/latency.js +79 -0
  154. package/dist/perf/latency.js.map +1 -0
  155. package/dist/privacy.d.ts +45 -0
  156. package/dist/privacy.d.ts.map +1 -0
  157. package/dist/privacy.js +66 -0
  158. package/dist/privacy.js.map +1 -0
  159. package/dist/providers/indexeddb.d.ts +37 -0
  160. package/dist/providers/indexeddb.d.ts.map +1 -0
  161. package/dist/providers/indexeddb.js +45 -0
  162. package/dist/providers/indexeddb.js.map +1 -0
  163. package/dist/providers/webrtc.d.ts +40 -0
  164. package/dist/providers/webrtc.d.ts.map +1 -0
  165. package/dist/providers/webrtc.js +81 -0
  166. package/dist/providers/webrtc.js.map +1 -0
  167. package/dist/providers/websocket.d.ts +45 -0
  168. package/dist/providers/websocket.d.ts.map +1 -0
  169. package/dist/providers/websocket.js +56 -0
  170. package/dist/providers/websocket.js.map +1 -0
  171. package/dist/security/e2e.d.ts +54 -0
  172. package/dist/security/e2e.d.ts.map +1 -0
  173. package/dist/security/e2e.js +147 -0
  174. package/dist/security/e2e.js.map +1 -0
  175. package/dist/security/index.d.ts +2 -0
  176. package/dist/security/index.d.ts.map +1 -0
  177. package/dist/security/index.js +5 -0
  178. package/dist/security/index.js.map +1 -0
  179. package/dist/session.d.ts +79 -0
  180. package/dist/session.d.ts.map +1 -0
  181. package/dist/session.js +112 -0
  182. package/dist/session.js.map +1 -0
  183. package/dist/snapshot/from-ifcx.d.ts +24 -0
  184. package/dist/snapshot/from-ifcx.d.ts.map +1 -0
  185. package/dist/snapshot/from-ifcx.js +93 -0
  186. package/dist/snapshot/from-ifcx.js.map +1 -0
  187. package/dist/snapshot/index.d.ts +6 -0
  188. package/dist/snapshot/index.d.ts.map +1 -0
  189. package/dist/snapshot/index.js +9 -0
  190. package/dist/snapshot/index.js.map +1 -0
  191. package/dist/snapshot/layers.d.ts +56 -0
  192. package/dist/snapshot/layers.d.ts.map +1 -0
  193. package/dist/snapshot/layers.js +82 -0
  194. package/dist/snapshot/layers.js.map +1 -0
  195. package/dist/snapshot/minimal-layer.d.ts +40 -0
  196. package/dist/snapshot/minimal-layer.d.ts.map +1 -0
  197. package/dist/snapshot/minimal-layer.js +123 -0
  198. package/dist/snapshot/minimal-layer.js.map +1 -0
  199. package/dist/snapshot/to-ifcx.d.ts +26 -0
  200. package/dist/snapshot/to-ifcx.d.ts.map +1 -0
  201. package/dist/snapshot/to-ifcx.js +54 -0
  202. package/dist/snapshot/to-ifcx.js.map +1 -0
  203. package/dist/snapshot/worker.d.ts +45 -0
  204. package/dist/snapshot/worker.d.ts.map +1 -0
  205. package/dist/snapshot/worker.js +73 -0
  206. package/dist/snapshot/worker.js.map +1 -0
  207. package/dist/sync/room.d.ts +15 -0
  208. package/dist/sync/room.d.ts.map +1 -0
  209. package/dist/sync/room.js +20 -0
  210. package/dist/sync/room.js.map +1 -0
  211. package/dist/undo.d.ts +25 -0
  212. package/dist/undo.d.ts.map +1 -0
  213. package/dist/undo.js +37 -0
  214. package/dist/undo.js.map +1 -0
  215. package/dist/viewer-bridge.d.ts +27 -0
  216. package/dist/viewer-bridge.d.ts.map +1 -0
  217. package/dist/viewer-bridge.js +82 -0
  218. package/dist/viewer-bridge.js.map +1 -0
  219. package/package.json +83 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branch-tree.js","sourceRoot":"","sources":["../../src/branch/branch-tree.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { type CollabSession, type CollabSessionOptions } from '../session.js';
2
+ export interface ForkOptions {
3
+ /** New room id for the branch. Defaults to `<parent.roomId>/branches/<name>`. */
4
+ roomId?: string;
5
+ /** Branch name; stored in branch's meta for UI. */
6
+ name: string;
7
+ /** Override the user identity on the branch session. Defaults to parent's. */
8
+ user?: CollabSessionOptions['user'];
9
+ /** Provider for the branch (default: parent's provider). */
10
+ provider?: CollabSessionOptions['provider'];
11
+ /** Forwarded to the new session. */
12
+ serverUrl?: CollabSessionOptions['serverUrl'];
13
+ token?: CollabSessionOptions['token'];
14
+ WebSocketPolyfill?: CollabSessionOptions['WebSocketPolyfill'];
15
+ }
16
+ export interface BranchSession {
17
+ readonly session: CollabSession;
18
+ readonly parentRoomId: string;
19
+ readonly branchName: string;
20
+ }
21
+ export declare function forkSession(parent: CollabSession, opts: ForkOptions): Promise<BranchSession>;
22
+ export type MergeStrategy = 'ops' | 'layer';
23
+ export interface MergeReport {
24
+ strategy: MergeStrategy;
25
+ /** Bytes of the merged update payload. */
26
+ bytes: number;
27
+ /** ISO timestamp of when the merge transaction landed on `parent`. */
28
+ mergedAt: string;
29
+ }
30
+ /**
31
+ * Merge `branch` back into `parent`. Returns a small report.
32
+ *
33
+ * The branch session is NOT disposed by this call — the caller decides
34
+ * whether to keep it around (e.g. for diff inspection) or `dispose()`
35
+ * it after merge.
36
+ */
37
+ export declare function mergeBranch(parent: CollabSession, branch: BranchSession, strategy?: MergeStrategy): MergeReport;
38
+ /** Read branch metadata back off a session's Y.Doc. */
39
+ export declare function readBranchMeta(session: CollabSession): {
40
+ parentRoomId?: string;
41
+ branchName?: string;
42
+ forkedAt?: string;
43
+ };
44
+ //# sourceMappingURL=branch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branch.d.ts","sourceRoot":"","sources":["../../src/branch/branch.ts"],"names":[],"mappings":"AA6BA,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,oBAAoB,EAC1B,MAAM,eAAe,CAAC;AAKvB,MAAM,WAAW,WAAW;IAC1B,iFAAiF;IACjF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,IAAI,CAAC,EAAE,oBAAoB,CAAC,MAAM,CAAC,CAAC;IACpC,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,oBAAoB,CAAC,UAAU,CAAC,CAAC;IAC5C,oCAAoC;IACpC,SAAS,CAAC,EAAE,oBAAoB,CAAC,WAAW,CAAC,CAAC;IAC9C,KAAK,CAAC,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC;IACtC,iBAAiB,CAAC,EAAE,oBAAoB,CAAC,mBAAmB,CAAC,CAAC;CAC/D;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAMD,wBAAsB,WAAW,CAC/B,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC,aAAa,CAAC,CAiCxB;AAED,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,OAAO,CAAC;AAE5C,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,aAAa,CAAC;IACxB,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,aAAa,EACrB,QAAQ,GAAE,aAAqB,GAC9B,WAAW,CA2Bb;AAED,uDAAuD;AACvD,wBAAgB,cAAc,CAC5B,OAAO,EAAE,aAAa,GACrB;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAOnE"}
@@ -0,0 +1,109 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ /**
5
+ * Branching (spec §12.4 — v0.7 starter).
6
+ *
7
+ * `forkSession(parent, opts)` — snapshot the parent Y.Doc, seed a new
8
+ * Y.Doc with the snapshot, and wrap it as a fresh `CollabSession`. The
9
+ * branch carries `meta.parentRoomId` + `meta.branchName` for round-trip
10
+ * tooling.
11
+ *
12
+ * `mergeBranch(parent, branch, strategy)` — bring the branch's edits
13
+ * back. Two strategies ship in v0.7:
14
+ * - `'ops'` : encode the branch's full state as a Y update and
15
+ * `applyUpdate` it into the parent. Works for any pair
16
+ * of CRDT docs; concurrent parent edits LWW-merge with
17
+ * the branch's edits per Yjs semantics.
18
+ * - `'layer'` : extract the branch contents as an IFCX layer and
19
+ * re-seed the parent with parent + branch composed.
20
+ * Useful when the branch was edited by tools that only
21
+ * speak IFCX, not the live Y.Doc.
22
+ *
23
+ * The proper differential layer composer lands later in v0.7 — for now
24
+ * `'layer'` produces a snapshot-of-branch layer, which is the same
25
+ * trade-off documented in `snapshot/layers.ts`.
26
+ */
27
+ import * as Y from 'yjs';
28
+ import { createCollabSession, } from '../session.js';
29
+ import { metaMap } from '../doc/schema.js';
30
+ import { snapshotToIfcx } from '../snapshot/to-ifcx.js';
31
+ import { seedFromIfcx } from '../snapshot/from-ifcx.js';
32
+ const META_PARENT = 'branch.parentRoomId';
33
+ const META_NAME = 'branch.name';
34
+ const META_FORKED_AT = 'branch.forkedAt';
35
+ export async function forkSession(parent, opts) {
36
+ // 1. Snapshot the parent Y.Doc as a binary update.
37
+ const update = Y.encodeStateAsUpdate(parent.doc);
38
+ // 2. Build the branch session.
39
+ const branchRoomId = opts.roomId ?? `${parent.roomId}/branches/${opts.name}`;
40
+ const branchUser = opts.user ?? parent.presence.getSelf()?.user ?? {
41
+ id: 'forker',
42
+ name: 'forker',
43
+ };
44
+ const branch = await createCollabSession({
45
+ roomId: branchRoomId,
46
+ user: branchUser,
47
+ provider: opts.provider ?? parent.provider,
48
+ serverUrl: opts.serverUrl,
49
+ token: opts.token,
50
+ WebSocketPolyfill: opts.WebSocketPolyfill,
51
+ });
52
+ // 3. Seed the branch doc with the parent state, then stamp branch metadata.
53
+ Y.applyUpdate(branch.doc, update, { source: 'fork', parentRoomId: parent.roomId });
54
+ branch.transact(() => {
55
+ const meta = metaMap(branch.doc);
56
+ meta.set(META_PARENT, parent.roomId);
57
+ meta.set(META_NAME, opts.name);
58
+ meta.set(META_FORKED_AT, new Date().toISOString());
59
+ });
60
+ return {
61
+ session: branch,
62
+ parentRoomId: parent.roomId,
63
+ branchName: opts.name,
64
+ };
65
+ }
66
+ /**
67
+ * Merge `branch` back into `parent`. Returns a small report.
68
+ *
69
+ * The branch session is NOT disposed by this call — the caller decides
70
+ * whether to keep it around (e.g. for diff inspection) or `dispose()`
71
+ * it after merge.
72
+ */
73
+ export function mergeBranch(parent, branch, strategy = 'ops') {
74
+ if (strategy === 'ops') {
75
+ const update = Y.encodeStateAsUpdate(branch.session.doc);
76
+ Y.applyUpdate(parent.doc, update, {
77
+ source: 'merge-branch',
78
+ branchName: branch.branchName,
79
+ });
80
+ return {
81
+ strategy,
82
+ bytes: update.byteLength,
83
+ mergedAt: new Date().toISOString(),
84
+ };
85
+ }
86
+ // 'layer' strategy: snapshot the branch as IFCX, then re-seed the
87
+ // parent with reset:false so existing parent state is preserved and
88
+ // branch nodes overlay (composition is left to the caller's IFCX
89
+ // layer stack — for now we fall back to "set everything we have").
90
+ const ifcx = snapshotToIfcx(branch.session.doc);
91
+ const before = Y.encodeStateAsUpdate(parent.doc);
92
+ seedFromIfcx(parent.doc, ifcx, { reset: false });
93
+ const after = Y.encodeStateAsUpdate(parent.doc);
94
+ return {
95
+ strategy,
96
+ bytes: Math.max(0, after.byteLength - before.byteLength),
97
+ mergedAt: new Date().toISOString(),
98
+ };
99
+ }
100
+ /** Read branch metadata back off a session's Y.Doc. */
101
+ export function readBranchMeta(session) {
102
+ const meta = metaMap(session.doc);
103
+ return {
104
+ parentRoomId: meta.get(META_PARENT),
105
+ branchName: meta.get(META_NAME),
106
+ forkedAt: meta.get(META_FORKED_AT),
107
+ };
108
+ }
109
+ //# sourceMappingURL=branch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branch.js","sourceRoot":"","sources":["../../src/branch/branch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import type { IfcxFile } from '@ifc-lite/ifcx';
2
+ import type { BranchInfo, HistoryDiff, HistoryEntry, HistorySidecar } from './history.js';
3
+ export interface AutomergeHistorySidecarOptions {
4
+ /** Restore from a previously-saved binary doc. */
5
+ serialised?: Uint8Array;
6
+ }
7
+ export declare class AutomergeHistorySidecar implements HistorySidecar {
8
+ private doc;
9
+ private counter;
10
+ constructor(opts?: AutomergeHistorySidecarOptions);
11
+ /** Serialise the entire history doc. Use to persist across restarts. */
12
+ save(): Uint8Array;
13
+ /** Replace the internal doc. Used by tests + restore flows. */
14
+ load(serialised: Uint8Array): void;
15
+ private nextEntryId;
16
+ record(input: {
17
+ branch?: string;
18
+ label?: string;
19
+ snapshot: IfcxFile;
20
+ diff?: IfcxFile;
21
+ authorClientId?: number;
22
+ }): Promise<HistoryEntry>;
23
+ entries(branch?: string): Promise<HistoryEntry[]>;
24
+ at(at: Date | string, branch?: string): Promise<HistoryEntry | null>;
25
+ diff(fromEntryId: string, toEntryId: string): Promise<HistoryDiff>;
26
+ branches(): Promise<BranchInfo[]>;
27
+ branch(name: string, fromEntryId?: string): Promise<BranchInfo>;
28
+ merge(branch: string, into: string, mergedSnapshot: IfcxFile): Promise<HistoryEntry>;
29
+ clear(): Promise<void>;
30
+ }
31
+ //# sourceMappingURL=history-automerge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history-automerge.d.ts","sourceRoot":"","sources":["../../src/branch/history-automerge.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,YAAY,EACZ,cAAc,EACf,MAAM,cAAc,CAAC;AA0BtB,MAAM,WAAW,8BAA8B;IAC7C,kDAAkD;IAClD,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED,qBAAa,uBAAwB,YAAW,cAAc;IAC5D,OAAO,CAAC,GAAG,CAAwB;IACnC,OAAO,CAAC,OAAO,CAAK;gBAER,IAAI,GAAE,8BAAmC;IAiBrD,wEAAwE;IACxE,IAAI,IAAI,UAAU;IAIlB,+DAA+D;IAC/D,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI;IAIlC,OAAO,CAAC,WAAW;IAKb,MAAM,CAAC,KAAK,EAAE;QAClB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,QAAQ,CAAC;QACnB,IAAI,CAAC,EAAE,QAAQ,CAAC;QAChB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,GAAG,OAAO,CAAC,YAAY,CAAC;IAgCnB,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAcjD,EAAE,CAAC,EAAE,EAAE,IAAI,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAWpE,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAoClE,QAAQ,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAOjC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IA2B/D,KAAK,CACT,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,cAAc,EAAE,QAAQ,GACvB,OAAO,CAAC,YAAY,CAAC;IAwClB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ7B"}
@@ -0,0 +1,237 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ /**
5
+ * Automerge-backed `HistorySidecar` (spec §4 + §12.4).
6
+ *
7
+ * Same interface as `MemoryHistorySidecar`, but every entry lives
8
+ * inside an Automerge document. That gives us:
9
+ * - first-class branching / merging at the storage layer
10
+ * - a binary `save()` representation we can persist
11
+ * - cheap time-travel via Automerge `view(heads)` and `getHistory()`
12
+ *
13
+ * The trade-off (per spec §4) is bundle size: Automerge is Rust+WASM.
14
+ * For deployments where that's unacceptable, `MemoryHistorySidecar`
15
+ * remains the default. Both satisfy `HistorySidecar`.
16
+ */
17
+ import * as A from '@automerge/automerge';
18
+ export class AutomergeHistorySidecar {
19
+ doc;
20
+ counter = 0;
21
+ constructor(opts = {}) {
22
+ if (opts.serialised && opts.serialised.byteLength > 0) {
23
+ this.doc = A.load(opts.serialised);
24
+ // Recompute counter so newly-recorded ids don't collide.
25
+ const ids = Object.keys(this.doc.entries ?? {});
26
+ this.counter = ids.length;
27
+ }
28
+ else {
29
+ this.doc = A.from({
30
+ entries: {},
31
+ branches: {
32
+ main: { name: 'main', createdAt: new Date().toISOString() },
33
+ },
34
+ byBranch: { main: [] },
35
+ });
36
+ }
37
+ }
38
+ /** Serialise the entire history doc. Use to persist across restarts. */
39
+ save() {
40
+ return A.save(this.doc);
41
+ }
42
+ /** Replace the internal doc. Used by tests + restore flows. */
43
+ load(serialised) {
44
+ this.doc = A.load(serialised);
45
+ }
46
+ nextEntryId() {
47
+ this.counter += 1;
48
+ return `e${this.counter}-${Date.now().toString(36)}`;
49
+ }
50
+ async record(input) {
51
+ const branch = input.branch ?? 'main';
52
+ const entryId = this.nextEntryId();
53
+ const at = new Date().toISOString();
54
+ const snapshotJson = JSON.stringify(input.snapshot);
55
+ const diffJson = input.diff ? JSON.stringify(input.diff) : undefined;
56
+ this.doc = A.change(this.doc, `record ${entryId}`, (d) => {
57
+ if (!d.branches[branch]) {
58
+ d.branches[branch] = { name: branch, createdAt: at };
59
+ d.byBranch[branch] = [];
60
+ }
61
+ // Automerge rejects `undefined` — only set defined fields.
62
+ const entry = { entryId, at, branch, snapshotJson };
63
+ if (input.authorClientId !== undefined)
64
+ entry.authorClientId = input.authorClientId;
65
+ if (input.label !== undefined)
66
+ entry.label = input.label;
67
+ if (diffJson !== undefined)
68
+ entry.diffJson = diffJson;
69
+ d.entries[entryId] = entry;
70
+ d.byBranch[branch].push(entryId);
71
+ });
72
+ return revive({
73
+ entryId,
74
+ at,
75
+ branch,
76
+ authorClientId: input.authorClientId,
77
+ label: input.label,
78
+ snapshotJson,
79
+ diffJson,
80
+ });
81
+ }
82
+ async entries(branch) {
83
+ const shape = this.doc;
84
+ if (branch) {
85
+ const ids = shape.byBranch[branch] ?? [];
86
+ return ids
87
+ .map((id) => shape.entries[id])
88
+ .filter((e) => Boolean(e))
89
+ .map(revive);
90
+ }
91
+ return Object.values(shape.entries)
92
+ .map(revive)
93
+ .sort((a, b) => a.at.localeCompare(b.at));
94
+ }
95
+ async at(at, branch) {
96
+ const target = at instanceof Date ? at.toISOString() : at;
97
+ const list = await this.entries(branch);
98
+ let best = null;
99
+ for (const e of list) {
100
+ if (e.at <= target)
101
+ best = e;
102
+ else
103
+ break;
104
+ }
105
+ return best;
106
+ }
107
+ async diff(fromEntryId, toEntryId) {
108
+ const shape = this.doc;
109
+ const from = shape.entries[fromEntryId];
110
+ const to = shape.entries[toEntryId];
111
+ if (!from || !to) {
112
+ return { from: fromEntryId, to: toEntryId, added: [], removed: [], changed: [] };
113
+ }
114
+ const fromIfcx = JSON.parse(from.snapshotJson);
115
+ const toIfcx = JSON.parse(to.snapshotJson);
116
+ const fromPaths = new Map();
117
+ const toPaths = new Map();
118
+ for (const n of fromIfcx.data ?? [])
119
+ fromPaths.set(n.path, n);
120
+ for (const n of toIfcx.data ?? [])
121
+ toPaths.set(n.path, n);
122
+ const added = [];
123
+ const removed = [];
124
+ const changed = [];
125
+ for (const path of toPaths.keys()) {
126
+ if (!fromPaths.has(path))
127
+ added.push(path);
128
+ else if (JSON.stringify(toPaths.get(path)) !== JSON.stringify(fromPaths.get(path))) {
129
+ changed.push(path);
130
+ }
131
+ }
132
+ for (const path of fromPaths.keys()) {
133
+ if (!toPaths.has(path))
134
+ removed.push(path);
135
+ }
136
+ return {
137
+ from: fromEntryId,
138
+ to: toEntryId,
139
+ added: added.sort(),
140
+ removed: removed.sort(),
141
+ changed: changed.sort(),
142
+ };
143
+ }
144
+ async branches() {
145
+ const shape = this.doc;
146
+ return Object.values(shape.branches).sort((a, b) => a.createdAt.localeCompare(b.createdAt));
147
+ }
148
+ async branch(name, fromEntryId) {
149
+ const shape = this.doc;
150
+ if (shape.branches[name]) {
151
+ throw new Error(`@ifc-lite/collab: branch "${name}" already exists`);
152
+ }
153
+ // Default fork point = current head of main when no explicit
154
+ // entry is supplied, matching `MemoryHistorySidecar` + the documented
155
+ // interface.
156
+ let resolvedFork = fromEntryId;
157
+ if (!resolvedFork) {
158
+ const mainIds = shape.byBranch.main ?? [];
159
+ resolvedFork = mainIds[mainIds.length - 1];
160
+ }
161
+ const info = {
162
+ name,
163
+ forkedFromEntryId: resolvedFork,
164
+ createdAt: new Date().toISOString(),
165
+ };
166
+ this.doc = A.change(this.doc, `branch ${name}`, (d) => {
167
+ const stored = { name, createdAt: info.createdAt };
168
+ if (resolvedFork !== undefined)
169
+ stored.forkedFromEntryId = resolvedFork;
170
+ d.branches[name] = stored;
171
+ d.byBranch[name] = [];
172
+ });
173
+ return info;
174
+ }
175
+ async merge(branch, into, mergedSnapshot) {
176
+ const shape = this.doc;
177
+ // Validate the source branch up front (matches MemoryHistorySidecar).
178
+ if (!shape.branches[branch]) {
179
+ throw new Error(`@ifc-lite/collab: source branch "${branch}" not found`);
180
+ }
181
+ if (!shape.branches[into]) {
182
+ throw new Error(`@ifc-lite/collab: target branch "${into}" not found`);
183
+ }
184
+ const sourceIds = shape.byBranch[branch] ?? [];
185
+ const sourceTipId = sourceIds[sourceIds.length - 1];
186
+ const entryId = this.nextEntryId();
187
+ const at = new Date().toISOString();
188
+ const snapshotJson = JSON.stringify(mergedSnapshot);
189
+ const label = `merge ${branch} → ${into}`;
190
+ this.doc = A.change(this.doc, `merge ${branch} → ${into}`, (d) => {
191
+ // Automerge rejects `undefined` — only set defined fields.
192
+ const entry = {
193
+ entryId,
194
+ at,
195
+ branch: into,
196
+ label,
197
+ snapshotJson,
198
+ mergedFromBranch: branch,
199
+ };
200
+ if (sourceTipId !== undefined)
201
+ entry.mergedFromEntryId = sourceTipId;
202
+ d.entries[entryId] = entry;
203
+ d.byBranch[into].push(entryId);
204
+ });
205
+ return revive({
206
+ entryId,
207
+ at,
208
+ branch: into,
209
+ label,
210
+ snapshotJson,
211
+ mergedFromBranch: branch,
212
+ mergedFromEntryId: sourceTipId,
213
+ });
214
+ }
215
+ async clear() {
216
+ this.doc = A.from({
217
+ entries: {},
218
+ branches: { main: { name: 'main', createdAt: new Date().toISOString() } },
219
+ byBranch: { main: [] },
220
+ });
221
+ this.counter = 0;
222
+ }
223
+ }
224
+ function revive(entry) {
225
+ return {
226
+ entryId: entry.entryId,
227
+ at: entry.at,
228
+ branch: entry.branch,
229
+ authorClientId: entry.authorClientId,
230
+ label: entry.label,
231
+ snapshot: JSON.parse(entry.snapshotJson),
232
+ diff: entry.diffJson ? JSON.parse(entry.diffJson) : undefined,
233
+ mergedFromBranch: entry.mergedFromBranch,
234
+ mergedFromEntryId: entry.mergedFromEntryId,
235
+ };
236
+ }
237
+ //# sourceMappingURL=history-automerge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history-automerge.js","sourceRoot":"","sources":["../../src/branch/history-automerge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,147 @@
1
+ /**
2
+ * History sidecar (spec §4 + §12.4).
3
+ *
4
+ * The Yjs runtime is optimized for live editing — it doesn't ship a
5
+ * first-class history / branch / time-travel UI. Per spec §4, we run an
6
+ * Automerge-shaped sidecar that records periodic snapshots of the live
7
+ * doc so apps can navigate `(branch, timestamp)` space.
8
+ *
9
+ * To avoid forcing every consumer to take the heavy `@automerge/automerge`
10
+ * Rust+WASM dep, this module ships:
11
+ *
12
+ * - `HistorySidecar` interface — `record(snapshot)`, `entries()`,
13
+ * `at(t)`, `diff(a, b)`, `branches()`, `branch(name, fromEntryId)`,
14
+ * `merge(branch, into)`.
15
+ * - `MemoryHistorySidecar` — keeps every snapshot + per-entry diff
16
+ * in RAM. Good for tests and short-lived sessions.
17
+ * - `IndexedDbHistorySidecar` — same shape, persisted to IDB.
18
+ * - `attachHistorySidecar(session, sidecar, opts)` — drives a sidecar
19
+ * from a `CollabSession` by snapshotting on a timer and on demand.
20
+ *
21
+ * A future `AutomergeHistorySidecar` (pending the heavy dep) will
22
+ * satisfy the same interface.
23
+ */
24
+ import type { IfcxFile } from '@ifc-lite/ifcx';
25
+ import type { CollabSession } from '../session.js';
26
+ import { type SnapshotOptions } from '../snapshot/to-ifcx.js';
27
+ export interface HistoryEntry {
28
+ /** Stable id (UUIDv4-like or timestamp-based). */
29
+ entryId: string;
30
+ /** ISO timestamp. */
31
+ at: string;
32
+ /** Branch this entry belongs to. */
33
+ branch: string;
34
+ /** clientID of the author at snapshot time, if known. */
35
+ authorClientId?: number;
36
+ /** Free-form label (commit-message-style). */
37
+ label?: string;
38
+ /** Composed IFCX snapshot — full state at this entry. */
39
+ snapshot: IfcxFile;
40
+ /** Optional minimal layer relative to the previous entry on this branch. */
41
+ diff?: IfcxFile;
42
+ /**
43
+ * Immutable merge metadata. Set ONLY by `merge()` — never by
44
+ * `record()`. UI layers (e.g. `branch-tree`) rely on these instead of
45
+ * parsing `label` so user-authored labels can't be misclassified as
46
+ * structural metadata, and so the merge edge always points at the
47
+ * commit that was actually merged (not the source branch's current tip).
48
+ */
49
+ mergedFromBranch?: string;
50
+ mergedFromEntryId?: string;
51
+ }
52
+ export interface HistoryDiff {
53
+ /** Entry IDs of `from` and `to`. */
54
+ from: string;
55
+ to: string;
56
+ /**
57
+ * Per-entity differences as observed by walking IFCX nodes:
58
+ * - `added` — entity exists in `to` but not in `from`
59
+ * - `removed` — entity exists in `from` but not in `to`
60
+ * - `changed` — both, with at least one attribute / child differing
61
+ */
62
+ added: string[];
63
+ removed: string[];
64
+ changed: string[];
65
+ }
66
+ export interface BranchInfo {
67
+ name: string;
68
+ /** entryId on the parent branch where this branch forked. */
69
+ forkedFromEntryId?: string;
70
+ /** Wall-clock time of branch creation. */
71
+ createdAt: string;
72
+ }
73
+ export interface HistorySidecar {
74
+ /** Append a new entry to a branch (default `'main'`). */
75
+ record(input: {
76
+ branch?: string;
77
+ label?: string;
78
+ snapshot: IfcxFile;
79
+ diff?: IfcxFile;
80
+ authorClientId?: number;
81
+ }): Promise<HistoryEntry>;
82
+ /** All entries, oldest first, optionally filtered to one branch. */
83
+ entries(branch?: string): Promise<HistoryEntry[]>;
84
+ /** The entry whose `at` is closest to (and not after) `at`. */
85
+ at(at: Date | string, branch?: string): Promise<HistoryEntry | null>;
86
+ /** Per-entity-id diff between two entries. */
87
+ diff(fromEntryId: string, toEntryId: string): Promise<HistoryDiff>;
88
+ /** All known branches, in creation order. */
89
+ branches(): Promise<BranchInfo[]>;
90
+ /** Create a new branch off `fromEntryId` (defaults to head of `main`). */
91
+ branch(name: string, fromEntryId?: string): Promise<BranchInfo>;
92
+ /**
93
+ * Merge `branch` into `into`. Returns a synthetic merge entry — apps
94
+ * compute the merged snapshot themselves (typically by replaying
95
+ * Y-update logs through `mergeBranch`).
96
+ */
97
+ merge(branch: string, into: string, mergedSnapshot: IfcxFile): Promise<HistoryEntry>;
98
+ /** Remove all entries / branches. */
99
+ clear(): Promise<void>;
100
+ }
101
+ export declare class MemoryHistorySidecar implements HistorySidecar {
102
+ private readonly entriesByBranch;
103
+ private readonly branchInfo;
104
+ private counter;
105
+ constructor();
106
+ private nextEntryId;
107
+ record(input: {
108
+ branch?: string;
109
+ label?: string;
110
+ snapshot: IfcxFile;
111
+ diff?: IfcxFile;
112
+ authorClientId?: number;
113
+ }): Promise<HistoryEntry>;
114
+ entries(branch?: string): Promise<HistoryEntry[]>;
115
+ at(at: Date | string, branch?: string): Promise<HistoryEntry | null>;
116
+ diff(fromEntryId: string, toEntryId: string): Promise<HistoryDiff>;
117
+ branches(): Promise<BranchInfo[]>;
118
+ branch(name: string, fromEntryId?: string): Promise<BranchInfo>;
119
+ merge(branch: string, into: string, mergedSnapshot: IfcxFile): Promise<HistoryEntry>;
120
+ clear(): Promise<void>;
121
+ }
122
+ export interface AttachHistoryOptions {
123
+ /** How often to record a snapshot, ms. Default 60_000. */
124
+ intervalMs?: number;
125
+ /** Branch to record on. Default 'main'. */
126
+ branch?: string;
127
+ /** Forwarded to `snapshotToIfcx`. */
128
+ snapshot?: SnapshotOptions;
129
+ /**
130
+ * If true (default), include a minimal-layer diff against the
131
+ * previous entry on the same branch. Diffs make `historySidecar.diff(a, b)`
132
+ * cheaper to compute.
133
+ */
134
+ includeDiff?: boolean;
135
+ }
136
+ export interface HistoryDriver {
137
+ /** Force a snapshot now. */
138
+ capture(label?: string): Promise<HistoryEntry>;
139
+ /** Stop the timer. */
140
+ detach(): void;
141
+ }
142
+ /**
143
+ * Drive a `HistorySidecar` from a live `CollabSession`. Records a
144
+ * snapshot every `intervalMs`, plus on-demand via `capture(label)`.
145
+ */
146
+ export declare function attachHistorySidecar(session: CollabSession, sidecar: HistorySidecar, options?: AttachHistoryOptions): HistoryDriver;
147
+ //# sourceMappingURL=history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/branch/history.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAkB,KAAK,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAI9E,MAAM,WAAW,YAAY;IAC3B,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,qBAAqB;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,QAAQ,EAAE,QAAQ,CAAC;IACnB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX;;;;;OAKG;IACH,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,yDAAyD;IACzD,MAAM,CAAC,KAAK,EAAE;QACZ,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,QAAQ,CAAC;QACnB,IAAI,CAAC,EAAE,QAAQ,CAAC;QAChB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC1B,oEAAoE;IACpE,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAClD,+DAA+D;IAC/D,EAAE,CAAC,EAAE,EAAE,IAAI,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IACrE,8CAA8C;IAC9C,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACnE,6CAA6C;IAC7C,QAAQ,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAClC,0EAA0E;IAC1E,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAChE;;;;OAIG;IACH,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IACrF,qCAAqC;IACrC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAmBD,qBAAa,oBAAqB,YAAW,cAAc;IACzD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqC;IACrE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAiC;IAC5D,OAAO,CAAC,OAAO,CAAK;;IAUpB,OAAO,CAAC,WAAW;IAKb,MAAM,CAAC,KAAK,EAAE;QAClB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,QAAQ,CAAC;QACnB,IAAI,CAAC,EAAE,QAAQ,CAAC;QAChB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,GAAG,OAAO,CAAC,YAAY,CAAC;IAuBnB,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAOjD,EAAE,CAAC,EAAE,EAAE,IAAI,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAWpE,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAiClE,QAAQ,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAMjC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAwB/D,KAAK,CACT,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,cAAc,EAAE,QAAQ,GACvB,OAAO,CAAC,YAAY,CAAC;IA8BlB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAO7B;AAMD,MAAM,WAAW,oBAAoB;IACnC,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2CAA2C;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,4BAA4B;IAC5B,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/C,sBAAsB;IACtB,MAAM,IAAI,IAAI,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,cAAc,EACvB,OAAO,GAAE,oBAAyB,GACjC,aAAa,CA6Cf"}