@czap/core 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.
Files changed (372) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +19 -0
  3. package/dist/addressed-digest.d.ts +15 -0
  4. package/dist/addressed-digest.d.ts.map +1 -0
  5. package/dist/addressed-digest.js +35 -0
  6. package/dist/addressed-digest.js.map +1 -0
  7. package/dist/animation.d.ts +46 -0
  8. package/dist/animation.d.ts.map +1 -0
  9. package/dist/animation.js +70 -0
  10. package/dist/animation.js.map +1 -0
  11. package/dist/assembly.d.ts +25 -0
  12. package/dist/assembly.d.ts.map +1 -0
  13. package/dist/assembly.js +58 -0
  14. package/dist/assembly.js.map +1 -0
  15. package/dist/av-bridge.d.ts +74 -0
  16. package/dist/av-bridge.d.ts.map +1 -0
  17. package/dist/av-bridge.js +107 -0
  18. package/dist/av-bridge.js.map +1 -0
  19. package/dist/av-renderer.d.ts +56 -0
  20. package/dist/av-renderer.d.ts.map +1 -0
  21. package/dist/av-renderer.js +65 -0
  22. package/dist/av-renderer.js.map +1 -0
  23. package/dist/blend.d.ts +61 -0
  24. package/dist/blend.d.ts.map +1 -0
  25. package/dist/blend.js +100 -0
  26. package/dist/blend.js.map +1 -0
  27. package/dist/boundary.d.ts +154 -0
  28. package/dist/boundary.d.ts.map +1 -0
  29. package/dist/boundary.js +269 -0
  30. package/dist/boundary.js.map +1 -0
  31. package/dist/brands.d.ts +63 -0
  32. package/dist/brands.d.ts.map +1 -0
  33. package/dist/brands.js +31 -0
  34. package/dist/brands.js.map +1 -0
  35. package/dist/caps.d.ts +49 -0
  36. package/dist/caps.d.ts.map +1 -0
  37. package/dist/caps.js +73 -0
  38. package/dist/caps.js.map +1 -0
  39. package/dist/capsule.d.ts +77 -0
  40. package/dist/capsule.d.ts.map +1 -0
  41. package/dist/capsule.js +18 -0
  42. package/dist/capsule.js.map +1 -0
  43. package/dist/capsules/boundary-evaluate.d.ts +28 -0
  44. package/dist/capsules/boundary-evaluate.d.ts.map +1 -0
  45. package/dist/capsules/boundary-evaluate.js +117 -0
  46. package/dist/capsules/boundary-evaluate.js.map +1 -0
  47. package/dist/capsules/canonical-cbor.d.ts +13 -0
  48. package/dist/capsules/canonical-cbor.d.ts.map +1 -0
  49. package/dist/capsules/canonical-cbor.js +60 -0
  50. package/dist/capsules/canonical-cbor.js.map +1 -0
  51. package/dist/capsules/token-buffer.d.ts +24 -0
  52. package/dist/capsules/token-buffer.d.ts.map +1 -0
  53. package/dist/capsules/token-buffer.js +53 -0
  54. package/dist/capsules/token-buffer.js.map +1 -0
  55. package/dist/capture.d.ts +40 -0
  56. package/dist/capture.d.ts.map +1 -0
  57. package/dist/capture.js +10 -0
  58. package/dist/capture.js.map +1 -0
  59. package/dist/cbor.d.ts +33 -0
  60. package/dist/cbor.d.ts.map +1 -0
  61. package/dist/cbor.js +179 -0
  62. package/dist/cbor.js.map +1 -0
  63. package/dist/cell.d.ts +53 -0
  64. package/dist/cell.d.ts.map +1 -0
  65. package/dist/cell.js +83 -0
  66. package/dist/cell.js.map +1 -0
  67. package/dist/codec.d.ts +30 -0
  68. package/dist/codec.d.ts.map +1 -0
  69. package/dist/codec.js +25 -0
  70. package/dist/codec.js.map +1 -0
  71. package/dist/component.d.ts +52 -0
  72. package/dist/component.d.ts.map +1 -0
  73. package/dist/component.js +44 -0
  74. package/dist/component.js.map +1 -0
  75. package/dist/composable.d.ts +76 -0
  76. package/dist/composable.d.ts.map +1 -0
  77. package/dist/composable.js +221 -0
  78. package/dist/composable.js.map +1 -0
  79. package/dist/compositor-pool.d.ts +74 -0
  80. package/dist/compositor-pool.d.ts.map +1 -0
  81. package/dist/compositor-pool.js +119 -0
  82. package/dist/compositor-pool.js.map +1 -0
  83. package/dist/compositor.d.ts +90 -0
  84. package/dist/compositor.d.ts.map +1 -0
  85. package/dist/compositor.js +278 -0
  86. package/dist/compositor.js.map +1 -0
  87. package/dist/config.d.ts +72 -0
  88. package/dist/config.d.ts.map +1 -0
  89. package/dist/config.js +97 -0
  90. package/dist/config.js.map +1 -0
  91. package/dist/dag.d.ts +251 -0
  92. package/dist/dag.d.ts.map +1 -0
  93. package/dist/dag.js +450 -0
  94. package/dist/dag.js.map +1 -0
  95. package/dist/defaults.d.ts +45 -0
  96. package/dist/defaults.d.ts.map +1 -0
  97. package/dist/defaults.js +45 -0
  98. package/dist/defaults.js.map +1 -0
  99. package/dist/derived.d.ts +34 -0
  100. package/dist/derived.d.ts.map +1 -0
  101. package/dist/derived.js +101 -0
  102. package/dist/derived.js.map +1 -0
  103. package/dist/diagnostics.d.ts +77 -0
  104. package/dist/diagnostics.d.ts.map +1 -0
  105. package/dist/diagnostics.js +122 -0
  106. package/dist/diagnostics.js.map +1 -0
  107. package/dist/dirty.d.ts +55 -0
  108. package/dist/dirty.d.ts.map +1 -0
  109. package/dist/dirty.js +80 -0
  110. package/dist/dirty.js.map +1 -0
  111. package/dist/easing.d.ts +55 -0
  112. package/dist/easing.d.ts.map +1 -0
  113. package/dist/easing.js +291 -0
  114. package/dist/easing.js.map +1 -0
  115. package/dist/ecs.d.ts +105 -0
  116. package/dist/ecs.d.ts.map +1 -0
  117. package/dist/ecs.js +245 -0
  118. package/dist/ecs.js.map +1 -0
  119. package/dist/fnv.d.ts +14 -0
  120. package/dist/fnv.d.ts.map +1 -0
  121. package/dist/fnv.js +28 -0
  122. package/dist/fnv.js.map +1 -0
  123. package/dist/frame-budget.d.ts +73 -0
  124. package/dist/frame-budget.d.ts.map +1 -0
  125. package/dist/frame-budget.js +114 -0
  126. package/dist/frame-budget.js.map +1 -0
  127. package/dist/gen-frame.d.ts +102 -0
  128. package/dist/gen-frame.d.ts.map +1 -0
  129. package/dist/gen-frame.js +121 -0
  130. package/dist/gen-frame.js.map +1 -0
  131. package/dist/harness/arbitrary-from-schema.d.ts +28 -0
  132. package/dist/harness/arbitrary-from-schema.d.ts.map +1 -0
  133. package/dist/harness/arbitrary-from-schema.js +262 -0
  134. package/dist/harness/arbitrary-from-schema.js.map +1 -0
  135. package/dist/harness/cached-projection.d.ts +19 -0
  136. package/dist/harness/cached-projection.d.ts.map +1 -0
  137. package/dist/harness/cached-projection.js +39 -0
  138. package/dist/harness/cached-projection.js.map +1 -0
  139. package/dist/harness/index.d.ts +16 -0
  140. package/dist/harness/index.d.ts.map +1 -0
  141. package/dist/harness/index.js +15 -0
  142. package/dist/harness/index.js.map +1 -0
  143. package/dist/harness/policy-gate.d.ts +18 -0
  144. package/dist/harness/policy-gate.d.ts.map +1 -0
  145. package/dist/harness/policy-gate.js +46 -0
  146. package/dist/harness/policy-gate.js.map +1 -0
  147. package/dist/harness/pure-transform.d.ts +42 -0
  148. package/dist/harness/pure-transform.d.ts.map +1 -0
  149. package/dist/harness/pure-transform.js +76 -0
  150. package/dist/harness/pure-transform.js.map +1 -0
  151. package/dist/harness/receipted-mutation.d.ts +23 -0
  152. package/dist/harness/receipted-mutation.d.ts.map +1 -0
  153. package/dist/harness/receipted-mutation.js +52 -0
  154. package/dist/harness/receipted-mutation.js.map +1 -0
  155. package/dist/harness/scene-composition.d.ts +19 -0
  156. package/dist/harness/scene-composition.d.ts.map +1 -0
  157. package/dist/harness/scene-composition.js +47 -0
  158. package/dist/harness/scene-composition.js.map +1 -0
  159. package/dist/harness/site-adapter.d.ts +18 -0
  160. package/dist/harness/site-adapter.d.ts.map +1 -0
  161. package/dist/harness/site-adapter.js +38 -0
  162. package/dist/harness/site-adapter.js.map +1 -0
  163. package/dist/harness/state-machine.d.ts +19 -0
  164. package/dist/harness/state-machine.d.ts.map +1 -0
  165. package/dist/harness/state-machine.js +44 -0
  166. package/dist/harness/state-machine.js.map +1 -0
  167. package/dist/hlc.d.ts +99 -0
  168. package/dist/hlc.d.ts.map +1 -0
  169. package/dist/hlc.js +219 -0
  170. package/dist/hlc.js.map +1 -0
  171. package/dist/index.d.ts +104 -0
  172. package/dist/index.d.ts.map +1 -0
  173. package/dist/index.js +137 -0
  174. package/dist/index.js.map +1 -0
  175. package/dist/interpolate.d.ts +14 -0
  176. package/dist/interpolate.d.ts.map +1 -0
  177. package/dist/interpolate.js +31 -0
  178. package/dist/interpolate.js.map +1 -0
  179. package/dist/live-cell.d.ts +46 -0
  180. package/dist/live-cell.d.ts.map +1 -0
  181. package/dist/live-cell.js +154 -0
  182. package/dist/live-cell.js.map +1 -0
  183. package/dist/op.d.ts +58 -0
  184. package/dist/op.d.ts.map +1 -0
  185. package/dist/op.js +171 -0
  186. package/dist/op.js.map +1 -0
  187. package/dist/plan.d.ts +195 -0
  188. package/dist/plan.d.ts.map +1 -0
  189. package/dist/plan.js +211 -0
  190. package/dist/plan.js.map +1 -0
  191. package/dist/protocol.d.ts +33 -0
  192. package/dist/protocol.d.ts.map +1 -0
  193. package/dist/protocol.js +10 -0
  194. package/dist/protocol.js.map +1 -0
  195. package/dist/quantizer-types.d.ts +28 -0
  196. package/dist/quantizer-types.d.ts.map +1 -0
  197. package/dist/quantizer-types.js +9 -0
  198. package/dist/quantizer-types.js.map +1 -0
  199. package/dist/receipt.d.ts +294 -0
  200. package/dist/receipt.d.ts.map +1 -0
  201. package/dist/receipt.js +352 -0
  202. package/dist/receipt.js.map +1 -0
  203. package/dist/runtime-coordinator.d.ts +75 -0
  204. package/dist/runtime-coordinator.d.ts.map +1 -0
  205. package/dist/runtime-coordinator.js +149 -0
  206. package/dist/runtime-coordinator.js.map +1 -0
  207. package/dist/scheduler.d.ts +58 -0
  208. package/dist/scheduler.d.ts.map +1 -0
  209. package/dist/scheduler.js +109 -0
  210. package/dist/scheduler.js.map +1 -0
  211. package/dist/ship-capsule.d.ts +54 -0
  212. package/dist/ship-capsule.d.ts.map +1 -0
  213. package/dist/ship-capsule.js +142 -0
  214. package/dist/ship-capsule.js.map +1 -0
  215. package/dist/ship-manifest.d.ts +45 -0
  216. package/dist/ship-manifest.d.ts.map +1 -0
  217. package/dist/ship-manifest.js +175 -0
  218. package/dist/ship-manifest.js.map +1 -0
  219. package/dist/signal.d.ts +149 -0
  220. package/dist/signal.d.ts.map +1 -0
  221. package/dist/signal.js +277 -0
  222. package/dist/signal.js.map +1 -0
  223. package/dist/speculative.d.ts +67 -0
  224. package/dist/speculative.d.ts.map +1 -0
  225. package/dist/speculative.js +139 -0
  226. package/dist/speculative.js.map +1 -0
  227. package/dist/store.d.ts +39 -0
  228. package/dist/store.d.ts.map +1 -0
  229. package/dist/store.js +42 -0
  230. package/dist/store.js.map +1 -0
  231. package/dist/style.d.ts +119 -0
  232. package/dist/style.d.ts.map +1 -0
  233. package/dist/style.js +168 -0
  234. package/dist/style.js.map +1 -0
  235. package/dist/testing.d.ts +14 -0
  236. package/dist/testing.d.ts.map +1 -0
  237. package/dist/testing.js +14 -0
  238. package/dist/testing.js.map +1 -0
  239. package/dist/theme.d.ts +78 -0
  240. package/dist/theme.d.ts.map +1 -0
  241. package/dist/theme.js +109 -0
  242. package/dist/theme.js.map +1 -0
  243. package/dist/timeline.d.ts +45 -0
  244. package/dist/timeline.d.ts.map +1 -0
  245. package/dist/timeline.js +101 -0
  246. package/dist/timeline.js.map +1 -0
  247. package/dist/token-buffer.d.ts +43 -0
  248. package/dist/token-buffer.d.ts.map +1 -0
  249. package/dist/token-buffer.js +112 -0
  250. package/dist/token-buffer.js.map +1 -0
  251. package/dist/token.d.ts +107 -0
  252. package/dist/token.d.ts.map +1 -0
  253. package/dist/token.js +143 -0
  254. package/dist/token.js.map +1 -0
  255. package/dist/tuple.d.ts +16 -0
  256. package/dist/tuple.d.ts.map +1 -0
  257. package/dist/tuple.js +16 -0
  258. package/dist/tuple.js.map +1 -0
  259. package/dist/type-utils.d.ts +41 -0
  260. package/dist/type-utils.d.ts.map +1 -0
  261. package/dist/type-utils.js +10 -0
  262. package/dist/type-utils.js.map +1 -0
  263. package/dist/typed-ref.d.ts +50 -0
  264. package/dist/typed-ref.d.ts.map +1 -0
  265. package/dist/typed-ref.js +59 -0
  266. package/dist/typed-ref.js.map +1 -0
  267. package/dist/ui-quality.d.ts +50 -0
  268. package/dist/ui-quality.d.ts.map +1 -0
  269. package/dist/ui-quality.js +64 -0
  270. package/dist/ui-quality.js.map +1 -0
  271. package/dist/validation-error.d.ts +25 -0
  272. package/dist/validation-error.d.ts.map +1 -0
  273. package/dist/validation-error.js +32 -0
  274. package/dist/validation-error.js.map +1 -0
  275. package/dist/vector-clock.d.ts +46 -0
  276. package/dist/vector-clock.d.ts.map +1 -0
  277. package/dist/vector-clock.js +91 -0
  278. package/dist/vector-clock.js.map +1 -0
  279. package/dist/video.d.ts +62 -0
  280. package/dist/video.d.ts.map +1 -0
  281. package/dist/video.js +59 -0
  282. package/dist/video.js.map +1 -0
  283. package/dist/wasm-dispatch.d.ts +52 -0
  284. package/dist/wasm-dispatch.d.ts.map +1 -0
  285. package/dist/wasm-dispatch.js +204 -0
  286. package/dist/wasm-dispatch.js.map +1 -0
  287. package/dist/wasm-fallback.d.ts +19 -0
  288. package/dist/wasm-fallback.d.ts.map +1 -0
  289. package/dist/wasm-fallback.js +93 -0
  290. package/dist/wasm-fallback.js.map +1 -0
  291. package/dist/wire.d.ts +49 -0
  292. package/dist/wire.d.ts.map +1 -0
  293. package/dist/wire.js +201 -0
  294. package/dist/wire.js.map +1 -0
  295. package/dist/zap.d.ts +42 -0
  296. package/dist/zap.d.ts.map +1 -0
  297. package/dist/zap.js +172 -0
  298. package/dist/zap.js.map +1 -0
  299. package/package.json +71 -0
  300. package/src/addressed-digest.ts +48 -0
  301. package/src/animation.ts +103 -0
  302. package/src/assembly.ts +76 -0
  303. package/src/av-bridge.ts +161 -0
  304. package/src/av-renderer.ts +118 -0
  305. package/src/blend.ts +135 -0
  306. package/src/boundary.ts +363 -0
  307. package/src/brands.ts +86 -0
  308. package/src/caps.ts +100 -0
  309. package/src/capsule.ts +95 -0
  310. package/src/capsules/boundary-evaluate.ts +128 -0
  311. package/src/capsules/canonical-cbor.ts +60 -0
  312. package/src/capsules/token-buffer.ts +57 -0
  313. package/src/capture.ts +48 -0
  314. package/src/cbor.ts +199 -0
  315. package/src/cell.ts +130 -0
  316. package/src/codec.ts +39 -0
  317. package/src/component.ts +102 -0
  318. package/src/composable.ts +328 -0
  319. package/src/compositor-pool.ts +162 -0
  320. package/src/compositor.ts +387 -0
  321. package/src/config.ts +157 -0
  322. package/src/dag.ts +527 -0
  323. package/src/defaults.ts +60 -0
  324. package/src/derived.ts +164 -0
  325. package/src/diagnostics.ts +186 -0
  326. package/src/dirty.ts +101 -0
  327. package/src/easing.ts +334 -0
  328. package/src/ecs.ts +382 -0
  329. package/src/fnv.ts +31 -0
  330. package/src/frame-budget.ts +149 -0
  331. package/src/gen-frame.ts +229 -0
  332. package/src/harness/arbitrary-from-schema.ts +270 -0
  333. package/src/harness/cached-projection.ts +46 -0
  334. package/src/harness/index.ts +16 -0
  335. package/src/harness/policy-gate.ts +51 -0
  336. package/src/harness/pure-transform.ts +121 -0
  337. package/src/harness/receipted-mutation.ts +59 -0
  338. package/src/harness/scene-composition.ts +54 -0
  339. package/src/harness/site-adapter.ts +43 -0
  340. package/src/harness/state-machine.ts +49 -0
  341. package/src/hlc.ts +238 -0
  342. package/src/index.ts +274 -0
  343. package/src/interpolate.ts +37 -0
  344. package/src/live-cell.ts +199 -0
  345. package/src/op.ts +233 -0
  346. package/src/plan.ts +317 -0
  347. package/src/protocol.ts +49 -0
  348. package/src/quantizer-types.ts +29 -0
  349. package/src/receipt.ts +444 -0
  350. package/src/runtime-coordinator.ts +230 -0
  351. package/src/scheduler.ts +161 -0
  352. package/src/ship-capsule.ts +191 -0
  353. package/src/signal.ts +345 -0
  354. package/src/speculative.ts +186 -0
  355. package/src/store.ts +77 -0
  356. package/src/style.ts +249 -0
  357. package/src/testing.ts +14 -0
  358. package/src/theme.ts +153 -0
  359. package/src/timeline.ts +146 -0
  360. package/src/token-buffer.ts +151 -0
  361. package/src/token.ts +197 -0
  362. package/src/tuple.ts +19 -0
  363. package/src/type-utils.ts +48 -0
  364. package/src/typed-ref.ts +79 -0
  365. package/src/ui-quality.ts +105 -0
  366. package/src/validation-error.ts +34 -0
  367. package/src/vector-clock.ts +111 -0
  368. package/src/video.ts +106 -0
  369. package/src/wasm-dispatch.ts +300 -0
  370. package/src/wasm-fallback.ts +102 -0
  371. package/src/wire.ts +274 -0
  372. package/src/zap.ts +241 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-2026 Eassa Ayoub <eassa@heyoub.dev>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,19 @@
1
+ # @czap/core
2
+
3
+ Primitives: Boundary, Token, Style, Theme, Signal, Compositor, ECS, HLC, DAG, Plan, AVBridge.
4
+
5
+ ## Docs
6
+
7
+ - [Naming & vocabulary](../../docs/GLOSSARY.md) — LiteShip, CZAP, `@czap/*`
8
+
9
+ - [API reference](https://github.com/heyoub/LiteShip/tree/main/docs/api/core/) — generated from source TSDoc
10
+ - [Architecture index](https://github.com/heyoub/LiteShip/blob/main/docs/ARCHITECTURE.md)
11
+ - [ADRs](https://github.com/heyoub/LiteShip/tree/main/docs/adr/)
12
+
13
+ ## Install
14
+
15
+ ```bash
16
+ pnpm add @czap/core
17
+ ```
18
+
19
+ ## Part of [LiteShip](https://github.com/heyoub/LiteShip#readme)
@@ -0,0 +1,15 @@
1
+ /**
2
+ * AddressedDigest construction — pair a {@link ContentAddress} (fnv1a) with an
3
+ * {@link IntegrityDigest} (sha256) over the same canonical bytes (ADR-0011).
4
+ *
5
+ * @module
6
+ */
7
+ import { Effect } from 'effect';
8
+ import type { AddressedDigest as _AddressedDigest } from './brands.js';
9
+ export type AddressedDigest = _AddressedDigest;
10
+ /** Derive an {@link AddressedDigest} from raw bytes. v0.1.0 implements `sha256` only. */
11
+ export declare const AddressedDigestOf: (bytes: Uint8Array, algo?: "sha256" | "blake3") => Effect.Effect<_AddressedDigest, Error>;
12
+ export declare const AddressedDigest: {
13
+ of: (bytes: Uint8Array, algo?: "sha256" | "blake3") => Effect.Effect<_AddressedDigest, Error>;
14
+ };
15
+ //# sourceMappingURL=addressed-digest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addressed-digest.d.ts","sourceRoot":"","sources":["../src/addressed-digest.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,EAAE,eAAe,IAAI,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAIvE,MAAM,MAAM,eAAe,GAAG,gBAAgB,CAAC;AAoB/C,yFAAyF;AACzF,eAAO,MAAM,iBAAiB,GAC5B,OAAO,UAAU,EACjB,OAAM,QAAQ,GAAG,QAAmB,KACnC,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,KAAK,CASpC,CAAC;AAEL,eAAO,MAAM,eAAe;gBAbnB,UAAU,SACX,QAAQ,GAAG,QAAQ,KACxB,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,KAAK,CAAC;CAWe,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * AddressedDigest construction — pair a {@link ContentAddress} (fnv1a) with an
3
+ * {@link IntegrityDigest} (sha256) over the same canonical bytes (ADR-0011).
4
+ *
5
+ * @module
6
+ */
7
+ import { Effect } from 'effect';
8
+ import { IntegrityDigest as mkIntegrityDigest } from './brands.js';
9
+ import { fnv1aBytes } from './fnv.js';
10
+ const bytesToHex = (bytes) => {
11
+ let out = '';
12
+ for (let i = 0; i < bytes.length; i++) {
13
+ out += bytes[i].toString(16).padStart(2, '0');
14
+ }
15
+ return out;
16
+ };
17
+ const sha256Hex = (bytes) => Effect.tryPromise({
18
+ try: async () => {
19
+ const buffer = await crypto.subtle.digest('SHA-256', bytes);
20
+ return bytesToHex(new Uint8Array(buffer));
21
+ },
22
+ catch: (error) => new Error(`SHA-256 hash failed: ${error instanceof Error ? error.message : String(error)}`),
23
+ }).pipe(Effect.orDie);
24
+ /** Derive an {@link AddressedDigest} from raw bytes. v0.1.0 implements `sha256` only. */
25
+ export const AddressedDigestOf = (bytes, algo = 'sha256') => Effect.gen(function* () {
26
+ if (algo !== 'sha256') {
27
+ return yield* Effect.fail(new Error(`AddressedDigest: algo "${algo}" not yet implemented (v0.2)`));
28
+ }
29
+ const display_id = fnv1aBytes(bytes);
30
+ const hex = yield* sha256Hex(bytes);
31
+ const integrity_digest = mkIntegrityDigest(`sha256:${hex}`);
32
+ return { display_id, integrity_digest, algo: 'sha256' };
33
+ });
34
+ export const AddressedDigest = { of: AddressedDigestOf };
35
+ //# sourceMappingURL=addressed-digest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addressed-digest.js","sourceRoot":"","sources":["../src/addressed-digest.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,eAAe,IAAI,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAItC,MAAM,UAAU,GAAG,CAAC,KAAiB,EAAU,EAAE;IAC/C,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,GAAG,IAAI,KAAK,CAAC,CAAC,CAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,SAAS,GAAG,CAAC,KAAiB,EAAyB,EAAE,CAC7D,MAAM,CAAC,UAAU,CAAC;IAChB,GAAG,EAAE,KAAK,IAAI,EAAE;QACd,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,KAAqB,CAAC,CAAC;QAC5E,OAAO,UAAU,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;IAC5C,CAAC;IACD,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CACf,IAAI,KAAK,CAAC,wBAAwB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;CAC9F,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAExB,yFAAyF;AACzF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,KAAiB,EACjB,OAA4B,QAAQ,EACI,EAAE,CAC1C,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,0BAA0B,IAAI,8BAA8B,CAAC,CAAC,CAAC;IACrG,CAAC;IACD,MAAM,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC;IAC5D,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,IAAI,EAAE,QAAiB,EAAE,CAAC;AACnE,CAAC,CAAC,CAAC;AAEL,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,EAAE,EAAE,iBAAiB,EAAE,CAAC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Animation -- rAF to Effect.Stream interpolation + value lerping.
3
+ *
4
+ * Produces a Stream of AnimationFrame values driven by requestAnimationFrame,
5
+ * with configurable duration and easing. Also provides numeric record
6
+ * interpolation for smooth state transitions.
7
+ *
8
+ * @module
9
+ */
10
+ import { Stream } from 'effect';
11
+ import type { Millis } from './brands.js';
12
+ import type { Easing } from './easing.js';
13
+ import type { Scheduler } from './scheduler.js';
14
+ import { interpolate } from './interpolate.js';
15
+ interface AnimationFrameShape {
16
+ readonly progress: number;
17
+ readonly eased: number;
18
+ readonly elapsed: Millis;
19
+ readonly timestamp: number;
20
+ }
21
+ /**
22
+ * Create a finite animation stream driven by rAF.
23
+ * Emits AnimationFrame values from progress 0 to 1.
24
+ */
25
+ declare function _run(config: {
26
+ duration: Millis;
27
+ easing?: Easing.Fn;
28
+ scheduler?: Scheduler.Shape;
29
+ }): Stream.Stream<AnimationFrameShape>;
30
+ /**
31
+ * Animation — rAF-driven value interpolation exposed as an `Effect.Stream`.
32
+ * Pairs a duration and easing with either primitive lerping or the generic
33
+ * {@link Animation.interpolate} over numeric records.
34
+ */
35
+ export declare const Animation: {
36
+ /** Run an rAF animation that yields a stream of {@link Animation.Frame}. */
37
+ run: typeof _run;
38
+ /** Shallow numeric-record interpolator; non-numeric keys pass through. */
39
+ interpolate: typeof interpolate;
40
+ };
41
+ export declare namespace Animation {
42
+ /** Structural shape of a single frame emitted by {@link Animation.run}. */
43
+ type Frame = AnimationFrameShape;
44
+ }
45
+ export {};
46
+ //# sourceMappingURL=animation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animation.d.ts","sourceRoot":"","sources":["../src/animation.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAU,MAAM,EAAS,MAAM,QAAQ,CAAC;AAC/C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,UAAU,mBAAmB;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED;;;GAGG;AACH,iBAAS,IAAI,CAAC,MAAM,EAAE;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC;IACnB,SAAS,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC;CAC7B,GAAG,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAmDrC;AAED;;;;GAIG;AACH,eAAO,MAAM,SAAS;IACpB,4EAA4E;;IAE5E,0EAA0E;;CAE3E,CAAC;AAEF,MAAM,CAAC,OAAO,WAAW,SAAS,CAAC;IACjC,2EAA2E;IAC3E,KAAY,KAAK,GAAG,mBAAmB,CAAC;CACzC"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Animation -- rAF to Effect.Stream interpolation + value lerping.
3
+ *
4
+ * Produces a Stream of AnimationFrame values driven by requestAnimationFrame,
5
+ * with configurable duration and easing. Also provides numeric record
6
+ * interpolation for smooth state transitions.
7
+ *
8
+ * @module
9
+ */
10
+ import { Effect, Stream, Queue } from 'effect';
11
+ import { Millis as mkMillis } from './brands.js';
12
+ import { Easing as EasingImpl } from './easing.js';
13
+ import { Scheduler as SchedulerImpl } from './scheduler.js';
14
+ import { interpolate } from './interpolate.js';
15
+ /**
16
+ * Create a finite animation stream driven by rAF.
17
+ * Emits AnimationFrame values from progress 0 to 1.
18
+ */
19
+ function _run(config) {
20
+ const { duration, easing = EasingImpl.linear } = config;
21
+ if (duration <= 0) {
22
+ return Stream.succeed({
23
+ progress: 1,
24
+ eased: easing(1),
25
+ elapsed: mkMillis(0),
26
+ timestamp: 0,
27
+ });
28
+ }
29
+ return Stream.callback((queue) => Effect.gen(function* () {
30
+ const sched = config.scheduler ?? (typeof requestAnimationFrame !== 'undefined' ? SchedulerImpl.raf() : SchedulerImpl.noop());
31
+ let startTime = null;
32
+ let schedId;
33
+ const tick = (timestamp) => {
34
+ if (startTime === null)
35
+ startTime = timestamp;
36
+ const elapsed = timestamp - startTime;
37
+ const progress = Math.min(elapsed / duration, 1);
38
+ const eased = easing(progress);
39
+ Queue.offerUnsafe(queue, {
40
+ progress,
41
+ eased,
42
+ elapsed: mkMillis(elapsed),
43
+ timestamp,
44
+ });
45
+ if (progress >= 1) {
46
+ Queue.endUnsafe(queue);
47
+ }
48
+ else {
49
+ schedId = sched.schedule(tick);
50
+ }
51
+ };
52
+ schedId = sched.schedule(tick);
53
+ yield* Effect.addFinalizer(() => Effect.sync(() => {
54
+ sched.cancel(schedId);
55
+ }));
56
+ yield* Effect.never;
57
+ }));
58
+ }
59
+ /**
60
+ * Animation — rAF-driven value interpolation exposed as an `Effect.Stream`.
61
+ * Pairs a duration and easing with either primitive lerping or the generic
62
+ * {@link Animation.interpolate} over numeric records.
63
+ */
64
+ export const Animation = {
65
+ /** Run an rAF animation that yields a stream of {@link Animation.Frame}. */
66
+ run: _run,
67
+ /** Shallow numeric-record interpolator; non-numeric keys pass through. */
68
+ interpolate,
69
+ };
70
+ //# sourceMappingURL=animation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animation.js","sourceRoot":"","sources":["../src/animation.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAE/C,OAAO,EAAE,MAAM,IAAI,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,aAAa,CAAC;AAEnD,OAAO,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAS/C;;;GAGG;AACH,SAAS,IAAI,CAAC,MAIb;IACC,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC;IAExD,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;QAClB,OAAO,MAAM,CAAC,OAAO,CAAsB;YACzC,QAAQ,EAAE,CAAC;YACX,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;YAChB,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;YACpB,SAAS,EAAE,CAAC;SACb,CAAC,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC,QAAQ,CAAsB,CAAC,KAAK,EAAE,EAAE,CACpD,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAClB,MAAM,KAAK,GACT,MAAM,CAAC,SAAS,IAAI,CAAC,OAAO,qBAAqB,KAAK,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC;QAElH,IAAI,SAAS,GAAkB,IAAI,CAAC;QACpC,IAAI,OAAe,CAAC;QAEpB,MAAM,IAAI,GAAG,CAAC,SAAiB,EAAQ,EAAE;YACvC,IAAI,SAAS,KAAK,IAAI;gBAAE,SAAS,GAAG,SAAS,CAAC;YAC9C,MAAM,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;YACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,GAAG,QAAQ,EAAE,CAAC,CAAC,CAAC;YACjD,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;YAE/B,KAAK,CAAC,WAAW,CAAC,KAAK,EAAE;gBACvB,QAAQ;gBACR,KAAK;gBACL,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC;gBAC1B,SAAS;aACV,CAAC,CAAC;YAEH,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;gBAClB,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YACzB,CAAC;iBAAM,CAAC;gBACN,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACjC,CAAC;QACH,CAAC,CAAC;QAEF,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAE/B,KAAK,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,CAC9B,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;YACf,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC,CAAC,CACH,CAAC;QAEF,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;IACtB,CAAC,CAAC,CACH,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,4EAA4E;IAC5E,GAAG,EAAE,IAAI;IACT,0EAA0E;IAC1E,WAAW;CACZ,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Assembly catalog — 7-arm closed vocabulary of capsule kinds.
3
+ * `defineCapsule` validates a contract, computes its content address,
4
+ * and registers it in the module-level catalog for the compiler to walk.
5
+ *
6
+ * @module
7
+ */
8
+ import type { CapsuleContract, AssemblyKind } from './capsule.js';
9
+ import type { ContentAddress } from './brands.js';
10
+ /** A capsule declaration plus its content-addressed id. */
11
+ export interface CapsuleDef<K extends AssemblyKind, In, Out, R> extends CapsuleContract<K, In, Out, R> {
12
+ readonly id: ContentAddress;
13
+ }
14
+ /**
15
+ * Declare a capsule. Validates shape, computes content address,
16
+ * registers in the module-level catalog, returns a typed def.
17
+ * No runtime behavior beyond registration — behavior comes from
18
+ * the harness/compiler walking the catalog.
19
+ */
20
+ export declare function defineCapsule<K extends AssemblyKind, In, Out, R>(decl: Omit<CapsuleContract<K, In, Out, R>, 'id'>): CapsuleDef<K, In, Out, R>;
21
+ /** Read-only snapshot of all registered capsules. */
22
+ export declare function getCapsuleCatalog(): readonly CapsuleDef<AssemblyKind, unknown, unknown, unknown>[];
23
+ /** Clear the registry. Intended for tests and hot-reload only. */
24
+ export declare function resetCapsuleCatalog(): void;
25
+ //# sourceMappingURL=assembly.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assembly.d.ts","sourceRoot":"","sources":["../src/assembly.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAKlD,2DAA2D;AAC3D,MAAM,WAAW,UAAU,CAAC,CAAC,SAAS,YAAY,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAC5D,SAAQ,eAAe,CAAC,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;IACtC,QAAQ,CAAC,EAAE,EAAE,cAAc,CAAC;CAC7B;AAqBD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,YAAY,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAC9D,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,GAC/C,UAAU,CAAC,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,CAkB3B;AAED,qDAAqD;AACrD,wBAAgB,iBAAiB,IAAI,SAAS,UAAU,CAAC,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,CAElG;AAED,kEAAkE;AAClE,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Assembly catalog — 7-arm closed vocabulary of capsule kinds.
3
+ * `defineCapsule` validates a contract, computes its content address,
4
+ * and registers it in the module-level catalog for the compiler to walk.
5
+ *
6
+ * @module
7
+ */
8
+ import { fnv1aBytes } from './fnv.js';
9
+ import { CanonicalCbor } from './cbor.js';
10
+ import { Diagnostics } from './diagnostics.js';
11
+ const catalog = [];
12
+ function computeId(contract) {
13
+ // ADR-0003: route through CanonicalCbor to obtain a deterministic byte
14
+ // sequence (RFC 8949 §4.2.1) before hashing. Stable across key order,
15
+ // platform endianness, and stringification quirks.
16
+ const canonicalBytes = CanonicalCbor.encode({
17
+ kind: contract._kind,
18
+ name: contract.name,
19
+ site: contract.site,
20
+ budgets: contract.budgets,
21
+ capabilities: contract.capabilities,
22
+ invariantNames: contract.invariants.map((i) => i.name),
23
+ });
24
+ return fnv1aBytes(canonicalBytes);
25
+ }
26
+ /**
27
+ * Declare a capsule. Validates shape, computes content address,
28
+ * registers in the module-level catalog, returns a typed def.
29
+ * No runtime behavior beyond registration — behavior comes from
30
+ * the harness/compiler walking the catalog.
31
+ */
32
+ export function defineCapsule(decl) {
33
+ // For pureTransform capsules: omitting `run` downgrades the generated
34
+ // harness test to `it.skip` (Task 8 honest-skip discipline). Warn so
35
+ // contributors notice rather than silently skip property tests.
36
+ // Other arms don't yet have a wired runtime channel — see ADR-TODO.
37
+ if (decl._kind === 'pureTransform' && decl.invariants.length > 0 && decl.run === undefined) {
38
+ Diagnostics.warn({
39
+ source: 'defineCapsule',
40
+ code: 'pure_transform_missing_run',
41
+ message: `pureTransform capsule "${decl.name}" declares ${decl.invariants.length} invariant(s) but no ` +
42
+ '`run` function — invariants are type-only without one. Add `run: (input) => ...` to enable runtime validation against your invariants.',
43
+ });
44
+ }
45
+ const id = computeId(decl);
46
+ const def = { ...decl, id };
47
+ catalog.push(def);
48
+ return def;
49
+ }
50
+ /** Read-only snapshot of all registered capsules. */
51
+ export function getCapsuleCatalog() {
52
+ return catalog.slice();
53
+ }
54
+ /** Clear the registry. Intended for tests and hot-reload only. */
55
+ export function resetCapsuleCatalog() {
56
+ catalog.length = 0;
57
+ }
58
+ //# sourceMappingURL=assembly.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assembly.js","sourceRoot":"","sources":["../src/assembly.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAQ/C,MAAM,OAAO,GAA0D,EAAE,CAAC;AAE1E,SAAS,SAAS,CAChB,QAA8E;IAE9E,uEAAuE;IACvE,sEAAsE;IACtE,mDAAmD;IACnD,MAAM,cAAc,GAAG,aAAa,CAAC,MAAM,CAAC;QAC1C,IAAI,EAAE,QAAQ,CAAC,KAAK;QACpB,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,OAAO,EAAE,QAAQ,CAAC,OAAO;QACzB,YAAY,EAAE,QAAQ,CAAC,YAAY;QACnC,cAAc,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;KACvD,CAAC,CAAC;IACH,OAAO,UAAU,CAAC,cAAc,CAAC,CAAC;AACpC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAC3B,IAAgD;IAEhD,sEAAsE;IACtE,qEAAqE;IACrE,gEAAgE;IAChE,oEAAoE;IACpE,IAAI,IAAI,CAAC,KAAK,KAAK,eAAe,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;QAC3F,WAAW,CAAC,IAAI,CAAC;YACf,MAAM,EAAE,eAAe;YACvB,IAAI,EAAE,4BAA4B;YAClC,OAAO,EACL,0BAA0B,IAAI,CAAC,IAAI,cAAc,IAAI,CAAC,UAAU,CAAC,MAAM,uBAAuB;gBAC9F,wIAAwI;SAC3I,CAAC,CAAC;IACL,CAAC;IACD,MAAM,EAAE,GAAG,SAAS,CAAC,IAA4E,CAAC,CAAC;IACnG,MAAM,GAAG,GAAG,EAAE,GAAG,IAAI,EAAE,EAAE,EAA+B,CAAC;IACzD,OAAO,CAAC,IAAI,CAAC,GAA0D,CAAC,CAAC;IACzE,OAAO,GAAG,CAAC;AACb,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,iBAAiB;IAC/B,OAAO,OAAO,CAAC,KAAK,EAAE,CAAC;AACzB,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,mBAAmB;IACjC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;AACrB,CAAC"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * AVBridge -- SharedArrayBuffer timeline bridge for A/V convergence.
3
+ *
4
+ * Provides a single sample counter shared between an AudioWorklet
5
+ * (which advances it) and the visual compositor (which reads it).
6
+ * Works in both real-time (browser) and offline (deterministic) modes.
7
+ *
8
+ * Memory layout (SharedArrayBuffer, 24 bytes):
9
+ * Int32[0] -- sample counter (atomic increment by audio, atomic read by video)
10
+ * Int32[1] -- audio running flag (1 = playing, 0 = paused)
11
+ * Float64[1] -- audio start timestamp in ms (bytes 8-15, for drift calc)
12
+ *
13
+ * @module
14
+ */
15
+ interface AVBridgeShape {
16
+ readonly buffer: SharedArrayBuffer;
17
+ readonly sampleRate: number;
18
+ readonly fps: number;
19
+ advanceSamples(count: number): void;
20
+ getCurrentSample(): number;
21
+ setRunning(running: boolean): void;
22
+ isRunning(): boolean;
23
+ getCurrentFrame(): number;
24
+ sampleToTime(sample: number): number;
25
+ timeToSample(time: number): number;
26
+ isAudioAhead(): boolean;
27
+ drift(): number;
28
+ reset(): void;
29
+ }
30
+ interface AVBridgeConfig {
31
+ readonly sampleRate: number;
32
+ readonly fps: number;
33
+ readonly buffer?: SharedArrayBuffer;
34
+ }
35
+ /**
36
+ * Creates an AVBridge backed by a SharedArrayBuffer for lock-free
37
+ * audio/video timeline synchronization between threads.
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * const bridge = AVBridge.make({ sampleRate: 48000, fps: 60 });
42
+ * bridge.setRunning(true);
43
+ * bridge.advanceSamples(800); // AudioWorklet advances by 800 samples
44
+ * const frame = bridge.getCurrentFrame(); // current video frame number
45
+ * const drift = bridge.drift(); // fractional frame offset
46
+ * bridge.reset(); // zero out counters
47
+ * ```
48
+ */
49
+ declare function _make(config: AVBridgeConfig): AVBridgeShape;
50
+ /**
51
+ * AVBridge -- SharedArrayBuffer-based timeline bridge for audio/video convergence.
52
+ * Provides atomic sample counting shared between AudioWorklet and visual compositor.
53
+ *
54
+ * @example
55
+ * ```ts
56
+ * const bridge = AVBridge.make({ sampleRate: 44100, fps: 30 });
57
+ * bridge.setRunning(true);
58
+ * bridge.advanceSamples(1470); // advance by one video frame worth of samples
59
+ * bridge.getCurrentFrame(); // 1
60
+ * bridge.sampleToTime(44100); // 1.0 (seconds)
61
+ * bridge.timeToSample(0.5); // 22050
62
+ * ```
63
+ */
64
+ export declare const AVBridge: {
65
+ make: typeof _make;
66
+ };
67
+ export declare namespace AVBridge {
68
+ /** Structural shape of an AVBridge instance — sample counters, time conversions, reset. */
69
+ type Shape = AVBridgeShape;
70
+ /** Configuration accepted by {@link AVBridge.make}: sample rate and fps. */
71
+ type Config = AVBridgeConfig;
72
+ }
73
+ export {};
74
+ //# sourceMappingURL=av-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"av-bridge.d.ts","sourceRoot":"","sources":["../src/av-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,UAAU,aAAa;IACrB,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAErB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,gBAAgB,IAAI,MAAM,CAAC;IAC3B,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACnC,SAAS,IAAI,OAAO,CAAC;IAErB,eAAe,IAAI,MAAM,CAAC;IAC1B,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACrC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAEnC,YAAY,IAAI,OAAO,CAAC;IACxB,KAAK,IAAI,MAAM,CAAC;IAChB,KAAK,IAAI,IAAI,CAAC;CACf;AAeD,UAAU,cAAc;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAC;CACrC;AAED;;;;;;;;;;;;;GAaG;AACH,iBAAS,KAAK,CAAC,MAAM,EAAE,cAAc,GAAG,aAAa,CAkEpD;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,QAAQ;;CAAkB,CAAC;AAExC,MAAM,CAAC,OAAO,WAAW,QAAQ,CAAC;IAChC,2FAA2F;IAC3F,KAAY,KAAK,GAAG,aAAa,CAAC;IAClC,4EAA4E;IAC5E,KAAY,MAAM,GAAG,cAAc,CAAC;CACrC"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * AVBridge -- SharedArrayBuffer timeline bridge for A/V convergence.
3
+ *
4
+ * Provides a single sample counter shared between an AudioWorklet
5
+ * (which advances it) and the visual compositor (which reads it).
6
+ * Works in both real-time (browser) and offline (deterministic) modes.
7
+ *
8
+ * Memory layout (SharedArrayBuffer, 24 bytes):
9
+ * Int32[0] -- sample counter (atomic increment by audio, atomic read by video)
10
+ * Int32[1] -- audio running flag (1 = playing, 0 = paused)
11
+ * Float64[1] -- audio start timestamp in ms (bytes 8-15, for drift calc)
12
+ *
13
+ * @module
14
+ */
15
+ // ---------------------------------------------------------------------------
16
+ // Constants
17
+ // ---------------------------------------------------------------------------
18
+ const BUFFER_BYTE_LENGTH = 24;
19
+ const SAMPLE_COUNTER_IDX = 0;
20
+ const RUNNING_FLAG_IDX = 1;
21
+ const START_TIMESTAMP_F64_IDX = 1;
22
+ /**
23
+ * Creates an AVBridge backed by a SharedArrayBuffer for lock-free
24
+ * audio/video timeline synchronization between threads.
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * const bridge = AVBridge.make({ sampleRate: 48000, fps: 60 });
29
+ * bridge.setRunning(true);
30
+ * bridge.advanceSamples(800); // AudioWorklet advances by 800 samples
31
+ * const frame = bridge.getCurrentFrame(); // current video frame number
32
+ * const drift = bridge.drift(); // fractional frame offset
33
+ * bridge.reset(); // zero out counters
34
+ * ```
35
+ */
36
+ function _make(config) {
37
+ const { sampleRate, fps } = config;
38
+ if (sampleRate <= 0 || !Number.isFinite(sampleRate)) {
39
+ throw new RangeError(`AVBridge.make: sampleRate must be a positive finite number, got ${sampleRate}`);
40
+ }
41
+ if (fps <= 0 || !Number.isFinite(fps)) {
42
+ throw new RangeError(`AVBridge.make: fps must be a positive finite number, got ${fps}`);
43
+ }
44
+ const buffer = config.buffer ?? new SharedArrayBuffer(BUFFER_BYTE_LENGTH);
45
+ const i32 = new Int32Array(buffer);
46
+ const f64 = new Float64Array(buffer);
47
+ return {
48
+ buffer,
49
+ sampleRate,
50
+ fps,
51
+ advanceSamples(count) {
52
+ Atomics.add(i32, SAMPLE_COUNTER_IDX, count);
53
+ },
54
+ getCurrentSample() {
55
+ return Atomics.load(i32, SAMPLE_COUNTER_IDX);
56
+ },
57
+ setRunning(running) {
58
+ Atomics.store(i32, RUNNING_FLAG_IDX, running ? 1 : 0);
59
+ },
60
+ isRunning() {
61
+ return Atomics.load(i32, RUNNING_FLAG_IDX) === 1;
62
+ },
63
+ getCurrentFrame() {
64
+ const sample = Atomics.load(i32, SAMPLE_COUNTER_IDX);
65
+ return Math.floor((sample / sampleRate) * fps);
66
+ },
67
+ sampleToTime(sample) {
68
+ return sample / sampleRate;
69
+ },
70
+ timeToSample(time) {
71
+ return Math.round(time * sampleRate);
72
+ },
73
+ isAudioAhead() {
74
+ const sample = Atomics.load(i32, SAMPLE_COUNTER_IDX);
75
+ const frame = Math.floor((sample / sampleRate) * fps);
76
+ const samplesPerFrame = sampleRate / fps;
77
+ return sample % samplesPerFrame > 0 || sample > (frame + 1) * samplesPerFrame;
78
+ },
79
+ drift() {
80
+ const sample = Atomics.load(i32, SAMPLE_COUNTER_IDX);
81
+ const exactFrame = (sample / sampleRate) * fps;
82
+ const currentFrame = Math.floor(exactFrame);
83
+ return exactFrame - currentFrame;
84
+ },
85
+ reset() {
86
+ Atomics.store(i32, SAMPLE_COUNTER_IDX, 0);
87
+ Atomics.store(i32, RUNNING_FLAG_IDX, 0);
88
+ f64[START_TIMESTAMP_F64_IDX] = 0;
89
+ },
90
+ };
91
+ }
92
+ /**
93
+ * AVBridge -- SharedArrayBuffer-based timeline bridge for audio/video convergence.
94
+ * Provides atomic sample counting shared between AudioWorklet and visual compositor.
95
+ *
96
+ * @example
97
+ * ```ts
98
+ * const bridge = AVBridge.make({ sampleRate: 44100, fps: 30 });
99
+ * bridge.setRunning(true);
100
+ * bridge.advanceSamples(1470); // advance by one video frame worth of samples
101
+ * bridge.getCurrentFrame(); // 1
102
+ * bridge.sampleToTime(44100); // 1.0 (seconds)
103
+ * bridge.timeToSample(0.5); // 22050
104
+ * ```
105
+ */
106
+ export const AVBridge = { make: _make };
107
+ //# sourceMappingURL=av-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"av-bridge.js","sourceRoot":"","sources":["../src/av-bridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * AVRenderer -- deterministic offline A/V renderer.
3
+ *
4
+ * Steps through audio samples and visual frames in lockstep.
5
+ * Each video frame knows its exact audio position. No wall-clock
6
+ * dependency -- fully deterministic.
7
+ *
8
+ * @module
9
+ */
10
+ import type { CompositeState } from './compositor.js';
11
+ import type { Compositor } from './compositor.js';
12
+ import { AVBridge } from './av-bridge.js';
13
+ import type { Millis } from './brands.js';
14
+ interface AVRenderConfig {
15
+ readonly sampleRate: number;
16
+ readonly fps: number;
17
+ readonly durationMs: Millis;
18
+ }
19
+ interface AVFrameOutput {
20
+ readonly frame: number;
21
+ readonly timestamp: number;
22
+ readonly sample: number;
23
+ readonly sampleCount: number;
24
+ readonly state: CompositeState;
25
+ }
26
+ interface AVRendererShape {
27
+ readonly config: AVRenderConfig;
28
+ readonly bridge: AVBridge.Shape;
29
+ readonly totalFrames: number;
30
+ frames(options?: {
31
+ onAudioFrame?: (sample: number, sampleCount: number) => void;
32
+ onVideoFrame?: (frame: number, timestamp: number, state: CompositeState) => void;
33
+ }): AsyncGenerator<AVFrameOutput>;
34
+ }
35
+ declare function _make(config: AVRenderConfig, compositor: Compositor.Shape, existingBridge?: AVBridge.Shape): AVRendererShape;
36
+ /**
37
+ * AVRenderer — deterministic offline audio+video renderer.
38
+ *
39
+ * Steps an {@link AVBridge} in lockstep with a {@link Compositor} so every
40
+ * video frame carries the exact sample offset it corresponds to. Pure clock
41
+ * math — no wall-clock input, reproducible across runs.
42
+ */
43
+ export declare const AVRenderer: {
44
+ /** Create a renderer bound to a compositor, optionally reusing an existing {@link AVBridge}. */
45
+ make: typeof _make;
46
+ };
47
+ export declare namespace AVRenderer {
48
+ /** Structural shape of a renderer instance returned by {@link AVRenderer.make}. */
49
+ type Shape = AVRendererShape;
50
+ /** Configuration accepted by {@link AVRenderer.make}. */
51
+ type Config = AVRenderConfig;
52
+ /** Per-frame output yielded by the async iterator. */
53
+ type FrameOutput = AVFrameOutput;
54
+ }
55
+ export {};
56
+ //# sourceMappingURL=av-renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"av-renderer.d.ts","sourceRoot":"","sources":["../src/av-renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAO1C,UAAU,cAAc;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,UAAU,aAAa;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;CAChC;AAED,UAAU,eAAe;IACvB,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,MAAM,CAAC,OAAO,CAAC,EAAE;QACf,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;QAC7D,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;KAClF,GAAG,cAAc,CAAC,aAAa,CAAC,CAAC;CACnC;AAMD,iBAAS,KAAK,CAAC,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,UAAU,CAAC,KAAK,EAAE,cAAc,CAAC,EAAE,QAAQ,CAAC,KAAK,GAAG,eAAe,CAgDrH;AAED;;;;;;GAMG;AACH,eAAO,MAAM,UAAU;IACrB,gGAAgG;;CAEjG,CAAC;AAEF,MAAM,CAAC,OAAO,WAAW,UAAU,CAAC;IAClC,mFAAmF;IACnF,KAAY,KAAK,GAAG,eAAe,CAAC;IACpC,yDAAyD;IACzD,KAAY,MAAM,GAAG,cAAc,CAAC;IACpC,sDAAsD;IACtD,KAAY,WAAW,GAAG,aAAa,CAAC;CACzC"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * AVRenderer -- deterministic offline A/V renderer.
3
+ *
4
+ * Steps through audio samples and visual frames in lockstep.
5
+ * Each video frame knows its exact audio position. No wall-clock
6
+ * dependency -- fully deterministic.
7
+ *
8
+ * @module
9
+ */
10
+ import { AVBridge } from './av-bridge.js';
11
+ import { Effect } from 'effect';
12
+ // ---------------------------------------------------------------------------
13
+ // Factory
14
+ // ---------------------------------------------------------------------------
15
+ function _make(config, compositor, existingBridge) {
16
+ const { sampleRate, fps, durationMs } = config;
17
+ const totalFrames = Math.ceil((durationMs / 1000) * fps);
18
+ const samplesPerFrame = Math.round(sampleRate / fps);
19
+ const bridge = existingBridge ?? AVBridge.make({ sampleRate, fps });
20
+ bridge.reset();
21
+ return {
22
+ config,
23
+ bridge,
24
+ totalFrames,
25
+ async *frames(options) {
26
+ const { onAudioFrame, onVideoFrame } = options ?? {};
27
+ for (let i = 0; i < totalFrames; i++) {
28
+ const targetSample = (i + 1) * samplesPerFrame;
29
+ const currentSample = bridge.getCurrentSample();
30
+ const advance = targetSample - currentSample;
31
+ if (advance > 0) {
32
+ bridge.advanceSamples(advance);
33
+ }
34
+ const frameSample = i * samplesPerFrame;
35
+ const timestamp = (i * 1000) / fps;
36
+ if (onAudioFrame) {
37
+ onAudioFrame(frameSample, samplesPerFrame);
38
+ }
39
+ const state = await Effect.runPromise(compositor.compute());
40
+ if (onVideoFrame) {
41
+ onVideoFrame(i, timestamp, state);
42
+ }
43
+ yield {
44
+ frame: i,
45
+ timestamp,
46
+ sample: frameSample,
47
+ sampleCount: samplesPerFrame,
48
+ state,
49
+ };
50
+ }
51
+ },
52
+ };
53
+ }
54
+ /**
55
+ * AVRenderer — deterministic offline audio+video renderer.
56
+ *
57
+ * Steps an {@link AVBridge} in lockstep with a {@link Compositor} so every
58
+ * video frame carries the exact sample offset it corresponds to. Pure clock
59
+ * math — no wall-clock input, reproducible across runs.
60
+ */
61
+ export const AVRenderer = {
62
+ /** Create a renderer bound to a compositor, optionally reusing an existing {@link AVBridge}. */
63
+ make: _make,
64
+ };
65
+ //# sourceMappingURL=av-renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"av-renderer.js","sourceRoot":"","sources":["../src/av-renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AA8BhC,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,SAAS,KAAK,CAAC,MAAsB,EAAE,UAA4B,EAAE,cAA+B;IAClG,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,MAAM,CAAC;IAC/C,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;IACzD,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC;IAErD,MAAM,MAAM,GAAG,cAAc,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;IACpE,MAAM,CAAC,KAAK,EAAE,CAAC;IAEf,OAAO;QACL,MAAM;QACN,MAAM;QACN,WAAW;QAEX,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO;YACnB,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,OAAO,IAAI,EAAE,CAAC;YAErD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;gBACrC,MAAM,YAAY,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,eAAe,CAAC;gBAC/C,MAAM,aAAa,GAAG,MAAM,CAAC,gBAAgB,EAAE,CAAC;gBAChD,MAAM,OAAO,GAAG,YAAY,GAAG,aAAa,CAAC;gBAE7C,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;oBAChB,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;gBACjC,CAAC;gBAED,MAAM,WAAW,GAAG,CAAC,GAAG,eAAe,CAAC;gBACxC,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC;gBAEnC,IAAI,YAAY,EAAE,CAAC;oBACjB,YAAY,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;gBAC7C,CAAC;gBAED,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;gBAE5D,IAAI,YAAY,EAAE,CAAC;oBACjB,YAAY,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;gBACpC,CAAC;gBAED,MAAM;oBACJ,KAAK,EAAE,CAAC;oBACR,SAAS;oBACT,MAAM,EAAE,WAAW;oBACnB,WAAW,EAAE,eAAe;oBAC5B,KAAK;iBACN,CAAC;YACJ,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,gGAAgG;IAChG,IAAI,EAAE,KAAK;CACZ,CAAC"}