@vibecook/ice 0.10.0 → 0.14.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 (380) hide show
  1. package/README.md +79 -50
  2. package/dist/chunk-BA7XJC27.js +2429 -0
  3. package/dist/chunk-BA7XJC27.js.map +1 -0
  4. package/dist/chunk-BKV4ZEU3.js +1 -0
  5. package/dist/chunk-BKV4ZEU3.js.map +1 -0
  6. package/dist/{chunk-5FQS7V2C.js → chunk-DYK6KNLG.js} +13303 -7485
  7. package/dist/chunk-DYK6KNLG.js.map +1 -0
  8. package/dist/chunk-ENIFIUEP.js +155 -0
  9. package/dist/chunk-ENIFIUEP.js.map +1 -0
  10. package/dist/chunk-IBWWLA6D.js +634 -0
  11. package/dist/chunk-IBWWLA6D.js.map +1 -0
  12. package/dist/{chunk-OR5FNVUE.js → chunk-JS6PG6YD.js} +398 -167
  13. package/dist/chunk-JS6PG6YD.js.map +1 -0
  14. package/dist/chunk-QXOCF56A.js +148 -0
  15. package/dist/chunk-QXOCF56A.js.map +1 -0
  16. package/dist/chunk-ZPUPBULB.js +7399 -0
  17. package/dist/chunk-ZPUPBULB.js.map +1 -0
  18. package/dist/desk-engine.js +36 -0
  19. package/dist/desk-engine.js.map +1 -0
  20. package/dist/desk-kit.js +244 -0
  21. package/dist/desk-kit.js.map +1 -0
  22. package/dist/desk-objects.js +12728 -0
  23. package/dist/desk-objects.js.map +1 -0
  24. package/dist/desk.js +469 -0
  25. package/dist/desk.js.map +1 -0
  26. package/dist/devtools.js +233 -189
  27. package/dist/devtools.js.map +1 -1
  28. package/dist/dom.js +7 -19
  29. package/dist/index.js +232 -20
  30. package/dist/kernel.js +53 -25
  31. package/dist/react.js +1045 -38
  32. package/dist/react.js.map +1 -1
  33. package/dist/types/packages/core/src/behavior/define-behavior.d.ts +11 -0
  34. package/dist/types/packages/core/src/behavior/runtime.d.ts +4 -0
  35. package/dist/types/packages/core/src/canvas/define-canvas-type.d.ts +86 -0
  36. package/dist/types/packages/core/src/canvas/define-container.d.ts +17 -0
  37. package/dist/types/packages/core/src/canvas/diagnostics.d.ts +27 -0
  38. package/dist/types/packages/core/src/canvas/engine-catalog.d.ts +70 -0
  39. package/dist/types/packages/core/src/canvas/extensions.d.ts +125 -0
  40. package/dist/types/packages/core/src/canvas/frame-behavior-host.d.ts +16 -0
  41. package/dist/types/packages/core/src/canvas/frame-preview.d.ts +79 -0
  42. package/dist/types/packages/core/src/canvas/frame-projection.d.ts +38 -0
  43. package/dist/types/packages/core/src/canvas/frame-view.d.ts +36 -0
  44. package/dist/types/packages/core/src/canvas/migrate.d.ts +14 -0
  45. package/dist/types/packages/core/src/canvas/placement.d.ts +30 -0
  46. package/dist/types/packages/core/src/canvas/presentation-transition.d.ts +100 -0
  47. package/dist/types/packages/core/src/canvas/runtime-extension-host.d.ts +16 -0
  48. package/dist/types/packages/core/src/canvas/session.d.ts +47 -0
  49. package/dist/types/packages/core/src/catalog/camera-derived.d.ts +16 -27
  50. package/dist/types/packages/core/src/catalog/desk.d.ts +326 -0
  51. package/dist/types/packages/core/src/catalog/gesture.d.ts +51 -0
  52. package/dist/types/packages/core/src/catalog/graph.d.ts +2 -2
  53. package/dist/types/packages/core/src/catalog/index.d.ts +2 -0
  54. package/dist/types/packages/core/src/catalog/pointer.d.ts +42 -0
  55. package/dist/types/packages/core/src/catalog/selection-presence.d.ts +7 -0
  56. package/dist/types/packages/core/src/catalog/settings-resources.d.ts +28 -2
  57. package/dist/types/packages/core/src/catalog/surface.d.ts +1 -0
  58. package/dist/types/packages/core/src/doc/doc-commit-sink.d.ts +18 -2
  59. package/dist/types/packages/core/src/doc/doc-kit.d.ts +21 -2
  60. package/dist/types/packages/core/src/doc/envelope.d.ts +5 -2
  61. package/dist/types/packages/core/src/doc/schema-migrate.d.ts +1 -1
  62. package/dist/types/packages/core/src/doc/version-gate.d.ts +21 -3
  63. package/dist/types/packages/core/src/engine/commit-sink.d.ts +10 -1
  64. package/dist/types/packages/core/src/engine/engine.d.ts +6 -0
  65. package/dist/types/packages/core/src/engine/frame-control.d.ts +74 -0
  66. package/dist/types/packages/core/src/engine/guests.d.ts +4 -1
  67. package/dist/types/packages/core/src/engine/world-doors.d.ts +12 -0
  68. package/dist/types/packages/core/src/facade/create-canvas-engine.d.ts +146 -13
  69. package/dist/types/packages/core/src/index.d.ts +34 -13
  70. package/dist/types/packages/core/src/input/queue.d.ts +3 -1
  71. package/dist/types/packages/core/src/interaction/install.d.ts +30 -0
  72. package/dist/types/packages/core/src/interaction/wakes.d.ts +24 -0
  73. package/dist/types/packages/core/src/nav/nav-geometry.d.ts +100 -0
  74. package/dist/types/packages/core/src/nav/nested-canvas.d.ts +47 -4
  75. package/dist/types/packages/core/src/ops/cascade.d.ts +2 -1
  76. package/dist/types/packages/core/src/ops/claims.d.ts +6 -0
  77. package/dist/types/packages/core/src/ops/insert.d.ts +4 -0
  78. package/dist/types/packages/core/src/ops/point-pick.d.ts +4 -1
  79. package/dist/types/packages/core/src/ops/sibling-order.d.ts +14 -4
  80. package/dist/types/packages/core/src/ops/tray.d.ts +48 -0
  81. package/dist/types/packages/core/src/presence/presence-kit.d.ts +5 -0
  82. package/dist/types/packages/core/src/schema/meta.d.ts +10 -0
  83. package/dist/types/packages/core/src/schema/prefab.d.ts +8 -0
  84. package/dist/types/packages/core/src/settings/defaults.d.ts +25 -6
  85. package/dist/types/packages/core/src/surface/gpu-device.d.ts +55 -0
  86. package/dist/types/packages/core/src/systems/camera-sim.d.ts +29 -0
  87. package/dist/types/packages/core/src/systems/chrome.d.ts +15 -23
  88. package/dist/types/packages/core/src/systems/drag-mods.d.ts +34 -0
  89. package/dist/types/packages/core/src/systems/held.d.ts +71 -0
  90. package/dist/types/packages/core/src/systems/insert-ghost.d.ts +2 -0
  91. package/dist/types/packages/core/src/systems/l0-input.d.ts +14 -0
  92. package/dist/types/packages/core/src/systems/l1-pick.d.ts +37 -1
  93. package/dist/types/packages/core/src/systems/l2-arbitrate.d.ts +18 -4
  94. package/dist/types/packages/core/src/systems/l3-behave.d.ts +4 -1
  95. package/dist/types/packages/core/src/systems/l3-claim.d.ts +7 -0
  96. package/dist/types/packages/core/src/systems/l3-connect.d.ts +1 -1
  97. package/dist/types/packages/core/src/systems/l3-drop.d.ts +30 -1
  98. package/dist/types/packages/core/src/systems/l3-marquee.d.ts +2 -1
  99. package/dist/types/packages/core/src/systems/l3-ports.d.ts +1 -1
  100. package/dist/types/packages/core/src/systems/l4-cursor.d.ts +5 -0
  101. package/dist/types/packages/core/src/systems/nav-flight.d.ts +85 -3
  102. package/dist/types/packages/core/src/systems/nav-tap.d.ts +44 -0
  103. package/dist/types/packages/core/src/systems/press-wheel.d.ts +11 -0
  104. package/dist/types/packages/core/src/systems/tray.d.ts +108 -0
  105. package/dist/types/packages/core/src/systems/zoom-through.d.ts +30 -0
  106. package/dist/types/packages/core/src/tools/define-tool.d.ts +10 -0
  107. package/dist/types/packages/core/src/widget/define-widget.d.ts +166 -63
  108. package/dist/types/packages/core/src/widget/equip.d.ts +14 -2
  109. package/dist/types/packages/core/src/widget/held-tools.d.ts +83 -0
  110. package/dist/types/packages/core/src/widget/menu-actions.d.ts +44 -0
  111. package/dist/types/packages/core/src/widget/mount-store.d.ts +21 -46
  112. package/dist/types/packages/core/src/widget/spawn.d.ts +1 -1
  113. package/dist/types/packages/desk/src/assets/blue-noise.gen.d.ts +10 -0
  114. package/dist/types/packages/desk/src/card/card.d.ts +103 -0
  115. package/dist/types/packages/desk/src/compose/ambient.d.ts +59 -0
  116. package/dist/types/packages/desk/src/compose/builder.d.ts +285 -0
  117. package/dist/types/packages/desk/src/compose/children.d.ts +3 -0
  118. package/dist/types/packages/desk/src/compose/index.d.ts +14 -0
  119. package/dist/types/packages/desk/src/compose/marks.d.ts +126 -0
  120. package/dist/types/packages/desk/src/compose/pick.d.ts +5 -0
  121. package/dist/types/packages/desk/src/compose/reflector.d.ts +111 -0
  122. package/dist/types/packages/desk/src/compose/tap.d.ts +5 -0
  123. package/dist/types/packages/desk/src/docs.d.ts +23 -0
  124. package/dist/types/packages/desk/src/engine/budget.d.ts +38 -0
  125. package/dist/types/packages/desk/src/engine/device.d.ts +54 -0
  126. package/dist/types/packages/desk/src/engine/index.d.ts +5 -0
  127. package/dist/types/packages/desk/src/engine/pipeline.d.ts +36 -0
  128. package/dist/types/packages/desk/src/engine/rasters.d.ts +66 -0
  129. package/dist/types/packages/desk/src/engine/records.d.ts +56 -0
  130. package/dist/types/packages/desk/src/engine/shader.d.ts +22 -0
  131. package/dist/types/packages/desk/src/engine/struct.d.ts +39 -0
  132. package/dist/types/packages/desk/src/engine/target.d.ts +26 -0
  133. package/dist/types/packages/desk/src/gpu-ablation.d.ts +61 -0
  134. package/dist/types/packages/desk/src/gpu-memory.d.ts +54 -0
  135. package/dist/types/packages/desk/src/gpu-profiler.d.ts +141 -0
  136. package/dist/types/packages/desk/src/gpu-wrap.d.ts +8 -0
  137. package/dist/types/packages/desk/src/ground.d.ts +388 -0
  138. package/dist/types/packages/desk/src/hold/focus.d.ts +53 -0
  139. package/dist/types/packages/desk/src/hold/pose.d.ts +132 -0
  140. package/dist/types/packages/desk/src/hold/shaders.d.ts +9 -0
  141. package/dist/types/packages/desk/src/host/editor.d.ts +18 -0
  142. package/dist/types/packages/desk/src/host/index.d.ts +9 -0
  143. package/dist/types/packages/desk/src/host/ink.d.ts +18 -0
  144. package/dist/types/packages/desk/src/host/layer.d.ts +430 -0
  145. package/dist/types/packages/desk/src/host/picture.d.ts +2 -0
  146. package/dist/types/packages/desk/src/host/surface.d.ts +5 -0
  147. package/dist/types/packages/desk/src/index.d.ts +13 -0
  148. package/dist/types/packages/desk/src/kind.d.ts +187 -0
  149. package/dist/types/packages/desk/src/kinds/world.d.ts +429 -0
  150. package/dist/types/packages/desk/src/kit/arrays.d.ts +88 -0
  151. package/dist/types/packages/desk/src/kit/blobs.d.ts +40 -0
  152. package/dist/types/packages/desk/src/kit/book.d.ts +2 -0
  153. package/dist/types/packages/desk/src/kit/editor.d.ts +103 -0
  154. package/dist/types/packages/desk/src/kit/eye.d.ts +37 -0
  155. package/dist/types/packages/desk/src/kit/hold.d.ts +1 -0
  156. package/dist/types/packages/desk/src/kit/index.d.ts +26 -0
  157. package/dist/types/packages/desk/src/kit/inside.d.ts +116 -0
  158. package/dist/types/packages/desk/src/kit/layer.d.ts +159 -0
  159. package/dist/types/packages/desk/src/kit/light.d.ts +3 -0
  160. package/dist/types/packages/desk/src/kit/mesh.d.ts +29 -0
  161. package/dist/types/packages/desk/src/kit/mips.d.ts +2 -0
  162. package/dist/types/packages/desk/src/kit/nav.d.ts +2 -0
  163. package/dist/types/packages/desk/src/kit/paper-tex.d.ts +5 -0
  164. package/dist/types/packages/desk/src/kit/physics.d.ts +44 -0
  165. package/dist/types/packages/desk/src/kit/place.d.ts +44 -0
  166. package/dist/types/packages/desk/src/kit/print.d.ts +30 -0
  167. package/dist/types/packages/desk/src/kit/raster.d.ts +34 -0
  168. package/dist/types/packages/desk/src/kit/sdf.d.ts +1 -0
  169. package/dist/types/packages/desk/src/kit/seeds.d.ts +11 -0
  170. package/dist/types/packages/desk/src/kit/services.d.ts +34 -0
  171. package/dist/types/packages/desk/src/kit/springs.d.ts +12 -0
  172. package/dist/types/packages/desk/src/kit/strokes.d.ts +93 -0
  173. package/dist/types/packages/desk/src/kit/text.d.ts +142 -0
  174. package/dist/types/packages/desk/src/kit/uniform.d.ts +8 -0
  175. package/dist/types/packages/desk/src/kit/view.d.ts +39 -0
  176. package/dist/types/packages/desk/src/kit/wgsl.d.ts +15 -0
  177. package/dist/types/packages/desk/src/lattice/line.d.ts +15 -0
  178. package/dist/types/packages/desk/src/lattice/lod.d.ts +52 -0
  179. package/dist/types/packages/desk/src/lattice/ruler.d.ts +88 -0
  180. package/dist/types/packages/desk/src/marks/assemble.d.ts +65 -0
  181. package/dist/types/packages/desk/src/marks/ease.d.ts +4 -0
  182. package/dist/types/packages/desk/src/marks/laser.d.ts +41 -0
  183. package/dist/types/packages/desk/src/marks/layout.d.ts +167 -0
  184. package/dist/types/packages/desk/src/marks/pass.d.ts +59 -0
  185. package/dist/types/packages/desk/src/marks/shaders.d.ts +12 -0
  186. package/dist/types/packages/desk/src/mat/grid.d.ts +50 -0
  187. package/dist/types/packages/desk/src/mat/lamp.d.ts +14 -0
  188. package/dist/types/packages/desk/src/mat/layout.d.ts +144 -0
  189. package/dist/types/packages/desk/src/mat/mat-pass.d.ts +83 -0
  190. package/dist/types/packages/desk/src/mat/night.d.ts +95 -0
  191. package/dist/types/packages/desk/src/mat/projector.d.ts +39 -0
  192. package/dist/types/packages/desk/src/mat/shaders.d.ts +17 -0
  193. package/dist/types/packages/desk/src/mat/tilt.d.ts +14 -0
  194. package/dist/types/packages/desk/src/nav/flight.d.ts +186 -0
  195. package/dist/types/packages/desk/src/nav/portal.d.ts +95 -0
  196. package/dist/types/packages/desk/src/object.d.ts +46 -0
  197. package/dist/types/packages/desk/src/pass-instrument.d.ts +89 -0
  198. package/dist/types/packages/desk/src/shaders.d.ts +12 -0
  199. package/dist/types/packages/desk/src/shaders.gen.d.ts +16 -0
  200. package/dist/types/packages/desk/src/submit-instrument.d.ts +36 -0
  201. package/dist/types/packages/desk/src/theme.d.ts +475 -0
  202. package/dist/types/packages/desk/src/tray/carry.d.ts +99 -0
  203. package/dist/types/packages/desk/src/tray/drawer.d.ts +113 -0
  204. package/dist/types/packages/desk/src/tray/flux.d.ts +46 -0
  205. package/dist/types/packages/desk/src/tray/index.d.ts +4 -0
  206. package/dist/types/packages/desk/src/tray/lattice.d.ts +71 -0
  207. package/dist/types/packages/desk/src/tray/layout.d.ts +7 -0
  208. package/dist/types/packages/desk/src/tray/look.d.ts +29 -0
  209. package/dist/types/packages/desk/src/tray/pass.d.ts +96 -0
  210. package/dist/types/packages/desk/src/tray/shaders.d.ts +10 -0
  211. package/dist/types/packages/desk/src/tray/specimens.d.ts +199 -0
  212. package/dist/types/packages/devtools/src/attach.d.ts +22 -8
  213. package/dist/types/packages/devtools/src/dock.d.ts +18 -14
  214. package/dist/types/packages/devtools/src/gpu-panel.d.ts +105 -0
  215. package/dist/types/packages/devtools/src/index.d.ts +5 -4
  216. package/dist/types/packages/dom/src/desk-host.d.ts +91 -0
  217. package/dist/types/packages/dom/src/host.d.ts +13 -14
  218. package/dist/types/packages/dom/src/index.d.ts +12 -10
  219. package/dist/types/packages/dom/src/loop.d.ts +18 -1
  220. package/dist/types/packages/dom/src/pointer-adapter.d.ts +5 -29
  221. package/dist/types/packages/dom/src/widget-focus.d.ts +17 -13
  222. package/dist/types/packages/ice/src/desk-engine.d.ts +2 -0
  223. package/dist/types/packages/ice/src/desk-kit.d.ts +6 -0
  224. package/dist/types/packages/ice/src/desk-objects.d.ts +5 -0
  225. package/dist/types/packages/ice/src/desk.d.ts +5 -0
  226. package/dist/types/packages/kernel/src/atlas-pack.d.ts +157 -0
  227. package/dist/types/packages/kernel/src/bezier.d.ts +0 -15
  228. package/dist/types/packages/kernel/src/coords.d.ts +0 -39
  229. package/dist/types/packages/kernel/src/index.d.ts +2 -2
  230. package/dist/types/packages/kernel/src/nav-flight.d.ts +6 -0
  231. package/dist/types/packages/kernel/src/tray.d.ts +155 -0
  232. package/dist/types/packages/objects/src/board/board-pass.d.ts +180 -0
  233. package/dist/types/packages/objects/src/board/board-pen.d.ts +36 -0
  234. package/dist/types/packages/objects/src/board/board.d.ts +104 -0
  235. package/dist/types/packages/objects/src/board/data.d.ts +31 -0
  236. package/dist/types/packages/objects/src/board/history.d.ts +33 -0
  237. package/dist/types/packages/objects/src/board/kind.d.ts +208 -0
  238. package/dist/types/packages/objects/src/board/layout.d.ts +102 -0
  239. package/dist/types/packages/objects/src/board/object.d.ts +7 -0
  240. package/dist/types/packages/objects/src/board/pen.d.ts +71 -0
  241. package/dist/types/packages/objects/src/board/shaders.d.ts +36 -0
  242. package/dist/types/packages/objects/src/board/stroke.d.ts +99 -0
  243. package/dist/types/packages/objects/src/board/theme.d.ts +150 -0
  244. package/dist/types/packages/objects/src/calendar/data.d.ts +97 -0
  245. package/dist/types/packages/objects/src/calendar/events.d.ts +58 -0
  246. package/dist/types/packages/objects/src/calendar/hand.d.ts +53 -0
  247. package/dist/types/packages/objects/src/calendar/host/input.d.ts +67 -0
  248. package/dist/types/packages/objects/src/calendar/host/print.d.ts +9 -0
  249. package/dist/types/packages/objects/src/calendar/kind.d.ts +297 -0
  250. package/dist/types/packages/objects/src/calendar/law.d.ts +151 -0
  251. package/dist/types/packages/objects/src/calendar/layout.d.ts +47 -0
  252. package/dist/types/packages/objects/src/calendar/month.d.ts +75 -0
  253. package/dist/types/packages/objects/src/calendar/object.d.ts +45 -0
  254. package/dist/types/packages/objects/src/calendar/pad.d.ts +42 -0
  255. package/dist/types/packages/objects/src/calendar/pass.d.ts +229 -0
  256. package/dist/types/packages/objects/src/calendar/print.d.ts +87 -0
  257. package/dist/types/packages/objects/src/calendar/printing.d.ts +80 -0
  258. package/dist/types/packages/objects/src/calendar/roll.d.ts +45 -0
  259. package/dist/types/packages/objects/src/calendar/shaders.d.ts +12 -0
  260. package/dist/types/packages/objects/src/calendar/sheet.d.ts +43 -0
  261. package/dist/types/packages/objects/src/calendar/tiles.d.ts +67 -0
  262. package/dist/types/packages/objects/src/calendar/turn.d.ts +73 -0
  263. package/dist/types/packages/objects/src/calendar/writing.d.ts +42 -0
  264. package/dist/types/packages/objects/src/index.d.ts +22 -0
  265. package/dist/types/packages/objects/src/kinds.d.ts +24 -0
  266. package/dist/types/packages/objects/src/minimat/inside.d.ts +17 -0
  267. package/dist/types/packages/objects/src/minimat/kind.d.ts +51 -0
  268. package/dist/types/packages/objects/src/minimat/layout.d.ts +83 -0
  269. package/dist/types/packages/objects/src/minimat/minimat.d.ts +179 -0
  270. package/dist/types/packages/objects/src/minimat/object.d.ts +8 -0
  271. package/dist/types/packages/objects/src/minimat/pass.d.ts +61 -0
  272. package/dist/types/packages/objects/src/minimat/shaders.d.ts +10 -0
  273. package/dist/types/packages/objects/src/minimat/theme.d.ts +98 -0
  274. package/dist/types/packages/objects/src/notebook/ink.d.ts +70 -0
  275. package/dist/types/packages/objects/src/notebook/kind.d.ts +236 -0
  276. package/dist/types/packages/objects/src/notebook/law.d.ts +129 -0
  277. package/dist/types/packages/objects/src/notebook/layout.d.ts +46 -0
  278. package/dist/types/packages/objects/src/notebook/leaf.d.ts +44 -0
  279. package/dist/types/packages/objects/src/notebook/mesh.d.ts +20 -0
  280. package/dist/types/packages/objects/src/notebook/motion.d.ts +107 -0
  281. package/dist/types/packages/objects/src/notebook/object.d.ts +8 -0
  282. package/dist/types/packages/objects/src/notebook/pages.d.ts +56 -0
  283. package/dist/types/packages/objects/src/notebook/pass.d.ts +197 -0
  284. package/dist/types/packages/objects/src/notebook/pick.d.ts +30 -0
  285. package/dist/types/packages/objects/src/notebook/raster.d.ts +28 -0
  286. package/dist/types/packages/objects/src/notebook/shaders.d.ts +11 -0
  287. package/dist/types/packages/objects/src/notebook/shape.d.ts +155 -0
  288. package/dist/types/packages/objects/src/notebook/theme.d.ts +76 -0
  289. package/dist/types/packages/objects/src/palette.d.ts +577 -0
  290. package/dist/types/packages/objects/src/paper/host/body.d.ts +30 -0
  291. package/dist/types/packages/objects/src/paper/kind.d.ts +81 -0
  292. package/dist/types/packages/objects/src/paper/layout.d.ts +73 -0
  293. package/dist/types/packages/objects/src/paper/object.d.ts +31 -0
  294. package/dist/types/packages/objects/src/paper/pages.d.ts +43 -0
  295. package/dist/types/packages/objects/src/paper/paper-pass.d.ts +86 -0
  296. package/dist/types/packages/objects/src/paper/paper.d.ts +117 -0
  297. package/dist/types/packages/objects/src/paper/shaders.d.ts +18 -0
  298. package/dist/types/packages/objects/src/paper/theme.d.ts +58 -0
  299. package/dist/types/packages/objects/src/paper/typing.d.ts +51 -0
  300. package/dist/types/packages/objects/src/paper/writing.d.ts +161 -0
  301. package/dist/types/packages/objects/src/photo/carry.d.ts +33 -0
  302. package/dist/types/packages/objects/src/photo/kind.d.ts +136 -0
  303. package/dist/types/packages/objects/src/photo/layout.d.ts +39 -0
  304. package/dist/types/packages/objects/src/photo/object.d.ts +5 -0
  305. package/dist/types/packages/objects/src/photo/photo-pass.d.ts +104 -0
  306. package/dist/types/packages/objects/src/photo/photo.d.ts +262 -0
  307. package/dist/types/packages/objects/src/photo/pictures.d.ts +152 -0
  308. package/dist/types/packages/objects/src/photo/sample.d.ts +9 -0
  309. package/dist/types/packages/objects/src/photo/shaders.d.ts +18 -0
  310. package/dist/types/packages/objects/src/preset.d.ts +44 -0
  311. package/dist/types/packages/objects/src/shaders.d.ts +3 -0
  312. package/dist/types/packages/objects/src/shaders.gen.d.ts +21 -0
  313. package/dist/types/packages/react/src/canvas-hooks.d.ts +12 -0
  314. package/dist/types/packages/react/src/desk.d.ts +56 -0
  315. package/dist/types/packages/react/src/engine-context.d.ts +2 -2
  316. package/dist/types/packages/react/src/frame-preview-boundary.d.ts +19 -0
  317. package/dist/types/packages/react/src/hooks.d.ts +9 -14
  318. package/dist/types/packages/react/src/index.d.ts +16 -9
  319. package/dist/types/packages/react/src/keymap.d.ts +21 -2
  320. package/dist/types/packages/react/src/selection-menu.d.ts +171 -0
  321. package/dist/types/packages/react/src/tray-bar.d.ts +124 -0
  322. package/package.json +64 -31
  323. package/dist/chunk-5FQS7V2C.js.map +0 -1
  324. package/dist/chunk-JWRHAM7L.js +0 -1163
  325. package/dist/chunk-JWRHAM7L.js.map +0 -1
  326. package/dist/chunk-MFTMPJUF.js +0 -681
  327. package/dist/chunk-MFTMPJUF.js.map +0 -1
  328. package/dist/chunk-OR5FNVUE.js.map +0 -1
  329. package/dist/ground.js +0 -1213
  330. package/dist/ground.js.map +0 -1
  331. package/dist/r3f.js +0 -1644
  332. package/dist/r3f.js.map +0 -1
  333. package/dist/types/packages/core/src/input/measure-queue.d.ts +0 -30
  334. package/dist/types/packages/core/src/settings/ground-config.d.ts +0 -103
  335. package/dist/types/packages/core/src/systems/measure-ingest.d.ts +0 -26
  336. package/dist/types/packages/devtools/src/gl-panel.d.ts +0 -69
  337. package/dist/types/packages/dom/src/measure-adapter.d.ts +0 -31
  338. package/dist/types/packages/dom/src/measure-wiring.d.ts +0 -49
  339. package/dist/types/packages/dom/src/planes.d.ts +0 -33
  340. package/dist/types/packages/dom/src/reflectors/chrome.d.ts +0 -33
  341. package/dist/types/packages/dom/src/reflectors/dom-widgets.d.ts +0 -59
  342. package/dist/types/packages/dom/src/reflectors/graybox.d.ts +0 -31
  343. package/dist/types/packages/dom/src/reflectors/plane-transform.d.ts +0 -38
  344. package/dist/types/packages/ground/src/index.d.ts +0 -69
  345. package/dist/types/packages/ground/src/layer.d.ts +0 -40
  346. package/dist/types/packages/ground/src/pass.d.ts +0 -41
  347. package/dist/types/packages/ground/src/passes/grid-classic.d.ts +0 -30
  348. package/dist/types/packages/ground/src/passes/grid-magnet.d.ts +0 -31
  349. package/dist/types/packages/ground/src/passes/grid.d.ts +0 -28
  350. package/dist/types/packages/ground/src/passes/guides-collect.d.ts +0 -14
  351. package/dist/types/packages/ground/src/passes/guides.d.ts +0 -3
  352. package/dist/types/packages/ground/src/passes/magnet-collect.d.ts +0 -63
  353. package/dist/types/packages/ground/src/passes/soup-collect.d.ts +0 -35
  354. package/dist/types/packages/ground/src/passes/soup-mesh.d.ts +0 -8
  355. package/dist/types/packages/ground/src/passes/wires-collect.d.ts +0 -35
  356. package/dist/types/packages/ground/src/passes/wires.d.ts +0 -10
  357. package/dist/types/packages/ground/src/poles.d.ts +0 -47
  358. package/dist/types/packages/ground/src/renderer.d.ts +0 -15
  359. package/dist/types/packages/ice/src/ground.d.ts +0 -1
  360. package/dist/types/packages/ice/src/r3f.d.ts +0 -1
  361. package/dist/types/packages/kernel/src/eviction.d.ts +0 -23
  362. package/dist/types/packages/kernel/src/zoom-bands.d.ts +0 -19
  363. package/dist/types/packages/r3f/src/bridge.d.ts +0 -129
  364. package/dist/types/packages/r3f/src/composite-material.d.ts +0 -26
  365. package/dist/types/packages/r3f/src/compositor-pass.d.ts +0 -105
  366. package/dist/types/packages/r3f/src/dev-write-trap.d.ts +0 -30
  367. package/dist/types/packages/r3f/src/gl-root.d.ts +0 -96
  368. package/dist/types/packages/r3f/src/gl-router.d.ts +0 -70
  369. package/dist/types/packages/r3f/src/index.d.ts +0 -17
  370. package/dist/types/packages/r3f/src/island-state.d.ts +0 -112
  371. package/dist/types/packages/r3f/src/island.d.ts +0 -13
  372. package/dist/types/packages/r3f/src/pool.d.ts +0 -56
  373. package/dist/types/packages/r3f/src/preview-capture.d.ts +0 -19
  374. package/dist/types/packages/r3f/src/resource-registry.d.ts +0 -30
  375. package/dist/types/packages/r3f/src/self-sustain.d.ts +0 -39
  376. package/dist/types/packages/r3f/src/use-island-frame.d.ts +0 -39
  377. package/dist/types/packages/react/src/infinite-canvas.d.ts +0 -140
  378. package/dist/types/packages/react/src/preview-snapshots.d.ts +0 -17
  379. package/dist/types/packages/react/src/widget-preview.d.ts +0 -14
  380. package/dist/types/packages/react/src/widget-root.d.ts +0 -33
package/dist/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
1
+ {"version":3,"sources":["../../react/src/hooks.ts","../../react/src/engine-context.tsx","../../react/src/use-commit.ts","../../react/src/use-tool.ts","../../react/src/canvas-hooks.ts","../../react/src/frame-preview-boundary.tsx","../../react/src/use-presence.ts","../../react/src/keymap.ts","../../react/src/selection-menu.tsx","../../react/src/tray-bar.tsx","../../react/src/desk.tsx","../../react/src/index.ts"],"sourcesContent":["/**\n * React hooks over the engine's Tier-3 reactivity (design-005 §2 hooks).\n *\n * Implemented directly on `world.reactive.observeValue` + `useSyncExternalStore`\n * rather than strata's own react module: core is react-free by law, so\n * strata/react cannot be re-exported through it — and the adapter is ~20\n * lines. Value semantics are strata Tier-3: equality-suppressed, fired at\n * notify(), never during the tick.\n *\n * These are the hooks of SCREEN-SPACE chrome (design-015 §2 law 2): a panel\n * that shows the selected object's props, a bar that reads its behaviour\n * state. Until design-015 D5b they also served the React faces of DOM widgets\n * and carried the frozen-hidden rule (a culled-but-kept-mounted portal must\n * not re-render) through `WidgetHiddenContext` and the mount store's freeze;\n * both left with the portals. `ChromeOwnerContext` left with the profiles.\n */\nimport {\n Selected,\n WidgetBreakpoint,\n defineQuery,\n widgets,\n type AnyBehaviorDef,\n type Component,\n type Entity,\n type World,\n} from \"@ice/core\";\nimport { useCallback, useMemo, useRef, useSyncExternalStore } from \"react\";\n\nconst selectedQ = defineQuery([Selected]);\n\n/** Shallow field equality — strata cells are flat field records. */\nfunction shallowEq(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true;\n if (typeof a !== \"object\" || typeof b !== \"object\" || a === null || b === null) return false;\n const ka = Object.keys(a);\n const kb = Object.keys(b);\n if (ka.length !== kb.length) return false;\n for (const k of ka) {\n if (!Object.is((a as Record<string, unknown>)[k], (b as Record<string, unknown>)[k])) return false;\n }\n return true;\n}\n\n/**\n * Tier-3 component value subscription (equality-suppressed). Snapshot\n * STABILITY is load-bearing: strata's `get()` materializes a fresh object per\n * read (SoA columns), and `useSyncExternalStore` treats a new reference as a\n * new snapshot — so reads go through a shallow-equality cache and only a real\n * field change yields a new reference.\n */\nexport function useWorldComponent<S>(world: World, entity: Entity, component: Component<S>): S | undefined {\n const last = useRef<S | undefined>(undefined);\n const subscribe = useCallback(\n (onChange: () => void) => world.reactive.observeValue(entity, component, onChange),\n [world, entity, component],\n );\n const getSnapshot = useCallback(() => {\n const v = world.isAlive(entity) ? world.get(entity, component) : undefined;\n if (!shallowEq(v, last.current)) last.current = v;\n return last.current;\n }, [world, entity, component]);\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\n/**\n * Typed props for one conflict group of a widget (design-005 §2). Group\n * component values come back whole; `p.json` fields are parsed. Identity is\n * stable per underlying group value (memo on the raw reference).\n */\nexport function useWidgetProps<T extends Record<string, unknown>>(\n world: World,\n entity: Entity,\n type: string,\n group = \"props\",\n): T | undefined {\n const widget = widgets.get(type);\n const g = widget?.groups.find((x) => x.name === group);\n if (widget === undefined || g === undefined) {\n throw new Error(`ice: useWidgetProps — unknown widget type/group \"${type}\"/\"${group}\".`);\n }\n const raw = useWorldComponent(world, entity, g.component) as Record<string, unknown> | undefined;\n return useMemo(() => {\n if (raw === undefined) return undefined;\n const out: Record<string, unknown> = {};\n for (const [name, spec] of Object.entries(g.fields)) {\n const v = raw[name];\n out[name] = spec.kind === \"json\" && typeof v === \"string\" ? parseJsonCell(v, spec.default) : v;\n }\n return out as T;\n }, [raw, g]);\n}\n\n/**\n * Live behavior data for one entity (design-009 §6, Tier-3 — the\n * `useWidgetProps` pattern). `p.json` fields come back parsed; the value is\n * `undefined` when the behavior is not attached, which is a legitimate render\n * state and not an error.\n *\n * READ-ONLY by construction. Chrome renders behavior state; it never writes it\n * (Law 10) — writes go through `ctx` inside the behavior's own hooks, or\n * through `engine.behaviors.attach` / a transaction from an app handler.\n */\nexport function useBehavior<T extends Record<string, unknown>>(\n world: World,\n entity: Entity,\n behavior: AnyBehaviorDef,\n): T | undefined {\n const raw = useWorldComponent(world, entity, behavior.component as Component) as\n | Record<string, unknown>\n | undefined;\n return useMemo(() => {\n if (raw === undefined) return undefined;\n const out: Record<string, unknown> = {};\n for (const [name, spec] of Object.entries(behavior.schema)) {\n const v = raw[name];\n out[name] = spec.kind === \"json\" && typeof v === \"string\" ? parseJsonCell(v, spec.default) : v;\n }\n return out as T;\n }, [raw, behavior]);\n}\n\n/**\n * A json cell is one CRDT string a remote peer may have written malformed —\n * decoding must never throw mid-render (2026-07-13 review). Fall back to the\n * spec's serialized default (engine-derived, always valid JSON), then null.\n */\nfunction parseJsonCell(cell: string, serializedDefault: string | undefined): unknown {\n try {\n return JSON.parse(cell);\n } catch {\n try {\n return JSON.parse(serializedDefault ?? \"null\");\n } catch {\n return null;\n }\n }\n}\n\n/** Selection membership (Tier-1 wake on Selected churn; O(1) snapshot). */\nexport function useSelected(world: World, entity: Entity): boolean {\n const last = useRef(false);\n const subscribe = useCallback(\n (onChange: () => void) => world.reactive.observeQuery(selectedQ, onChange),\n [world],\n );\n const getSnapshot = useCallback(() => {\n last.current = world.isAlive(entity) && world.hasTag(entity, Selected);\n return last.current;\n }, [world, entity]);\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\n/** LOD tier (design-004 §8); \"normal\" until the breakpoint system stamps one. */\nexport function useBreakpoint(world: World, entity: Entity): string {\n const bp = useWorldComponent(world, entity, WidgetBreakpoint);\n return (bp as { tier?: string } | undefined)?.tier ?? \"normal\";\n}\n","/**\n * `<EngineProvider>` + engine access hooks (design-005 §5; the M6 field\n * amendment 2026-07-10 gap — grep \"useCommit\" in design-005).\n *\n * The whole React surface reaches the running canvas through ONE context\n * carrying the {@link CanvasEngine} facade (world + engine + stack + runtime +\n * ops + docs). Widgets never hand-roll store plumbing again: {@link useOps}\n * gives the engine-owned write paths, {@link useCommit} (its own module) the\n * sanctioned durable commit seam, and {@link useWorld} the read/observe escape\n * hatch. `<Desk>` provides this automatically; apps that mount\n * WidgetRoot themselves wrap it in `<EngineProvider>`.\n */\nimport { devGuardsEnabled, type CanvasEngine, type CanvasOps, type World } from \"@ice/core\";\nimport { createContext, useContext, useEffect, type ReactElement, type ReactNode } from \"react\";\n\nconst EngineContext = createContext<CanvasEngine | null>(null);\n\nexport interface EngineProviderProps {\n readonly engine: CanvasEngine;\n readonly children?: ReactNode;\n}\n\n/** Publish the canvas engine to the React subtree (WidgetRoot + userland hooks). */\nexport function EngineProvider({ engine, children }: EngineProviderProps): ReactElement {\n return <EngineContext.Provider value={engine}>{children}</EngineContext.Provider>;\n}\n\n/** The canvas engine for this subtree; throws with guidance outside a provider. */\nexport function useCanvasEngine(): CanvasEngine {\n const engine = useContext(EngineContext);\n if (engine === null) {\n throw new Error(\n \"ice: useCanvasEngine — no <EngineProvider>. Render inside <Desk> (which provides it) or wrap your tree in <EngineProvider engine={...}>.\",\n );\n }\n return engine;\n}\n\n/** The engine-owned write paths (design-005 §4): setTool, deleteSelection, etc. */\nexport function useOps(): CanvasOps {\n return useCanvasEngine().ops;\n}\n\n/**\n * Take a stage background hold while `active` (ce.stage, 2026-07-19): the\n * overlay-lifecycle sugar — the disposer releases on deactivate AND unmount,\n * so a crashed/unmounted overlay can never wedge the canvas backgrounded.\n * `engine` is an explicit param (not context): overlays typically render as\n * SIBLINGS of <Desk>, outside the provider.\n */\nexport function useStageHold(engine: CanvasEngine, active: boolean, name: string): void {\n useEffect(() => {\n if (!active) return undefined;\n return engine.stage.background(name);\n }, [engine, active, name]);\n}\n\n/**\n * Freeze the engine while `active` (ce.frame, 2026-08-04) — {@link useStageHold}'s\n * stricter sibling, same lifecycle sugar: the effect cleanup IS the thaw, so an\n * overlay that unmounts (or crashes) can never wedge the engine parked.\n *\n * WHICH ONE. A stage hold quiets discretionary rendering over a world that\n * keeps stepping — right for chrome that RECEDES the canvas, where undo,\n * collab and tweens must still land visibly behind a partial overlay. A freeze\n * stops the loop outright — right for chrome that COVERS the canvas, where\n * every frame behind it is work nobody can see. Reaching for a freeze under a\n * partial overlay will look broken: the canvas is a photograph until thaw.\n */\nexport function useFrameFreeze(engine: CanvasEngine, active: boolean, name: string): void {\n useEffect(() => {\n if (!active) return undefined;\n return engine.frame.freeze(name);\n }, [engine, active, name]);\n}\n\nlet warnedUseWorld = false;\n\n/**\n * Escape hatch — the raw {@link World} for READS and Tier-3 OBSERVATION only.\n * Mutation goes through {@link useOps}/{@link useCommit} (a gesture-claimed,\n * one-tx-per-gesture durable write; direct world writes bypass sovereignty and\n * the guards). DEV-warns once on first use.\n */\nexport function useWorld(): World {\n const engine = useCanvasEngine();\n if (devGuardsEnabled() && !warnedUseWorld) {\n warnedUseWorld = true;\n console.warn(\n \"ice: useWorld() is a READ/OBSERVE escape hatch — never write to the world directly. Use useOps()/useCommit() for mutation (design-005 §5).\",\n );\n }\n return engine.world;\n}\n","/**\n * `useCommit` + `useUndoStatus` — the sanctioned widget durable-write path and\n * the undo/redo status subscription (design-005 §2 M6 field amendment,\n * 2026-07-10: \"widgets also need a SANCTIONED commit path\").\n *\n * A widget commits a prop edit through {@link useCommit}: it resolves the\n * CURRENT doc session (`engine.docs.current()`) and runs a\n * {@link guardedTransaction} against that session's store — one transaction per\n * call, eligibility-guarded, absolute writes only. The session is resolved at\n * CALL time (not hook time) so a widget rendered doc-less that gains a doc later\n * commits correctly without re-mounting.\n */\nimport { DurableUndoStatus, guardedTransaction, type GuardedTx, type GuardedTxOpts } from \"@ice/core\";\nimport { useCallback, useRef, useSyncExternalStore } from \"react\";\nimport { useCanvasEngine } from \"./engine-context\";\n\n/** A durable commit: run `fn` against the current doc session's store, one tx. */\nexport type Commit = (fn: (tx: GuardedTx) => void, opts?: GuardedTxOpts) => void;\n\n/**\n * The widget commit seam. The returned function throws with guidance when no\n * document is attached (commits need a durable store — call\n * `engine.docs.create()/open()/join()` first).\n */\nexport function useCommit(): Commit {\n const engine = useCanvasEngine();\n return useCallback(\n (fn, opts) => {\n const session = engine.docs.current();\n if (session === undefined) {\n throw new Error(\n \"ice: useCommit — no active document. Attach one with engine.docs.create()/open()/join() before committing widget edits.\",\n );\n }\n if (session.readOnly) {\n // The version gate said read-only: a raw store write here would edit —\n // and broadcast — a document the gate refused (2026-07-13 review).\n throw new Error(\"ice: useCommit — the document is read-only (version gate); widget edits are disabled.\");\n }\n guardedTransaction(session.store, engine.world, fn, opts);\n },\n [engine],\n );\n}\n\nexport interface UndoStatus {\n readonly canUndo: boolean;\n readonly canRedo: boolean;\n}\n\nconst NO_UNDO: UndoStatus = { canUndo: false, canRedo: false };\n\n/**\n * Undo/redo availability for the current document (drives toolbar\n * disablement) — the design-005 §5 path: the `DurableUndoStatus` RESOURCE\n * (strata plan-undo U2, re-exported through @ice/core) via\n * `observeResource`. A resource subscription is WORLD-level, so it survives\n * document swaps — no remount needed, the earlier onHistoryChange-per-store\n * caveat is gone. Fires at notify(), equality-suppressed; snapshot identity\n * is stable while the flags are unchanged.\n */\nexport function useUndoStatus(): UndoStatus {\n const engine = useCanvasEngine();\n const last = useRef<UndoStatus>(NO_UNDO);\n const subscribe = useCallback(\n (onChange: () => void) => engine.world.reactive.observeResource(DurableUndoStatus, onChange),\n [engine],\n );\n const getSnapshot = useCallback(() => {\n const status = engine.world.getResource(DurableUndoStatus);\n const canUndo = status?.canUndo ?? false;\n const canRedo = status?.canRedo ?? false;\n if (last.current.canUndo !== canUndo || last.current.canRedo !== canRedo) {\n last.current = { canUndo, canRedo };\n }\n return last.current;\n }, [engine]);\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n","/**\n * `useTool` + `useToolState` — the active-tool subscription (design-005 §5).\n *\n * The active tool is the `ActiveTool` runtime resource (design-005 §4). Reads go\n * through strata's Tier-3 `observeResource` (fires only when the id actually\n * changes, at notify()); the setter is `ops.setTool`, which cancels active\n * gestures before the switch (the strata-example lesson, design-003 §8) — never\n * a raw resource write. The snapshot is a primitive string, so identity is\n * inherently stable.\n */\nimport { ActiveTool } from \"@ice/core\";\nimport { useCallback, useSyncExternalStore } from \"react\";\nimport { useCanvasEngine } from \"./engine-context\";\n\n/** `[activeToolId, setTool]`. `setTool` routes through `ops.setTool`. */\nexport function useTool(): [string, (id: string) => void] {\n const engine = useCanvasEngine();\n const subscribe = useCallback(\n (onChange: () => void) => engine.world.reactive.observeResource(ActiveTool, onChange),\n [engine],\n );\n const getSnapshot = useCallback(() => engine.world.getResource(ActiveTool)?.id ?? \"select\", [engine]);\n const active = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n const setTool = useCallback((id: string) => engine.ops.setTool(id), [engine]);\n return [active, setTool];\n}\n\n/** Sugar: is tool `id` the active one? (toolbar button pressed-state). */\nexport function useToolState(id: string): boolean {\n const [active] = useTool();\n return active === id;\n}\n","/** Stable React projections over the headless Canvas SDK facade. */\nimport type {\n CanvasCatalogSection,\n CanvasDiagnostic,\n CanvasSessionValue,\n Entity,\n FramePreviewSnapshot,\n Tool,\n} from \"@ice/core\";\nimport { useCallback, useSyncExternalStore } from \"react\";\nimport { useCanvasEngine } from \"./engine-context\";\n\nexport function useCurrentCanvas(): CanvasSessionValue {\n const engine = useCanvasEngine();\n const subscribe = useCallback(\n (onChange: () => void) => engine.canvas.subscribe(onChange),\n [engine],\n );\n return useSyncExternalStore(subscribe, engine.canvas.current, engine.canvas.current);\n}\n\nexport function useCanvasCatalog(): readonly CanvasCatalogSection[] {\n const engine = useCanvasEngine();\n const subscribe = useCallback(\n (onChange: () => void) => engine.canvas.subscribe(onChange),\n [engine],\n );\n return useSyncExternalStore(subscribe, engine.canvas.catalog, engine.canvas.catalog);\n}\n\nexport function useCanvasTools(): readonly Tool[] {\n const engine = useCanvasEngine();\n const subscribe = useCallback(\n (onChange: () => void) => engine.canvas.subscribe(onChange),\n [engine],\n );\n return useSyncExternalStore(subscribe, engine.canvas.tools, engine.canvas.tools);\n}\n\nexport function useCanvasDiagnostics(): readonly CanvasDiagnostic[] {\n const engine = useCanvasEngine();\n const subscribe = useCallback(\n (onChange: () => void) => engine.canvas.subscribe(onChange),\n [engine],\n );\n return useSyncExternalStore(\n subscribe,\n engine.canvas.diagnostics,\n engine.canvas.diagnostics,\n );\n}\n\n/**\n * Demand-driven semantic frame preview. Merely reading the hook does not scan\n * the frame: useSyncExternalStore activates the core projection on subscribe\n * and removes every observer on unmount.\n */\nexport function useFramePreview(frame: Entity): FramePreviewSnapshot {\n const engine = useCanvasEngine();\n const subscribe = useCallback(\n (onChange: () => void) => engine.previews.subscribe(frame, onChange),\n [engine, frame],\n );\n const getSnapshot = useCallback(() => engine.previews.snapshot(frame), [engine, frame]);\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n","import {\n Component,\n type ErrorInfo,\n type ReactElement,\n type ReactNode,\n} from \"react\";\n\nexport interface FramePreviewBoundaryProps {\n readonly children: ReactNode;\n readonly fallback?: ReactNode;\n readonly onError?: (error: unknown, info: ErrorInfo) => void;\n}\n\n/** Isolates one author-owned instance preview from the rest of the canvas. */\nexport class FramePreviewBoundary extends Component<\n FramePreviewBoundaryProps,\n { readonly failed: boolean }\n> {\n override state = { failed: false };\n\n static getDerivedStateFromError(): { failed: boolean } {\n return { failed: true };\n }\n\n override componentDidCatch(error: unknown, info: ErrorInfo): void {\n this.props.onError?.(error, info);\n }\n\n override render(): ReactElement | ReactNode {\n return this.state.failed ? (this.props.fallback ?? null) : this.props.children;\n }\n}\n","/**\n * `usePresencePeers` — the remote-collaborator roster (design-005 §5:\n * \"Not(Local) presence query\").\n *\n * Queries `PresencePeer` entities that are NOT `Local` (the local peer carries\n * `Local`, auto-applied by the ephemeral store and never transmitted) and pairs\n * each with its `PresenceInfo` (name/color). Wakes on Tier-1 query membership\n * churn (`observeQuery`) — peers joining/leaving. The snapshot is\n * MEMBERSHIP-KEYED: identity stays stable across unrelated re-renders, and info\n * is sampled when membership changes (steady-state presence info is set once at\n * join; a mid-session rename reflects on the next membership change).\n */\nimport { Local, Not, PresenceInfo, PresencePeer, defineQuery, type Entity } from \"@ice/core\";\nimport { useCallback, useRef, useSyncExternalStore } from \"react\";\nimport { useCanvasEngine } from \"./engine-context\";\n\nconst remotePeersQ = defineQuery([PresencePeer, Not(Local)]);\n\nexport interface PresencePeerView {\n readonly entity: Entity;\n /** The peer's `PresenceInfo` (strata \"string\" fields are nullable until set). */\n readonly info: { readonly name: string | null; readonly color: string | null } | undefined;\n}\n\n/** Remote presence peers (excludes the local peer); stable identity by membership. */\nexport function usePresencePeers(): readonly PresencePeerView[] {\n const engine = useCanvasEngine();\n const cache = useRef<{ key: string; value: readonly PresencePeerView[] }>({ key: \"\u0000\", value: [] });\n const subscribe = useCallback(\n (onChange: () => void) => engine.world.reactive.observeQuery(remotePeersQ, onChange),\n [engine],\n );\n const getSnapshot = useCallback(() => {\n const world = engine.world;\n const ids: Entity[] = [];\n world.query(remotePeersQ).each((b) => {\n for (const r of b) ids.push(b.entity(r));\n });\n const key = ids.join(\",\");\n if (key !== cache.current.key) {\n cache.current = {\n key,\n value: ids.map((entity) => ({ entity, info: world.get(entity, PresenceInfo) })),\n };\n }\n return cache.current.value;\n }, [engine]);\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n","/**\n * The default keymap (design-005 §4 \"Keymap\"; design-003 §2 — NO system-side\n * keyboard logic, every entry resolves to an `ops.*`/`docs.*` call).\n *\n * Locked defaults:\n * ⌫/Delete → ops.deleteSelection\n * ⌘Z / Ctrl-Z → docs.undo\n * ⇧⌘Z / ⇧Ctrl-Z → docs.redo\n * ⌘D → ops.duplicateSelection\n * ⌘A → ops.selectAll\n * Esc → closes the pegboard tray first (design-017 §4), else ops.cancelActiveGestures\n * Arrows → nudge the selection ±1px (⇧ = ±10px) — ONE tx per press; a TAPED widget\n * never moves (design-015 §5.1 — `Locked`, D4a), its untaped companions do\n * ⇧⌘L / ⇧Ctrl-L → tape the selection down, or lift the tape when all of it is taped\n * (*Marks on the Mat*'s keys, D4a) — `ops.setLocked`, one transaction\n * tool shortcuts → ops.setTool (v/h/c + any registered tool's shortcut)\n * in hand → the held object's own tools first (design-015 §8, D3t-a): its type's\n * `heldTools` keys → ops.useHeldTool — and only while it is held\n *\n * Space-hold pan is ALREADY owned by the pointer adapter (design-003 §2) — it is\n * NOT rebound here. `mod` = ⌘ on macOS, Ctrl elsewhere (metaKey || ctrlKey).\n *\n * The widget input contract (design-007, petition I1) — three gates, in order:\n * 1. `event.defaultPrevented` → the widget's own handler consumed the key\n * (\"preventDefault = handled by content\"); the engine never competes.\n * 2. The `data-canvas-keyboard` claim marker on the event-target chain (the\n * keydown target IS `document.activeElement` — browser focus is the one\n * page-global truth, so two engines on one page stand down together) →\n * EVERY entry cedes except Escape, the engine-reserved release gesture:\n * Escape blurs the claim (the NEXT press, with focus gone, falls through\n * to cancelActiveGestures). A widget that declared `keyboardEscape:\n * \"widget\"` receives even Escape — release is click-away or blurFocus().\n * This gate runs BEFORE the editable gate on purpose (2026-08-09 review):\n * a claim whose focus node is an editable proxy (the Ghosttea-style\n * hidden textarea, design-007 §6) must still get the Escape release —\n * editable-first would shadow it and silently turn every such widget\n * into `keyboardEscape: \"widget\"`.\n * 3. Editable target (input/textarea/select/contentEditable — the shared\n * 4-class predicate from @ice/dom) → ignored, so typing never triggers a\n * shortcut. Kept narrow so UNDECLARED widgets behave exactly as before.\n *\n * Overrides replace a default by its key-signature `key|mod|shift`; a signature\n * with no default is added. A matched entry `preventDefault()`s (the target was\n * already filtered to non-editable, so no typing is swallowed). An override on\n * Space warns at attach: the pointer adapter owns Space (the pan modifier,\n * design-003 §4.4) and preventDefaults it before gate 1 can let it through.\n */\nimport { Container, GestureActive, Locked, Position, PrefabId, closeTray, currentNavEntry, defineQuery, guardedTransaction, heldEntity, matchHeldTool, selectedEntities, tools, trayOpen, type CanvasEngine } from \"@ice/core\";\nimport { isEditableTarget, keyboardClaimOf } from \"@ice/dom\";\n\nconst gestureActiveQ = defineQuery([GestureActive]);\n\n/**\n * ⏎ (design-015 §8 · §9): exactly one selected widget — an object whose kind OPENS is picked up into the hand (D4b); a\n * container the catalog can enter is flown into. Nothing while something is already held.\n */\nfunction openOrEnterSelected(engine: CanvasEngine): void {\n const { world } = engine;\n if (heldEntity(world) !== undefined || trayOpen(world)) return;\n const selected = selectedEntities(world);\n if (selected.length !== 1) return;\n const target = selected[0];\n if (target === undefined || !world.isAlive(target)) return;\n const typeId = world.get(target, PrefabId)?.id;\n if (typeof typeId === \"string\" && engine.catalog.widget(typeId)?.openable === true) { engine.ops.open(target); return; }\n if (!world.hasTag(target, Container)) return;\n engine.ops.enterContainer(target);\n}\n\n/**\n * Esc (design-007 §3.3, design-015 §8 · §9, design-017 §4): the pegboard tray is closed first (K3 — the drawer is the nearest\n * thing to let go of); an object in hand is put down next (D4b — the object lands, still selected, so ⏎ opens it again); else a\n * live gesture is cancelled, as ever; with none to cancel, the current frame is left.\n */\nfunction escapeOrExit(engine: CanvasEngine): void {\n const { world } = engine;\n if (trayOpen(world)) { closeTray(world); return; }\n if (heldEntity(world) !== undefined) { engine.ops.putDown(); return; }\n const gestureLive = world.firstOf(gestureActiveQ) !== undefined;\n if (!gestureLive && currentNavEntry(world) !== undefined) {\n engine.ops.exitContainer();\n return;\n }\n engine.ops.cancelActiveGestures();\n}\n\n/**\n * The desk's keys go quiet while it is inert — an object in hand (D4b) or the pegboard tray open (design-017 §4): what would delete,\n * copy, nudge or gather on the inert desk does nothing. Exported for an app's OWN keys (K9 S3: the desk app's `w`, `m`, Tab and its\n * ⇧ arrows — which replace the entries here — made, walked and nudged objects under the open drawer and moved a notebook in hand).\n */\nexport const unlessInert = (run: (engine: CanvasEngine) => void) => (engine: CanvasEngine): void => { if (heldEntity(engine.world) === undefined && !trayOpen(engine.world)) run(engine); };\n\n/**\n * The held bar's keys (design-015 §8; D3t-a): with an object in hand, its type's tools (`heldTools` — the kind's `open.tools`)\n * take their keys before any entry here, and only then — `1`–`4` are the board's markers in hand and nothing on the desk. The\n * tool is used through `ops.useHeldTool` (a mode becomes the tool in hand, an action runs its op). True when a tool took it.\n */\nfunction heldToolKey(engine: CanvasEngine, event: KeyboardEvent): boolean {\n const held = heldEntity(engine.world);\n if (held === undefined) return false;\n const typeId = engine.world.get(held, PrefabId)?.id;\n const tools = typeof typeId === \"string\" ? (engine.catalog.widget(typeId)?.heldTools ?? []) : [];\n const tool = matchHeldTool(tools, { key: event.key, mod: event.metaKey || event.ctrlKey, shift: event.shiftKey, alt: event.altKey });\n if (tool === undefined) return false;\n engine.ops.useHeldTool(tool.id);\n return true;\n}\n\nexport interface KeymapEntry {\n /** `event.key` to match (case-insensitive; e.g. \"z\", \"Backspace\", \"ArrowUp\"). */\n readonly key: string;\n /** Require ⌘/Ctrl (default false → must NOT be held). */\n readonly mod?: boolean;\n /** Require ⇧ (default false → must NOT be held). */\n readonly shift?: boolean;\n /** Resolve to an engine write path — no keyboard logic beyond dispatch. */\n run(engine: CanvasEngine): void;\n}\n\ntype KeyTarget = Pick<Window, \"addEventListener\" | \"removeEventListener\">;\n\nconst signature = (key: string, mod?: boolean, shift?: boolean): string =>\n `${key.toLowerCase()}|${mod ? 1 : 0}|${shift ? 1 : 0}`;\n\n/**\n * One nudge = one gesture-equivalent transaction (absolute Position writes). A taped widget (`Locked`) is passed\n * over — the tape holds it as it holds against a drag (design-015 §5.1, D4a). Exported so an app can bind its own\n * step (the desk's ⇧ nudge is one lattice cell, 20).\n */\nexport function nudgeSelection(engine: CanvasEngine, dx: number, dy: number): void {\n const session = engine.docs.current();\n if (session === undefined) return;\n const selection = selectedEntities(engine.world).filter((e) => session.store.keyOf(e) !== undefined && !engine.world.hasTag(e, Locked));\n if (selection.length === 0) return;\n guardedTransaction(session.store, engine.world, (tx) => {\n for (const e of selection) {\n const p = engine.world.get(e, Position);\n if (p === undefined) continue;\n tx.edit(e).set(Position, { x: p.x + dx, y: p.y + dy });\n }\n });\n}\n\nconst ARROWS: readonly [key: string, dx: number, dy: number][] = [\n [\"ArrowLeft\", -1, 0],\n [\"ArrowRight\", 1, 0],\n [\"ArrowUp\", 0, -1],\n [\"ArrowDown\", 0, 1],\n];\n\n/** ⇧⌘L: tape the selection down — or, when every selected widget is taped, lift the tape (one transaction). */\nexport function toggleTape(engine: CanvasEngine): void {\n const selection = selectedEntities(engine.world);\n if (selection.length === 0) return;\n engine.ops.setLocked(selection, !selection.every((e) => engine.world.hasTag(e, Locked)));\n}\n\n/** The locked defaults + tool shortcuts (read from the registry at attach time). */\nfunction defaultEntries(): KeymapEntry[] {\n const entries: KeymapEntry[] = [\n { key: \"Backspace\", run: unlessInert((e) => e.ops.deleteSelection()) },\n { key: \"Delete\", run: unlessInert((e) => e.ops.deleteSelection()) },\n { key: \"z\", mod: true, run: (e) => e.docs.undo() },\n { key: \"z\", mod: true, shift: true, run: (e) => e.docs.redo() },\n { key: \"d\", mod: true, run: unlessInert((e) => e.ops.duplicateSelection()) },\n { key: \"a\", mod: true, run: unlessInert((e) => e.ops.selectAll()) },\n // design-015 §8 · §9 (D2b, D4b): ⏎ with ONE selected picks an openable object up, or flies into a container; Esc puts\n // the held object down, else cancels a live gesture as ever, and with none to cancel flies back out of the current frame.\n { key: \"Enter\", run: (e) => openOrEnterSelected(e) },\n { key: \"Escape\", run: (e) => escapeOrExit(e) },\n { key: \"l\", mod: true, shift: true, run: unlessInert(toggleTape) },\n ];\n for (const [key, dx, dy] of ARROWS) {\n entries.push({ key, run: unlessInert((e) => nudgeSelection(e, dx, dy)) });\n entries.push({ key, shift: true, run: unlessInert((e) => nudgeSelection(e, dx * 10, dy * 10)) });\n }\n // A tool's letter sets that tool only where it is LEGAL — the current canvas's `tools()` (K9 S8: on the desk, whose canvas allows\n // `desk.select` and pan alone, `v` and `c` threw \"not legal in the current CanvasType\" and `h` left it in pan for good). Tools may\n // share a letter (core's `select` and the desk's `desk.select` both answer `v`): the first registered that is legal here takes it;\n // none legal, the key does nothing (still matched — never the browser's).\n const byLetter = new Map<string, string[]>();\n for (const tool of tools.all()) {\n if (tool.shortcut === undefined) continue;\n byLetter.set(tool.shortcut, [...(byLetter.get(tool.shortcut) ?? []), tool.id]);\n }\n for (const [key, ids] of byLetter) {\n entries.push({\n key,\n run: (e) => {\n const legal = e.canvas.tools();\n const id = ids.find((t) => legal.some((tool) => tool.id === t));\n if (id !== undefined) e.ops.setTool(id);\n },\n });\n }\n return entries;\n}\n\nfunction resolveTarget(target?: KeyTarget): KeyTarget | undefined {\n if (target !== undefined) return target;\n return typeof window !== \"undefined\" ? window : undefined;\n}\n\n/**\n * Attach the default keymap (plus `overrides`) to `target` (default: `window`).\n * Returns a detach function. No-op (returns a no-op detach) when there is no\n * target — e.g. a headless environment with no `window`.\n */\nexport function attachKeymap(\n engine: CanvasEngine,\n target?: KeyTarget,\n overrides: readonly KeymapEntry[] = [],\n): () => void {\n const el = resolveTarget(target);\n if (el === undefined) return () => {};\n\n const map = new Map<string, KeymapEntry>();\n for (const entry of defaultEntries()) map.set(signature(entry.key, entry.mod, entry.shift), entry);\n for (const entry of overrides) {\n if (entry.key === \" \") {\n // Fail loud at attach, not silently at runtime: the adapter's window\n // listener registers first and preventDefaults Space (pan modifier),\n // so gate 1 makes this entry unreachable by construction.\n console.warn(\n \"ice: attachKeymap — an override on Space can never fire: the pointer adapter owns Space as the pan modifier (design-003 §4.4) and preventDefaults it before the keymap's handled-by-content gate.\",\n );\n }\n map.set(signature(entry.key, entry.mod, entry.shift), entry);\n }\n\n const onKeyDown = (event: KeyboardEvent): void => {\n if (event.defaultPrevented) return; // gate 1 — handled by content\n const claim = keyboardClaimOf(event.target);\n if (claim.claimed) {\n // Gate 2 — exclusive standdown (BEFORE the editable gate, so editable\n // focus proxies keep the release gesture — header note). Escape stays\n // engine-reserved (blur, no gesture-cancel THIS press) unless the\n // widget owns it. Everything else flows to the widget,\n // un-preventDefaulted.\n if (event.key === \"Escape\" && !claim.ownsEscape) {\n event.preventDefault();\n // SVG nodes are focusable too (tabindex) and are not HTMLElement —\n // the release must never eat Escape without actually blurring.\n const t = event.target;\n if (t instanceof HTMLElement || t instanceof SVGElement) t.blur();\n }\n return;\n }\n if (isEditableTarget(event.target)) return; // gate 3 — typing\n if (heldToolKey(engine, event)) { event.preventDefault(); return; } // the object in hand's tools first (D3t-a)\n const mod = event.metaKey || event.ctrlKey;\n const entry = map.get(signature(event.key, mod, event.shiftKey));\n if (entry === undefined) return;\n event.preventDefault();\n entry.run(engine);\n };\n\n el.addEventListener(\"keydown\", onKeyDown as EventListener);\n return () => el.removeEventListener(\"keydown\", onKeyDown as EventListener);\n}\n","/**\n * `<SelectionMenu>` — the desk's selection menu (design-015 §7, *Marks on the Mat*'s \"ink bar\"; D4a):\n * the ONE piece of DOM beside the focused editor that the desk keeps (design-015 §2's law), in SCREEN\n * space — one element tree, one plain transform, never a camera's. It is placed from the anchor the\n * desk publishes (`source`, structurally the desk handle's `selection`: the marks' box around the\n * selection as DRAWN — the brackets 6 px out, the union 10 px out), 10 px above it, centred; it flips\n * below when it would cross the top ruler's band (or the view's top) and keeps 16 px from the sides.\n * It steps aside for any gesture (a drag, a vellum, a pan, a pinch) — and while a note is being written\n * (the one focused editor has the keys) — in 90 ms, and comes back 200 ms after (180 ms in). Its acts are an app-extensible list: ICE ships Duplicate (gone\n * when the selection is all tape — \"a copy of a taped thing is not taped\"), Tape it down / Lift the tape,\n * More (every act with its key), and Delete alone past a rule, colourless until the pointer arms it red;\n * an app adds its own (VibeField: Send to agent, first). The glyphs are DESIGN.md §13's drawings and the\n * page's six, inline SVG, currentColor. The ink is the whiteboard tray's (94 % ink, cream glyphs, brass\n * hairlines, the lamp's shadow falling lower left) — CSS custom properties an app may re-point.\n *\n * `@ice/react` never imports the desk: the source is read structurally, as the ground layer is.\n */\nimport { Locked, selectedEntities, type CanvasEngine } from \"@ice/core\";\nimport { type ReactElement, type ReactNode, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { useCanvasEngine } from \"./engine-context\";\n\n/** A screen rect, CSS px. */\nexport interface SelectionMenuBox { readonly x0: number; readonly y0: number; readonly x1: number; readonly y1: number }\n\n/** What the menu is placed from — the desk handle's `selection.anchor()`, mirrored structurally. */\nexport interface SelectionMenuAnchor {\n /** The marks' box around the selection on screen (null: nothing selected, or none of it drawn). */\n readonly box: SelectionMenuBox | null;\n readonly count: number;\n /** Every selected object is taped. */\n readonly locked: boolean;\n /** A gesture is on: the menu steps aside. */\n readonly gesturing: boolean;\n /** A note is being written (the one focused editor): the menu steps aside as for a gesture. */\n readonly editing?: boolean;\n readonly view: { readonly width: number; readonly height: number };\n /** The rulers printed along the top and left (their margin and band, CSS px), or null. */\n readonly rulers: { readonly margin: number; readonly band: number } | null;\n /**\n * An object is IN HAND (design-015 §8, D4b): the menu travels to the foot of the view and changes role (M1) — one element,\n * not a second toolbar — Send stays first, the kind's tools take the middle, Done ends the bar. `landing`: the object is\n * flying home — the bar steps aside and comes back above the object 200 ms after it lands. `active` (D3t-a): the mode in\n * hand — core's `HeldTool` — the one slot marked.\n */\n readonly held?: { readonly tools: readonly SelectionMenuTool[]; readonly active?: string; readonly landing: boolean; readonly settled: boolean };\n /**\n * The selection's KIND ACTS (design-016 K8a — the desk's `MenuSlot`s, mirrored structurally): what every selected object's type\n * declares (`defineObject({ menu })`); the menu shows them first among its acts and runs one through `ops.runMenuAction`.\n */\n readonly menu?: readonly SelectionMenuAct[];\n}\n\n/** A kind's act as the desk publishes it (its `MenuSlot`, mirrored structurally — K8a): plain data; the op stays on the widget type. */\nexport interface SelectionMenuAct {\n readonly id: string;\n readonly label: string;\n readonly glyph?: SelectionGlyph;\n readonly keys?: string;\n}\n\n/**\n * A glyph the bar draws (K8a — core's `HeldGlyph`, mirrored structurally): a NAME of its set (`SELECTION_GLYPHS`), or a tool's OWN\n * drawing — SVG path data in the 24-unit box, stroked 2 units in the bar's ink (`currentColor`) as the set's are, or filled.\n */\nexport type SelectionGlyph = string | { readonly path: string; readonly fill?: boolean };\n\n/**\n * A slot of the held bar as the desk publishes it (its `HeldSlot`, mirrored structurally — D3t-a): a `mode` (pressed, it\n * becomes the tool in hand) or an `action` (pressed, it runs its op), both through `ops.useHeldTool`; no `kind` = declared\n * only, shown dim and inert. `swatch`: a colour shown instead of the glyph (a marker's ink). `glyph` (K8a): a name of the bar's\n * set or the tool's own drawing — a plugin kind's tool draws its own; a name the bar does not draw is MARKED missing (its label's\n * initial, `data-glyph-missing`, one console error), never drawn as another glyph.\n */\nexport interface SelectionMenuTool {\n readonly id: string;\n readonly label: string;\n readonly kind?: \"mode\" | \"action\";\n readonly hint?: string;\n readonly glyph?: SelectionGlyph;\n readonly swatch?: string;\n}\n\n/** The anchor's source — the desk handle's `selection` (anchor + a subscription that fires when it moves). */\nexport interface SelectionMenuSource {\n anchor(): SelectionMenuAnchor;\n subscribe(listener: () => void): () => void;\n}\n\n/** What an act is told about the selection. */\nexport interface SelectionState {\n readonly count: number;\n readonly locked: boolean;\n}\n\nexport interface SelectionAction {\n readonly id: string;\n /** Its name — the button's accessible label and its tip; may read the selection (\"Lift the tape\"). */\n readonly label: string | ((s: SelectionState) => string);\n /** A glyph from `SELECTION_GLYPHS` by name, or any node — or one read off the selection (the lock opens when it is taped). */\n readonly glyph: string | ReactNode | ((s: SelectionState) => string | ReactNode);\n /** The key that does the same, shown in the tip and in More (e.g. \"⌘D\"). */\n readonly keys?: string;\n /** `lead` sits first (the app's own act — Send), `main` in the middle, `end` alone past a rule (Delete). */\n readonly place?: \"lead\" | \"main\" | \"end\";\n /** `danger`: colourless until the pointer arms it red. */\n readonly tone?: \"danger\";\n /** A text button (the lead act's label beside its glyph). */\n readonly text?: boolean;\n /** Shown for this selection (default: always). */\n readonly when?: (s: SelectionState) => boolean;\n /** Pressed-looking (the lock turns solid cream while the selection is taped). */\n readonly on?: (s: SelectionState) => boolean;\n run(engine: CanvasEngine, s: SelectionState): void;\n}\n\n/**\n * The menu's numbers (*Marks on the Mat* §14): 40 tall, 10 above the marks, 16 from the sides, 8 from the view's top and foot;\n * away 90 ms, back 200 ms after, in 180 ms. The held bar (§8, D4b): centred in the 72 px band at the foot, the travel 340 ms.\n */\nexport const SELECTION_MENU = { height: 40, gap: 10, margin: 16, edge: 8, awayMs: 90, backMs: 200, inMs: 180, outMs: 120, foot: 72, travelMs: 340 } as const;\n\nconst clamp = (x: number, a: number, b: number): number => Math.min(Math.max(x, a), Math.max(a, b));\n\n/**\n * Where the menu goes (desk.js `positionMenu`, number for number): centred on the anchor, `gap` above it; below it when\n * there is no room above (under the top ruler's band) and more below; `margin` from the sides, `edge` from the top and foot.\n * `sheet` = the height of an open sheet that must fit too. Null when there is nothing to anchor to. With an object IN HAND\n * (D4b) the bar sits centred in the band at the foot of the view, whatever the selection's box.\n */\nexport function placeSelectionMenu(anchor: SelectionMenuAnchor, size: { readonly w: number; readonly h: number }, sheet = 0): { readonly x: number; readonly y: number; readonly below: boolean } | null {\n const M = SELECTION_MENU;\n const { width: W, height: H } = anchor.view;\n if (anchor.held !== undefined && !anchor.held.landing) {\n return { x: clamp(W / 2 - size.w / 2, M.margin, W - size.w - M.margin), y: H - M.foot + (M.foot - size.h) / 2, below: false };\n }\n const b = anchor.box;\n if (b === null || anchor.count === 0) return null;\n let x = (b.x0 + b.x1) / 2 - size.w / 2;\n let y = b.y0 - M.gap - size.h;\n const top = anchor.rulers !== null ? anchor.rulers.margin + anchor.rulers.band + M.edge : M.edge;\n const yBelow = b.y1 + M.gap;\n const roomAbove = y - sheet - top;\n const roomBelow = H - M.edge - (yBelow + size.h + sheet);\n let below = false;\n if (roomAbove < 0 && roomBelow > roomAbove) { y = yBelow; below = true; }\n x = clamp(x, M.margin, W - size.w - M.margin);\n y = clamp(y, M.edge, H - size.h - M.edge);\n return { x, y, below };\n}\n\n// ---------------------------------------------------------------- the glyphs (the desk-chrome page's paths, objects.js `GLYPH`)\n\nconst stroke = (children: ReactNode): ReactNode => <g fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\">{children}</g>;\n/** DESIGN.md §13's drawings the bar uses and the six *Marks on the Mat* adds — 24-unit boxes, one 2-unit stroke, currentColor. */\nexport const SELECTION_GLYPHS: Readonly<Record<string, ReactNode>> = {\n agents: stroke(<><circle cx=\"12\" cy=\"12\" r=\"3\" /><circle cx=\"12\" cy=\"4.5\" r=\"2\" /><circle cx=\"5.5\" cy=\"15.75\" r=\"2\" /><circle cx=\"18.5\" cy=\"15.75\" r=\"2\" /></>),\n chevron: stroke(<path d=\"M9.5 6l6 6-6 6\" />),\n trash: stroke(<path d=\"M4.5 6.5h15M9.5 6.5V5a1.5 1.5 0 0 1 1.5-1.5h2A1.5 1.5 0 0 1 14.5 5v1.5M6.5 6.5l.9 12.2a2 2 0 0 0 2 1.8h5.2a2 2 0 0 0 2-1.8l.9-12.2M10 10.5v6M14 10.5v6\" />),\n duplicate: stroke(<><rect x=\"8.5\" y=\"8.5\" width=\"12\" height=\"12\" rx=\"3\" /><path d=\"M15.5 8.5V6.5a3 3 0 0 0-3-3h-6a3 3 0 0 0-3 3v6a3 3 0 0 0 3 3h2\" /></>),\n lock: stroke(<><rect x=\"4.5\" y=\"10.5\" width=\"15\" height=\"10\" rx=\"3\" /><path d=\"M8 10.5V8a4 4 0 0 1 8 0v2.5M12 14.5v2\" /></>),\n unlock: stroke(<><rect x=\"4.5\" y=\"10.5\" width=\"15\" height=\"10\" rx=\"3\" /><path d=\"M8 10.5V8a4 4 0 0 1 7.7-1.5M12 14.5v2\" /></>),\n ellipsis: <path fill=\"currentColor\" fillRule=\"evenodd\" d=\"M3.7 10.4h1.9a0.7 0.7 0 0 1 0.7 0.7v1.9a0.7 0.7 0 0 1 -0.7 0.7h-1.9a0.7 0.7 0 0 1 -0.7 -0.7v-1.9a0.7 0.7 0 0 1 0.7 -0.7ZM11.05 10.4h1.9a0.7 0.7 0 0 1 0.7 0.7v1.9a0.7 0.7 0 0 1 -0.7 0.7h-1.9a0.7 0.7 0 0 1 -0.7 -0.7v-1.9a0.7 0.7 0 0 1 0.7 -0.7ZM18.4 10.4h1.9a0.7 0.7 0 0 1 0.7 0.7v1.9a0.7 0.7 0 0 1 -0.7 0.7h-1.9a0.7 0.7 0 0 1 -0.7 -0.7v-1.9a0.7 0.7 0 0 1 0.7 -0.7Z\" />,\n // the held bar's (design-015 §8, D4b): the kinds' declared tools and Done — the same 24-box, one 2-unit stroke\n \"chevron-left\": stroke(<path d=\"M14.5 6l-6 6 6 6\" />),\n pen: stroke(<><path d=\"M5 19l1.2-4.2L15.6 5.4a2 2 0 0 1 2.8 0l.2.2a2 2 0 0 1 0 2.8L9.2 17.8z\" /><path d=\"M13.5 7.5l3 3\" /></>),\n eraser: stroke(<><path d=\"M4.5 15.5l7-7a2 2 0 0 1 2.8 0l4.2 4.2a2 2 0 0 1 0 2.8l-4 4H9.3l-4.8-4z\" /><path d=\"M9 19.5h11\" /></>),\n undo: stroke(<><path d=\"M8.5 7.5H15a4.5 4.5 0 0 1 0 9H7\" /><path d=\"M11 4.5l-3.5 3 3.5 3\" /></>),\n redo: stroke(<><path d=\"M15.5 7.5H9a4.5 4.5 0 0 0 0 9h8\" /><path d=\"M13 4.5l3.5 3-3.5 3\" /></>),\n today: stroke(<><rect x=\"4.5\" y=\"6\" width=\"15\" height=\"13.5\" rx=\"2.5\" /><path d=\"M4.5 10.5h15M8.5 4v3.5M15.5 4v3.5\" /><circle cx=\"12\" cy=\"15\" r=\"1.4\" /></>),\n check: stroke(<path d=\"M5 12.5l4.5 4.5L19 7.5\" />),\n};\nfunction Glyph({ glyph, size = 16 }: { readonly glyph: string | ReactNode; readonly size?: number }): ReactElement {\n const body = typeof glyph === \"string\" ? SELECTION_GLYPHS[glyph] : glyph;\n return <svg viewBox=\"0 0 24 24\" width={size} height={size} aria-hidden=\"true\" focusable=\"false\">{body}</svg>;\n}\n\n/** Is this glyph a DRAWING (`{ path }`) rather than a name or a node? */\nconst isDrawing = (g: unknown): g is { readonly path: string; readonly fill?: boolean } => typeof g === \"object\" && g !== null && typeof (g as { path?: unknown }).path === \"string\";\n/** A drawing in the bar's hand: the path in the 24-unit box, stroked like the set's (or filled). */\nconst drawn = (g: { readonly path: string; readonly fill?: boolean }): ReactNode => (g.fill === true ? <path fill=\"currentColor\" fillRule=\"evenodd\" d={g.path} /> : stroke(<path d={g.path} />));\n/** A glyph a tool named that the bar cannot draw: its label's initial, unmistakably not a glyph of the set (K8a — never \"ellipsis\"). */\nconst initial = (label: string): ReactNode => <text x=\"12\" y=\"16.5\" textAnchor=\"middle\" fontSize=\"13\" fontWeight=\"600\" fill=\"currentColor\">{(label.trim()[0] ?? \"?\").toUpperCase()}</text>;\n/** Each missing name said once, loudly: a declaration error, not a look. */\nconst missingSaid = new Set<string>();\n\n/** A kind act's glyph as the menu draws it (K8a): its drawing, a name of the set, or — a name the set lacks, or none — its initial, the missing name said once. */\nfunction actGlyph(k: SelectionMenuAct): ReactNode {\n return toolGlyph({ id: k.id, label: k.label, ...(k.glyph !== undefined ? { glyph: k.glyph } : {}) }).node;\n}\n\n/** A held tool's glyph as the bar draws it — and whether a NAME it gave is missing from the set. */\nfunction toolGlyph(t: SelectionMenuTool): { readonly node: ReactNode; readonly missing: string | undefined } {\n const g = t.glyph;\n if (isDrawing(g)) return { node: drawn(g), missing: undefined };\n if (typeof g === \"string\" && g in SELECTION_GLYPHS) return { node: SELECTION_GLYPHS[g], missing: undefined };\n if (typeof g === \"string\" && !missingSaid.has(g)) {\n missingSaid.add(g);\n console.error(`[ice] the held tool \"${t.id}\" names the glyph \"${g}\", which the bar does not draw — declare its drawing (\\`glyph: { path }\\`) or a name of SELECTION_GLYPHS`);\n }\n // no glyph at all, or a name the bar does not know: the tool's initial — honest, and never another tool's glyph\n return { node: initial(t.label), missing: typeof g === \"string\" ? g : undefined };\n}\n\n// ---------------------------------------------------------------- the acts ICE ships\n\n/** ICE's own acts, in the bar's order: Duplicate (not for tape), Tape it down / Lift the tape, More, and Delete past a rule. */\nexport function defaultSelectionActions(): SelectionAction[] {\n return [\n { id: \"duplicate\", label: \"Duplicate\", glyph: \"duplicate\", keys: \"⌘D\", when: (s) => !s.locked, run: (e) => { e.ops.duplicateSelection(); } },\n {\n id: \"tape\", label: (s) => (s.locked ? \"Lift the tape\" : \"Tape it down\"), glyph: (s) => (s.locked ? \"unlock\" : \"lock\"), keys: \"⇧⌘L\", on: (s) => s.locked,\n run: (e, s) => { e.ops.setLocked(selectedEntities(e.world), !s.locked); },\n },\n { id: \"more\", label: \"More\", glyph: \"ellipsis\", run: () => {} },\n { id: \"delete\", label: \"Delete\", glyph: \"trash\", keys: \"⌫\", place: \"end\", tone: \"danger\", run: (e) => { e.ops.deleteSelection(); } },\n ];\n}\n\nconst labelOf = (a: SelectionAction, s: SelectionState): string => (typeof a.label === \"function\" ? a.label(s) : a.label);\nconst glyphOf = (a: SelectionAction, s: SelectionState): string | ReactNode => (typeof a.glyph === \"function\" ? a.glyph(s) : a.glyph);\n\n// ---------------------------------------------------------------- the ink (desk.css `.sel-menu`, the tray's material)\n\n/** The desk's INK as CSS custom properties — the menu's and, since design-018 §5, the tray bar's (`<TrayBar>`): one set of values; an app re-points them on either island. */\nexport const DESK_INK = \"--ice-menu-ink:rgb(16 9 4 / .94);--ice-menu-ink-solid:rgb(16 9 4);--ice-menu-cream:rgb(255 237 215);--ice-menu-cream-rgb:255 237 215;--ice-menu-brass:rgb(196 165 116);--ice-menu-hair:rgb(196 165 116 / .24);--ice-menu-rule:rgb(196 165 116 / .34);--ice-menu-danger:rgb(255 69 58);--ice-menu-danger-bg:rgb(255 69 58 / .16);--ice-menu-shadow:-1px 2px 3px rgb(14 26 10 / .25),-8px 14px 32px rgb(14 26 10 / .38)\";\n\nconst STYLE = `\n[data-ice-selection-menu]{${DESK_INK};position:absolute;left:0;top:0;z-index:20;will-change:transform,opacity;font:500 12.5px/1 var(--ice-menu-font,system-ui,-apple-system,sans-serif);user-select:none}\n[data-ice-selection-menu] .ice-sm-bar{position:relative;display:flex;align-items:center;gap:2px;height:40px;padding:4px;box-sizing:border-box;white-space:nowrap;border-radius:20px;background:var(--ice-menu-ink);color:var(--ice-menu-cream);box-shadow:inset 0 0 0 1px var(--ice-menu-hair),var(--ice-menu-shadow)}\n[data-ice-selection-menu] button{appearance:none;border:0;margin:0;padding:0;background:none;color:inherit;font:inherit;cursor:pointer}\n[data-ice-selection-menu] .ice-sm-btn{width:32px;height:32px;border-radius:16px;display:grid;place-items:center;color:rgb(var(--ice-menu-cream-rgb) / .86);transition:background 120ms ease,color 120ms ease,transform 120ms ease}\n[data-ice-selection-menu] .ice-sm-btn:hover{background:rgb(var(--ice-menu-cream-rgb) / .09);color:var(--ice-menu-cream)}\n[data-ice-selection-menu] .ice-sm-btn:active{transform:scale(.95);background:rgb(var(--ice-menu-cream-rgb) / .15)}\n[data-ice-selection-menu] .ice-sm-btn[data-on=\"true\"]{background:var(--ice-menu-cream);color:var(--ice-menu-ink-solid)}\n[data-ice-selection-menu] .ice-sm-btn[data-tone=\"danger\"]:hover{color:var(--ice-menu-danger);background:var(--ice-menu-danger-bg)}\n[data-ice-selection-menu] .ice-sm-text{height:32px;padding:0 9px;border-radius:16px;display:inline-flex;align-items:center;gap:7px;color:var(--ice-menu-cream);background:rgb(var(--ice-menu-cream-rgb) / .08);transition:background 120ms ease,transform 120ms ease}\n[data-ice-selection-menu] .ice-sm-text:hover{background:rgb(var(--ice-menu-cream-rgb) / .15)}\n[data-ice-selection-menu] .ice-sm-text:active{transform:scale(.97)}\n[data-ice-selection-menu] .ice-sm-text svg:last-child{transform:rotate(-90deg);opacity:.55;margin-left:-1px;transition:transform 240ms cubic-bezier(.25,1,.3,1)}\n[data-ice-selection-menu][data-below=\"true\"] .ice-sm-text svg:last-child{transform:rotate(90deg)}\n[data-ice-selection-menu] .ice-sm-rule{flex:none;width:0;height:22px;margin:0 4px;border-left:1px dashed var(--ice-menu-rule)}\n[data-ice-selection-menu] .ice-sm-sheet{position:absolute;left:0;min-width:208px;padding:6px;box-sizing:border-box;border-radius:14px;background:var(--ice-menu-ink);color:var(--ice-menu-cream);box-shadow:inset 0 0 0 1px var(--ice-menu-hair),var(--ice-menu-shadow)}\n[data-ice-selection-menu] .ice-sm-item{display:flex;width:100%;align-items:center;justify-content:space-between;gap:16px;padding:8px 10px;border-radius:8px;text-align:left}\n[data-ice-selection-menu] .ice-sm-item:hover{background:rgb(var(--ice-menu-cream-rgb) / .09)}\n[data-ice-selection-menu] .ice-sm-item[data-tone=\"danger\"]:hover{color:var(--ice-menu-danger);background:var(--ice-menu-danger-bg)}\n[data-ice-selection-menu] .ice-sm-item kbd{font:500 11px/1 var(--ice-menu-mono,ui-monospace,monospace);color:var(--ice-menu-brass)}\n[data-ice-selection-menu] .ice-sm-btn.is-dim{color:rgb(var(--ice-menu-cream-rgb) / .38);cursor:default}\n[data-ice-selection-menu] .ice-sm-btn.is-dim:hover{background:none;color:rgb(var(--ice-menu-cream-rgb) / .38)}\n[data-ice-selection-menu] .ice-sm-btn.is-dim:active{transform:none;background:none}\n[data-ice-selection-menu][data-held=\"true\"] .ice-sm-text svg:last-child{display:none}\n[data-ice-selection-menu] .ice-sm-ink{width:28px;height:32px;border-radius:14px;display:grid;place-items:center}\n[data-ice-selection-menu] .ice-sm-ink i{width:12px;height:12px;border-radius:50%;box-shadow:inset 0 0 0 1px rgb(255 255 255 / .16);transition:transform 160ms cubic-bezier(.3,1.4,.5,1),box-shadow 160ms ease}\n[data-ice-selection-menu] .ice-sm-ink:hover i{transform:scale(1.18)}\n[data-ice-selection-menu] .ice-sm-ink[data-on=\"true\"] i{box-shadow:0 0 0 2px var(--ice-menu-ink-solid),0 0 0 3.5px var(--ice-menu-cream)}\n`;\n\nexport interface SelectionMenuProps {\n /** Where to go — the desk handle's `selection`. */\n readonly source: SelectionMenuSource;\n /** The acts, in the bar's order within their places (default: `defaultSelectionActions()`); an app prepends its own. */\n readonly actions?: readonly SelectionAction[];\n /** The engine the acts run on (default: the `EngineProvider`'s — the one `<Desk>` is mounted under). */\n readonly engine?: CanvasEngine;\n}\n\ninterface Shown { readonly count: number; readonly locked: boolean; readonly visible: boolean; readonly gesturing: boolean; readonly held: boolean; readonly tools: string; readonly active: string; readonly menu: string }\nconst shownOf = (a: SelectionMenuAnchor): Shown => {\n const held = a.held !== undefined && !a.held.landing;\n // flying home the bar steps aside as for a gesture — and comes back 200 ms after the landing\n const landing = a.held?.landing === true;\n const tools = held ? (a.held?.tools ?? []).map((t) => `${t.id}:${t.kind ?? \"\"}:${t.swatch ?? \"\"}`).join(\"|\") : \"\";\n const menu = (a.menu ?? []).map((m) => `${m.id}:${m.label}`).join(\"|\");\n return { count: a.count, locked: a.locked, visible: (a.count > 0 && a.box !== null) || held, gesturing: a.gesturing || a.editing === true || landing, held, tools, active: held ? (a.held?.active ?? \"\") : \"\", menu };\n};\nconst sameShown = (a: Shown, b: Shown): boolean => a.count === b.count && a.locked === b.locked && a.visible === b.visible && a.gesturing === b.gesturing && a.held === b.held && a.tools === b.tools && a.active === b.active && a.menu === b.menu;\n/** The one element's transitions: the opacity's, and — while the bar travels between the selection and the foot (M1) — the transform's. */\nconst transitionOf = (away: boolean, visible: boolean, traveling: boolean): string => {\n const M = SELECTION_MENU;\n const opacity = away ? `opacity ${M.awayMs}ms ease-out` : visible ? `opacity ${M.inMs}ms ease-out` : `opacity ${M.outMs}ms ease-out, visibility 0s linear ${M.outMs}ms`;\n return traveling ? `${opacity}, transform ${M.travelMs}ms cubic-bezier(.25,1,.3,1)` : opacity;\n};\n\nexport function SelectionMenu({ source, actions, engine: given }: SelectionMenuProps): ReactElement | null {\n const provided = useOptionalEngine();\n const engine = given ?? provided;\n const acts = useMemo(() => actions ?? defaultSelectionActions(), [actions]);\n const root = useRef<HTMLDivElement | null>(null);\n const [shown, setShown] = useState<Shown>(() => shownOf(source.anchor()));\n const [away, setAway] = useState(false);\n const [open, setOpen] = useState(false);\n const [below, setBelow] = useState(false);\n const [traveling, setTraveling] = useState(false);\n const tools = useRef<readonly SelectionMenuTool[]>(source.anchor().held?.tools ?? []);\n const kindActs = useRef<readonly SelectionMenuAct[]>(source.anchor().menu ?? []);\n const heldRef = useRef(shown.held);\n const travelTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // placement: written straight to the one element's transform on every anchor the desk publishes (no render per frame)\n const placeRef = useRef<() => void>(() => {});\n placeRef.current = (): void => {\n const el = root.current;\n const a = source.anchor();\n const next = shownOf(a);\n if (next.held) tools.current = a.held?.tools ?? [];\n kindActs.current = a.menu ?? [];\n setShown((prev) => (sameShown(prev, next) ? prev : next));\n if (el === null) return;\n // THE TRAVEL (M1, D4b): the bar changes place and role — the transform's transition must be on BEFORE the new place is\n // written, or the bar jumps (desk.js `morphBar`); it stays on for the travel and no longer, so a moving selection still\n // places instantly\n if (next.held !== heldRef.current) {\n heldRef.current = next.held;\n el.style.transition = transitionOf(away, next.visible, true);\n setTraveling(true);\n if (travelTimer.current !== null) clearTimeout(travelTimer.current);\n travelTimer.current = setTimeout(() => { travelTimer.current = null; setTraveling(false); }, SELECTION_MENU.travelMs);\n }\n const bar = el.firstElementChild as HTMLElement | null;\n const sheet = el.querySelector<HTMLElement>(\".ice-sm-sheet\");\n // a bar not laid out yet (0 tall) is placed as the 40 it will be\n const p = placeSelectionMenu(a, { w: bar?.offsetWidth ?? 0, h: bar?.offsetHeight || SELECTION_MENU.height }, sheet?.offsetHeight ?? 0);\n if (p === null) return;\n el.style.transform = `translate(${p.x.toFixed(1)}px, ${p.y.toFixed(1)}px)`;\n el.dataset.below = String(p.below);\n setBelow((prev) => (prev === p.below ? prev : p.below));\n };\n useEffect(() => () => { if (travelTimer.current !== null) clearTimeout(travelTimer.current); }, []);\n useLayoutEffect(() => {\n const run = (): void => placeRef.current();\n run();\n return source.subscribe(run);\n }, [source]);\n // re-place after the bar's contents change size (a taped selection drops Duplicate; More opens; the bar becomes the held bar)\n // biome-ignore lint/correctness/useExhaustiveDependencies: the placement follows what was rendered — these are its triggers, not its inputs\n useLayoutEffect(() => { placeRef.current(); }, [shown.count, shown.locked, shown.visible, shown.held, shown.tools, shown.menu, open]);\n\n // a gesture: away in 90 ms at once; back 200 ms after the hand lets go\n useEffect(() => {\n if (shown.gesturing) { setAway(true); setOpen(false); return; }\n const t = setTimeout(() => setAway(false), SELECTION_MENU.backMs);\n return () => clearTimeout(t);\n }, [shown.gesturing]);\n // a new selection closes More\n // biome-ignore lint/correctness/useExhaustiveDependencies: the count is the trigger, not an input\n useEffect(() => { setOpen(false); }, [shown.count]);\n\n if (engine === undefined) return null;\n const state: SelectionState = { count: shown.count, locked: shown.locked };\n const visible = shown.visible;\n // the selection's KIND ACTS (K8a) first among the main acts: each runs its op through the engine, on the types that declare it\n const kinds: SelectionAction[] = kindActs.current.map((k) => ({\n id: `kind.${k.id}`, label: k.label, glyph: actGlyph(k), ...(k.keys !== undefined ? { keys: k.keys } : {}),\n run: (e) => { e.ops.runMenuAction(k.id); },\n }));\n const listed = [...kinds, ...acts].filter((a) => a.when === undefined || a.when(state));\n const at = (place: \"lead\" | \"main\" | \"end\") => listed.filter((a) => (a.place ?? \"main\") === place);\n const button = (a: SelectionAction): ReactElement => {\n const label = labelOf(a, state);\n const tip = a.keys !== undefined ? `${label} (${a.keys})` : label;\n const run = (): void => { if (a.id === \"more\") { setOpen((o) => !o); return; } setOpen(false); a.run(engine, state); };\n if (a.text === true) {\n return (\n <button key={a.id} type=\"button\" className=\"ice-sm-text\" data-act={a.id} aria-label={label} title={tip} onClick={run}>\n <Glyph glyph={glyphOf(a, state)} />\n <span>{label}</span>\n <Glyph glyph=\"chevron\" size={12} />\n </button>\n );\n }\n return (\n <button key={a.id} type=\"button\" className=\"ice-sm-btn\" data-act={a.id} data-on={a.on?.(state) === true ? \"true\" : undefined} data-tone={a.tone} data-glyph={typeof glyphOf(a, state) === \"string\" ? (glyphOf(a, state) as string) : undefined} aria-label={label} title={tip} aria-haspopup={a.id === \"more\" ? \"menu\" : undefined} aria-expanded={a.id === \"more\" ? open : undefined} onClick={run}>\n <Glyph glyph={glyphOf(a, state)} />\n </button>\n );\n };\n const lead = at(\"lead\");\n const main = at(\"main\");\n const end = at(\"end\");\n const opacity = visible && !away ? 1 : 0;\n // THE HELD BAR (design-015 §8, D4b): Send stays first, the kind's tools take the middle, Done ends it. D3t-a: a slot is LIVE —\n // pressed, it uses its tool through the engine (`ops.useHeldTool`: a mode becomes the tool in hand, an action runs its op); the\n // mode in hand is marked in cream, the tray's own ink (*Marks on the Mat* Q-f: never `--hot`), and only it; a tool declared with\n // no kind stays dim and inert\n const slot = (t: SelectionMenuTool): ReactElement => {\n const tip = t.hint !== undefined ? `${t.label} (${t.hint})` : t.label;\n const g = toolGlyph(t);\n const glyph = <Glyph glyph={g.node} />;\n if (t.kind === undefined) {\n return (\n <button key={t.id} type=\"button\" className=\"ice-sm-btn is-dim\" data-tool={t.id} data-glyph-missing={g.missing} aria-label={t.label} aria-disabled=\"true\" title={tip} tabIndex={-1}>\n {glyph}\n </button>\n );\n }\n const on = t.kind === \"mode\" && t.id === shown.active;\n return (\n <button\n key={t.id} type=\"button\" className={t.swatch !== undefined ? \"ice-sm-ink\" : \"ice-sm-btn\"} data-tool={t.id} data-kind={t.kind} data-glyph-missing={g.missing}\n data-on={on ? \"true\" : undefined} aria-pressed={t.kind === \"mode\" ? on : undefined} aria-label={t.label} title={tip}\n onClick={() => { setOpen(false); engine.ops.useHeldTool(t.id); }}\n >\n {t.swatch !== undefined ? <i style={{ background: t.swatch }} /> : glyph}\n </button>\n );\n };\n const done = (\n <button key=\"done\" type=\"button\" className=\"ice-sm-text\" data-act=\"done\" aria-label=\"Done\" title=\"Done (Esc)\" onClick={() => { setOpen(false); engine.ops.putDown(); }}>\n <Glyph glyph=\"check\" />\n <span>Done</span>\n </button>\n );\n return (\n <div\n ref={root}\n data-ice-selection-menu=\"\"\n data-canvas-interactive=\"\"\n data-away={String(away)}\n data-visible={String(visible)}\n data-held={String(shown.held)}\n role=\"toolbar\"\n aria-label={shown.held ? \"In hand\" : \"Selection\"}\n aria-hidden={!visible}\n onPointerDown={(e) => e.stopPropagation()}\n style={{\n opacity,\n visibility: visible ? \"visible\" : \"hidden\",\n pointerEvents: opacity === 1 ? \"auto\" : \"none\",\n transition: transitionOf(away, visible, traveling),\n }}\n >\n <div className=\"ice-sm-bar\">\n {shown.held ? (\n <>\n {lead.map(button)}\n {lead.length > 0 ? <span className=\"ice-sm-rule\" aria-hidden=\"true\" /> : null}\n {tools.current.map(slot)}\n {tools.current.length > 0 ? <span className=\"ice-sm-rule\" aria-hidden=\"true\" /> : null}\n {done}\n </>\n ) : (\n <>\n {lead.map(button)}\n {lead.length > 0 && main.length > 0 ? <span className=\"ice-sm-rule\" aria-hidden=\"true\" /> : null}\n {main.map(button)}\n {end.length > 0 && lead.length + main.length > 0 ? <span className=\"ice-sm-rule\" aria-hidden=\"true\" /> : null}\n {end.map(button)}\n </>\n )}\n </div>\n {open && !shown.held ? (\n <div className=\"ice-sm-sheet\" role=\"menu\" style={below ? { top: \"calc(100% + 6px)\" } : { bottom: \"calc(100% + 6px)\" }}>\n {listed.filter((a) => a.id !== \"more\").map((a) => (\n <button key={a.id} type=\"button\" role=\"menuitem\" className=\"ice-sm-item\" data-act={a.id} data-tone={a.tone} onClick={() => { setOpen(false); a.run(engine, state); }}>\n <span>{labelOf(a, state)}</span>\n {a.keys !== undefined ? <kbd>{a.keys}</kbd> : null}\n </button>\n ))}\n </div>\n ) : null}\n <style>{STYLE}</style>\n </div>\n );\n}\n\n/** The provider's engine when there is one (the menu may also be mounted outside an `EngineProvider` with `engine` given). */\nfunction useOptionalEngine(): CanvasEngine | undefined {\n try {\n return useCanvasEngine();\n } catch {\n return undefined;\n }\n}\n\n/** Is every selected widget taped? (for an app's own acts) */\nexport function selectionTaped(engine: CanvasEngine): boolean {\n const sel = selectedEntities(engine.world);\n return sel.length > 0 && sel.every((e) => engine.world.hasTag(e, Locked));\n}\n","/**\n * `<TrayBar>` — the pegboard drawer's HANDLE and its FILTERS (design-018 §5–§6, R4; ICE M22): DOM in screen space, the selection menu's\n * sibling (design-015 §2 law 2 — never under the camera). The drawer stays the renderer's (design-017 §1); its handle and its filters\n * are chrome, two islands under one root.\n *\n * THE PILL, in the desk's ink (`DESK_INK`, the same custom properties an app re-points): closed, a 40 px pill centred 16 px above the\n * view's foot — the pegboard glyph (three staggered stadium holes) and the word Objects, titled \"Objects (A)\", `aria-expanded`; open, the\n * same pill rides the drawer's top edge, its bottom 10 px above the board — `min(vh − 16, drawer.y − 10)`, written as the desk publishes\n * each frame of the slide, so it follows the drawer exactly — its glyph a close ×.\n *\n * THE CHIPS (R4 — James: \"design the filters nicely at that empty safe top space\"): LABEL TAPE stuck on the board in the drawer's clear\n * HEADER (the anchor's `drawer.header`, where nothing of the board's content shows), centred on the drawer's centre line and in the\n * header, following the drawer every frame of its slide and fading in over its last part — All, then the frame's categories in the\n * lay's order, in the specimens' own tag language (`DESK_TAPE`: the embosser's near-black tape and its raised pale capitals, the desk's\n * `MARKS.label`), the chosen one CREAM tape with ink letters (the desk's \"chosen is cream\" — the menu's `data-on`), `aria-pressed`, in a\n * `role=\"toolbar\"`; past the header's width they scroll inside it, each end fading where more tape lies beyond. By night the tape steps\n * back as the tags do (`night`, the anchor's).\n * Both step aside while an object is IN HAND (the held bar has the view's foot then) and while the drawer has nothing to offer.\n *\n * Its pointer is chrome's: `data-canvas-interactive` flags the downs on the pill and on the chips, so the tray's input never takes one (a\n * chip never closes the drawer as a click on the dimmed desk would) and the desk's tap never lends the object under it the editor — the\n * header's bare board beside the chips stays the drawer's. Its keys: Enter and Space act on a focused button and ←/→ (Home/End) walk\n * the chips, before the page's own listeners — the keymap keeps `a` and Esc; a pointer's click leaves no focus behind, so Space still\n * pans and ⏎ is still the desk's. No rAF of its own: it moves only when the desk drew a frame that moved the drawer (idle-zero).\n *\n * `@ice/react` never imports the desk: the source is the desk handle's `tray` door, read structurally.\n */\nimport { type KeyboardEvent, type MouseEvent, type ReactElement, type ReactNode, useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport { DESK_INK } from \"./selection-menu\";\n\n/** A category chip as the door lists it (core's `TrayCategory`, mirrored structurally): its id, its label, how many entries it holds. */\nexport interface TrayBarCategory {\n readonly id: string;\n readonly label: string;\n readonly count: number;\n}\n\n/** What the bar is placed from — the desk handle's `tray.anchor()` (`TrayAnchor`), mirrored structurally. */\nexport interface TrayBarAnchor {\n /** The drawer is out (the fact — its slide may still be on its way). */\n readonly open: boolean;\n /**\n * The drawer's outline as drawn this frame (CSS px) and its slide — null before its first frame, or hidden — and its HEADER: the clear\n * band under its edge (from `y`, `h` high) where nothing of the board's content shows, the chips' place.\n */\n readonly drawer: { readonly x: number; readonly y: number; readonly w: number; readonly p: number; readonly header: { readonly y: number; readonly h: number } } | null;\n readonly view: { readonly width: number; readonly height: number };\n /** The theme's night, 0 day … 1 the Moon: the tape steps back by it as the specimens' tags do. */\n readonly night: number;\n /** An object is in hand: the held bar has the view's foot — the bar steps aside. */\n readonly held: boolean;\n /** How many entries the drawer's frame hangs (0: nothing to offer — the bar steps aside). */\n readonly entries: number;\n /** The category shown (\"\" all) and the frame's categories in the lay's order. */\n readonly category: string;\n readonly categories: readonly TrayBarCategory[];\n}\n\n/** The bar's source — the desk handle's `tray` door: the anchor, a subscription that fires after each frame that moved it, and the acts. */\nexport interface TrayBarSource {\n anchor(): TrayBarAnchor;\n subscribe(listener: () => void): () => void;\n toggle(): boolean;\n category(id?: string): string;\n}\n\n/**\n * The bar's numbers (design-018 §5, R4): the pill 40 tall, 16 above the view's foot closed, 10 above the board open, 16 from the view's\n * sides; away 90 ms, back in 180. The header's chips keep 12 in from the drawer's sides and fade in over the slide's last part — from\n * `p` 0.6 to 1, a smoothstep (D-R4.6).\n */\nexport const TRAY_BAR = { height: 40, foot: 16, ride: 10, margin: 16, awayMs: 90, inMs: 180, headInset: 12, headFrom: 0.6 } as const;\n\n/** Where the bar goes: the pill's top edge (CSS px), and the HEADER strip the chips lie centred in — with its opacity (null: no drawer drawn). */\nexport interface TrayBarPlace {\n readonly y: number;\n readonly head: { readonly x: number; readonly y: number; readonly w: number; readonly h: number; readonly opacity: number } | null;\n}\n\n/**\n * Where the bar goes. The pill: its bottom `min(vh − foot, drawer.y − ride)`, so it waits at the foot while the drawer's edge is below it\n * and rides the edge from there, one continuous motion. The chips: the drawer's header as drawn, `headInset` in from its sides, at the\n * slide's `smoothstep(headFrom, 1, p)` — one motion with the board, arriving as it does.\n */\nexport function placeTrayBar(a: TrayBarAnchor, height: number = TRAY_BAR.height): TrayBarPlace {\n const B = TRAY_BAR;\n const foot = a.view.height - B.foot;\n const d = a.drawer;\n const bottom = d === null ? foot : Math.min(foot, d.y - B.ride);\n if (d === null) return { y: bottom - height, head: null };\n const t = Math.min(Math.max((d.p - B.headFrom) / (1 - B.headFrom), 0), 1);\n return { y: bottom - height, head: { x: d.x + B.headInset, y: d.header.y, w: Math.max(0, d.w - 2 * B.headInset), h: d.header.h, opacity: t * t * (3 - 2 * t) } };\n}\n\nconst stadium = (x: number, y: number): ReactNode => <rect x={x} y={y} width=\"3.5\" height=\"8.5\" rx=\"1.75\" />;\n/** The bar's two drawings (24-unit boxes, currentColor): the PEGBOARD — three staggered stadium holes, a board's punched slots — and the close ×. */\nexport const TRAY_BAR_GLYPHS = {\n pegboard: <g fill=\"currentColor\">{stadium(5.75, 3.5)}{stadium(14.75, 3.5)}{stadium(10.25, 12)}</g>,\n close: <path d=\"M7 7l10 10M17 7L7 17\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" />,\n} as const;\n\n/**\n * The LABEL TAPE (design-018 R4) as custom properties an app re-points, as it does the ink's: the specimens' own tags — the embosser's\n * near-black tape and the pale plastic of its raised capitals (the desk's `MARKS.label`, the marks pass's `tagMarks`) — the CHOSEN tape,\n * cream with ink letters, and the capitals' face (the page's mono stack, `--vf-font-mono`, as the tags' glyph atlas draws them).\n */\nexport const DESK_TAPE = \"--ice-tape:#17181b;--ice-tape-letters-rgb:236 235 228;--ice-tape-chosen:#efe9da;--ice-tape-chosen-ink:rgb(16 9 4);--ice-tape-font:var(--vf-font-mono,ui-monospace,\\\"SF Mono\\\",Menlo,monospace)\";\n\n// ---------------------------------------------------------------- the ink (the menu's, `DESK_INK`) and the tape (`DESK_TAPE`)\n\n// The tape by night (`--ice-tb-night`, 0 … 1 — the anchor's, written with the placement) steps back as `tagMarks` has the tags do: the\n// capitals' plastic to 55 % over the tape, the gloss gone, the contact shadow at half; the CREAM tape — no tag to follow — steps back to\n// the brightness those capitals reach (brightness .6: ≈ 140, still the brightest tape, its ink ≈ 6:1) and loses its colour as the desk's\n// masking tape does by night (`MARKS.tape.night`'s saturate .3). The shadows fall down the tray lamp's ground direction\n// (≈ 0.47, 0.88 — the tags' 0.6, 0.9 px): a contact shadow on the board, and a soft one that grows as a hovered tape lifts 1 px.\nconst STYLE = `\n[data-ice-tray-bar]{${DESK_INK};${DESK_TAPE};--ice-tb-night:0;position:absolute;left:0;right:0;top:0;height:0;z-index:19;pointer-events:none;font:500 12.5px/1 var(--ice-menu-font,system-ui,-apple-system,sans-serif);user-select:none}\n[data-ice-tray-bar] .ice-tb-handle{position:absolute;left:0;right:0;top:0;display:flex;justify-content:center;pointer-events:none;will-change:transform}\n[data-ice-tray-bar] .ice-tb-bar{pointer-events:auto;display:flex;align-items:center;height:40px;padding:4px;box-sizing:border-box;white-space:nowrap;border-radius:20px;background:var(--ice-menu-ink);color:var(--ice-menu-cream);box-shadow:inset 0 0 0 1px var(--ice-menu-hair),var(--ice-menu-shadow);opacity:1;visibility:visible;transition:opacity ${TRAY_BAR.inMs}ms ease-out}\n[data-ice-tray-bar][data-visible=\"false\"] .ice-tb-bar{opacity:0;visibility:hidden;pointer-events:none;transition:opacity ${TRAY_BAR.awayMs}ms ease-out,visibility 0s linear ${TRAY_BAR.awayMs}ms}\n[data-ice-tray-bar] button{appearance:none;border:0;margin:0;padding:0;background:none;color:inherit;font:inherit;cursor:pointer}\n[data-ice-tray-bar] button:focus-visible{outline:2px solid var(--ice-menu-brass);outline-offset:1px}\n[data-ice-tray-bar] .ice-tb-toggle{flex:none;height:32px;padding:0 12px 0 9px;border-radius:16px;display:inline-flex;align-items:center;gap:7px;background:rgb(var(--ice-menu-cream-rgb) / .08);transition:background 120ms ease,transform 120ms ease}\n[data-ice-tray-bar] .ice-tb-toggle:hover{background:rgb(var(--ice-menu-cream-rgb) / .15)}\n[data-ice-tray-bar] .ice-tb-toggle:active{transform:scale(.97)}\n[data-ice-tray-bar] .ice-tb-head{position:absolute;left:0;top:0;display:flex;align-items:center;justify-content:center;box-sizing:border-box;pointer-events:none;visibility:visible;will-change:transform,opacity}\n[data-ice-tray-bar][data-visible=\"false\"] .ice-tb-head,[data-ice-tray-bar] .ice-tb-head[data-shown=\"false\"]{visibility:hidden}\n[data-ice-tray-bar] .ice-tb-chips{pointer-events:auto;display:flex;align-items:center;gap:8px;min-width:0;max-width:100%;padding:8px 7px;box-sizing:border-box;overflow-x:auto;scrollbar-width:none}\n[data-ice-tray-bar] .ice-tb-chips::-webkit-scrollbar{display:none}\n[data-ice-tray-bar] .ice-tb-chips[data-before=\"true\"]{mask-image:linear-gradient(90deg,transparent 0,#000 18px)}\n[data-ice-tray-bar] .ice-tb-chips[data-after=\"true\"]{mask-image:linear-gradient(90deg,#000 calc(100% - 18px),transparent 100%)}\n[data-ice-tray-bar] .ice-tb-chips[data-before=\"true\"][data-after=\"true\"]{mask-image:linear-gradient(90deg,transparent 0,#000 18px,#000 calc(100% - 18px),transparent 100%)}\n[data-ice-tray-bar] .ice-tb-chip{--n:var(--ice-tb-night);flex:none;height:26px;padding:0 10px;border-radius:2.5px;display:inline-flex;align-items:center;font:600 11px/1 var(--ice-tape-font);letter-spacing:.08em;text-transform:uppercase;color:rgb(var(--ice-tape-letters-rgb) / calc(1 - .45 * var(--n)));background:linear-gradient(180deg,rgb(255 255 255 / calc(.1 * (1 - var(--n)))) 0,rgb(255 255 255 / calc(.035 * (1 - var(--n)))) 46%,rgb(255 255 255 / 0) 54%),var(--ice-tape);text-shadow:0 1px 0 rgb(0 0 0 / .55),0 -.5px 0 rgb(255 255 255 / calc(.1 * (1 - var(--n))));box-shadow:inset 0 .75px 0 rgb(255 255 255 / calc(.1 * (1 - var(--n)))),.6px .9px 0 rgb(0 0 0 / calc(.24 * (1 - .5 * var(--n)))),1px 2px 3px rgb(0 0 0 / calc(.16 * (1 - .5 * var(--n))));transition:transform 120ms ease,box-shadow 120ms ease}\n[data-ice-tray-bar] .ice-tb-chip:hover{transform:translateY(-1px);box-shadow:inset 0 .75px 0 rgb(255 255 255 / calc(.1 * (1 - var(--n)))),1px 1.8px .5px rgb(0 0 0 / calc(.22 * (1 - .5 * var(--n)))),1.6px 3.2px 5px rgb(0 0 0 / calc(.2 * (1 - .5 * var(--n))))}\n[data-ice-tray-bar] .ice-tb-chip:active{transform:none}\n[data-ice-tray-bar] .ice-tb-chip:focus-visible{outline:2px solid var(--ice-menu-brass);outline-offset:2px}\n[data-ice-tray-bar] .ice-tb-chip[data-on=\"true\"]{--ice-tape:var(--ice-tape-chosen);color:var(--ice-tape-chosen-ink);text-shadow:0 1px 0 rgb(255 255 255 / .5),0 -.5px 0 rgb(60 40 20 / .18);filter:saturate(calc(1 - .7 * var(--n))) brightness(calc(1 - .4 * var(--n)))}\n`;\n\nexport interface TrayBarProps {\n /** The drawer's door — the desk handle's `tray`. */\n readonly source: TrayBarSource;\n /** The button's word (default \"Objects\") and the key named in its tip (default \"A\" — the app's toggle). */\n readonly label?: string;\n readonly keys?: string;\n}\n\n/** What the bar renders from (the placement is written straight to the elements: no render per frame of the slide). */\ninterface Shown { readonly visible: boolean; readonly open: boolean; readonly category: string; readonly chips: string }\nconst shownOf = (a: TrayBarAnchor): Shown => ({\n visible: !a.held && a.entries > 0,\n open: a.open,\n category: a.category,\n chips: a.categories.map((c) => `${c.id}:${c.label}:${c.count}`).join(\"|\"),\n});\nconst sameShown = (a: Shown, b: Shown): boolean => a.visible === b.visible && a.open === b.open && a.category === b.category && a.chips === b.chips;\n\n/** Enter and Space on a focused button act HERE, before the page's listeners (the keymap's ⏎, the pan's Space — both stand down for a handled key), the platform's own activation cancelled with them: once. */\nconst pressed = (run: () => void) => (e: KeyboardEvent<HTMLButtonElement>): void => {\n if (e.key !== \"Enter\" && e.key !== \" \") return;\n e.preventDefault();\n if (!e.repeat) run();\n};\nconst spaceUp = (e: KeyboardEvent<HTMLButtonElement>): void => { if (e.key === \" \") e.preventDefault(); };\n/** A pointer's click leaves no focus behind (the keys stay the desk's: Space pans, ⏎ opens the selection); a key's focus stays. */\nconst clicked = (run: () => void) => (e: MouseEvent<HTMLButtonElement>): void => { run(); if (e.detail > 0) e.currentTarget.blur(); };\n\nexport function TrayBar({ source, label = \"Objects\", keys = \"A\" }: TrayBarProps): ReactElement {\n const root = useRef<HTMLDivElement | null>(null);\n const handle = useRef<HTMLDivElement | null>(null);\n const head = useRef<HTMLDivElement | null>(null);\n const chipsRef = useRef<HTMLDivElement | null>(null);\n const toggleRef = useRef<HTMLButtonElement | null>(null);\n const cats = useRef<readonly TrayBarCategory[]>(source.anchor().categories);\n const [shown, setShown] = useState<Shown>(() => shownOf(source.anchor()));\n\n // the chips scrolled inside the header (past its width): each end fades where more tape lies beyond it — told on a scroll, a render,\n // and a new width (never per frame: reading the layout is once per change)\n const edges = (): void => {\n const c = chipsRef.current;\n if (c === null) return;\n const more = c.scrollWidth - c.clientWidth;\n c.dataset.before = String(more > 0.5 && c.scrollLeft > 0.5);\n c.dataset.after = String(more > 0.5 && c.scrollLeft < more - 0.5);\n };\n const width = useRef(-1);\n // placement: written straight to the elements on every anchor the desk publishes (no render per frame) — the pill's rise, the header\n // strip's rect and its fade, the night the tape steps back by\n const placeRef = useRef<() => void>(() => {});\n placeRef.current = (): void => {\n const a = source.anchor();\n cats.current = a.categories;\n const next = shownOf(a);\n setShown((prev) => (sameShown(prev, next) ? prev : next));\n const at = placeTrayBar(a);\n if (handle.current !== null) handle.current.style.transform = `translateY(${at.y.toFixed(1)}px)`;\n const h = head.current;\n if (h !== null) {\n const box = at.head;\n h.dataset.shown = String(box !== null && box.opacity > 0);\n if (box !== null) {\n h.style.transform = `translate(${box.x.toFixed(1)}px, ${box.y.toFixed(1)}px)`;\n h.style.width = `${box.w.toFixed(1)}px`;\n h.style.height = `${box.h.toFixed(1)}px`;\n h.style.opacity = box.opacity.toFixed(3);\n if (box.w !== width.current) { width.current = box.w; edges(); }\n }\n }\n root.current?.style.setProperty(\"--ice-tb-night\", Math.min(Math.max(a.night, 0), 1).toFixed(3));\n };\n useLayoutEffect(() => {\n const run = (): void => placeRef.current();\n run();\n return source.subscribe(run);\n }, [source]);\n useLayoutEffect(() => { edges(); });\n // the drawer shut under a focused chip: the focus goes back to the button, never to the page's body mid-walk\n useEffect(() => {\n if (!shown.open && chipsRef.current?.contains(document.activeElement) === true) toggleRef.current?.focus();\n }, [shown.open]);\n\n const toggle = (): void => { source.toggle(); };\n // ←/→ (Home/End) walk the chips — WAI-ARIA's toolbar; the desk's own arrows are quiet while the drawer is out\n const walk = (e: KeyboardEvent<HTMLDivElement>): void => {\n const found = chipsRef.current?.querySelectorAll<HTMLButtonElement>(\"button\");\n const list: HTMLButtonElement[] = found === undefined ? [] : Array.from(found);\n const at = list.indexOf(document.activeElement as HTMLButtonElement);\n const to = e.key === \"ArrowRight\" ? at + 1 : e.key === \"ArrowLeft\" ? at - 1 : e.key === \"Home\" ? 0 : e.key === \"End\" ? list.length - 1 : null;\n if (at < 0 || to === null) return;\n e.preventDefault();\n list[Math.min(Math.max(to, 0), list.length - 1)]?.focus();\n };\n const chips: readonly TrayBarCategory[] = [{ id: \"\", label: \"All\", count: 0 }, ...cats.current];\n return (\n <div ref={root} data-ice-tray-bar=\"\" data-open={String(shown.open)} data-visible={String(shown.visible)} aria-hidden={!shown.visible}>\n <div ref={handle} className=\"ice-tb-handle\">\n <div className=\"ice-tb-bar\" data-canvas-interactive=\"\" onPointerDown={(e) => e.stopPropagation()}>\n <button\n ref={toggleRef} type=\"button\" className=\"ice-tb-toggle\" data-act=\"tray\" aria-expanded={shown.open} aria-keyshortcuts={keys} title={`${label} (${keys})`}\n onClick={clicked(toggle)} onKeyDown={pressed(toggle)} onKeyUp={spaceUp}\n >\n <svg viewBox=\"0 0 24 24\" width={16} height={16} aria-hidden=\"true\" focusable=\"false\">{shown.open ? TRAY_BAR_GLYPHS.close : TRAY_BAR_GLYPHS.pegboard}</svg>\n <span>{label}</span>\n </button>\n </div>\n </div>\n <div ref={head} className=\"ice-tb-head\">\n <div ref={chipsRef} className=\"ice-tb-chips\" role=\"toolbar\" aria-label=\"Categories\" data-canvas-interactive=\"\" onKeyDown={walk} onScroll={edges} onPointerDown={(e) => e.stopPropagation()}>\n {chips.map((c) => {\n const on = c.id === shown.category;\n const choose = (): void => { source.category(c.id); };\n return (\n <button\n key={c.id === \"\" ? \"*\" : `=${c.id}`} type=\"button\" className=\"ice-tb-chip\" data-category={c.id} data-on={on ? \"true\" : undefined} aria-pressed={on}\n tabIndex={shown.open ? undefined : -1} onClick={clicked(choose)} onKeyDown={pressed(choose)} onKeyUp={spaceUp}\n >\n {c.label}\n </button>\n );\n })}\n </div>\n </div>\n <style>{STYLE}</style>\n </div>\n );\n}\n","/**\n * `<Desk>` — the one-line desk mount (design-015 §3, D5b): `@ice/dom`'s `createDeskHost` under\n * React. This component owns the container element and the keymap; the host owns the layer, the\n * adapters, the reflectors, the loop and the viewport sync. `<InfiniteCanvas>` became this BY\n * DELETION (plan D-D0.6): no planes, no profile gate, no DOM widget portals, no chrome plane (the\n * desk draws its own marks, design-015 §7), no measurement, no GL route, no `grid` prop (the\n * desk's handle has `configureFadeIn`/`configureMat`).\n *\n * The desk arrives as an OPAQUE layer factory — `layer={deskLayer({ … })}` from `@vibecook/ice/desk`\n * — typed structurally by `@ice/dom`; this package imports neither `@ice/desk` nor its handle.\n * Memoize the factory in the caller: a new identity re-boots the mount.\n *\n * Lifecycle: the engine is NOT owned here (the app disposes it). Unmount disposes the host.\n * Children render inside the container, above the canvas: the screen-space chrome (the selection\n * menu, a dev panel) and nothing that moves with the camera (design-015 §2 law 2).\n */\nimport type { CanvasEngine } from \"@ice/core\";\nimport {\n createDeskHost,\n type CanvasHost,\n type LayerFactory,\n type LayerHandle,\n type WidgetFocusHandle,\n} from \"@ice/dom\";\nimport { useEffect, useRef, type CSSProperties, type ReactElement, type ReactNode } from \"react\";\nimport { EngineProvider } from \"./engine-context\";\nimport { attachKeymap, type KeymapEntry } from \"./keymap\";\n\n/** Handed to {@link DeskProps.onReady} once the host is live (app-side devtools, the desk's handle). */\nexport interface DeskHandle {\n readonly engine: CanvasEngine;\n readonly host: CanvasHost;\n /** The mounted layer's handle, as the factory returned it (the desk's `DeskLayerHandle` under `deskLayer`). */\n readonly layer: LayerHandle;\n /**\n * Programmatic focus release (design-007 §2.3): `blurFocus()`. Focus is VIEW state\n * (design-007 §2.6) — it rides this handle, not `engine.ops` (a headless engine has none).\n */\n readonly focus: WidgetFocusHandle;\n}\n\nexport interface DeskProps {\n /** A constructed engine (`createCanvasEngine(...)`); NOT disposed on unmount. */\n readonly engine: CanvasEngine;\n /** The desk's layer factory (`deskLayer({ … })`), received opaquely. Memoize in the caller. */\n readonly layer: LayerFactory;\n /**\n * Called once per mount after the host, the reflectors and the loop are live. What it starts that outlives the call — a\n * listener, a wait, a join — it undoes in the cleanup it may return, which runs when the mount ends, before the host goes.\n * An effect's contract: StrictMode's development double mount runs it for the mount it discards (K9).\n */\n // biome-ignore lint/suspicious/noConfusingVoidType: React's EffectCallback shape — `undefined` would refuse `(h) => log(h)`\n readonly onReady?: (handle: DeskHandle) => void | (() => void);\n /**\n * Keymap overrides plumbed to {@link attachKeymap} (design-007 §5 M-d). An entry replaces a\n * default by its `key|mod|shift` signature; conditional behaviour belongs INSIDE `run`. BOUND\n * ONCE at mount, like the adapters: entries read live engine state at run time, never\n * render-time values.\n */\n readonly keymapOverrides?: readonly KeymapEntry[];\n readonly className?: string;\n readonly style?: CSSProperties;\n /** Screen-space chrome inside the viewport (the selection menu, a HUD) — rendered under the EngineProvider. */\n readonly children?: ReactNode;\n}\n\nexport function Desk({ engine, layer, onReady, keymapOverrides, className, style, children }: DeskProps): ReactElement {\n const containerRef = useRef<HTMLDivElement>(null);\n // Identity churn on these must not re-boot the mount: they ride refs.\n const onReadyRef = useRef(onReady);\n onReadyRef.current = onReady;\n const keymapOverridesRef = useRef(keymapOverrides);\n keymapOverridesRef.current = keymapOverrides;\n\n useEffect(() => {\n const container = containerRef.current;\n if (container === null) return;\n const mount = createDeskHost({ container, engine, layer });\n const detachKeymap = attachKeymap(engine, undefined, keymapOverridesRef.current ?? []);\n const undoReady = onReadyRef.current?.({ engine, host: mount.host, layer: mount.layer, focus: mount.focus });\n return () => {\n if (typeof undoReady === \"function\") undoReady(); // the app's own first, while the host it started from stands\n detachKeymap();\n mount.dispose();\n };\n }, [engine, layer]);\n\n return (\n <EngineProvider engine={engine}>\n <div ref={containerRef} className={className} style={{ width: \"100%\", height: \"100%\", ...style }} data-ice-canvas=\"\">\n {children}\n </div>\n </EngineProvider>\n );\n}\n","/**\n * @ice/react — the React face of the desk (design-015 §3): `<Desk>` (wraps `@ice/dom`'s\n * `createDeskHost`), EngineProvider + the Tier-3 hooks, the keymap, the screen-space selection\n * menu and held bar, the tray's bar (design-018). Renderer-free: the desk arrives as an opaque layer factory.\n * Import wall: @ice/dom → @ice/core down only — never three/desk (enforced). react/react-dom are peers.\n *\n * GONE at D5b (design-015 §1): `<InfiniteCanvas>` (→ `<Desk>`), `WidgetRoot` and the portals,\n * `WidgetPreview` + the preview snapshots, the surface content seam, the two presentation\n * profiles, `ChromeOwnerContext` and `WidgetHiddenContext`. One presentation (DK-D8).\n */\nexport const REACT_VERSION = \"0.0.0\";\n\nexport { useBreakpoint, useSelected, useBehavior, useWidgetProps, useWorldComponent } from \"./hooks\";\n\n// M10 React facade (design-005 §5): engine context, commit seam, hooks, keymap,\n// and the <Desk> mount.\nexport {\n EngineProvider,\n useCanvasEngine,\n useFrameFreeze,\n useOps,\n useStageHold,\n useWorld,\n type EngineProviderProps,\n} from \"./engine-context\";\nexport { useCommit, useUndoStatus, type Commit, type UndoStatus } from \"./use-commit\";\nexport { useTool, useToolState } from \"./use-tool\";\nexport {\n useCanvasCatalog,\n useCanvasDiagnostics,\n useCanvasTools,\n useCurrentCanvas,\n useFramePreview,\n} from \"./canvas-hooks\";\nexport {\n FramePreviewBoundary,\n type FramePreviewBoundaryProps,\n} from \"./frame-preview-boundary\";\nexport { usePresencePeers, type PresencePeerView } from \"./use-presence\";\nexport { attachKeymap, type KeymapEntry, nudgeSelection, toggleTape, unlessInert } from \"./keymap\";\nexport {\n defaultSelectionActions,\n placeSelectionMenu,\n SELECTION_GLYPHS,\n SELECTION_MENU,\n type SelectionAction,\n SelectionMenu,\n type SelectionMenuAnchor,\n type SelectionMenuBox,\n type SelectionMenuProps,\n type SelectionMenuSource,\n type SelectionGlyph,\n type SelectionMenuAct,\n type SelectionMenuTool,\n type SelectionState,\n selectionTaped,\n} from \"./selection-menu\";\n// design-018 §5–§6 (R2, R4): the pegboard drawer's handle — the menu's sibling in the desk's ink — and its category chips, label tape in\n// the drawer's header\nexport {\n DESK_TAPE,\n placeTrayBar,\n TRAY_BAR,\n TRAY_BAR_GLYPHS,\n TrayBar,\n type TrayBarAnchor,\n type TrayBarCategory,\n type TrayBarPlace,\n type TrayBarProps,\n type TrayBarSource,\n} from \"./tray-bar\";\nexport { Desk, type DeskHandle, type DeskProps } from \"./desk\";\n// The layer seam, re-exported so an app types its factory wrapper without naming @ice/dom.\nexport type { LayerContext, LayerFactory, LayerHandle } from \"@ice/dom\";\n"],"mappings":"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","names":["useCallback","useRef","useSyncExternalStore","useCallback","useRef","useSyncExternalStore","useCallback","useSyncExternalStore","useCallback","useSyncExternalStore","useCallback","useSyncExternalStore","useCallback","useSyncExternalStore","useCallback","useRef","useSyncExternalStore","useRef","useCallback","useSyncExternalStore","tools","useEffect","useMemo","useRef","jsx","tools","useMemo","useRef","useEffect","useEffect","useLayoutEffect","useRef","useState","jsx","jsxs","STYLE","shownOf","sameShown","useRef","useState","useLayoutEffect","useEffect","useEffect","useRef","jsx","useRef","useEffect"]}
@@ -59,6 +59,17 @@ export declare function readComponentOf(r: BehaviorRead): Component | undefined;
59
59
  export declare function facetBytesOf(cell: Record<string, unknown>): number;
60
60
  export declare function describeBehavior(behavior: AnyBehaviorDef): BehaviorDescription;
61
61
  export declare function defineBehavior<const S extends BehaviorStore, const Sch extends BehaviorSchema = BehaviorSchema>(name: string, spec: BehaviorSpec<S, Sch>): BehaviorHandle<DataOf<Sch>>;
62
+ /**
63
+ * `defineBehavior` for the ENGINE's own behaviours — the only way into the
64
+ * reserved `ice:` namespace (A3b fix 4).
65
+ *
66
+ * Deliberately NOT on the package barrel: it is not a second public door but
67
+ * the same door with the engine's key in it. `surface/standard-behaviors.ts`
68
+ * is its only caller today; anything else the engine ships in `ice:` uses it
69
+ * for the same two reasons — the compiler's attestation and the read-surface
70
+ * exemption both mean "ICE wrote this", and a string prefix cannot say that.
71
+ */
72
+ export declare function defineEngineBehavior<const S extends BehaviorStore, const Sch extends BehaviorSchema = BehaviorSchema>(name: string, spec: BehaviorSpec<S, Sch>): BehaviorHandle<DataOf<Sch>>;
62
73
  /**
63
74
  * TEST-ONLY registry wipe (mirrors `__resetPrefabsForTests`; deliberately NOT
64
75
  * on the barrel). strata's schema registry has no reset, so a test that wipes
@@ -46,6 +46,10 @@ export interface BehaviorRuntimeOpts {
46
46
  addSystems(group: PhaseGroup, ...systems: readonly never[]): () => void;
47
47
  readonly guests: GuestRegistry;
48
48
  onPublish(hook: (world: World) => void): () => void;
49
+ /** The frame gate's registered wakes (K7a): a behavior with a `tick` hook and instances is due every frame. */
50
+ readonly frame?: {
51
+ wakeWhen(name: string, due: (now: number) => number): () => void;
52
+ };
49
53
  };
50
54
  /** The FORWARDING session seam — the target swaps per doc open/close. */
51
55
  readonly session?: () => BehaviorSession | undefined;
@@ -0,0 +1,86 @@
1
+ /**
2
+ * CanvasType definitions — the semantic/presentation profile for one frame.
3
+ *
4
+ * Definitions are immutable handles. The process registry is discovery and
5
+ * duplicate-id diagnostics only; an EngineCatalog decides which definitions
6
+ * have authority in a particular engine.
7
+ */
8
+ import type { Tool } from "../tools/define-tool";
9
+ import type { WidgetType } from "../widget/define-widget";
10
+ import type { CanvasRuntimeExtension, CanvasSemanticMigration, FrameBehavior } from "./extensions";
11
+ import type { CanvasPreviewDeclaration } from "./frame-projection";
12
+ export interface CanvasPlacementDef {
13
+ /** Exact capability keys matched against normalized WidgetType.provides. */
14
+ readonly accepts?: readonly string[];
15
+ /** Explicit widget handles admitted independently of capability keys. */
16
+ readonly widgets?: readonly WidgetType[];
17
+ }
18
+ export interface CanvasCatalogSection {
19
+ readonly id: string;
20
+ readonly order?: number;
21
+ readonly items: readonly WidgetType[];
22
+ }
23
+ export interface CanvasCatalogContribution {
24
+ readonly id: string;
25
+ readonly canvas: CanvasType;
26
+ readonly sections: readonly CanvasCatalogSection[];
27
+ }
28
+ export interface CanvasTypeDef {
29
+ readonly id: string;
30
+ readonly semanticVersion: number;
31
+ readonly semantic: {
32
+ readonly placement: CanvasPlacementDef;
33
+ readonly frameBehaviors?: readonly FrameBehavior[];
34
+ };
35
+ /** Consecutive, view-independent semantic upgrades into semanticVersion. */
36
+ readonly migrations?: readonly CanvasSemanticMigration[];
37
+ readonly presentation?: {
38
+ readonly catalog?: {
39
+ readonly sections: readonly CanvasCatalogSection[];
40
+ };
41
+ readonly tools?: {
42
+ readonly allowed: readonly Tool[];
43
+ readonly default: Tool;
44
+ };
45
+ /**
46
+ * The type DECLARES the desk's ground (design-013 §8 C2; a bare marker since design-015 D7): its one live
47
+ * meaning is that a flight into or out of the type requires the `ground` presentation plane to prepare.
48
+ * The declaration's fields are gone and REFUSED by name at definition time rather than quietly ignored:
49
+ * `program` (C2 — three's GroundProgramDefinition), and at D7 `glyph`, `grid`, `wires` and `guides`, which
50
+ * nothing had read since D5b (the desk's mat is the one ground; its snap guides are marks, always drawn —
51
+ * `guides: false` no longer hid them; the wire overlay left with dom's world-space half).
52
+ */
53
+ readonly ground?: Readonly<Record<string, never>>;
54
+ readonly camera?: {
55
+ readonly arrival?: "fit" | "identity";
56
+ readonly padding?: number;
57
+ readonly minZoom?: number;
58
+ readonly maxZoom?: number;
59
+ };
60
+ readonly runtimeExtensions?: readonly CanvasRuntimeExtension[];
61
+ readonly preview?: CanvasPreviewDeclaration;
62
+ };
63
+ }
64
+ export interface CanvasType extends CanvasTypeDef {
65
+ readonly __canvasType: true;
66
+ }
67
+ export interface CanvasTypeIdentity {
68
+ readonly id: string;
69
+ readonly semanticVersion: number;
70
+ }
71
+ export declare const ROOT_CANVAS_META_KEY = "ice:rootCanvas";
72
+ /** Existing pack-gate namespace reserved for CanvasType semantics. */
73
+ export declare function canvasPackId(id: string): string;
74
+ export declare function canvasIdentityOf(type: CanvasType): CanvasTypeIdentity;
75
+ export declare function sameCanvasIdentity(a: CanvasTypeIdentity | undefined, b: CanvasTypeIdentity | undefined): boolean;
76
+ export declare function encodeCanvasIdentity(identity: CanvasTypeIdentity): string;
77
+ export declare function parseCanvasIdentity(value: unknown): CanvasTypeIdentity | undefined;
78
+ export declare const canvasTypes: {
79
+ get(id: string): CanvasType | undefined;
80
+ all(): CanvasType[];
81
+ };
82
+ export declare function defineCanvasType(def: CanvasTypeDef): CanvasType;
83
+ /** Immutable, explicitly compiled presentation-only catalog contribution. */
84
+ export declare function contributeCanvasCatalog(contribution: CanvasCatalogContribution): CanvasCatalogContribution;
85
+ /** Legacy/default CanvasType. Engine compilation expands placement/catalog. */
86
+ export declare const DefaultCanvasType: CanvasType;
@@ -0,0 +1,17 @@
1
+ /** `defineContainer` — an ordinary WidgetType with one fixed CanvasType portal. */
2
+ import type { CanvasType } from "./define-canvas-type";
3
+ import type { FrameProjection } from "./frame-projection";
4
+ import { type WidgetDef, type WidgetPortalInsets, type WidgetType } from "../widget/define-widget";
5
+ export interface ContainerIngressDef {
6
+ readonly accepts?: readonly string[];
7
+ readonly widgets?: readonly WidgetType[];
8
+ }
9
+ export type ContainerDef = Omit<WidgetDef, "container" | "provides"> & {
10
+ readonly canvas: CanvasType;
11
+ /** Omission inherits the CanvasType's complete compiled legal placement set. */
12
+ readonly drop?: ContainerIngressDef;
13
+ readonly provides?: readonly string[];
14
+ readonly portal?: WidgetPortalInsets;
15
+ readonly frameProjection?: FrameProjection;
16
+ };
17
+ export declare function defineContainer(def: ContainerDef): WidgetType;
@@ -0,0 +1,27 @@
1
+ /** Deterministic, non-mutating diagnostics for remote/legacy frame violations. */
2
+ import { type Entity, type World } from "@vibecook/strata-ecs";
3
+ import type { DurableStore } from "@vibecook/strata-ecs/durable";
4
+ import type { DocVersionReport } from "../doc/version-gate";
5
+ import type { EngineCatalog } from "./engine-catalog";
6
+ export type CanvasDiagnosticCode = "content-without-requirement" | "unknown-widget" | "malformed-parent" | "child-of-cycle" | "depth-limit" | "incompatible-placement";
7
+ export interface CanvasDiagnostic {
8
+ readonly code: CanvasDiagnosticCode;
9
+ readonly key: string;
10
+ readonly entity: Entity;
11
+ readonly frame?: Entity;
12
+ readonly canvasTypeId?: string;
13
+ readonly message: string;
14
+ /** This condition removes document-wide authority rather than locking one row. */
15
+ readonly removesWriteAuthority: boolean;
16
+ }
17
+ export interface CanvasDiagnosticSnapshot {
18
+ readonly diagnostics: readonly CanvasDiagnostic[];
19
+ readonly authorityIssue?: string;
20
+ }
21
+ export declare function collectCanvasDiagnostics(opts: {
22
+ readonly world: World;
23
+ readonly store: DurableStore;
24
+ readonly catalog: EngineCatalog;
25
+ readonly report: DocVersionReport;
26
+ readonly maxDepth?: number;
27
+ }): CanvasDiagnosticSnapshot;
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Immutable, engine-scoped definition authority.
3
+ *
4
+ * Global registries remain definition stores for authoring/HMR. Runtime code
5
+ * resolves through the catalog bound to its World; unbound lower-level test
6
+ * worlds retain the legacy registry fallback.
7
+ */
8
+ import type { World } from "@vibecook/strata-ecs";
9
+ import { type Prefab } from "../schema/prefab";
10
+ import { type Tool } from "../tools/define-tool";
11
+ import { type WidgetType } from "../widget/define-widget";
12
+ import { type CanvasCatalogContribution, type CanvasCatalogSection, type CanvasType } from "./define-canvas-type";
13
+ import { type CanvasRuntimeExtension, type FrameBehavior } from "./extensions";
14
+ import { type FrameProjection } from "./frame-projection";
15
+ export interface EngineCatalogCompileOpts {
16
+ readonly widgets?: readonly {
17
+ readonly type: string;
18
+ }[];
19
+ readonly tools?: readonly Tool[];
20
+ readonly canvasTypes?: readonly CanvasType[];
21
+ readonly rootCanvas?: CanvasType;
22
+ readonly presentationFallback?: CanvasType;
23
+ readonly catalogContributions?: readonly CanvasCatalogContribution[];
24
+ readonly canvasRuntimeExtensions?: readonly CanvasRuntimeExtension[];
25
+ readonly frameBehaviors?: readonly FrameBehavior[];
26
+ readonly frameProjections?: readonly FrameProjection[];
27
+ }
28
+ export interface EngineCatalog {
29
+ readonly typed: boolean;
30
+ readonly rootCanvas: CanvasType;
31
+ readonly presentationFallback: CanvasType;
32
+ widget(id: string): WidgetType | undefined;
33
+ widgetTypes(): readonly WidgetType[];
34
+ tool(id: string): Tool | undefined;
35
+ toolTypes(): readonly Tool[];
36
+ canvasType(id: string): CanvasType | undefined;
37
+ canvasTypeDefs(): readonly CanvasType[];
38
+ runtimeExtension(id: string): CanvasRuntimeExtension | undefined;
39
+ runtimeExtensionsFor(canvasTypeId: string): readonly CanvasRuntimeExtension[];
40
+ frameBehavior(id: string): FrameBehavior | undefined;
41
+ frameBehaviorsFor(canvasTypeId: string): readonly FrameBehavior[];
42
+ frameProjection(id: string): FrameProjection | undefined;
43
+ frameProjectionForContainer(widgetTypeId: string): FrameProjection | undefined;
44
+ canvasForContainer(widgetTypeId: string): CanvasType | undefined;
45
+ placementFor(canvasTypeId: string): ReadonlySet<string>;
46
+ toolsFor(canvasTypeId: string): readonly Tool[];
47
+ defaultToolFor(canvasTypeId: string): Tool;
48
+ catalogFor(canvasTypeId: string): readonly CanvasCatalogSection[];
49
+ /** Every pack/version this engine can interpret while opening a document. */
50
+ localPacks(): Readonly<Record<string, number>>;
51
+ /** Exact capability manifest granted to a newly created document. */
52
+ initialPacks(): Readonly<Record<string, number>>;
53
+ /** Semantic requirement closure keyed by the pack that introduces it. */
54
+ packDependencies(): Readonly<Record<string, Readonly<Record<string, number>>>>;
55
+ /** Requirement closure that must be stamped before this widget can be created. */
56
+ requirementsForWidget(widgetTypeId: string): Readonly<Record<string, number>> | undefined;
57
+ /** A registered widget's DATA prefab by id (design-015 §5.1, D3t-a — the board's strokes): tracked, stamped and gated with the widget. */
58
+ dataPrefab(id: string): Prefab | undefined;
59
+ }
60
+ export declare function compileEngineCatalog(opts?: EngineCatalogCompileOpts): EngineCatalog;
61
+ export declare function bindEngineCatalog(world: World, catalog: EngineCatalog): () => void;
62
+ export declare function engineCatalogFor(world: World): EngineCatalog | undefined;
63
+ export declare function widgetTypeFor(world: World, id: string): WidgetType | undefined;
64
+ export declare function toolTypeFor(world: World, id: string): Tool | undefined;
65
+ /** Unknown tools retain select semantics only in unbound legacy worlds. */
66
+ export declare function resolveToolFor(world: World, id: string): Tool;
67
+ /** Engine-scoped durable prefab resolution for transaction/live-write guards. */
68
+ export declare function durablePrefabFor(world: World, id: string): Prefab | undefined;
69
+ /** A DATA prefab the engine tracks (an object's `data` — D3t-a), or, in an unbound legacy world, any registered durable prefab that is no widget's. */
70
+ export declare function dataPrefabFor(world: World, id: string): Prefab | undefined;