@evolu/common 7.4.0 → 8.0.0-next.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 (251) hide show
  1. package/README.md +4 -61
  2. package/dist/src/Array.d.ts +343 -102
  3. package/dist/src/Array.d.ts.map +1 -1
  4. package/dist/src/Array.js +181 -85
  5. package/dist/src/Assert.d.ts +57 -11
  6. package/dist/src/Assert.d.ts.map +1 -1
  7. package/dist/src/Assert.js +47 -11
  8. package/dist/src/BigInt.d.ts +6 -1
  9. package/dist/src/BigInt.d.ts.map +1 -1
  10. package/dist/src/BigInt.js +5 -0
  11. package/dist/src/Brand.d.ts +40 -12
  12. package/dist/src/Brand.d.ts.map +1 -1
  13. package/dist/src/Brand.js +5 -0
  14. package/dist/src/Buffer.d.ts +6 -1
  15. package/dist/src/Buffer.d.ts.map +1 -1
  16. package/dist/src/Buffer.js +7 -2
  17. package/dist/src/Cache.d.ts +10 -2
  18. package/dist/src/Cache.d.ts.map +1 -1
  19. package/dist/src/Cache.js +6 -0
  20. package/dist/src/Callbacks.d.ts +10 -7
  21. package/dist/src/Callbacks.d.ts.map +1 -1
  22. package/dist/src/Callbacks.js +23 -13
  23. package/dist/src/Console.d.ts +361 -69
  24. package/dist/src/Console.d.ts.map +1 -1
  25. package/dist/src/Console.js +217 -117
  26. package/dist/src/Crypto.d.ts +70 -21
  27. package/dist/src/Crypto.d.ts.map +1 -1
  28. package/dist/src/Crypto.js +72 -27
  29. package/dist/src/Eq.d.ts +22 -2
  30. package/dist/src/Eq.d.ts.map +1 -1
  31. package/dist/src/Eq.js +21 -1
  32. package/dist/src/Error.d.ts +23 -12
  33. package/dist/src/Error.d.ts.map +1 -1
  34. package/dist/src/Error.js +27 -11
  35. package/dist/src/Function.d.ts +128 -56
  36. package/dist/src/Function.d.ts.map +1 -1
  37. package/dist/src/Function.js +118 -14
  38. package/dist/src/Identicon.d.ts +5 -0
  39. package/dist/src/Identicon.d.ts.map +1 -1
  40. package/dist/src/Identicon.js +6 -1
  41. package/dist/src/Lookup.d.ts +160 -0
  42. package/dist/src/Lookup.d.ts.map +1 -0
  43. package/dist/src/Lookup.js +192 -0
  44. package/dist/src/Microtask.d.ts +21 -0
  45. package/dist/src/Microtask.d.ts.map +1 -0
  46. package/dist/src/Microtask.js +37 -0
  47. package/dist/src/Number.d.ts +18 -4
  48. package/dist/src/Number.d.ts.map +1 -1
  49. package/dist/src/Number.js +23 -1
  50. package/dist/src/Object.d.ts +110 -5
  51. package/dist/src/Object.d.ts.map +1 -1
  52. package/dist/src/Object.js +108 -5
  53. package/dist/src/Option.d.ts +58 -0
  54. package/dist/src/Option.d.ts.map +1 -0
  55. package/dist/src/Option.js +43 -0
  56. package/dist/src/Order.d.ts +5 -0
  57. package/dist/src/Order.d.ts.map +1 -1
  58. package/dist/src/Order.js +8 -3
  59. package/dist/src/Platform.d.ts +36 -2
  60. package/dist/src/Platform.d.ts.map +1 -1
  61. package/dist/src/Platform.js +10 -6
  62. package/dist/src/Polyfills.d.ts +27 -0
  63. package/dist/src/Polyfills.d.ts.map +1 -0
  64. package/dist/src/Polyfills.js +299 -0
  65. package/dist/src/Random.d.ts +18 -7
  66. package/dist/src/Random.d.ts.map +1 -1
  67. package/dist/src/Random.js +9 -7
  68. package/dist/src/Redacted.d.ts +7 -4
  69. package/dist/src/Redacted.d.ts.map +1 -1
  70. package/dist/src/Redacted.js +5 -0
  71. package/dist/src/Ref.d.ts +31 -16
  72. package/dist/src/Ref.d.ts.map +1 -1
  73. package/dist/src/Ref.js +35 -7
  74. package/dist/src/RefCount.d.ts +62 -0
  75. package/dist/src/RefCount.d.ts.map +1 -0
  76. package/dist/src/RefCount.js +83 -0
  77. package/dist/src/Relation.d.ts +84 -29
  78. package/dist/src/Relation.d.ts.map +1 -1
  79. package/dist/src/Relation.js +83 -105
  80. package/dist/src/Resource.d.ts +263 -0
  81. package/dist/src/Resource.d.ts.map +1 -0
  82. package/dist/src/Resource.js +389 -0
  83. package/dist/src/Result.d.ts +390 -374
  84. package/dist/src/Result.d.ts.map +1 -1
  85. package/dist/src/Result.js +142 -70
  86. package/dist/src/Schedule.d.ts +953 -0
  87. package/dist/src/Schedule.d.ts.map +1 -0
  88. package/dist/src/Schedule.js +1199 -0
  89. package/dist/src/Set.d.ts +181 -0
  90. package/dist/src/Set.d.ts.map +1 -0
  91. package/dist/src/Set.js +137 -0
  92. package/dist/src/Skiplist.d.ts +6 -1
  93. package/dist/src/Skiplist.d.ts.map +1 -1
  94. package/dist/src/Skiplist.js +5 -0
  95. package/dist/src/Sqlite.d.ts +160 -60
  96. package/dist/src/Sqlite.d.ts.map +1 -1
  97. package/dist/src/Sqlite.js +290 -190
  98. package/dist/src/Store.d.ts +36 -28
  99. package/dist/src/Store.d.ts.map +1 -1
  100. package/dist/src/Store.js +55 -15
  101. package/dist/src/String.d.ts +5 -0
  102. package/dist/src/String.d.ts.map +1 -1
  103. package/dist/src/String.js +5 -0
  104. package/dist/src/Task.d.ts +2263 -423
  105. package/dist/src/Task.d.ts.map +1 -1
  106. package/dist/src/Task.js +1488 -348
  107. package/dist/src/Test.d.ts +122 -0
  108. package/dist/src/Test.d.ts.map +1 -0
  109. package/dist/src/Test.js +66 -0
  110. package/dist/src/Time.d.ts +201 -48
  111. package/dist/src/Time.d.ts.map +1 -1
  112. package/dist/src/Time.js +190 -86
  113. package/dist/src/Tracer.d.ts +48 -0
  114. package/dist/src/Tracer.d.ts.map +1 -0
  115. package/dist/src/Tracer.js +6 -0
  116. package/dist/src/Type.d.ts +582 -209
  117. package/dist/src/Type.d.ts.map +1 -1
  118. package/dist/src/Type.js +362 -240
  119. package/dist/src/Types.d.ts +160 -6
  120. package/dist/src/Types.d.ts.map +1 -1
  121. package/dist/src/Types.js +22 -2
  122. package/dist/src/WebSocket.d.ts +113 -58
  123. package/dist/src/WebSocket.d.ts.map +1 -1
  124. package/dist/src/WebSocket.js +210 -118
  125. package/dist/src/Worker.d.ts +245 -60
  126. package/dist/src/Worker.d.ts.map +1 -1
  127. package/dist/src/Worker.js +220 -64
  128. package/dist/src/index.d.ts +25 -3
  129. package/dist/src/index.d.ts.map +1 -1
  130. package/dist/src/index.js +19 -3
  131. package/dist/src/local-first/Db.d.ts +24 -213
  132. package/dist/src/local-first/Db.d.ts.map +1 -1
  133. package/dist/src/local-first/Db.js +622 -293
  134. package/dist/src/local-first/Error.d.ts +12 -0
  135. package/dist/src/local-first/Error.d.ts.map +1 -0
  136. package/dist/src/local-first/Error.js +6 -0
  137. package/dist/src/local-first/Evolu.d.ts +330 -285
  138. package/dist/src/local-first/Evolu.d.ts.map +1 -1
  139. package/dist/src/local-first/Evolu.js +472 -402
  140. package/dist/src/local-first/LocalAuth.d.ts +10 -10
  141. package/dist/src/local-first/LocalAuth.d.ts.map +1 -1
  142. package/dist/src/local-first/LocalAuth.js +6 -1
  143. package/dist/src/local-first/Owner.d.ts +70 -27
  144. package/dist/src/local-first/Owner.d.ts.map +1 -1
  145. package/dist/src/local-first/Owner.js +27 -14
  146. package/dist/src/local-first/Protocol.d.ts +58 -50
  147. package/dist/src/local-first/Protocol.d.ts.map +1 -1
  148. package/dist/src/local-first/Protocol.js +253 -155
  149. package/dist/src/local-first/Query.d.ts +133 -43
  150. package/dist/src/local-first/Query.d.ts.map +1 -1
  151. package/dist/src/local-first/Query.js +139 -90
  152. package/dist/src/local-first/Relay.d.ts +18 -38
  153. package/dist/src/local-first/Relay.d.ts.map +1 -1
  154. package/dist/src/local-first/Relay.js +59 -171
  155. package/dist/src/local-first/Schema.d.ts +139 -144
  156. package/dist/src/local-first/Schema.d.ts.map +1 -1
  157. package/dist/src/local-first/Schema.js +78 -163
  158. package/dist/src/local-first/Shared.d.ts +125 -0
  159. package/dist/src/local-first/Shared.d.ts.map +1 -0
  160. package/dist/src/local-first/Shared.js +569 -0
  161. package/dist/src/local-first/Storage.d.ts +50 -53
  162. package/dist/src/local-first/Storage.d.ts.map +1 -1
  163. package/dist/src/local-first/Storage.js +121 -173
  164. package/dist/src/local-first/Timestamp.d.ts +28 -35
  165. package/dist/src/local-first/Timestamp.d.ts.map +1 -1
  166. package/dist/src/local-first/Timestamp.js +24 -25
  167. package/dist/src/local-first/index.d.ts +2 -15
  168. package/dist/src/local-first/index.d.ts.map +1 -1
  169. package/dist/src/local-first/index.js +2 -15
  170. package/package.json +36 -26
  171. package/src/Array.ts +467 -106
  172. package/src/Assert.ts +87 -12
  173. package/src/BigInt.ts +7 -1
  174. package/src/Brand.ts +41 -12
  175. package/src/Buffer.ts +10 -4
  176. package/src/Cache.ts +11 -2
  177. package/src/Callbacks.ts +33 -23
  178. package/src/Console.ts +567 -178
  179. package/src/Crypto.ts +111 -62
  180. package/src/Eq.ts +30 -3
  181. package/src/Error.ts +50 -34
  182. package/src/Function.ts +140 -68
  183. package/src/Identicon.ts +7 -1
  184. package/src/Lookup.ts +415 -0
  185. package/src/Microtask.ts +58 -0
  186. package/src/Number.ts +40 -7
  187. package/src/Object.ts +155 -16
  188. package/src/Option.ts +74 -0
  189. package/src/Order.ts +11 -3
  190. package/src/Platform.ts +43 -7
  191. package/src/Polyfills.ts +465 -0
  192. package/src/Random.ts +25 -11
  193. package/src/Redacted.ts +8 -4
  194. package/src/Ref.ts +72 -21
  195. package/src/RefCount.ts +170 -0
  196. package/src/Relation.ts +188 -136
  197. package/src/Resource.ts +864 -0
  198. package/src/Result.ts +548 -381
  199. package/src/Schedule.ts +1471 -0
  200. package/src/Set.ts +247 -0
  201. package/src/Skiplist.ts +7 -1
  202. package/src/Sqlite.ts +409 -304
  203. package/src/Store.ts +94 -48
  204. package/src/String.ts +6 -0
  205. package/src/Task.ts +3685 -740
  206. package/src/Test.ts +162 -0
  207. package/src/Time.ts +348 -145
  208. package/src/Tracer.ts +54 -0
  209. package/src/Type.ts +1064 -630
  210. package/src/Types.ts +202 -7
  211. package/src/WebSocket.ts +311 -178
  212. package/src/Worker.ts +527 -147
  213. package/src/index.ts +74 -3
  214. package/src/local-first/Db.ts +871 -597
  215. package/src/local-first/Error.ts +17 -0
  216. package/src/local-first/Evolu.ts +884 -823
  217. package/src/local-first/LocalAuth.ts +10 -10
  218. package/src/local-first/Owner.ts +94 -42
  219. package/src/local-first/Protocol.ts +440 -303
  220. package/src/local-first/Query.ts +243 -194
  221. package/src/local-first/Relay.ts +91 -252
  222. package/src/local-first/Schema.ts +284 -394
  223. package/src/local-first/Shared.ts +932 -0
  224. package/src/local-first/Storage.ts +209 -282
  225. package/src/local-first/Timestamp.ts +38 -45
  226. package/src/local-first/index.ts +2 -16
  227. package/LICENSE +0 -21
  228. package/dist/src/Instances.d.ts +0 -34
  229. package/dist/src/Instances.d.ts.map +0 -1
  230. package/dist/src/Instances.js +0 -44
  231. package/dist/src/Resources.d.ts +0 -118
  232. package/dist/src/Resources.d.ts.map +0 -1
  233. package/dist/src/Resources.js +0 -197
  234. package/dist/src/local-first/Platform.d.ts +0 -25
  235. package/dist/src/local-first/Platform.d.ts.map +0 -1
  236. package/dist/src/local-first/Platform.js +0 -1
  237. package/dist/src/local-first/Public.d.ts +0 -22
  238. package/dist/src/local-first/Public.d.ts.map +0 -1
  239. package/dist/src/local-first/Public.js +0 -15
  240. package/dist/src/local-first/PublicKysely.d.ts +0 -148
  241. package/dist/src/local-first/PublicKysely.d.ts.map +0 -1
  242. package/dist/src/local-first/PublicKysely.js +0 -184
  243. package/dist/src/local-first/Sync.d.ts +0 -112
  244. package/dist/src/local-first/Sync.d.ts.map +0 -1
  245. package/dist/src/local-first/Sync.js +0 -529
  246. package/src/Instances.ts +0 -90
  247. package/src/Resources.ts +0 -367
  248. package/src/local-first/Platform.ts +0 -27
  249. package/src/local-first/Public.ts +0 -42
  250. package/src/local-first/PublicKysely.ts +0 -239
  251. package/src/local-first/Sync.ts +0 -960
@@ -1,16 +1,18 @@
1
+ /**
2
+ * Function utilities including exhaustive checks and composition.
3
+ *
4
+ * @module
5
+ */
1
6
  /**
2
7
  * Helper function to ensure exhaustive matching in a switch statement. Throws
3
8
  * an error if an unhandled case is encountered.
4
9
  *
5
- * Remember, it's useful only when we don't return anything from the switch
6
- * statement. Otherwise, a return type of a function is enough.
7
- *
8
10
  * ### Example
9
11
  *
10
12
  * ```ts
11
13
  * type Color = "red" | "green" | "blue";
12
14
  *
13
- * function handleColor(color: Color): void {
15
+ * const handleColor = (color: Color): void => {
14
16
  * switch (color) {
15
17
  * case "red":
16
18
  * console.log("Handling red");
@@ -24,14 +26,70 @@
24
26
  * default:
25
27
  * exhaustiveCheck(color); // Ensures all cases are handled
26
28
  * }
27
- * }
29
+ * };
30
+ * ```
31
+ *
32
+ * Use this primarily in side-effect switches (`void` branches). For
33
+ * value-producing switches, TypeScript can enforce exhaustiveness without a
34
+ * `default` branch.
35
+ *
36
+ * ### Example
37
+ *
38
+ * Return from each case for value-producing switches.
39
+ *
40
+ * ```ts
41
+ * type Color = "red" | "green" | "blue";
42
+ *
43
+ * const colorToHex = (color: Color): string => {
44
+ * switch (color) {
45
+ * case "red":
46
+ * return "#ff0000";
47
+ * case "green":
48
+ * return "#00ff00";
49
+ * case "blue":
50
+ * return "#0000ff";
51
+ * }
52
+ * };
53
+ * ```
54
+ *
55
+ * ### Example
56
+ *
57
+ * Use assignment + no `default` to get exhaustiveness by definite assignment.
58
+ *
59
+ * ```ts
60
+ * type Input =
61
+ * | { readonly type: "Mutate" }
62
+ * | { readonly type: "Query" }
63
+ * | { readonly type: "Export" };
64
+ *
65
+ * const onInput = (input: Input): void => {
66
+ * let result: "A" | "B" | "C";
67
+ *
68
+ * switch (input.type) {
69
+ * case "Mutate":
70
+ * result = "A";
71
+ * break;
72
+ * case "Query":
73
+ * result = "B";
74
+ * break;
75
+ * case "Export":
76
+ * result = "C";
77
+ * break;
78
+ * }
79
+ *
80
+ * handleKind(result);
81
+ * };
82
+ *
83
+ * const handleKind = (kind: "A" | "B" | "C"): void => {
84
+ * console.log(kind);
85
+ * };
28
86
  * ```
29
87
  */
30
88
  export const exhaustiveCheck = (value) => {
31
89
  throw new Error(`exhaustiveCheck unhandled case: ${JSON.stringify(value)}`);
32
90
  };
33
91
  /**
34
- * Returns the input value unchanged.
92
+ * Returns the value unchanged.
35
93
  *
36
94
  * Useful as a default transformation, placeholder callback, or when a function
37
95
  * is required but no transformation is needed.
@@ -47,11 +105,57 @@ export const exhaustiveCheck = (value) => {
47
105
  * ```
48
106
  */
49
107
  export const identity = (a) => a;
50
- export function readonly(value) {
51
- return value;
52
- }
53
- export const constVoid = () => undefined;
54
- export const constUndefined = () => undefined;
55
- export const constNull = () => null;
56
- export const constTrue = () => true;
57
- export const constFalse = () => false;
108
+ /**
109
+ * Creates a {@link Lazy} from a precomputed value.
110
+ *
111
+ * Use when the value is expensive to compute and want to compute it once at
112
+ * definition time rather than on every call.
113
+ *
114
+ * ### Example
115
+ *
116
+ * ```ts
117
+ * // Computed once at definition, returned on every call
118
+ * const getConfig = lazy(parseConfig(rawConfig));
119
+ *
120
+ * // vs. computed on every call
121
+ * const getConfig = () => parseConfig(rawConfig);
122
+ * ```
123
+ */
124
+ export const lazy = (value) => () => value;
125
+ /** A {@link Lazy} that returns `true`. */
126
+ export const lazyTrue = /*#__PURE__*/ lazy(true);
127
+ /** A {@link Lazy} that returns `false`. */
128
+ export const lazyFalse = /*#__PURE__*/ lazy(false);
129
+ /** A {@link Lazy} that returns `null`. */
130
+ export const lazyNull = /*#__PURE__*/ lazy(null);
131
+ /** A {@link Lazy} that returns `undefined`. */
132
+ export const lazyUndefined = /*#__PURE__*/ lazy(undefined);
133
+ /** A {@link Lazy} that returns `undefined` for void callbacks. */
134
+ export const lazyVoid = lazyUndefined;
135
+ /**
136
+ * Development placeholder that always throws.
137
+ *
138
+ * Use to sketch function bodies before implementing them. TypeScript infers the
139
+ * return type from context, so surrounding code still type-checks. Use an
140
+ * explicit generic when there is no return type annotation.
141
+ *
142
+ * ### Example
143
+ *
144
+ * ```ts
145
+ * // Type inferred from return type annotation
146
+ * const fetchUser = (id: UserId): Result<User, FetchError> => todo();
147
+ *
148
+ * expectTypeOf(fetchUser).returns.toEqualTypeOf<
149
+ * Result<User, FetchError>
150
+ * >();
151
+ *
152
+ * // Explicit generic when no return type
153
+ * const getConfig = () => todo<Config>();
154
+ *
155
+ * expectTypeOf(getConfig).returns.toEqualTypeOf<Config>();
156
+ * ```
157
+ */
158
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
159
+ export const todo = () => {
160
+ throw new Error("not yet implemented");
161
+ };
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Visual identicon generation from IDs.
3
+ *
4
+ * @module
5
+ */
1
6
  import type { Brand } from "./Brand.js";
2
7
  import { Id } from "./Type.js";
3
8
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"Identicon.d.ts","sourceRoot":"","sources":["../../src/Identicon.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,EAAE,EAAe,MAAM,WAAW,CAAC;AAG5C;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC;AAEpD,+BAA+B;AAC/B,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE3E;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,eAAe,GAC1B,IAAI,EAAE,EACN,QAAO,cAAyB,KAC/B,SA4JF,CAAC"}
1
+ {"version":3,"file":"Identicon.d.ts","sourceRoot":"","sources":["../../src/Identicon.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,EAAE,EAAe,MAAM,WAAW,CAAC;AAE5C;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC;AAEpD,+BAA+B;AAC/B,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE3E;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,eAAe,GAC1B,IAAI,EAAE,EACN,QAAO,cAAyB,KAC/B,SA4JF,CAAC"}
@@ -1,5 +1,10 @@
1
- import { idToIdBytes } from "./Type.js";
1
+ /**
2
+ * Visual identicon generation from IDs.
3
+ *
4
+ * @module
5
+ */
2
6
  import { md5 } from "@noble/hashes/legacy.js";
7
+ import { Id, idToIdBytes } from "./Type.js";
3
8
  /**
4
9
  * Creates a deterministic identicon SVG from an {@link Id}.
5
10
  *
@@ -0,0 +1,160 @@
1
+ /**
2
+ * Lookup-key collections and helpers.
3
+ *
4
+ * @module
5
+ */
6
+ import type { Brand } from "./Brand.js";
7
+ /**
8
+ * Derives the native lookup key used by lookup-based collections.
9
+ *
10
+ * Native `Map` and `Set` are suitable for primitive keys and keys where
11
+ * reference identity is the intended key, but they are not useful when
12
+ * different references should represent the same logical key.
13
+ *
14
+ * Lookup-based collections solve that by deriving a stable lookup key from each
15
+ * input key and using that lookup key for the internal native `Map` lookup.
16
+ * Keys that derive the same lookup key are treated as the same logical key.
17
+ *
18
+ * Use this when callers provide keys in one form but logical identity should be
19
+ * based on another stable key, such as a natural id or {@link StructuralKey}.
20
+ *
21
+ * @see {@link createLookupMap}
22
+ * @see {@link createLookupSet}
23
+ */
24
+ export type Lookup<K, L> = (key: K) => L;
25
+ /** Optional {@link Lookup}. */
26
+ export interface LookupOption<K, L = K> {
27
+ /** Derives the lookup key used for logical equality. */
28
+ readonly lookup?: Lookup<K, L>;
29
+ }
30
+ /**
31
+ * `Map`-like collection keyed by a {@link Lookup derived lookup key}.
32
+ *
33
+ * `set` preserves the first inserted representative for a logical key. `getKey`
34
+ * returns that representative for callers that need stable identity.
35
+ *
36
+ * @see {@link createLookupMap}
37
+ */
38
+ export interface LookupMap<K, V> extends Iterable<readonly [K, V]> {
39
+ readonly size: number;
40
+ readonly has: (key: K) => boolean;
41
+ readonly get: (key: K) => V | undefined;
42
+ readonly getKey: (key: K) => K | undefined;
43
+ readonly set: (key: K, value: V) => LookupMap<K, V>;
44
+ readonly delete: (key: K) => boolean;
45
+ readonly clear: () => void;
46
+ readonly keys: () => IterableIterator<K>;
47
+ readonly values: () => IterableIterator<V>;
48
+ readonly entries: () => IterableIterator<readonly [K, V]>;
49
+ readonly forEach: (callback: (value: V, key: K, map: LookupMap<K, V>) => void) => void;
50
+ readonly [Symbol.iterator]: () => IterableIterator<readonly [K, V]>;
51
+ }
52
+ /** Options for {@link createLookupMap}. */
53
+ export interface CreateLookupMapOptions<K, V, L> extends Required<LookupOption<K, L>> {
54
+ /** Initial entries for the map. */
55
+ readonly entries?: Iterable<readonly [K, V]>;
56
+ }
57
+ /** Creates {@link LookupMap}. */
58
+ export declare const createLookupMap: <K, V, L>({ lookup, entries, }: CreateLookupMapOptions<K, V, L>) => LookupMap<K, V>;
59
+ /**
60
+ * `Set`-like collection keyed by a {@link Lookup derived lookup key}.
61
+ *
62
+ * `add` preserves the first inserted representative for a logical key. `get`
63
+ * returns that representative for callers that need stable identity.
64
+ *
65
+ * @see {@link createLookupSet}
66
+ */
67
+ export interface LookupSet<K> extends Iterable<K> {
68
+ readonly size: number;
69
+ readonly has: (key: K) => boolean;
70
+ readonly get: (key: K) => K | undefined;
71
+ readonly add: (key: K) => LookupSet<K>;
72
+ readonly delete: (key: K) => boolean;
73
+ readonly clear: () => void;
74
+ readonly keys: () => IterableIterator<K>;
75
+ readonly values: () => IterableIterator<K>;
76
+ readonly entries: () => IterableIterator<readonly [K, K]>;
77
+ readonly forEach: (callback: (value: K, key: K, set: LookupSet<K>) => void) => void;
78
+ readonly [Symbol.iterator]: () => IterableIterator<K>;
79
+ }
80
+ /** Options for {@link createLookupSet}. */
81
+ export interface CreateLookupSetOptions<K, L> extends Required<LookupOption<K, L>> {
82
+ /** Initial values for the set. */
83
+ readonly values?: Iterable<K>;
84
+ }
85
+ /** Creates {@link LookupSet}. */
86
+ export declare const createLookupSet: <K, L>({ lookup, values, }: CreateLookupSetOptions<K, L>) => LookupSet<K>;
87
+ /** Scalar branch shared by {@link StructuralKey} and {@link Structural}. */
88
+ export type StructuralScalar = string | number | boolean | null | Uint8Array;
89
+ /** Branded native key produced by {@link structuralLookup}. */
90
+ export type StructuralLookupKey = string & Brand<"StructuralLookupKey">;
91
+ /**
92
+ * Immutable structural key.
93
+ *
94
+ * Structural keys are JSON-like values with `NaN` and positive/negative
95
+ * infinity also supported, or `Uint8Array`.
96
+ *
97
+ * @see {@link Structural}
98
+ * @see {@link structuralLookup}
99
+ */
100
+ export type StructuralKey = StructuralScalar | ReadonlyArray<StructuralKey> | {
101
+ readonly [key: string]: StructuralKey;
102
+ };
103
+ /**
104
+ * Compile-time structural form of `T` for structural lookup APIs.
105
+ *
106
+ * This exists because {@link StructuralKey} is the runtime serialization model,
107
+ * not a good public generic constraint for interface-shaped objects.
108
+ * `StructuralKey` models object values with a string index signature, which is
109
+ * stricter than ordinary interfaces like `{ readonly id: string }` even though
110
+ * the runtime serializer accepts such plain objects.
111
+ *
112
+ * `Structural<T>` checks a concrete type recursively at compile time instead:
113
+ * scalars pass through, arrays recurse, object properties recurse, and
114
+ * function-valued properties are rejected. This keeps public structural APIs
115
+ * ergonomic for interface-based inputs while preserving the same runtime
116
+ * constraints as structural lookup serialization.
117
+ *
118
+ * @see {@link StructuralKey}
119
+ * @see {@link structuralLookup}
120
+ */
121
+ export type Structural<T> = T extends StructuralScalar ? T : T extends ReadonlyArray<infer Item> ? ReadonlyArray<Structural<Item>> : T extends StructuralFunction ? never : T extends object ? {
122
+ readonly [K in keyof T as Extract<T[K], StructuralFunction> extends never ? K : never]: Structural<Exclude<T[K], StructuralFunction>>;
123
+ } & {
124
+ readonly [K in keyof T as Extract<T[K], StructuralFunction> extends never ? never : K]?: never;
125
+ } : never;
126
+ /** Function branch excluded by {@link Structural}. */
127
+ export type StructuralFunction = (...args: ReadonlyArray<unknown>) => unknown;
128
+ /**
129
+ * Returns the structural lookup key for `key`.
130
+ *
131
+ * Structural lookup keys are derived from JSON-like values plus `Uint8Array`.
132
+ * Equal structures produce the same lookup key even when they are different
133
+ * JavaScript instances.
134
+ *
135
+ * The derived key is memoized by non-null object identity in a module-scoped
136
+ * `WeakMap` shared by all callers, so keys must be immutable.
137
+ *
138
+ * Use this as a {@link Lookup} when logical equality should be based on
139
+ * structural value instead of reference identity.
140
+ *
141
+ * ### Example
142
+ *
143
+ * ```ts
144
+ * const byFilter = createLookupMap<
145
+ * { readonly table: string; readonly where: readonly [string, string] },
146
+ * string,
147
+ * StructuralLookupKey
148
+ * >({
149
+ * lookup: structuralLookup,
150
+ * });
151
+ *
152
+ * byFilter.set({ table: "todo", where: ["owner", "ada"] }, "cached");
153
+ * byFilter.get({ table: "todo", where: ["owner", "ada"] }); // "cached"
154
+ * ```
155
+ *
156
+ * @see {@link StructuralKey}
157
+ * @see {@link Structural}
158
+ */
159
+ export declare const structuralLookup: <K>(key: Structural<K>) => StructuralLookupKey;
160
+ //# sourceMappingURL=Lookup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Lookup.d.ts","sourceRoot":"","sources":["../../src/Lookup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,192 @@
1
+ /**
2
+ * Lookup-key collections and helpers.
3
+ *
4
+ * @module
5
+ */
6
+ import { assert } from "./Assert.js";
7
+ import { isPlainObject } from "./Object.js";
8
+ import { Uint8Array, uint8ArrayToBase64Url } from "./Type.js";
9
+ /** Creates {@link LookupMap}. */
10
+ export const createLookupMap = ({ lookup, entries, }) => {
11
+ const entriesByLookupKey = new Map();
12
+ const map = {
13
+ get size() {
14
+ return entriesByLookupKey.size;
15
+ },
16
+ has: (key) => entriesByLookupKey.has(lookup(key)),
17
+ get: (key) => entriesByLookupKey.get(lookup(key))?.value,
18
+ getKey: (key) => entriesByLookupKey.get(lookup(key))?.key,
19
+ set: (key, value) => {
20
+ const lookupKey = lookup(key);
21
+ const existingEntry = entriesByLookupKey.get(lookupKey);
22
+ entriesByLookupKey.set(lookupKey, {
23
+ key: existingEntry?.key ?? key,
24
+ value,
25
+ });
26
+ return map;
27
+ },
28
+ delete: (key) => entriesByLookupKey.delete(lookup(key)),
29
+ clear: () => {
30
+ entriesByLookupKey.clear();
31
+ },
32
+ keys: function* () {
33
+ for (const entry of entriesByLookupKey.values()) {
34
+ yield entry.key;
35
+ }
36
+ },
37
+ values: function* () {
38
+ for (const entry of entriesByLookupKey.values()) {
39
+ yield entry.value;
40
+ }
41
+ },
42
+ entries: function* () {
43
+ for (const entry of entriesByLookupKey.values()) {
44
+ yield [entry.key, entry.value];
45
+ }
46
+ },
47
+ forEach: (callback) => {
48
+ for (const entry of entriesByLookupKey.values()) {
49
+ callback(entry.value, entry.key, map);
50
+ }
51
+ },
52
+ [Symbol.iterator]: function () {
53
+ return map.entries();
54
+ },
55
+ };
56
+ if (entries) {
57
+ for (const [key, value] of entries) {
58
+ map.set(key, value);
59
+ }
60
+ }
61
+ return map;
62
+ };
63
+ /** Creates {@link LookupSet}. */
64
+ export const createLookupSet = ({ lookup, values, }) => {
65
+ const map = createLookupMap({ lookup });
66
+ const set = {
67
+ get size() {
68
+ return map.size;
69
+ },
70
+ has: (key) => map.has(key),
71
+ get: (key) => map.getKey(key),
72
+ add: (key) => {
73
+ map.set(key, true);
74
+ return set;
75
+ },
76
+ delete: (key) => map.delete(key),
77
+ clear: () => {
78
+ map.clear();
79
+ },
80
+ keys: () => map.keys(),
81
+ values: () => map.keys(),
82
+ entries: function* () {
83
+ for (const key of map.keys()) {
84
+ yield [key, key];
85
+ }
86
+ },
87
+ forEach: (callback) => {
88
+ for (const key of map.keys()) {
89
+ callback(key, key, set);
90
+ }
91
+ },
92
+ [Symbol.iterator]: function () {
93
+ return set.keys();
94
+ },
95
+ };
96
+ if (values) {
97
+ for (const value of values) {
98
+ set.add(value);
99
+ }
100
+ }
101
+ return set;
102
+ };
103
+ /**
104
+ * Returns the structural lookup key for `key`.
105
+ *
106
+ * Structural lookup keys are derived from JSON-like values plus `Uint8Array`.
107
+ * Equal structures produce the same lookup key even when they are different
108
+ * JavaScript instances.
109
+ *
110
+ * The derived key is memoized by non-null object identity in a module-scoped
111
+ * `WeakMap` shared by all callers, so keys must be immutable.
112
+ *
113
+ * Use this as a {@link Lookup} when logical equality should be based on
114
+ * structural value instead of reference identity.
115
+ *
116
+ * ### Example
117
+ *
118
+ * ```ts
119
+ * const byFilter = createLookupMap<
120
+ * { readonly table: string; readonly where: readonly [string, string] },
121
+ * string,
122
+ * StructuralLookupKey
123
+ * >({
124
+ * lookup: structuralLookup,
125
+ * });
126
+ *
127
+ * byFilter.set({ table: "todo", where: ["owner", "ada"] }, "cached");
128
+ * byFilter.get({ table: "todo", where: ["owner", "ada"] }); // "cached"
129
+ * ```
130
+ *
131
+ * @see {@link StructuralKey}
132
+ * @see {@link Structural}
133
+ */
134
+ export const structuralLookup = (key) => structuralLookupInternal(key);
135
+ const structuralLookupKeyByValue = new WeakMap();
136
+ const structuralLookupInternal = (value, path = new Set()) => {
137
+ switch (typeof value) {
138
+ case "string":
139
+ return `s:${JSON.stringify(value)}`;
140
+ case "number":
141
+ if (Number.isNaN(value))
142
+ return "n:NaN";
143
+ if (value === Number.POSITIVE_INFINITY)
144
+ return "n:Infinity";
145
+ if (value === Number.NEGATIVE_INFINITY)
146
+ return "n:-Infinity";
147
+ return Object.is(value, -0) ? "n:0" : `n:${value}`;
148
+ case "boolean":
149
+ return value ? "b:true" : "b:false";
150
+ case "object": {
151
+ if (value === null)
152
+ return "l:null";
153
+ const cachedLookupKey = structuralLookupKeyByValue.get(value);
154
+ if (cachedLookupKey)
155
+ return cachedLookupKey;
156
+ let lookupKey;
157
+ if (Array.isArray(value)) {
158
+ assert(!path.has(value), "Structural lookup keys must not contain cycles.");
159
+ path.add(value);
160
+ lookupKey = getStructuralArrayLookupKey(value, path);
161
+ path.delete(value);
162
+ }
163
+ else if (isPlainObject(value)) {
164
+ assert(!path.has(value), "Structural lookup keys must not contain cycles.");
165
+ path.add(value);
166
+ lookupKey = getStructuralObjectLookupKey(value, path);
167
+ path.delete(value);
168
+ }
169
+ else if (Uint8Array.is(value)) {
170
+ lookupKey = `u:${uint8ArrayToBase64Url(value)}`;
171
+ }
172
+ else {
173
+ assert(false, "Structural lookup keys must be JSON-like values or Uint8Array.");
174
+ }
175
+ structuralLookupKeyByValue.set(value, lookupKey);
176
+ return lookupKey;
177
+ }
178
+ default:
179
+ assert(false, "Structural lookup keys must be JSON-like values or Uint8Array.");
180
+ }
181
+ };
182
+ const getStructuralArrayLookupKey = (value, path) => `a:[${Array.from(value, (item) => structuralLookupInternal(item, path)).join(",")}]`;
183
+ const getStructuralObjectLookupKey = (value, path) => {
184
+ const valueRecord = value;
185
+ const entries = Object.keys(valueRecord)
186
+ .toSorted()
187
+ .map((key) => {
188
+ const item = valueRecord[key];
189
+ return `${JSON.stringify(key)}:${structuralLookupInternal(item, path)}`;
190
+ });
191
+ return `o:{${entries.join(",")}}`;
192
+ };
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Microtask queue utilities.
3
+ *
4
+ * @module
5
+ */
6
+ import { type NonEmptyReadonlyArray } from "./Array.js";
7
+ /**
8
+ * Batches values and flushes them in a single microtask.
9
+ *
10
+ * Calls to {@link MicrotaskBatch.push} within the same tick are coalesced into
11
+ * one flush.
12
+ */
13
+ export interface MicrotaskBatch<T> extends Disposable {
14
+ /** Enqueues one item and schedules a microtask flush if needed. */
15
+ readonly push: (item: T) => void;
16
+ /** Flushes queued items immediately. */
17
+ readonly flushNow: () => void;
18
+ }
19
+ /** Creates {@link MicrotaskBatch}. */
20
+ export declare const createMicrotaskBatch: <T>(onFlush: (items: NonEmptyReadonlyArray<T>) => void) => MicrotaskBatch<T>;
21
+ //# sourceMappingURL=Microtask.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Microtask.d.ts","sourceRoot":"","sources":["../../src/Microtask.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAiB,KAAK,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEvE;;;;;GAKG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC,CAAE,SAAQ,UAAU;IACnD,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IAEjC,wCAAwC;IACxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC;CAC/B;AAED,sCAAsC;AACtC,eAAO,MAAM,oBAAoB,GAAI,CAAC,EACpC,SAAS,CAAC,KAAK,EAAE,qBAAqB,CAAC,CAAC,CAAC,KAAK,IAAI,KACjD,cAAc,CAAC,CAAC,CAgClB,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Microtask queue utilities.
3
+ *
4
+ * @module
5
+ */
6
+ import { appendToArray } from "./Array.js";
7
+ /** Creates {@link MicrotaskBatch}. */
8
+ export const createMicrotaskBatch = (onFlush) => {
9
+ let queue = null;
10
+ let disposed = false;
11
+ const flushNow = () => {
12
+ if (disposed || queue == null)
13
+ return;
14
+ const queuedItems = queue;
15
+ queue = null;
16
+ onFlush(queuedItems);
17
+ };
18
+ return {
19
+ push: (item) => {
20
+ if (disposed)
21
+ return;
22
+ if (queue == null) {
23
+ queue = [item];
24
+ queueMicrotask(flushNow);
25
+ return;
26
+ }
27
+ queue = appendToArray(queue, item);
28
+ },
29
+ flushNow,
30
+ [Symbol.dispose]: () => {
31
+ if (disposed)
32
+ return;
33
+ disposed = true;
34
+ queue = null;
35
+ },
36
+ };
37
+ };
@@ -1,8 +1,13 @@
1
- import { NonEmptyReadonlyArray } from "./Array.js";
2
- import { Result } from "./Result.js";
1
+ /**
2
+ * Number arithmetic, comparison, and branded numeric types.
3
+ *
4
+ * @module
5
+ */
6
+ import type { NonEmptyReadonlyArray } from "./Array.js";
7
+ import type { IsBranded } from "./Brand.js";
8
+ import type { Result } from "./Result.js";
3
9
  import { NonNegativeInt, PositiveInt } from "./Type.js";
4
- import { Predicate, WidenLiteral } from "./Types.js";
5
- import { IsBranded } from "./Brand.js";
10
+ import type { Predicate, WidenLiteral } from "./Types.js";
6
11
  export declare const increment: (n: number) => number;
7
12
  export declare const decrement: (n: number) => number;
8
13
  /** Clamps a number within a given range. */
@@ -40,4 +45,13 @@ export declare const computeBalancedBuckets: (numberOfItems: NonNegativeInt,
40
45
  numberOfBuckets?: number & import("./Brand.js").Brand<"Int"> & import("./Brand.js").Brand<"NonNegative"> & import("./Brand.js").Brand<"Positive">,
41
46
  /** Default: 2 */
42
47
  minNumberOfItemsPerBucket?: number & import("./Brand.js").Brand<"Int"> & import("./Brand.js").Brand<"NonNegative"> & import("./Brand.js").Brand<"Positive">) => Result<NonEmptyReadonlyArray<PositiveInt>, PositiveInt>;
48
+ /**
49
+ * Valid index for {@link fibonacciAt}, constrained to 1-78.
50
+ *
51
+ * Limited to 78 because F(79) exceeds JavaScript's `MAX_SAFE_INTEGER`.
52
+ */
53
+ export declare const FibonacciIndex: import("./Type.js").BrandType<import("./Type.js").BrandType<import("./Type.js").Type<"Brand", number & import("./Brand.js").Brand<"Int"> & import("./Brand.js").Brand<"NonNegative"> & import("./Brand.js").Brand<"Positive">, number, import("./Type.js").PositiveError, number & import("./Brand.js").Brand<"Int"> & import("./Brand.js").Brand<"NonNegative">, import("./Type.js").NumberError | import("./Type.js").NonNegativeError | import("./Type.js").IntError>, "LessThanOrEqualTo78", import("./Type.js").LessThanOrEqualToError<78>, import("./Type.js").NumberError | import("./Type.js").NonNegativeError | import("./Type.js").IntError | import("./Type.js").PositiveError>, "FibonacciIndex", import("./Type.js").BrandWithoutRefineError<"FibonacciIndex", import("./Type.js").NumberError | import("./Type.js").NonNegativeError | import("./Type.js").IntError | import("./Type.js").PositiveError | import("./Type.js").LessThanOrEqualToError<78>>, never>;
54
+ export type FibonacciIndex = typeof FibonacciIndex.Type;
55
+ /** Returns the Fibonacci number at the given index (1-indexed: 1,1,2,3,5,8,...). */
56
+ export declare const fibonacciAt: (index: FibonacciIndex) => PositiveInt;
43
57
  //# sourceMappingURL=Number.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Number.d.ts","sourceRoot":"","sources":["../../src/Number.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEnD,OAAO,EAAW,MAAM,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,EAAoB,SAAS,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,eAAO,MAAM,SAAS,GAAI,GAAG,MAAM,KAAG,MAAe,CAAC;AAEtD,eAAO,MAAM,SAAS,GAAI,GAAG,MAAM,KAAG,MAAe,CAAC;AAEtD,4CAA4C;AAC5C,eAAO,MAAM,KAAK,GACf,KAAK,MAAM,EAAE,KAAK,MAAM,MACxB,GAAG,MAAM,KAAG,MACoB,CAAC;AAEpC;;;;;;;;;;GAUG;AACH,eAAO,MAAM,SAAS,GACnB,KAAK,MAAM,EAAE,KAAK,MAAM,KAAG,SAAS,CAAC,MAAM,CAEd,CAAC;AAEjC,wEAAwE;AACxE,eAAO,MAAM,GAAG,GAAI,CAAC,SAAS,MAAM,EAClC,GAAG,QAAQ,CAAC,CAAC,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,KAClC,SAAS,CAAC,CAAC,CAAC,SAAS,IAAI,GAAG,CAAC,GAAG,YAAY,CAAC,CAAC,CACa,CAAC;AAE/D,wEAAwE;AACxE,eAAO,MAAM,GAAG,GAAI,CAAC,SAAS,MAAM,EAClC,GAAG,QAAQ,CAAC,CAAC,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,KAClC,SAAS,CAAC,CAAC,CAAC,SAAS,IAAI,GAAG,CAAC,GAAG,YAAY,CAAC,CAAC,CACa,CAAC;AAE/D;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,GACjC,eAAe,cAAc;AAE7B,kBAAkB;AAClB,iJAAyC;AAEzC,iBAAiB;AACjB,2JAAkD,KACjD,MAAM,CAAC,qBAAqB,CAAC,WAAW,CAAC,EAAE,WAAW,CAoBxD,CAAC"}
1
+ {"version":3,"file":"Number.d.ts","sourceRoot":"","sources":["../../src/Number.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAExD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAIL,cAAc,EACd,WAAW,EACZ,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1D,eAAO,MAAM,SAAS,GAAI,GAAG,MAAM,KAAG,MAAe,CAAC;AAEtD,eAAO,MAAM,SAAS,GAAI,GAAG,MAAM,KAAG,MAAe,CAAC;AAEtD,4CAA4C;AAC5C,eAAO,MAAM,KAAK,GACf,KAAK,MAAM,EAAE,KAAK,MAAM,MACxB,GAAG,MAAM,KAAG,MACoB,CAAC;AAEpC;;;;;;;;;;GAUG;AACH,eAAO,MAAM,SAAS,GACnB,KAAK,MAAM,EAAE,KAAK,MAAM,KAAG,SAAS,CAAC,MAAM,CAEd,CAAC;AAEjC,wEAAwE;AACxE,eAAO,MAAM,GAAG,GAAI,CAAC,SAAS,MAAM,EAClC,GAAG,QAAQ,CAAC,CAAC,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,KAClC,SAAS,CAAC,CAAC,CAAC,SAAS,IAAI,GAAG,CAAC,GAAG,YAAY,CAAC,CAAC,CACE,CAAC;AAEpD,wEAAwE;AACxE,eAAO,MAAM,GAAG,GAAI,CAAC,SAAS,MAAM,EAClC,GAAG,QAAQ,CAAC,CAAC,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,KAClC,SAAS,CAAC,CAAC,CAAC,SAAS,IAAI,GAAG,CAAC,GAAG,YAAY,CAAC,CAAC,CACE,CAAC;AAEpD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,GACjC,eAAe,cAAc;AAE7B,kBAAkB;AAClB,iJAAyC;AAEzC,iBAAiB;AACjB,2JAAkD,KACjD,MAAM,CAAC,qBAAqB,CAAC,WAAW,CAAC,EAAE,WAAW,CAoBxD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,cAAc,k7BAG1B,CAAC;AACF,MAAM,MAAM,cAAc,GAAG,OAAO,cAAc,CAAC,IAAI,CAAC;AAExD,oFAAoF;AACpF,eAAO,MAAM,WAAW,GAAI,OAAO,cAAc,KAAG,WAMnD,CAAC"}