@vibecook/ice 0.11.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.
- package/README.md +79 -50
- package/dist/chunk-BA7XJC27.js +2429 -0
- package/dist/chunk-BA7XJC27.js.map +1 -0
- package/dist/chunk-BKV4ZEU3.js +1 -0
- package/dist/chunk-BKV4ZEU3.js.map +1 -0
- package/dist/{chunk-VGVDJZSP.js → chunk-DYK6KNLG.js} +13206 -7387
- package/dist/chunk-DYK6KNLG.js.map +1 -0
- package/dist/chunk-ENIFIUEP.js +155 -0
- package/dist/chunk-ENIFIUEP.js.map +1 -0
- package/dist/chunk-IBWWLA6D.js +634 -0
- package/dist/chunk-IBWWLA6D.js.map +1 -0
- package/dist/{chunk-OR5FNVUE.js → chunk-JS6PG6YD.js} +398 -167
- package/dist/chunk-JS6PG6YD.js.map +1 -0
- package/dist/chunk-QXOCF56A.js +148 -0
- package/dist/chunk-QXOCF56A.js.map +1 -0
- package/dist/chunk-ZPUPBULB.js +7399 -0
- package/dist/chunk-ZPUPBULB.js.map +1 -0
- package/dist/desk-engine.js +36 -0
- package/dist/desk-engine.js.map +1 -0
- package/dist/desk-kit.js +244 -0
- package/dist/desk-kit.js.map +1 -0
- package/dist/desk-objects.js +12728 -0
- package/dist/desk-objects.js.map +1 -0
- package/dist/desk.js +469 -0
- package/dist/desk.js.map +1 -0
- package/dist/devtools.js +233 -189
- package/dist/devtools.js.map +1 -1
- package/dist/dom.js +7 -19
- package/dist/index.js +232 -20
- package/dist/kernel.js +53 -25
- package/dist/react.js +1045 -38
- package/dist/react.js.map +1 -1
- package/dist/types/packages/core/src/behavior/define-behavior.d.ts +11 -0
- package/dist/types/packages/core/src/behavior/runtime.d.ts +4 -0
- package/dist/types/packages/core/src/canvas/define-canvas-type.d.ts +86 -0
- package/dist/types/packages/core/src/canvas/define-container.d.ts +17 -0
- package/dist/types/packages/core/src/canvas/diagnostics.d.ts +27 -0
- package/dist/types/packages/core/src/canvas/engine-catalog.d.ts +70 -0
- package/dist/types/packages/core/src/canvas/extensions.d.ts +125 -0
- package/dist/types/packages/core/src/canvas/frame-behavior-host.d.ts +16 -0
- package/dist/types/packages/core/src/canvas/frame-preview.d.ts +79 -0
- package/dist/types/packages/core/src/canvas/frame-projection.d.ts +38 -0
- package/dist/types/packages/core/src/canvas/frame-view.d.ts +36 -0
- package/dist/types/packages/core/src/canvas/migrate.d.ts +14 -0
- package/dist/types/packages/core/src/canvas/placement.d.ts +30 -0
- package/dist/types/packages/core/src/canvas/presentation-transition.d.ts +100 -0
- package/dist/types/packages/core/src/canvas/runtime-extension-host.d.ts +16 -0
- package/dist/types/packages/core/src/canvas/session.d.ts +47 -0
- package/dist/types/packages/core/src/catalog/camera-derived.d.ts +16 -27
- package/dist/types/packages/core/src/catalog/desk.d.ts +326 -0
- package/dist/types/packages/core/src/catalog/gesture.d.ts +51 -0
- package/dist/types/packages/core/src/catalog/graph.d.ts +2 -2
- package/dist/types/packages/core/src/catalog/index.d.ts +2 -0
- package/dist/types/packages/core/src/catalog/pointer.d.ts +42 -0
- package/dist/types/packages/core/src/catalog/selection-presence.d.ts +7 -0
- package/dist/types/packages/core/src/catalog/settings-resources.d.ts +28 -2
- package/dist/types/packages/core/src/catalog/surface.d.ts +1 -0
- package/dist/types/packages/core/src/doc/doc-commit-sink.d.ts +18 -2
- package/dist/types/packages/core/src/doc/doc-kit.d.ts +21 -2
- package/dist/types/packages/core/src/doc/envelope.d.ts +5 -2
- package/dist/types/packages/core/src/doc/schema-migrate.d.ts +1 -1
- package/dist/types/packages/core/src/doc/version-gate.d.ts +21 -3
- package/dist/types/packages/core/src/engine/commit-sink.d.ts +10 -1
- package/dist/types/packages/core/src/engine/engine.d.ts +6 -0
- package/dist/types/packages/core/src/engine/frame-control.d.ts +74 -0
- package/dist/types/packages/core/src/engine/guests.d.ts +4 -1
- package/dist/types/packages/core/src/engine/world-doors.d.ts +12 -0
- package/dist/types/packages/core/src/facade/create-canvas-engine.d.ts +146 -13
- package/dist/types/packages/core/src/index.d.ts +33 -12
- package/dist/types/packages/core/src/input/queue.d.ts +3 -1
- package/dist/types/packages/core/src/interaction/install.d.ts +30 -0
- package/dist/types/packages/core/src/interaction/wakes.d.ts +24 -0
- package/dist/types/packages/core/src/nav/nav-geometry.d.ts +100 -0
- package/dist/types/packages/core/src/nav/nested-canvas.d.ts +47 -4
- package/dist/types/packages/core/src/ops/cascade.d.ts +2 -1
- package/dist/types/packages/core/src/ops/claims.d.ts +6 -0
- package/dist/types/packages/core/src/ops/insert.d.ts +4 -0
- package/dist/types/packages/core/src/ops/point-pick.d.ts +4 -1
- package/dist/types/packages/core/src/ops/sibling-order.d.ts +14 -4
- package/dist/types/packages/core/src/ops/tray.d.ts +48 -0
- package/dist/types/packages/core/src/presence/presence-kit.d.ts +5 -0
- package/dist/types/packages/core/src/schema/meta.d.ts +10 -0
- package/dist/types/packages/core/src/schema/prefab.d.ts +8 -0
- package/dist/types/packages/core/src/settings/defaults.d.ts +25 -6
- package/dist/types/packages/core/src/surface/gpu-device.d.ts +55 -0
- package/dist/types/packages/core/src/systems/camera-sim.d.ts +29 -0
- package/dist/types/packages/core/src/systems/chrome.d.ts +15 -23
- package/dist/types/packages/core/src/systems/drag-mods.d.ts +34 -0
- package/dist/types/packages/core/src/systems/held.d.ts +71 -0
- package/dist/types/packages/core/src/systems/insert-ghost.d.ts +2 -0
- package/dist/types/packages/core/src/systems/l0-input.d.ts +14 -0
- package/dist/types/packages/core/src/systems/l1-pick.d.ts +37 -1
- package/dist/types/packages/core/src/systems/l2-arbitrate.d.ts +18 -4
- package/dist/types/packages/core/src/systems/l3-behave.d.ts +4 -1
- package/dist/types/packages/core/src/systems/l3-claim.d.ts +7 -0
- package/dist/types/packages/core/src/systems/l3-connect.d.ts +1 -1
- package/dist/types/packages/core/src/systems/l3-drop.d.ts +30 -1
- package/dist/types/packages/core/src/systems/l3-marquee.d.ts +2 -1
- package/dist/types/packages/core/src/systems/l3-ports.d.ts +1 -1
- package/dist/types/packages/core/src/systems/l4-cursor.d.ts +5 -0
- package/dist/types/packages/core/src/systems/nav-flight.d.ts +85 -3
- package/dist/types/packages/core/src/systems/nav-tap.d.ts +44 -0
- package/dist/types/packages/core/src/systems/press-wheel.d.ts +11 -0
- package/dist/types/packages/core/src/systems/tray.d.ts +108 -0
- package/dist/types/packages/core/src/systems/zoom-through.d.ts +30 -0
- package/dist/types/packages/core/src/tools/define-tool.d.ts +10 -0
- package/dist/types/packages/core/src/widget/define-widget.d.ts +166 -63
- package/dist/types/packages/core/src/widget/equip.d.ts +14 -2
- package/dist/types/packages/core/src/widget/held-tools.d.ts +83 -0
- package/dist/types/packages/core/src/widget/menu-actions.d.ts +44 -0
- package/dist/types/packages/core/src/widget/mount-store.d.ts +21 -46
- package/dist/types/packages/core/src/widget/spawn.d.ts +1 -1
- package/dist/types/packages/desk/src/assets/blue-noise.gen.d.ts +10 -0
- package/dist/types/packages/desk/src/card/card.d.ts +103 -0
- package/dist/types/packages/desk/src/compose/ambient.d.ts +59 -0
- package/dist/types/packages/desk/src/compose/builder.d.ts +285 -0
- package/dist/types/packages/desk/src/compose/children.d.ts +3 -0
- package/dist/types/packages/desk/src/compose/index.d.ts +14 -0
- package/dist/types/packages/desk/src/compose/marks.d.ts +126 -0
- package/dist/types/packages/desk/src/compose/pick.d.ts +5 -0
- package/dist/types/packages/desk/src/compose/reflector.d.ts +111 -0
- package/dist/types/packages/desk/src/compose/tap.d.ts +5 -0
- package/dist/types/packages/desk/src/docs.d.ts +23 -0
- package/dist/types/packages/desk/src/engine/budget.d.ts +38 -0
- package/dist/types/packages/desk/src/engine/device.d.ts +54 -0
- package/dist/types/packages/desk/src/engine/index.d.ts +5 -0
- package/dist/types/packages/desk/src/engine/pipeline.d.ts +36 -0
- package/dist/types/packages/desk/src/engine/rasters.d.ts +66 -0
- package/dist/types/packages/desk/src/engine/records.d.ts +56 -0
- package/dist/types/packages/desk/src/engine/shader.d.ts +22 -0
- package/dist/types/packages/desk/src/engine/struct.d.ts +39 -0
- package/dist/types/packages/desk/src/engine/target.d.ts +26 -0
- package/dist/types/packages/desk/src/gpu-ablation.d.ts +61 -0
- package/dist/types/packages/desk/src/gpu-memory.d.ts +54 -0
- package/dist/types/packages/desk/src/gpu-profiler.d.ts +141 -0
- package/dist/types/packages/desk/src/gpu-wrap.d.ts +8 -0
- package/dist/types/packages/desk/src/ground.d.ts +388 -0
- package/dist/types/packages/desk/src/hold/focus.d.ts +53 -0
- package/dist/types/packages/desk/src/hold/pose.d.ts +132 -0
- package/dist/types/packages/desk/src/hold/shaders.d.ts +9 -0
- package/dist/types/packages/desk/src/host/editor.d.ts +18 -0
- package/dist/types/packages/desk/src/host/index.d.ts +9 -0
- package/dist/types/packages/desk/src/host/ink.d.ts +18 -0
- package/dist/types/packages/desk/src/host/layer.d.ts +430 -0
- package/dist/types/packages/desk/src/host/picture.d.ts +2 -0
- package/dist/types/packages/desk/src/host/surface.d.ts +5 -0
- package/dist/types/packages/desk/src/index.d.ts +13 -0
- package/dist/types/packages/desk/src/kind.d.ts +187 -0
- package/dist/types/packages/desk/src/kinds/world.d.ts +429 -0
- package/dist/types/packages/desk/src/kit/arrays.d.ts +88 -0
- package/dist/types/packages/desk/src/kit/blobs.d.ts +40 -0
- package/dist/types/packages/desk/src/kit/book.d.ts +2 -0
- package/dist/types/packages/desk/src/kit/editor.d.ts +103 -0
- package/dist/types/packages/desk/src/kit/eye.d.ts +37 -0
- package/dist/types/packages/desk/src/kit/hold.d.ts +1 -0
- package/dist/types/packages/desk/src/kit/index.d.ts +26 -0
- package/dist/types/packages/desk/src/kit/inside.d.ts +116 -0
- package/dist/types/packages/desk/src/kit/layer.d.ts +159 -0
- package/dist/types/packages/desk/src/kit/light.d.ts +3 -0
- package/dist/types/packages/desk/src/kit/mesh.d.ts +29 -0
- package/dist/types/packages/desk/src/kit/mips.d.ts +2 -0
- package/dist/types/packages/desk/src/kit/nav.d.ts +2 -0
- package/dist/types/packages/desk/src/kit/paper-tex.d.ts +5 -0
- package/dist/types/packages/desk/src/kit/physics.d.ts +44 -0
- package/dist/types/packages/desk/src/kit/place.d.ts +44 -0
- package/dist/types/packages/desk/src/kit/print.d.ts +30 -0
- package/dist/types/packages/desk/src/kit/raster.d.ts +34 -0
- package/dist/types/packages/desk/src/kit/sdf.d.ts +1 -0
- package/dist/types/packages/desk/src/kit/seeds.d.ts +11 -0
- package/dist/types/packages/desk/src/kit/services.d.ts +34 -0
- package/dist/types/packages/desk/src/kit/springs.d.ts +12 -0
- package/dist/types/packages/desk/src/kit/strokes.d.ts +93 -0
- package/dist/types/packages/desk/src/kit/text.d.ts +142 -0
- package/dist/types/packages/desk/src/kit/uniform.d.ts +8 -0
- package/dist/types/packages/desk/src/kit/view.d.ts +39 -0
- package/dist/types/packages/desk/src/kit/wgsl.d.ts +15 -0
- package/dist/types/packages/desk/src/lattice/line.d.ts +15 -0
- package/dist/types/packages/desk/src/lattice/lod.d.ts +52 -0
- package/dist/types/packages/desk/src/lattice/ruler.d.ts +88 -0
- package/dist/types/packages/desk/src/marks/assemble.d.ts +65 -0
- package/dist/types/packages/desk/src/marks/ease.d.ts +4 -0
- package/dist/types/packages/desk/src/marks/laser.d.ts +41 -0
- package/dist/types/packages/desk/src/marks/layout.d.ts +167 -0
- package/dist/types/packages/desk/src/marks/pass.d.ts +59 -0
- package/dist/types/packages/desk/src/marks/shaders.d.ts +12 -0
- package/dist/types/packages/desk/src/mat/grid.d.ts +50 -0
- package/dist/types/packages/desk/src/mat/lamp.d.ts +14 -0
- package/dist/types/packages/desk/src/mat/layout.d.ts +144 -0
- package/dist/types/packages/desk/src/mat/mat-pass.d.ts +83 -0
- package/dist/types/packages/desk/src/mat/night.d.ts +95 -0
- package/dist/types/packages/desk/src/mat/projector.d.ts +39 -0
- package/dist/types/packages/desk/src/mat/shaders.d.ts +17 -0
- package/dist/types/packages/desk/src/mat/tilt.d.ts +14 -0
- package/dist/types/packages/desk/src/nav/flight.d.ts +186 -0
- package/dist/types/packages/desk/src/nav/portal.d.ts +95 -0
- package/dist/types/packages/desk/src/object.d.ts +46 -0
- package/dist/types/packages/desk/src/pass-instrument.d.ts +89 -0
- package/dist/types/packages/desk/src/shaders.d.ts +12 -0
- package/dist/types/packages/desk/src/shaders.gen.d.ts +16 -0
- package/dist/types/packages/desk/src/submit-instrument.d.ts +36 -0
- package/dist/types/packages/desk/src/theme.d.ts +475 -0
- package/dist/types/packages/desk/src/tray/carry.d.ts +99 -0
- package/dist/types/packages/desk/src/tray/drawer.d.ts +113 -0
- package/dist/types/packages/desk/src/tray/flux.d.ts +46 -0
- package/dist/types/packages/desk/src/tray/index.d.ts +4 -0
- package/dist/types/packages/desk/src/tray/lattice.d.ts +71 -0
- package/dist/types/packages/desk/src/tray/layout.d.ts +7 -0
- package/dist/types/packages/desk/src/tray/look.d.ts +29 -0
- package/dist/types/packages/desk/src/tray/pass.d.ts +96 -0
- package/dist/types/packages/desk/src/tray/shaders.d.ts +10 -0
- package/dist/types/packages/desk/src/tray/specimens.d.ts +199 -0
- package/dist/types/packages/devtools/src/attach.d.ts +22 -8
- package/dist/types/packages/devtools/src/dock.d.ts +18 -14
- package/dist/types/packages/devtools/src/gpu-panel.d.ts +105 -0
- package/dist/types/packages/devtools/src/index.d.ts +5 -4
- package/dist/types/packages/dom/src/desk-host.d.ts +91 -0
- package/dist/types/packages/dom/src/host.d.ts +13 -14
- package/dist/types/packages/dom/src/index.d.ts +12 -10
- package/dist/types/packages/dom/src/loop.d.ts +18 -1
- package/dist/types/packages/dom/src/pointer-adapter.d.ts +5 -29
- package/dist/types/packages/dom/src/widget-focus.d.ts +17 -13
- package/dist/types/packages/ice/src/desk-engine.d.ts +2 -0
- package/dist/types/packages/ice/src/desk-kit.d.ts +6 -0
- package/dist/types/packages/ice/src/desk-objects.d.ts +5 -0
- package/dist/types/packages/ice/src/desk.d.ts +5 -0
- package/dist/types/packages/kernel/src/atlas-pack.d.ts +157 -0
- package/dist/types/packages/kernel/src/bezier.d.ts +0 -15
- package/dist/types/packages/kernel/src/coords.d.ts +0 -39
- package/dist/types/packages/kernel/src/index.d.ts +2 -2
- package/dist/types/packages/kernel/src/nav-flight.d.ts +6 -0
- package/dist/types/packages/kernel/src/tray.d.ts +155 -0
- package/dist/types/packages/objects/src/board/board-pass.d.ts +180 -0
- package/dist/types/packages/objects/src/board/board-pen.d.ts +36 -0
- package/dist/types/packages/objects/src/board/board.d.ts +104 -0
- package/dist/types/packages/objects/src/board/data.d.ts +31 -0
- package/dist/types/packages/objects/src/board/history.d.ts +33 -0
- package/dist/types/packages/objects/src/board/kind.d.ts +208 -0
- package/dist/types/packages/objects/src/board/layout.d.ts +102 -0
- package/dist/types/packages/objects/src/board/object.d.ts +7 -0
- package/dist/types/packages/objects/src/board/pen.d.ts +71 -0
- package/dist/types/packages/objects/src/board/shaders.d.ts +36 -0
- package/dist/types/packages/objects/src/board/stroke.d.ts +99 -0
- package/dist/types/packages/objects/src/board/theme.d.ts +150 -0
- package/dist/types/packages/objects/src/calendar/data.d.ts +97 -0
- package/dist/types/packages/objects/src/calendar/events.d.ts +58 -0
- package/dist/types/packages/objects/src/calendar/hand.d.ts +53 -0
- package/dist/types/packages/objects/src/calendar/host/input.d.ts +67 -0
- package/dist/types/packages/objects/src/calendar/host/print.d.ts +9 -0
- package/dist/types/packages/objects/src/calendar/kind.d.ts +297 -0
- package/dist/types/packages/objects/src/calendar/law.d.ts +151 -0
- package/dist/types/packages/objects/src/calendar/layout.d.ts +47 -0
- package/dist/types/packages/objects/src/calendar/month.d.ts +75 -0
- package/dist/types/packages/objects/src/calendar/object.d.ts +45 -0
- package/dist/types/packages/objects/src/calendar/pad.d.ts +42 -0
- package/dist/types/packages/objects/src/calendar/pass.d.ts +229 -0
- package/dist/types/packages/objects/src/calendar/print.d.ts +87 -0
- package/dist/types/packages/objects/src/calendar/printing.d.ts +80 -0
- package/dist/types/packages/objects/src/calendar/roll.d.ts +45 -0
- package/dist/types/packages/objects/src/calendar/shaders.d.ts +12 -0
- package/dist/types/packages/objects/src/calendar/sheet.d.ts +43 -0
- package/dist/types/packages/objects/src/calendar/tiles.d.ts +67 -0
- package/dist/types/packages/objects/src/calendar/turn.d.ts +73 -0
- package/dist/types/packages/objects/src/calendar/writing.d.ts +42 -0
- package/dist/types/packages/objects/src/index.d.ts +22 -0
- package/dist/types/packages/objects/src/kinds.d.ts +24 -0
- package/dist/types/packages/objects/src/minimat/inside.d.ts +17 -0
- package/dist/types/packages/objects/src/minimat/kind.d.ts +51 -0
- package/dist/types/packages/objects/src/minimat/layout.d.ts +83 -0
- package/dist/types/packages/objects/src/minimat/minimat.d.ts +179 -0
- package/dist/types/packages/objects/src/minimat/object.d.ts +8 -0
- package/dist/types/packages/objects/src/minimat/pass.d.ts +61 -0
- package/dist/types/packages/objects/src/minimat/shaders.d.ts +10 -0
- package/dist/types/packages/objects/src/minimat/theme.d.ts +98 -0
- package/dist/types/packages/objects/src/notebook/ink.d.ts +70 -0
- package/dist/types/packages/objects/src/notebook/kind.d.ts +236 -0
- package/dist/types/packages/objects/src/notebook/law.d.ts +129 -0
- package/dist/types/packages/objects/src/notebook/layout.d.ts +46 -0
- package/dist/types/packages/objects/src/notebook/leaf.d.ts +44 -0
- package/dist/types/packages/objects/src/notebook/mesh.d.ts +20 -0
- package/dist/types/packages/objects/src/notebook/motion.d.ts +107 -0
- package/dist/types/packages/objects/src/notebook/object.d.ts +8 -0
- package/dist/types/packages/objects/src/notebook/pages.d.ts +56 -0
- package/dist/types/packages/objects/src/notebook/pass.d.ts +197 -0
- package/dist/types/packages/objects/src/notebook/pick.d.ts +30 -0
- package/dist/types/packages/objects/src/notebook/raster.d.ts +28 -0
- package/dist/types/packages/objects/src/notebook/shaders.d.ts +11 -0
- package/dist/types/packages/objects/src/notebook/shape.d.ts +155 -0
- package/dist/types/packages/objects/src/notebook/theme.d.ts +76 -0
- package/dist/types/packages/objects/src/palette.d.ts +577 -0
- package/dist/types/packages/objects/src/paper/host/body.d.ts +30 -0
- package/dist/types/packages/objects/src/paper/kind.d.ts +81 -0
- package/dist/types/packages/objects/src/paper/layout.d.ts +73 -0
- package/dist/types/packages/objects/src/paper/object.d.ts +31 -0
- package/dist/types/packages/objects/src/paper/pages.d.ts +43 -0
- package/dist/types/packages/objects/src/paper/paper-pass.d.ts +86 -0
- package/dist/types/packages/objects/src/paper/paper.d.ts +117 -0
- package/dist/types/packages/objects/src/paper/shaders.d.ts +18 -0
- package/dist/types/packages/objects/src/paper/theme.d.ts +58 -0
- package/dist/types/packages/objects/src/paper/typing.d.ts +51 -0
- package/dist/types/packages/objects/src/paper/writing.d.ts +161 -0
- package/dist/types/packages/objects/src/photo/carry.d.ts +33 -0
- package/dist/types/packages/objects/src/photo/kind.d.ts +136 -0
- package/dist/types/packages/objects/src/photo/layout.d.ts +39 -0
- package/dist/types/packages/objects/src/photo/object.d.ts +5 -0
- package/dist/types/packages/objects/src/photo/photo-pass.d.ts +104 -0
- package/dist/types/packages/objects/src/photo/photo.d.ts +262 -0
- package/dist/types/packages/objects/src/photo/pictures.d.ts +152 -0
- package/dist/types/packages/objects/src/photo/sample.d.ts +9 -0
- package/dist/types/packages/objects/src/photo/shaders.d.ts +18 -0
- package/dist/types/packages/objects/src/preset.d.ts +44 -0
- package/dist/types/packages/objects/src/shaders.d.ts +3 -0
- package/dist/types/packages/objects/src/shaders.gen.d.ts +21 -0
- package/dist/types/packages/react/src/canvas-hooks.d.ts +12 -0
- package/dist/types/packages/react/src/desk.d.ts +56 -0
- package/dist/types/packages/react/src/engine-context.d.ts +2 -2
- package/dist/types/packages/react/src/frame-preview-boundary.d.ts +19 -0
- package/dist/types/packages/react/src/hooks.d.ts +9 -14
- package/dist/types/packages/react/src/index.d.ts +16 -9
- package/dist/types/packages/react/src/keymap.d.ts +21 -2
- package/dist/types/packages/react/src/selection-menu.d.ts +171 -0
- package/dist/types/packages/react/src/tray-bar.d.ts +124 -0
- package/package.json +64 -31
- package/dist/chunk-2TNVB2ON.js +0 -1163
- package/dist/chunk-2TNVB2ON.js.map +0 -1
- package/dist/chunk-OR5FNVUE.js.map +0 -1
- package/dist/chunk-Q665T4L7.js +0 -681
- package/dist/chunk-Q665T4L7.js.map +0 -1
- package/dist/chunk-VGVDJZSP.js.map +0 -1
- package/dist/ground.js +0 -1108
- package/dist/ground.js.map +0 -1
- package/dist/r3f.js +0 -1644
- package/dist/r3f.js.map +0 -1
- package/dist/types/packages/core/src/input/measure-queue.d.ts +0 -30
- package/dist/types/packages/core/src/settings/ground-config.d.ts +0 -101
- package/dist/types/packages/core/src/systems/measure-ingest.d.ts +0 -26
- package/dist/types/packages/devtools/src/gl-panel.d.ts +0 -69
- package/dist/types/packages/dom/src/measure-adapter.d.ts +0 -31
- package/dist/types/packages/dom/src/measure-wiring.d.ts +0 -49
- package/dist/types/packages/dom/src/planes.d.ts +0 -33
- package/dist/types/packages/dom/src/reflectors/chrome.d.ts +0 -33
- package/dist/types/packages/dom/src/reflectors/dom-widgets.d.ts +0 -59
- package/dist/types/packages/dom/src/reflectors/graybox.d.ts +0 -31
- package/dist/types/packages/dom/src/reflectors/plane-transform.d.ts +0 -38
- package/dist/types/packages/ground/src/index.d.ts +0 -69
- package/dist/types/packages/ground/src/layer.d.ts +0 -40
- package/dist/types/packages/ground/src/pass.d.ts +0 -41
- package/dist/types/packages/ground/src/passes/grid-contract.d.ts +0 -28
- package/dist/types/packages/ground/src/passes/grid-magnet-pass.d.ts +0 -2
- package/dist/types/packages/ground/src/passes/grid-magnet.d.ts +0 -31
- package/dist/types/packages/ground/src/passes/grid.d.ts +0 -10
- package/dist/types/packages/ground/src/passes/guides-collect.d.ts +0 -14
- package/dist/types/packages/ground/src/passes/guides.d.ts +0 -3
- package/dist/types/packages/ground/src/passes/magnet-collect.d.ts +0 -63
- package/dist/types/packages/ground/src/passes/soup-collect.d.ts +0 -35
- package/dist/types/packages/ground/src/passes/soup-mesh.d.ts +0 -8
- package/dist/types/packages/ground/src/passes/wires-collect.d.ts +0 -35
- package/dist/types/packages/ground/src/passes/wires.d.ts +0 -10
- package/dist/types/packages/ground/src/poles.d.ts +0 -47
- package/dist/types/packages/ground/src/renderer.d.ts +0 -15
- package/dist/types/packages/ice/src/ground.d.ts +0 -1
- package/dist/types/packages/ice/src/r3f.d.ts +0 -1
- package/dist/types/packages/kernel/src/eviction.d.ts +0 -23
- package/dist/types/packages/kernel/src/zoom-bands.d.ts +0 -19
- package/dist/types/packages/r3f/src/bridge.d.ts +0 -129
- package/dist/types/packages/r3f/src/composite-material.d.ts +0 -26
- package/dist/types/packages/r3f/src/compositor-pass.d.ts +0 -105
- package/dist/types/packages/r3f/src/dev-write-trap.d.ts +0 -30
- package/dist/types/packages/r3f/src/gl-root.d.ts +0 -96
- package/dist/types/packages/r3f/src/gl-router.d.ts +0 -70
- package/dist/types/packages/r3f/src/index.d.ts +0 -17
- package/dist/types/packages/r3f/src/island-state.d.ts +0 -112
- package/dist/types/packages/r3f/src/island.d.ts +0 -13
- package/dist/types/packages/r3f/src/pool.d.ts +0 -56
- package/dist/types/packages/r3f/src/preview-capture.d.ts +0 -19
- package/dist/types/packages/r3f/src/resource-registry.d.ts +0 -30
- package/dist/types/packages/r3f/src/self-sustain.d.ts +0 -39
- package/dist/types/packages/r3f/src/use-island-frame.d.ts +0 -39
- package/dist/types/packages/react/src/infinite-canvas.d.ts +0 -140
- package/dist/types/packages/react/src/preview-snapshots.d.ts +0 -17
- package/dist/types/packages/react/src/widget-preview.d.ts +0 -14
- package/dist/types/packages/react/src/widget-root.d.ts +0 -33
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../dom/src/host.ts","../../dom/src/planes.ts","../../dom/src/reflectors/plane-transform.ts","../../dom/src/reflectors/graybox.ts","../../dom/src/input-ownership.ts","../../dom/src/reflectors/dom-widgets.ts","../../dom/src/loop.ts","../../dom/src/pointer-adapter.ts","../../dom/src/widget-focus.ts","../../dom/src/reflectors/cursor.ts","../../dom/src/reflectors/remote-cursors.ts","../../dom/src/reflectors/chrome.ts","../../dom/src/measure-adapter.ts","../../dom/src/measure-wiring.ts","../../dom/src/index.ts"],"sourcesContent":["/**\n * The DOM canvas host (design-004 §1, host pipeline — M3 slice).\n *\n * M3 stands up ONE content plane: an absolutely-positioned div whose single CSS\n * transform (written by the plane-transform reflector) applies the camera to\n * every world-positioned child at once (design-002 §5 `planeTransform`; kernel\n * `planeCssTransform`). The full six-plane model (background/content/overlay/\n * chrome/HUD/nav + the FBO compositor) arrives in M6 — this file is deliberately\n * the minimum that lets a reflector paint into a camera-transformed space.\n *\n * The container is styled to be a stable, gesture-clean viewport: `relative` so\n * the absolute plane anchors to it, `overflow:hidden` to clip the infinite\n * plane, `touch-action:none` + `user-select:none` so browser scroll/zoom and\n * text selection never fight the interaction stack.\n */\n\nexport interface CanvasHost {\n /** The app-provided viewport element (styled, not created, by the host). */\n readonly container: HTMLElement;\n /** The single camera-transformed plane; world-positioned children mount here. */\n readonly contentPlane: HTMLDivElement;\n /** Remove the plane and clear the inline styles the host wrote. */\n dispose(): void;\n}\n\n/** The container styles the host owns unconditionally (cleared on dispose). */\nconst CONTAINER_STYLE: Readonly<Record<string, string>> = {\n overflow: \"hidden\",\n touchAction: \"none\",\n userSelect: \"none\",\n};\n\n/** The content-plane styles: origin-anchored, transform-ready (design-002 §5). */\nconst PLANE_STYLE: Readonly<Record<string, string>> = {\n position: \"absolute\",\n left: \"0\",\n top: \"0\",\n transformOrigin: \"0 0\",\n willChange: \"transform\",\n};\n\nexport function createCanvasHost(container: HTMLElement): CanvasHost {\n // The plane needs the container to be a POSITIONED containing block — but\n // `absolute`/`fixed` already qualify, so only promote a `static` container\n // to `relative`. Stomping an app's `position: absolute` with inline\n // `relative` collapses the common `#app { position: absolute; inset: 0 }`\n // sizing pattern to zero height (inset offsets a relative box, it does not\n // size it), and the host's own overflow:hidden then clips everything.\n // Inline style first (authoritative and environment-independent), computed\n // second (catches stylesheet rules like `#app { position: absolute }`).\n const view = container.ownerDocument.defaultView;\n const position =\n container.style.position !== \"\"\n ? container.style.position\n : (view?.getComputedStyle(container).position ?? \"\");\n const promoteToRelative = position === \"\" || position === \"static\";\n if (promoteToRelative) container.style.position = \"relative\";\n // Record each host-owned property's prior inline value BEFORE overwriting it,\n // so dispose restores what the caller set (e.g. an inline overflow:auto) rather\n // than blanket-clearing it. Empty string = the caller had no inline value here.\n const priorContainerStyle = Object.keys(CONTAINER_STYLE).map((prop) => {\n // camelCase → kebab-case for the CSSOM property API (touchAction → touch-action).\n const cssName = prop.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);\n return [cssName, container.style.getPropertyValue(cssName)] as const;\n });\n Object.assign(container.style, CONTAINER_STYLE);\n\n const contentPlane = container.ownerDocument.createElement(\"div\");\n Object.assign(contentPlane.style, PLANE_STYLE);\n container.appendChild(contentPlane);\n\n return {\n container,\n contentPlane,\n dispose() {\n contentPlane.remove();\n if (promoteToRelative) container.style.removeProperty(\"position\");\n for (const [cssName, prior] of priorContainerStyle) {\n // Restore the caller's prior inline value, or clear the host's if the\n // caller had none.\n if (prior !== \"\") container.style.setProperty(cssName, prior);\n else container.style.removeProperty(cssName);\n }\n },\n };\n}\n","/**\n * The lifted plane (design-004 §1, planes P1/P3 — M6 slice).\n *\n * M3 stood up ONE camera-transformed content plane (`host.ts`, P1). M6 adds P3,\n * the **lifted** plane: a second transform-origin-0-0 div appended to the\n * container AFTER the content plane, so it stacks ABOVE it (P3 over P1) with no\n * z-index bookkeeping — DOM order is the strata order (§1: \"stacking is\n * stratified\"). Both planes take the SAME single camera transform (the\n * plane-transform reflector writes both), so a promoted widget re-parented\n * content→lifted keeps its world position; it just paints above the content\n * layer for the duration of the drag.\n *\n * `createCanvasHost` is intentionally untouched: the content plane it owns is\n * the P1 authority. `createPlanes` is additive — it borrows that content plane\n * and mints the lifted sibling next to it.\n */\nimport type { CanvasHost } from \"./host\";\n\n/** The two DOM planes M6 addresses: P1 content (host-owned) + P3 lifted. */\nexport interface Planes {\n /** P1: the host's camera-transformed content plane; world-positioned hosts mount here. */\n readonly content: HTMLDivElement;\n /** P3: camera-transformed, stacked above content; promoted (dragged) hosts re-parent here. */\n readonly lifted: HTMLDivElement;\n /** Remove the lifted plane (the content plane is the host's — host.dispose reaps it). */\n dispose(): void;\n}\n\n/**\n * The lifted-plane styles — identical to the content plane's (origin-anchored,\n * transform-ready). Re-declared here rather than reaching into `host.ts` so that\n * file stays the sole owner of the content plane and nothing it exports moves.\n */\nconst LIFTED_PLANE_STYLE: Readonly<Record<string, string>> = {\n position: \"absolute\",\n left: \"0\",\n top: \"0\",\n transformOrigin: \"0 0\",\n willChange: \"transform\",\n // The ONE explicit z in the plane sandwich (2026-07-19): in-container app\n // chrome may slot BETWEEN the planes with z-index 1 — resting widgets\n // slide under it while the dragged (promoted) widget floats over it. DOM\n // order alone leaves no gap for that; everything else stays order-stacked.\n zIndex: \"2\",\n};\n\n/**\n * Mint the lifted plane next to the host's content plane. The lifted div is\n * appended to the container AFTER the content plane, so it renders above it\n * (P3 > P1). Returns both planes for the plane-transform reflector (writes both)\n * and the dom-widgets reflector (re-parents hosts between them on drag-promote).\n */\nexport function createPlanes(host: CanvasHost): Planes {\n const lifted = host.container.ownerDocument.createElement(\"div\");\n Object.assign(lifted.style, LIFTED_PLANE_STYLE);\n host.container.appendChild(lifted); // after contentPlane ⇒ P3 stacks above P1\n return {\n content: host.contentPlane,\n lifted,\n // Without this a React StrictMode remount stacks a second P3\n // (2026-07-11 reflector-teardown sweep, with the grid-canvas fix).\n dispose() {\n lifted.remove();\n },\n };\n}\n","/**\n * The plane-transform reflector (design-002 §5 `planeTransform`; M3 exit gate,\n * widened for the M6 lifted plane).\n *\n * Observes the `Camera` RESOURCE and nothing else. Each flush reads the camera,\n * derives the ONE per-plane CSS transform via kernel `planeCssTransform` (the\n * sole owner of that math — Law 13), and writes it to EVERY camera-transformed\n * DOM plane in a SINGLE `style.transform` assignment each. Panning the whole\n * canvas is therefore O(1) in the DOM: one transform write per plane per moving\n * frame, independent of node count — the property that makes an infinite canvas\n * of 10k gray boxes pan at frame rate.\n *\n * The input is widened to `{ contentPlane; liftedPlane? }` (design-004 §1: P1 +\n * P3 share the one camera). A `CanvasHost` still satisfies it structurally, so\n * M3 callers are unchanged; M6 passes both planes and the lifted plane (P3)\n * tracks the content plane (P1) exactly, so a promoted widget keeps its world\n * position across the content→lifted re-parent.\n *\n * `transformWrites()` is the M3 instrument: because the reflector is dirty-\n * driven on the Camera resource (equality-suppressed — design-002 §5), a static\n * camera flushes zero times and the counter stays flat; every distinct camera\n * value bumps it exactly once. The frame-contract tests assert both halves.\n *\n * Law 10: reflectors run post-notify, write output only, and NEVER read layout\n * or write ECS — this flush touches only `host.contentPlane.style`.\n */\nimport { Camera, type ReflectorDef, type World } from \"@ice/core\";\nimport { planeCssTransform } from \"@ice/kernel\";\n\n/**\n * The camera-transformed DOM plane(s). A `CanvasHost` satisfies this\n * structurally (M3 backward compat); M6 passes `liftedPlane` too so P3 tracks P1.\n */\nexport interface CameraPlanes {\n readonly contentPlane: HTMLElement;\n readonly liftedPlane?: HTMLElement;\n}\n\nexport function createPlaneTransformReflector(\n host: CameraPlanes,\n): ReflectorDef & { transformWrites(): number } {\n let writes = 0;\n return {\n name: \"plane-transform\",\n observe: { resources: [Camera] },\n flush(world: World) {\n const camera = world.getResource(Camera);\n if (camera === undefined) return;\n const { tx, ty, scale } = planeCssTransform(camera);\n const transform = `translate(${tx}px, ${ty}px) scale(${scale})`;\n host.contentPlane.style.transform = transform;\n if (host.liftedPlane !== undefined) host.liftedPlane.style.transform = transform;\n writes++; // one flush per distinct camera value, regardless of plane count\n },\n transformWrites: () => writes,\n };\n}\n","/**\n * The gray-box reflector (design-002 §5 reflector doctrine; M3 exit gate).\n *\n * A minimal enter/update/exit reconciler: it mirrors every `Position` + `Size`\n * entity to an absolutely-positioned div inside the content plane, laying each\n * out in WORLD units (`left/top/width/height` in world coordinates) — the\n * plane's single camera transform (see plane-transform.ts) does the screen\n * mapping, so this reflector never touches the camera and never reads layout\n * (Law 10). It is the stand-in for real widget rendering until the widget\n * runtime lands (M4+); \"gray box\" = deterministic per-entity fill, no content.\n *\n * Reconciliation, dirty-driven on the `Position`/`Size` query (design-002 §5):\n * - enter: create a div (fill hashed from the entity handle), write geometry,\n * stage it in a DocumentFragment (one plane append per flush — 10k mounts do\n * not thrash layout);\n * - update: compare against a per-entity geometry cache and rewrite ONLY the\n * entities whose world geometry actually changed;\n * - exit: remove divs for entities absent from this flush.\n *\n * `styleWrites()` counts entities whose geometry was (re)written this flush (one\n * per enter, one per changed entity, zero for unchanged) — the churn instrument\n * the M3 tests assert: change one entity ⇒ exactly one style write. `nodeCount()`\n * is the live div count. Because the reflector is dirty-driven, a static frame\n * does not flush at all, so neither counter moves.\n */\nimport { defineQuery, type Entity, Position, type ReflectorDef, Size, type World } from \"@ice/core\";\nimport type { CanvasHost } from \"../host\";\n\nconst grayboxQuery = defineQuery([Position, Size]);\n\ninterface Geom {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\n/** Deterministic fill from the entity handle (a packed u32) — stable across flushes. */\nfunction fillFor(entity: Entity): string {\n const n: number = entity;\n const hash = (Math.imul(n, 2654435761) >>> 0) % 360;\n return `hsl(${hash}, 55%, 55%)`;\n}\n\nfunction writeGeom(div: HTMLDivElement, x: number, y: number, w: number, h: number): void {\n div.style.left = `${x}px`;\n div.style.top = `${y}px`;\n div.style.width = `${w}px`;\n div.style.height = `${h}px`;\n}\n\nexport function createGrayboxReflector(\n host: CanvasHost,\n): ReflectorDef & { styleWrites(): number; nodeCount(): number } {\n const divs = new Map<Entity, HTMLDivElement>();\n const geom = new Map<Entity, Geom>();\n const seen = new Set<Entity>();\n const doc = host.container.ownerDocument;\n let styleWrites = 0;\n\n return {\n name: \"graybox\",\n observe: { queries: [{ q: grayboxQuery, cols: [Position, Size] }] },\n flush(world: World) {\n seen.clear();\n let fragment: DocumentFragment | null = null;\n\n world.query(grayboxQuery).each((batch) => {\n const px = batch.col(Position).x;\n const py = batch.col(Position).y;\n const sw = batch.col(Size).w;\n const sh = batch.col(Size).h;\n for (const r of batch) {\n const entity = batch.entity(r);\n seen.add(entity);\n const x = px[r] as number;\n const y = py[r] as number;\n const w = sw[r] as number;\n const h = sh[r] as number;\n\n const existing = divs.get(entity);\n if (existing === undefined) {\n const div = doc.createElement(\"div\");\n div.style.position = \"absolute\";\n div.style.background = fillFor(entity);\n writeGeom(div, x, y, w, h);\n styleWrites++;\n divs.set(entity, div);\n geom.set(entity, { x, y, w, h });\n if (fragment === null) fragment = doc.createDocumentFragment();\n fragment.appendChild(div);\n continue;\n }\n\n const prev = geom.get(entity);\n if (prev === undefined) {\n writeGeom(existing, x, y, w, h);\n styleWrites++;\n geom.set(entity, { x, y, w, h });\n } else if (prev.x !== x || prev.y !== y || prev.w !== w || prev.h !== h) {\n writeGeom(existing, x, y, w, h);\n styleWrites++;\n prev.x = x;\n prev.y = y;\n prev.w = w;\n prev.h = h;\n }\n }\n });\n\n if (fragment !== null) host.contentPlane.appendChild(fragment);\n\n for (const [entity, div] of divs) {\n if (seen.has(entity)) continue;\n div.remove();\n divs.delete(entity);\n geom.delete(entity);\n }\n },\n styleWrites: () => styleWrites,\n nodeCount: () => divs.size,\n };\n}\n","/**\n * Input-ownership predicates (design-007 §4 — one predicate FAMILY, not one\n * predicate; petitions I1/I4). \"Does the widget own input here\" is answered\n * per-surface at the right scope, sharing the DOM-walk mechanics:\n *\n * - `isEditableTarget` — the 4-class editable gate (keymap default + the\n * adapter's Space-types fix). Kept narrow so UNDECLARED widgets behave\n * exactly as before (design-007 F5).\n * - `keyboardClaimOf` — the `data-canvas-keyboard` claim marker written by the\n * dom-widgets reflector for `interaction.keyboard: \"exclusive\"` widgets.\n * Read UNBOUNDED (page-global) on purpose: `document.activeElement` is one\n * per page, so engine B's keymap must stand down while you type into engine\n * A's claiming widget (design-007 F2 — only the DOM is page-global).\n * - `wheelCede` — the NARROW, DYNAMIC scroll opt-out (design-007 §3.4/§4):\n * plain wheel cedes to native scroll only when a scroller WITH ROOM in the\n * wheel's dominant axis sits inside a claim-marked / `data-canvas-\n * interactive` / editable subtree. At the scroll bounds the predicate turns\n * false and the wheel falls through to canvas pan/zoom — the familiar\n * nested-scroll feel — which also keeps scroll-chaining from ever reaching\n * the page. Deliberately NOT the full `crossesInteractive` set: hovering a\n * bare `<button>` must not kill canvas zoom (design-007 F4).\n *\n * The keymap (`@ice/react`) imports these — the two historically disagreeing\n * guards now share one implementation (the I1 unification).\n */\n\n/** The claim marker the dom-widgets reflector writes on an exclusive widget's host. */\nexport const KEYBOARD_CLAIM_ATTR = \"data-canvas-keyboard\";\n\n/** Marker value for `keyboardEscape: \"widget\"` (the widget receives even Escape). */\nexport const CLAIM_OWNS_ESCAPE = \"escape\";\n\nexport interface KeyboardClaim {\n /** The event-target chain crosses a claim marker (⇒ engine keyboard stands down). */\n readonly claimed: boolean;\n /** The claiming widget owns Escape too (`keyboardEscape: \"widget\"`). */\n readonly ownsEscape: boolean;\n}\n\nconst NO_CLAIM: KeyboardClaim = { claimed: false, ownsEscape: false };\n\n/** The keymap's editable gate — exactly INPUT/TEXTAREA/SELECT/contentEditable. */\nexport function isEditableTarget(target: EventTarget | null): boolean {\n if (target === null || !(target instanceof HTMLElement)) return false;\n const tag = target.tagName;\n return tag === \"INPUT\" || tag === \"TEXTAREA\" || tag === \"SELECT\" || target.isContentEditable;\n}\n\n/**\n * Resolve the keyboard claim for an event target (keydown targets ARE\n * `document.activeElement`, so this reads browser focus — the single source of\n * truth, design-007 §2.1). Unbounded `closest` by design (see header).\n */\nexport function keyboardClaimOf(target: EventTarget | null): KeyboardClaim {\n if (!(target instanceof Element)) return NO_CLAIM;\n const marked = target.closest(`[${KEYBOARD_CLAIM_ATTR}]`);\n if (marked === null) return NO_CLAIM;\n return { claimed: true, ownsEscape: marked.getAttribute(KEYBOARD_CLAIM_ATTR) === CLAIM_OWNS_ESCAPE };\n}\n\n/**\n * The scroll-opt-out subtree roots (design-007 §4 `crossesScrollable` — the\n * narrow set): the claim marker, the explicit interactive opt-in, and real\n * editable scrollers. NOT bare button/a/media.\n */\nconst SCROLL_OPT_OUT_SELECTOR =\n `[${KEYBOARD_CLAIM_ATTR}], [data-canvas-interactive], input, textarea, select, [contenteditable=\"\"], [contenteditable=\"true\"]`;\n\n/** Sub-pixel tolerance for fractional scroll positions. */\nconst SCROLL_EPS = 1;\n\n/** The element can consume this wheel's dominant-axis delta RIGHT NOW (overflow + room). */\nfunction hasScrollRoom(el: HTMLElement, dx: number, dy: number): boolean {\n const style = el.ownerDocument.defaultView?.getComputedStyle(el);\n if (style === undefined || style === null) return false;\n if (Math.abs(dy) >= Math.abs(dx)) {\n if (dy === 0) return false;\n const oy = style.overflowY;\n if (oy !== \"auto\" && oy !== \"scroll\") return false;\n if (el.scrollHeight <= el.clientHeight + SCROLL_EPS) return false;\n return dy > 0 ? el.scrollTop + el.clientHeight < el.scrollHeight - SCROLL_EPS : el.scrollTop > SCROLL_EPS;\n }\n if (dx === 0) return false;\n const ox = style.overflowX;\n if (ox !== \"auto\" && ox !== \"scroll\") return false;\n if (el.scrollWidth <= el.clientWidth + SCROLL_EPS) return false;\n return dx > 0 ? el.scrollLeft + el.clientWidth < el.scrollWidth - SCROLL_EPS : el.scrollLeft > SCROLL_EPS;\n}\n\n/**\n * Should this plain (non-pinch) wheel be ceded to native widget scroll?\n * Walks target → container: remembers any scroller-with-room, cedes on the\n * first opt-out root at or above it. Walking up meets scrollers BEFORE their\n * widget's marker (the marker sits on the host), so \"a scroller inside an\n * opt-out subtree\" is exactly \"saw a scroller by the time the marker matches\".\n * ctrl/pinch wheels never reach this — they are ALWAYS the canvas's zoom.\n */\nexport function wheelCede(\n target: EventTarget | null,\n container: HTMLElement,\n dx: number,\n dy: number,\n): boolean {\n if (!(target instanceof Element)) return false;\n if (dx === 0 && dy === 0) return false;\n let sawScrollableRoom = false;\n for (let el: Element | null = target; el !== null && el !== container; el = el.parentElement) {\n if (el instanceof HTMLElement && hasScrollRoom(el, dx, dy)) sawScrollableRoom = true;\n if (sawScrollableRoom && el.matches(SCROLL_OPT_OUT_SELECTOR)) return true;\n }\n return false;\n}\n","/**\n * The DOM widget HOST reflector (design-004 §2 host pipeline; design-002 §5\n * `domWidgets`).\n *\n * This is the reflector-owned HALF of the widget runtime: it reconciles a host\n * `<div>` per mounted widget against the engine's mount store and paints its\n * world-unit geometry. The OTHER half — the React portal list — is owned by a\n * hook subscribed to the SAME store (design-004 §2, decision 3); this file never\n * touches React. Each host carries an inner `data-ice-content` element that the\n * portal targets, so the two halves meet only at that node.\n *\n * Store, not query: membership (enter/exit) and the culled-but-kept-mounted\n * `hidden` flag are ENGINE-side decisions (cull + keep-mounted LRU, mount-store.ts)\n * published through a `useSyncExternalStore` snapshot. That store has NO ECS stamp\n * for a reflector `observe` to watch, so — like the cursor reflector — this one is\n * `always: true` and does its own cheap dirt detection:\n * - **membership**: `store.getSnapshot()` identity is O(1); the snapshot changes\n * IFF membership or a hidden flag changed, so an unchanged snapshot skips the\n * reconcile entirely;\n * - **geometry**: a private observer on `[Position, Size]` sets a dirty flag, so\n * the (change-only) geometry pass runs only when a widget actually moved/resized\n * — a still scene touches no DOM. Effective size is `MeasuredSize` where present\n * and non-zero, else `Size` (design-004 §2). (MeasuredSize changes ride a\n * dedicated observer; the note below is historical:\n * picked up on the next Position/Size stamp or membership change; the ResizeObserver\n * measurement path — a later slice — will arm its own dirt.)\n * - **opacity**: a private observer on `[Opacity]` (attach/detach/value) sets a\n * dirty flag; the change-only pass writes `style.opacity` on the host (absent\n * component = 1 = property cleared). The GL twin is the composite quad's\n * `uOpacity` — a gl widget's host here carries only its DOM chrome, so the\n * two halves fade from the same cell.\n * - **drag-promote** (P3): a private observer on `[Grab]` membership sets a dirty\n * flag; a host whose entity holds `Grab` re-parents content→lifted plane and back\n * on release. Re-parenting MOVES the host node (with its content child), which\n * PRESERVES the React portal — the portal targets the content node, and moving a\n * portal's container node does not remount it, so widget React state survives the\n * lift. While ANY host is lifted, every host's content element is inerted\n * (`pointer-events: none`, the pinned inert-during-drag contract, design-004 §4).\n *\n * Law 10: reflectors run post-notify, write output only, never read layout or\n * write ECS — this flush touches only host `<div>` style/attributes/parentage.\n */\nimport {\n Grab,\n MeasuredSize,\n Opacity,\n Position,\n PrefabId,\n Size,\n compareStackOrder,\n createSiblingOrderIndex,\n defineQuery,\n widgets,\n type Entity,\n type MountEntry,\n type ReflectorDef,\n type WidgetMountStore,\n type World,\n} from \"@ice/core\";\nimport { CLAIM_OWNS_ESCAPE, KEYBOARD_CLAIM_ATTR } from \"../input-ownership\";\n\n/** The two planes a host can live in (design-004 §1: P1 content, P3 lifted). */\nexport interface DomWidgetsHost {\n readonly contentPlane: HTMLElement;\n readonly liftedPlane: HTMLElement;\n}\n\ninterface HostRec {\n /** The absolute-positioned, world-unit host div; re-parents content↔lifted on promote. */\n readonly host: HTMLDivElement;\n /** The `data-ice-content` portal target (React mounts INTO this). */\n readonly content: HTMLDivElement;\n // Geometry cache — the change-only guard (graybox pattern).\n x: number;\n y: number;\n w: number;\n h: number;\n /** Last-applied `display:none` (culled-but-kept-mounted) state. */\n hidden: boolean;\n /** Last-applied parent: true = lifted plane, false = content plane. */\n lifted: boolean;\n /** Last-applied `Opacity.a` (1 = the no-component default, style cleared). */\n opacity: number;\n}\n\ninterface Geom {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nconst geometryQuery = defineQuery([Position, Size]);\nconst measuredQuery = defineQuery([MeasuredSize]);\nconst grabQuery = defineQuery([Grab]);\nconst opacityQuery = defineQuery([Opacity]);\n\nfunction writeGeom(el: HTMLDivElement, x: number, y: number, w: number, h: number): void {\n el.style.left = `${x}px`;\n el.style.top = `${y}px`;\n el.style.width = `${w}px`;\n el.style.height = `${h}px`;\n}\n\nexport interface DomWidgetsReflector extends ReflectorDef {\n /** The entity's content element (the `data-ice-content` portal target), or undefined if not hosted. */\n hostFor(entity: Entity): HTMLElement | undefined;\n /** Live host count (= mounted widgets, visible + kept-mounted). */\n hostCount(): number;\n /** Geometry writes so far — one per enter, one per changed host, zero for unchanged (churn instrument). */\n geometryWrites(): number;\n /** Tear down the private observers (call when unregistering the reflector before the world dies). */\n dispose(): void;\n}\n\nexport function createDomWidgetsReflector(\n host: DomWidgetsHost,\n world: World,\n store: WidgetMountStore,\n): DomWidgetsReflector {\n const doc = host.contentPlane.ownerDocument;\n const hosts = new Map<Entity, HostRec>();\n // The pull-based frame ordinal cache (petition 8): sibling sequence →\n // entity → position, stamp-checked so updateOrder rebuilds only when the\n // frame parent's order actually moved.\n const order = createSiblingOrderIndex(world);\n let lastSnapshot: readonly MountEntry[] | undefined;\n let geometryWrites = 0;\n /** True while any host is lifted → all content is inerted (pinned drag contract). */\n let inert = false;\n\n // Private dirt flags — the store carries no ECS stamp, so geometry/promote work\n // is gated by observers rather than the registry's (unused under `always`) dirt.\n let geometryDirty = false;\n let promoteDirty = false;\n let opacityDirty = false;\n let orderDirty = false;\n const unsubs: Array<() => void> = [\n world.reactive.observeQuery(geometryQuery, () => { geometryDirty = true; }, { cols: [Position, Size] }),\n // MeasuredSize rides its own observer: adding it to geometryQuery's cols\n // would require it in the query and drop widgets without the rider.\n world.reactive.observeQuery(measuredQuery, () => { geometryDirty = true; }, { cols: [MeasuredSize] }),\n world.reactive.observeQuery(grabQuery, () => { promoteDirty = true; }, { cols: [] }),\n // Opacity is an optional rider like MeasuredSize: membership (attach/detach)\n // and value changes both arm the flag; detach resets the host to the\n // default via the `?? 1` read.\n world.reactive.observeQuery(opacityQuery, () => { opacityDirty = true; }, { cols: [Opacity] }),\n // Within-plane stacking IS the frame's ChildOf sibling sequence (petition\n // 8, superseding the StackZ sort that fixed the 2026-07-18 comment-box\n // paint bug). The wake names the relation (Related grammar — pure\n // reorders fire it); the ordinal cache's stamp check in updateOrder\n // keeps other-frame churn cheap.\n order.observe(() => { orderDirty = true; }),\n ];\n\n /**\n * GL widgets' hosts carry DOM CHROME that must stay in the content plane\n * (P1, UNDER the GL canvas) even while grabbed — promoting to P3 would\n * cover the widget's own 3D content with its opaque card. The GL side pops\n * the grabbed quad renderOrder-top within P2 instead (design-004 §1).\n */\n function promotable(e: Entity): boolean {\n const type = world.get(e, PrefabId)?.id;\n return typeof type !== \"string\" || widgets.get(type)?.surface !== \"gl\";\n }\n\n function readGeom(e: Entity): Geom {\n const p = world.get(e, Position);\n const measured = world.get(e, MeasuredSize);\n const s = measured !== undefined && measured.w > 0 ? measured : world.get(e, Size);\n return { x: p?.x ?? 0, y: p?.y ?? 0, w: s?.w ?? 0, h: s?.h ?? 0 };\n }\n\n function readOpacity(e: Entity): number {\n return world.get(e, Opacity)?.a ?? 1;\n }\n\n function createHost(e: Entity): HostRec {\n const el = doc.createElement(\"div\");\n el.style.position = \"absolute\";\n el.setAttribute(\"data-ice-entity\", String(e));\n\n // Keyboard claim marker (design-007 §3.1, petition I1) — REGISTRY truth,\n // read like `promotable` reads `surface` (no equip-tag timing to race).\n // Static-on-host: the marker declares \"this subtree claims keyboard when\n // focused\"; readers gate on the EVENT-TARGET chain, and a keydown targets\n // `document.activeElement`, so the standdown engages exactly while focus\n // is inside. `tabindex=-1` makes the host itself click-focusable (the\n // fallback focus node when no proxy/editable is under the pointer);\n // `outline:none` because the P4 selection chrome is the affordance, not a\n // UA focus ring on a bare card div.\n const claimType = world.get(e, PrefabId)?.id;\n const claimWidget = typeof claimType === \"string\" ? widgets.get(claimType) : undefined;\n if (claimWidget?.keyboard === \"exclusive\") {\n el.setAttribute(KEYBOARD_CLAIM_ATTR, claimWidget.keyboardEscape === \"widget\" ? CLAIM_OWNS_ESCAPE : \"\");\n el.tabIndex = -1;\n el.style.outline = \"none\";\n }\n\n const content = doc.createElement(\"div\");\n content.setAttribute(\"data-ice-content\", \"\");\n content.style.width = \"100%\";\n content.style.height = \"100%\";\n el.appendChild(content);\n\n const g = readGeom(e);\n writeGeom(el, g.x, g.y, g.w, g.h);\n geometryWrites++;\n const opacity = readOpacity(e);\n if (opacity !== 1) el.style.opacity = String(opacity);\n const lifted = world.has(e, Grab) && promotable(e);\n (lifted ? host.liftedPlane : host.contentPlane).appendChild(el);\n return { host: el, content, x: g.x, y: g.y, w: g.w, h: g.h, hidden: false, lifted, opacity };\n }\n\n /** Enter/exit/hidden reconcile against the store snapshot. Returns whether membership changed. */\n function reconcile(snapshot: readonly MountEntry[]): boolean {\n let membershipChanged = false;\n const present = new Set<Entity>();\n for (const entry of snapshot) {\n present.add(entry.entity);\n let rec = hosts.get(entry.entity);\n if (rec === undefined) {\n rec = createHost(entry.entity);\n hosts.set(entry.entity, rec);\n membershipChanged = true;\n }\n if (entry.hidden !== rec.hidden) {\n rec.hidden = entry.hidden;\n rec.host.style.display = entry.hidden ? \"none\" : \"\"; // cull ≠ unmount\n }\n }\n for (const [e, rec] of hosts) {\n if (present.has(e)) continue;\n rec.host.remove(); // React unmounts via the store; the host div goes too\n hosts.delete(e);\n membershipChanged = true;\n }\n return membershipChanged;\n }\n\n /** Change-only geometry rewrite over the live hosts (graybox pattern). */\n function updateGeometry(): void {\n for (const [e, rec] of hosts) {\n const g = readGeom(e);\n if (g.x !== rec.x || g.y !== rec.y || g.w !== rec.w || g.h !== rec.h) {\n writeGeom(rec.host, g.x, g.y, g.w, g.h);\n rec.x = g.x;\n rec.y = g.y;\n rec.w = g.w;\n rec.h = g.h;\n geometryWrites++;\n }\n }\n }\n\n /**\n * Within-plane stacking = the frame parent's ChildOf sibling sequence\n * (petition 8; design-004 §1 amendment). DOM paint order is the plane's\n * child order, so each plane's hosts are kept DOM-sorted by their sibling\n * ordinal — a comment box placed \"first\" paints UNDER the members it wraps\n * even though its host mounted last. Hosts without an ordinal (no ChildOf\n * edge — a pre-schema-2 read-only doc, or a kept-mounted other-frame host)\n * use the legacy (StackZ asc, entity asc) fallback among themselves and\n * sort ABOVE the ordinal set (compareStackOrder's documented choice; mixed\n * planes are nominally impossible post-migration). Reorder is change-only\n * (a DOM sequence already in order touches nothing) and skips a plane while\n * it contains the focused element (re-appending would blur a mid-rename\n * input — and, since design-007, the STEADY state of a focused\n * keyboard-claiming host). Returns whether every plane applied: a skipped\n * plane must keep the caller's dirt armed, or an order change landing while\n * a terminal holds focus would be consumed-but-dropped and never re-assert\n * at blur (2026-08-09 review finding).\n */\n function updateOrder(): boolean {\n const ordinals = order.ordinals();\n let allApplied = true;\n for (const plane of [host.contentPlane, host.liftedPlane]) {\n const active = doc.activeElement;\n if (active !== null && active !== doc.body && plane.contains(active)) {\n allApplied = false; // blur-safety skip — retry on the next flush\n continue;\n }\n const mine: Array<{ el: HTMLDivElement; e: Entity }> = [];\n for (const [e, rec] of hosts) {\n if (rec.host.parentNode !== plane) continue;\n mine.push({ el: rec.host, e });\n }\n if (mine.length < 2) continue;\n const target = [...mine].sort((a, b) => compareStackOrder(world, ordinals, a.e, b.e));\n // Change-only: compare the CURRENT sibling sequence of our hosts.\n let cursor = 0;\n let inOrder = true;\n for (let i = 0; i < plane.children.length; i++) {\n const child = plane.children.item(i);\n if (cursor >= target.length || child === null) break;\n if (child === (target[cursor] as { el: HTMLDivElement }).el) cursor += 1;\n else if (mine.some((m) => m.el === child)) {\n inOrder = false;\n break;\n }\n }\n if (inOrder && cursor === target.length) continue;\n for (const m of target) plane.appendChild(m.el); // moves, in sibling order\n }\n return allApplied;\n }\n\n /** Change-only opacity rewrite over the live hosts (graybox pattern). */\n function updateOpacity(): void {\n for (const [e, rec] of hosts) {\n const o = readOpacity(e);\n if (o !== rec.opacity) {\n // 1 clears the property — the no-component host carries no inline style.\n rec.host.style.opacity = o === 1 ? \"\" : String(o);\n rec.opacity = o;\n }\n }\n }\n\n /** Re-parent promoted hosts content↔lifted and toggle the global inert state. */\n function updatePromote(): void {\n let anyLifted = false;\n for (const [e, rec] of hosts) {\n const grabbed = world.has(e, Grab);\n const shouldLift = grabbed && promotable(e);\n if (shouldLift) anyLifted = true;\n if (shouldLift !== rec.lifted) {\n rec.lifted = shouldLift;\n // appendChild MOVES the existing node between planes — the React portal\n // (targeting the content child) survives the move.\n (shouldLift ? host.liftedPlane : host.contentPlane).appendChild(rec.host);\n orderDirty = true; // the move appended LAST — re-assert sibling order\n }\n // A grabbed GL widget's chrome host stays in P1 (see promotable) but must\n // still stack over its P1 NEIGHBORS while dragged — the within-plane\n // z-pop, mirroring the quad's renderOrder-top within P2. (Neighbor GL\n // content can still overdraw the dragged card's gradient — the v1\n // uDraggedRect situation; an accepted transient until the app compositor\n // hook lands, design-005.)\n if (grabbed && !shouldLift) {\n if (rec.host.style.zIndex !== \"1000\") rec.host.style.zIndex = \"1000\";\n } else if (rec.host.style.zIndex !== \"\") {\n rec.host.style.zIndex = \"\";\n }\n }\n if (anyLifted !== inert) {\n inert = anyLifted;\n // PLANE-LEVEL inert (review finding — design-004 §1/§4 contract): two\n // writes cover every widget, including the lifted one and any host that\n // enters mid-drag; events fall through to the container, so canvas\n // facts keep flowing while content handlers go quiet.\n host.contentPlane.style.pointerEvents = inert ? \"none\" : \"\";\n host.liftedPlane.style.pointerEvents = inert ? \"none\" : \"\";\n }\n }\n\n return {\n name: \"domWidgets\",\n always: true, // store membership has no ECS stamp; the flush self-gates cheaply\n flush(_world: World) {\n const snapshot = store.getSnapshot();\n let membershipChanged = false;\n if (snapshot !== lastSnapshot) {\n lastSnapshot = snapshot;\n membershipChanged = reconcile(snapshot);\n }\n if (geometryDirty) {\n geometryDirty = false;\n updateGeometry();\n }\n if (opacityDirty) {\n opacityDirty = false;\n updateOpacity();\n }\n // Membership changes can add/remove a lifted host → recompute inert even\n // without a Grab stamp (e.g. a lifted widget despawns mid-drag).\n if (promoteDirty || membershipChanged) {\n promoteDirty = false;\n updatePromote();\n }\n // AFTER promote: a re-parent appends last and must re-assert z order;\n // a fresh mount (createHost appends last) rides membershipChanged. A\n // plane parked by the focused element keeps the dirt ARMED — the flush\n // is `always`, so the first post-blur pass re-asserts the order.\n if (orderDirty || membershipChanged) {\n orderDirty = !updateOrder();\n }\n },\n hostFor: (entity) => hosts.get(entity)?.content,\n hostCount: () => hosts.size,\n geometryWrites: () => geometryWrites,\n dispose() {\n for (const u of unsubs) u();\n unsubs.length = 0;\n },\n };\n}\n","/**\n * The rAF frame loop (design-002 §1: core is scheduler-free — the DOM package\n * owns the loop; core never touches the platform).\n *\n * Drives `engine.step(now)` once per animation frame, threading the rAF\n * timestamp straight into the frame clock (so FrameInfo.dt is real wall time,\n * clamped in core). The returned stop fn cancels the pending frame AND latches\n * so a frame already in flight cannot re-schedule — calling it is idempotent.\n *\n * THE FREEZE GATE (2026-08-04). Before each frame the loop claims a step from\n * `engine.frame`. While a freeze is held the gate walks its settle and then\n * refuses, at which point the loop PARKS: it stops scheduling rAF at all\n * rather than spinning a callback that does nothing — \"the engine is stopped\"\n * should mean the browser has no work queued for it either. Thaw arrives\n * through the gate's change subscription, which schedules the next frame.\n *\n * The dt clamp is what makes resume safe: a freeze that lasted an hour hands\n * `step` an enormous `now`, and core clamps the delta (frame-info.ts), so\n * tweens advance by one ordinary frame instead of teleporting to their end.\n *\n * THE LOOP OUTLIVES A THROWING STEP (2026-08-15, petition I14). Until this fix\n * the reschedule sat on the line AFTER `engine.step(now)`, so ONE throw from a\n * publish hook (which propagate loudly by design — engine.ts) escaped the rAF\n * callback, left `handle` un-renewed, and killed the canvas PERMANENTLY: with\n * `parked` still false, `wake` early-returns forever, so even freeze/thaw could\n * not restart it. Recovery needed a fresh `startRafLoop`. The next frame is now\n * scheduled in a `finally`, so a faulting frame is loud but survivable — the\n * throw still reaches the browser's error handler; only the death is gone.\n */\nimport type { Engine } from \"@ice/core\";\n\nexport function startRafLoop(engine: Engine): () => void {\n let handle = 0;\n let stopped = false;\n let parked = false;\n\n const tick = (now: number): void => {\n if (stopped) return;\n if (!engine.frame.claimStep()) {\n // Park: no step, and deliberately no reschedule. `wake` owns the restart.\n parked = true;\n handle = 0;\n return;\n }\n try {\n engine.step(now);\n } finally {\n // Re-checked AFTER the body: a `stop()` called from inside the step\n // (a publish hook, a reflector) must still win, or the loop would\n // resurrect itself past its own stopper.\n if (!stopped) handle = requestAnimationFrame(tick);\n }\n };\n\n const wake = (): void => {\n if (stopped || !parked || engine.frame.isFrozen()) return;\n parked = false;\n handle = requestAnimationFrame(tick);\n };\n const unsubscribe = engine.frame.onChange(wake);\n\n handle = requestAnimationFrame(tick);\n\n return () => {\n stopped = true;\n unsubscribe();\n cancelAnimationFrame(handle);\n };\n}\n","/**\n * The real L0 pointer adapter (design-003 §2–§3; replaces the M3 demo-input scaffold).\n *\n * Translates DOM pointer / wheel / keyboard events into normalized `InputEvent`s\n * and ONLY enqueues them (Law 2: adapters enqueue, they never touch the world —\n * this file imports no ECS state and writes nothing). `pointerIngest` drains the\n * queue once per tick and turns the facts into world state.\n *\n * Details that matter:\n * - stable pointer ids: `\"mouse\"` for the one mouse, `\"touch:<pointerId>\"` per\n * contact, `\"pen\"` — ingest keys pointer entities off these (design-003 §2);\n * - container-relative CSS px (the kernel screen space) via getBoundingClientRect;\n * - `setPointerCapture` on down so a drag keeps delivering outside the element;\n * - Space is the pan modifier (design-003 §4.4): tracked here and threaded onto\n * every event's `mods.space`; keydown/keyup emit a `key` fact only when the\n * modifier tuple actually changes. Space's preventDefault/latch is OWNERSHIP-\n * AWARE (design-007 §3.4, petition I1): into an editable it neither latches\n * nor preventDefaults (Space must TYPE — the §1.6 live-bug fix); into a\n * `data-canvas-keyboard` claim it cedes the pan SEMANTICS but keeps killing\n * the page-scroll default (the key still reaches the widget's own listener —\n * preventDefault is not stopPropagation); elsewhere it pans, as ever;\n * - wheel: ctrl-wheel / trackpad pinch is ALWAYS `preventDefault` + the canvas\n * zoom signal (`wheel.pinch`) — a browser page-zoom over a widget is\n * catastrophic, claimed or not. A PLAIN wheel over a scroller-with-room\n * inside a claim/`data-canvas-interactive`/editable subtree (`wheelCede`,\n * design-007 §3.4/§3.5) is ceded: NO preventDefault (native scroll\n * proceeds), the fact still lands flagged `wheelHandled` so ingest stamps\n * the one-tick `WheelHandled` and the wheel recognizers skip the tick. At\n * the scroll bounds the predicate flips and the wheel falls through to\n * canvas pan/zoom. Everything else: `preventDefault`, dx/dy (deltaMode\n * lines → px ×16) — unchanged;\n * - window blur enqueues a synthetic `cancel` for every pointer still down\n * (design-003 §8) — the browser will not send the pointerups.\n *\n * Widget opt-out (the pinned widget-event contract, design-002 §8 / design-004 §4):\n * on `pointerdown` ONLY, if the event's target chain (up to the container) crosses\n * a native interactive (input/textarea/select/button/a[href]/contenteditable/\n * media[controls]) or an explicit `[data-canvas-interactive]`, the down fact is\n * flagged `surfaceHandled: true` — the fact still lands (the one input path is\n * absolute), but recognizer-spawn/arbitration skip it (`HandledByWidget` flows\n * through L0). `stopPropagation()` inside widget content is the OTHER boundary:\n * a stopped event never reaches the container listener, so it never becomes a\n * canvas fact at all — that is the design, not a gap.\n *\n * Hover-time amendment (design-002 §8, 2026-07-18): down/move facts ALSO carry\n * `overInteractive` — the same `crossesInteractive` check, run at hover time,\n * OR'd with the GL router's hover verdict — so the world can telegraph the\n * opt-out BEFORE a down (cursor affordances). It never gates gestures:\n * `surfaceHandled` stays down-only and keeps its exact meaning. During a\n * container-captured drag every event retargets to the container, so\n * `overInteractive` reads false mid-gesture — correct: the gesture owns the\n * pointer, not the widget under it.\n */\nimport { NO_MODS, type InputEvent, type InputMods, type InputQueue } from \"@ice/core\";\nimport type { CanvasHost } from \"./host\";\nimport { isEditableTarget, keyboardClaimOf, wheelCede } from \"./input-ownership\";\n\n/**\n * The router GL path's adapter seam (design-004 §4). The GL plane is\n * `pointer-events: none` — its events land HERE, and the injected router\n * (built by @ice/r3f; the adapter stays ECS-free) performs the synchronous\n * point-pick + island raycast + synthetic dispatch at event time. Returning\n * `true` means island content claimed the event (stopPropagation'd or held\n * under island capture): the fact still lands — flagged `surfaceHandled`, so\n * recognizers skip it via `HandledByWidget` — the same contract as the\n * native-interactive opt-out.\n */\nexport type GLRoute = (\n kind: \"down\" | \"move\" | \"up\" | \"cancel\",\n screenX: number,\n screenY: number,\n native: PointerEvent,\n) => boolean | GLRouteVerdict;\n\n/**\n * The richer GL verdict (hover-time amendment, 2026-07-18): `handled` keeps the\n * boolean's exact meaning (island content claimed the event); `overInteractive`\n * adds the hover fact — the pick chain holds claim-capable content (a mesh with\n * a down/click handler), so a down HERE would be the island's. Plain `boolean`\n * returns stay legal (≡ `{ handled }`), so existing routes never break.\n */\nexport interface GLRouteVerdict {\n readonly handled: boolean;\n readonly overInteractive?: boolean;\n}\n\nconst asVerdict = (v: boolean | GLRouteVerdict | undefined): GLRouteVerdict =>\n typeof v === \"object\" ? v : { handled: v === true };\n\nexport interface PointerAdapterOpts {\n readonly glRoute?: GLRoute;\n}\n\n/** DOM_DELTA_LINE → px (one wheel \"line\" ≈ 16px; matches typical browser mapping). */\nconst WHEEL_LINE_PX = 16;\n\n/**\n * Elements whose `pointerdown` is the widget's, not the canvas's (design-002 §8).\n * `contenteditable=\"\"` (bare attribute) and `=\"true\"` are editable; `=\"false\"` is\n * not. Media only opts out WITH visible controls.\n */\nconst INTERACTIVE_SELECTOR =\n 'input, textarea, select, button, a[href], [contenteditable=\"\"], [contenteditable=\"true\"], audio[controls], video[controls], [data-canvas-interactive]';\n\n/** True if `target`'s ancestor chain, up to but excluding `container`, holds an interactive surface. */\nfunction crossesInteractive(target: EventTarget | null, container: HTMLElement): boolean {\n if (!(target instanceof Element)) return false;\n const match = target.closest(INTERACTIVE_SELECTOR);\n // `closest` walks to the document root; bound it to inside the canvas so an\n // interactive ANCESTOR of the container (unusual, but legal) does not count.\n return match !== null && container.contains(match);\n}\n\nfunction pointerIdOf(e: PointerEvent): string {\n if (e.pointerType === \"touch\") return `touch:${e.pointerId}`;\n if (e.pointerType === \"pen\") return \"pen\";\n return \"mouse\";\n}\n\nfunction deviceOf(e: PointerEvent): InputEvent[\"device\"] {\n if (e.pointerType === \"touch\") return \"touch\";\n if (e.pointerType === \"pen\") return \"pen\";\n return \"mouse\";\n}\n\nexport function attachPointerAdapter(\n host: CanvasHost,\n queue: InputQueue,\n opts: PointerAdapterOpts = {},\n): () => void {\n const { container } = host;\n const view = container.ownerDocument.defaultView;\n const { glRoute } = opts;\n\n let spaceHeld = false;\n // Pointers currently down — blur-cancel sweep + DEFERRED-CAPTURE state.\n // Capture timing (field report 2026-07-12, v1's click-vs-drag discrimination):\n // capturing on DOWN retargets the derived `click`/`dblclick` to the container,\n // killing every widget-body handler (todo rows, folder double-click). So:\n // - GL-claimed downs capture IMMEDIATELY (the router synthesizes its own\n // clicks; island drags must keep delivering outside the element);\n // - native-interactive downs NEVER capture (the engine ignores them);\n // - everything else captures on the FIRST held-button move past a 4px slop\n // — below every recognizer dead zone, so a drag is always captured\n // before it can activate, while a clean tap never captures at all.\n const live = new Map<\n string,\n {\n device: InputEvent[\"device\"];\n x: number;\n y: number;\n downX: number;\n downY: number;\n native: boolean;\n captured: boolean;\n }\n >();\n const CAPTURE_SLOP_PX = 4;\n\n const capture = (pointerId: number): void => {\n if (typeof container.setPointerCapture !== \"function\") return;\n try {\n container.setPointerCapture(pointerId);\n } catch {\n // capture is best-effort — a detached or unsupported target must not throw here.\n }\n };\n // Last emitted keyboard tuple — emit a `key` fact only when it actually changes.\n let lastMods = { shift: false, ctrl: false, alt: false, meta: false, space: false };\n\n const relative = (clientX: number, clientY: number): { x: number; y: number } => {\n const rect = container.getBoundingClientRect();\n return { x: clientX - rect.left, y: clientY - rect.top };\n };\n\n const pointerMods = (e: PointerEvent | WheelEvent): InputMods => ({\n shift: e.shiftKey,\n ctrl: e.ctrlKey,\n alt: e.altKey,\n meta: e.metaKey,\n space: spaceHeld,\n });\n\n const onPointerDown = (e: PointerEvent): void => {\n const id = pointerIdOf(e);\n const device = deviceOf(e);\n const { x, y } = relative(e.clientX, e.clientY);\n // Widget opt-out: down on a native interactive / [data-canvas-interactive]\n // flags the fact so recognizers skip it (design-002 §8). The GL router is\n // the same boundary for island content — its synchronous pick + synthetic\n // dispatch happens HERE, at event time (design-004 §4).\n const native = crossesInteractive(e.target, container);\n const gl = asVerdict(glRoute?.(\"down\", x, y, e));\n const glClaimed = gl.handled;\n live.set(id, { device, x, y, downX: x, downY: y, native, captured: glClaimed });\n if (glClaimed) capture(e.pointerId); // island capture semantics need it NOW\n const surfaceHandled = native || glClaimed;\n queue.enqueue({\n kind: \"down\",\n pointerId: id,\n device,\n screenX: x,\n screenY: y,\n buttons: e.buttons,\n mods: pointerMods(e),\n tMs: e.timeStamp,\n ...(surfaceHandled ? { surfaceHandled: true } : {}),\n // The down IS a hover-bearing fact: a touch's first event must seed the\n // pointer's OverInteractive truth (no prior moves exist to).\n overInteractive: surfaceHandled || gl.overInteractive === true,\n });\n };\n\n const onPointerMove = (e: PointerEvent): void => {\n const id = pointerIdOf(e);\n const device = deviceOf(e);\n const { x, y } = relative(e.clientX, e.clientY);\n let seen = live.get(id);\n // ADOPTED-gesture hardening (ops.insertByDrag, 2026-07-19): a held-button\n // move for a pointer whose down we never saw means widget content started\n // the gesture and handed it to the engine (the tray tile stopPropagation'd\n // its down — the sanctioned boundary). Track it from HERE so the deferred\n // capture below still takes the pointer before it can leave the window\n // mid-drag, and the blur sweep knows to cancel it. Gated off interactive\n // targets: a move over opted-out content (text selection in a widget's\n // input, the tray panel itself) must never trigger a container capture.\n if (seen === undefined && e.buttons !== 0 && !crossesInteractive(e.target, container)) {\n seen = { device, x, y, downX: x, downY: y, native: false, captured: false };\n live.set(id, seen);\n }\n if (seen !== undefined) {\n seen.x = x;\n seen.y = y;\n // Deferred capture: a real drag is forming — take it before any\n // recognizer dead zone (>=8px) can activate.\n if (\n !seen.captured &&\n !seen.native &&\n e.buttons !== 0 &&\n Math.hypot(x - seen.downX, y - seen.downY) > CAPTURE_SLOP_PX\n ) {\n capture(e.pointerId);\n seen.captured = true;\n }\n }\n const gl = asVerdict(glRoute?.(\"move\", x, y, e)); // island capture / hover synth\n queue.enqueue({\n kind: \"move\",\n pointerId: id,\n device,\n screenX: x,\n screenY: y,\n buttons: e.buttons,\n mods: pointerMods(e),\n tMs: e.timeStamp,\n ...(gl.handled ? { surfaceHandled: true } : {}),\n // Hover fact, every move: DOM chain check ∪ GL verdict. A gl-captured\n // move (island drag) counts — the widget owns the pointer right now.\n overInteractive:\n crossesInteractive(e.target, container) || gl.handled || gl.overInteractive === true,\n });\n };\n\n const endPointer =\n (kind: \"up\" | \"cancel\") =>\n (e: PointerEvent): void => {\n const id = pointerIdOf(e);\n const device = deviceOf(e);\n const { x, y } = relative(e.clientX, e.clientY);\n live.delete(id);\n if (typeof container.releasePointerCapture === \"function\") {\n try {\n container.releasePointerCapture(e.pointerId);\n } catch {\n // release is best-effort (capture may already be gone).\n }\n }\n const gl = asVerdict(glRoute?.(kind, x, y, e)); // releases island capture\n queue.enqueue({\n kind,\n pointerId: id,\n device,\n screenX: x,\n screenY: y,\n buttons: e.buttons,\n mods: pointerMods(e),\n ...(gl.handled ? { surfaceHandled: true } : {}),\n // No overInteractive stamp: a capture-retargeted up reads the container,\n // not the content under the pointer — the next real move re-truths it.\n });\n };\n const onPointerUp = endPointer(\"up\");\n const onPointerCancel = endPointer(\"cancel\");\n\n const onWheel = (e: WheelEvent): void => {\n const { x, y } = relative(e.clientX, e.clientY);\n const scale = e.deltaMode === 1 ? WHEEL_LINE_PX : 1; // DOM_DELTA_LINE → px\n if (e.ctrlKey) {\n // Pinch/ctrl-wheel: ALWAYS the canvas's zoom (design-007 F4) — the\n // browser's page pinch-zoom must never fire, claimed content or not.\n e.preventDefault();\n queue.enqueue({ kind: \"wheel\", pointerId: \"mouse\", device: \"mouse\", screenX: x, screenY: y, buttons: e.buttons, mods: pointerMods(e), wheel: { dx: 0, dy: 0, pinch: e.deltaY } });\n return;\n }\n const wheel = { dx: e.deltaX * scale, dy: e.deltaY * scale, pinch: 0 };\n if (wheelCede(e.target, container, e.deltaX, e.deltaY)) {\n // Ceded to widget scroll (I4): no preventDefault — native scroll consumes\n // the deltas. The fact still lands (the one input path is absolute),\n // flagged so recognizers treat the tick as wheel silence. The room-check\n // in wheelCede means an at-bounds scroller falls through to the branch\n // below — and scroll-chaining can never escape to the page.\n queue.enqueue({ kind: \"wheel\", pointerId: \"mouse\", device: \"mouse\", screenX: x, screenY: y, buttons: e.buttons, mods: pointerMods(e), wheel, wheelHandled: true });\n return;\n }\n e.preventDefault(); // own zoom/pan — never let the page scroll\n queue.enqueue({ kind: \"wheel\", pointerId: \"mouse\", device: \"mouse\", screenX: x, screenY: y, buttons: e.buttons, mods: pointerMods(e), wheel });\n };\n\n /** Emit a `key` fact iff the modifier tuple changed (design-003 §2 minimal keyboard). */\n const emitKeyIfChanged = (e: KeyboardEvent): void => {\n const mods: InputMods = { shift: e.shiftKey, ctrl: e.ctrlKey, alt: e.altKey, meta: e.metaKey, space: spaceHeld };\n if (\n mods.shift === lastMods.shift &&\n mods.ctrl === lastMods.ctrl &&\n mods.alt === lastMods.alt &&\n mods.meta === lastMods.meta &&\n mods.space === lastMods.space\n ) {\n return;\n }\n lastMods = { ...mods };\n queue.enqueue({ kind: \"key\", pointerId: \"\", device: \"mouse\", screenX: 0, screenY: 0, buttons: 0, mods });\n };\n\n const isSpace = (e: KeyboardEvent): boolean => e.key === \" \" || e.code === \"Space\";\n\n const onKeyDown = (e: KeyboardEvent): void => {\n if (isSpace(e) && !e.defaultPrevented) {\n // Ownership-aware Space (design-007 §3.4; the keydown target IS the\n // focused node, so this reads browser focus — the one truth).\n if (isEditableTarget(e.target)) {\n // Space must TYPE into widget fields (§1.6 live-bug fix): no\n // preventDefault, no pan latch.\n } else if (keyboardClaimOf(e.target).claimed) {\n // Cede the pan SEMANTICS to the claiming widget; keep suppressing the\n // page-scroll default (§3.3 residual — preventDefault still lets the\n // key reach the widget's own keydown listener).\n e.preventDefault();\n } else {\n e.preventDefault(); // Space would otherwise page-scroll\n spaceHeld = true;\n }\n }\n emitKeyIfChanged(e);\n };\n const onKeyUp = (e: KeyboardEvent): void => {\n if (isSpace(e)) {\n if (!e.defaultPrevented && !isEditableTarget(e.target) && !keyboardClaimOf(e.target).claimed) {\n e.preventDefault();\n }\n // Clear UNCONDITIONALLY: the down may have latched over canvas and the\n // up can land after focus moved into a widget/editable — a skipped clear\n // here would strand the pan modifier held.\n spaceHeld = false;\n }\n emitKeyIfChanged(e);\n };\n\n /**\n * Drain every latched input to a clean slate (Law 2: enqueue only). Called on\n * window blur AND on detach: the browser delivers no more pointerups/keyups\n * once we blur, and detaching mid-gesture (unmounting the canvas while the\n * engine outlives it) must not strand an Active drag / held buttons / latched\n * modifiers in the world for a remount of the same engine to resurrect. Also\n * clears the deferred-capture `live` map so no per-pointer tracking survives.\n */\n const cancelAllInput = (): void => {\n // The browser will not deliver pointerups once we lose focus — cancel every\n // still-down pointer so no gesture is stranded Active (design-003 §8).\n for (const [id, s] of live) {\n queue.enqueue({ kind: \"cancel\", pointerId: id, device: s.device, screenX: s.x, screenY: s.y, buttons: 0, mods: { ...NO_MODS, space: spaceHeld } });\n }\n live.clear();\n // Modifier keyups are also lost on blur — ENQUEUE the clearing fact, or\n // the world's Keyboard resource stays latched (space-stuck: every canvas\n // drag pans forever). Clearing only local state was the bug: lastMods\n // already saying \"space up\" suppressed the next emitKeyIfChanged too.\n spaceHeld = false;\n if (lastMods.space || lastMods.shift || lastMods.ctrl || lastMods.alt || lastMods.meta) {\n lastMods = { ...NO_MODS };\n queue.enqueue({\n kind: \"key\",\n pointerId: \"\",\n device: \"mouse\",\n screenX: 0,\n screenY: 0,\n buttons: 0,\n mods: { ...NO_MODS },\n });\n }\n };\n\n const onBlur = (): void => {\n cancelAllInput();\n };\n\n container.addEventListener(\"pointerdown\", onPointerDown);\n container.addEventListener(\"pointermove\", onPointerMove);\n container.addEventListener(\"pointerup\", onPointerUp);\n container.addEventListener(\"pointercancel\", onPointerCancel);\n container.addEventListener(\"wheel\", onWheel, { passive: false });\n view?.addEventListener(\"keydown\", onKeyDown);\n view?.addEventListener(\"keyup\", onKeyUp);\n view?.addEventListener(\"blur\", onBlur);\n\n return () => {\n // Sweep first (a detach can land mid-gesture) — same clean-slate cancel as\n // blur; facts drain on the engine's next step. Then unwire the listeners.\n cancelAllInput();\n container.removeEventListener(\"pointerdown\", onPointerDown);\n container.removeEventListener(\"pointermove\", onPointerMove);\n container.removeEventListener(\"pointerup\", onPointerUp);\n container.removeEventListener(\"pointercancel\", onPointerCancel);\n container.removeEventListener(\"wheel\", onWheel);\n view?.removeEventListener(\"keydown\", onKeyDown);\n view?.removeEventListener(\"keyup\", onKeyUp);\n view?.removeEventListener(\"blur\", onBlur);\n };\n}\n","/**\n * The focus driver — acquisition + programmatic focus for keyboard-claiming\n * widgets (design-007 §2.3–§2.5, petition I1).\n *\n * The single source of truth is BROWSER focus: `document.activeElement` inside\n * a `data-canvas-keyboard` subtree is what makes every engine keyboard surface\n * stand down (input-ownership.ts). This driver's whole job is to make that\n * state reachable — it drives `.focus()`, it never mirrors focus into the\n * world (there is no Focus resource; design-007 §2.2 demoted it, and despawn\n * integrity is free: removing the node resets `activeElement`).\n *\n * Acquisition is DOM-at-event-time, not a world system: for DOM widgets the\n * browser's own event targeting IS the pick (the down target sits inside the\n * claiming host), and for GL widgets the claim lives on the DOM-chrome host\n * under the pointer (the GL plane is `pointer-events:none`, so the down lands\n * on the chrome — design-007 §2.5's proxy path). A capture-phase listener\n * keeps ordering deterministic across browsers (Safari's click-focus quirks):\n *\n * - down on a natively-focusable node inside the claim (textarea, canvas\n * with tabindex, the declared proxy itself) → the browser's own mousedown\n * focus is correct; the driver does nothing.\n * - down anywhere else inside the claim → the driver focuses the widget's\n * declared `[data-canvas-focus]` proxy when one exists, else the host\n * (the reflector gave it `tabindex=\"-1\"`), with `preventScroll` — and\n * `preventDefault()`s the pointerdown so the native focus fixup cannot\n * fight the choice. Canceling a pointerdown suppresses only the compat\n * mouse events (focus fixup + text selection — the container is already\n * `user-select:none`); `click` still derives and the adapter's container\n * listener has already enqueued the down fact (one input path intact).\n * - down outside any claim → untouched; the browser blurs to body/other\n * content on its own (click-away release, design-007 §2.4).\n *\n * Release stays where the design put it: Escape in the keymap (blur), lifecycle\n * via node removal, window blur deliberately does NOT force-blur (the browser\n * restores focus on refocus — adapter's cancelAllInput keeps its hands off).\n */\nimport type { Entity } from \"@ice/core\";\nimport type { CanvasHost } from \"./host\";\nimport { KEYBOARD_CLAIM_ATTR } from \"./input-ownership\";\n\n/** The widget-declared focus target (a proxy descendant): `<div data-canvas-focus tabIndex={-1}>`. */\nexport const FOCUS_PROXY_ATTR = \"data-canvas-focus\";\n\n/**\n * Natively click-focusable content — where the browser's own mousedown focus\n * already lands inside the widget (the driver must not override it).\n */\nconst FOCUSABLE_SELECTOR =\n 'input, textarea, select, button, a[href], [contenteditable=\"\"], [contenteditable=\"true\"], [tabindex], audio[controls], video[controls], iframe';\n\n/** Resolves an entity to its host's content element (the dom-widgets reflector's `hostFor`). */\nexport interface FocusHostLookup {\n hostFor(entity: Entity): HTMLElement | undefined;\n}\n\nexport interface WidgetFocusHandle {\n /**\n * Programmatically focus a claiming widget (its proxy, else its host).\n * Returns false when the entity has no mounted host or no keyboard claim —\n * only `keyboard: \"exclusive\"` widgets are focusable (declaration drives\n * focusability; design-007 §3.1).\n */\n focusWidget(entity: Entity): boolean;\n /** Blur whatever claim currently holds focus. False when none does. */\n blurFocus(): boolean;\n /** Remove the acquisition listener. */\n detach(): void;\n}\n\n/** The claiming host's focus node: the declared proxy, else the (tabindexed) host. */\nfunction focusNodeOf(claimHost: HTMLElement): HTMLElement {\n const proxy = claimHost.querySelector<HTMLElement>(`[${FOCUS_PROXY_ATTR}]`);\n return proxy ?? claimHost;\n}\n\nexport function attachWidgetFocus(host: CanvasHost, lookup: FocusHostLookup): WidgetFocusHandle {\n const { container } = host;\n const doc = container.ownerDocument;\n\n const onPointerDown = (e: PointerEvent): void => {\n if (!(e.target instanceof Element)) return;\n const marked = e.target.closest(`[${KEYBOARD_CLAIM_ATTR}]`);\n if (!(marked instanceof HTMLElement) || !container.contains(marked)) return;\n // A natively-focusable node under the pointer (deeper than the host)\n // takes browser focus on its own — the common editable/terminal case.\n const focusable = e.target.closest(FOCUSABLE_SELECTOR);\n if (focusable !== null && focusable !== marked && marked.contains(focusable)) return;\n const node = focusNodeOf(marked);\n if (doc.activeElement === node) return; // already held — never disturb mid-gesture\n e.preventDefault(); // suppress the native focus fixup; the driver owns the choice\n node.focus({ preventScroll: true });\n };\n\n // Capture phase: runs before widget content's own handlers and before the\n // adapter's bubble listener — deterministic acquisition, no races.\n container.addEventListener(\"pointerdown\", onPointerDown, true);\n\n return {\n focusWidget(entity) {\n const content = lookup.hostFor(entity);\n const hostEl = content?.parentElement;\n if (!(hostEl instanceof HTMLElement) || !hostEl.hasAttribute(KEYBOARD_CLAIM_ATTR)) return false;\n const node = focusNodeOf(hostEl);\n node.focus({ preventScroll: true });\n return doc.activeElement === node;\n },\n blurFocus() {\n const active = doc.activeElement;\n // SVG focus targets included — same rule as the keymap's Escape release.\n if (!(active instanceof HTMLElement || active instanceof SVGElement)) return false;\n if (active.closest(`[${KEYBOARD_CLAIM_ATTR}]`) === null) return false;\n active.blur();\n return true;\n },\n detach() {\n container.removeEventListener(\"pointerdown\", onPointerDown, true);\n },\n };\n}\n","/**\n * The cursor reflector (design-003 §7 L4 cursor projection; v1 approach:\n * local cursor = OS cursor via one `style.cursor` write).\n *\n * `createCursorSync` resolves the cursor string into closure state every\n * `derive` tick with no observable ECS stamp (a plain string, not a\n * component/resource write), so there is nothing for `observe` to watch —\n * hence `always: true` with an internal last-value cache, mirroring the\n * \"cheap-overlay style\" carve-out `ReflectorDef.always` exists for. The cache\n * is what keeps the write ONE-per-change: `flush` runs every frame, but\n * `host.container.style.cursor` is only touched when `readCursor()` differs\n * from the last-applied value.\n *\n * Law 10: reflectors run post-notify, write output only, never read layout\n * or write ECS — this flush touches only `host.container.style`.\n */\nimport type { ReflectorDef, World } from \"@ice/core\";\nimport type { CanvasHost } from \"../host\";\n\nexport function createCursorReflector(\n host: CanvasHost,\n readCursor: () => string,\n): ReflectorDef & { writes(): number } {\n let writes = 0;\n let last: string | undefined;\n return {\n name: \"cursor\",\n always: true,\n flush(_world: World) {\n const next = readCursor();\n if (next === last) return;\n last = next;\n host.container.style.cursor = next;\n writes++;\n },\n writes: () => writes,\n };\n}\n","/**\n * P5 — remote cursors (design-004 §1: screen-space DOM, \"remote cursors are\n * always custom nodes\"; design-003 §7).\n *\n * Renders one pooled node per REMOTE cursor entity (`CursorVisual` kind\n * \"remote\" + world `Position`, derived by core's remote-cursors system from\n * presence peers; `Follows` names the peer whose `PresenceInfo` supplies\n * color + label). Screen-space by design: an acknowledged small-N\n * camera→position consumer (design-002 §5 rescope), recomputed on camera or\n * cursor dirt only. The plane mounts LAST in the container, above chrome;\n * `pointer-events: none` throughout — cursors are never hit-testable.\n */\nimport {\n Camera,\n CursorVisual,\n Follows,\n Position,\n PresenceInfo,\n defineQuery,\n type Entity,\n type ReflectorDef,\n type World,\n} from \"@ice/core\";\nimport { worldToScreen } from \"@ice/kernel\";\nimport type { CanvasHost } from \"../host\";\n\nconst remoteCursorQ = defineQuery([Position, CursorVisual]);\n\nexport interface RemoteCursorsReflector {\n readonly reflector: ReflectorDef;\n /** Remove the plane + pool (doc close / HMR). */\n destroy(): void;\n}\n\nexport function createRemoteCursorsReflector(host: CanvasHost, world: World): RemoteCursorsReflector {\n const doc = host.container.ownerDocument;\n const plane = doc.createElement(\"div\");\n Object.assign(plane.style, {\n position: \"absolute\",\n inset: \"0\",\n overflow: \"hidden\",\n pointerEvents: \"none\",\n } as Partial<CSSStyleDeclaration>);\n host.container.appendChild(plane); // last child ⇒ topmost (P5 over P4)\n\n interface Node {\n root: HTMLDivElement;\n label: HTMLDivElement;\n color: string;\n name: string;\n x: number;\n y: number;\n }\n const pool = new Map<Entity, Node>();\n\n const ensure = (e: Entity): Node => {\n let n = pool.get(e);\n if (n !== undefined) return n;\n const root = doc.createElement(\"div\");\n Object.assign(root.style, {\n position: \"absolute\",\n left: \"0\",\n top: \"0\",\n willChange: \"transform\",\n pointerEvents: \"none\",\n } as Partial<CSSStyleDeclaration>);\n // Arrow glyph + name chip (color applied on first style pass).\n const arrow = doc.createElement(\"div\");\n Object.assign(arrow.style, {\n width: \"0\",\n height: \"0\",\n borderLeft: \"6px solid transparent\",\n borderRight: \"6px solid transparent\",\n borderBottom: \"14px solid currentColor\",\n transform: \"rotate(-32deg)\",\n } as Partial<CSSStyleDeclaration>);\n const label = doc.createElement(\"div\");\n Object.assign(label.style, {\n marginTop: \"2px\",\n marginLeft: \"8px\",\n padding: \"1px 6px\",\n borderRadius: \"8px\",\n font: \"11px system-ui, sans-serif\",\n color: \"#fff\",\n whiteSpace: \"nowrap\",\n } as Partial<CSSStyleDeclaration>);\n root.appendChild(arrow);\n root.appendChild(label);\n plane.appendChild(root);\n n = { root, label, color: \"\", name: \"\", x: Number.NaN, y: Number.NaN };\n pool.set(e, n);\n return n;\n };\n\n const reflector: ReflectorDef = {\n name: \"remoteCursors\",\n observe: {\n resources: [Camera],\n queries: [{ q: remoteCursorQ, cols: [Position, CursorVisual] }],\n },\n flush: (w) => {\n const cam = w.getResource(Camera) ?? { x: 0, y: 0, zoom: 1 };\n const seen = new Set<Entity>();\n w.query(remoteCursorQ).each((b) => {\n for (const r of b) {\n const e = b.entity(r);\n if (w.get(e, CursorVisual)?.kind !== \"remote\") continue;\n seen.add(e);\n const p = w.read(e, Position);\n const s = worldToScreen(p.x, p.y, cam);\n const n = ensure(e);\n if (n.x !== s.x || n.y !== s.y) {\n n.root.style.transform = `translate(${s.x}px, ${s.y}px)`;\n n.x = s.x;\n n.y = s.y;\n }\n const peer = w.getRelation(e, Follows);\n const info = peer !== undefined ? w.get(peer, PresenceInfo) : undefined;\n const color = info?.color ?? \"#7a8aa0\";\n const name = info?.name ?? \"\";\n if (n.color !== color) {\n n.root.style.color = color;\n n.label.style.background = color;\n n.color = color;\n }\n if (n.name !== name) {\n n.label.textContent = name;\n n.label.style.display = name === \"\" ? \"none\" : \"block\";\n n.name = name;\n }\n }\n });\n for (const [e, n] of pool) {\n if (!seen.has(e)) {\n n.root.remove();\n pool.delete(e);\n }\n }\n },\n };\n\n return {\n reflector,\n destroy() {\n pool.clear();\n plane.remove();\n },\n };\n}\n","/**\n * The chrome reflector (design-004 §5 chrome plane P4; post-notify, SCREEN-space).\n *\n * Draws the engine's pooled chrome entities plus the out-of-ECS marquee buffer\n * into a dedicated, non-transformed overlay plane above the content plane:\n * - each `SelectionBox` entity → a 1px outline rect (its world x,y,w,h mapped to\n * screen via `worldToScreen` × zoom);\n * - each `HandleSpec` entity → an 8×8 screen-px square CENTERED on the handle's\n * world AABB center (the handle's world size is zoom-scaled for picking; the\n * drawn size is screen-constant);\n * - the `marqueeBuffer.rect` (world) → a rect while non-null.\n *\n * P4 is screen-space by design (design-004 §2 rescope): unlike the content plane\n * (one camera transform), chrome is recomputed per camera change — small N. This\n * reflector therefore reads the `Camera` resource directly (an acknowledged\n * small-N screen-space camera consumer).\n *\n * `always: true`, not observer-driven: the marquee buffer has no ECS stamp to\n * observe, so the reflector must get a chance every frame. A cheap early-out\n * keeps it idle-free — it returns immediately when there is nothing to draw AND\n * nothing was drawn last frame (so a cleared selection still gets one flush to\n * remove its nodes). Style writes are change-only (per-node geometry cache) and\n * counted by `writes()` — the churn instrument, mirroring the other reflectors.\n *\n * Law 10: reflectors write output only, never read layout or write ECS — this\n * flush touches only the overlay plane's node styles.\n */\nimport {\n Camera,\n defineQuery,\n type Entity,\n HandleSpec,\n type MarqueeBuffer,\n Position,\n type ReflectorDef,\n SelectionBox,\n Size,\n type World,\n} from \"@ice/core\";\nimport { worldToScreen } from \"@ice/kernel\";\nimport type { CanvasHost } from \"../host\";\n\n/** On-screen handle square edge (px) — the hit target (world size) is larger. */\nconst HANDLE_DRAW_PX = 8;\n\nconst boxQ = defineQuery([SelectionBox]);\nconst handleQ = defineQuery([HandleSpec, Position, Size]);\n\nfunction makeNode(doc: Document, extra: Record<string, string>): HTMLDivElement {\n const node = doc.createElement(\"div\");\n Object.assign(node.style, { position: \"absolute\", boxSizing: \"border-box\", pointerEvents: \"none\" }, extra);\n return node;\n}\n\nexport function createChromeReflector(\n host: CanvasHost,\n // Signature carries `world` (design-004 chrome install shape); the flush is\n // handed the same world by the registry, so we read it there, not from closure.\n _world: World,\n marqueeBuffer: MarqueeBuffer,\n): ReflectorDef & { writes(): number; dispose(): void } {\n const doc = host.container.ownerDocument;\n // The screen-space overlay plane — appended after the content plane, so it\n // paints above it (P4 over P1) without a camera transform of its own.\n const plane = makeNode(doc, { left: \"0\", top: \"0\", width: \"0\", height: \"0\" });\n host.container.appendChild(plane);\n\n const boxNodes = new Map<Entity, HTMLDivElement>();\n const handleNodes = new Map<Entity, HTMLDivElement>();\n let marqueeNode: HTMLDivElement | null = null;\n\n const boxCache = new Map<Entity, string>();\n const handleCache = new Map<Entity, string>();\n let marqueeCache: string | null = null;\n let drewLast = false;\n\n const seenBox = new Set<Entity>();\n const seenHandle = new Set<Entity>();\n\n let writes = 0;\n\n const writeRect = (node: HTMLDivElement, left: number, top: number, w: number, h: number): void => {\n node.style.left = `${left}px`;\n node.style.top = `${top}px`;\n node.style.width = `${w}px`;\n node.style.height = `${h}px`;\n writes++;\n };\n\n return {\n name: \"chrome\",\n always: true,\n observe: {\n queries: [\n { q: boxQ, cols: [SelectionBox] },\n { q: handleQ, cols: [Position, Size] },\n ],\n resources: [Camera],\n },\n flush(w: World) {\n const cam = w.getResource(Camera);\n if (cam === undefined) return;\n\n const marqueeRect = marqueeBuffer.rect;\n // Cheap early-out: nothing to draw and nothing drawn last frame ⇒ skip the\n // full reconcile. `firstOf` is O(1)-ish (first matching archetype).\n const hasContent =\n marqueeRect !== null ||\n w.firstOf(boxQ) !== undefined ||\n w.firstOf(handleQ) !== undefined;\n if (!hasContent && !drewLast) return;\n\n seenBox.clear();\n seenHandle.clear();\n\n // Selection boxes: world rect → screen outline. Corner radius is the\n // app's `--ic-selection-radius` CSS var (world px, so it matches card\n // corners), zoom-scaled via calc — 0 (unset) keeps the classic sharp box.\n w.query(boxQ).each((batch) => {\n const bx = batch.col(SelectionBox).x;\n const by = batch.col(SelectionBox).y;\n const bw = batch.col(SelectionBox).w;\n const bh = batch.col(SelectionBox).h;\n for (const r of batch) {\n const e = batch.entity(r);\n seenBox.add(e);\n const tl = worldToScreen(bx[r] as number, by[r] as number, cam);\n const sw = (bw[r] as number) * cam.zoom;\n const sh = (bh[r] as number) * cam.zoom;\n const key = `${tl.x}:${tl.y}:${sw}:${sh}:${cam.zoom}`;\n let node = boxNodes.get(e);\n if (node === undefined) {\n node = makeNode(doc, { border: \"1px solid #4a90d9\" });\n node.dataset.chrome = \"box\";\n boxNodes.set(e, node);\n plane.appendChild(node);\n }\n if (boxCache.get(e) !== key) {\n writeRect(node, tl.x, tl.y, sw, sh);\n node.style.borderRadius = `calc(var(--ic-selection-radius, 0px) * ${cam.zoom})`;\n boxCache.set(e, key);\n }\n }\n });\n for (const [e, node] of boxNodes) {\n if (seenBox.has(e)) continue;\n node.remove();\n boxNodes.delete(e);\n boxCache.delete(e);\n }\n\n // Handles: world AABB center → screen, draw a fixed 8×8 square around it.\n w.query(handleQ).each((batch) => {\n const px = batch.col(Position).x;\n const py = batch.col(Position).y;\n const sw = batch.col(Size).w;\n const sh = batch.col(Size).h;\n for (const r of batch) {\n const e = batch.entity(r);\n seenHandle.add(e);\n const cx = (px[r] as number) + (sw[r] as number) / 2;\n const cy = (py[r] as number) + (sh[r] as number) / 2;\n const sc = worldToScreen(cx, cy, cam);\n const left = sc.x - HANDLE_DRAW_PX / 2;\n const top = sc.y - HANDLE_DRAW_PX / 2;\n const key = `${left}:${top}`;\n let node = handleNodes.get(e);\n if (node === undefined) {\n node = makeNode(doc, {\n width: `${HANDLE_DRAW_PX}px`,\n height: `${HANDLE_DRAW_PX}px`,\n background: \"#fff\",\n border: \"1px solid #4a90d9\",\n });\n node.dataset.chrome = \"handle\";\n handleNodes.set(e, node);\n plane.appendChild(node);\n }\n if (handleCache.get(e) !== key) {\n node.style.left = `${left}px`;\n node.style.top = `${top}px`;\n writes++;\n handleCache.set(e, key);\n }\n }\n });\n for (const [e, node] of handleNodes) {\n if (seenHandle.has(e)) continue;\n node.remove();\n handleNodes.delete(e);\n handleCache.delete(e);\n }\n\n // Marquee: from the out-of-ECS buffer, drawn while non-null.\n if (marqueeRect !== null) {\n const tl = worldToScreen(marqueeRect.x, marqueeRect.y, cam);\n const mw = marqueeRect.w * cam.zoom;\n const mh = marqueeRect.h * cam.zoom;\n const key = `${tl.x}:${tl.y}:${mw}:${mh}`;\n if (marqueeNode === null) {\n marqueeNode = makeNode(doc, { border: \"1px dashed #4a90d9\", background: \"rgba(74,144,217,0.1)\" });\n marqueeNode.dataset.chrome = \"marquee\";\n plane.appendChild(marqueeNode);\n }\n if (marqueeCache !== key) {\n writeRect(marqueeNode, tl.x, tl.y, mw, mh);\n marqueeCache = key;\n }\n } else if (marqueeNode !== null) {\n marqueeNode.remove();\n marqueeNode = null;\n marqueeCache = null;\n }\n\n drewLast = boxNodes.size > 0 || handleNodes.size > 0 || marqueeNode !== null;\n },\n writes: () => writes,\n // The P4 overlay plane is this factory's insertion — unregistering the\n // reflector alone leaves it behind (2026-07-11 teardown sweep).\n dispose() {\n plane.remove();\n },\n };\n}\n","/**\n * The measurement adapter (design-004 §2 host pipeline; measure side).\n *\n * Wraps a `ResizeObserver` over auto-sized widgets' CONTENT elements and pushes\n * `{ entity, w, h }` samples into the engine's {@link MeasureQueue} — the\n * adapter-only path (Law 2: adapters ONLY enqueue; `measureIngest` turns samples\n * into `MeasuredSize` facts inside the frame contract). It resolves an entity's\n * content element on demand via the caller's `hostFor` (the widget host reflector\n * owns the element↔entity mapping).\n *\n * §2 hidden-measure rule: a `display:none` host collapses to `0×0`, and a\n * full→0 sample would pass any dead-band and corrupt bounds/cull on re-entry —\n * so the adapter NEVER enqueues while the host is hidden (computed `display:none`\n * / no `offsetParent`), and also drops a literal `0×0`. It is the CALLER's job to\n * re-`observe` (or otherwise force a remeasure) on re-show — a `ResizeObserver`\n * does not re-fire for an element that was hidden and shown at the same box size.\n *\n * One shared `ResizeObserver` multiplexes every observed element (fewer objects,\n * identical semantics to one-per-element); `element → entity` maps a callback\n * entry back to its widget.\n */\nimport type { Entity, MeasureQueue } from \"@ice/core\";\n\nexport interface MeasureAdapter {\n /** Begin observing the entity's content element (no-op if `hostFor` yields none). */\n observe(entity: Entity): void;\n /** Stop observing the entity's content element. */\n unobserve(entity: Entity): void;\n /** Disconnect the observer and drop all mappings. */\n dispose(): void;\n}\n\n/** True when the element is `display:none` (collapsed to 0×0) and must not be measured. */\nfunction isHidden(el: HTMLElement): boolean {\n // offsetParent is null for display:none — but also for position:fixed and the\n // <body>, so a null offsetParent is only conclusive with a computed-display check.\n if (el.offsetParent !== null) return false;\n const display = el.ownerDocument.defaultView?.getComputedStyle(el).display;\n return display === \"none\";\n}\n\nexport function attachMeasureAdapter(\n hostFor: (e: Entity) => HTMLElement | undefined,\n queue: MeasureQueue,\n): MeasureAdapter {\n const byElement = new Map<Element, Entity>();\n const byEntity = new Map<Entity, Element>();\n\n const ro = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const el = entry.target as HTMLElement;\n const entity = byElement.get(el);\n if (entity === undefined) continue;\n if (isHidden(el)) continue; // never ingest from a hidden host (§2)\n const box = entry.borderBoxSize?.[0];\n const w = box !== undefined ? box.inlineSize : entry.contentRect.width;\n const h = box !== undefined ? box.blockSize : entry.contentRect.height;\n if (w === 0 && h === 0) continue; // double wall with ingest's 0×0 skip\n queue.enqueue({ entity, w, h });\n }\n });\n\n return {\n observe(entity) {\n const el = hostFor(entity);\n if (el === undefined) return;\n const prev = byEntity.get(entity);\n if (prev !== undefined && prev !== el) {\n ro.unobserve(prev);\n byElement.delete(prev);\n }\n byElement.set(el, entity);\n byEntity.set(entity, el);\n ro.observe(el);\n },\n unobserve(entity) {\n const el = byEntity.get(entity);\n if (el === undefined) return;\n ro.unobserve(el);\n byElement.delete(el);\n byEntity.delete(entity);\n },\n dispose() {\n ro.disconnect();\n byElement.clear();\n byEntity.clear();\n },\n };\n}\n","/**\n * Measurement wiring (design-004 §2 host pipeline; measure side, the store half).\n *\n * `attachMeasureAdapter` owns the `ResizeObserver` and the element→entity\n * mapping; THIS module owns *when* to observe/unobserve, driven by the engine's\n * widget mount store. It subscribes and reconciles each snapshot diff into four\n * transitions (design-004 §2 / decision 4):\n *\n * - **fresh mount + visible** → `observe` (the RO fires its own first sample);\n * - **visible → hidden** (culled-but-kept-mounted) → `unobserve` (disconnect on\n * hide — a `display:none` host measures `0×0` and a full→0 sample corrupts\n * bounds/cull on re-entry);\n * - **hidden → shown** → re-`observe` AND a FORCED synchronous re-measure: a\n * `ResizeObserver` does not re-fire for an element hidden and shown at the\n * same box size, so the reconnect alone would leave the rider stale;\n * - **unmount** (exits the snapshot) → `unobserve`.\n *\n * Ordering note: the mount store notifies from the widget-runtime flush\n * reflector, which is registered BEFORE the `domWidgets` host reflector — so at\n * notify time the host `<div>` for a just-mounted (or just-shown) widget may not\n * exist / may still be `display:none`. Like the React portal hook (which defers\n * via its own scheduler), this defers the reconcile to a microtask so it runs\n * AFTER the whole synchronous reflector pass, by which point `domWidgets` has\n * created/unhidden the host and `hostFor` + the forced re-measure see a real box.\n *\n * Law 2 holds: everything here only enqueues (through the adapter or the forced\n * sample) — no world writes, no ECS reads.\n */\nimport type { Entity, MeasureQueue, WidgetMountStore } from \"@ice/core\";\nimport { attachMeasureAdapter } from \"./measure-adapter\";\n\n/** The element source (the `domWidgets` reflector supplies this via `hostFor`). */\nexport interface MeasureWiringHosts {\n hostFor(entity: Entity): HTMLElement | undefined;\n}\n\nexport interface MeasureWiringOpts {\n /**\n * Border-box read for the forced re-measure on show. Defaults to layout\n * `offsetWidth`/`offsetHeight`; tests inject a deterministic stub.\n */\n readonly measure?: (el: HTMLElement) => { w: number; h: number };\n}\n\n// Layout border-box size, transform-independent — matches the ResizeObserver\n// path's borderBoxSize. getBoundingClientRect would fold in the camera plane's\n// CSS transform and record zoomed CSS pixels as world size at zoom ≠ 1.\nfunction defaultMeasure(el: HTMLElement): { w: number; h: number } {\n return { w: el.offsetWidth, h: el.offsetHeight };\n}\n\n/**\n * Begin observing auto-sized widget hosts against `store`, pushing measurements\n * into `queue` (drained by `measureIngest`). Returns a teardown that\n * unsubscribes and disposes the underlying `ResizeObserver`.\n */\nexport function wireMeasurement(\n store: WidgetMountStore,\n hosts: MeasureWiringHosts,\n queue: MeasureQueue,\n opts: MeasureWiringOpts = {},\n): () => void {\n const adapter = attachMeasureAdapter((e) => hosts.hostFor(e), queue);\n const measure = opts.measure ?? defaultMeasure;\n // Last-applied per-entity state — the diff basis. Absent = not mounted.\n const state = new Map<Entity, \"visible\" | \"hidden\">();\n let scheduled = false;\n let disposed = false;\n\n /** Reconnect leaves the rider stale for an unchanged box — force one sample (§2). */\n const forceRemeasure = (e: Entity): void => {\n const el = hosts.hostFor(e);\n if (el === undefined) return;\n const { w, h } = measure(el);\n if (w <= 0 && h <= 0) return; // never enqueue a hidden / 0×0 sample (§2)\n queue.enqueue({ entity: e, w, h });\n };\n\n const reconcile = (): void => {\n if (disposed) return;\n const snapshot = store.getSnapshot();\n const present = new Set<Entity>();\n for (const entry of snapshot) {\n present.add(entry.entity);\n const prev = state.get(entry.entity);\n if (entry.hidden) {\n if (prev === \"visible\") adapter.unobserve(entry.entity); // visible → hidden: disconnect\n state.set(entry.entity, \"hidden\");\n } else {\n if (prev === undefined) {\n adapter.observe(entry.entity); // fresh mount: the RO fires its own first sample\n } else if (prev === \"hidden\") {\n adapter.observe(entry.entity); // reconnect on show…\n forceRemeasure(entry.entity); // …and force it (the RO won't re-fire same-box)\n }\n state.set(entry.entity, \"visible\");\n }\n }\n for (const [e, s] of [...state]) {\n if (present.has(e)) continue;\n if (s === \"visible\") adapter.unobserve(e); // unmount from visible: disconnect\n state.delete(e);\n }\n };\n\n // Defer to a microtask so the reconcile runs AFTER the synchronous reflector\n // pass (the host reflector creates/unhides the host later this frame).\n const onStoreChange = (): void => {\n if (scheduled || disposed) return;\n scheduled = true;\n queueMicrotask(() => {\n scheduled = false;\n reconcile();\n });\n };\n\n const unsub = store.subscribe(onStoreChange);\n onStoreChange(); // pick up any entries already present at wire time\n\n return () => {\n disposed = true;\n unsub();\n adapter.dispose();\n state.clear();\n };\n}\n","/**\n * @ice/dom — DOM planes, pointer adapters (events→queue ONLY), built-in DOM reflectors.\n * Import wall: @ice/core + @ice/kernel down only — never react/three (enforced).\n */\nexport const DOM_VERSION = \"0.0.0\";\n\n// The canvas host (design-004 §1; M3: one content plane).\nexport { createCanvasHost, type CanvasHost } from \"./host\";\n\n// The lifted plane (design-004 §1, P3 — M6): host + lifted for drag-promote.\nexport { createPlanes, type Planes } from \"./planes\";\n\n// Built-in DOM reflectors (design-002 §5, post-notify output only).\nexport { createPlaneTransformReflector, type CameraPlanes } from \"./reflectors/plane-transform\";\nexport { createGrayboxReflector } from \"./reflectors/graybox\";\n\n// The DOM widget host layer (design-004 §2): host divs reconciled against the\n// engine mount store; React portals target each host's content element.\nexport {\n createDomWidgetsReflector,\n type DomWidgetsHost,\n type DomWidgetsReflector,\n} from \"./reflectors/dom-widgets\";\n\n// The rAF frame loop (design-002 §1: the platform owns the loop).\nexport { startRafLoop } from \"./loop\";\n\n// The L0 pointer adapter (design-003 §2–§3): DOM events → InputQueue, nothing more.\nexport { attachPointerAdapter, type GLRoute, type GLRouteVerdict, type PointerAdapterOpts } from \"./pointer-adapter\";\n\n// Input-ownership predicates (design-007 §4, petitions I1/I4): the shared\n// per-surface guard family — the keymap (@ice/react) reads these too.\nexport {\n CLAIM_OWNS_ESCAPE,\n KEYBOARD_CLAIM_ATTR,\n isEditableTarget,\n keyboardClaimOf,\n wheelCede,\n type KeyboardClaim,\n} from \"./input-ownership\";\n\n// The focus driver (design-007 §2.3–§2.5): click-to-focus acquisition for\n// `keyboard: \"exclusive\"` widgets + the programmatic focusWidget/blurFocus\n// handle. Focus is VIEW state (design-007 §2.6) — it lives here, not in core.\nexport {\n FOCUS_PROXY_ATTR,\n attachWidgetFocus,\n type FocusHostLookup,\n type WidgetFocusHandle,\n} from \"./widget-focus\";\n\n// L4 cursor projection output (design-003 §7: local cursor = OS cursor, one write).\nexport { createCursorReflector } from \"./reflectors/cursor\";\n// P5 remote cursors (design-004 §1: screen-space pooled nodes; M9 presence).\nexport { createRemoteCursorsReflector, type RemoteCursorsReflector } from \"./reflectors/remote-cursors\";\n\n// The P0 ground layer (grid, wires, snap guides) moved to @ice/ground\n// (2026-07-16: one WebGPU canvas, TSL passes — design-004 §1 as-built\n// amendment). @ice/dom has no ground code; configs live in @ice/core.\n\n// M6 chrome plane reflector (P4) + measurement adapter (design-004 §2 measure, §5 chrome).\nexport { createChromeReflector } from \"./reflectors/chrome\";\nexport { attachMeasureAdapter, type MeasureAdapter } from \"./measure-adapter\";\n// M6 measurement wiring: mount-store → observe/unobserve + reconnect-on-show (design-004 §2).\nexport { wireMeasurement, type MeasureWiringHosts, type MeasureWiringOpts } from \"./measure-wiring\";\n"],"mappings":"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","names":["writeGeom"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../kernel/src/shapes.ts","../../kernel/src/coords.ts","../../kernel/src/snap.ts","../../kernel/src/spatial-index.ts","../../kernel/src/zoom-bands.ts","../../kernel/src/eviction.ts","../../kernel/src/anchors.ts","../../kernel/src/bezier.ts","../../kernel/src/easing.ts","../../kernel/src/nav-flight.ts","../../kernel/src/layout.ts","../../kernel/src/index.ts"],"sourcesContent":["/** Plain geometric structs shared across the kernel. Ported from v1 `ecs/math.ts`. */\n\nexport interface Vec2 {\n x: number;\n y: number;\n}\n\nexport interface Rect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport interface AABB {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n}\n\nexport function rectToAABB(r: Rect): AABB {\n return { minX: r.x, minY: r.y, maxX: r.x + r.width, maxY: r.y + r.height };\n}\n\nexport function aabbToRect(a: AABB): Rect {\n return { x: a.minX, y: a.minY, width: a.maxX - a.minX, height: a.maxY - a.minY };\n}\n\nexport function intersectsAABB(a: AABB, b: AABB): boolean {\n return a.maxX >= b.minX && a.minX <= b.maxX && a.maxY >= b.minY && a.minY <= b.maxY;\n}\n\nexport function pointInAABB(px: number, py: number, a: AABB): boolean {\n return px >= a.minX && px <= a.maxX && py >= a.minY && py <= a.maxY;\n}\n\nexport function clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n","/**\n * THE coordinate seam (Law 13): every conversion between screen, world, and\n * island (widget-local GL) space lives here — including the ONE Y-flip.\n * v1 duplicated this math in three places; nothing outside this module may\n * re-derive it.\n *\n * Conventions:\n * - screen: CSS px, canvas-container-relative, Y-down. DPR never enters world\n * math (it exists only in GL uniforms / FBO sizing — see zoom-bands).\n * - world: world units, Y-down. `Camera.{x,y}` is the WORLD point at the\n * viewport's top-left; `zoom` is screen px per world unit.\n * - island: widget-local GL space — CENTER origin, Y-UP, world-unit scale.\n * (v1 VirtualWidget convention; the only Y-flip in the codebase.)\n */\nimport type { Rect, Vec2 } from \"./shapes\";\n\nexport interface CameraState {\n x: number;\n y: number;\n zoom: number;\n}\n\nexport function screenToWorld(screenX: number, screenY: number, camera: CameraState): Vec2 {\n return {\n x: screenX / camera.zoom + camera.x,\n y: screenY / camera.zoom + camera.y,\n };\n}\n\nexport function worldToScreen(worldX: number, worldY: number, camera: CameraState): Vec2 {\n return {\n x: (worldX - camera.x) * camera.zoom,\n y: (worldY - camera.y) * camera.zoom,\n };\n}\n\n/**\n * Zoom about a fixed screen point (v1 `zoomAtPoint`): the world point under\n * `(screenX, screenY)` stays under it after the zoom change.\n * Returns the new camera (does not mutate). Clamping is the caller's policy.\n */\nexport function zoomAtPoint(\n camera: CameraState,\n screenX: number,\n screenY: number,\n newZoom: number,\n): CameraState {\n const anchor = screenToWorld(screenX, screenY, camera);\n return {\n x: anchor.x - screenX / newZoom,\n y: anchor.y - screenY / newZoom,\n zoom: newZoom,\n };\n}\n\n/**\n * The DEFAULT framing camera (2026-07-18, James: \"do zoom to fit, but with a\n * upper and bottom cap … should feel natural\"): zoom-to-fit `content` (a\n * world-space bbox) with `pad` px of breathing room on every side, zoom\n * clamped into [minZoom, maxZoom] — the natural band: never so far in that\n * one small card fills the screen, never so far out that the board turns\n * into an ant farm. The content CENTER stays centered whether or not a cap\n * engages. Callers own the band policy (engine default: FIT_DEFAULTS ∩ the\n * session's hard CameraLimits) and must pass a real viewport.\n */\nexport function fitCamera(\n content: Rect,\n vpW: number,\n vpH: number,\n opts: { pad: number; minZoom: number; maxZoom: number },\n): CameraState {\n const fit = Math.min(vpW / (content.width + opts.pad * 2), vpH / (content.height + opts.pad * 2));\n const zoom = Math.min(opts.maxZoom, Math.max(opts.minZoom, fit));\n return {\n x: content.x + content.width / 2 - vpW / (2 * zoom),\n y: content.y + content.height / 2 - vpH / (2 * zoom),\n zoom,\n };\n}\n\n/**\n * Camera → the ONE per-plane CSS transform (design-002 §5 `planeTransform`).\n * Children are laid out in WORLD units inside the plane (left/top = world x/y),\n * the plane carries `transform: translate(tx px, ty px) scale(scale)` with\n * `transform-origin: 0 0` — so a child at world point p lands at\n * `p·zoom + t = (p − camera)·zoom`, i.e. exactly `worldToScreen(p)`.\n */\nexport function planeCssTransform(camera: CameraState): { tx: number; ty: number; scale: number } {\n return {\n tx: -camera.x * camera.zoom,\n ty: -camera.y * camera.zoom,\n scale: camera.zoom,\n };\n}\n\n/** World → island (center-origin, Y-up). THE Y-flip, direction one. */\nexport function worldToIsland(worldX: number, worldY: number, widget: Rect): Vec2 {\n return {\n x: worldX - (widget.x + widget.width / 2),\n y: -(worldY - (widget.y + widget.height / 2)),\n };\n}\n\n/** Island → world. THE Y-flip, direction two. */\nexport function islandToWorld(islandX: number, islandY: number, widget: Rect): Vec2 {\n return {\n x: widget.x + widget.width / 2 + islandX,\n y: widget.y + widget.height / 2 - islandY,\n };\n}\n\n// --- P2 composite scene (design-004 §1/§3) -------------------------------\n// The GL-views plane composites island quads in a Three scene whose axes are\n// world-unit X-right / Y-UP (Three convention). Same flip as island space,\n// applied at WORLD scale — these two helpers are the only place it exists.\n\n/**\n * Camera → the P2 composite ortho frustum + camera position (world units,\n * Y-up scene). `left/top` pin the viewport's top-left to `Camera.{x,y}`\n * exactly like `planeCssTransform` does for the DOM planes: the frustum spans\n * `viewport / zoom` world units and the camera sits at the world origin\n * offset, so a quad at `worldRectToComposite(rect)` lands on the same screen\n * pixels as a DOM host at `rect` under the plane transform.\n */\nexport function compositeCameraFrustum(\n camera: CameraState,\n viewportW: number,\n viewportH: number,\n): { left: number; right: number; top: number; bottom: number; x: number; y: number } {\n return {\n left: 0,\n right: viewportW / camera.zoom,\n top: 0,\n bottom: -(viewportH / camera.zoom),\n x: camera.x,\n y: -camera.y,\n };\n}\n\n/** World rect → composite-quad center + scale in the Y-up P2 scene. */\nexport function worldRectToComposite(rect: Rect): { x: number; y: number; sx: number; sy: number } {\n return {\n x: rect.x + rect.width / 2,\n y: -(rect.y + rect.height / 2),\n sx: rect.width,\n sy: rect.height,\n };\n}\n","/**\n * Snap guide computation (Figma-style), ported verbatim from v1\n * `ecs/spatial/snap.ts` (audited CLEAN-PORT):\n * Phase 1 — edge/center alignment (7 X + 7 Y candidate pairs per reference,\n * per-axis nearest-wins, ties within 0.01 accumulate guides)\n * Phase 2 — equal spacing (between-two-neighbors midpoint; extend-a-pattern),\n * same-perpendicular-band filter\n * Merge — alignment takes priority per axis; equal spacing fills the other;\n * indicators recomputed post-snap at threshold × 0.5.\n * Pure function over plain bounds. Candidate GATHERING (spatial index, tags,\n * Active scoping) is the caller's job — design-003 §5.2/§6.\n */\n\nexport interface SnapGuide {\n axis: \"x\" | \"y\";\n /** World-space coordinate of the alignment line */\n position: number;\n type: \"edge\" | \"center\";\n}\n\nexport interface EqualSpacingIndicator {\n axis: \"x\" | \"y\";\n /** The equal gap value (world units) */\n gap: number;\n /** Pairs of (from, to) marking each equal gap segment */\n segments: { from: number; to: number }[];\n /** Position on the perpendicular axis (for rendering) */\n perpPosition: number;\n}\n\nexport interface SnapResult {\n /** Snap-corrected delta (world units). Apply to entity position. */\n snapDx: number;\n snapDy: number;\n guides: SnapGuide[];\n spacings: EqualSpacingIndicator[];\n}\n\nexport interface EntityBounds {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport function computeSnapGuides(\n dragged: EntityBounds,\n references: EntityBounds[],\n threshold: number,\n): SnapResult {\n const guides: SnapGuide[] = [];\n const spacings: EqualSpacingIndicator[] = [];\n let snapDx = 0;\n let snapDy = 0;\n\n const dLeft = dragged.x;\n const dRight = dragged.x + dragged.width;\n const dCenterX = dragged.x + dragged.width / 2;\n const dTop = dragged.y;\n const dBottom = dragged.y + dragged.height;\n const dCenterY = dragged.y + dragged.height / 2;\n\n let bestSnapX = Number.POSITIVE_INFINITY;\n let bestSnapY = Number.POSITIVE_INFINITY;\n let bestDx = 0;\n let bestDy = 0;\n const xGuides: SnapGuide[] = [];\n const yGuides: SnapGuide[] = [];\n\n // --- Phase 1: edge/center alignment ---\n for (const ref of references) {\n const rLeft = ref.x;\n const rRight = ref.x + ref.width;\n const rCenterX = ref.x + ref.width / 2;\n const rTop = ref.y;\n const rBottom = ref.y + ref.height;\n const rCenterY = ref.y + ref.height / 2;\n\n const xPairs: [number, number, \"edge\" | \"center\"][] = [\n [dLeft, rLeft, \"edge\"],\n [dLeft, rRight, \"edge\"],\n [dRight, rLeft, \"edge\"],\n [dRight, rRight, \"edge\"],\n [dCenterX, rCenterX, \"center\"],\n [dLeft, rCenterX, \"edge\"],\n [dRight, rCenterX, \"edge\"],\n ];\n for (const [dVal, rVal, type] of xPairs) {\n const dist = Math.abs(dVal - rVal);\n if (dist <= threshold) {\n const dx = rVal - dVal;\n if (dist < bestSnapX) {\n bestSnapX = dist;\n bestDx = dx;\n xGuides.length = 0;\n }\n if (dist <= bestSnapX + 0.01) {\n xGuides.push({ axis: \"x\", position: rVal, type });\n }\n }\n }\n\n const yPairs: [number, number, \"edge\" | \"center\"][] = [\n [dTop, rTop, \"edge\"],\n [dTop, rBottom, \"edge\"],\n [dBottom, rTop, \"edge\"],\n [dBottom, rBottom, \"edge\"],\n [dCenterY, rCenterY, \"center\"],\n [dTop, rCenterY, \"edge\"],\n [dBottom, rCenterY, \"edge\"],\n ];\n for (const [dVal, rVal, type] of yPairs) {\n const dist = Math.abs(dVal - rVal);\n if (dist <= threshold) {\n const dy = rVal - dVal;\n if (dist < bestSnapY) {\n bestSnapY = dist;\n bestDy = dy;\n yGuides.length = 0;\n }\n if (dist <= bestSnapY + 0.01) {\n yGuides.push({ axis: \"y\", position: rVal, type });\n }\n }\n }\n }\n\n // --- Phase 2: equal spacing ---\n const eqResult = computeEqualSpacing(dragged, references, threshold);\n\n // Merge: alignment snap takes priority; equal spacing fills the other axis.\n if (bestSnapX <= threshold) {\n snapDx = bestDx;\n } else if (eqResult.snapDx !== undefined) {\n snapDx = eqResult.snapDx;\n }\n if (bestSnapY <= threshold) {\n snapDy = bestDy;\n } else if (eqResult.snapDy !== undefined) {\n snapDy = eqResult.snapDy;\n }\n\n if (bestSnapX <= threshold) {\n const seen = new Set<number>();\n for (const g of xGuides) {\n if (!seen.has(g.position)) {\n seen.add(g.position);\n guides.push(g);\n }\n }\n }\n if (bestSnapY <= threshold) {\n const seen = new Set<number>();\n for (const g of yGuides) {\n if (!seen.has(g.position)) {\n seen.add(g.position);\n guides.push(g);\n }\n }\n }\n\n // Indicators recomputed against the SNAPPED bounds at half threshold.\n const snappedBounds: EntityBounds = {\n x: dragged.x + snapDx,\n y: dragged.y + snapDy,\n width: dragged.width,\n height: dragged.height,\n };\n const eqFinal = computeEqualSpacing(snappedBounds, references, threshold * 0.5);\n spacings.push(...eqFinal.indicators);\n\n return { snapDx, snapDy, guides, spacings };\n}\n\ninterface EqualSpacingResult {\n snapDx: number | undefined;\n snapDy: number | undefined;\n indicators: EqualSpacingIndicator[];\n}\n\nfunction computeEqualSpacing(\n dragged: EntityBounds,\n references: EntityBounds[],\n threshold: number,\n): EqualSpacingResult {\n const indicators: EqualSpacingIndicator[] = [];\n let snapDx: number | undefined;\n let snapDy: number | undefined;\n\n const xResult = checkAxisSpacing(dragged, references, threshold, \"x\");\n if (xResult) {\n snapDx = xResult.snap;\n indicators.push(...xResult.indicators);\n }\n const yResult = checkAxisSpacing(dragged, references, threshold, \"y\");\n if (yResult) {\n snapDy = yResult.snap;\n indicators.push(...yResult.indicators);\n }\n return { snapDx, snapDy, indicators };\n}\n\nfunction checkAxisSpacing(\n dragged: EntityBounds,\n references: EntityBounds[],\n threshold: number,\n axis: \"x\" | \"y\",\n): { snap: number; indicators: EqualSpacingIndicator[] } | null {\n const isX = axis === \"x\";\n const pos = (b: EntityBounds) => (isX ? b.x : b.y);\n const size = (b: EntityBounds) => (isX ? b.width : b.height);\n const perpPos = (b: EntityBounds) => (isX ? b.y : b.x);\n const perpSize = (b: EntityBounds) => (isX ? b.height : b.width);\n const end = (b: EntityBounds) => pos(b) + size(b);\n\n // Same-perpendicular-band filter.\n const neighbors = references.filter(\n (ref) =>\n perpPos(ref) < perpPos(dragged) + perpSize(dragged) &&\n perpPos(ref) + perpSize(ref) > perpPos(dragged),\n );\n if (neighbors.length < 1) return null;\n\n const sorted = [...neighbors].sort((a, b) => pos(a) - pos(b));\n\n // Existing gaps between consecutive references.\n const refGaps: { from: EntityBounds; to: EntityBounds; gap: number }[] = [];\n for (let i = 0; i < sorted.length - 1; i++) {\n const a = sorted[i];\n const b = sorted[i + 1];\n if (a === undefined || b === undefined) continue;\n const gap = pos(b) - end(a);\n if (gap > 0.1) refGaps.push({ from: a, to: b, gap });\n }\n\n let bestSnap: number | null = null;\n let bestIndicators: EqualSpacingIndicator[] = [];\n let bestDiff = Number.POSITIVE_INFINITY;\n\n // Case 1: between two neighbors — equalize left/right gaps.\n let leftN: EntityBounds | null = null;\n let rightN: EntityBounds | null = null;\n for (const ref of sorted) {\n if (end(ref) <= pos(dragged) + threshold) {\n if (!leftN || end(ref) > end(leftN)) leftN = ref;\n }\n if (pos(ref) >= end(dragged) - threshold) {\n if (!rightN || pos(ref) < pos(rightN)) rightN = ref;\n }\n }\n if (leftN && rightN) {\n const lGap = pos(dragged) - end(leftN);\n const rGap = pos(rightN) - end(dragged);\n const diff = Math.abs(lGap - rGap);\n if (diff <= threshold && diff < bestDiff) {\n const idealPos = (end(leftN) + pos(rightN) - size(dragged)) / 2;\n const snap = idealPos - pos(dragged);\n const equalGap = (pos(rightN) - end(leftN) - size(dragged)) / 2;\n if (equalGap > 0.1) {\n const perpY = computePerpCenter(dragged, [leftN, rightN], isX);\n bestSnap = snap;\n bestDiff = diff;\n bestIndicators = [\n {\n axis,\n gap: equalGap,\n segments: [\n { from: end(leftN), to: idealPos },\n { from: idealPos + size(dragged), to: pos(rightN) },\n ],\n perpPosition: perpY,\n },\n ];\n }\n }\n }\n\n // Case 2: extend an existing gap pattern (append right / prepend left).\n for (const refGap of refGaps) {\n const patternGap = refGap.gap;\n\n if (rightN === null || pos(refGap.to) >= end(dragged) - threshold * 2) {\n const chainEnd = refGap.to;\n const dragGap = pos(dragged) - end(chainEnd);\n const diff = Math.abs(dragGap - patternGap);\n if (diff <= threshold && diff < bestDiff) {\n const idealPos = end(chainEnd) + patternGap;\n const snap = idealPos - pos(dragged);\n const perpY = computePerpCenter(dragged, [refGap.from, refGap.to], isX);\n bestSnap = snap;\n bestDiff = diff;\n bestIndicators = [\n {\n axis,\n gap: patternGap,\n segments: [\n { from: end(refGap.from), to: pos(refGap.to) },\n { from: end(chainEnd), to: idealPos },\n ],\n perpPosition: perpY,\n },\n ];\n }\n }\n\n if (leftN === null || end(refGap.from) <= pos(dragged) + threshold * 2) {\n const chainStart = refGap.from;\n const dragGap = pos(chainStart) - end(dragged);\n const diff = Math.abs(dragGap - patternGap);\n if (diff <= threshold && diff < bestDiff) {\n const idealPos = pos(chainStart) - patternGap - size(dragged);\n const snap = idealPos - pos(dragged);\n const perpY = computePerpCenter(dragged, [refGap.from, refGap.to], isX);\n bestSnap = snap;\n bestDiff = diff;\n bestIndicators = [\n {\n axis,\n gap: patternGap,\n segments: [\n { from: idealPos + size(dragged), to: pos(chainStart) },\n { from: end(refGap.from), to: pos(refGap.to) },\n ],\n perpPosition: perpY,\n },\n ];\n }\n }\n }\n\n if (bestSnap !== null) return { snap: bestSnap, indicators: bestIndicators };\n return null;\n}\n\nfunction computePerpCenter(dragged: EntityBounds, refs: EntityBounds[], isX: boolean): number {\n const perpPos = (b: EntityBounds) => (isX ? b.y : b.x);\n const perpSize = (b: EntityBounds) => (isX ? b.height : b.width);\n const allBounds = [dragged, ...refs];\n const maxStart = Math.max(...allBounds.map(perpPos));\n const minEnd = Math.min(...allBounds.map((b) => perpPos(b) + perpSize(b)));\n if (minEnd < maxStart) {\n return perpPos(dragged) + perpSize(dragged) / 2;\n }\n return maxStart + (minEnd - maxStart) / 2;\n}\n","/**\n * Spatial index backed by an R-tree (rbush) — ported from v1 (audited CLEAN-PORT).\n * World-space AABBs for culling, hit-testing, and snap-candidate gathering\n * (Law 15: the ONLY hit path). The id↔entry map gives O(log n) removal by\n * passing rbush the exact stored reference (v1 \"Fix #8\").\n *\n * `rbush` is the kernel's single, named dependency exception: a zero-dep pure\n * data structure (see .dependency-cruiser.cjs).\n */\nimport RBushImport from \"rbush\";\nimport type { AABB } from \"./shapes\";\n\n// CJS/ESM interop — rbush exports differently depending on context (kept from v1).\ntype RBushModule = typeof RBushImport & { default?: typeof RBushImport };\nconst rbushModule = RBushImport as RBushModule;\nconst RBush = (\n typeof rbushModule.default === \"function\" ? rbushModule.default : RBushImport\n) as typeof RBushImport;\n\nexport interface SpatialEntry<Id> extends AABB {\n id: Id;\n}\n\nexport class SpatialIndex<Id> {\n private tree = new RBush<SpatialEntry<Id>>();\n private entries = new Map<Id, SpatialEntry<Id>>();\n\n upsert(id: Id, bounds: AABB): void {\n const existing = this.entries.get(id);\n if (existing) this.tree.remove(existing);\n const entry: SpatialEntry<Id> = { ...bounds, id };\n this.entries.set(id, entry);\n this.tree.insert(entry);\n }\n\n remove(id: Id): void {\n const existing = this.entries.get(id);\n if (existing) {\n this.tree.remove(existing);\n this.entries.delete(id);\n }\n }\n\n /** All entries intersecting the given AABB. */\n search(bounds: AABB): SpatialEntry<Id>[] {\n return this.tree.search(bounds);\n }\n\n /** Entries within `tolerance` of a point (z-priority is the caller's job). */\n searchPoint(x: number, y: number, tolerance = 0): SpatialEntry<Id>[] {\n return this.tree.search({\n minX: x - tolerance,\n minY: y - tolerance,\n maxX: x + tolerance,\n maxY: y + tolerance,\n });\n }\n\n clear(): void {\n this.tree.clear();\n this.entries.clear();\n }\n\n get size(): number {\n return this.entries.size;\n }\n}\n","/**\n * Hysteresis-banded zoom-resolution policy — ported from v1 `ZoomBands.ts`\n * (RFC-002). An island FBO is allocated at `widget bounds × dpr × band(zoom)`;\n * while zoom stays within `[band × 0.5, band × 2]` no repaint is needed.\n * Bands are powers of 2 (each covers a 4× display range).\n */\nexport const ZOOM_BANDS = [0.0625, 0.125, 0.25, 0.5, 1, 2, 4, 8, 16] as const;\nconst MIN_BAND = 0.0625;\nconst MAX_BAND = 16;\n\n/** Smallest band ≥ zoom (clamped to the ladder). */\nexport function selectBand(zoom: number): number {\n if (zoom <= MIN_BAND) return MIN_BAND;\n if (zoom >= MAX_BAND) return MAX_BAND;\n for (const b of ZOOM_BANDS) {\n if (zoom <= b) return b;\n }\n return MAX_BAND;\n}\n\n/**\n * True when zoom left the `[band × 0.5, band × 2]` window of the band the\n * island was painted at. `paintedBand ≤ 0` = never painted (handled elsewhere).\n */\nexport function isOutOfBand(currentZoom: number, paintedBand: number): boolean {\n if (paintedBand <= 0) return false;\n const ratio = currentZoom / paintedBand;\n return ratio > 2 || ratio < 0.5;\n}\n\n/** FBO pixel size for a widget at a band (v1: `bounds × dpr × band`, min 1px). */\nexport function fboPixelSize(\n worldWidth: number,\n worldHeight: number,\n dpr: number,\n band: number,\n): { width: number; height: number } {\n return {\n width: Math.max(1, Math.round(worldWidth * dpr * band)),\n height: Math.max(1, Math.round(worldHeight * dpr * band)),\n };\n}\n","/**\n * FBO-pool eviction policy — ported from v1 `eviction.ts` (pure part of the\n * pool). Priority: Cold(0) < Warm(1) < Dormant(2); LRU within a phase;\n * Hot/Waking are never evicted even under an impossible budget.\n */\nexport type IslandPhase = \"Hot\" | \"Warm\" | \"Waking\" | \"Cold\" | \"Dormant\";\n\nexport interface EvictionCandidate<Id> {\n id: Id;\n phase: IslandPhase;\n bytes: number;\n lastUsedMs: number;\n}\n\nconst PHASE_PRIORITY: Record<IslandPhase, number> = {\n Cold: 0,\n Warm: 1,\n Dormant: 2,\n Waking: Number.POSITIVE_INFINITY,\n Hot: Number.POSITIVE_INFINITY,\n};\n\n/**\n * The island phase truth table (design-004 §3; v1 `computePhase` verbatim —\n * RFC-002 pinned it with tests). `active` is the nested-canvas membership\n * signal (always true until M8); `hasFbo` splits Warm (retained texture,\n * composite-ready) from Waking (must paint before compositing) — after an\n * eviction a re-entering island comes back as Waking, after a plain cull\n * round-trip it comes back Warm from the retained texture.\n */\nexport function computeIslandPhase(\n active: boolean,\n visible: boolean,\n animating: boolean,\n hasFbo: boolean,\n): IslandPhase {\n if (!active) return \"Dormant\";\n if (visible) {\n if (animating) return \"Hot\";\n return hasFbo ? \"Warm\" : \"Waking\";\n }\n // Culled OR not yet culled-classified: treat as Cold — never paint a widget\n // the engine hasn't placed in the viewport yet (v1 rule, kept).\n return \"Cold\";\n}\n\n/** Ordered ids to release so total bytes ≤ budget. Pure. */\nexport function selectEvictions<Id>(\n candidates: EvictionCandidate<Id>[],\n totalBytes: number,\n maxBytes: number,\n): Id[] {\n if (totalBytes <= maxBytes) return [];\n\n const eligible = candidates.filter((c) => Number.isFinite(PHASE_PRIORITY[c.phase]));\n eligible.sort((a, b) => {\n const p = PHASE_PRIORITY[a.phase] - PHASE_PRIORITY[b.phase];\n if (p !== 0) return p;\n return a.lastUsedMs - b.lastUsedMs;\n });\n\n const toEvict: Id[] = [];\n let remaining = totalBytes;\n for (const c of eligible) {\n if (remaining <= maxBytes) break;\n toEvict.push(c.id);\n remaining -= c.bytes;\n }\n return toEvict;\n}\n","/**\n * Port-anchor math (design-001 §5.3): wire geometry NEVER reads port entities —\n * anchors are pure functions over the widget rect + the port declaration, so\n * culled endpoints work by construction.\n */\nimport type { Rect, Vec2 } from \"./shapes\";\n\nexport type PortSide = \"n\" | \"e\" | \"s\" | \"w\";\n\nexport interface PortSlot {\n side: PortSide;\n /** 0-based position among the ports sharing this side. */\n index: number;\n /** Total ports on this side. */\n count: number;\n}\n\n/** World-space anchor point: ports distribute evenly along their side. */\nexport function portAnchor(widget: Rect, slot: PortSlot): Vec2 {\n const f = (slot.index + 1) / (slot.count + 1);\n switch (slot.side) {\n case \"n\":\n return { x: widget.x + widget.width * f, y: widget.y };\n case \"s\":\n return { x: widget.x + widget.width * f, y: widget.y + widget.height };\n case \"w\":\n return { x: widget.x, y: widget.y + widget.height * f };\n case \"e\":\n return { x: widget.x + widget.width, y: widget.y + widget.height * f };\n }\n}\n\n/** Outward unit direction of a side (wire tangent stubs, Y-down world). */\nexport function sideDirection(side: PortSide): Vec2 {\n switch (side) {\n case \"n\":\n return { x: 0, y: -1 };\n case \"s\":\n return { x: 0, y: 1 };\n case \"w\":\n return { x: -1, y: 0 };\n case \"e\":\n return { x: 1, y: 0 };\n }\n}\n","/**\n * Cubic-bezier wire geometry: construction from port anchors, conservative\n * AABB (for the spatial index), and sampled distance (for picking — wires rank\n * below widgets, design-003 §3).\n */\nimport { sideDirection, type PortSide } from \"./anchors\";\nimport type { AABB, Vec2 } from \"./shapes\";\n\nexport interface Cubic {\n x0: number;\n y0: number;\n x1: number;\n y1: number;\n x2: number;\n y2: number;\n x3: number;\n y3: number;\n}\n\n/**\n * Wire curve between two anchors: tangent stubs leave each port along its\n * side's outward direction, scaled with distance (min stub keeps short wires\n * readable).\n */\nexport function wireCubic(\n from: Vec2,\n fromSide: PortSide,\n to: Vec2,\n toSide: PortSide,\n stubScale = 0.4,\n minStub = 24,\n): Cubic {\n const dist = Math.hypot(to.x - from.x, to.y - from.y);\n const stub = Math.max(minStub, dist * stubScale);\n const df = sideDirection(fromSide);\n const dt = sideDirection(toSide);\n return {\n x0: from.x,\n y0: from.y,\n x1: from.x + df.x * stub,\n y1: from.y + df.y * stub,\n x2: to.x + dt.x * stub,\n y2: to.y + dt.y * stub,\n x3: to.x,\n y3: to.y,\n };\n}\n\n/** Point on the curve at t ∈ [0, 1] (Bernstein form). */\nexport function cubicPoint(c: Cubic, t: number): Vec2 {\n const u = 1 - t;\n const b0 = u * u * u;\n const b1 = 3 * u * u * t;\n const b2 = 3 * u * t * t;\n const b3 = t * t * t;\n return {\n x: b0 * c.x0 + b1 * c.x1 + b2 * c.x2 + b3 * c.x3,\n y: b0 * c.y0 + b1 * c.y1 + b2 * c.y2 + b3 * c.y3,\n };\n}\n\n/**\n * Conservative bounds: the control-point hull contains the curve (convex-hull\n * property). Cheap and index-friendly; exact extrema are unnecessary for\n * culling/picking prefilters.\n */\nexport function cubicAABB(c: Cubic): AABB {\n return {\n minX: Math.min(c.x0, c.x1, c.x2, c.x3),\n minY: Math.min(c.y0, c.y1, c.y2, c.y3),\n maxX: Math.max(c.x0, c.x1, c.x2, c.x3),\n maxY: Math.max(c.y0, c.y1, c.y2, c.y3),\n };\n}\n\nexport interface Tessellation {\n /** Flattened polyline, interleaved [x0,y0, x1,y1, …] in the cubic's own space. */\n points: Float32Array;\n /** Cumulative arc length at each polyline point (same unit; [0] = 0). */\n arcLength: Float32Array;\n}\n\n/**\n * Anti-Grain-Geometry flatness: the control points' summed deviation from the\n * chord, squared, against tolerance² × chord² (degenerate chords fall back to\n * raw control-point distance from p0).\n */\nfunction flatEnough(c: Cubic, tolSq: number): boolean {\n const dx = c.x3 - c.x0;\n const dy = c.y3 - c.y0;\n const chordSq = dx * dx + dy * dy;\n if (chordSq <= 1e-12) {\n const d1 = Math.hypot(c.x1 - c.x0, c.y1 - c.y0);\n const d2 = Math.hypot(c.x2 - c.x0, c.y2 - c.y0);\n return (d1 + d2) * (d1 + d2) <= tolSq;\n }\n const d1 = Math.abs((c.x1 - c.x0) * dy - (c.y1 - c.y0) * dx);\n const d2 = Math.abs((c.x2 - c.x0) * dy - (c.y2 - c.y0) * dx);\n return (d1 + d2) * (d1 + d2) <= tolSq * chordSq;\n}\n\n/** De Casteljau split at t = 0.5 → [left, right]. */\nfunction splitCubic(c: Cubic): [Cubic, Cubic] {\n const ax = (c.x0 + c.x1) / 2;\n const ay = (c.y0 + c.y1) / 2;\n const bx = (c.x1 + c.x2) / 2;\n const by = (c.y1 + c.y2) / 2;\n const cx = (c.x2 + c.x3) / 2;\n const cy = (c.y2 + c.y3) / 2;\n const abx = (ax + bx) / 2;\n const aby = (ay + by) / 2;\n const bcx = (bx + cx) / 2;\n const bcy = (by + cy) / 2;\n const mx = (abx + bcx) / 2;\n const my = (aby + bcy) / 2;\n return [\n { x0: c.x0, y0: c.y0, x1: ax, y1: ay, x2: abx, y2: aby, x3: mx, y3: my },\n { x0: mx, y0: my, x1: bcx, y1: bcy, x2: cx, y2: cy, x3: c.x3, y3: c.y3 },\n ];\n}\n\n/**\n * Adaptive cubic flattening + prefix arc length (2026-07-16, the @ice/ground\n * wires pass: stroke tessellation and dash placement both ride this). Emit\n * density follows curvature — flat spans emit one segment regardless of\n * length; tolerance is in the cubic's OWN space (the ground renderer passes\n * screen-px cubics with ~0.25 px tolerance, so density tracks zoom for free).\n * `maxDepth` bounds pathological inputs (2^depth segments worst case).\n */\nexport function tessellateCubic(c: Cubic, tolerance = 0.25, maxDepth = 16): Tessellation {\n const pts: number[] = [c.x0, c.y0];\n const tolSq = tolerance * tolerance;\n const walk = (cur: Cubic, depth: number): void => {\n if (depth >= maxDepth || flatEnough(cur, tolSq)) {\n pts.push(cur.x3, cur.y3);\n return;\n }\n const [l, r] = splitCubic(cur);\n walk(l, depth + 1);\n walk(r, depth + 1);\n };\n walk(c, 0);\n\n const n = pts.length / 2;\n const points = new Float32Array(pts);\n const arcLength = new Float32Array(n);\n let acc = 0;\n for (let i = 1; i < n; i++) {\n const dx = (pts[i * 2] as number) - (pts[i * 2 - 2] as number);\n const dy = (pts[i * 2 + 1] as number) - (pts[i * 2 - 1] as number);\n acc += Math.hypot(dx, dy);\n arcLength[i] = acc;\n }\n return { points, arcLength };\n}\n\n/** Distance from a point to a line segment. */\nexport function distanceToSegment(\n px: number,\n py: number,\n ax: number,\n ay: number,\n bx: number,\n by: number,\n): number {\n const dx = bx - ax;\n const dy = by - ay;\n const lenSq = dx * dx + dy * dy;\n let t = 0;\n if (lenSq > 0) {\n t = ((px - ax) * dx + (py - ay) * dy) / lenSq;\n t = Math.max(0, Math.min(1, t));\n }\n const cx = ax + t * dx;\n const cy = ay + t * dy;\n return Math.hypot(px - cx, py - cy);\n}\n\n/**\n * Min distance from a point to the curve via polyline sampling. 32 samples is\n * ample for hit thresholds of a few px; error shrinks with curve flatness.\n */\nexport function distanceToCubic(px: number, py: number, c: Cubic, samples = 32): number {\n let best = Number.POSITIVE_INFINITY;\n let prev = cubicPoint(c, 0);\n for (let i = 1; i <= samples; i++) {\n const cur = cubicPoint(c, i / samples);\n const d = distanceToSegment(px, py, prev.x, prev.y, cur.x, cur.y);\n if (d < best) best = d;\n prev = cur;\n }\n return best;\n}\n","/**\n * CSS-style cubic-bezier timing functions (pure math — kernel).\n *\n * `cubicBezierEase(x1, y1, x2, y2)` builds f(t): the exact curve CSS\n * `transition-timing-function: cubic-bezier(…)` runs, so GL surfaces can\n * match DOM transitions beat-for-beat (the composite-quad lift mirrors the\n * DOM card lift's spring, cubic-bezier(0.2, 0.9, 0.3, 1.2)). y outside [0,1]\n * (overshoot springs) is legal and expected; x1/x2 are clamped to [0,1] per\n * spec so x(u) stays monotone and invertible.\n */\n\n/** Bernstein sample with P0=0, P3=1 (one axis of the timing curve). */\nfunction sample(u: number, p1: number, p2: number): number {\n const v = 1 - u;\n return 3 * v * v * u * p1 + 3 * v * u * u * p2 + u * u * u;\n}\n\nexport function cubicBezierEase(x1: number, y1: number, x2: number, y2: number): (t: number) => number {\n const cx1 = Math.min(1, Math.max(0, x1));\n const cx2 = Math.min(1, Math.max(0, x2));\n const sampleDx = (u: number): number => {\n const v = 1 - u;\n return 3 * v * v * cx1 + 6 * v * u * (cx2 - cx1) + 3 * u * u * (1 - cx2);\n };\n\n return (t: number): number => {\n if (t <= 0) return 0;\n if (t >= 1) return 1;\n // Solve x(u) = t: Newton first (fast for well-behaved curves)…\n let u = t;\n for (let i = 0; i < 8; i++) {\n const err = sample(u, cx1, cx2) - t;\n if (Math.abs(err) < 1e-6) return sample(u, y1, y2);\n const d = sampleDx(u);\n if (d < 1e-6) break; // flat spot — Newton would explode\n u = Math.min(1, Math.max(0, u - err / d));\n }\n // …bisection fallback (x is monotone under the clamp).\n let lo = 0;\n let hi = 1;\n u = t;\n while (hi - lo > 1e-6) {\n if (sample(u, cx1, cx2) < t) lo = u;\n else hi = u;\n u = (lo + hi) / 2;\n }\n return sample(u, y1, y2);\n };\n}\n","/**\n * Nav-flight math (design-006 §2/§4 — the portal zoom, T1 camera-flight half).\n *\n * Pure math, no ECS/DOM. Conventions are coords.ts's (Law 13): camera {x,y} =\n * world point at the viewport top-left, zoom = screen px per world unit,\n * `screen = (world − cam)·zoom`.\n *\n * The portal embedding: a container's content coordinates are FRAME-LOCAL\n * (design-001 §5.1) — the transition DEFINES the embedding by mapping the\n * arrival camera's visible rect onto the container's body rect (`portalAffine`,\n * aspect-fit, centers aligned). With that affine fixed, both transition layers\n * ride ONE camera: the destination frame renders under `c(t)` directly; the\n * departed frame renders under `c(t) ∘ A` where A maps departed-frame coords\n * into destination-frame coords. Continuity at the cut is exact by\n * construction (`solveFlightStart`), and no drift is possible mid-flight —\n * there is no second clock.\n *\n * Numerics locked by the mock (2026-07-15, three rounds of field testing):\n * - the progress spring uses the CLOSED-FORM critically-damped solution —\n * semi-implicit Euler diverges once ω·dt nears 1 (a fast exit response on\n * one dropped frame sent the mock's camera to zoom 1501);\n * - the path interpolates zoom in LOG space (constant perceived zoom\n * velocity — van Wijk & Nuij) with the view center linear in 1/zoom, which\n * is exactly an anchored zoom whenever a fixed screen point exists;\n * - flights beyond `maxOctaves` must be depth-capped (`capFlightStart`):\n * sweeping a DOM plane's raster scale ~30× in one flight outruns\n * Chromium's async tile re-raster (stale/missing tiles, persisting at\n * rest) — the capped flight is presented as a crossfade-through-zoom.\n */\nimport type { CameraState } from \"./coords\";\nimport type { Rect } from \"./shapes\";\n\n/** Uniform scale + translate: `A(q) = o + q·s`. */\nexport interface PortalAffine {\n readonly s: number;\n readonly ox: number;\n readonly oy: number;\n}\n\n/** The world rect a camera shows through a viewport. */\nexport function visibleRect(cam: CameraState, vpW: number, vpH: number): Rect {\n return { x: cam.x, y: cam.y, width: vpW / cam.zoom, height: vpH / cam.zoom };\n}\n\n/**\n * The portal embedding: map `arrival` (the world rect the arrival camera will\n * show, in the CHILD frame's coords) onto `portal` (the container's body rect,\n * in the PARENT frame's coords). Aspect-FIT with centers aligned (design-006\n * §8.3 — the card chrome absorbs the letterbox).\n */\nexport function portalAffine(arrival: Rect, portal: Rect): PortalAffine {\n const s = Math.min(portal.width / arrival.width, portal.height / arrival.height);\n return {\n s,\n ox: portal.x + portal.width / 2 - (arrival.x + arrival.width / 2) * s,\n oy: portal.y + portal.height / 2 - (arrival.y + arrival.height / 2) * s,\n };\n}\n\nexport function invertAffine(a: PortalAffine): PortalAffine {\n return { s: 1 / a.s, ox: -a.ox / a.s, oy: -a.oy / a.s };\n}\n\n/** `(outer ∘ inner)(q) = outer(inner(q))` — for multi-level exit portals. */\nexport function composeAffine(outer: PortalAffine, inner: PortalAffine): PortalAffine {\n return { s: outer.s * inner.s, ox: outer.ox + inner.ox * outer.s, oy: outer.oy + inner.oy * outer.s };\n}\n\n/**\n * Continuity solve: the camera `c0` (in the DESTINATION frame) under which\n * departed-frame content mapped through `A` (departed → destination coords)\n * renders EXACTLY as it did under `camPre` (in the departed frame) the instant\n * before the cut. Derivation: a departed point q renders at\n * `(A(q) − c0)·z0 = q·(A.s·z0) + (A.o − c0)·z0`; matching `(q − camPre)·zPre`\n * coefficient-wise gives z0 and the origin below. Zoom limits deliberately do\n * NOT apply here — flight paths transit far outside the user-gesture band\n * (design-006 §3.1); only the ARRIVAL camera is clamped by the caller.\n */\nexport function solveFlightStart(A: PortalAffine, camPre: CameraState): CameraState {\n return {\n x: A.ox + camPre.x * A.s,\n y: A.oy + camPre.y * A.s,\n zoom: camPre.zoom / A.s,\n };\n}\n\n/** Zoom distance in octaves — the flight-length measure (design-006 §4/§5). */\nexport function flightOctaves(from: CameraState, to: CameraState): number {\n return Math.abs(Math.log2(to.zoom / from.zoom));\n}\n\n/**\n * Depth-cap a flight start (design-006 §5): beyond `maxOctaves`, clamp the\n * start zoom to `capFactor ×` the arrival zoom (dive direction preserved),\n * keeping the exact start's view CENTER — the portal anchor — so the motion\n * still comes from/goes to the right place. `capped: true` means the caller\n * must present the flight as a crossfade (frozen departing cover + incoming\n * fade-in): geometric continuity is unpresentable at that raster-scale swing.\n */\nexport function capFlightStart(\n exact: CameraState,\n arrival: CameraState,\n vpW: number,\n vpH: number,\n maxOctaves: number,\n capFactor: number,\n): { c0: CameraState; capped: boolean } {\n if (flightOctaves(exact, arrival) <= maxOctaves) return { c0: exact, capped: false };\n const zCap = exact.zoom > arrival.zoom ? arrival.zoom * capFactor : arrival.zoom / capFactor;\n return {\n c0: {\n x: exact.x + (vpW / 2) * (1 / exact.zoom - 1 / zCap),\n y: exact.y + (vpH / 2) * (1 / exact.zoom - 1 / zCap),\n zoom: zCap,\n },\n capped: true,\n };\n}\n\n/**\n * The flight path `c(p)`, p ∈ [0,1]: zoom log-lerped (constant perceived zoom\n * velocity); view CENTER linear in 1/zoom — exactly an anchored zoom whenever\n * a fixed screen point exists between the endpoints, a graceful blend\n * otherwise. Endpoints are exact: c(0) = c0, c(1) = c1.\n */\nexport function flightCamera(\n c0: CameraState,\n c1: CameraState,\n p: number,\n vpW: number,\n vpH: number,\n): CameraState {\n const zoom = Math.exp(Math.log(c0.zoom) + (Math.log(c1.zoom) - Math.log(c0.zoom)) * p);\n const inv0 = 1 / c0.zoom;\n const inv1 = 1 / c1.zoom;\n const inv = 1 / zoom;\n const w = Math.abs(inv1 - inv0) < 1e-12 ? p : (inv - inv0) / (inv1 - inv0);\n const cx = c0.x + vpW * inv0 * 0.5 + (c1.x + vpW * inv1 * 0.5 - (c0.x + vpW * inv0 * 0.5)) * w;\n const cy = c0.y + vpH * inv0 * 0.5 + (c1.y + vpH * inv1 * 0.5 - (c0.y + vpH * inv0 * 0.5)) * w;\n return { x: cx - vpW * inv * 0.5, y: cy - vpH * inv * 0.5, zoom };\n}\n\n/**\n * One step of the critically-damped progress spring toward 1, in CLOSED FORM:\n * with u = 1 − p, the exact solution is `u(t) = (u₀ + Bt)·e^(−ωt)`,\n * `B = −v₀ + ω·u₀`. Unconditionally stable at ANY dt — the discretized form\n * (semi-implicit Euler) diverges once ω·dt approaches 1, which one dropped\n * frame at a fast response reaches easily (mock-measured, 2026-07-15).\n * From rest (v=0) the approach is monotonic: p never overshoots 1.\n */\nexport function springStep(\n p: number,\n v: number,\n omega: number,\n dtSec: number,\n): { p: number; v: number } {\n const u = 1 - p;\n const B = -v + omega * u;\n const decay = Math.exp(-omega * dtSec);\n const u2 = (u + B * dtSec) * decay;\n const du2 = (B - omega * (u + B * dtSec)) * decay;\n return { p: 1 - u2, v: -du2 };\n}\n","/**\n * Pure auto-layout math (2026-07-17, James: cards dropped into a folder \"just\n * pile up on each other\" — and, later, an explicit desktop-style Clean Up).\n *\n * Two primitives, two products, one law each:\n * - `insertSlot` — place ONE newcomer near a drop hint without moving\n * anything: newcomers get a free slot, incumbents never move. Consumed by\n * the drop-consume path (l3-behave). Candidates are edge-aligned to the\n * incumbents (flush right/below/left/above with a gutter), so successive\n * drops grow aligned rows and columns instead of a global imposed grid.\n * - `packLayout` — bottom-left candidate packing for the explicit\n * \"Clean Up\" command (v2 2026-07-17, James: shelves were \"not really\n * efficient\" and selection packs \"overlay on top of unselected widgets\"):\n * items flow in reading order (current y, then x, then index) and each\n * takes the lowest-then-leftmost free spot, so small cards fill the air\n * beside tall ones instead of opening a new shelf. `obstacles` rects are\n * honored as immovable — a scoped pack flows AROUND bystanders. Still\n * \"my mess, straightened\": deterministic, anchored at the cluster's own\n * top-left, idempotent on packed input (pinned by test).\n * - `layerGraph` — the Unreal-Blueprint-style arrange for WIRED widgets:\n * Sugiyama-lite layered layout (longest-path ranks along edge direction,\n * barycenter ordering, columns left→right, vertically centered). Callers\n * lay out each connected component with this and pack the resulting\n * blocks with `packLayout`.\n *\n * Plain structs in, plain structs out (Law 13): no ECS, no DOM, no camera.\n * All coordinates live in ONE frame — callers convert (container-local for\n * folder drops, world for canvas clean-up) before and after.\n */\n\nexport interface LayoutRect {\n readonly x: number;\n readonly y: number;\n readonly w: number;\n readonly h: number;\n}\n\nexport interface LayoutSize {\n readonly w: number;\n readonly h: number;\n}\n\nexport interface LayoutPoint {\n readonly x: number;\n readonly y: number;\n}\n\n/** True when the rects are closer than `gutter` on BOTH axes (≥gutter on either axis = fine). */\nfunction crowds(a: LayoutRect, b: LayoutRect, gutter: number): boolean {\n return (\n a.x < b.x + b.w + gutter &&\n b.x < a.x + a.w + gutter &&\n a.y < b.y + b.h + gutter &&\n b.y < a.y + a.h + gutter\n );\n}\n\nfunction isFree(x: number, y: number, size: LayoutSize, incumbents: readonly LayoutRect[], gutter: number): boolean {\n const r = { x, y, w: size.w, h: size.h };\n for (const i of incumbents) {\n if (crowds(r, i, gutter)) return false;\n }\n return true;\n}\n\n/**\n * Nearest free slot to `hint` for a `size` newcomer among `incumbents`.\n *\n * The hint wins verbatim when it is already free (a deliberate drop into\n * empty space is user intent — don't second-guess it). Otherwise candidates\n * flush against each incumbent's edges (top- and far-aligned variants) are\n * ranked by squared distance to the hint; ties resolve to the first-seen\n * candidate (stable in incumbent order — deterministic across runs). The\n * fallback — a spot gutter-right of EVERYTHING — cannot crowd anyone, so a\n * slot always exists.\n */\nexport function insertSlot(\n incumbents: readonly LayoutRect[],\n size: LayoutSize,\n hint: LayoutPoint,\n gutter: number,\n): { x: number; y: number } {\n if (incumbents.length === 0 || isFree(hint.x, hint.y, size, incumbents, gutter)) {\n return { x: hint.x, y: hint.y };\n }\n let best: { x: number; y: number } | undefined;\n let bestD = Number.POSITIVE_INFINITY;\n for (const i of incumbents) {\n const candidates = [\n { x: i.x + i.w + gutter, y: i.y }, // right, top-aligned\n { x: i.x, y: i.y + i.h + gutter }, // below, left-aligned\n { x: i.x - size.w - gutter, y: i.y }, // left, top-aligned\n { x: i.x, y: i.y - size.h - gutter }, // above, left-aligned\n { x: i.x + i.w + gutter, y: i.y + i.h - size.h }, // right, bottom-aligned\n { x: i.x + i.w - size.w, y: i.y + i.h + gutter }, // below, right-aligned\n ];\n for (const c of candidates) {\n if (!isFree(c.x, c.y, size, incumbents, gutter)) continue;\n const d = (c.x - hint.x) ** 2 + (c.y - hint.y) ** 2;\n if (d < bestD) {\n bestD = d;\n best = c;\n }\n }\n }\n if (best !== undefined) return best;\n let maxRight = Number.NEGATIVE_INFINITY;\n for (const i of incumbents) maxRight = Math.max(maxRight, i.x + i.w);\n return { x: maxRight + gutter, y: hint.y };\n}\n\nexport interface PackOpts {\n readonly gutter: number;\n /** Pack origin; defaults to the items' current bbox top-left (the cluster stays put). */\n readonly origin?: LayoutPoint;\n /**\n * Band wrap width; defaults to a near-square derivation (√(total area × 1.6),\n * never narrower than the widest item). Soft: an item that fits nowhere\n * inside the band still places (lowest spot, band ignored) rather than\n * failing.\n */\n readonly maxWidth?: number;\n /**\n * Immovable rects the pack must flow AROUND (e.g. unselected widgets when\n * arranging a selection). Never returned, never moved, never crowded.\n */\n readonly obstacles?: readonly LayoutRect[];\n}\n\n/**\n * Bottom-left candidate packing: items in reading order of their CURRENT\n * positions (strict y, then x, then input index) each take the\n * lowest-then-leftmost free spot from the candidate set (the origin, plus\n * gutter-flush right-of and below-of every placed/obstacle rect, plus the\n * band-left row start under each). Dense with mixed sizes — small cards fill\n * the air beside tall ones — and obstacle-aware. Returns placements parallel\n * to the input array.\n */\nexport function packLayout(items: readonly LayoutRect[], opts: PackOpts): Array<{ x: number; y: number }> {\n if (items.length === 0) return [];\n const gutter = opts.gutter;\n\n let ox: number;\n let oy: number;\n if (opts.origin !== undefined) {\n ox = opts.origin.x;\n oy = opts.origin.y;\n } else {\n ox = Number.POSITIVE_INFINITY;\n oy = Number.POSITIVE_INFINITY;\n for (const it of items) {\n ox = Math.min(ox, it.x);\n oy = Math.min(oy, it.y);\n }\n }\n\n let maxWidth = opts.maxWidth;\n if (maxWidth === undefined) {\n let area = 0;\n let widest = 0;\n for (const it of items) {\n area += (it.w + gutter) * (it.h + gutter);\n widest = Math.max(widest, it.w);\n }\n maxWidth = Math.max(widest, Math.sqrt(area * 1.6));\n }\n\n const order = items\n .map((_, i) => i)\n .sort((a, b) => {\n const ia = items[a] as LayoutRect;\n const ib = items[b] as LayoutRect;\n return ia.y - ib.y || ia.x - ib.x || a - b;\n });\n\n // Feasibility set: obstacles first (they also seed candidates), then\n // every placed item as it lands.\n const placed: LayoutRect[] = [...(opts.obstacles ?? [])];\n const out = new Array<{ x: number; y: number }>(items.length);\n for (const idx of order) {\n const it = items[idx] as LayoutRect;\n const cands: LayoutPoint[] = [{ x: ox, y: oy }];\n for (const r of placed) {\n cands.push({ x: r.x + r.w + gutter, y: r.y }); // right, top-aligned\n cands.push({ x: r.x, y: r.y + r.h + gutter }); // below, left-aligned\n cands.push({ x: ox, y: r.y + r.h + gutter }); // band-left row start\n }\n let best: LayoutPoint | undefined;\n // Pass 1 honors the band; pass 2 drops it (an oversize item or a wall of\n // obstacles must still place — the below-everything candidate is always\n // free, so pass 2 cannot come up empty).\n for (const inBand of [true, false]) {\n for (const c of cands) {\n if (c.x < ox || c.y < oy) continue;\n if (inBand && c.x + it.w > ox + maxWidth) continue;\n if (!isFree(c.x, c.y, it, placed, gutter)) continue;\n if (best === undefined || c.y < best.y || (c.y === best.y && c.x < best.x)) best = c;\n }\n if (best !== undefined) break;\n }\n if (best === undefined) {\n // Defensive only (see pass-2 note above).\n let maxBottom = oy;\n for (const r of placed) maxBottom = Math.max(maxBottom, r.y + r.h);\n best = { x: ox, y: maxBottom + gutter };\n }\n out[idx] = { x: best.x, y: best.y };\n placed.push({ x: best.x, y: best.y, w: it.w, h: it.h });\n }\n return out;\n}\n\nexport interface LayerGraphOpts {\n /** Horizontal gap between columns (leave room for wires to breathe). */\n readonly gapX: number;\n /** Vertical gap between nodes inside a column. */\n readonly gapY: number;\n /**\n * Wrap the column run into stacked BANDS when the unwrapped width would\n * exceed this (carriage-return style: each band flows left→right, bands\n * stack top→down with a 2×gapY separator). Omit for a single band — a\n * graph is inherently wide and only wraps when the caller says the canvas\n * band demands it.\n */\n readonly maxWidth?: number;\n}\n\n/**\n * Layered graph layout (Sugiyama-lite) — the Unreal-Blueprint-style arrange\n * for wired widgets. Rank = longest path from the sources along edge\n * direction (a DFS drops back edges, so cycles are safe); columns flow\n * left→right; nodes stack top→down within a column. Ordering = alternating\n * barycenter sweeps with the BEST ordering kept (counted wire crossings),\n * then the classic transpose refinement (adjacent swaps that strictly\n * reduce crossings) — not provably minimal, but the standard practical\n * pair. Columns center vertically on their band's tallest. Placements are\n * relative to (0,0) — callers anchor the block. Deterministic: all\n * orderings tie-break on node index.\n */\nexport function layerGraph(\n nodes: readonly LayoutSize[],\n edges: readonly (readonly [number, number])[],\n opts: LayerGraphOpts,\n): Array<{ x: number; y: number }> {\n const n = nodes.length;\n if (n === 0) return [];\n\n // Drop self-edges; find back edges via iterative DFS (in index order).\n const outAdj: number[][] = Array.from({ length: n }, () => []);\n for (const [u, v] of edges) {\n if (u !== v && u >= 0 && u < n && v >= 0 && v < n) outAdj[u]?.push(v);\n }\n const kept: Array<[number, number]> = [];\n const state = new Array<0 | 1 | 2>(n).fill(0); // 0 unseen, 1 on stack, 2 done\n for (let root = 0; root < n; root++) {\n if (state[root] !== 0) continue;\n const stack: Array<{ u: number; i: number }> = [{ u: root, i: 0 }];\n state[root] = 1;\n while (stack.length > 0) {\n const top = stack[stack.length - 1] as { u: number; i: number };\n const adj = outAdj[top.u] as number[];\n if (top.i < adj.length) {\n const v = adj[top.i] as number;\n top.i += 1;\n if (state[v] === 1) continue; // back edge — dropped\n kept.push([top.u, v]);\n if (state[v] === 0) {\n state[v] = 1;\n stack.push({ u: v, i: 0 });\n }\n } else {\n state[top.u] = 2;\n stack.pop();\n }\n }\n }\n\n // Longest-path ranks over the kept DAG (topological relaxation).\n const keptOut: number[][] = Array.from({ length: n }, () => []);\n const indeg = new Array<number>(n).fill(0);\n for (const [u, v] of kept) {\n keptOut[u]?.push(v);\n indeg[v] = (indeg[v] as number) + 1;\n }\n const rank = new Array<number>(n).fill(0);\n const queue: number[] = [];\n for (let i = 0; i < n; i++) if (indeg[i] === 0) queue.push(i);\n for (let qi = 0; qi < queue.length; qi++) {\n const u = queue[qi] as number;\n for (const v of keptOut[u] as number[]) {\n rank[v] = Math.max(rank[v] as number, (rank[u] as number) + 1);\n indeg[v] = (indeg[v] as number) - 1;\n if (indeg[v] === 0) queue.push(v);\n }\n }\n\n const maxRank = Math.max(...rank);\n const layers: number[][] = Array.from({ length: maxRank + 1 }, () => []);\n for (let i = 0; i < n; i++) layers[rank[i] as number]?.push(i);\n\n // Barycenter ordering: neighbors (both directions) pull a node toward\n // their average slot in the adjacent fixed layer.\n const neighbors: number[][] = Array.from({ length: n }, () => []);\n for (const [u, v] of kept) {\n neighbors[u]?.push(v);\n neighbors[v]?.push(u);\n }\n const slot = new Array<number>(n).fill(0);\n const reSlot = (): void => {\n for (const layer of layers) {\n layer.forEach((node, s) => {\n slot[node] = s;\n });\n }\n };\n reSlot();\n\n /** Wire crossings across every adjacent layer pair, under the current slots. */\n const crossings = (): number => {\n let total = 0;\n for (let li = 0; li < maxRank; li++) {\n const pairs: Array<[number, number]> = [];\n for (const [u, v] of kept) {\n if (rank[u] === li && rank[v] === li + 1) pairs.push([slot[u] as number, slot[v] as number]);\n }\n for (let i = 0; i < pairs.length; i++) {\n for (let j = i + 1; j < pairs.length; j++) {\n const a = pairs[i] as [number, number];\n const b = pairs[j] as [number, number];\n if ((a[0] - b[0]) * (a[1] - b[1]) < 0) total += 1;\n }\n }\n }\n return total;\n };\n\n // Alternating barycenter sweeps; a sweep can WORSEN crossings, so the best\n // ordering seen is kept, not the last.\n const snapshot = (): number[][] => layers.map((l) => [...l]);\n const restore = (saved: number[][]): void => {\n saved.forEach((l, li) => {\n layers[li] = [...l];\n });\n reSlot();\n };\n let best = snapshot();\n let bestX = crossings();\n for (let sweep = 0; sweep < 4 && bestX > 0; sweep++) {\n const forward = sweep % 2 === 0;\n for (let li = forward ? 1 : maxRank - 1; forward ? li <= maxRank : li >= 0; li += forward ? 1 : -1) {\n const layer = layers[li] as number[];\n const bary = (node: number): number => {\n const ns = (neighbors[node] as number[]).filter((m) => Math.abs((rank[m] as number) - li) === 1);\n if (ns.length === 0) return slot[node] as number;\n return ns.reduce((sum, m) => sum + (slot[m] as number), 0) / ns.length;\n };\n layer.sort((a, b) => bary(a) - bary(b) || a - b);\n reSlot();\n }\n const x = crossings();\n if (x < bestX) {\n bestX = x;\n best = snapshot();\n }\n }\n restore(best);\n\n // Transpose refinement (the classic Sugiyama tail): adjacent swaps that\n // STRICTLY reduce crossings, until a quiet round. Catches the barycenter's\n // tie stalls.\n let improved = bestX > 0;\n for (let round = 0; round < 4 && improved; round++) {\n improved = false;\n for (const layer of layers) {\n for (let s = 0; s + 1 < layer.length; s++) {\n const a = layer[s] as number;\n const b = layer[s + 1] as number;\n layer[s] = b;\n layer[s + 1] = a;\n reSlot();\n const x = crossings();\n if (x < bestX) {\n bestX = x;\n improved = true;\n } else {\n layer[s] = a;\n layer[s + 1] = b;\n reSlot();\n }\n }\n }\n }\n\n // Coordinates. Column widths first; then the column run is partitioned\n // into bands (single band unless maxWidth demands wrapping); each band\n // flows left→right from x=0, stacks below the previous with a 2×gapY\n // separator, and centers its columns on the band's tallest.\n const colW = (layers as number[][]).map((layer) => {\n let widest = 0;\n for (const node of layer) widest = Math.max(widest, (nodes[node] as LayoutSize).w);\n return widest;\n });\n const colH = (layers as number[][]).map((layer) =>\n layer.reduce((sum, node, i) => sum + (nodes[node] as LayoutSize).h + (i > 0 ? opts.gapY : 0), 0),\n );\n\n const bands: number[][] = [];\n if (opts.maxWidth === undefined) {\n bands.push((layers as number[][]).map((_, li) => li));\n } else {\n let cur: number[] = [];\n let width = 0;\n for (let li = 0; li <= maxRank; li++) {\n const grown = (cur.length > 0 ? width + opts.gapX : 0) + (colW[li] as number);\n if (cur.length > 0 && grown > opts.maxWidth) {\n bands.push(cur);\n cur = [li];\n width = colW[li] as number;\n } else {\n cur.push(li);\n width = grown;\n }\n }\n if (cur.length > 0) bands.push(cur);\n }\n\n const out = new Array<{ x: number; y: number }>(n);\n let bandTop = 0;\n for (const band of bands) {\n let tallest = 0;\n for (const li of band) tallest = Math.max(tallest, colH[li] as number);\n let x = 0;\n for (const li of band) {\n let y = bandTop + (tallest - (colH[li] as number)) / 2;\n for (const node of layers[li] as number[]) {\n out[node] = { x, y };\n y += (nodes[node] as LayoutSize).h + opts.gapY;\n }\n x += (colW[li] as number) + opts.gapX;\n }\n bandTop += tallest + opts.gapY * 2;\n }\n return out;\n}\n","/**\n * @ice/kernel — pure math. Plain structs in, plain structs out.\n * Import wall: nothing but `rbush` (named exception — zero-dep R-tree).\n */\nexport const KERNEL_VERSION = \"0.0.0\";\n\nexport * from \"./shapes\";\nexport * from \"./coords\";\nexport * from \"./snap\";\nexport * from \"./spatial-index\";\nexport * from \"./zoom-bands\";\nexport * from \"./eviction\";\nexport * from \"./anchors\";\nexport * from \"./bezier\";\nexport * from \"./easing\";\nexport * from \"./nav-flight\";\nexport * from \"./layout\";\n"],"mappings":"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","names":["d1","d2"]}
|