@hypit/hypit 0.0.1 → 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 (962) hide show
  1. package/LICENSE +26 -0
  2. package/README.md +203 -0
  3. package/README.zh-CN.md +195 -0
  4. package/bin/hypit.mjs +46 -0
  5. package/dist/public/artifact.d.ts +75 -0
  6. package/dist/public/author-kit.d.ts +559 -0
  7. package/dist/public/browser-capture.d.ts +56 -0
  8. package/dist/public/caption.d.ts +751 -0
  9. package/dist/public/composition.d.ts +672 -0
  10. package/dist/public/endpoint-kit.d.ts +366 -0
  11. package/dist/public/generation.d.ts +591 -0
  12. package/dist/public/hyperframes.d.ts +774 -0
  13. package/dist/public/media.d.ts +708 -0
  14. package/dist/public/model-kit.d.ts +523 -0
  15. package/dist/public/narrative.d.ts +315 -0
  16. package/dist/public/program-space.d.ts +193 -0
  17. package/dist/public/runtime-kit.d.ts +427 -0
  18. package/dist/public/semantic-track.d.ts +418 -0
  19. package/dist/public/spatial.d.ts +1193 -0
  20. package/dist/public/speech.d.ts +391 -0
  21. package/dist/public/studio-adapter.d.ts +686 -0
  22. package/dist/public/svs.d.ts +311 -0
  23. package/dist/public/temporal-markup.d.ts +343 -0
  24. package/dist/public/temporal.d.ts +497 -0
  25. package/dist/public/text.d.ts +817 -0
  26. package/dist/public/visual-ir.d.ts +98 -0
  27. package/docs/public/hypit-logo-dark.svg +36 -0
  28. package/docs/public/hypit-logo-light.svg +38 -0
  29. package/examples/README.md +24 -0
  30. package/examples/minimal-author-package/README.md +18 -0
  31. package/examples/minimal-author-package/packages/example-component/README.md +44 -0
  32. package/examples/minimal-author-package/packages/example-component/package.json +27 -0
  33. package/examples/minimal-author-package/packages/example-component/preview/Box.png +0 -0
  34. package/examples/minimal-author-package/packages/example-component/preview/build.svrun +6 -0
  35. package/examples/minimal-author-package/packages/example-component/preview/preview.svml +47 -0
  36. package/examples/minimal-author-package/packages/example-component/preview/recipes.svs +8 -0
  37. package/examples/minimal-author-package/packages/example-component/src/activation.ts +10 -0
  38. package/examples/minimal-author-package/packages/example-component/src/component.ts +44 -0
  39. package/examples/minimal-author-package/packages/example-component/src/fragment.ts +32 -0
  40. package/examples/minimal-author-package/packages/example-component/src/index.ts +6 -0
  41. package/examples/minimal-author-package/packages/example-component/src/manifest.ts +82 -0
  42. package/examples/minimal-author-package/packages/example-component/src/style.ts +13 -0
  43. package/examples/minimal-author-package/packages/example-component/src/surface.ts +41 -0
  44. package/examples/minimal-author-package/packages/example-component/src/temporal.ts +6 -0
  45. package/examples/minimal-author-package/packages/example-component/tsconfig.json +18 -0
  46. package/examples/semantic-composition/README.md +35 -0
  47. package/examples/semantic-composition/chat.svml +25 -0
  48. package/examples/semantic-composition/chat.svrun +6 -0
  49. package/examples/semantic-composition/chat.svs +4 -0
  50. package/examples/semantic-composition/hypit.runtime.json +8 -0
  51. package/examples/semantic-composition/packages/chat-scene/README.md +29 -0
  52. package/examples/semantic-composition/packages/chat-scene/package.json +11 -0
  53. package/examples/semantic-composition/packages/chat-scene/src/activation.ts +112 -0
  54. package/examples/semantic-composition/packages/chat-scene/src/render.ts +64 -0
  55. package/examples/semantic-composition/packages/chat-scene/tsconfig.json +18 -0
  56. package/examples/semantic-composition/packages/responsive-explainer/README.md +45 -0
  57. package/examples/semantic-composition/packages/responsive-explainer/package.json +11 -0
  58. package/examples/semantic-composition/packages/responsive-explainer/src/activation.ts +90 -0
  59. package/examples/semantic-composition/packages/responsive-explainer/src/render.ts +68 -0
  60. package/examples/semantic-composition/packages/responsive-explainer/tsconfig.json +18 -0
  61. package/package.json +259 -7
  62. package/packages/artifact/README.md +10 -0
  63. package/packages/artifact/package.json +16 -0
  64. package/packages/artifact/src/activation.ts +8 -0
  65. package/packages/artifact/src/index.ts +24 -0
  66. package/packages/audio-track/README.md +43 -0
  67. package/packages/audio-track/package.json +36 -0
  68. package/packages/audio-track/src/activation.ts +20 -0
  69. package/packages/audio-track/src/component.ts +40 -0
  70. package/packages/audio-track/src/fragment.ts +63 -0
  71. package/packages/audio-track/src/index.ts +7 -0
  72. package/packages/audio-track/src/manifest.ts +151 -0
  73. package/packages/audio-track/src/program.ts +254 -0
  74. package/packages/audio-track/src/surface.ts +187 -0
  75. package/packages/audio-track/src/types.ts +62 -0
  76. package/packages/audio-track-studio/README.md +3 -0
  77. package/packages/audio-track-studio/package.json +14 -0
  78. package/packages/audio-track-studio/src/activation.ts +7 -0
  79. package/packages/audio-track-studio/src/index.ts +72 -0
  80. package/packages/author-kit/README.md +31 -0
  81. package/packages/author-kit/package.json +16 -0
  82. package/packages/author-kit/src/index.ts +59 -0
  83. package/packages/background-removal/README.md +29 -0
  84. package/packages/background-removal/package.json +16 -0
  85. package/packages/background-removal/src/activation.ts +18 -0
  86. package/packages/background-removal/src/component.ts +32 -0
  87. package/packages/background-removal/src/fragment.ts +18 -0
  88. package/packages/background-removal/src/index.ts +6 -0
  89. package/packages/background-removal/src/manifest.ts +45 -0
  90. package/packages/background-removal/src/program.ts +19 -0
  91. package/packages/background-removal/src/surface.ts +27 -0
  92. package/packages/background-removal/src/types.ts +5 -0
  93. package/packages/browser-capture/README.md +82 -0
  94. package/packages/browser-capture/package.json +15 -0
  95. package/packages/browser-capture/src/browser.ts +19 -0
  96. package/packages/browser-capture/src/index.ts +198 -0
  97. package/packages/build-result/package.json +13 -0
  98. package/packages/build-result/src/decode.ts +286 -0
  99. package/packages/build-result/src/index.ts +25 -0
  100. package/packages/build-result/src/store.ts +505 -0
  101. package/packages/build-result/src/types.ts +354 -0
  102. package/packages/build-result/src/writer.ts +184 -0
  103. package/packages/build-result-fs/README.md +29 -0
  104. package/packages/build-result-fs/package.json +17 -0
  105. package/packages/build-result-fs/src/activation.ts +62 -0
  106. package/packages/build-result-fs/src/index.ts +1 -0
  107. package/packages/build-result-kit/README.md +10 -0
  108. package/packages/build-result-kit/package.json +15 -0
  109. package/packages/build-result-kit/src/index.ts +144 -0
  110. package/packages/build-result-s3/README.md +49 -0
  111. package/packages/build-result-s3/package.json +19 -0
  112. package/packages/build-result-s3/src/activation.ts +71 -0
  113. package/packages/build-result-s3/src/client.ts +254 -0
  114. package/packages/build-result-s3/src/index.ts +4 -0
  115. package/packages/build-result-s3/src/repository.ts +361 -0
  116. package/packages/caption/README.md +77 -0
  117. package/packages/caption/package.json +28 -0
  118. package/packages/caption/src/activation.ts +17 -0
  119. package/packages/caption/src/component.ts +38 -0
  120. package/packages/caption/src/display.ts +111 -0
  121. package/packages/caption/src/error.ts +9 -0
  122. package/packages/caption/src/fragment.ts +26 -0
  123. package/packages/caption/src/index.ts +33 -0
  124. package/packages/caption/src/manifest.ts +97 -0
  125. package/packages/caption/src/style.ts +170 -0
  126. package/packages/caption/src/surface.ts +96 -0
  127. package/packages/caption/src/temporalize.ts +124 -0
  128. package/packages/caption/src/types.ts +71 -0
  129. package/packages/caption-fine/README.md +108 -0
  130. package/packages/caption-fine/package.json +30 -0
  131. package/packages/caption-fine/preview/Track.png +0 -0
  132. package/packages/caption-fine/src/activation.ts +32 -0
  133. package/packages/caption-fine/src/component.ts +58 -0
  134. package/packages/caption-fine/src/fragment.ts +112 -0
  135. package/packages/caption-fine/src/index.ts +19 -0
  136. package/packages/caption-fine/src/manifest.ts +383 -0
  137. package/packages/caption-fine/src/recipe.ts +120 -0
  138. package/packages/caption-fine/src/render.ts +1133 -0
  139. package/packages/caption-fine/src/schedule.ts +126 -0
  140. package/packages/caption-fine/src/spacing.ts +69 -0
  141. package/packages/caption-fine/src/style.ts +370 -0
  142. package/packages/caption-fine/src/surface.ts +152 -0
  143. package/packages/caption-fine/src/types.ts +191 -0
  144. package/packages/caption-fine-studio/README.md +3 -0
  145. package/packages/caption-fine-studio/package.json +15 -0
  146. package/packages/caption-fine-studio/src/activation.ts +7 -0
  147. package/packages/caption-fine-studio/src/index.ts +163 -0
  148. package/packages/cli/README.md +51 -0
  149. package/packages/cli/package.json +33 -0
  150. package/packages/cli/src/arguments.ts +605 -0
  151. package/packages/cli/src/build-planning.ts +460 -0
  152. package/packages/cli/src/command.ts +202 -0
  153. package/packages/cli/src/commands/environment.ts +391 -0
  154. package/packages/cli/src/commands/execution.ts +321 -0
  155. package/packages/cli/src/commands/results.ts +187 -0
  156. package/packages/cli/src/commands/types.ts +9 -0
  157. package/packages/cli/src/distribution.ts +74 -0
  158. package/packages/cli/src/index.ts +30 -0
  159. package/packages/cli/src/machine-view.ts +28 -0
  160. package/packages/cli/src/main.ts +654 -0
  161. package/packages/cli/src/oauth.ts +228 -0
  162. package/packages/cli/src/observation.ts +203 -0
  163. package/packages/cli/src/output.ts +1007 -0
  164. package/packages/cli/src/paths.ts +7 -0
  165. package/packages/cli/src/project-context.ts +38 -0
  166. package/packages/cli/src/reachability.ts +91 -0
  167. package/packages/cli/src/result-export.ts +148 -0
  168. package/packages/cli/src/result-query.ts +46 -0
  169. package/packages/cli/src/run-file.ts +186 -0
  170. package/packages/cli/src/runtime-port.ts +13 -0
  171. package/packages/cli/src/runtime-selection.ts +94 -0
  172. package/packages/cli/src/runtime-view.ts +15 -0
  173. package/packages/cli/src/source-discovery.ts +150 -0
  174. package/packages/cli/src/source-packages.ts +91 -0
  175. package/packages/cli/src/view.ts +228 -0
  176. package/packages/comment-sticker/README.md +41 -0
  177. package/packages/comment-sticker/package.json +29 -0
  178. package/packages/comment-sticker/preview/Track.png +0 -0
  179. package/packages/comment-sticker/src/activation.ts +32 -0
  180. package/packages/comment-sticker/src/author.ts +148 -0
  181. package/packages/comment-sticker/src/component.ts +97 -0
  182. package/packages/comment-sticker/src/fragment.ts +124 -0
  183. package/packages/comment-sticker/src/index.ts +8 -0
  184. package/packages/comment-sticker/src/manifest.ts +373 -0
  185. package/packages/comment-sticker/src/program.ts +610 -0
  186. package/packages/comment-sticker/src/surface.ts +172 -0
  187. package/packages/comment-sticker/src/types.ts +109 -0
  188. package/packages/comment-sticker-studio/README.md +3 -0
  189. package/packages/comment-sticker-studio/package.json +14 -0
  190. package/packages/comment-sticker-studio/src/activation.ts +7 -0
  191. package/packages/comment-sticker-studio/src/index.ts +132 -0
  192. package/packages/compiler-markup-node/README.md +12 -0
  193. package/packages/compiler-markup-node/package.json +22 -0
  194. package/packages/compiler-markup-node/src/index.ts +59 -0
  195. package/packages/compiler-node/README.md +60 -0
  196. package/packages/compiler-node/package.json +25 -0
  197. package/packages/compiler-node/src/compiler.ts +207 -0
  198. package/packages/compiler-node/src/error.ts +11 -0
  199. package/packages/compiler-node/src/graph-query.ts +51 -0
  200. package/packages/compiler-node/src/index.ts +27 -0
  201. package/packages/compiler-node/src/modules.ts +107 -0
  202. package/packages/compiler-node/src/run.ts +355 -0
  203. package/packages/component-kit/README.md +97 -0
  204. package/packages/component-kit/package.json +13 -0
  205. package/packages/component-kit/src/index.ts +155 -0
  206. package/packages/composition/README.md +53 -0
  207. package/packages/composition/package.json +29 -0
  208. package/packages/composition/src/activation.ts +3 -0
  209. package/packages/composition/src/component.ts +10 -0
  210. package/packages/composition/src/index.ts +18 -0
  211. package/packages/composition/src/manifest.ts +13 -0
  212. package/packages/composition/src/schema.ts +194 -0
  213. package/packages/composition/src/track.ts +1403 -0
  214. package/packages/core/README.md +22 -0
  215. package/packages/core/package.json +13 -0
  216. package/packages/core/src/error.ts +12 -0
  217. package/packages/core/src/graph.ts +341 -0
  218. package/packages/core/src/index.ts +32 -0
  219. package/packages/core/src/link.ts +240 -0
  220. package/packages/core/src/machine.ts +60 -0
  221. package/packages/core/src/plan.ts +504 -0
  222. package/packages/core/src/reducer.ts +428 -0
  223. package/packages/core/src/reference.ts +25 -0
  224. package/packages/core/src/slice.ts +108 -0
  225. package/packages/credential-store-env/README.md +11 -0
  226. package/packages/credential-store-env/package.json +17 -0
  227. package/packages/credential-store-env/src/activation.ts +25 -0
  228. package/packages/credential-store-env/src/index.ts +23 -0
  229. package/packages/credential-store-os/README.md +13 -0
  230. package/packages/credential-store-os/package.json +22 -0
  231. package/packages/credential-store-os/runtime/windows-credential.ps1 +59 -0
  232. package/packages/credential-store-os/src/activation.ts +32 -0
  233. package/packages/credential-store-os/src/index.ts +2 -0
  234. package/packages/credential-store-os/src/store.ts +196 -0
  235. package/packages/deck-track/README.md +52 -0
  236. package/packages/deck-track/package.json +35 -0
  237. package/packages/deck-track/preview/DepthStack.png +0 -0
  238. package/packages/deck-track/src/activation.ts +32 -0
  239. package/packages/deck-track/src/author.ts +217 -0
  240. package/packages/deck-track/src/component.ts +86 -0
  241. package/packages/deck-track/src/fragment.ts +148 -0
  242. package/packages/deck-track/src/index.ts +16 -0
  243. package/packages/deck-track/src/lower.ts +370 -0
  244. package/packages/deck-track/src/manifest.ts +438 -0
  245. package/packages/deck-track/src/program.ts +367 -0
  246. package/packages/deck-track/src/surface.ts +286 -0
  247. package/packages/deck-track/src/types.ts +119 -0
  248. package/packages/deck-track-studio/README.md +3 -0
  249. package/packages/deck-track-studio/package.json +14 -0
  250. package/packages/deck-track-studio/src/activation.ts +7 -0
  251. package/packages/deck-track-studio/src/index.ts +134 -0
  252. package/packages/driver-node/README.md +23 -0
  253. package/packages/driver-node/package.json +18 -0
  254. package/packages/driver-node/src/driver.ts +616 -0
  255. package/packages/driver-node/src/index.ts +10 -0
  256. package/packages/driver-node/src/planning.ts +67 -0
  257. package/packages/driver-node/src/registry.ts +234 -0
  258. package/packages/driver-node/src/resources.ts +36 -0
  259. package/packages/driver-node/src/types.ts +69 -0
  260. package/packages/elaborator/README.md +74 -0
  261. package/packages/elaborator/package.json +16 -0
  262. package/packages/elaborator/src/author.ts +308 -0
  263. package/packages/elaborator/src/fragment.ts +505 -0
  264. package/packages/elaborator/src/frontend-facet.ts +30 -0
  265. package/packages/elaborator/src/index.ts +78 -0
  266. package/packages/elaborator/src/source.ts +608 -0
  267. package/packages/endpoint-kit/README.md +111 -0
  268. package/packages/endpoint-kit/package.json +14 -0
  269. package/packages/endpoint-kit/src/index.ts +488 -0
  270. package/packages/estimate/README.md +32 -0
  271. package/packages/estimate/package.json +20 -0
  272. package/packages/estimate/src/activation.ts +11 -0
  273. package/packages/estimate/src/index.ts +16 -0
  274. package/packages/estimate/src/manifest.ts +34 -0
  275. package/packages/estimate/src/policy.ts +70 -0
  276. package/packages/estimate/src/program.ts +196 -0
  277. package/packages/estimate/src/types.ts +15 -0
  278. package/packages/film/README.md +49 -0
  279. package/packages/film/package.json +34 -0
  280. package/packages/film/src/activation.ts +16 -0
  281. package/packages/film/src/component.ts +61 -0
  282. package/packages/film/src/fragment.ts +83 -0
  283. package/packages/film/src/index.ts +11 -0
  284. package/packages/film/src/manifest.ts +152 -0
  285. package/packages/film/src/program.ts +110 -0
  286. package/packages/film/src/recipe.ts +24 -0
  287. package/packages/film/src/surface.ts +146 -0
  288. package/packages/film/src/types.ts +26 -0
  289. package/packages/film-studio/package.json +16 -0
  290. package/packages/film-studio/src/activation.ts +8 -0
  291. package/packages/film-studio/src/index.ts +17 -0
  292. package/packages/fonts-open/README.md +77 -0
  293. package/packages/fonts-open/package.json +130 -0
  294. package/packages/fonts-open/src/activation.ts +30 -0
  295. package/packages/fonts-open/src/catalog.ts +317 -0
  296. package/packages/fonts-open/src/index.ts +13 -0
  297. package/packages/fonts-open/src/manifest.ts +83 -0
  298. package/packages/fonts-open/src/surface.ts +239 -0
  299. package/packages/generation/README.md +19 -0
  300. package/packages/generation/package.json +23 -0
  301. package/packages/generation/src/activation.ts +9 -0
  302. package/packages/generation/src/component.ts +77 -0
  303. package/packages/generation/src/identity.ts +80 -0
  304. package/packages/generation/src/index.ts +79 -0
  305. package/packages/generation/src/manifest.ts +65 -0
  306. package/packages/generation/src/mapping.ts +231 -0
  307. package/packages/generation/src/ports.ts +222 -0
  308. package/packages/generation/src/request.ts +427 -0
  309. package/packages/generation/src/schema.ts +62 -0
  310. package/packages/generation/src/types.ts +17 -0
  311. package/packages/gpt-image/README.md +54 -0
  312. package/packages/gpt-image/package.json +34 -0
  313. package/packages/gpt-image/src/activation.ts +39 -0
  314. package/packages/gpt-image/src/fragment.ts +101 -0
  315. package/packages/gpt-image/src/index.ts +203 -0
  316. package/packages/gpt-image/src/surface.ts +194 -0
  317. package/packages/gpt-image-kits/README.md +44 -0
  318. package/packages/gpt-image-kits/kits/phone-ugc-v1.svs +34 -0
  319. package/packages/gpt-image-kits/package.json +15 -0
  320. package/packages/grok-imagine/README.md +21 -0
  321. package/packages/grok-imagine/package.json +21 -0
  322. package/packages/grok-imagine/src/activation.ts +29 -0
  323. package/packages/grok-imagine/src/index.ts +174 -0
  324. package/packages/grok-imagine/src/surface.ts +149 -0
  325. package/packages/host/README.md +5 -0
  326. package/packages/host/package.json +10 -0
  327. package/packages/host/src/facet.ts +6 -0
  328. package/packages/host/src/frontend.ts +56 -0
  329. package/packages/host/src/index.ts +9 -0
  330. package/packages/hyperframes/README.md +69 -0
  331. package/packages/hyperframes/package.json +36 -0
  332. package/packages/hyperframes/src/activation.ts +8 -0
  333. package/packages/hyperframes/src/browser-program.ts +79 -0
  334. package/packages/hyperframes/src/component.ts +32 -0
  335. package/packages/hyperframes/src/document.ts +827 -0
  336. package/packages/hyperframes/src/fragment.ts +32 -0
  337. package/packages/hyperframes/src/index.ts +13 -0
  338. package/packages/hyperframes/src/manifest.ts +67 -0
  339. package/packages/hyperframes/src/project.ts +118 -0
  340. package/packages/hyperframes/src/text.ts +1179 -0
  341. package/packages/hyperframes/src/types.ts +38 -0
  342. package/packages/image-compose/README.md +25 -0
  343. package/packages/image-compose/package.json +18 -0
  344. package/packages/image-compose/src/activation.ts +21 -0
  345. package/packages/image-compose/src/component.ts +100 -0
  346. package/packages/image-compose/src/fragment.ts +54 -0
  347. package/packages/image-compose/src/index.ts +10 -0
  348. package/packages/image-compose/src/manifest.ts +119 -0
  349. package/packages/image-compose/src/program.ts +75 -0
  350. package/packages/image-compose/src/surface.ts +83 -0
  351. package/packages/image-compose/src/types.ts +22 -0
  352. package/packages/image-transform/README.md +29 -0
  353. package/packages/image-transform/package.json +21 -0
  354. package/packages/image-transform/src/activation.ts +33 -0
  355. package/packages/image-transform/src/component.ts +67 -0
  356. package/packages/image-transform/src/fragment.ts +25 -0
  357. package/packages/image-transform/src/index.ts +13 -0
  358. package/packages/image-transform/src/manifest.ts +209 -0
  359. package/packages/image-transform/src/program.ts +23 -0
  360. package/packages/image-transform/src/surface.ts +216 -0
  361. package/packages/image-transform/src/types.ts +20 -0
  362. package/packages/interview-emoji-reveal/README.md +39 -0
  363. package/packages/interview-emoji-reveal/package.json +23 -0
  364. package/packages/interview-emoji-reveal/preview/Track.png +0 -0
  365. package/packages/interview-emoji-reveal/src/activation.ts +14 -0
  366. package/packages/interview-emoji-reveal/src/component.ts +45 -0
  367. package/packages/interview-emoji-reveal/src/fragment.ts +62 -0
  368. package/packages/interview-emoji-reveal/src/index.ts +16 -0
  369. package/packages/interview-emoji-reveal/src/manifest.ts +174 -0
  370. package/packages/interview-emoji-reveal/src/program.ts +242 -0
  371. package/packages/interview-emoji-reveal/src/style.ts +47 -0
  372. package/packages/interview-emoji-reveal/src/surface.ts +110 -0
  373. package/packages/interview-emoji-reveal/src/types.ts +52 -0
  374. package/packages/markup/README.md +81 -0
  375. package/packages/markup/package.json +16 -0
  376. package/packages/markup/src/element.ts +39 -0
  377. package/packages/markup/src/error.ts +20 -0
  378. package/packages/markup/src/frontend.ts +518 -0
  379. package/packages/markup/src/host-facet.ts +115 -0
  380. package/packages/markup/src/index.ts +25 -0
  381. package/packages/markup/src/registry.ts +83 -0
  382. package/packages/markup/src/syntax.ts +271 -0
  383. package/packages/markup/src/types.ts +246 -0
  384. package/packages/media/README.md +37 -0
  385. package/packages/media/package.json +19 -0
  386. package/packages/media/src/activation.ts +38 -0
  387. package/packages/media/src/component.ts +16 -0
  388. package/packages/media/src/frame-range.ts +33 -0
  389. package/packages/media/src/identity.ts +227 -0
  390. package/packages/media/src/index.ts +15 -0
  391. package/packages/media/src/manifest.ts +122 -0
  392. package/packages/media/src/render.ts +140 -0
  393. package/packages/media/src/schema.ts +69 -0
  394. package/packages/media/src/surface.ts +150 -0
  395. package/packages/media/src/types.ts +121 -0
  396. package/packages/media-execution/README.md +28 -0
  397. package/packages/media-execution/package.json +17 -0
  398. package/packages/media-execution/src/execute.ts +1322 -0
  399. package/packages/media-execution/src/index.ts +16 -0
  400. package/packages/media-execution/src/probe.ts +315 -0
  401. package/packages/media-execution/src/surface.ts +286 -0
  402. package/packages/media-execution/src/toolchain.ts +81 -0
  403. package/packages/media-execution/src/webp.ts +200 -0
  404. package/packages/media-pipeline/README.md +113 -0
  405. package/packages/media-pipeline/package.json +27 -0
  406. package/packages/media-pipeline/src/activation.ts +47 -0
  407. package/packages/media-pipeline/src/audio-plan.ts +113 -0
  408. package/packages/media-pipeline/src/component.ts +373 -0
  409. package/packages/media-pipeline/src/fragment.ts +167 -0
  410. package/packages/media-pipeline/src/index.ts +46 -0
  411. package/packages/media-pipeline/src/manifest.ts +653 -0
  412. package/packages/media-pipeline/src/operations.ts +248 -0
  413. package/packages/media-pipeline/src/selection.ts +110 -0
  414. package/packages/media-pipeline/src/surface.ts +389 -0
  415. package/packages/media-pipeline/src/types.ts +175 -0
  416. package/packages/media-track/README.md +197 -0
  417. package/packages/media-track/package.json +29 -0
  418. package/packages/media-track/preview/Track.png +0 -0
  419. package/packages/media-track/preview/build.svrun +5 -0
  420. package/packages/media-track/preview/flush.png +0 -0
  421. package/packages/media-track/preview/preview.svml +47 -0
  422. package/packages/media-track/preview/recipes.svs +23 -0
  423. package/packages/media-track/preview/rounded.png +0 -0
  424. package/packages/media-track/src/activation.ts +20 -0
  425. package/packages/media-track/src/author.ts +317 -0
  426. package/packages/media-track/src/component.ts +162 -0
  427. package/packages/media-track/src/fragment.ts +57 -0
  428. package/packages/media-track/src/index.ts +65 -0
  429. package/packages/media-track/src/layers.ts +308 -0
  430. package/packages/media-track/src/lower.ts +335 -0
  431. package/packages/media-track/src/manifest.ts +624 -0
  432. package/packages/media-track/src/motion.ts +387 -0
  433. package/packages/media-track/src/performance.ts +37 -0
  434. package/packages/media-track/src/presentation.ts +35 -0
  435. package/packages/media-track/src/program.ts +565 -0
  436. package/packages/media-track/src/sampling.ts +118 -0
  437. package/packages/media-track/src/sequence.ts +403 -0
  438. package/packages/media-track/src/sounds.ts +71 -0
  439. package/packages/media-track/src/surface.ts +668 -0
  440. package/packages/media-track/src/types.ts +311 -0
  441. package/packages/media-track-studio/README.md +3 -0
  442. package/packages/media-track-studio/package.json +15 -0
  443. package/packages/media-track-studio/src/activation.ts +7 -0
  444. package/packages/media-track-studio/src/index.ts +235 -0
  445. package/packages/mimo-speech/README.md +33 -0
  446. package/packages/mimo-speech/package.json +21 -0
  447. package/packages/mimo-speech/src/activation.ts +32 -0
  448. package/packages/mimo-speech/src/fragment.ts +11 -0
  449. package/packages/mimo-speech/src/index.ts +160 -0
  450. package/packages/mimo-speech/src/surface.ts +193 -0
  451. package/packages/minimax-h3/README.md +21 -0
  452. package/packages/minimax-h3/package.json +21 -0
  453. package/packages/minimax-h3/src/activation.ts +14 -0
  454. package/packages/minimax-h3/src/index.ts +188 -0
  455. package/packages/minimax-h3/src/surface.ts +87 -0
  456. package/packages/model-kit/README.md +52 -0
  457. package/packages/model-kit/package.json +19 -0
  458. package/packages/model-kit/src/index.ts +728 -0
  459. package/packages/nano-banana/README.md +23 -0
  460. package/packages/nano-banana/package.json +21 -0
  461. package/packages/nano-banana/src/activation.ts +14 -0
  462. package/packages/nano-banana/src/index.ts +172 -0
  463. package/packages/nano-banana/src/surface.ts +120 -0
  464. package/packages/narrative/README.md +7 -0
  465. package/packages/narrative/package.json +17 -0
  466. package/packages/narrative/src/activation.ts +7 -0
  467. package/packages/narrative/src/component.ts +33 -0
  468. package/packages/narrative/src/identity.ts +131 -0
  469. package/packages/narrative/src/index.ts +11 -0
  470. package/packages/narrative/src/manifest.ts +30 -0
  471. package/packages/narrative/src/schema.ts +89 -0
  472. package/packages/narrative/src/types.ts +141 -0
  473. package/packages/package-loader-node/README.md +23 -0
  474. package/packages/package-loader-node/package.json +15 -0
  475. package/packages/package-loader-node/src/contribution.ts +97 -0
  476. package/packages/package-loader-node/src/distribution-resolution.ts +146 -0
  477. package/packages/package-loader-node/src/index.ts +27 -0
  478. package/packages/package-loader-node/src/loader.ts +301 -0
  479. package/packages/package-loader-node/src/location.ts +279 -0
  480. package/packages/package-loader-node/src/types.ts +60 -0
  481. package/packages/program-space/README.md +20 -0
  482. package/packages/program-space/package.json +17 -0
  483. package/packages/program-space/src/activation.ts +19 -0
  484. package/packages/program-space/src/index.ts +107 -0
  485. package/packages/program-space/src/surface.ts +55 -0
  486. package/packages/protocol/README.md +11 -0
  487. package/packages/protocol/package.json +10 -0
  488. package/packages/protocol/src/build-id.ts +52 -0
  489. package/packages/protocol/src/build.ts +265 -0
  490. package/packages/protocol/src/canonical.ts +37 -0
  491. package/packages/protocol/src/error.ts +11 -0
  492. package/packages/protocol/src/identity.ts +59 -0
  493. package/packages/protocol/src/index.ts +9 -0
  494. package/packages/protocol/src/module.ts +67 -0
  495. package/packages/protocol/src/value.ts +88 -0
  496. package/packages/provider-hyperframes-aws-lambda/README.md +30 -0
  497. package/packages/provider-hyperframes-aws-lambda/package.json +30 -0
  498. package/packages/provider-hyperframes-aws-lambda/src/activation.ts +97 -0
  499. package/packages/provider-hyperframes-aws-lambda/src/client.ts +114 -0
  500. package/packages/provider-hyperframes-aws-lambda/src/index.ts +21 -0
  501. package/packages/provider-hyperframes-aws-lambda/src/provider.ts +522 -0
  502. package/packages/provider-hyperframes-local/README.md +129 -0
  503. package/packages/provider-hyperframes-local/package.json +34 -0
  504. package/packages/provider-hyperframes-local/src/activation.ts +107 -0
  505. package/packages/provider-hyperframes-local/src/capture-process.ts +110 -0
  506. package/packages/provider-hyperframes-local/src/capture-worker.ts +17 -0
  507. package/packages/provider-hyperframes-local/src/capture.ts +184 -0
  508. package/packages/provider-hyperframes-local/src/index.ts +10 -0
  509. package/packages/provider-hyperframes-local/src/options.ts +19 -0
  510. package/packages/provider-hyperframes-local/src/output.ts +73 -0
  511. package/packages/provider-hyperframes-local/src/process.ts +83 -0
  512. package/packages/provider-hyperframes-local/src/program.ts +58 -0
  513. package/packages/provider-hyperframes-local/src/provider.ts +62 -0
  514. package/packages/provider-hyperframes-local/src/render.ts +114 -0
  515. package/packages/provider-hyperframes-local/src/sampling.ts +89 -0
  516. package/packages/provider-hypihub/README.md +143 -0
  517. package/packages/provider-hypihub/package.json +26 -0
  518. package/packages/provider-hypihub/src/activation.ts +91 -0
  519. package/packages/provider-hypihub/src/index.ts +2 -0
  520. package/packages/provider-hypihub/src/mapping.ts +145 -0
  521. package/packages/provider-hypihub/src/oauth.ts +113 -0
  522. package/packages/provider-hypihub/src/provider.ts +566 -0
  523. package/packages/provider-hypihub/src/routes.ts +134 -0
  524. package/packages/provider-hypihub/src/upload.ts +402 -0
  525. package/packages/provider-image-opencv-local/README.md +16 -0
  526. package/packages/provider-image-opencv-local/package.json +27 -0
  527. package/packages/provider-image-opencv-local/runtime/raster_execute.py +299 -0
  528. package/packages/provider-image-opencv-local/src/activation.ts +61 -0
  529. package/packages/provider-image-opencv-local/src/deployment.ts +68 -0
  530. package/packages/provider-image-opencv-local/src/index.ts +2 -0
  531. package/packages/provider-image-opencv-local/src/program.ts +60 -0
  532. package/packages/provider-image-opencv-local/src/provider.ts +155 -0
  533. package/packages/provider-kie/README.md +134 -0
  534. package/packages/provider-kie/package.json +43 -0
  535. package/packages/provider-kie/src/activation.ts +71 -0
  536. package/packages/provider-kie/src/index.ts +10 -0
  537. package/packages/provider-kie/src/mapping.ts +182 -0
  538. package/packages/provider-kie/src/provider.ts +657 -0
  539. package/packages/provider-kie/src/routes.ts +150 -0
  540. package/packages/provider-media-local/README.md +58 -0
  541. package/packages/provider-media-local/package.json +28 -0
  542. package/packages/provider-media-local/src/activation.ts +65 -0
  543. package/packages/provider-media-local/src/index.ts +2 -0
  544. package/packages/provider-media-local/src/program.ts +19 -0
  545. package/packages/provider-media-local/src/provider.ts +150 -0
  546. package/packages/provider-whisperx-local/README.md +44 -0
  547. package/packages/provider-whisperx-local/package.json +27 -0
  548. package/packages/provider-whisperx-local/src/activation.ts +93 -0
  549. package/packages/provider-whisperx-local/src/index.ts +5 -0
  550. package/packages/provider-whisperx-local/src/program.ts +157 -0
  551. package/packages/provider-whisperx-local/src/provider.ts +191 -0
  552. package/packages/provider-xiaomi-mimo/README.md +32 -0
  553. package/packages/provider-xiaomi-mimo/package.json +24 -0
  554. package/packages/provider-xiaomi-mimo/src/activation.ts +57 -0
  555. package/packages/provider-xiaomi-mimo/src/index.ts +5 -0
  556. package/packages/provider-xiaomi-mimo/src/provider.ts +214 -0
  557. package/packages/ranking/README.md +67 -0
  558. package/packages/ranking/package.json +33 -0
  559. package/packages/ranking/preview/Column.svg +29 -0
  560. package/packages/ranking/preview/TierBoard.png +0 -0
  561. package/packages/ranking/preview/TierBoard.svg +36 -0
  562. package/packages/ranking/preview/TopThree.png +0 -0
  563. package/packages/ranking/src/activation.ts +38 -0
  564. package/packages/ranking/src/component.ts +271 -0
  565. package/packages/ranking/src/fragment.ts +206 -0
  566. package/packages/ranking/src/index.ts +26 -0
  567. package/packages/ranking/src/manifest.ts +807 -0
  568. package/packages/ranking/src/render.ts +698 -0
  569. package/packages/ranking/src/schedule.ts +895 -0
  570. package/packages/ranking/src/style.ts +272 -0
  571. package/packages/ranking/src/surface.ts +322 -0
  572. package/packages/ranking/src/tier.ts +176 -0
  573. package/packages/ranking/src/types.ts +277 -0
  574. package/packages/ranking-studio/README.md +3 -0
  575. package/packages/ranking-studio/package.json +14 -0
  576. package/packages/ranking-studio/src/activation.ts +7 -0
  577. package/packages/ranking-studio/src/index.ts +255 -0
  578. package/packages/raster/README.md +7 -0
  579. package/packages/raster/package.json +14 -0
  580. package/packages/raster/src/activation.ts +7 -0
  581. package/packages/raster/src/index.ts +7 -0
  582. package/packages/raster/src/manifest.ts +14 -0
  583. package/packages/raster/src/program.ts +128 -0
  584. package/packages/raster/src/schema.ts +53 -0
  585. package/packages/raster/src/types.ts +61 -0
  586. package/packages/render-hyperframes/README.md +58 -0
  587. package/packages/render-hyperframes/package.json +33 -0
  588. package/packages/render-hyperframes/src/activation.ts +18 -0
  589. package/packages/render-hyperframes/src/component.ts +37 -0
  590. package/packages/render-hyperframes/src/fragment.ts +73 -0
  591. package/packages/render-hyperframes/src/index.ts +6 -0
  592. package/packages/render-hyperframes/src/manifest.ts +100 -0
  593. package/packages/render-hyperframes/src/product.ts +29 -0
  594. package/packages/render-hyperframes/src/surface.ts +65 -0
  595. package/packages/resource-store-fs/README.md +13 -0
  596. package/packages/resource-store-fs/package.json +14 -0
  597. package/packages/resource-store-fs/src/index.ts +2 -0
  598. package/packages/resource-store-fs/src/store.ts +154 -0
  599. package/packages/resource-store-s3/README.md +15 -0
  600. package/packages/resource-store-s3/package.json +15 -0
  601. package/packages/resource-store-s3/src/client.ts +138 -0
  602. package/packages/resource-store-s3/src/index.ts +10 -0
  603. package/packages/resource-store-s3/src/store.ts +258 -0
  604. package/packages/run/README.md +23 -0
  605. package/packages/run/package.json +16 -0
  606. package/packages/run/src/candidate.ts +33 -0
  607. package/packages/run/src/facet.ts +59 -0
  608. package/packages/run/src/frontend-facet.ts +23 -0
  609. package/packages/run/src/frontend.ts +62 -0
  610. package/packages/run/src/graph.ts +65 -0
  611. package/packages/run/src/index.ts +33 -0
  612. package/packages/run/src/registry.ts +24 -0
  613. package/packages/run/src/resolve.ts +213 -0
  614. package/packages/run/src/types.ts +147 -0
  615. package/packages/run-markup/README.md +60 -0
  616. package/packages/run-markup/package.json +22 -0
  617. package/packages/run-markup/src/activation.ts +10 -0
  618. package/packages/run-markup/src/frontend.ts +16 -0
  619. package/packages/run-markup/src/index.ts +5 -0
  620. package/packages/run-markup/src/syntax.ts +304 -0
  621. package/packages/runtime/README.md +39 -0
  622. package/packages/runtime/package.json +15 -0
  623. package/packages/runtime/src/capacity.ts +51 -0
  624. package/packages/runtime/src/catalog.ts +30 -0
  625. package/packages/runtime/src/credentials.ts +124 -0
  626. package/packages/runtime/src/environment.ts +6 -0
  627. package/packages/runtime/src/execution.ts +125 -0
  628. package/packages/runtime/src/index.ts +24 -0
  629. package/packages/runtime/src/operations.ts +99 -0
  630. package/packages/runtime/src/scheduler.ts +281 -0
  631. package/packages/runtime/src/submission.ts +24 -0
  632. package/packages/runtime/src/types.ts +157 -0
  633. package/packages/runtime-host-node/README.md +25 -0
  634. package/packages/runtime-host-node/package.json +19 -0
  635. package/packages/runtime-host-node/src/index.ts +421 -0
  636. package/packages/runtime-host-node/src/packages.ts +158 -0
  637. package/packages/runtime-kit/README.md +42 -0
  638. package/packages/runtime-kit/package.json +16 -0
  639. package/packages/runtime-kit/src/index.ts +307 -0
  640. package/packages/runtime-kit/src/request-deadline.ts +17 -0
  641. package/packages/runtime-local/README.md +119 -0
  642. package/packages/runtime-local/package.json +33 -0
  643. package/packages/runtime-local/src/actions.ts +20 -0
  644. package/packages/runtime-local/src/config.ts +1229 -0
  645. package/packages/runtime-local/src/control.ts +120 -0
  646. package/packages/runtime-local/src/credentials.ts +61 -0
  647. package/packages/runtime-local/src/host.ts +174 -0
  648. package/packages/runtime-local/src/index.ts +36 -0
  649. package/packages/runtime-local/src/process-control.ts +59 -0
  650. package/packages/runtime-local/src/process-logs.ts +33 -0
  651. package/packages/runtime-local/src/programs.ts +441 -0
  652. package/packages/runtime-local/src/result-writer.ts +246 -0
  653. package/packages/runtime-local/src/runtime.ts +342 -0
  654. package/packages/runtime-local/src/types.ts +100 -0
  655. package/packages/runtime-local/src/worker-process.ts +343 -0
  656. package/packages/runtime-local/src/worker.ts +449 -0
  657. package/packages/screen-overlay/README.md +17 -0
  658. package/packages/screen-overlay/package.json +31 -0
  659. package/packages/screen-overlay/preview/Track.png +0 -0
  660. package/packages/screen-overlay/src/activation.ts +15 -0
  661. package/packages/screen-overlay/src/component.ts +20 -0
  662. package/packages/screen-overlay/src/fragment.ts +40 -0
  663. package/packages/screen-overlay/src/index.ts +7 -0
  664. package/packages/screen-overlay/src/manifest.ts +305 -0
  665. package/packages/screen-overlay/src/program.ts +321 -0
  666. package/packages/screen-overlay/src/surface.ts +90 -0
  667. package/packages/screen-overlay/src/types.ts +69 -0
  668. package/packages/screen-overlay-studio/README.md +3 -0
  669. package/packages/screen-overlay-studio/package.json +14 -0
  670. package/packages/screen-overlay-studio/src/activation.ts +7 -0
  671. package/packages/screen-overlay-studio/src/index.ts +80 -0
  672. package/packages/script/README.md +137 -0
  673. package/packages/script/package.json +22 -0
  674. package/packages/script/src/activation.ts +20 -0
  675. package/packages/script/src/edit.ts +174 -0
  676. package/packages/script/src/error.ts +13 -0
  677. package/packages/script/src/format.ts +83 -0
  678. package/packages/script/src/index.ts +20 -0
  679. package/packages/script/src/lexical.ts +133 -0
  680. package/packages/script/src/manifest.ts +95 -0
  681. package/packages/script/src/narrative.ts +232 -0
  682. package/packages/script/src/parser.ts +850 -0
  683. package/packages/script/src/surface.ts +132 -0
  684. package/packages/script/src/types.ts +125 -0
  685. package/packages/script-studio/package.json +13 -0
  686. package/packages/script-studio/src/activation.ts +8 -0
  687. package/packages/script-studio/src/index.ts +61 -0
  688. package/packages/seedance/README.md +19 -0
  689. package/packages/seedance/package.json +22 -0
  690. package/packages/seedance/src/activation.ts +38 -0
  691. package/packages/seedance/src/fragment.ts +46 -0
  692. package/packages/seedance/src/index.ts +329 -0
  693. package/packages/seedance/src/surface.ts +355 -0
  694. package/packages/seedance-kits/README.md +153 -0
  695. package/packages/seedance-kits/kits/broll-v1.svs +52 -0
  696. package/packages/seedance-kits/kits/call-v1.svs +55 -0
  697. package/packages/seedance-kits/kits/camera-reference-v1.svs +9 -0
  698. package/packages/seedance-kits/kits/motion-reference-v1.svs +9 -0
  699. package/packages/seedance-kits/kits/podcast-v1.svs +55 -0
  700. package/packages/seedance-kits/kits/speaker-v1.svs +136 -0
  701. package/packages/seedance-kits/kits/street-interview-v1.svs +49 -0
  702. package/packages/seedance-kits/package.json +24 -0
  703. package/packages/seedream/README.md +21 -0
  704. package/packages/seedream/package.json +21 -0
  705. package/packages/seedream/src/activation.ts +12 -0
  706. package/packages/seedream/src/index.ts +162 -0
  707. package/packages/seedream/src/surface.ts +84 -0
  708. package/packages/semantic-take-adjust/package.json +21 -0
  709. package/packages/semantic-take-adjust/src/activation.ts +22 -0
  710. package/packages/semantic-take-adjust/src/component.ts +31 -0
  711. package/packages/semantic-take-adjust/src/fragment.ts +24 -0
  712. package/packages/semantic-take-adjust/src/index.ts +12 -0
  713. package/packages/semantic-take-adjust/src/manifest.ts +57 -0
  714. package/packages/semantic-take-adjust/src/program.ts +49 -0
  715. package/packages/semantic-take-adjust/src/surface.ts +96 -0
  716. package/packages/semantic-take-adjust/src/types.ts +9 -0
  717. package/packages/semantic-track/README.md +21 -0
  718. package/packages/semantic-track/package.json +22 -0
  719. package/packages/semantic-track/src/activation.ts +8 -0
  720. package/packages/semantic-track/src/component.ts +24 -0
  721. package/packages/semantic-track/src/identity.ts +58 -0
  722. package/packages/semantic-track/src/index.ts +6 -0
  723. package/packages/semantic-track/src/location.ts +81 -0
  724. package/packages/semantic-track/src/manifest.ts +38 -0
  725. package/packages/semantic-track/src/projection.ts +71 -0
  726. package/packages/semantic-track/src/types.ts +26 -0
  727. package/packages/source/README.md +13 -0
  728. package/packages/source/package.json +13 -0
  729. package/packages/source/src/header.ts +80 -0
  730. package/packages/source/src/index.ts +17 -0
  731. package/packages/source/src/unit.ts +38 -0
  732. package/packages/spatial/README.md +77 -0
  733. package/packages/spatial/package.json +24 -0
  734. package/packages/spatial/src/activation.ts +43 -0
  735. package/packages/spatial/src/author.ts +59 -0
  736. package/packages/spatial/src/component.ts +45 -0
  737. package/packages/spatial/src/fragment.ts +36 -0
  738. package/packages/spatial/src/geometry.ts +238 -0
  739. package/packages/spatial/src/index.ts +37 -0
  740. package/packages/spatial/src/manifest.ts +341 -0
  741. package/packages/spatial/src/region-timeline.ts +69 -0
  742. package/packages/spatial/src/schema.ts +47 -0
  743. package/packages/spatial/src/surface.ts +319 -0
  744. package/packages/spatial/src/types.ts +101 -0
  745. package/packages/speech/README.md +16 -0
  746. package/packages/speech/package.json +19 -0
  747. package/packages/speech/src/activation.ts +7 -0
  748. package/packages/speech/src/component.ts +43 -0
  749. package/packages/speech/src/identity.ts +73 -0
  750. package/packages/speech/src/index.ts +6 -0
  751. package/packages/speech/src/manifest.ts +30 -0
  752. package/packages/speech/src/materialize.ts +103 -0
  753. package/packages/speech/src/schema.ts +42 -0
  754. package/packages/speech/src/types.ts +54 -0
  755. package/packages/speech-alignment/README.md +29 -0
  756. package/packages/speech-alignment/package.json +25 -0
  757. package/packages/speech-alignment/src/activation.ts +8 -0
  758. package/packages/speech-alignment/src/align.ts +235 -0
  759. package/packages/speech-alignment/src/component.ts +37 -0
  760. package/packages/speech-alignment/src/error.ts +9 -0
  761. package/packages/speech-alignment/src/index.ts +7 -0
  762. package/packages/speech-alignment/src/local.ts +64 -0
  763. package/packages/speech-alignment/src/locate.ts +473 -0
  764. package/packages/speech-alignment/src/manifest.ts +37 -0
  765. package/packages/speech-alignment/src/normalize.ts +79 -0
  766. package/packages/speech-alignment/src/types.ts +30 -0
  767. package/packages/speech-evidence/README.md +3 -0
  768. package/packages/speech-evidence/package.json +16 -0
  769. package/packages/speech-evidence/src/activation.ts +3 -0
  770. package/packages/speech-evidence/src/index.ts +102 -0
  771. package/packages/speech-track/README.md +51 -0
  772. package/packages/speech-track/package.json +28 -0
  773. package/packages/speech-track/preview/Track.png +0 -0
  774. package/packages/speech-track/src/activation.ts +19 -0
  775. package/packages/speech-track/src/component.ts +45 -0
  776. package/packages/speech-track/src/fragment.ts +74 -0
  777. package/packages/speech-track/src/index.ts +7 -0
  778. package/packages/speech-track/src/manifest.ts +73 -0
  779. package/packages/speech-track/src/program.ts +64 -0
  780. package/packages/speech-track/src/surface.ts +35 -0
  781. package/packages/speech-track/src/types.ts +6 -0
  782. package/packages/speech-track-studio/README.md +3 -0
  783. package/packages/speech-track-studio/package.json +14 -0
  784. package/packages/speech-track-studio/src/activation.ts +7 -0
  785. package/packages/speech-track-studio/src/index.ts +40 -0
  786. package/packages/store-sqlite/README.md +14 -0
  787. package/packages/store-sqlite/package.json +18 -0
  788. package/packages/store-sqlite/src/index.ts +2 -0
  789. package/packages/store-sqlite/src/store.ts +1101 -0
  790. package/packages/studio/README.md +125 -0
  791. package/packages/studio/index.html +10 -0
  792. package/packages/studio/package.json +50 -0
  793. package/packages/studio/src/build-library.ts +281 -0
  794. package/packages/studio/src/companion-assembly.ts +39 -0
  795. package/packages/studio/src/compile.ts +166 -0
  796. package/packages/studio/src/domain.ts +139 -0
  797. package/packages/studio/src/execute.ts +57 -0
  798. package/packages/studio/src/fallback-companions.ts +98 -0
  799. package/packages/studio/src/observe.ts +202 -0
  800. package/packages/studio/src/parameter-values.ts +81 -0
  801. package/packages/studio/src/parameters.ts +550 -0
  802. package/packages/studio/src/preview/render.ts +51 -0
  803. package/packages/studio/src/preview/runtime-shim.ts +184 -0
  804. package/packages/studio/src/programme.ts +276 -0
  805. package/packages/studio/src/run.ts +85 -0
  806. package/packages/studio/src/server.ts +725 -0
  807. package/packages/studio/src/session.ts +111 -0
  808. package/packages/studio/src/shared.ts +315 -0
  809. package/packages/studio/src/snapshot.ts +454 -0
  810. package/packages/studio/src/source-transaction.ts +57 -0
  811. package/packages/studio/src/storyboard.ts +133 -0
  812. package/packages/studio/src/studio-preflight.ts +198 -0
  813. package/packages/studio/src/studio-registry.ts +406 -0
  814. package/packages/studio/src/studio-trace.ts +136 -0
  815. package/packages/studio/src/style.css +1525 -0
  816. package/packages/studio/src/surface-preview.ts +35 -0
  817. package/packages/studio/src/temporal-graph.ts +227 -0
  818. package/packages/studio/src/ui/code.ts +450 -0
  819. package/packages/studio/src/ui/icons.ts +51 -0
  820. package/packages/studio/src/ui/library.ts +378 -0
  821. package/packages/studio/src/ui/main.ts +1001 -0
  822. package/packages/studio/src/ui/markers.ts +152 -0
  823. package/packages/studio/src/ui/material-preview.ts +176 -0
  824. package/packages/studio/src/ui/overlay.ts +144 -0
  825. package/packages/studio/src/ui/resize.ts +74 -0
  826. package/packages/studio/src/ui/selection.ts +178 -0
  827. package/packages/studio/src/ui/stage.ts +231 -0
  828. package/packages/studio/src/ui/syntax.ts +195 -0
  829. package/packages/studio/src/ui/timeline.ts +1041 -0
  830. package/packages/studio/src/ui/writeback.ts +10 -0
  831. package/packages/studio/src/ui/zoom.ts +129 -0
  832. package/packages/studio/start.ts +143 -0
  833. package/packages/studio-adapter/README.md +186 -0
  834. package/packages/studio-adapter/package.json +14 -0
  835. package/packages/studio-adapter/src/index.ts +850 -0
  836. package/packages/svs/README.md +37 -0
  837. package/packages/svs/package.json +21 -0
  838. package/packages/svs/src/activation.ts +11 -0
  839. package/packages/svs/src/format.ts +16 -0
  840. package/packages/svs/src/frontend.ts +33 -0
  841. package/packages/svs/src/index.ts +5 -0
  842. package/packages/svs/src/manifest.ts +17 -0
  843. package/packages/svs/src/parser.ts +279 -0
  844. package/packages/svs/src/types.ts +26 -0
  845. package/packages/temporal/README.md +31 -0
  846. package/packages/temporal/package.json +20 -0
  847. package/packages/temporal/src/activation.ts +9 -0
  848. package/packages/temporal/src/component.ts +68 -0
  849. package/packages/temporal/src/index.ts +110 -0
  850. package/packages/temporal/src/location.ts +67 -0
  851. package/packages/temporal/src/projection.ts +280 -0
  852. package/packages/temporal/src/rational.ts +80 -0
  853. package/packages/temporal/src/sample.ts +43 -0
  854. package/packages/temporal/src/schedule.ts +52 -0
  855. package/packages/temporal/src/types.ts +124 -0
  856. package/packages/temporal-markup/README.md +75 -0
  857. package/packages/temporal-markup/package.json +18 -0
  858. package/packages/temporal-markup/src/index.ts +537 -0
  859. package/packages/temporal-markup/src/space.ts +59 -0
  860. package/packages/text/README.md +59 -0
  861. package/packages/text/package.json +21 -0
  862. package/packages/text/src/activation.ts +33 -0
  863. package/packages/text/src/component.ts +72 -0
  864. package/packages/text/src/fragment.ts +57 -0
  865. package/packages/text/src/frontend.ts +39 -0
  866. package/packages/text/src/index.ts +27 -0
  867. package/packages/text/src/manifest.ts +170 -0
  868. package/packages/text/src/program.ts +418 -0
  869. package/packages/text/src/surface.ts +212 -0
  870. package/packages/text/src/svs.ts +189 -0
  871. package/packages/text/src/types.ts +82 -0
  872. package/packages/transport-aws-lambda/README.md +20 -0
  873. package/packages/transport-aws-lambda/package.json +14 -0
  874. package/packages/transport-aws-lambda/src/index.ts +131 -0
  875. package/packages/typography-track/README.md +50 -0
  876. package/packages/typography-track/package.json +34 -0
  877. package/packages/typography-track/preview/Mask.png +0 -0
  878. package/packages/typography-track/preview/Track.png +0 -0
  879. package/packages/typography-track/src/activation.ts +36 -0
  880. package/packages/typography-track/src/component.ts +93 -0
  881. package/packages/typography-track/src/fragment.ts +30 -0
  882. package/packages/typography-track/src/index.ts +11 -0
  883. package/packages/typography-track/src/manifest.ts +556 -0
  884. package/packages/typography-track/src/program.ts +622 -0
  885. package/packages/typography-track/src/surface.ts +842 -0
  886. package/packages/typography-track/src/types.ts +109 -0
  887. package/packages/typography-track-studio/README.md +3 -0
  888. package/packages/typography-track-studio/package.json +14 -0
  889. package/packages/typography-track-studio/src/activation.ts +7 -0
  890. package/packages/typography-track-studio/src/index.ts +116 -0
  891. package/packages/validation/README.md +11 -0
  892. package/packages/validation/package.json +15 -0
  893. package/packages/validation/src/index.ts +100 -0
  894. package/packages/video-cli/README.md +181 -0
  895. package/packages/video-cli/package.json +37 -0
  896. package/packages/video-cli/src/capture.ts +174 -0
  897. package/packages/video-cli/src/cli.ts +109 -0
  898. package/packages/video-cli/src/compiler.ts +32 -0
  899. package/packages/video-cli/src/creation.ts +449 -0
  900. package/packages/video-cli/src/distribution.ts +88 -0
  901. package/packages/video-cli/src/index.ts +50 -0
  902. package/packages/video-cli/src/media.ts +701 -0
  903. package/packages/video-cli/src/package-selection.ts +34 -0
  904. package/packages/video-cli/src/process.ts +71 -0
  905. package/packages/video-cli/src/studio-distribution.ts +19 -0
  906. package/packages/video-cli/src/transcript.ts +71 -0
  907. package/packages/video-cli/src/vocabulary.ts +386 -0
  908. package/packages/visual-ir/README.md +36 -0
  909. package/packages/visual-ir/package.json +16 -0
  910. package/packages/visual-ir/src/activation.ts +3 -0
  911. package/packages/visual-ir/src/index.ts +7 -0
  912. package/packages/visual-ir/src/style.ts +222 -0
  913. package/packages/volcengine-matting/README.md +89 -0
  914. package/packages/volcengine-matting/package.json +16 -0
  915. package/packages/volcengine-matting/src/activation.ts +13 -0
  916. package/packages/volcengine-matting/src/index.ts +45 -0
  917. package/packages/volcengine-matting/src/surface.ts +48 -0
  918. package/packages/whisperx/README.md +34 -0
  919. package/packages/whisperx/package.json +28 -0
  920. package/packages/whisperx/src/activation.ts +18 -0
  921. package/packages/whisperx/src/component.ts +64 -0
  922. package/packages/whisperx/src/evidence.ts +69 -0
  923. package/packages/whisperx/src/fragment.ts +76 -0
  924. package/packages/whisperx/src/index.ts +14 -0
  925. package/packages/whisperx/src/manifest.ts +92 -0
  926. package/packages/whisperx/src/surface.ts +90 -0
  927. package/packages/whisperx/src/transcript.ts +97 -0
  928. package/packages/whisperx/src/types.ts +9 -0
  929. package/packages/workspace/README.md +4 -0
  930. package/packages/workspace/package.json +14 -0
  931. package/packages/workspace/src/index.ts +38 -0
  932. package/packages/workspace-fs-node/README.md +13 -0
  933. package/packages/workspace-fs-node/package.json +15 -0
  934. package/packages/workspace-fs-node/src/index.ts +6 -0
  935. package/packages/workspace-fs-node/src/workspace.ts +226 -0
  936. package/packages/yt-dlp/README.md +31 -0
  937. package/packages/yt-dlp/package.json +10 -0
  938. package/packages/yt-dlp/src/download.ts +104 -0
  939. package/packages/yt-dlp/src/index.ts +1 -0
  940. package/services/image-opencv/README.md +33 -0
  941. package/services/image-opencv/package.json +14 -0
  942. package/services/image-opencv/pyproject.toml +13 -0
  943. package/services/image-opencv/uv.lock +56 -0
  944. package/services/whisperx/README.md +82 -0
  945. package/services/whisperx/package.json +15 -0
  946. package/services/whisperx/pyproject.toml +26 -0
  947. package/services/whisperx/src/hypit_whisperx_service/__init__.py +6 -0
  948. package/services/whisperx/src/hypit_whisperx_service/__main__.py +29 -0
  949. package/services/whisperx/src/hypit_whisperx_service/application.py +88 -0
  950. package/services/whisperx/src/hypit_whisperx_service/audio.py +66 -0
  951. package/services/whisperx/src/hypit_whisperx_service/check.py +35 -0
  952. package/services/whisperx/src/hypit_whisperx_service/config.py +81 -0
  953. package/services/whisperx/src/hypit_whisperx_service/engine.py +173 -0
  954. package/services/whisperx/src/hypit_whisperx_service/prepare.py +19 -0
  955. package/services/whisperx/src/hypit_whisperx_service/resources.py +41 -0
  956. package/services/whisperx/src/hypit_whisperx_service/server.py +101 -0
  957. package/services/whisperx/uv.lock +3381 -0
  958. package/services/yt-dlp/README.md +19 -0
  959. package/services/yt-dlp/package.json +14 -0
  960. package/services/yt-dlp/pyproject.toml +13 -0
  961. package/services/yt-dlp/uv.lock +23 -0
  962. package/index.js +0 -1
@@ -0,0 +1,1179 @@
1
+ import type { FontArtifactRef } from "@hypit/media";
2
+ import type {
3
+ VisualColorPaint,
4
+ VisualPathTextElement,
5
+ VisualTextDocument,
6
+ VisualTextFlowElement,
7
+ VisualTextPaintLayer,
8
+ VisualTextRunStyle,
9
+ VisualTextSequenceAnimation,
10
+ VisualTextTypography,
11
+ VisualVectorPathCommand,
12
+ } from "@hypit/composition";
13
+ import { canonicalStringify } from "@hypit/protocol";
14
+
15
+ type TerminalTextElement = VisualTextFlowElement | VisualPathTextElement;
16
+
17
+ export type TextRenderContext = {
18
+ readonly trackId: string;
19
+ readonly presentId: string;
20
+ readonly durationFrames: number;
21
+ readonly durationSeconds: string;
22
+ readonly presentStartFrame: number;
23
+ readonly programNumerator: number;
24
+ readonly programDenominator: number;
25
+ readonly escape: (value: string) => string;
26
+ readonly stableId: (parts: readonly string[]) => string;
27
+ readonly exactFontFamily: (font: FontArtifactRef) => string;
28
+ readonly baseStyle: string;
29
+ readonly commonAttributes: string;
30
+ /**
31
+ * Filter identifiers already written into this document.
32
+ *
33
+ * A caption is one element per word, and every word carries the same Paint, so without somewhere
34
+ * to remember that, each word writes the whole set again.
35
+ */
36
+ readonly emittedFilterIds?: Set<string>;
37
+ };
38
+
39
+ function number(value: number): string {
40
+ if (Object.is(value, -0)) return "0";
41
+ return Number.isInteger(value) ? String(value) : String(Number(value.toFixed(8)));
42
+ }
43
+
44
+ function colorStop(stop: { readonly offset: number; readonly color: string; readonly opacity: number }): string {
45
+ const color = stop.opacity === 1
46
+ ? stop.color
47
+ : `color-mix(in srgb,${stop.color} ${number(stop.opacity * 100)}%,transparent)`;
48
+ return `${color} ${number(stop.offset * 100)}%`;
49
+ }
50
+
51
+ export function colorPaintCss(paint: VisualColorPaint): string {
52
+ if (paint.kind === "solid") return paint.color;
53
+ const stops = paint.stops.map(colorStop).join(",");
54
+ if (paint.kind === "linear-gradient") return `linear-gradient(${number(paint.angleDeg)}deg,${stops})`;
55
+ return `radial-gradient(circle at ${number(paint.center.x * 100)}% ${number(paint.center.y * 100)}%,${stops})`;
56
+ }
57
+
58
+ function solidPaint(paint: VisualColorPaint): string | undefined {
59
+ return paint.kind === "solid" ? paint.color : undefined;
60
+ }
61
+
62
+ function exactFontCss(fonts: readonly FontArtifactRef[] | undefined, exactFontFamily: TextRenderContext["exactFontFamily"]): string[] {
63
+ if (fonts === undefined) return [];
64
+ return [
65
+ `font-family:${fonts.map(exactFontFamily).join(",")}`,
66
+ `font-weight:${fonts[0]!.weight}`,
67
+ `font-style:${fonts[0]!.style}`,
68
+ "font-synthesis:none",
69
+ ];
70
+ }
71
+
72
+ function typographyCss(
73
+ typography: VisualTextTypography,
74
+ exactFontFamily: TextRenderContext["exactFontFamily"],
75
+ ): string[] {
76
+ const synthesis = typography.synthesis === "weight-style"
77
+ ? "weight style"
78
+ : typography.synthesis;
79
+ const decorations = typography.decorations;
80
+ const decoration = decorations[0];
81
+ if (decorations.some((item) => item.paint.kind !== "solid")) {
82
+ throw new Error("HyperFrames Text decorations currently require solid Paint.");
83
+ }
84
+ if (decoration !== undefined && decorations.some((item) =>
85
+ item.style !== decoration.style
86
+ || item.paint.kind !== "solid"
87
+ || decoration.paint.kind !== "solid"
88
+ || item.paint.color !== decoration.paint.color
89
+ || item.thicknessPx !== decoration.thicknessPx
90
+ || item.offsetPx !== decoration.offsetPx
91
+ || item.skipInk !== decoration.skipInk)) {
92
+ throw new Error("HyperFrames Text decorations on one run must share Paint and metric settings.");
93
+ }
94
+ return [
95
+ ...exactFontCss(typography.fonts, exactFontFamily),
96
+ `font-size:${number(typography.sizePx)}px`,
97
+ `font-weight:${typography.weight}`,
98
+ `font-style:${typography.style}`,
99
+ `font-synthesis:${synthesis}`,
100
+ `font-kerning:${typography.kerning}`,
101
+ `font-variation-settings:${typography.axes.length === 0 ? "normal" : typography.axes.map((axis) => `"${axis.tag}" ${number(axis.value)}`).join(",")}`,
102
+ `font-feature-settings:${typography.features.length === 0 ? "normal" : typography.features.map((feature) => `"${feature.tag}" ${feature.enabled ? 1 : 0}`).join(",")}`,
103
+ `letter-spacing:${number(typography.trackingPx)}px`,
104
+ `word-spacing:${number(typography.wordSpacingPx)}px`,
105
+ `line-height:${number(typography.lineHeight)}`,
106
+ ...(typography.direction === "auto" ? [] : [`direction:${typography.direction}`]),
107
+ `writing-mode:${typography.writingMode}`,
108
+ `text-transform:${typography.transform}`,
109
+ `font-variant-caps:${typography.variantCaps}`,
110
+ `tab-size:${typography.tabSize}`,
111
+ `text-indent:${number(typography.indentationPx)}px`,
112
+ ...(typography.baselineShiftPx === 0 ? [] : [`vertical-align:${number(typography.baselineShiftPx)}px`]),
113
+ ...(typography.baselineShiftPx !== 0 || typography.verticalAlign === "baseline" ? [] : [`vertical-align:${typography.verticalAlign}`]),
114
+ `text-autospace:${typography.cjk.textSpacing === "normal" ? "normal" : "no-autospace"}`,
115
+ `text-spacing-trim:${typography.cjk.punctuationTrim === "none" ? "space-all" : typography.cjk.punctuationTrim === "start" ? "trim-start" : typography.cjk.punctuationTrim === "adjacent" ? "trim-both" : typography.cjk.punctuationTrim === "all" ? "trim-all" : "space-first"}`,
116
+ ...(decoration === undefined ? [] : [
117
+ `text-decoration-line:${decorations.map((item) => item.line).join(" ")}`,
118
+ `text-decoration-color:${decoration.paint.kind === "solid" ? decoration.paint.color : "currentColor"}`,
119
+ `text-decoration-style:${decoration.style}`,
120
+ ...(decoration.thicknessPx === undefined ? [] : [`text-decoration-thickness:${number(decoration.thicknessPx)}px`]),
121
+ ...(decoration.offsetPx === undefined ? [] : [`text-underline-offset:${number(decoration.offsetPx)}px`]),
122
+ `text-decoration-skip-ink:${decoration.skipInk ? "auto" : "none"}`,
123
+ ]),
124
+ ];
125
+ }
126
+
127
+ function textLanguageAttributes(
128
+ typography: VisualTextTypography,
129
+ escape: TextRenderContext["escape"],
130
+ language?: string,
131
+ direction?: "auto" | "ltr" | "rtl",
132
+ ): string {
133
+ const actualLanguage = language ?? typography.language;
134
+ const actualDirection = direction ?? typography.direction;
135
+ return [
136
+ ...(actualLanguage === undefined ? [] : [`lang="${escape(actualLanguage)}"`]),
137
+ `dir="${actualDirection}"`,
138
+ ].join(" ");
139
+ }
140
+
141
+ function mergedTypography(
142
+ base: VisualTextTypography,
143
+ style: VisualTextRunStyle | undefined,
144
+ ): VisualTextTypography {
145
+ const override = style?.typography;
146
+ if (override === undefined) return base;
147
+ const {
148
+ fonts: _fonts,
149
+ axes: _axes,
150
+ features: _features,
151
+ decorations: _decorations,
152
+ cjk: _cjk,
153
+ ...scalarOverrides
154
+ } = override;
155
+ return {
156
+ ...base,
157
+ ...scalarOverrides,
158
+ fonts: override.fonts ?? base.fonts,
159
+ axes: override.axes ?? base.axes,
160
+ features: override.features ?? base.features,
161
+ decorations: override.decorations ?? base.decorations,
162
+ cjk: override.cjk === undefined ? base.cjk : { ...base.cjk, ...override.cjk },
163
+ };
164
+ }
165
+
166
+ type GlyphPaintLayer = Exclude<VisualTextPaintLayer, { readonly kind: "box" }>;
167
+ type FilterGlyphPaint = Extract<GlyphPaintLayer, { kind: "stroke" | "shadow" | "glow" }>;
168
+
169
+ function glyphPaintLayers(paints: readonly VisualTextPaintLayer[]): GlyphPaintLayer[] {
170
+ return paints.filter((paint): paint is GlyphPaintLayer => paint.kind !== "box");
171
+ }
172
+
173
+ function usesGlyphFilter(paint: GlyphPaintLayer): paint is FilterGlyphPaint {
174
+ return paint.kind === "shadow" || paint.kind === "glow"
175
+ || (paint.kind === "stroke" && paint.placement !== "outside");
176
+ }
177
+
178
+ function inheritedGlyphColor(paints: readonly VisualTextPaintLayer[]): string[] {
179
+ const fills = glyphPaintLayers(paints).filter((paint): paint is Extract<GlyphPaintLayer, { kind: "fill" }> => paint.kind === "fill");
180
+ return fills.length === 1 && fills[0]!.paint.kind === "solid" ? [`color:${fills[0]!.paint.color}`] : [];
181
+ }
182
+
183
+ /**
184
+ * Name a filter after the Paint it draws, and after nothing else.
185
+ *
186
+ * What the filter contains is decided by the Paint alone, so two Paints that are equal want one
187
+ * definition between them. Naming the Track and the Present as well made every element that shared
188
+ * a Paint carry its own copy: a five-word caption with an outline, a glow and a long shadow emitted
189
+ * eighty definitions of sixteen distinct filters, thirty-six kilobytes of which thirty were the
190
+ * same bytes repeated. Identifiers are resolved across the document, so one copy answers for all.
191
+ */
192
+ function glyphFilterId(
193
+ paint: Extract<GlyphPaintLayer, { kind: "stroke" | "shadow" | "glow" }>,
194
+ context: TextRenderContext,
195
+ ): string {
196
+ return context.stableId(["text-glyph-filter", canonicalStringify(paint)]);
197
+ }
198
+
199
+ function glyphFilterDefinition(
200
+ paint: Extract<GlyphPaintLayer, { kind: "stroke" | "shadow" | "glow" }>,
201
+ context: TextRenderContext,
202
+ ): string {
203
+ const color = solidPaint(paint.paint);
204
+ if (color === undefined) {
205
+ throw new Error(`HyperFrames ${paint.kind} Text Paint requires solid color; materialize gradient ${paint.kind} as a Surface.`);
206
+ }
207
+ const id = glyphFilterId(paint, context);
208
+ const flood = `<feFlood flood-color="${context.escape(color)}" result="paint"/>`;
209
+ if (paint.kind === "stroke") {
210
+ const radius = paint.placement === "center" ? paint.widthPx / 2 : paint.widthPx;
211
+ const expanded = `<feMorphology in="SourceAlpha" operator="dilate" radius="${number(radius)}" result="expanded"/>`;
212
+ const contracted = `<feMorphology in="SourceAlpha" operator="erode" radius="${number(radius)}" result="contracted"/>`;
213
+ const ring = paint.placement === "outside"
214
+ ? `<feComposite in="expanded" in2="SourceAlpha" operator="out" result="shape"/>`
215
+ : paint.placement === "inside"
216
+ ? `<feComposite in="SourceAlpha" in2="contracted" operator="out" result="shape"/>`
217
+ : `<feComposite in="expanded" in2="contracted" operator="out" result="shape"/>`;
218
+ return `<filter id="${id}" x="-100%" y="-100%" width="300%" height="300%" color-interpolation-filters="sRGB">${expanded}${contracted}${ring}${flood}<feComposite in="paint" in2="shape" operator="in"/></filter>`;
219
+ }
220
+ const spread = paint.spreadPx <= 0
221
+ ? `<feComposite in="SourceAlpha" in2="SourceAlpha" operator="in" result="spread"/>`
222
+ : `<feMorphology in="SourceAlpha" operator="dilate" radius="${number(paint.spreadPx)}" result="spread"/>`;
223
+ const blur = `<feGaussianBlur in="spread" stdDeviation="${number(paint.blurPx)}" result="blurred"/>`;
224
+ const offset = paint.kind === "shadow"
225
+ ? `<feOffset in="blurred" dx="${number(paint.offsetX)}" dy="${number(paint.offsetY)}" result="shape"/>`
226
+ : `<feComposite in="blurred" in2="blurred" operator="in" result="shape"/>`;
227
+ return `<filter id="${id}" x="-100%" y="-100%" width="300%" height="300%" color-interpolation-filters="sRGB">${spread}${blur}${offset}${flood}<feComposite in="paint" in2="shape" operator="in"/></filter>`;
228
+ }
229
+
230
+ /** Every glyph Paint the document reaches, from the element, its paragraphs and their runs. */
231
+ function documentGlyphPaintLayers(element: TerminalTextElement): GlyphPaintLayer[] {
232
+ const layers: GlyphPaintLayer[] = [];
233
+ const append = (paints: readonly VisualTextPaintLayer[] | undefined): void => {
234
+ layers.push(...glyphPaintLayers(paints ?? []));
235
+ };
236
+ append(element.paints);
237
+ for (const paragraph of element.document.paragraphs) {
238
+ append(paragraph.style?.paints);
239
+ for (const inline of paragraph.inlines) if (inline.kind === "text") append(inline.style?.paints);
240
+ }
241
+ return layers;
242
+ }
243
+
244
+ function glyphFilterDefinitions(element: TerminalTextElement, context: TextRenderContext): string {
245
+ const layers = documentGlyphPaintLayers(element);
246
+ const filtered = layers.filter(usesGlyphFilter);
247
+ const definitions = [...new Map(filtered.map((paint) => [canonicalStringify(paint), paint])).values()]
248
+ .map((paint) => glyphFilterDefinition(paint, context)).join("");
249
+ return definitions;
250
+ }
251
+
252
+ function glyphPaintDefinitions(element: TerminalTextElement, context: TextRenderContext): string {
253
+ const definitions = glyphFilterDefinitions(element, context);
254
+ return definitions.length === 0 ? "" : `<svg aria-hidden="true" width="0" height="0" style="position:absolute;overflow:hidden"><defs>${definitions}</defs></svg>`;
255
+ }
256
+
257
+ function glyphLayerCss(
258
+ paint: GlyphPaintLayer,
259
+ inheritSolidFill: boolean,
260
+ context: TextRenderContext,
261
+ ): string[] {
262
+ const common = ["grid-area:1/1", "position:relative", "pointer-events:none"];
263
+ if (paint.kind === "fill") {
264
+ if (paint.paint.kind === "solid") return [...common, `color:${inheritSolidFill ? "inherit" : paint.paint.color}`];
265
+ return [
266
+ ...common,
267
+ `background-image:${colorPaintCss(paint.paint)}`,
268
+ "background-clip:text",
269
+ "-webkit-background-clip:text",
270
+ "color:transparent",
271
+ "-webkit-text-fill-color:transparent",
272
+ ];
273
+ }
274
+ if (paint.kind === "stroke" && paint.placement === "outside") {
275
+ // CSS centres a stroke on the glyph edge. Doubling the requested width and drawing the body
276
+ // again in the following fill layer covers the inner half, leaving exactly the authored width
277
+ // outside without passing the descender through an SVG filter input box first.
278
+ const color = solidPaint(paint.paint);
279
+ if (color === undefined) {
280
+ throw new Error("HyperFrames outside Text stroke requires solid color; materialize a gradient stroke as a Surface.");
281
+ }
282
+ return [
283
+ ...common,
284
+ `color:${color}`,
285
+ `-webkit-text-fill-color:${color}`,
286
+ `-webkit-text-stroke:${number(paint.widthPx * 2)}px ${color}`,
287
+ "paint-order:stroke fill",
288
+ ];
289
+ }
290
+ return [
291
+ ...common,
292
+ "color:#ffffff",
293
+ "-webkit-text-fill-color:#ffffff",
294
+ // The filter builds its shape out of this layer's own alpha, so anything inherited that also
295
+ // marks the glyph — a shadow from the element around it — would be dilated along with it.
296
+ "text-shadow:none",
297
+ `filter:url(#${glyphFilterId(paint, context)})`,
298
+ ];
299
+ }
300
+
301
+ function renderGlyphPaint(
302
+ value: string,
303
+ paints: readonly VisualTextPaintLayer[],
304
+ context: TextRenderContext,
305
+ ): string {
306
+ const layers = glyphPaintLayers(paints);
307
+ if (layers.length === 0) return context.escape(value);
308
+ const singleSolidFill = layers.length === 1 && layers[0]?.kind === "fill" && layers[0].paint.kind === "solid";
309
+ return layers.map((paint, index) => `<span aria-hidden="${index === layers.length - 1 ? "false" : "true"}" data-hypit-text-paint-layer="${index}"${styleAttribute(glyphLayerCss(paint, singleSolidFill, context), context.escape)}>${context.escape(value)}</span>`).join("");
310
+ }
311
+
312
+ /**
313
+ * Render one plain string as ordered glyph Paint, with the filter definitions it needs.
314
+ *
315
+ * Text Flow reaches these layers through its document structure, a run at a time. A plain text
316
+ * element has no structure to walk — its whole content is one string — so it arrives here instead.
317
+ * Both end up in the same layers, drawn by the same filters, which is the point: an outline placed
318
+ * outside the letter is one thing, not one thing per element kind.
319
+ */
320
+ export function renderGlyphPaintedString(
321
+ value: string,
322
+ paints: readonly VisualTextPaintLayer[],
323
+ context: TextRenderContext,
324
+ ): string {
325
+ const layers = glyphPaintLayers(paints);
326
+ if (layers.length === 0) return context.escape(value);
327
+ const shaped = layers.filter(usesGlyphFilter);
328
+ const written = context.emittedFilterIds;
329
+ const definitions = [...new Map(shaped.map((paint) => [canonicalStringify(paint), paint])).values()]
330
+ .filter((paint) => {
331
+ const id = glyphFilterId(paint, context);
332
+ if (written === undefined) return true;
333
+ if (written.has(id)) return false;
334
+ written.add(id);
335
+ return true;
336
+ })
337
+ .map((paint) => glyphFilterDefinition(paint, context)).join("");
338
+ const defs = definitions.length === 0
339
+ ? ""
340
+ : `<svg aria-hidden="true" width="0" height="0" style="position:absolute;overflow:hidden"><defs>${definitions}</defs></svg>`;
341
+ // Paint layers share one grid cell. The wrapper stacks them but does not absorb their ink into
342
+ // layout: outline, shadow and glow remain visible overflow around the measured letterform.
343
+ return `${defs}<span style="position:relative;display:inline-grid">${renderGlyphPaint(value, paints, context)}</span>`;
344
+ }
345
+
346
+ function boxLayers(
347
+ paints: readonly VisualTextPaintLayer[],
348
+ target: Extract<VisualTextPaintLayer, { kind: "box" }>["target"],
349
+ continuity?: "isolated" | "joined",
350
+ ): Array<Extract<VisualTextPaintLayer, { kind: "box" }>> {
351
+ return paints.filter((paint): paint is Extract<VisualTextPaintLayer, { kind: "box" }> =>
352
+ paint.kind === "box" && paint.target === target && (continuity === undefined || paint.continuity === continuity));
353
+ }
354
+
355
+ function boxCss(
356
+ paints: readonly VisualTextPaintLayer[],
357
+ target: Extract<VisualTextPaintLayer, { kind: "box" }>["target"],
358
+ continuity?: "isolated" | "joined",
359
+ ): string[] {
360
+ const layers = boxLayers(paints, target, continuity);
361
+ if (layers.length === 0) return [];
362
+ const result: string[] = [];
363
+ const shadows: string[] = [];
364
+ const backgrounds: string[] = [];
365
+ for (const layer of layers) {
366
+ const decoration = layer.decoration;
367
+ if (decoration.fill !== undefined) {
368
+ backgrounds.push(decoration.fill.kind === "solid"
369
+ ? `linear-gradient(${decoration.fill.color},${decoration.fill.color})`
370
+ : colorPaintCss(decoration.fill));
371
+ }
372
+ if (decoration.border !== undefined) {
373
+ const color = solidPaint(decoration.border.paint);
374
+ if (color === undefined) throw new Error("HyperFrames Text Box borders require solid Paint.");
375
+ result.push(
376
+ `border-style:${decoration.border.style}`,
377
+ `border-color:${color}`,
378
+ `border-width:${number(decoration.border.widthsPx.top)}px ${number(decoration.border.widthsPx.right)}px ${number(decoration.border.widthsPx.bottom)}px ${number(decoration.border.widthsPx.left)}px`,
379
+ );
380
+ }
381
+ result.push(
382
+ `padding:${number(decoration.paddingPx.top)}px ${number(decoration.paddingPx.right)}px ${number(decoration.paddingPx.bottom)}px ${number(decoration.paddingPx.left)}px`,
383
+ `border-radius:${number(decoration.radiiPx.topLeft)}px ${number(decoration.radiiPx.topRight)}px ${number(decoration.radiiPx.bottomRight)}px ${number(decoration.radiiPx.bottomLeft)}px`,
384
+ );
385
+ for (const shadow of decoration.shadows) {
386
+ const color = solidPaint(shadow.paint);
387
+ if (color === undefined) throw new Error("HyperFrames Text Box shadows require solid Paint.");
388
+ shadows.push(`${number(shadow.offsetX)}px ${number(shadow.offsetY)}px ${number(shadow.blurPx)}px ${number(shadow.spreadPx)}px ${color}`);
389
+ }
390
+ }
391
+ if (backgrounds.length > 0) result.push(`background-image:${backgrounds.reverse().join(",")}`);
392
+ if (shadows.length > 0) result.push(`box-shadow:${shadows.join(",")}`);
393
+ return result;
394
+ }
395
+
396
+ function tailHtml(
397
+ paints: readonly VisualTextPaintLayer[],
398
+ target: Extract<VisualTextPaintLayer, { kind: "box" }>["target"],
399
+ context: TextRenderContext,
400
+ continuity?: "isolated" | "joined",
401
+ ): string {
402
+ return boxLayers(paints, target, continuity).flatMap((layer, index) => {
403
+ const tail = layer.decoration.tail;
404
+ if (tail === undefined) return [];
405
+ const side = tail.side;
406
+ const position = side === "top"
407
+ ? `left:${number(tail.offset)}px;top:${number(-tail.heightPx)}px`
408
+ : side === "bottom"
409
+ ? `left:${number(tail.offset)}px;bottom:${number(-tail.heightPx)}px`
410
+ : side === "left"
411
+ ? `left:${number(-tail.widthPx)}px;top:${number(tail.offset)}px`
412
+ : `right:${number(-tail.widthPx)}px;top:${number(tail.offset)}px`;
413
+ const polygon = side === "top" ? "0 100%,50% 0,100% 100%"
414
+ : side === "bottom" ? "0 0,100% 0,50% 100%"
415
+ : side === "left" ? "100% 0,0 50%,100% 100%" : "0 0,100% 50%,0 100%";
416
+ const style = `position:absolute;pointer-events:none;width:${number(tail.widthPx)}px;height:${number(tail.heightPx)}px;${position};background:${colorPaintCss(tail.paint)};clip-path:polygon(${polygon});z-index:${index}`;
417
+ return [`<span aria-hidden="true" data-hypit-text-tail="${side}" style="${context.escape(style)}"></span>`];
418
+ }).join("");
419
+ }
420
+
421
+ function flowCss(element: VisualTextFlowElement): string[] {
422
+ const flow = element.flow;
423
+ const overflow = flow.overflow === "visible" ? "visible" : "hidden";
424
+ const align = flow.inlineAlign === "start" ? "start" : flow.inlineAlign === "end" ? "end" : flow.inlineAlign;
425
+ return [
426
+ "box-sizing:border-box",
427
+ "flex-shrink:0",
428
+ `padding:${number(flow.paddingPx.blockStart)}px ${number(flow.paddingPx.inlineEnd)}px ${number(flow.paddingPx.blockEnd)}px ${number(flow.paddingPx.inlineStart)}px`,
429
+ `text-align:${align}`,
430
+ `overflow:${overflow}`,
431
+ `white-space:${flow.wrap === "none" ? "pre" : "pre-wrap"}`,
432
+ `overflow-wrap:${flow.wrap === "grapheme" ? "anywhere" : flow.wrap === "word" ? "break-word" : "normal"}`,
433
+ `word-break:${flow.wrap === "grapheme" ? "break-all" : "normal"}`,
434
+ `column-count:${flow.columns}`,
435
+ `column-gap:${number(flow.columnGapPx)}px`,
436
+ ...(flow.inlineSize === "hug" ? ["width:max-content"] : ["width:100%"]),
437
+ ...(flow.blockSize === "hug" ? ["height:max-content"] : ["height:100%"]),
438
+ ...(flow.overflow !== "ellipsis" || flow.wrap === "none" ? [] : [
439
+ "display:-webkit-box",
440
+ "-webkit-box-orient:vertical",
441
+ ...(flow.maxLines === undefined ? [] : [`-webkit-line-clamp:${flow.maxLines}`]),
442
+ ]),
443
+ ...(flow.overflow === "ellipsis" && flow.wrap === "none" ? ["text-overflow:ellipsis"] : []),
444
+ ];
445
+ }
446
+
447
+ function metricEdgeCss(
448
+ edge: VisualTextFlowElement["flow"]["metricEdge"],
449
+ trim: "trim-start" | "trim-end" | "trim-both",
450
+ ): string[] {
451
+ if (edge === "line-box") return [];
452
+ return [
453
+ `text-box-trim:${trim}`,
454
+ `text-box-edge:${edge === "cap-height" ? "cap alphabetic" : "text alphabetic"}`,
455
+ ];
456
+ }
457
+
458
+ type UnitIndices = {
459
+ paragraph: number;
460
+ run: number;
461
+ word: number;
462
+ grapheme: number;
463
+ };
464
+
465
+ function unitAnimationCss(
466
+ _element: TerminalTextElement,
467
+ _unit: VisualTextSequenceAnimation["unit"],
468
+ _index: number,
469
+ _context: TextRenderContext,
470
+ ): string[] {
471
+ // Unit-local animation is installed once as typed WAAPI keyframes after
472
+ // exact-font layout. HyperFrames owns the frame clock and seeks those
473
+ // persistent animations; no renderer script samples wall time.
474
+ return [];
475
+ }
476
+
477
+ function styleAttribute(values: readonly string[], escape: TextRenderContext["escape"]): string {
478
+ return values.length === 0 ? "" : ` style="${escape(values.join(";"))}"`;
479
+ }
480
+
481
+ function segmentRun(text: string, language: string | undefined): Array<{ text: string; wordLike: boolean }> {
482
+ const segmenter = new Intl.Segmenter(language, { granularity: "word" });
483
+ return [...segmenter.segment(text)].map((segment) => ({ text: segment.segment, wordLike: segment.isWordLike ?? false }));
484
+ }
485
+
486
+ function graphemes(text: string, language: string | undefined): string[] {
487
+ return [...new Intl.Segmenter(language, { granularity: "grapheme" }).segment(text)].map((segment) => segment.segment);
488
+ }
489
+
490
+ function textUnitCounts(document: VisualTextDocument, typography: VisualTextTypography): Record<"paragraph" | "run" | "word" | "grapheme", number> {
491
+ const result = { paragraph: document.paragraphs.length, run: 0, word: 0, grapheme: 0 };
492
+ for (const paragraph of document.paragraphs) {
493
+ const paragraphTypography = mergedTypography(typography, paragraph.style);
494
+ for (const inline of paragraph.inlines) {
495
+ if (inline.kind === "break") continue;
496
+ result.run += 1;
497
+ const runTypography = mergedTypography(paragraphTypography, inline.style);
498
+ const language = inline.language ?? runTypography.language;
499
+ for (const segment of segmentRun(inline.text, language)) {
500
+ if (segment.wordLike) result.word += 1;
501
+ result.grapheme += graphemes(segment.text, language).length;
502
+ }
503
+ }
504
+ }
505
+ return result;
506
+ }
507
+
508
+ function assertTextUnitRanges(element: TerminalTextElement): void {
509
+ const counts = textUnitCounts(element.document, element.typography);
510
+ for (const sequence of element.sequences) {
511
+ if (sequence.unit !== "line" && sequence.range.endExclusive > counts[sequence.unit]) {
512
+ throw new Error(`Text sequence ${sequence.id} selects ${sequence.unit} ${sequence.range.endExclusive}, but only ${counts[sequence.unit]} exist.`);
513
+ }
514
+ }
515
+ }
516
+
517
+ function renderDocument(
518
+ document: VisualTextDocument,
519
+ element: VisualTextFlowElement,
520
+ context: TextRenderContext,
521
+ ): string {
522
+ const indices: UnitIndices = { paragraph: 0, run: 0, word: 0, grapheme: 0 };
523
+ const renderGrapheme = (value: string, paints: readonly VisualTextPaintLayer[]): string => {
524
+ const graphemeIndex = indices.grapheme++;
525
+ const styles = [
526
+ "position:relative",
527
+ "display:inline-grid",
528
+ ...boxCss(paints, "grapheme", "isolated"),
529
+ ...unitAnimationCss(element, "grapheme", graphemeIndex, context),
530
+ ];
531
+ return `<span data-hypit-text-unit-grapheme="${graphemeIndex}"${styleAttribute(styles, context.escape)}>${tailHtml(paints, "grapheme", context, "isolated")}${renderGlyphPaint(value, paints, context)}</span>`;
532
+ };
533
+ return document.paragraphs.map((paragraph, paragraphPosition) => {
534
+ const paragraphIndex = indices.paragraph++;
535
+ const paragraphTypography = mergedTypography(element.typography, paragraph.style);
536
+ const paragraphPaints = paragraph.style?.paints ?? element.paints;
537
+ const content = paragraph.inlines.map((inline) => {
538
+ if (inline.kind === "break") return "<br/>";
539
+ const runIndex = indices.run++;
540
+ const typography = mergedTypography(paragraphTypography, inline.style);
541
+ const paints = inline.style?.paints ?? paragraphPaints;
542
+ const runContents = segmentRun(inline.text, inline.language ?? typography.language).map((segment) => {
543
+ if (!segment.wordLike) {
544
+ return graphemes(segment.text, inline.language ?? typography.language).map((grapheme) => renderGrapheme(grapheme, paints)).join("");
545
+ }
546
+ const wordIndex = indices.word++;
547
+ const wordContent = graphemes(segment.text, inline.language ?? typography.language).map((grapheme) => renderGrapheme(grapheme, paints)).join("");
548
+ return `<span data-hypit-text-unit-word="${wordIndex}"${styleAttribute([
549
+ "position:relative",
550
+ ...boxCss(paints, "word", "isolated"),
551
+ ...unitAnimationCss(element, "word", wordIndex, context),
552
+ ], context.escape)}>${tailHtml(paints, "word", context, "isolated")}${wordContent}</span>`;
553
+ }).join("");
554
+ const runStyle = [
555
+ "position:relative",
556
+ "box-decoration-break:clone",
557
+ "-webkit-box-decoration-break:clone",
558
+ ...typographyCss(typography, context.exactFontFamily),
559
+ ...inheritedGlyphColor(paints),
560
+ ...boxCss(paints, "run"),
561
+ ...boxCss(paints, "word", "joined"),
562
+ ...boxCss(paints, "grapheme", "joined"),
563
+ ...unitAnimationCss(element, "run", runIndex, context),
564
+ ];
565
+ return `<span data-hypit-text-run="${context.escape(inline.id)}" data-hypit-text-unit-run="${runIndex}" ${textLanguageAttributes(typography, context.escape, inline.language, inline.direction)}${styleAttribute(runStyle, context.escape)}>${tailHtml(paints, "run", context)}${tailHtml(paints, "word", context, "joined")}${tailHtml(paints, "grapheme", context, "joined")}${runContents}</span>`;
566
+ }).join("");
567
+ const paragraphStyle = [
568
+ "position:relative",
569
+ `margin:${number(paragraphTypography.paragraphBeforePx)}px 0 ${number(paragraphTypography.paragraphAfterPx)}px 0`,
570
+ ...boxCss(paragraphPaints, "paragraph"),
571
+ ...unitAnimationCss(element, "paragraph", paragraphIndex, context),
572
+ ];
573
+ const isFirstParagraph = paragraphPosition === 0;
574
+ const isLastParagraph = paragraphPosition === document.paragraphs.length - 1;
575
+ const metricTrim = isFirstParagraph && isLastParagraph
576
+ ? "trim-both"
577
+ : isFirstParagraph ? "trim-start" : isLastParagraph ? "trim-end" : undefined;
578
+ const lineFragments = `<span data-hypit-text-line-fragments${styleAttribute([
579
+ "position:relative",
580
+ "box-decoration-break:clone",
581
+ "-webkit-box-decoration-break:clone",
582
+ ...boxCss(paragraphPaints, "line"),
583
+ ], context.escape)}>${tailHtml(paragraphPaints, "line", context)}${content}</span>`;
584
+ const measuredText = element.flow.metricEdge === "line-box" || metricTrim === undefined
585
+ ? lineFragments
586
+ : `<span data-hypit-text-metrics${styleAttribute([
587
+ "display:block",
588
+ ...metricEdgeCss(element.flow.metricEdge, metricTrim),
589
+ ], context.escape)}>${lineFragments}</span>`;
590
+ return `<div data-hypit-text-paragraph="${context.escape(paragraph.id)}" data-hypit-text-unit-paragraph="${paragraphIndex}" ${textLanguageAttributes(paragraphTypography, context.escape)}${styleAttribute(paragraphStyle, context.escape)}>${tailHtml(paragraphPaints, "paragraph", context)}${measuredText}</div>`;
591
+ }).join("");
592
+ }
593
+
594
+ function pathData(commands: readonly VisualVectorPathCommand[]): string {
595
+ return commands.map((command) => {
596
+ if (command.kind === "move") return `M ${number(command.x)} ${number(command.y)}`;
597
+ if (command.kind === "line") return `L ${number(command.x)} ${number(command.y)}`;
598
+ if (command.kind === "quadratic") return `Q ${number(command.controlX)} ${number(command.controlY)} ${number(command.x)} ${number(command.y)}`;
599
+ if (command.kind === "cubic") return `C ${number(command.control1X)} ${number(command.control1Y)} ${number(command.control2X)} ${number(command.control2Y)} ${number(command.x)} ${number(command.y)}`;
600
+ return "Z";
601
+ }).join(" ");
602
+ }
603
+
604
+ type PathSegment = (
605
+ | { readonly kind: "line"; readonly x: number; readonly y: number }
606
+ | { readonly kind: "quadratic"; readonly controlX: number; readonly controlY: number; readonly x: number; readonly y: number }
607
+ | { readonly kind: "cubic"; readonly control1X: number; readonly control1Y: number; readonly control2X: number; readonly control2Y: number; readonly x: number; readonly y: number }
608
+ ) & { readonly from: { readonly x: number; readonly y: number } };
609
+
610
+ function reversePath(commands: readonly VisualVectorPathCommand[]): VisualVectorPathCommand[] {
611
+ const result: VisualVectorPathCommand[] = [];
612
+ let start: { x: number; y: number } | undefined;
613
+ let current: { x: number; y: number } | undefined;
614
+ let segments: PathSegment[] = [];
615
+ let closed = false;
616
+ const flush = (): void => {
617
+ if (start === undefined || current === undefined) return;
618
+ const reversed = [...segments].reverse();
619
+ result.push({ kind: "move", x: current.x, y: current.y });
620
+ for (const segment of reversed) {
621
+ if (segment.kind === "line") result.push({ kind: "line", x: segment.from.x, y: segment.from.y });
622
+ else if (segment.kind === "quadratic") result.push({ kind: "quadratic", controlX: segment.controlX, controlY: segment.controlY, x: segment.from.x, y: segment.from.y });
623
+ else result.push({
624
+ kind: "cubic", control1X: segment.control2X, control1Y: segment.control2Y,
625
+ control2X: segment.control1X, control2Y: segment.control1Y, x: segment.from.x, y: segment.from.y,
626
+ });
627
+ }
628
+ if (closed) result.push({ kind: "close" });
629
+ start = undefined; current = undefined; segments = []; closed = false;
630
+ };
631
+ for (const command of commands) {
632
+ if (command.kind === "move") {
633
+ flush();
634
+ start = { x: command.x, y: command.y };
635
+ current = start;
636
+ } else if (command.kind === "close") {
637
+ if (start === undefined || current === undefined) throw new Error("Path close has no open subpath.");
638
+ if (current.x !== start.x || current.y !== start.y) segments.push({ kind: "line", from: current, x: start.x, y: start.y });
639
+ current = start;
640
+ closed = true;
641
+ } else {
642
+ if (current === undefined) throw new Error("Path segment has no current point.");
643
+ if (command.kind === "line") segments.push({ kind: "line", x: command.x, y: command.y, from: current });
644
+ else if (command.kind === "quadratic") segments.push({ ...command, from: current });
645
+ else if (command.kind === "cubic") segments.push({ ...command, from: current });
646
+ else throw new Error("Path segment is unsupported.");
647
+ current = { x: command.x, y: command.y };
648
+ }
649
+ }
650
+ flush();
651
+ return result;
652
+ }
653
+
654
+ function allDocumentPaints(element: TerminalTextElement): VisualColorPaint[] {
655
+ const result: VisualColorPaint[] = [];
656
+ const append = (paints: readonly VisualTextPaintLayer[] | undefined): void => {
657
+ for (const layer of paints ?? []) {
658
+ if (layer.kind === "box") {
659
+ if (layer.decoration.fill !== undefined) result.push(layer.decoration.fill);
660
+ if (layer.decoration.border !== undefined) result.push(layer.decoration.border.paint);
661
+ } else result.push(layer.paint);
662
+ }
663
+ };
664
+ append(element.paints);
665
+ for (const paragraph of element.document.paragraphs) {
666
+ append(paragraph.style?.paints);
667
+ for (const inline of paragraph.inlines) if (inline.kind === "text") append(inline.style?.paints);
668
+ }
669
+ return [...new Map(result.map((paint) => [canonicalStringify(paint), paint])).values()];
670
+ }
671
+
672
+ function svgPaintId(paint: VisualColorPaint, context: TextRenderContext): string {
673
+ return context.stableId([context.trackId, context.presentId, "text-paint", canonicalStringify(paint)]);
674
+ }
675
+
676
+ function svgPaintValue(paint: VisualColorPaint, context: TextRenderContext): string {
677
+ return paint.kind === "solid" ? paint.color : `url(#${svgPaintId(paint, context)})`;
678
+ }
679
+
680
+ function svgPaintDefinitions(element: TerminalTextElement, context: TextRenderContext): string {
681
+ return allDocumentPaints(element).flatMap((paint) => {
682
+ if (paint.kind === "solid") return [];
683
+ const stops = paint.stops.map((stop) => `<stop offset="${number(stop.offset * 100)}%" stop-color="${context.escape(stop.color)}" stop-opacity="${number(stop.opacity)}"/>`).join("");
684
+ const id = svgPaintId(paint, context);
685
+ if (paint.kind === "radial-gradient") {
686
+ return [`<radialGradient id="${id}" cx="${number(paint.center.x * 100)}%" cy="${number(paint.center.y * 100)}%" r="70.710678%">${stops}</radialGradient>`];
687
+ }
688
+ const radians = (paint.angleDeg - 90) * Math.PI / 180;
689
+ const x = Math.cos(radians) * 50;
690
+ const y = Math.sin(radians) * 50;
691
+ return [`<linearGradient id="${id}" x1="${number(50 - x)}%" y1="${number(50 - y)}%" x2="${number(50 + x)}%" y2="${number(50 + y)}%">${stops}</linearGradient>`];
692
+ }).join("");
693
+ }
694
+
695
+ function svgGlyphLayerCss(paint: GlyphPaintLayer | undefined, context: TextRenderContext): string[] {
696
+ if (paint === undefined) return ["fill:transparent", "stroke:none", "filter:none"];
697
+ if (paint.kind === "fill") return [`fill:${svgPaintValue(paint.paint, context)}`, "stroke:none", "filter:none"];
698
+ // The same morphology/filter definition used by flow Text gives Path Text
699
+ // exact inside/center/outside rings, spread, blur and ordered effects. A
700
+ // gradient effect is deliberately materialized rather than approximated.
701
+ glyphFilterDefinition(paint, context);
702
+ return ["fill:#ffffff", "stroke:none", `filter:url(#${glyphFilterId(paint, context)})`];
703
+ }
704
+
705
+ function pathPaintLayerCount(element: VisualPathTextElement): number {
706
+ let count = glyphPaintLayers(element.paints).length;
707
+ const inspect = (paints: readonly VisualTextPaintLayer[] | undefined): void => {
708
+ for (const paint of paints ?? []) {
709
+ if (paint.kind === "box") {
710
+ throw new Error("HyperFrames Path Text requires Box Paint to be materialized by its owning package.");
711
+ }
712
+ }
713
+ count = Math.max(count, glyphPaintLayers(paints ?? []).length);
714
+ };
715
+ inspect(element.paints);
716
+ for (const paragraph of element.document.paragraphs) {
717
+ inspect(paragraph.style?.paints);
718
+ for (const inline of paragraph.inlines) if (inline.kind === "text") inspect(inline.style?.paints);
719
+ }
720
+ return Math.max(1, count);
721
+ }
722
+
723
+ function renderPathDocument(element: VisualPathTextElement, context: TextRenderContext, layerIndex: number): string {
724
+ const indices: UnitIndices = { paragraph: 0, run: 0, word: 0, grapheme: 0 };
725
+ return element.document.paragraphs.map((paragraph, paragraphPosition) => {
726
+ const paragraphIndex = indices.paragraph++;
727
+ const paragraphTypography = mergedTypography(element.typography, paragraph.style);
728
+ const paragraphPaints = paragraph.style?.paints ?? element.paints;
729
+ const content = paragraph.inlines.map((inline) => {
730
+ if (inline.kind === "break") return " ";
731
+ const runIndex = indices.run++;
732
+ const typography = mergedTypography(paragraphTypography, inline.style);
733
+ const paints = inline.style?.paints ?? paragraphPaints;
734
+ const paint = glyphPaintLayers(paints)[layerIndex];
735
+ const text = segmentRun(inline.text, inline.language ?? typography.language).map((segment) => {
736
+ if (!segment.wordLike) return graphemes(segment.text, inline.language ?? typography.language).map((value) => {
737
+ const index = indices.grapheme++;
738
+ return `<tspan data-hypit-text-unit-grapheme="${index}"${styleAttribute(unitAnimationCss(element, "grapheme", index, context), context.escape)}>${context.escape(value)}</tspan>`;
739
+ }).join("");
740
+ const word = indices.word++;
741
+ const value = graphemes(segment.text, inline.language ?? typography.language).map((item) => {
742
+ const index = indices.grapheme++;
743
+ return `<tspan data-hypit-text-unit-grapheme="${index}"${styleAttribute(unitAnimationCss(element, "grapheme", index, context), context.escape)}>${context.escape(item)}</tspan>`;
744
+ }).join("");
745
+ return `<tspan data-hypit-text-unit-word="${word}"${styleAttribute(unitAnimationCss(element, "word", word, context), context.escape)}>${value}</tspan>`;
746
+ }).join("");
747
+ const style = [...typographyCss(typography, context.exactFontFamily), ...svgGlyphLayerCss(paint, context), ...unitAnimationCss(element, "run", runIndex, context)];
748
+ return `<tspan data-hypit-text-unit-run="${runIndex}" ${textLanguageAttributes(typography, context.escape, inline.language, inline.direction)}${styleAttribute(style, context.escape)}>${text}</tspan>`;
749
+ }).join("");
750
+ const separator = paragraphPosition === 0 ? "" : " ";
751
+ return `${separator}<tspan data-hypit-text-unit-paragraph="${paragraphIndex}"${styleAttribute(unitAnimationCss(element, "paragraph", paragraphIndex, context), context.escape)}>${content}</tspan>`;
752
+ }).join("");
753
+ }
754
+
755
+ export function renderTerminalTextElement(element: TerminalTextElement, context: TextRenderContext): string {
756
+ assertTextUnitRanges(element);
757
+ const clockAttributes = `data-hypit-text-clock data-hypit-text-start-frame="${context.presentStartFrame}" data-hypit-text-frame-numerator="${context.programNumerator}" data-hypit-text-frame-denominator="${context.programDenominator}"`;
758
+ const sequenceAttributes = element.sequences.length === 0 ? "" : ` data-hypit-text-sequences="${context.escape(JSON.stringify(element.sequences))}" data-hypit-text-duration-frames="${context.durationFrames}"`;
759
+ if (element.kind === "path-text") {
760
+ const pathId = context.stableId([context.trackId, context.presentId, element.id, "path"]);
761
+ const anchor = element.align === "start" ? "start" : element.align === "end" ? "end" : "middle";
762
+ const offset = element.marginAnimation?.keyframes[0]?.startMarginPx
763
+ ?? (element.align === "start" ? element.startMarginPx : element.align === "end" ? "100%" : "50%");
764
+ const placementData = element.marginAnimation === undefined
765
+ ? ` data-hypit-text-path-placement="${context.escape(JSON.stringify({
766
+ align: element.align, startMarginPx: element.startMarginPx, endMarginPx: element.endMarginPx,
767
+ }))}"`
768
+ : ` data-hypit-text-path-margin="${context.escape(JSON.stringify({
769
+ startFrame: context.presentStartFrame,
770
+ numerator: context.programNumerator,
771
+ denominator: context.programDenominator,
772
+ align: element.align,
773
+ endMarginPx: element.endMarginPx,
774
+ keyframes: element.marginAnimation.keyframes,
775
+ }))}"`;
776
+ const layerCount = pathPaintLayerCount(element);
777
+ const layers = Array.from({ length: layerCount }, (_, layerIndex) => {
778
+ const textCss = [...typographyCss(element.typography, context.exactFontFamily), "fill:transparent", "stroke:none"].join(";");
779
+ return `<text aria-hidden="${layerIndex === layerCount - 1 ? "false" : "true"}" data-hypit-text-path-paint-layer="${layerIndex}" style="${context.escape(textCss)}" text-anchor="${anchor}" dominant-baseline="central"><textPath href="#${pathId}" startOffset="${typeof offset === "number" ? number(offset) : offset}" side="${element.side}"${placementData}${element.orientation === "upright" ? ' data-hypit-text-path-upright="true"' : ""}>${renderPathDocument(element, context, layerIndex)}</textPath></text>`;
780
+ }).join("");
781
+ return `<svg ${context.commonAttributes} ${clockAttributes}${sequenceAttributes} ${textLanguageAttributes(element.typography, context.escape)} width="100%" height="100%" style="${context.escape(`${context.baseStyle};overflow:${element.overflow === "clip" ? "hidden" : "visible"}`)}"><defs><path id="${pathId}" d="${context.escape(pathData(element.reverse ? reversePath(element.path) : element.path))}"/>${svgPaintDefinitions(element, context)}${glyphFilterDefinitions(element, context)}</defs>${layers}</svg>`;
782
+ }
783
+ const rootStyle = [
784
+ context.baseStyle,
785
+ "display:flex",
786
+ `align-items:${element.flow.blockAlign === "start" ? "flex-start" : element.flow.blockAlign === "end" ? "flex-end" : "center"}`,
787
+ `justify-content:${element.flow.inlineAlign === "start" ? "flex-start" : element.flow.inlineAlign === "end" ? "flex-end" : "center"}`,
788
+ ...(element.flow.clipToFrame ? ["overflow:hidden"] : []),
789
+ ...boxCss(element.paints, "frame"),
790
+ ];
791
+ const contentStyle = [
792
+ "position:relative",
793
+ ...flowCss(element),
794
+ ...typographyCss(element.typography, context.exactFontFamily),
795
+ ...inheritedGlyphColor(element.paints),
796
+ ...boxCss(element.paints, "content"),
797
+ ];
798
+ const lineSequences = element.sequences.filter((sequence) => sequence.unit === "line");
799
+ const layoutData = [
800
+ `data-hypit-text-overflow="${element.flow.overflow}"`,
801
+ `data-hypit-text-inline-size="${element.flow.inlineSize}"`,
802
+ `data-hypit-text-block-size="${element.flow.blockSize}"`,
803
+ `data-hypit-text-inline-align="${element.flow.inlineAlign}"`,
804
+ `data-hypit-text-block-align="${element.flow.blockAlign}"`,
805
+ `data-hypit-text-writing-mode="${element.typography.writingMode}"`,
806
+ ...(element.flow.minimumScale === undefined ? [] : [`data-hypit-text-minimum-scale="${number(element.flow.minimumScale)}"`]),
807
+ ...(element.flow.maxLines === undefined ? [] : [`data-hypit-text-max-lines="${element.flow.maxLines}"`]),
808
+ ].join(" ");
809
+ const lineData = lineSequences.length === 0 ? "" : ` data-hypit-text-line-sequences="${context.escape(JSON.stringify(lineSequences))}"`;
810
+ return `<div ${context.commonAttributes} ${clockAttributes}${sequenceAttributes} ${textLanguageAttributes(element.typography, context.escape)} style="${context.escape(rootStyle.join(";"))}">${glyphPaintDefinitions(element, context)}${tailHtml(element.paints, "frame", context)}<div data-hypit-text-flow ${layoutData}${lineData}${styleAttribute(contentStyle, context.escape)}>${tailHtml(element.paints, "content", context)}${renderDocument(element.document, element, context)}</div></div>`;
811
+ }
812
+
813
+ export function collectTerminalTextFonts(element: TerminalTextElement): FontArtifactRef[] {
814
+ const result: FontArtifactRef[] = [...element.typography.fonts];
815
+ for (const paragraph of element.document.paragraphs) {
816
+ result.push(...(paragraph.style?.typography?.fonts ?? []));
817
+ for (const inline of paragraph.inlines) {
818
+ if (inline.kind === "text") result.push(...(inline.style?.typography?.fonts ?? []));
819
+ }
820
+ }
821
+ const unique = new Map(result.map((font) => [canonicalStringify(font), font]));
822
+ return [...unique.values()];
823
+ }
824
+
825
+ /** Renderer-owned deterministic post-layout step for physical-line selectors. */
826
+ export const terminalTextLayoutScript = String.raw`
827
+ const svmlTextEase = (name, value) => {
828
+ if (name === 'ease-in') return value * value;
829
+ if (name === 'ease-out') return 1 - (1 - value) * (1 - value);
830
+ if (name === 'ease-in-out') return value < 0.5 ? 2 * value * value : 1 - Math.pow(-2 * value + 2, 2) / 2;
831
+ return value;
832
+ };
833
+ const svmlUpdateUprightTextPaths = () => {
834
+ for (const path of document.querySelectorAll('[data-hypit-text-path-upright]')) {
835
+ for (const glyph of path.querySelectorAll('[data-hypit-text-unit-grapheme]')) {
836
+ try {
837
+ glyph.removeAttribute('rotate');
838
+ const pathRotation = glyph.getRotationOfChar(0);
839
+ glyph.setAttribute('rotate', String(-pathRotation));
840
+ } catch (error) {
841
+ throw new Error('Upright Path Text could not resolve exact glyph orientation.', { cause: error });
842
+ }
843
+ }
844
+ }
845
+ };
846
+ const svmlUpdateStaticTextPathPlacements = () => {
847
+ for (const textPath of document.querySelectorAll('[data-hypit-text-path-placement]')) {
848
+ const data = JSON.parse(textPath.getAttribute('data-hypit-text-path-placement'));
849
+ const href = textPath.getAttribute('href');
850
+ const path = href && document.getElementById(href.slice(1));
851
+ if (!path || typeof path.getTotalLength !== 'function') throw new Error('Path Text cannot resolve its owned vector path.');
852
+ const length = path.getTotalLength();
853
+ const start = data.startMarginPx;
854
+ const end = length - data.endMarginPx;
855
+ if (end < start) throw new Error('Path Text margins exceed the owned path length.');
856
+ textPath.setAttribute('startOffset', String(data.align === 'start' ? start : data.align === 'end' ? end : (start + end) / 2));
857
+ }
858
+ };
859
+ const svmlUpdateTextPathMargins = (time) => {
860
+ for (const path of document.querySelectorAll('[data-hypit-text-path-margin]')) {
861
+ const data = JSON.parse(path.getAttribute('data-hypit-text-path-margin'));
862
+ const frames = data.keyframes;
863
+ // HyperFrames may reach the same source frame through an incremental seek
864
+ // or a fresh worker seek. Quantize the absolute clock back to the authored
865
+ // integer frame before evaluating package-owned motion so both routes are
866
+ // byte-identical.
867
+ const local = Math.round(time * data.numerator / data.denominator - data.startFrame);
868
+ let value = frames[0].startMarginPx;
869
+ if (local >= frames[frames.length - 1].atFrame) value = frames[frames.length - 1].startMarginPx;
870
+ else {
871
+ for (let index = 0; index < frames.length - 1; index += 1) {
872
+ const left = frames[index];
873
+ const right = frames[index + 1];
874
+ if (local < left.atFrame || local > right.atFrame) continue;
875
+ const progress = svmlTextEase(left.easing || 'linear', (local - left.atFrame) / (right.atFrame - left.atFrame));
876
+ value = left.startMarginPx + (right.startMarginPx - left.startMarginPx) * progress;
877
+ break;
878
+ }
879
+ }
880
+ const href = path.getAttribute('href');
881
+ const geometry = href && document.getElementById(href.slice(1));
882
+ if (!geometry || typeof geometry.getTotalLength !== 'function') throw new Error('Animated Path Text cannot resolve its owned vector path.');
883
+ const end = geometry.getTotalLength() - data.endMarginPx;
884
+ if (end < value) throw new Error('Animated Path Text margins exceed the owned path length.');
885
+ path.setAttribute('startOffset', String(data.align === 'start' ? value : data.align === 'end' ? end : (value + end) / 2));
886
+ }
887
+ svmlUpdateUprightTextPaths();
888
+ };
889
+ const svmlTextUnitBaseStyles = new WeakMap();
890
+ const svmlTextAnimatedStyleNames = ['-webkit-text-fill-color', '-webkit-text-stroke-color', 'background-color', 'color', 'filter', 'opacity', 'transform'];
891
+ const svmlTextPropertyName = (name) => {
892
+ if (name === '-webkit-text-fill-color') return 'webkitTextFillColor';
893
+ if (name === '-webkit-text-stroke-color') return 'webkitTextStrokeColor';
894
+ if (name === 'background-color') return 'backgroundColor';
895
+ return name;
896
+ };
897
+ const svmlTextSeededOrder = (length, seed) => {
898
+ const result = Array.from({ length }, (_, index) => index);
899
+ let state = seed >>> 0;
900
+ for (let index = result.length - 1; index > 0; index -= 1) {
901
+ state = (Math.imul(state, 1664525) + 1013904223) >>> 0;
902
+ const selected = state % (index + 1);
903
+ [result[index], result[selected]] = [result[selected], result[index]];
904
+ }
905
+ return result;
906
+ };
907
+ const svmlTextSequenceRank = (sequence, index) => {
908
+ if (index < sequence.range.start || index >= sequence.range.endExclusive) return null;
909
+ const length = sequence.range.endExclusive - sequence.range.start;
910
+ const local = index - sequence.range.start;
911
+ if (sequence.order === 'forward') return local;
912
+ if (sequence.order === 'reverse') return length - 1 - local;
913
+ return svmlTextSeededOrder(length, sequence.seed || 0).indexOf(local);
914
+ };
915
+ const svmlTextSequenceClock = (sequence, rank, frame) => {
916
+ const start = sequence.startFrame + rank * sequence.staggerFrames;
917
+ const end = start + sequence.unitDurationFrames * sequence.cycles;
918
+ if (frame <= start) return 0;
919
+ if (frame >= end) return sequence.unitDurationFrames;
920
+ // Every cycle is a half-open interval. At an exact cycle boundary the next
921
+ // cycle begins at progress zero; the result therefore depends only on this
922
+ // absolute authored frame, never on which partition rendered the previous
923
+ // frame. A repeated keyframe-offset list cannot express that law reliably
924
+ // across fresh and incrementally-seeked browser animation instances.
925
+ return (frame - start) % sequence.unitDurationFrames;
926
+ };
927
+ const svmlTextSequenceProgress = (sequence, clock) => {
928
+ const progress = clock / sequence.unitDurationFrames;
929
+ let left = sequence.keyframes[0];
930
+ let right = sequence.keyframes[sequence.keyframes.length - 1];
931
+ for (let index = 0; index < sequence.keyframes.length - 1; index += 1) {
932
+ if (progress < sequence.keyframes[index].atProgress || progress > sequence.keyframes[index + 1].atProgress) continue;
933
+ left = sequence.keyframes[index];
934
+ right = sequence.keyframes[index + 1];
935
+ break;
936
+ }
937
+ const width = right.atProgress - left.atProgress;
938
+ return {
939
+ left,
940
+ right,
941
+ progress: svmlTextEase(left.easing || 'linear', width <= 0 ? 1 : (progress - left.atProgress) / width),
942
+ };
943
+ };
944
+ const svmlSeekTextUnitAnimations = (time) => {
945
+ const unitSelector = '[data-hypit-text-unit-paragraph],[data-hypit-text-unit-run],[data-hypit-text-unit-word],[data-hypit-text-unit-grapheme]';
946
+ for (const root of document.querySelectorAll('[data-hypit-text-clock][data-hypit-text-sequences]')) {
947
+ const startFrame = Number(root.getAttribute('data-hypit-text-start-frame'));
948
+ const numerator = Number(root.getAttribute('data-hypit-text-frame-numerator'));
949
+ const denominator = Number(root.getAttribute('data-hypit-text-frame-denominator'));
950
+ const durationFrames = Number(root.getAttribute('data-hypit-text-duration-frames'));
951
+ if (!Number.isSafeInteger(startFrame) || !Number.isSafeInteger(numerator) || !Number.isSafeInteger(denominator)
952
+ || !Number.isSafeInteger(durationFrames) || numerator <= 0 || denominator <= 0 || durationFrames <= 0) {
953
+ throw new Error('Invalid terminal Text animation clock.');
954
+ }
955
+ const sequences = JSON.parse(root.getAttribute('data-hypit-text-sequences') || '[]');
956
+ const localFrame = Math.max(0, Math.min(durationFrames, Math.round(time * numerator / denominator - startFrame)));
957
+ for (const unit of root.querySelectorAll(unitSelector)) {
958
+ let base = svmlTextUnitBaseStyles.get(unit);
959
+ if (!base) {
960
+ base = Object.fromEntries(svmlTextAnimatedStyleNames.map((name) => [name, unit.style.getPropertyValue(name)]));
961
+ svmlTextUnitBaseStyles.set(unit, base);
962
+ }
963
+ for (const name of svmlTextAnimatedStyleNames) {
964
+ if (base[name]) unit.style.setProperty(name, base[name]);
965
+ else unit.style.removeProperty(name);
966
+ }
967
+ for (const sequence of sequences) {
968
+ const attribute = sequence.unit === 'line' ? 'data-hypit-text-physical-line' : 'data-hypit-text-unit-' + sequence.unit;
969
+ if (!unit.hasAttribute(attribute)) continue;
970
+ const index = Number(unit.getAttribute(attribute));
971
+ const rank = Number.isSafeInteger(index) ? svmlTextSequenceRank(sequence, index) : null;
972
+ if (rank === null) continue;
973
+ const clock = svmlTextSequenceClock(sequence, rank, localFrame);
974
+ const keyframes = sequence.keyframes.map((point) => {
975
+ const frame = { offset: point.atProgress, ...(point.easing ? { easing: point.easing } : {}) };
976
+ for (const declaration of point.style) frame[svmlTextPropertyName(declaration.name)] = declaration.value;
977
+ return frame;
978
+ });
979
+ const nativeAnimate = Element.prototype.__hfOriginalAnimate;
980
+ const animation = typeof nativeAnimate === 'function'
981
+ ? nativeAnimate.call(unit, keyframes, { duration: sequence.unitDurationFrames, fill: 'both', iterations: 1 })
982
+ : unit.animate(keyframes, { duration: sequence.unitDurationFrames, fill: 'both', iterations: 1 });
983
+ animation.pause();
984
+ animation.currentTime = clock;
985
+ const animatedNames = [...new Set(sequence.keyframes.flatMap((keyframe) => keyframe.style.map((declaration) => declaration.name)))];
986
+ const computed = getComputedStyle(unit);
987
+ const sampled = Object.fromEntries(animatedNames.map((name) => [name, computed.getPropertyValue(name)]));
988
+ animation.cancel();
989
+ if (animatedNames.includes('opacity')) {
990
+ const { left, right, progress } = svmlTextSequenceProgress(sequence, clock);
991
+ const leftValue = left.style.find((declaration) => declaration.name === 'opacity')?.value;
992
+ const rightValue = right.style.find((declaration) => declaration.name === 'opacity')?.value;
993
+ if (typeof leftValue === 'number' && typeof rightValue === 'number') sampled.opacity = String(leftValue + (rightValue - leftValue) * progress);
994
+ }
995
+ for (const name of animatedNames) unit.style.setProperty(name, sampled[name]);
996
+ }
997
+ }
998
+ }
999
+ };
1000
+ const svmlTextComposition = document.querySelector('[data-composition-id]');
1001
+ if (!svmlTextComposition) throw new Error('Terminal Text could not resolve the containing HyperFrames composition.');
1002
+ const svmlTextCompositionId = svmlTextComposition.getAttribute('data-composition-id');
1003
+ if (!svmlTextCompositionId) throw new Error('Terminal Text composition identity is empty.');
1004
+ let svmlTextAbsoluteTime = 0;
1005
+ let svmlTextReady = false;
1006
+ const svmlTextTimeline = {
1007
+ pause() { return this; },
1008
+ seek(time) { return this.totalTime(time); },
1009
+ totalTime(time) {
1010
+ if (time === undefined) return svmlTextAbsoluteTime;
1011
+ // Register and remember seeks synchronously, even while exact fonts are
1012
+ // still loading. A worker may begin at any frame; once layout becomes
1013
+ // ready the latest requested absolute frame is evaluated exactly once.
1014
+ svmlTextAbsoluteTime = Math.max(0, Number(time) || 0);
1015
+ if (svmlTextReady) {
1016
+ svmlSeekTextUnitAnimations(svmlTextAbsoluteTime);
1017
+ svmlUpdateTextPathMargins(svmlTextAbsoluteTime);
1018
+ // Attribute changes on SVG text paths and browser text layout are
1019
+ // sampled synchronously for the exact authored frame. Do not wait for a
1020
+ // requestAnimationFrame from HyperFrames' seek barrier: capture is
1021
+ // paused behind that barrier, so doing so would deadlock both clocks.
1022
+ document.documentElement.getBoundingClientRect();
1023
+ }
1024
+ return this;
1025
+ },
1026
+ };
1027
+ window.__timelines = window.__timelines || {};
1028
+ window.__timelines[svmlTextCompositionId] = svmlTextTimeline;
1029
+ if (typeof window.__hfForceTimelineRebind === 'function') window.__hfForceTimelineRebind();
1030
+ const svmlTextLayoutReady = document.fonts.ready.then(() => {
1031
+ svmlUpdateStaticTextPathPlacements();
1032
+ svmlUpdateUprightTextPaths();
1033
+ const physicalLines = (flow) => {
1034
+ const values = [];
1035
+ const vertical = flow.getAttribute('data-hypit-text-writing-mode') !== 'horizontal-tb';
1036
+ for (const glyph of flow.querySelectorAll('[data-hypit-text-unit-grapheme]')) {
1037
+ const rect = glyph.getBoundingClientRect();
1038
+ const axis = vertical ? rect.left : rect.top;
1039
+ if (!values.some((value) => Math.abs(value - axis) < 0.5)) values.push(axis);
1040
+ }
1041
+ return values;
1042
+ };
1043
+ for (const flow of document.querySelectorAll('[data-hypit-text-flow][data-hypit-text-overflow="ellipsis"]')) {
1044
+ if (flow.getAttribute('data-hypit-text-max-lines') || getComputedStyle(flow).whiteSpace === 'pre') continue;
1045
+ const parent = flow.parentElement;
1046
+ if (!parent) throw new Error('Ellipsis Text has no placement frame.');
1047
+ const vertical = flow.getAttribute('data-hypit-text-writing-mode') !== 'horizontal-tb';
1048
+ const boundary = parent.getBoundingClientRect();
1049
+ const groups = [];
1050
+ for (const glyph of flow.querySelectorAll('[data-hypit-text-unit-grapheme]')) {
1051
+ const rect = glyph.getBoundingClientRect();
1052
+ const axis = vertical ? rect.left : rect.top;
1053
+ let group = groups.find((item) => Math.abs(item.axis - axis) < 0.5);
1054
+ if (!group) { group = { axis, rects: [] }; groups.push(group); }
1055
+ group.rects.push(rect);
1056
+ }
1057
+ const visible = groups.filter((group) => group.rects.some((rect) => vertical
1058
+ ? rect.left >= boundary.left - 0.5 && rect.right <= boundary.right + 0.5
1059
+ : rect.top >= boundary.top - 0.5 && rect.bottom <= boundary.bottom + 0.5)).length;
1060
+ flow.style.webkitLineClamp = String(Math.max(1, visible));
1061
+ }
1062
+ for (const flow of document.querySelectorAll('[data-hypit-text-flow][data-hypit-text-overflow="shrink"]')) {
1063
+ const minimum = Number(flow.getAttribute('data-hypit-text-minimum-scale'));
1064
+ const maximumLines = Number(flow.getAttribute('data-hypit-text-max-lines') || '0');
1065
+ const inlineSize = flow.getAttribute('data-hypit-text-inline-size');
1066
+ const blockSize = flow.getAttribute('data-hypit-text-block-size');
1067
+ const inlineAlign = flow.getAttribute('data-hypit-text-inline-align');
1068
+ const blockAlign = flow.getAttribute('data-hypit-text-block-align');
1069
+ const parent = flow.parentElement;
1070
+ if (!parent || !Number.isFinite(minimum) || minimum <= 0 || minimum > 1
1071
+ || (inlineSize !== 'fixed' && inlineSize !== 'hug')
1072
+ || (blockSize !== 'fixed' && blockSize !== 'hug')) throw new Error('Invalid bounded Text shrink request.');
1073
+ const availableWidth = parent.clientWidth;
1074
+ const availableHeight = parent.clientHeight;
1075
+ const apply = (scale) => {
1076
+ flow.style.position = 'relative';
1077
+ flow.style.left = '';
1078
+ flow.style.top = '';
1079
+ flow.style.zoom = '';
1080
+ const inlineOrigin = inlineAlign === 'start' ? 'left' : inlineAlign === 'end' ? 'right' : 'center';
1081
+ const blockOrigin = blockAlign === 'start' ? 'top' : blockAlign === 'end' ? 'bottom' : 'center';
1082
+ flow.style.transformOrigin = inlineOrigin + ' ' + blockOrigin;
1083
+ flow.style.transform = 'scale(' + scale + ')';
1084
+ flow.style.width = inlineSize === 'fixed' ? String(100 / scale) + '%' : 'max-content';
1085
+ flow.style.height = blockSize === 'fixed' ? String(100 / scale) + '%' : 'max-content';
1086
+ };
1087
+ const measure = (scale) => {
1088
+ apply(scale);
1089
+ const lines = physicalLines(flow).length;
1090
+ const boundary = parent.getBoundingClientRect();
1091
+ const glyphRects = [...flow.querySelectorAll('[data-hypit-text-unit-grapheme]')]
1092
+ .map((glyph) => glyph.getBoundingClientRect());
1093
+ const left = glyphRects.length === 0 ? boundary.left : Math.min(...glyphRects.map((rect) => rect.left));
1094
+ const right = glyphRects.length === 0 ? boundary.left : Math.max(...glyphRects.map((rect) => rect.right));
1095
+ const top = glyphRects.length === 0 ? boundary.top : Math.min(...glyphRects.map((rect) => rect.top));
1096
+ const bottom = glyphRects.length === 0 ? boundary.top : Math.max(...glyphRects.map((rect) => rect.bottom));
1097
+ const width = right - left;
1098
+ const height = bottom - top;
1099
+ return {
1100
+ fits: left >= boundary.left - 0.5
1101
+ && right <= boundary.right + 0.5
1102
+ && top >= boundary.top - 0.5
1103
+ && bottom <= boundary.bottom + 0.5
1104
+ && (maximumLines === 0 || lines <= maximumLines),
1105
+ width, height, lines,
1106
+ offsets: {
1107
+ left: left - boundary.left,
1108
+ right: boundary.right - right,
1109
+ top: top - boundary.top,
1110
+ bottom: boundary.bottom - bottom,
1111
+ },
1112
+ };
1113
+ };
1114
+ const fullSizeMeasurement = measure(1);
1115
+ if (fullSizeMeasurement.fits) {
1116
+ apply(1);
1117
+ flow.setAttribute('data-hypit-text-shrink-scale', '1.00000000');
1118
+ continue;
1119
+ }
1120
+ const minimumMeasurement = measure(minimum);
1121
+ if (!minimumMeasurement.fits) throw new Error('Text cannot fit at its authored minimum scale: '
1122
+ + minimumMeasurement.width.toFixed(2) + 'x' + minimumMeasurement.height.toFixed(2)
1123
+ + ' in ' + availableWidth + 'x' + availableHeight + ', lines=' + minimumMeasurement.lines
1124
+ + ', offsets=' + JSON.stringify(minimumMeasurement.offsets)
1125
+ + (maximumLines === 0 ? '' : ', maxLines=' + maximumLines) + '.');
1126
+ let low = minimum;
1127
+ let high = 1;
1128
+ for (let index = 0; index < 20; index += 1) {
1129
+ const middle = (low + high) / 2;
1130
+ if (measure(middle).fits) low = middle;
1131
+ else high = middle;
1132
+ }
1133
+ apply(low);
1134
+ flow.setAttribute('data-hypit-text-shrink-scale', low.toFixed(8));
1135
+ }
1136
+ for (const flow of document.querySelectorAll('[data-hypit-text-flow][data-hypit-text-line-sequences]')) {
1137
+ const sequences = JSON.parse(flow.getAttribute('data-hypit-text-line-sequences') || '[]');
1138
+ const glyphs = [...flow.querySelectorAll('[data-hypit-text-unit-grapheme]')];
1139
+ const vertical = flow.getAttribute('data-hypit-text-writing-mode') !== 'horizontal-tb';
1140
+ const axes = [];
1141
+ const lineOf = new Map();
1142
+ for (const glyph of glyphs) {
1143
+ const rect = glyph.getBoundingClientRect();
1144
+ const axis = vertical ? rect.left : rect.top;
1145
+ let line = axes.findIndex((value) => Math.abs(value - axis) < 0.5);
1146
+ if (line < 0) { line = axes.length; axes.push(axis); }
1147
+ lineOf.set(glyph, line);
1148
+ }
1149
+ for (const sequence of sequences) {
1150
+ if (sequence.range.endExclusive > axes.length) throw new Error('Text line sequence selects a line that does not exist.');
1151
+ }
1152
+ for (let line = 0; line < axes.length; line += 1) {
1153
+ const members = glyphs.filter((glyph) => lineOf.get(glyph) === line);
1154
+ const rects = members.map((glyph) => glyph.getBoundingClientRect());
1155
+ const left = Math.min(...rects.map((rect) => rect.left));
1156
+ const right = Math.max(...rects.map((rect) => rect.right));
1157
+ const top = Math.min(...rects.map((rect) => rect.top));
1158
+ const bottom = Math.max(...rects.map((rect) => rect.bottom));
1159
+ for (const [memberIndex, glyph] of members.entries()) {
1160
+ const rect = rects[memberIndex];
1161
+ glyph.style.transformOrigin = String((left + right) / 2 - rect.left) + 'px ' + String((top + bottom) / 2 - rect.top) + 'px';
1162
+ glyph.setAttribute('data-hypit-text-physical-line', String(line));
1163
+ }
1164
+ }
1165
+ }
1166
+ svmlTextReady = true;
1167
+ svmlTextTimeline.totalTime(svmlTextAbsoluteTime);
1168
+ });
1169
+ window.addEventListener('hf-seek', (event) => {
1170
+ if (!event?.detail || typeof event.detail.waitUntil !== 'function') return;
1171
+ // HyperFrames requires waitUntil to be registered synchronously while the
1172
+ // seek event is dispatched. The Promise itself waits for exact fonts and
1173
+ // deterministic static layout validation. Per-frame sampling is synchronous
1174
+ // inside the registered timeline and forces layout before it returns. A
1175
+ // rejected layout (for example bounded shrink below the authored minimum)
1176
+ // therefore rejects the render instead of becoming an unobserved Promise.
1177
+ event.detail.waitUntil(svmlTextLayoutReady);
1178
+ });
1179
+ `;