@vibecook/ice 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/README.md +37 -2
  2. package/dist/chunk-5SJYHQI4.js +636 -0
  3. package/dist/chunk-5SJYHQI4.js.map +1 -0
  4. package/dist/{chunk-5S7GSXJG.js → chunk-DXU3RZZS.js} +2913 -1180
  5. package/dist/chunk-DXU3RZZS.js.map +1 -0
  6. package/dist/{chunk-FIAXPNNY.js → chunk-IASTQMU5.js} +130 -551
  7. package/dist/chunk-IASTQMU5.js.map +1 -0
  8. package/dist/{chunk-BCJ47SX7.js → chunk-OR5FNVUE.js} +460 -1
  9. package/dist/chunk-OR5FNVUE.js.map +1 -0
  10. package/dist/devtools.js +508 -372
  11. package/dist/devtools.js.map +1 -1
  12. package/dist/dom.js +3 -11
  13. package/dist/ground.js +715 -0
  14. package/dist/ground.js.map +1 -0
  15. package/dist/index.js +70 -2
  16. package/dist/kernel.js +31 -1
  17. package/dist/r3f.js +599 -62
  18. package/dist/r3f.js.map +1 -1
  19. package/dist/react.js +34 -418
  20. package/dist/react.js.map +1 -1
  21. package/dist/types/packages/core/src/catalog/camera-derived.d.ts +41 -3
  22. package/dist/types/packages/core/src/catalog/gesture.d.ts +39 -3
  23. package/dist/types/packages/core/src/catalog/graph.d.ts +7 -6
  24. package/dist/types/packages/core/src/catalog/index.d.ts +1 -0
  25. package/dist/types/packages/core/src/catalog/insert.d.ts +31 -0
  26. package/dist/types/packages/core/src/catalog/pointer.d.ts +11 -0
  27. package/dist/types/packages/core/src/catalog/scene.d.ts +37 -4
  28. package/dist/types/packages/core/src/catalog/selection-presence.d.ts +7 -0
  29. package/dist/types/packages/core/src/catalog/settings-resources.d.ts +21 -0
  30. package/dist/types/packages/core/src/doc/autosave.d.ts +15 -2
  31. package/dist/types/packages/core/src/doc/bootstrap.d.ts +29 -0
  32. package/dist/types/packages/core/src/doc/channels.d.ts +9 -0
  33. package/dist/types/packages/core/src/doc/doc-commit-sink.d.ts +2 -1
  34. package/dist/types/packages/core/src/doc/doc-kit.d.ts +16 -1
  35. package/dist/types/packages/core/src/doc/envelope.d.ts +2 -1
  36. package/dist/types/packages/core/src/doc/migrate.d.ts +8 -6
  37. package/dist/types/packages/core/src/doc/schema-migrate.d.ts +50 -0
  38. package/dist/types/packages/core/src/doc/version-gate.d.ts +3 -0
  39. package/dist/types/packages/core/src/engine/commit-sink.d.ts +24 -2
  40. package/dist/types/packages/core/src/engine/frame-info.d.ts +16 -1
  41. package/dist/types/packages/core/src/facade/create-canvas-engine.d.ts +70 -6
  42. package/dist/types/packages/core/src/guards/guarded-tx.d.ts +4 -2
  43. package/dist/types/packages/core/src/helpers/churn-guard.d.ts +40 -0
  44. package/dist/types/packages/core/src/index.d.ts +13 -7
  45. package/dist/types/packages/core/src/input/queue.d.ts +11 -0
  46. package/dist/types/packages/core/src/nav/nested-canvas.d.ts +47 -11
  47. package/dist/types/packages/core/src/ops/arrange.d.ts +15 -0
  48. package/dist/types/packages/core/src/ops/insert.d.ts +62 -0
  49. package/dist/types/packages/core/src/ops/point-pick.d.ts +11 -7
  50. package/dist/types/packages/core/src/ops/sibling-order.d.ts +70 -0
  51. package/dist/types/packages/core/src/schema/meta.d.ts +1 -0
  52. package/dist/types/packages/core/src/settings/defaults.d.ts +45 -0
  53. package/dist/types/packages/core/src/settings/ground-config.d.ts +55 -0
  54. package/dist/types/packages/core/src/systems/chrome.d.ts +6 -2
  55. package/dist/types/packages/core/src/systems/insert-ghost.d.ts +25 -0
  56. package/dist/types/packages/core/src/systems/l1-pick.d.ts +25 -11
  57. package/dist/types/packages/core/src/systems/l2-recognize.d.ts +10 -4
  58. package/dist/types/packages/core/src/systems/l3-behave.d.ts +6 -4
  59. package/dist/types/packages/core/src/systems/l3-claim.d.ts +7 -3
  60. package/dist/types/packages/core/src/systems/l3-drop.d.ts +3 -1
  61. package/dist/types/packages/core/src/systems/l3-resize.d.ts +3 -1
  62. package/dist/types/packages/core/src/systems/l3-snap.d.ts +25 -7
  63. package/dist/types/packages/core/src/systems/nav-flight.d.ts +95 -0
  64. package/dist/types/packages/core/src/widget/define-widget.d.ts +39 -0
  65. package/dist/types/packages/core/src/widget/mount-store.d.ts +11 -3
  66. package/dist/types/packages/core/src/widget/set-props.d.ts +16 -0
  67. package/dist/types/packages/core/src/widget/spawn.d.ts +21 -1
  68. package/dist/types/packages/devtools/src/attach.d.ts +77 -0
  69. package/dist/types/packages/devtools/src/dock.d.ts +38 -0
  70. package/dist/types/packages/devtools/src/gl-panel.d.ts +69 -0
  71. package/dist/types/packages/devtools/src/index.d.ts +8 -6
  72. package/dist/types/packages/dom/src/index.d.ts +1 -3
  73. package/dist/types/packages/dom/src/measure-wiring.d.ts +2 -2
  74. package/dist/types/packages/dom/src/pointer-adapter.d.ts +21 -1
  75. package/dist/types/packages/dom/src/reflectors/dom-widgets.d.ts +5 -0
  76. package/dist/types/packages/ground/src/index.d.ts +52 -0
  77. package/dist/types/packages/ground/src/layer.d.ts +40 -0
  78. package/dist/types/packages/ground/src/pass.d.ts +41 -0
  79. package/dist/types/packages/ground/src/passes/grid.d.ts +21 -0
  80. package/dist/types/packages/ground/src/passes/guides-collect.d.ts +14 -0
  81. package/dist/types/packages/ground/src/passes/guides.d.ts +3 -0
  82. package/dist/types/packages/ground/src/passes/soup-collect.d.ts +35 -0
  83. package/dist/types/packages/ground/src/passes/soup-mesh.d.ts +8 -0
  84. package/dist/types/packages/ground/src/passes/wires-collect.d.ts +31 -0
  85. package/dist/types/packages/ground/src/passes/wires.d.ts +10 -0
  86. package/dist/types/packages/ground/src/renderer.d.ts +15 -0
  87. package/dist/types/packages/ice/src/ground.d.ts +1 -0
  88. package/dist/types/packages/kernel/src/bezier.d.ts +15 -0
  89. package/dist/types/packages/kernel/src/coords.d.ts +15 -0
  90. package/dist/types/packages/kernel/src/easing.d.ts +11 -0
  91. package/dist/types/packages/kernel/src/index.d.ts +3 -0
  92. package/dist/types/packages/kernel/src/layout.d.ts +118 -0
  93. package/dist/types/packages/kernel/src/nav-flight.d.ts +93 -0
  94. package/dist/types/packages/r3f/src/bridge.d.ts +73 -12
  95. package/dist/types/packages/r3f/src/composite-material.d.ts +9 -0
  96. package/dist/types/packages/r3f/src/compositor-pass.d.ts +22 -0
  97. package/dist/types/packages/r3f/src/gl-root.d.ts +76 -1
  98. package/dist/types/packages/r3f/src/gl-router.d.ts +10 -0
  99. package/dist/types/packages/r3f/src/index.d.ts +3 -2
  100. package/dist/types/packages/r3f/src/island-state.d.ts +44 -0
  101. package/dist/types/packages/r3f/src/preview-capture.d.ts +19 -0
  102. package/dist/types/packages/r3f/src/self-sustain.d.ts +39 -0
  103. package/dist/types/packages/r3f/src/use-island-frame.d.ts +16 -1
  104. package/dist/types/packages/react/src/engine-context.d.ts +8 -0
  105. package/dist/types/packages/react/src/index.d.ts +4 -2
  106. package/dist/types/packages/react/src/infinite-canvas.d.ts +40 -6
  107. package/dist/types/packages/react/src/preview-snapshots.d.ts +17 -0
  108. package/dist/types/packages/react/src/widget-preview.d.ts +14 -0
  109. package/package.json +13 -8
  110. package/dist/chunk-5S7GSXJG.js.map +0 -1
  111. package/dist/chunk-BCJ47SX7.js.map +0 -1
  112. package/dist/chunk-FIAXPNNY.js.map +0 -1
  113. package/dist/types/packages/devtools/src/panel.d.ts +0 -48
  114. package/dist/types/packages/dom/src/reflectors/grid.d.ts +0 -63
  115. package/dist/types/packages/dom/src/reflectors/wires.d.ts +0 -88
@@ -0,0 +1 @@
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/reflectors/dom-widgets.ts","../../dom/src/loop.ts","../../dom/src/pointer-adapter.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 * 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\";\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 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; the next dirt re-asserts the order).\n */\n function updateOrder(): void {\n const ordinals = order.ordinals();\n for (const plane of [host.contentPlane, host.liftedPlane]) {\n const active = doc.activeElement;\n if (active !== null && active !== doc.body && plane.contains(active)) continue;\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 }\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.\n if (orderDirty || membershipChanged) {\n orderDirty = false;\n 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 */\nimport type { Engine } from \"@ice/core\";\n\nexport function startRafLoop(engine: Engine): () => void {\n let handle = 0;\n let stopped = false;\n\n const tick = (now: number): void => {\n if (stopped) return;\n engine.step(now);\n handle = requestAnimationFrame(tick);\n };\n\n handle = requestAnimationFrame(tick);\n\n return () => {\n stopped = true;\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, and Space `preventDefault`s to stop page scroll;\n * - wheel `preventDefault`s: a ctrl-wheel / trackpad pinch becomes `wheel.pinch`\n * (the zoom signal), a plain wheel becomes dx/dy (deltaMode lines → px ×16);\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\";\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 e.preventDefault(); // own zoom/pan — never let the page scroll\n const { x, y } = relative(e.clientX, e.clientY);\n const scale = e.deltaMode === 1 ? WHEEL_LINE_PX : 1; // DOM_DELTA_LINE → px\n const wheel = e.ctrlKey\n ? { dx: 0, dy: 0, pinch: e.deltaY } // ctrl-wheel / trackpad pinch = zoom signal\n : { dx: e.deltaX * scale, dy: e.deltaY * scale, pinch: 0 };\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)) {\n e.preventDefault(); // Space would otherwise page-scroll\n spaceHeld = true;\n }\n emitKeyIfChanged(e);\n };\n const onKeyUp = (e: KeyboardEvent): void => {\n if (isSpace(e)) {\n e.preventDefault();\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 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// 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"]}