@hraness/slopcamera 3.2.4

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 (441) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE.md +60 -0
  3. package/PRIVACY.md +46 -0
  4. package/README.md +311 -0
  5. package/SECURITY.md +21 -0
  6. package/apps/desktop/README.md +966 -0
  7. package/apps/desktop/analysis/protocol.ts +223 -0
  8. package/apps/desktop/application/capability-binding.ts +594 -0
  9. package/apps/desktop/application/context.ts +97 -0
  10. package/apps/desktop/application/creative-iteration.ts +1385 -0
  11. package/apps/desktop/application/default-registry.ts +146 -0
  12. package/apps/desktop/application/directing-contract.ts +218 -0
  13. package/apps/desktop/application/directing-plan.ts +178 -0
  14. package/apps/desktop/application/errors.ts +18 -0
  15. package/apps/desktop/application/gateway-port.ts +867 -0
  16. package/apps/desktop/application/html-overlay-browser-runtime.ts +687 -0
  17. package/apps/desktop/application/html-overlay-integrity.ts +337 -0
  18. package/apps/desktop/application/html-overlay-renderer.ts +45 -0
  19. package/apps/desktop/application/index.ts +13 -0
  20. package/apps/desktop/application/operation-completion-checkpoint.ts +333 -0
  21. package/apps/desktop/application/operation-effects.ts +94 -0
  22. package/apps/desktop/application/operation.ts +224 -0
  23. package/apps/desktop/application/operations/analysis/faces.ts +244 -0
  24. package/apps/desktop/application/operations/analysis/music.ts +248 -0
  25. package/apps/desktop/application/operations/analysis/project-auto-zooms.ts +302 -0
  26. package/apps/desktop/application/operations/analysis/project-inactivity.ts +381 -0
  27. package/apps/desktop/application/operations/analysis/scenes.ts +272 -0
  28. package/apps/desktop/application/operations/analysis/shared.ts +202 -0
  29. package/apps/desktop/application/operations/derive/edit-batch.ts +967 -0
  30. package/apps/desktop/application/operations/derive/follow-faces.ts +454 -0
  31. package/apps/desktop/application/operations/edit/bind-candidate-revision.ts +91 -0
  32. package/apps/desktop/application/operations/edit/create-candidate-revision.ts +377 -0
  33. package/apps/desktop/application/operations/edit/create-revision.ts +255 -0
  34. package/apps/desktop/application/operations/edit/freeze-revision.ts +182 -0
  35. package/apps/desktop/application/operations/gateway/image.ts +41 -0
  36. package/apps/desktop/application/operations/gateway/index.ts +17 -0
  37. package/apps/desktop/application/operations/gateway/shared.ts +122 -0
  38. package/apps/desktop/application/operations/gateway/speech.ts +41 -0
  39. package/apps/desktop/application/operations/gateway/transcription.ts +42 -0
  40. package/apps/desktop/application/operations/gateway/video.ts +41 -0
  41. package/apps/desktop/application/operations/index.ts +31 -0
  42. package/apps/desktop/application/operations/iteration/create-candidate.ts +240 -0
  43. package/apps/desktop/application/operations/iteration/create-matrix.ts +117 -0
  44. package/apps/desktop/application/operations/iteration/select.ts +155 -0
  45. package/apps/desktop/application/operations/iteration/shared.ts +250 -0
  46. package/apps/desktop/application/operations/media/audio-effects.ts +376 -0
  47. package/apps/desktop/application/operations/media/binding.ts +79 -0
  48. package/apps/desktop/application/operations/media/capabilities.ts +112 -0
  49. package/apps/desktop/application/operations/media/color-grade.ts +343 -0
  50. package/apps/desktop/application/operations/media/html-overlay.ts +802 -0
  51. package/apps/desktop/application/operations/media/index.ts +8 -0
  52. package/apps/desktop/application/operations/media/ingest.ts +303 -0
  53. package/apps/desktop/application/operations/media/overlay.ts +729 -0
  54. package/apps/desktop/application/operations/media/shared.ts +845 -0
  55. package/apps/desktop/application/operations/media/transform-platform.ts +120 -0
  56. package/apps/desktop/application/operations/project/commit-edits.ts +2054 -0
  57. package/apps/desktop/application/operations/project/promote-selection.ts +495 -0
  58. package/apps/desktop/application/operations/project/snapshot.ts +95 -0
  59. package/apps/desktop/application/operations/recording/index.ts +5 -0
  60. package/apps/desktop/application/operations/recording/pause.ts +34 -0
  61. package/apps/desktop/application/operations/recording/resume.ts +34 -0
  62. package/apps/desktop/application/operations/recording/shared.ts +199 -0
  63. package/apps/desktop/application/operations/recording/start.ts +169 -0
  64. package/apps/desktop/application/operations/recording/stop.ts +34 -0
  65. package/apps/desktop/application/operations/render/bind-candidate-output.ts +324 -0
  66. package/apps/desktop/application/operations/render/materialize-selection.ts +322 -0
  67. package/apps/desktop/application/operations/render/project-caption-plan.ts +287 -0
  68. package/apps/desktop/application/operations/render/project-plan.ts +939 -0
  69. package/apps/desktop/application/operations/render/project-spatial-receipt.ts +70 -0
  70. package/apps/desktop/application/operations/render/project.ts +1922 -0
  71. package/apps/desktop/application/operations/shared.ts +67 -0
  72. package/apps/desktop/application/operations/slopcamera-portable.ts +1188 -0
  73. package/apps/desktop/application/operations/slopcamera-visuals.ts +784 -0
  74. package/apps/desktop/application/operations/spatial-project.ts +209 -0
  75. package/apps/desktop/application/operations/spatial-render.ts +415 -0
  76. package/apps/desktop/application/operations/spatial-scene.ts +97 -0
  77. package/apps/desktop/application/operations/studio.ts +143 -0
  78. package/apps/desktop/application/output-publication-lease.ts +163 -0
  79. package/apps/desktop/application/project-publication-lease.ts +233 -0
  80. package/apps/desktop/application/project-store.ts +196 -0
  81. package/apps/desktop/application/receipts.ts +533 -0
  82. package/apps/desktop/application/registry.ts +182 -0
  83. package/apps/desktop/application/spatial-assets.ts +675 -0
  84. package/apps/desktop/application/spatial-compositor-cadence.ts +23 -0
  85. package/apps/desktop/application/spatial-project-authority.ts +35 -0
  86. package/apps/desktop/application/spatial-project-lease.ts +126 -0
  87. package/apps/desktop/application/spatial-project-render-preparation.ts +225 -0
  88. package/apps/desktop/application/spatial-project-store.ts +286 -0
  89. package/apps/desktop/application/spatial-render-projection.ts +201 -0
  90. package/apps/desktop/application/spatial-render.ts +677 -0
  91. package/apps/desktop/application/spatial-spz.ts +44 -0
  92. package/apps/desktop/application/spatial-world-import.ts +135 -0
  93. package/apps/desktop/application/spatial-world-provenance.ts +46 -0
  94. package/apps/desktop/application/studio-port.ts +58 -0
  95. package/apps/desktop/application/verified-receipt-reconciliation.ts +1574 -0
  96. package/apps/desktop/capture/protocol.ts +689 -0
  97. package/apps/desktop/cli/analyzer.ts +406 -0
  98. package/apps/desktop/cli/args.ts +3181 -0
  99. package/apps/desktop/cli/asset-ingest.ts +747 -0
  100. package/apps/desktop/cli/atomic-render-effects.ts +210 -0
  101. package/apps/desktop/cli/atomic-render-platform.ts +205 -0
  102. package/apps/desktop/cli/atomic-render.ts +50 -0
  103. package/apps/desktop/cli/audio-analysis.ts +252 -0
  104. package/apps/desktop/cli/bounded-map.ts +39 -0
  105. package/apps/desktop/cli/bundle-service.ts +256 -0
  106. package/apps/desktop/cli/capabilities.ts +212 -0
  107. package/apps/desktop/cli/capture-bundle.ts +1117 -0
  108. package/apps/desktop/cli/command-host-resources.ts +251 -0
  109. package/apps/desktop/cli/commands.ts +6836 -0
  110. package/apps/desktop/cli/directing-blob.ts +291 -0
  111. package/apps/desktop/cli/directing-media.ts +517 -0
  112. package/apps/desktop/cli/directing-quote.ts +89 -0
  113. package/apps/desktop/cli/directing-service.ts +288 -0
  114. package/apps/desktop/cli/emoji-assets.ts +538 -0
  115. package/apps/desktop/cli/errors.ts +29 -0
  116. package/apps/desktop/cli/face-analysis-service.ts +940 -0
  117. package/apps/desktop/cli/filter-script.ts +76 -0
  118. package/apps/desktop/cli/gateway-application-port.ts +1142 -0
  119. package/apps/desktop/cli/gateway-credential.ts +81 -0
  120. package/apps/desktop/cli/gateway-media-artifacts.ts +723 -0
  121. package/apps/desktop/cli/gateway-media-catalog.ts +922 -0
  122. package/apps/desktop/cli/gateway-media-service.ts +3106 -0
  123. package/apps/desktop/cli/gateway-media-signature.ts +122 -0
  124. package/apps/desktop/cli/gateway-provider-options.ts +562 -0
  125. package/apps/desktop/cli/gateway-scene-provider.ts +391 -0
  126. package/apps/desktop/cli/help.ts +501 -0
  127. package/apps/desktop/cli/html-overlay-gpu.ts +97 -0
  128. package/apps/desktop/cli/html-overlay-renderer.ts +2478 -0
  129. package/apps/desktop/cli/io.ts +290 -0
  130. package/apps/desktop/cli/main.ts +123 -0
  131. package/apps/desktop/cli/media-effects-service.ts +885 -0
  132. package/apps/desktop/cli/media-ingest-model.ts +364 -0
  133. package/apps/desktop/cli/media-ingest-platform.ts +227 -0
  134. package/apps/desktop/cli/media-ingest-program.ts +200 -0
  135. package/apps/desktop/cli/media-ingest.ts +30 -0
  136. package/apps/desktop/cli/music-analysis-service.ts +434 -0
  137. package/apps/desktop/cli/mutation-lock.ts +530 -0
  138. package/apps/desktop/cli/native-assets.d.ts +12 -0
  139. package/apps/desktop/cli/native-media-runtime.macos.ts +7 -0
  140. package/apps/desktop/cli/overlay-playback.ts +177 -0
  141. package/apps/desktop/cli/paths.ts +265 -0
  142. package/apps/desktop/cli/portable-surface.ts +242 -0
  143. package/apps/desktop/cli/project-camera-receipt.ts +112 -0
  144. package/apps/desktop/cli/project-face-camera.ts +394 -0
  145. package/apps/desktop/cli/project-inactivity-service.ts +552 -0
  146. package/apps/desktop/cli/project-media-integrity.ts +121 -0
  147. package/apps/desktop/cli/project-renderer.ts +1526 -0
  148. package/apps/desktop/cli/project-service.ts +519 -0
  149. package/apps/desktop/cli/project-state-transaction.ts +520 -0
  150. package/apps/desktop/cli/query-limits.ts +1 -0
  151. package/apps/desktop/cli/recording-controller.ts +1567 -0
  152. package/apps/desktop/cli/recording-daemon.ts +931 -0
  153. package/apps/desktop/cli/recording-ref.ts +56 -0
  154. package/apps/desktop/cli/renamed-environment.ts +6 -0
  155. package/apps/desktop/cli/renderer.ts +1439 -0
  156. package/apps/desktop/cli/run-cli-test-helper.ts +60 -0
  157. package/apps/desktop/cli/scene-analysis-service.ts +879 -0
  158. package/apps/desktop/cli/spatial-compositor-verifier.ts +213 -0
  159. package/apps/desktop/cli/spatial-project-service.ts +90 -0
  160. package/apps/desktop/cli/spatial-scene-service.ts +105 -0
  161. package/apps/desktop/cli/spatial-world-service.ts +39 -0
  162. package/apps/desktop/cli/speech-analysis-service.ts +682 -0
  163. package/apps/desktop/cli/studio-assemble.ts +58 -0
  164. package/apps/desktop/cli/studio-command.ts +60 -0
  165. package/apps/desktop/cli/studio-custody.ts +60 -0
  166. package/apps/desktop/cli/studio-encode.ts +216 -0
  167. package/apps/desktop/cli/studio-exr.ts +52 -0
  168. package/apps/desktop/cli/studio-files.ts +179 -0
  169. package/apps/desktop/cli/studio-output-validation.ts +162 -0
  170. package/apps/desktop/cli/studio-process.ts +145 -0
  171. package/apps/desktop/cli/studio-runtime.ts +77 -0
  172. package/apps/desktop/cli/studio-scaffold.ts +70 -0
  173. package/apps/desktop/cli/studio-service.ts +301 -0
  174. package/apps/desktop/cli/studio-spatial-asset.ts +248 -0
  175. package/apps/desktop/cli/studio-template-names.ts +3 -0
  176. package/apps/desktop/cli/studio-workflow.ts +19 -0
  177. package/apps/desktop/cli/time.ts +25 -0
  178. package/apps/desktop/cli/workflow-code.ts +584 -0
  179. package/apps/desktop/cli/workflow-runs.ts +576 -0
  180. package/apps/desktop/code/advanced.ts +139 -0
  181. package/apps/desktop/code/application-node-planner.ts +1288 -0
  182. package/apps/desktop/code/compiler.ts +329 -0
  183. package/apps/desktop/code/contracts.ts +13 -0
  184. package/apps/desktop/code/creative-recipes.ts +94 -0
  185. package/apps/desktop/code/define-workflow.ts +115 -0
  186. package/apps/desktop/code/editing.ts +284 -0
  187. package/apps/desktop/code/file-candidate-provenance.ts +420 -0
  188. package/apps/desktop/code/file-candidate.ts +69 -0
  189. package/apps/desktop/code/graph-builder.ts +10 -0
  190. package/apps/desktop/code/host-resource-policy.ts +55 -0
  191. package/apps/desktop/code/plan-contracts.ts +159 -0
  192. package/apps/desktop/code/planning.ts +361 -0
  193. package/apps/desktop/code/public.ts +134 -0
  194. package/apps/desktop/code/reference-projection.ts +62 -0
  195. package/apps/desktop/code/run-contracts.ts +466 -0
  196. package/apps/desktop/code/run-store.ts +2478 -0
  197. package/apps/desktop/code/runtime-identity.ts +328 -0
  198. package/apps/desktop/code/scheduler.ts +3067 -0
  199. package/apps/desktop/code/semantic-builder.ts +1436 -0
  200. package/apps/desktop/code/source-bundle.ts +1641 -0
  201. package/apps/desktop/code/source-typecheck.ts +211 -0
  202. package/apps/desktop/code/testing.ts +79 -0
  203. package/apps/desktop/code/worker-client.ts +1675 -0
  204. package/apps/desktop/code/worker-effects.ts +141 -0
  205. package/apps/desktop/code/worker-entry.ts +435 -0
  206. package/apps/desktop/code/worker-lease-guardian.ts +179 -0
  207. package/apps/desktop/code/worker-process-identity.ts +484 -0
  208. package/apps/desktop/code/worker-protocol.ts +211 -0
  209. package/apps/desktop/code/workflow-effects.ts +132 -0
  210. package/apps/desktop/contracts/analysis.ts +949 -0
  211. package/apps/desktop/contracts/edit.ts +576 -0
  212. package/apps/desktop/contracts/index.ts +9 -0
  213. package/apps/desktop/contracts/media-effects.ts +139 -0
  214. package/apps/desktop/contracts/project-render.ts +644 -0
  215. package/apps/desktop/contracts/project.ts +740 -0
  216. package/apps/desktop/contracts/recording.ts +1434 -0
  217. package/apps/desktop/contracts/render.ts +334 -0
  218. package/apps/desktop/contracts/runtime.ts +155 -0
  219. package/apps/desktop/contracts/spatial-compositor.ts +58 -0
  220. package/apps/desktop/contracts/spatial-project.ts +159 -0
  221. package/apps/desktop/contracts/spatial-world.ts +48 -0
  222. package/apps/desktop/contracts/video-effects.ts +120 -0
  223. package/apps/desktop/core/alignment-apply.ts +400 -0
  224. package/apps/desktop/core/audio-alignment.ts +466 -0
  225. package/apps/desktop/core/auto-zoom.ts +209 -0
  226. package/apps/desktop/core/canonical-json.ts +14 -0
  227. package/apps/desktop/core/emoji.ts +210 -0
  228. package/apps/desktop/core/events.ts +409 -0
  229. package/apps/desktop/core/face-framing.ts +533 -0
  230. package/apps/desktop/core/face-tracks.ts +326 -0
  231. package/apps/desktop/core/inactivity.ts +137 -0
  232. package/apps/desktop/core/index.ts +30 -0
  233. package/apps/desktop/core/intervals.ts +123 -0
  234. package/apps/desktop/core/montage.ts +236 -0
  235. package/apps/desktop/core/music-analysis.ts +518 -0
  236. package/apps/desktop/core/plan.ts +244 -0
  237. package/apps/desktop/core/project-auto-zoom.ts +75 -0
  238. package/apps/desktop/core/project-camera-spatial.ts +676 -0
  239. package/apps/desktop/core/project-camera.ts +403 -0
  240. package/apps/desktop/core/project-captions.ts +888 -0
  241. package/apps/desktop/core/project-inactivity.ts +125 -0
  242. package/apps/desktop/core/project-metadata.ts +927 -0
  243. package/apps/desktop/core/project-plan.ts +375 -0
  244. package/apps/desktop/core/project-render-plan.ts +303 -0
  245. package/apps/desktop/core/project-time.ts +469 -0
  246. package/apps/desktop/core/render-plan.ts +442 -0
  247. package/apps/desktop/core/scene-cache.ts +174 -0
  248. package/apps/desktop/core/scene-sampling.ts +448 -0
  249. package/apps/desktop/core/spatial-compositor.ts +22 -0
  250. package/apps/desktop/core/spatial-durability.ts +99 -0
  251. package/apps/desktop/core/spatial-project.ts +169 -0
  252. package/apps/desktop/core/spatial-shot-clock.ts +32 -0
  253. package/apps/desktop/core/speech-analysis.ts +333 -0
  254. package/apps/desktop/core/storage.ts +970 -0
  255. package/apps/desktop/core/time-map.ts +91 -0
  256. package/apps/desktop/core/time.ts +61 -0
  257. package/apps/desktop/core/video-effects.ts +660 -0
  258. package/apps/desktop/dist/cli/NebulaSans-Bold-26se8aek.otf +0 -0
  259. package/apps/desktop/dist/cli/NebulaSans-Bold-bcz7y08t.woff2 +0 -0
  260. package/apps/desktop/dist/cli/NebulaSans-Book-5ax05zvn.woff2 +0 -0
  261. package/apps/desktop/dist/cli/NebulaSans-Book-8cenzchw.otf +0 -0
  262. package/apps/desktop/dist/cli/main.js +5086 -0
  263. package/apps/desktop/html-overlay/catalog.ts +171 -0
  264. package/apps/desktop/html-overlay/contracts.ts +372 -0
  265. package/apps/desktop/html-overlay/execution-profile.ts +77 -0
  266. package/apps/desktop/html-overlay/index.ts +98 -0
  267. package/apps/desktop/html-overlay/libraries.ts +263 -0
  268. package/apps/desktop/html-overlay/random.ts +49 -0
  269. package/apps/desktop/html-overlay/runtime.ts +813 -0
  270. package/apps/desktop/html-overlay/scaffolds.ts +792 -0
  271. package/apps/desktop/html-overlay/spark-runtime.ts +88 -0
  272. package/apps/desktop/html-overlay/spatial-splat-runtime.ts +60 -0
  273. package/apps/desktop/html-overlay/spatial.ts +720 -0
  274. package/apps/desktop/studio/assets/README.md +39 -0
  275. package/apps/desktop/studio/assets/contracts.ts +129 -0
  276. package/apps/desktop/studio/assets/network.ts +64 -0
  277. package/apps/desktop/studio/assets/poly-haven.ts +148 -0
  278. package/apps/desktop/studio/drivers/blender_driver.py +466 -0
  279. package/apps/desktop/studio/drivers/cadquery_driver.py +176 -0
  280. package/apps/desktop/studio/education/driver.py +308 -0
  281. package/apps/desktop/studio/education/lesson.py +180 -0
  282. package/apps/desktop/studio/education/toolkit.py +249 -0
  283. package/apps/desktop/workflows/chaptered-demo.ts +48 -0
  284. package/apps/desktop/workflows/creative-iteration.ts +107 -0
  285. package/apps/desktop/workflows/creative-selection.ts +92 -0
  286. package/apps/desktop/workflows/fragments.ts +486 -0
  287. package/apps/desktop/workflows/index.ts +93 -0
  288. package/apps/desktop/workflows/polished-screen-demo.ts +128 -0
  289. package/apps/desktop/workflows/scene-direction.ts +12 -0
  290. package/apps/desktop/workflows/social-variants.ts +75 -0
  291. package/apps/desktop/workflows/talking-head-cleanup.ts +53 -0
  292. package/dist/NebulaSans-Bold-26se8aek.otf +0 -0
  293. package/dist/NebulaSans-Bold-bcz7y08t.woff2 +0 -0
  294. package/dist/NebulaSans-Book-5ax05zvn.woff2 +0 -0
  295. package/dist/NebulaSans-Book-8cenzchw.otf +0 -0
  296. package/dist/cli.js +479 -0
  297. package/dist/code/advanced.js +270 -0
  298. package/dist/code/index.js +2240 -0
  299. package/dist/generate.js +24 -0
  300. package/dist/host-resources.js +26 -0
  301. package/dist/index-42zsesc1.js +2257 -0
  302. package/dist/index-7308egqr.js +48 -0
  303. package/dist/index-8txs6fkn.js +712 -0
  304. package/dist/index-mcy8z0br.js +192 -0
  305. package/dist/index-p63wavx0.js +2029 -0
  306. package/dist/index-r7gdhmsp.js +424 -0
  307. package/dist/index-sh6xbav6.js +1219 -0
  308. package/dist/index-z1w83f81.js +4 -0
  309. package/dist/index-z7239b4h.js +2363 -0
  310. package/dist/index-zfeg9hmw.js +2013 -0
  311. package/dist/index.js +241 -0
  312. package/dist/operations.js +29 -0
  313. package/dist/skill-install-dh0ntqba.js +10 -0
  314. package/dist/vectorize/worker.js +142 -0
  315. package/dist/workflow.js +16 -0
  316. package/docs/README.md +38 -0
  317. package/docs/studio.md +215 -0
  318. package/examples/studio/blender/README.md +26 -0
  319. package/examples/studio/blender/character.py +152 -0
  320. package/examples/studio/blender/cloth.py +101 -0
  321. package/examples/studio/blender/color_chart.py +29 -0
  322. package/examples/studio/blender/fluid.py +78 -0
  323. package/examples/studio/blender/import_model.py +74 -0
  324. package/examples/studio/blender/product.py +53 -0
  325. package/examples/studio/blender/shaded_street.py +481 -0
  326. package/examples/studio/blender/studio_scene.py +147 -0
  327. package/examples/studio/cadquery/README.md +13 -0
  328. package/examples/studio/cadquery/bracket.py +36 -0
  329. package/examples/studio/cadquery/import_step.py +12 -0
  330. package/examples/studio/education/README.md +46 -0
  331. package/examples/studio/education/lesson.json +99 -0
  332. package/examples/studio/education/scene.py +7 -0
  333. package/examples/studio/hybrid-scene.ts +96 -0
  334. package/examples/studio/native-workflow.ts +14 -0
  335. package/examples/studio/vgpu/README.md +64 -0
  336. package/examples/studio/vgpu/heat-field.mjs +290 -0
  337. package/package.json +304 -0
  338. package/packages/scene/src/index.ts +1 -0
  339. package/packages/scene/src/scene.ts +215 -0
  340. package/schema/diagram.schema.json +334 -0
  341. package/skills/slopcamera/SKILL.md +45 -0
  342. package/skills/slopcamera/agents/openai.yaml +4 -0
  343. package/skills/slopcamera/references/customization.md +77 -0
  344. package/skills/slopcamera/references/diagrams.md +153 -0
  345. package/skills/slopcamera/references/directed-scenes.md +42 -0
  346. package/skills/slopcamera/references/directing-video.md +18 -0
  347. package/skills/slopcamera/references/educational-video.md +26 -0
  348. package/skills/slopcamera/references/gateway-media.md +134 -0
  349. package/skills/slopcamera/references/install.md +62 -0
  350. package/skills/slopcamera/references/native-studio.md +31 -0
  351. package/skills/slopcamera/references/reference-led-3d.md +140 -0
  352. package/skills/slopcamera/references/rubber-stamp-examples/poster-example-1.jpg +0 -0
  353. package/skills/slopcamera/references/rubber-stamp-examples/poster-example-2.jpg +0 -0
  354. package/skills/slopcamera/references/rubber-stamp-examples/stamp-style-1.png +0 -0
  355. package/skills/slopcamera/references/rubber-stamp-examples/stamp-style-2.png +0 -0
  356. package/skills/slopcamera/references/rubber-stamp-field-notes.md +144 -0
  357. package/skills/slopcamera/references/vectorization.md +29 -0
  358. package/skills/slopcamera/references/video-projects.md +187 -0
  359. package/skills/slopcamera/references/visual-communication.md +120 -0
  360. package/skills/slopcamera/references/workflows-sdk.md +45 -0
  361. package/skills/slopcamera/scripts/compose-rubber-stamp-field-note.ts +229 -0
  362. package/src/artifacts.ts +106 -0
  363. package/src/assets/fonts/nebula-sans/LICENSE.txt +96 -0
  364. package/src/assets/fonts/nebula-sans/NebulaSans-Bold.otf +0 -0
  365. package/src/assets/fonts/nebula-sans/NebulaSans-Bold.woff2 +0 -0
  366. package/src/assets/fonts/nebula-sans/NebulaSans-Book.otf +0 -0
  367. package/src/assets/fonts/nebula-sans/NebulaSans-Book.woff2 +0 -0
  368. package/src/assets/fonts/nebula-sans/PROVENANCE.md +21 -0
  369. package/src/assets.d.ts +9 -0
  370. package/src/cli.ts +601 -0
  371. package/src/cloud-errors.ts +26 -0
  372. package/src/code/advanced.ts +10 -0
  373. package/src/code/boundary.ts +21 -0
  374. package/src/code/canonical-json.ts +129 -0
  375. package/src/code/compiler.ts +953 -0
  376. package/src/code/contracts.ts +576 -0
  377. package/src/code/define-workflow.ts +334 -0
  378. package/src/code/errors.ts +41 -0
  379. package/src/code/graph-builder.ts +945 -0
  380. package/src/code/index.ts +121 -0
  381. package/src/code/json-snapshot.ts +899 -0
  382. package/src/code/json-utf8.ts +88 -0
  383. package/src/code/portable-builder.ts +136 -0
  384. package/src/code/projection.ts +378 -0
  385. package/src/code/public-operations.ts +450 -0
  386. package/src/code/runtime.ts +580 -0
  387. package/src/code/sha256.ts +36 -0
  388. package/src/config.ts +180 -0
  389. package/src/desktop.ts +253 -0
  390. package/src/fs.ts +10 -0
  391. package/src/generate.ts +704 -0
  392. package/src/host-resource-posix.ts +161 -0
  393. package/src/host-resources.ts +1749 -0
  394. package/src/icons.ts +58 -0
  395. package/src/index.ts +200 -0
  396. package/src/label-layout.ts +130 -0
  397. package/src/layout.ts +413 -0
  398. package/src/lint.ts +127 -0
  399. package/src/mcp/boundary.ts +354 -0
  400. package/src/mcp/index.ts +33 -0
  401. package/src/mcp/server.ts +272 -0
  402. package/src/mcp/tools.ts +963 -0
  403. package/src/mcp/types.ts +71 -0
  404. package/src/operations.ts +775 -0
  405. package/src/parse.ts +861 -0
  406. package/src/process-environment.ts +17 -0
  407. package/src/render.ts +437 -0
  408. package/src/skill-install.ts +49 -0
  409. package/src/spatial-scene/authoring.ts +27 -0
  410. package/src/spatial-scene/camera-track.ts +83 -0
  411. package/src/spatial-scene/contracts.ts +277 -0
  412. package/src/spatial-scene/evaluate.ts +145 -0
  413. package/src/spatial-scene/gltf.ts +558 -0
  414. package/src/spatial-scene/identity.ts +260 -0
  415. package/src/spatial-scene/index.ts +10 -0
  416. package/src/spatial-scene/inspect.ts +68 -0
  417. package/src/spatial-scene/math.ts +280 -0
  418. package/src/spatial-scene/patch.ts +131 -0
  419. package/src/spatial-scene/time.ts +53 -0
  420. package/src/studio/contracts.ts +129 -0
  421. package/src/studio/index.ts +2 -0
  422. package/src/studio/plan.ts +156 -0
  423. package/src/studio/shared.ts +41 -0
  424. package/src/theme.ts +68 -0
  425. package/src/tldr.ts +474 -0
  426. package/src/types.ts +212 -0
  427. package/src/vectorize/archive.ts +101 -0
  428. package/src/vectorize/command.ts +797 -0
  429. package/src/vectorize/index.ts +27 -0
  430. package/src/vectorize/limits.ts +61 -0
  431. package/src/vectorize/metrics.ts +351 -0
  432. package/src/vectorize/pixels.ts +323 -0
  433. package/src/vectorize/supervisor.ts +339 -0
  434. package/src/vectorize/svg.ts +188 -0
  435. package/src/vectorize/tool.ts +542 -0
  436. package/src/vectorize/types.ts +113 -0
  437. package/src/vectorize/vectorize.ts +634 -0
  438. package/src/vectorize/worker-protocol.ts +40 -0
  439. package/src/vectorize/worker.ts +209 -0
  440. package/src/version.ts +1 -0
  441. package/src/workflow.ts +409 -0
@@ -0,0 +1,277 @@
1
+ import { z } from "zod"
2
+
3
+ export const SPATIAL_SCENE_LIMITS = Object.freeze({
4
+ sourceBytes: 2_097_152,
5
+ sourceDepth: 32,
6
+ sourceValues: 200_000,
7
+ entities: 4_096,
8
+ assets: 128,
9
+ cameras: 64,
10
+ channels: 4_096,
11
+ keysPerChannel: 4_096,
12
+ durationUs: 3_600_000_000,
13
+ patchOperations: 256,
14
+ })
15
+
16
+ export const SpatialDigestSchema = z.string().regex(/^[a-f0-9]{64}$/u)
17
+ const stableId = (prefix: string) => z.string().min(prefix.length + 1).max(128)
18
+ .regex(new RegExp(`^${prefix}[a-zA-Z0-9][a-zA-Z0-9_-]*$`, "u"))
19
+ export const SpatialSceneIdSchema = stableId("scene_")
20
+ export const SpatialEntityIdSchema = stableId("entity_")
21
+ export const SpatialCameraIdSchema = stableId("camera_")
22
+ export const SpatialAssetIdSchema = stableId("asset_")
23
+ export const SpatialGeneratorIdSchema = stableId("generator_")
24
+ export const SpatialChannelIdSchema = stableId("channel_")
25
+ export const SpatialShotIdSchema = stableId("shot_")
26
+ const finiteCoordinate = z.number().finite().min(-1_000_000).max(1_000_000)
27
+ const positiveDimension = z.number().finite().min(0.000001).max(1_000_000)
28
+ const unit = z.number().finite().min(0).max(1)
29
+ export const SpatialTimeUsSchema = z.number().int().safe().min(0).max(SPATIAL_SCENE_LIMITS.durationUs)
30
+ export const SpatialVec3Schema = z.tuple([finiteCoordinate, finiteCoordinate, finiteCoordinate])
31
+ export const SpatialQuaternionSchema = z.tuple([
32
+ z.number().finite().min(-1).max(1), z.number().finite().min(-1).max(1),
33
+ z.number().finite().min(-1).max(1), z.number().finite().min(-1).max(1),
34
+ ]).refine(value => Math.abs(value.reduce((sum, part) => sum + part * part, 0) - 1) <= 1e-6,
35
+ "Rotation must be a unit quaternion in XYZW order.")
36
+ export const SpatialTransformSchema = z.strictObject({
37
+ position: SpatialVec3Schema,
38
+ rotation: SpatialQuaternionSchema,
39
+ scale: z.tuple([positiveDimension, positiveDimension, positiveDimension]),
40
+ })
41
+ export const SpatialPoseSchema = z.strictObject({
42
+ position: SpatialVec3Schema,
43
+ rotation: SpatialQuaternionSchema,
44
+ })
45
+ export const SpatialFrameRateSchema = z.strictObject({
46
+ numerator: z.number().int().safe().min(1).max(1_000_000),
47
+ denominator: z.number().int().safe().min(1).max(1_000_000),
48
+ }).refine(rate => rate.numerator / rate.denominator <= 1_000, "Frame rate exceeds 1,000 fps.")
49
+ const dimensions = {
50
+ width: z.number().int().min(1).max(16_384),
51
+ height: z.number().int().min(1).max(16_384),
52
+ }
53
+ const clipping = { near: positiveDimension, far: positiveDimension }
54
+ export const SpatialProjectionSchema = z.discriminatedUnion("kind", [
55
+ z.strictObject({
56
+ kind: z.literal("perspective"), ...dimensions, ...clipping,
57
+ fx: positiveDimension, fy: positiveDimension,
58
+ cx: finiteCoordinate, cy: finiteCoordinate,
59
+ }),
60
+ z.strictObject({
61
+ kind: z.literal("orthographic"), ...dimensions, ...clipping,
62
+ left: finiteCoordinate, right: finiteCoordinate,
63
+ top: finiteCoordinate, bottom: finiteCoordinate,
64
+ }),
65
+ ]).superRefine((projection, context) => {
66
+ if (projection.far <= projection.near) context.addIssue({ code: "custom", message: "Far clipping must exceed near clipping." })
67
+ if (projection.width * projection.height > 33_554_432) context.addIssue({ code: "custom", message: "Camera exceeds the 32-megapixel limit." })
68
+ if (projection.kind === "orthographic" && (projection.right <= projection.left || projection.top <= projection.bottom)) {
69
+ context.addIssue({ code: "custom", message: "Orthographic extents must have positive width and height." })
70
+ }
71
+ })
72
+ export const SpatialCameraSchema = z.strictObject({
73
+ cameraId: SpatialCameraIdSchema,
74
+ name: z.string().min(1).max(256),
75
+ pose: SpatialPoseSchema,
76
+ projection: SpatialProjectionSchema,
77
+ })
78
+
79
+ const relativePath = z.string().min(1).max(1_024).refine(value =>
80
+ !value.startsWith("/") && !/[\\\u0000-\u001f]/u.test(value)
81
+ && !/^[a-zA-Z]:/u.test(value)
82
+ && value.split("/").every(part => part !== "" && part !== "." && part !== ".."),
83
+ "Asset paths must be contained root-relative paths.")
84
+ export const SpatialPayloadSchema = z.strictObject({
85
+ path: relativePath,
86
+ sha256: SpatialDigestSchema,
87
+ bytes: z.number().int().safe().min(1).max(134_217_728),
88
+ })
89
+ const imageInterpretation = {
90
+ ...dimensions,
91
+ colorSpace: z.literal("srgb"),
92
+ alpha: z.enum(["straight", "opaque"]),
93
+ }
94
+ export const SpatialAssetInterpretationSchema = z.discriminatedUnion("kind", [
95
+ z.strictObject({ kind: z.literal("image"), ...imageInterpretation, mimeType: z.enum(["image/png", "image/jpeg", "image/svg+xml"]) }),
96
+ z.strictObject({ kind: z.literal("video"), ...imageInterpretation, durationUs: SpatialTimeUsSchema.refine(value => value > 0), frameRate: SpatialFrameRateSchema }),
97
+ z.strictObject({ kind: z.literal("diagram"), schemaVersion: z.literal(1), theme: z.enum(["light", "dark"]) }),
98
+ z.strictObject({ kind: z.literal("gltf"), format: z.enum(["glb", "gltf"]), metersPerUnit: positiveDimension, sourceUp: z.enum(["x", "y", "z"]) }),
99
+ z.strictObject({ kind: z.literal("font"), format: z.enum(["otf", "woff2"]), family: z.string().min(1).max(128) }),
100
+ z.strictObject({ kind: z.literal("splat"), format: z.enum(["spz", "ply"]), metersPerUnit: positiveDimension, sourceUp: z.enum(["x", "y", "z"]) }),
101
+ z.strictObject({ kind: z.literal("metadata"), format: z.literal("json"), schema: z.enum(["slopcamera.spatial-world-import", "slopcamera.world-labs-provenance"]) }),
102
+ ])
103
+ export const SpatialAssetManifestSchema = z.strictObject({
104
+ assetId: SpatialAssetIdSchema,
105
+ payload: SpatialPayloadSchema,
106
+ interpretation: SpatialAssetInterpretationSchema,
107
+ dependencies: z.array(SpatialAssetIdSchema).max(SPATIAL_SCENE_LIMITS.assets),
108
+ provenance: z.strictObject({
109
+ source: z.enum(["authored", "imported", "generated", "derived"]),
110
+ description: z.string().min(1).max(2_048),
111
+ receiptSha256: SpatialDigestSchema.optional(),
112
+ }),
113
+ })
114
+ const color = z.string().regex(/^#[a-fA-F0-9]{6}$/u)
115
+ export const SpatialMaterialSchema = z.discriminatedUnion("kind", [
116
+ z.strictObject({ kind: z.literal("unlit"), color, opacity: unit }),
117
+ z.strictObject({ kind: z.literal("standard"), color, opacity: unit, roughness: unit, metalness: unit }),
118
+ ])
119
+ export const SpatialGeometrySchema = z.discriminatedUnion("kind", [
120
+ z.strictObject({ kind: z.literal("box"), size: z.tuple([positiveDimension, positiveDimension, positiveDimension]) }),
121
+ z.strictObject({ kind: z.literal("sphere"), radius: positiveDimension }),
122
+ z.strictObject({ kind: z.literal("plane"), width: positiveDimension, height: positiveDimension }),
123
+ z.strictObject({ kind: z.literal("cylinder"), radius: positiveDimension, height: positiveDimension }),
124
+ z.strictObject({ kind: z.literal("asset"), assetId: SpatialAssetIdSchema, nodeIndex: z.number().int().min(0).max(65_535).optional(), materialMode: z.enum(["entity", "source"]).optional(),
125
+ clip: z.strictObject({ index: z.number().int().min(0).max(255), offsetUs: SpatialTimeUsSchema, playback: z.enum(["once", "loop", "freeze"]) }).optional(),
126
+ }),
127
+ ])
128
+ export const SpatialOriginSchema = z.discriminatedUnion("kind", [
129
+ z.strictObject({ kind: z.literal("authored") }),
130
+ z.strictObject({ kind: z.literal("generated"), generatorId: SpatialGeneratorIdSchema, key: z.string().min(1).max(256) }),
131
+ ])
132
+ export const SpatialPlacementSchema = z.discriminatedUnion("kind", [
133
+ z.strictObject({ kind: z.literal("world") }),
134
+ z.strictObject({ kind: z.literal("view"), cameraId: SpatialCameraIdSchema, units: z.enum(["pixels", "normalized"]), order: z.number().int().min(-4_096).max(4_096) }),
135
+ ])
136
+ const entityBase = {
137
+ entityId: SpatialEntityIdSchema,
138
+ name: z.string().min(1).max(256),
139
+ parentId: SpatialEntityIdSchema.nullable(),
140
+ transform: SpatialTransformSchema,
141
+ placement: SpatialPlacementSchema,
142
+ origin: SpatialOriginSchema,
143
+ visible: z.boolean(),
144
+ }
145
+ const surfaceBase = {
146
+ assetId: SpatialAssetIdSchema,
147
+ width: positiveDimension,
148
+ height: positiveDimension,
149
+ fit: z.enum(["contain", "cover", "stretch"]),
150
+ opacity: unit,
151
+ }
152
+ export const SpatialEntitySchema = z.discriminatedUnion("kind", [
153
+ z.strictObject({ ...entityBase, kind: z.literal("group") }),
154
+ z.strictObject({ ...entityBase, kind: z.literal("mesh"), geometry: SpatialGeometrySchema, material: SpatialMaterialSchema }),
155
+ z.strictObject({ ...entityBase, ...surfaceBase, kind: z.literal("image") }),
156
+ z.strictObject({ ...entityBase, ...surfaceBase, kind: z.literal("diagram") }),
157
+ z.strictObject({ ...entityBase, ...surfaceBase, kind: z.literal("video"), sourceOffsetUs: SpatialTimeUsSchema, playback: z.enum(["once", "loop", "freeze"]) }),
158
+ z.strictObject({ ...entityBase, kind: z.literal("text"), text: z.string().max(16_384), fontAssetId: SpatialAssetIdSchema, fontSize: positiveDimension, width: positiveDimension, color, align: z.enum(["left", "center", "right"]) }),
159
+ z.strictObject({ ...entityBase, kind: z.literal("light"), light: z.enum(["ambient", "directional", "point"]), color, intensity: z.number().finite().min(0).max(100_000) }),
160
+ z.strictObject({ ...entityBase, kind: z.literal("splat"), assetId: SpatialAssetIdSchema }),
161
+ ])
162
+
163
+ const key = <T extends z.ZodType>(value: T) => z.strictObject({ timeUs: SpatialTimeUsSchema, value })
164
+ const channelBase = { channelId: SpatialChannelIdSchema, targetId: z.union([SpatialEntityIdSchema, SpatialCameraIdSchema]) }
165
+ export const SpatialAnimationSchema = z.discriminatedUnion("property", [
166
+ z.strictObject({ ...channelBase, property: z.literal("position"), interpolation: z.enum(["step", "linear"]), keys: z.array(key(SpatialVec3Schema)).min(1).max(SPATIAL_SCENE_LIMITS.keysPerChannel) }),
167
+ z.strictObject({ ...channelBase, property: z.literal("rotation"), interpolation: z.enum(["step", "slerp"]), keys: z.array(key(SpatialQuaternionSchema)).min(1).max(SPATIAL_SCENE_LIMITS.keysPerChannel) }),
168
+ z.strictObject({ ...channelBase, property: z.literal("scale"), interpolation: z.enum(["step", "linear"]), keys: z.array(key(z.tuple([positiveDimension, positiveDimension, positiveDimension]))).min(1).max(SPATIAL_SCENE_LIMITS.keysPerChannel) }),
169
+ z.strictObject({ ...channelBase, property: z.literal("opacity"), interpolation: z.enum(["step", "linear"]), keys: z.array(key(unit)).min(1).max(SPATIAL_SCENE_LIMITS.keysPerChannel) }),
170
+ ])
171
+ export const SpatialOverrideSchema = z.discriminatedUnion("property", [
172
+ z.strictObject({ entityId: SpatialEntityIdSchema, property: z.literal("color"), value: color }),
173
+ z.strictObject({ entityId: SpatialEntityIdSchema, property: z.literal("opacity"), value: unit }),
174
+ z.strictObject({ entityId: SpatialEntityIdSchema, property: z.literal("transform"), value: SpatialTransformSchema }),
175
+ ])
176
+ export const SpatialGeneratorSchema = z.strictObject({
177
+ generatorId: SpatialGeneratorIdSchema,
178
+ sourceSha256: SpatialDigestSchema,
179
+ closureSha256: SpatialDigestSchema,
180
+ parametersSha256: SpatialDigestSchema,
181
+ seed: z.number().int().safe().min(0).max(0xffff_ffff),
182
+ outputSha256: SpatialDigestSchema,
183
+ execution: z.discriminatedUnion("kind", [
184
+ z.strictObject({ kind: z.literal("qualified"), runtimeSha256: SpatialDigestSchema }),
185
+ z.strictObject({ kind: z.literal("attempt"), attemptId: z.string().min(1).max(128), runtimeSha256: SpatialDigestSchema }),
186
+ ]),
187
+ editableKeys: z.array(z.strictObject({ key: z.string().min(1).max(256), properties: z.array(z.enum(["color", "opacity", "transform"])).min(1).max(3) })).max(SPATIAL_SCENE_LIMITS.entities),
188
+ })
189
+ export const SpatialSceneV1Schema = z.strictObject({
190
+ kind: z.literal("slopcamera.spatial-scene"),
191
+ schemaVersion: z.literal(1),
192
+ sceneId: SpatialSceneIdSchema,
193
+ coordinates: z.literal("right-handed-y-up-meters"),
194
+ durationUs: SpatialTimeUsSchema.refine(value => value > 0),
195
+ entities: z.array(SpatialEntitySchema).max(SPATIAL_SCENE_LIMITS.entities),
196
+ cameras: z.array(SpatialCameraSchema).min(1).max(SPATIAL_SCENE_LIMITS.cameras),
197
+ assets: z.array(SpatialAssetManifestSchema).max(SPATIAL_SCENE_LIMITS.assets),
198
+ animations: z.array(SpatialAnimationSchema).max(SPATIAL_SCENE_LIMITS.channels),
199
+ generators: z.array(SpatialGeneratorSchema).max(128),
200
+ overrides: z.array(SpatialOverrideSchema).max(SPATIAL_SCENE_LIMITS.entities),
201
+ })
202
+
203
+ export const SpatialPatchOperationSchema = z.discriminatedUnion("kind", [
204
+ z.strictObject({ kind: z.literal("add-asset"), asset: SpatialAssetManifestSchema }),
205
+ z.strictObject({ kind: z.literal("replace-asset"), asset: SpatialAssetManifestSchema }),
206
+ z.strictObject({ kind: z.literal("set-mesh-geometry"), entityId: SpatialEntityIdSchema, geometry: SpatialGeometrySchema }),
207
+ z.strictObject({ kind: z.literal("rename-entity"), entityId: SpatialEntityIdSchema, name: z.string().min(1).max(256) }),
208
+ z.strictObject({ kind: z.literal("reparent-entity"), entityId: SpatialEntityIdSchema, parentId: SpatialEntityIdSchema.nullable() }),
209
+ z.strictObject({ kind: z.literal("set-transform"), entityId: SpatialEntityIdSchema, transform: SpatialTransformSchema }),
210
+ z.strictObject({ kind: z.literal("set-color"), entityId: SpatialEntityIdSchema, color }),
211
+ z.strictObject({ kind: z.literal("set-opacity"), entityId: SpatialEntityIdSchema, opacity: unit }),
212
+ z.strictObject({ kind: z.literal("set-camera"), camera: SpatialCameraSchema }),
213
+ z.strictObject({ kind: z.literal("set-channel"), channel: SpatialAnimationSchema }),
214
+ z.strictObject({ kind: z.literal("remove-channel"), channelId: SpatialChannelIdSchema }),
215
+ z.strictObject({ kind: z.literal("add-entity"), entity: SpatialEntitySchema }),
216
+ z.strictObject({ kind: z.literal("remove-entity"), entityId: SpatialEntityIdSchema }),
217
+ z.strictObject({ kind: z.literal("set-override"), override: SpatialOverrideSchema }),
218
+ z.strictObject({ kind: z.literal("remove-override"), entityId: SpatialEntityIdSchema, property: z.enum(["color", "opacity", "transform"]) }),
219
+ z.strictObject({ kind: z.literal("replace-generator-output"), generator: SpatialGeneratorSchema, entities: z.array(SpatialEntitySchema).max(SPATIAL_SCENE_LIMITS.entities) }),
220
+ ])
221
+ export const SpatialScenePatchV1Schema = z.strictObject({
222
+ kind: z.literal("slopcamera.spatial-scene-patch"),
223
+ schemaVersion: z.literal(1),
224
+ expectedSceneSha256: SpatialDigestSchema,
225
+ operations: z.array(SpatialPatchOperationSchema).min(1).max(SPATIAL_SCENE_LIMITS.patchOperations),
226
+ })
227
+ export const SpatialShotV1Schema = z.strictObject({
228
+ shotId: SpatialShotIdSchema,
229
+ sceneSha256: SpatialDigestSchema,
230
+ cameraId: SpatialCameraIdSchema,
231
+ range: z.strictObject({ startUs: SpatialTimeUsSchema, endUs: SpatialTimeUsSchema }),
232
+ sceneStartUs: SpatialTimeUsSchema,
233
+ playback: z.enum(["once", "loop", "freeze"]),
234
+ overrides: z.array(SpatialOverrideSchema).max(SPATIAL_SCENE_LIMITS.entities),
235
+ cameraPoseOverride: SpatialPoseSchema.optional(),
236
+ }).refine(shot => shot.range.endUs > shot.range.startUs, "Shot range must be nonempty and half-open.")
237
+
238
+ const matrixNumber = z.number().finite().min(-1e12).max(1e12)
239
+ export const SpatialMatrixSchema = z.tuple([
240
+ matrixNumber, matrixNumber, matrixNumber, matrixNumber,
241
+ matrixNumber, matrixNumber, matrixNumber, matrixNumber,
242
+ matrixNumber, matrixNumber, matrixNumber, matrixNumber,
243
+ matrixNumber, matrixNumber, matrixNumber, matrixNumber,
244
+ ])
245
+ export const EvaluatedSpatialSceneSchema = z.strictObject({
246
+ kind: z.literal("slopcamera.spatial-snapshot"),
247
+ schemaVersion: z.literal(1),
248
+ sceneSha256: SpatialDigestSchema,
249
+ stateSha256: SpatialDigestSchema,
250
+ viewSha256: SpatialDigestSchema,
251
+ timeUs: SpatialTimeUsSchema,
252
+ camera: SpatialCameraSchema,
253
+ entities: z.array(z.strictObject({
254
+ entity: SpatialEntitySchema,
255
+ worldMatrix: SpatialMatrixSchema,
256
+ visible: z.boolean(),
257
+ selectionId: z.number().int().min(1).max(SPATIAL_SCENE_LIMITS.entities),
258
+ })).max(SPATIAL_SCENE_LIMITS.entities),
259
+ assets: z.array(SpatialAssetManifestSchema).max(SPATIAL_SCENE_LIMITS.assets),
260
+ })
261
+
262
+ type DeepReadonly<T> = T extends object ? { readonly [Key in keyof T]: DeepReadonly<T[Key]> } : T
263
+ export type SpatialSceneV1 = DeepReadonly<z.infer<typeof SpatialSceneV1Schema>>
264
+ export type SpatialEntity = DeepReadonly<z.infer<typeof SpatialEntitySchema>>
265
+ export type SpatialCamera = DeepReadonly<z.infer<typeof SpatialCameraSchema>>
266
+ export type SpatialProjection = DeepReadonly<z.infer<typeof SpatialProjectionSchema>>
267
+ export type SpatialTransform = DeepReadonly<z.infer<typeof SpatialTransformSchema>>
268
+ export type SpatialPose = DeepReadonly<z.infer<typeof SpatialPoseSchema>>
269
+ export type SpatialAssetManifest = DeepReadonly<z.infer<typeof SpatialAssetManifestSchema>>
270
+ export type SpatialAnimation = DeepReadonly<z.infer<typeof SpatialAnimationSchema>>
271
+ export type SpatialOverride = DeepReadonly<z.infer<typeof SpatialOverrideSchema>>
272
+ export type SpatialGenerator = DeepReadonly<z.infer<typeof SpatialGeneratorSchema>>
273
+ export type SpatialFrameRate = DeepReadonly<z.infer<typeof SpatialFrameRateSchema>>
274
+ export type SpatialScenePatchV1 = DeepReadonly<z.infer<typeof SpatialScenePatchV1Schema>>
275
+ export type SpatialPatchOperation = DeepReadonly<z.infer<typeof SpatialPatchOperationSchema>>
276
+ export type SpatialShotV1 = DeepReadonly<z.infer<typeof SpatialShotV1Schema>>
277
+ export type EvaluatedSpatialScene = DeepReadonly<z.infer<typeof EvaluatedSpatialSceneSchema>>
@@ -0,0 +1,145 @@
1
+ import { z } from "zod"
2
+ import { deepFreezeJson } from "../code/json-snapshot.js"
3
+ import {
4
+ EvaluatedSpatialSceneSchema, SPATIAL_SCENE_LIMITS, SpatialCameraIdSchema, SpatialOverrideSchema, SpatialPoseSchema,
5
+ SpatialShotV1Schema, SpatialTimeUsSchema,
6
+ type EvaluatedSpatialScene, type SpatialAnimation, type SpatialCamera, type SpatialEntity,
7
+ type SpatialOverride, type SpatialPose, type SpatialShotV1,
8
+ } from "./contracts.js"
9
+ import {
10
+ parseSpatialScene, parseSpatialValue, sortSpatialBy, spatialAssetClosureDigests,
11
+ SpatialSceneError, spatialPropertySupported, spatialStateValueSha256, spatialTopologicalIds, spatialValueSha256, validateSpatialOverrides,
12
+ } from "./identity.js"
13
+ import { composeTransform, multiplyTransforms, slerpQuaternion, type Mat4 } from "./math.js"
14
+
15
+ export interface EvaluateSpatialSceneOptions {
16
+ readonly timeUs: number
17
+ readonly cameraId: string
18
+ readonly overrides?: readonly SpatialOverride[]
19
+ readonly cameraPoseOverride?: SpatialPose
20
+ }
21
+
22
+ const EvaluatedOptionsSchema = z.strictObject({
23
+ timeUs: SpatialTimeUsSchema, cameraId: SpatialCameraIdSchema,
24
+ overrides: z.array(SpatialOverrideSchema).max(SPATIAL_SCENE_LIMITS.entities).optional(),
25
+ cameraPoseOverride: SpatialPoseSchema.optional(),
26
+ })
27
+
28
+ export function mergeSpatialOverrides(sceneOverrides: readonly SpatialOverride[], shotOverrides: readonly SpatialOverride[]): readonly SpatialOverride[] {
29
+ const effective = new Map(sceneOverrides.map(override => [`${override.entityId}:${override.property}`, override]))
30
+ const seen = new Set<string>()
31
+ for (const override of shotOverrides) {
32
+ const key = `${override.entityId}:${override.property}`
33
+ if (seen.has(key)) throw new SpatialSceneError("conflict", `Duplicate shot override ${key}.`, "shot.overrides")
34
+ seen.add(key)
35
+ effective.set(key, override)
36
+ }
37
+ return deepFreezeJson(sortSpatialBy([...effective.values()], item => `${item.entityId}:${item.property}`))
38
+ }
39
+
40
+ export function applySpatialEntityOverride(entity: SpatialEntity, override: SpatialOverride): SpatialEntity {
41
+ if (!spatialPropertySupported(entity, override.property)) throw new SpatialSceneError("conflict", `Unsupported override ${entity.entityId}.${override.property}.`)
42
+ if (override.property === "transform") return { ...entity, transform: override.value }
43
+ if (override.property === "color") {
44
+ const color = override.value.toLowerCase()
45
+ if (entity.kind === "mesh") return { ...entity, material: { ...entity.material, color } }
46
+ if (entity.kind === "text" || entity.kind === "light") return { ...entity, color }
47
+ }
48
+ if (override.property === "opacity") {
49
+ if (entity.kind === "mesh") return { ...entity, material: { ...entity.material, opacity: override.value } }
50
+ if (entity.kind === "image" || entity.kind === "diagram" || entity.kind === "video") return { ...entity, opacity: override.value }
51
+ }
52
+ throw new SpatialSceneError("conflict", `Unsupported override ${entity.entityId}.${override.property}.`)
53
+ }
54
+
55
+ function sampleChannel(channel: SpatialAnimation, timeUs: number): number | readonly number[] {
56
+ const keys = channel.keys
57
+ if (timeUs <= keys[0]!.timeUs) return keys[0]!.value
58
+ if (timeUs >= keys[keys.length - 1]!.timeUs) return keys[keys.length - 1]!.value
59
+ let lower = 0, upper = keys.length - 1
60
+ while (upper - lower > 1) {
61
+ const middle = Math.floor((lower + upper) / 2)
62
+ if (keys[middle]!.timeUs <= timeUs) lower = middle
63
+ else upper = middle
64
+ }
65
+ const a = keys[lower]!, b = keys[upper]!
66
+ if (channel.interpolation === "step") return a.value
67
+ const t = (timeUs - a.timeUs) / (b.timeUs - a.timeUs)
68
+ if (channel.property === "rotation") {
69
+ return slerpQuaternion(channel.keys[lower]!.value, channel.keys[upper]!.value, t)
70
+ }
71
+ if (typeof a.value === "number" && typeof b.value === "number") return a.value + (b.value - a.value) * t
72
+ const av = a.value as readonly number[], bv = b.value as readonly number[]
73
+ return av.map((value, index) => value + (bv[index]! - value) * t)
74
+ }
75
+
76
+ export function validateSpatialShot(sceneInput: unknown, shotInput: unknown): SpatialShotV1 {
77
+ const scene = parseSpatialScene(sceneInput)
78
+ const shot = parseSpatialValue(SpatialShotV1Schema, shotInput, "shot")
79
+ if (shot.sceneSha256 !== spatialValueSha256(scene)) throw new SpatialSceneError("conflict", "Shot pins another scene revision.", "shot.sceneSha256")
80
+ if (!scene.cameras.some(camera => camera.cameraId === shot.cameraId)) throw new SpatialSceneError("invalid-data", "Shot camera is absent from its scene.", "shot.cameraId")
81
+ if (shot.sceneStartUs >= scene.durationUs) throw new SpatialSceneError("invalid-data", "Shot scene start must precede scene duration.", "shot.sceneStartUs")
82
+ if (shot.playback === "once" && shot.sceneStartUs + shot.range.endUs - shot.range.startUs > scene.durationUs) throw new SpatialSceneError("invalid-data", "Once playback exceeds scene duration.", "shot.range")
83
+ validateSpatialOverrides(scene, mergeSpatialOverrides(scene.overrides, shot.overrides))
84
+ if (shot.cameraPoseOverride && scene.animations.some(channel => channel.targetId === shot.cameraId)) throw new SpatialSceneError("conflict", "Camera animation and shot pose override both own camera pose.", "shot.cameraPoseOverride")
85
+ return deepFreezeJson(shot)
86
+ }
87
+
88
+ /** Absolute time evaluation produces one immutable snapshot; calls share no mutable state. */
89
+ export function evaluateSpatialScene(sceneInput: unknown, options: EvaluateSpatialSceneOptions): EvaluatedSpatialScene {
90
+ const scene = parseSpatialScene(sceneInput)
91
+ // Capture the complete options object before inspecting optional properties.
92
+ const capturedOptions = parseSpatialValue(
93
+ // Explicit object schema also rejects unsupported simulation or executable fields.
94
+ EvaluatedOptionsSchema, options, "evaluation options",
95
+ )
96
+ const timeUs = capturedOptions.timeUs
97
+ if (timeUs > scene.durationUs) throw new SpatialSceneError("invalid-data", "Evaluation time exceeds scene duration.", "timeUs")
98
+ let camera = scene.cameras.find(item => item.cameraId === capturedOptions.cameraId)
99
+ if (!camera) throw new SpatialSceneError("not-found", `Unknown camera ${capturedOptions.cameraId}.`, "cameraId")
100
+ const overrides = mergeSpatialOverrides(scene.overrides, capturedOptions.overrides ?? [])
101
+ validateSpatialOverrides(scene, overrides)
102
+ if (capturedOptions.cameraPoseOverride && scene.animations.some(channel => channel.targetId === camera!.cameraId)) throw new SpatialSceneError("conflict", "Camera animation conflicts with camera pose override.", "cameraPoseOverride")
103
+ const entities = new Map(scene.entities.map(entity => [entity.entityId, entity]))
104
+ for (const channel of scene.animations) {
105
+ const value = sampleChannel(channel, timeUs)
106
+ if (channel.targetId === camera.cameraId) {
107
+ camera = { ...camera, pose: { ...camera.pose, [channel.property]: value } } as SpatialCamera
108
+ } else {
109
+ const entity = entities.get(channel.targetId)
110
+ if (!entity) continue // Other cameras do not affect the requested view.
111
+ if (channel.property === "opacity") entities.set(entity.entityId, applySpatialEntityOverride(entity, { entityId: entity.entityId, property: "opacity", value: value as number }))
112
+ else entities.set(entity.entityId, { ...entity, transform: { ...entity.transform, [channel.property]: value } } as SpatialEntity)
113
+ }
114
+ }
115
+ for (const override of overrides) entities.set(override.entityId, applySpatialEntityOverride(entities.get(override.entityId)!, override))
116
+ if (capturedOptions.cameraPoseOverride) camera = { ...camera, pose: capturedOptions.cameraPoseOverride }
117
+ const matrices = new Map<string, Mat4>()
118
+ const visibility = new Map<string, boolean>()
119
+ const order = spatialTopologicalIds(new Map(scene.entities.map(entity => [entity.entityId, entity.parentId === null ? [] : [entity.parentId]])), "entity hierarchy")
120
+ for (const id of order) {
121
+ const entity = entities.get(id)!
122
+ try {
123
+ const local = composeTransform(entity.transform)
124
+ matrices.set(id, entity.parentId === null ? local : multiplyTransforms(matrices.get(entity.parentId)!, local))
125
+ } catch (error) {
126
+ throw new SpatialSceneError("invalid-data", error instanceof Error ? error.message : "Invalid evaluated transform.", `entities.${id}.transform`)
127
+ }
128
+ visibility.set(id, entity.visible && (entity.parentId === null || visibility.get(entity.parentId) === true))
129
+ }
130
+ const evaluated = scene.entities.map((source, index) => ({
131
+ entity: entities.get(source.entityId)!, worldMatrix: matrices.get(source.entityId)!,
132
+ visible: visibility.get(source.entityId)!, selectionId: index + 1,
133
+ }))
134
+ // The state identity excludes camera choice, camera pose, asset locator and provenance.
135
+ const assetDigests = spatialAssetClosureDigests(scene.assets)
136
+ const stateSha256 = spatialStateValueSha256({ domain: "slopcamera.spatial-state.v1", timeUs, entities: evaluated, assetDigests })
137
+ const viewSha256 = spatialValueSha256({ domain: "slopcamera.spatial-view.v1", stateSha256, camera })
138
+ const result = EvaluatedSpatialSceneSchema.parse({
139
+ kind: "slopcamera.spatial-snapshot", schemaVersion: 1, sceneSha256: spatialValueSha256(scene),
140
+ stateSha256, viewSha256, timeUs, camera,
141
+ entities: evaluated.map(item => ({ ...item, visible: item.visible && (item.entity.placement.kind === "world" || item.entity.placement.cameraId === camera.cameraId) })),
142
+ assets: scene.assets,
143
+ })
144
+ return deepFreezeJson(result)
145
+ }