incanto 0.33.0 → 0.34.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 (42) hide show
  1. package/dist/2d.d.ts +2 -2
  2. package/dist/2d.js +3 -3
  3. package/dist/3d.d.ts +3 -3
  4. package/dist/3d.js +4 -4
  5. package/dist/{behavior-CKwTCjfR.d.ts → behavior-CtPScDMo.d.ts} +9 -0
  6. package/dist/{create-game-D2QU5x7S.js → create-game-CFNqoqOX.js} +5 -5
  7. package/dist/{create-game-sFuTLqjD.js → create-game-QTfghzwM.js} +5 -5
  8. package/dist/debug.d.ts +1 -1
  9. package/dist/{duplicate-BgnG1Lqz.js → duplicate-DlOvknDO.js} +1 -1
  10. package/dist/{environment-presets-CQtEGogB.js → environment-presets-B6WiUsaO.js} +2 -2
  11. package/dist/{gameplay-BpQCbABv.js → gameplay-BxFtmfSe.js} +2 -2
  12. package/dist/gameplay.d.ts +1 -1
  13. package/dist/gameplay.js +1 -1
  14. package/dist/index.d.ts +53 -3
  15. package/dist/index.js +4 -4
  16. package/dist/{loader-Buk8Bu1h.js → loader-BwR0DxeM.js} +13 -0
  17. package/dist/{loader-COn5fS0o.d.ts → loader-DmXfj6Uv.d.ts} +1 -1
  18. package/dist/net.d.ts +1 -1
  19. package/dist/net.js +3 -3
  20. package/dist/{pathfinding-DUw9mir9.d.ts → pathfinding-DRCe89SI.d.ts} +1 -1
  21. package/dist/{physics-2d-DjXR5DMu.js → physics-2d-BuyAwsW5.js} +2 -2
  22. package/dist/{physics-3d-DF8npb1O.js → physics-3d-C8Kn_Nyb.js} +3 -3
  23. package/dist/react.d.ts +1 -1
  24. package/dist/react.js +1 -1
  25. package/dist/{register-FIJtNbub.js → register-BLPC10Mj.js} +3 -3
  26. package/dist/{register-CscIzJEO.js → register-G3edsjJ2.js} +208 -10
  27. package/dist/{register-CtI-itec.js → register-OodmuUMK.js} +2 -2
  28. package/dist/{test-BRxLd2jH.js → test-C4B5znap.js} +10 -10
  29. package/dist/test.d.ts +2 -2
  30. package/dist/test.js +1 -1
  31. package/dist/vite.js +1 -1
  32. package/editor/assets/{agent8-BdDP3xKW.js → agent8-BTODHtdM.js} +1 -1
  33. package/editor/assets/{debug-DbjTyTlC.js → debug-CJEz4EwC.js} +1 -1
  34. package/editor/assets/{index-BWCudoz1.js → index-BYCso8Bf.js} +90 -90
  35. package/editor/index.html +1 -1
  36. package/package.json +1 -1
  37. package/schemas/scene.schema.json +142 -6
  38. package/skills/incanto-hud.md +57 -1
  39. package/skills/incanto-node-reference.md +45 -6
  40. package/templates-app/beacon-isle-3d/package.json +1 -1
  41. package/templates-app/tps-3d/package.json +1 -1
  42. package/templates-app/village-quest-3d/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { f as Node, h as InputMap, x as Signal } from "./loader-Buk8Bu1h.js";
1
+ import { f as Node, h as InputMap, x as Signal } from "./loader-BwR0DxeM.js";
2
2
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
3
3
  import { t as Rng } from "./rng-DP-SR7eg.js";
4
4
  import { l as registerNode } from "./registry-CJdGpT2V.js";
@@ -1727,10 +1727,17 @@ var HudLayer = class extends Node {
1727
1727
  static typeName = "HudLayer";
1728
1728
  static props = {
1729
1729
  zIndex: { default: 100 },
1730
- visible: { default: true }
1730
+ visible: { default: true },
1731
+ /**
1732
+ * Arrow keys / d-pad move focus between the focusable widgets under this
1733
+ * layer, Enter / A activates. OFF by default — a game whose HUD has a
1734
+ * button must not lose its arrow keys the moment one exists.
1735
+ */
1736
+ focusNavigation: { default: false }
1731
1737
  };
1732
1738
  zIndex = 100;
1733
1739
  visible = true;
1740
+ focusNavigation = false;
1734
1741
  /** @internal root overlay element (null headless). */
1735
1742
  _element = null;
1736
1743
  slots = /* @__PURE__ */ new Map();
@@ -1771,6 +1778,66 @@ var HudLayer = class extends Node {
1771
1778
  this._mount();
1772
1779
  this._element.style.display = this.visible ? "" : "none";
1773
1780
  }
1781
+ if (this.focusNavigation) this.stepFocus();
1782
+ }
1783
+ /**
1784
+ * Arrow keys / d-pad move the focus, Enter / A activates it.
1785
+ *
1786
+ * Off by default: a game whose HUD has a button must not lose its arrow keys
1787
+ * to a menu the moment one exists. Turn it on for the screens that ARE menus
1788
+ * (`"focusNavigation": true` on the pause panel's layer), and off again when
1789
+ * play resumes.
1790
+ */
1791
+ stepFocus() {
1792
+ const engine = this.tree?.engine;
1793
+ if (!engine) return;
1794
+ const items = this.focusables();
1795
+ if (items.length === 0) return;
1796
+ const input = engine.input;
1797
+ const down = input.keyJustPressed("ArrowDown") || input.keyJustPressed("Pad13");
1798
+ const up = input.keyJustPressed("ArrowUp") || input.keyJustPressed("Pad12");
1799
+ const left = input.keyJustPressed("ArrowLeft") || input.keyJustPressed("Pad14");
1800
+ const right = input.keyJustPressed("ArrowRight") || input.keyJustPressed("Pad15");
1801
+ const confirm = input.keyJustPressed("Enter") || input.keyJustPressed("Pad0");
1802
+ let index = items.findIndex((w) => w._focused);
1803
+ if (index === -1 && (down || up || confirm)) index = 0;
1804
+ else if (down) index = (index + 1) % items.length;
1805
+ else if (up) index = (index - 1 + items.length) % items.length;
1806
+ if (index !== -1) {
1807
+ for (const w of items) {
1808
+ const next = w === items[index];
1809
+ if (next !== w._focused) {
1810
+ w._focused = next;
1811
+ w._paintFocus();
1812
+ }
1813
+ }
1814
+ const focused = items[index];
1815
+ if (focused) {
1816
+ if (confirm) focused._activate(0);
1817
+ else if (left) focused._activate(-1);
1818
+ else if (right) focused._activate(1);
1819
+ }
1820
+ }
1821
+ }
1822
+ /** Focusable widgets under this layer, in tree order. */
1823
+ focusables() {
1824
+ const out = [];
1825
+ const walk = (node) => {
1826
+ if (node instanceof HudWidgetBase && node.focusable && node.visible) out.push(node);
1827
+ for (const child of node.children) walk(child);
1828
+ };
1829
+ walk(this);
1830
+ return out;
1831
+ }
1832
+ /** Move focus to a widget by hand — opening a menu should start somewhere. */
1833
+ focus(widget) {
1834
+ for (const w of this.focusables()) {
1835
+ const next = w === widget;
1836
+ if (next !== w._focused) {
1837
+ w._focused = next;
1838
+ w._paintFocus();
1839
+ }
1840
+ }
1774
1841
  }
1775
1842
  /** @internal Widgets mount into per-anchor flex columns. */
1776
1843
  _slot(anchor) {
@@ -1785,6 +1852,22 @@ var HudLayer = class extends Node {
1785
1852
  return slot;
1786
1853
  }
1787
1854
  };
1855
+ /**
1856
+ * The widget an element belongs to.
1857
+ *
1858
+ * A pick lands on whatever div is under the cursor — usually a CHILD of the
1859
+ * widget (an icon inside a slot), so the walk upward is the point.
1860
+ */
1861
+ const widgetOf = /* @__PURE__ */ new WeakMap();
1862
+ function widgetFromElement(el) {
1863
+ for (let n = el; n; n = n.parentElement) {
1864
+ const found = widgetOf.get(n);
1865
+ if (found) return found;
1866
+ }
1867
+ return null;
1868
+ }
1869
+ /** The drag in flight, if any. One pointer, one drag. */
1870
+ let dragging = null;
1788
1871
  /** Shared plumbing: mount into the parent HudLayer's anchor slot. */
1789
1872
  var HudWidgetBase = class extends Node {
1790
1873
  static props = {
@@ -1802,10 +1885,46 @@ var HudWidgetBase = class extends Node {
1802
1885
  "bottomRight"
1803
1886
  ]
1804
1887
  },
1805
- visible: { default: true }
1888
+ visible: { default: true },
1889
+ /**
1890
+ * Can menu navigation land on this? Interactive widgets default to true.
1891
+ *
1892
+ * A menu you can only click is not playable on a controller, and "add
1893
+ * gamepad support" is not a thing a JSON scene could express at all.
1894
+ */
1895
+ focusable: { default: false },
1896
+ /**
1897
+ * Can the player pick this up and drop it somewhere? An inventory item is
1898
+ * a `draggable` widget; a slot is a `dropTarget`.
1899
+ */
1900
+ draggable: { default: false },
1901
+ /** Can something be dropped ON this? */
1902
+ dropTarget: { default: false }
1806
1903
  };
1904
+ static signals = [
1905
+ "dragStarted",
1906
+ "dragCancelled",
1907
+ "droppedOn",
1908
+ "dropped"
1909
+ ];
1807
1910
  anchor = "topLeft";
1808
1911
  visible = true;
1912
+ focusable = false;
1913
+ draggable = false;
1914
+ dropTarget = false;
1915
+ /** @internal Set by the owning HudLayer while this widget has focus. */
1916
+ _focused = false;
1917
+ /**
1918
+ * @internal Confirm (`dir` 0) or nudge (-1 left / +1 right) — what pressing
1919
+ * A or an arrow ON this widget means. Default: nothing.
1920
+ */
1921
+ _activate(_dir) {}
1922
+ /** @internal Draw the focus ring. Overridable if a widget wants its own. */
1923
+ _paintFocus() {
1924
+ if (!this._element) return;
1925
+ this._element.style.outline = this._focused ? "2px solid #6ee7dc" : "";
1926
+ this._element.style.outlineOffset = this._focused ? "2px" : "";
1927
+ }
1809
1928
  /** @internal */
1810
1929
  _element = null;
1811
1930
  layer() {
@@ -1830,8 +1949,45 @@ var HudWidgetBase = class extends Node {
1830
1949
  const host = this.host() ?? this.layer()?._slot(this.anchor);
1831
1950
  if (!host) return;
1832
1951
  this._element = this._build();
1952
+ widgetOf.set(this._element, this);
1953
+ if (this.draggable || this.dropTarget) this._wireDrag(this._element);
1833
1954
  host.appendChild(this._element);
1834
1955
  }
1956
+ /**
1957
+ * Drag and drop, on the DOM the engine already builds.
1958
+ *
1959
+ * An inventory is the one screen where "click it" is not enough, and every
1960
+ * game that wanted one dropped out of scene JSON to hand-roll pointer
1961
+ * handlers. The whole gesture is four signals and no new node type: a
1962
+ * `draggable` widget emits `dragStarted` and, if it lands on one,
1963
+ * `droppedOn(target)`; a `dropTarget` emits `dropped(source)`. Who owns the
1964
+ * ITEM is the game's business — this reports the gesture, not a model.
1965
+ */
1966
+ _wireDrag(el) {
1967
+ el.style.touchAction = "none";
1968
+ if (this.draggable) {
1969
+ el.style.cursor = "grab";
1970
+ el.addEventListener("pointerdown", (event) => {
1971
+ if (!this.draggable) return;
1972
+ event.preventDefault();
1973
+ el.setPointerCapture?.(event.pointerId);
1974
+ dragging = this;
1975
+ el.style.opacity = "0.6";
1976
+ this.emit("dragStarted", this);
1977
+ });
1978
+ el.addEventListener("pointerup", (event) => {
1979
+ if (dragging !== this) return;
1980
+ el.style.opacity = "";
1981
+ el.releasePointerCapture?.(event.pointerId);
1982
+ const target = widgetFromElement(document.elementFromPoint?.(event.clientX, event.clientY) ?? null);
1983
+ dragging = null;
1984
+ if (target && target !== this && target.dropTarget) {
1985
+ this.emit("droppedOn", target);
1986
+ target.emit("dropped", this);
1987
+ } else this.emit("dragCancelled", this);
1988
+ });
1989
+ }
1990
+ }
1835
1991
  /** The nearest ancestor that holds widgets itself (a UiPanel). */
1836
1992
  host() {
1837
1993
  for (let p = this.parent; p; p = p.parent) {
@@ -2035,13 +2191,19 @@ var UiButton = class extends HudWidgetBase {
2035
2191
  size: { default: 16 },
2036
2192
  color: { default: "#ffffff" },
2037
2193
  background: { default: "rgba(255,255,255,0.14)" },
2038
- disabled: { default: false }
2194
+ disabled: { default: false },
2195
+ focusable: { default: true }
2039
2196
  };
2040
2197
  text = "OK";
2041
2198
  size = 16;
2042
2199
  color = "#ffffff";
2043
2200
  background = "rgba(255,255,255,0.14)";
2044
2201
  disabled = false;
2202
+ focusable = true;
2203
+ /** Enter / A on a focused button is a press. */
2204
+ _activate(_dir) {
2205
+ this.press();
2206
+ }
2045
2207
  lastText = "";
2046
2208
  /** Programmatic press — same path as a click (tests, gamepad menus). */
2047
2209
  press() {
@@ -2419,9 +2581,10 @@ var UiSlider = class extends HudWidgetBase {
2419
2581
  max: { default: 1 },
2420
2582
  step: { default: .01 },
2421
2583
  width: { default: 180 },
2422
- color: { default: "#6ee7dc" }
2584
+ color: { default: "#6ee7dc" },
2585
+ focusable: { default: true }
2423
2586
  };
2424
- static signals = ["changed"];
2587
+ static signals = [...HudWidgetBase.signals, "changed"];
2425
2588
  label = "";
2426
2589
  value = .5;
2427
2590
  min = 0;
@@ -2429,6 +2592,17 @@ var UiSlider = class extends HudWidgetBase {
2429
2592
  step = .01;
2430
2593
  width = 180;
2431
2594
  color = "#6ee7dc";
2595
+ focusable = true;
2596
+ /** Left/right nudge by one step — the only sane thing a d-pad can mean here. */
2597
+ _activate(dir) {
2598
+ if (dir === 0) return;
2599
+ const next = Math.min(this.max, Math.max(this.min, this.value + dir * this.step));
2600
+ if (next === this.value) return;
2601
+ this.value = next;
2602
+ this.last = next;
2603
+ if (this.input) this.input.value = String(next);
2604
+ this.emit("changed", next);
2605
+ }
2432
2606
  input = null;
2433
2607
  text = null;
2434
2608
  last = NaN;
@@ -2470,11 +2644,22 @@ var UiToggle = class extends HudWidgetBase {
2470
2644
  static props = {
2471
2645
  ...HudWidgetBase.props,
2472
2646
  label: { default: "" },
2473
- value: { default: false }
2647
+ value: { default: false },
2648
+ focusable: { default: true }
2474
2649
  };
2475
- static signals = ["changed"];
2650
+ static signals = [...HudWidgetBase.signals, "changed"];
2476
2651
  label = "";
2477
2652
  value = false;
2653
+ focusable = true;
2654
+ /** Confirm flips it; left/right set it explicitly, which reads better on a pad. */
2655
+ _activate(dir) {
2656
+ const next = dir === 0 ? !this.value : dir > 0;
2657
+ if (next === this.value) return;
2658
+ this.value = next;
2659
+ this.last = next;
2660
+ if (this.input) this.input.checked = next;
2661
+ this.emit("changed", next);
2662
+ }
2478
2663
  input = null;
2479
2664
  last = null;
2480
2665
  _build() {
@@ -2510,12 +2695,25 @@ var UiSelect = class extends HudWidgetBase {
2510
2695
  label: { default: "" },
2511
2696
  /** Comma-separated choices: `"low,medium,high"`. */
2512
2697
  options: { default: "" },
2513
- value: { default: "" }
2698
+ value: { default: "" },
2699
+ focusable: { default: true }
2514
2700
  };
2515
- static signals = ["changed"];
2701
+ static signals = [...HudWidgetBase.signals, "changed"];
2516
2702
  label = "";
2517
2703
  options = "";
2518
2704
  value = "";
2705
+ focusable = true;
2706
+ /** Left/right (and confirm) walk the list — a select has no other gesture. */
2707
+ _activate(dir) {
2708
+ const choices = this.options.split(",").map((o) => o.trim()).filter(Boolean);
2709
+ if (choices.length === 0) return;
2710
+ const next = choices[(Math.max(0, choices.indexOf(this.value)) + (dir === 0 ? 1 : dir) + choices.length) % choices.length];
2711
+ if (!next || next === this.value) return;
2712
+ this.value = next;
2713
+ this.last = next;
2714
+ if (this.select) this.select.value = next;
2715
+ this.emit("changed", next);
2716
+ }
2519
2717
  select = null;
2520
2718
  lastOptions = "\0";
2521
2719
  last = "\0";
@@ -1,5 +1,5 @@
1
- import { f as Node, t as buildNodeJson, x as Signal } from "./loader-Buk8Bu1h.js";
2
- import { t as registerCoreNodes } from "./register-CscIzJEO.js";
1
+ import { f as Node, t as buildNodeJson, x as Signal } from "./loader-BwR0DxeM.js";
2
+ import { t as registerCoreNodes } from "./register-G3edsjJ2.js";
3
3
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
4
4
  import { n as jsonEquals, t as jsonClone } from "./json-BLk7H2Qa.js";
5
5
  import { l as registerNode } from "./registry-CJdGpT2V.js";
@@ -1,12 +1,12 @@
1
- import { n as loadScene, y as registerBehavior } from "./loader-Buk8Bu1h.js";
2
- import { h as Engine } from "./register-CscIzJEO.js";
1
+ import { n as loadScene, y as registerBehavior } from "./loader-BwR0DxeM.js";
2
+ import { h as Engine } from "./register-G3edsjJ2.js";
3
3
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
4
4
  import { n as jsonEquals, t as jsonClone } from "./json-BLk7H2Qa.js";
5
5
  import { i as getNodeSchema, s as mergeStaticProps } from "./registry-CJdGpT2V.js";
6
- import { n as registerGameplayBehaviors } from "./gameplay-BpQCbABv.js";
7
- import { t as registerNodes2D } from "./register-FIJtNbub.js";
8
- import { n as registerNodes3D, t as resolveEnvironmentHdri } from "./environment-presets-CQtEGogB.js";
9
- import { t as registerNodesNet } from "./register-CtI-itec.js";
6
+ import { n as registerGameplayBehaviors } from "./gameplay-BxFtmfSe.js";
7
+ import { t as registerNodes2D } from "./register-BLPC10Mj.js";
8
+ import { n as registerNodes3D, t as resolveEnvironmentHdri } from "./environment-presets-B6WiUsaO.js";
9
+ import { t as registerNodesNet } from "./register-OodmuUMK.js";
10
10
  import { Box3, Euler, Matrix4, PerspectiveCamera, Quaternion, Vector3 } from "three";
11
11
  //#region src/test/framing.ts
12
12
  /**
@@ -482,10 +482,10 @@ async function runScript(json, opts) {
482
482
  engine.setScene(scene);
483
483
  const physics = opts.physics ?? "auto";
484
484
  if (physics === "2d" || physics === "auto" && scene.dimension === "2d") {
485
- const { enablePhysics2D } = await import("./physics-2d-DjXR5DMu.js").then((n) => n.r);
485
+ const { enablePhysics2D } = await import("./physics-2d-BuyAwsW5.js").then((n) => n.r);
486
486
  await enablePhysics2D(engine);
487
487
  } else if (physics === "3d" || physics === "auto" && scene.dimension === "3d") {
488
- const { enablePhysics3D } = await import("./physics-3d-DF8npb1O.js").then((n) => n.r);
488
+ const { enablePhysics3D } = await import("./physics-3d-C8Kn_Nyb.js").then((n) => n.r);
489
489
  await enablePhysics3D(engine);
490
490
  }
491
491
  const failures = [];
@@ -598,10 +598,10 @@ async function createPlaySession(json, opts = {}) {
598
598
  engine.setScene(scene);
599
599
  const physics = opts.physics ?? "auto";
600
600
  if (physics === "2d" || physics === "auto" && scene.dimension === "2d") {
601
- const { enablePhysics2D } = await import("./physics-2d-DjXR5DMu.js").then((n) => n.r);
601
+ const { enablePhysics2D } = await import("./physics-2d-BuyAwsW5.js").then((n) => n.r);
602
602
  await enablePhysics2D(engine);
603
603
  } else if (physics === "3d" || physics === "auto" && scene.dimension === "3d") {
604
- const { enablePhysics3D } = await import("./physics-3d-DF8npb1O.js").then((n) => n.r);
604
+ const { enablePhysics3D } = await import("./physics-3d-C8Kn_Nyb.js").then((n) => n.r);
605
605
  await enablePhysics3D(engine);
606
606
  }
607
607
  const stepMs = 1e3 / (opts.fixedHz ?? 60);
package/dist/test.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { N as Scene, at as Node, ct as LogEntry, n as BehaviorCtor, v as Engine } from "./behavior-CKwTCjfR.js";
1
+ import { N as Scene, at as Node, ct as LogEntry, n as BehaviorCtor, v as Engine } from "./behavior-CtPScDMo.js";
2
2
  import { c as JsonValue, i as SceneJson } from "./schema-CcoWb32N.js";
3
- import { t as LoadSceneOptions } from "./loader-COn5fS0o.js";
3
+ import { t as LoadSceneOptions } from "./loader-DmXfj6Uv.js";
4
4
  import { i as auditScene, t as IncantoError } from "./errors-1dXlIwoR.js";
5
5
 
6
6
  //#region src/test/framing.d.ts
package/dist/test.js CHANGED
@@ -1,3 +1,3 @@
1
1
  import { t as auditScene } from "./audit-C4kmDK0o.js";
2
- import { a as registerAllNodes, c as describeFraming, i as findFloatingProps, l as framingText, n as createPlaySession, o as runScript, r as describeCapture, s as validateScene, t as captureScene } from "./test-BRxLd2jH.js";
2
+ import { a as registerAllNodes, c as describeFraming, i as findFloatingProps, l as framingText, n as createPlaySession, o as runScript, r as describeCapture, s as validateScene, t as captureScene } from "./test-C4B5znap.js";
3
3
  export { auditScene, captureScene, createPlaySession, describeCapture, describeFraming, findFloatingProps, framingText, registerAllNodes, runScript, validateScene };
package/dist/vite.js CHANGED
@@ -1,4 +1,4 @@
1
- import { s as validateScene } from "./test-BRxLd2jH.js";
1
+ import { s as validateScene } from "./test-C4B5znap.js";
2
2
  import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
3
3
  import { basename, dirname, join, normalize, relative, resolve, sep } from "node:path";
4
4
  //#region src/vite/index.ts
@@ -1 +1 @@
1
- import{n as e}from"./index-BWCudoz1.js";async function t(t){return new n((await e(()=>import(`./GameServer-C56iOUgF.js`),[],import.meta.url)).GameServer,t)}var n=class{raw;active=new Map;reconnecting=!1;disposed=!1;constructor(e,t){this.raw=new e({...t})}get account(){return this.raw.account}get connected(){return this.raw.connected}connect(){return this.raw.connected?Promise.resolve(!0):(this.disposed=!1,this.rawConnect())}rawConnect(){return this.raw.connect({onDisconnect:()=>void this.reconnect()})}disconnect(){this.disposed=!0;for(let e of this.active.values())e.off();return this.active.clear(),this.raw.disconnect()}remoteFunction(e,t,n){return this.raw.remoteFunction(e,t,n)}track(e){let t=Symbol(`sub`),n={make:e,off:e()};return this.active.set(t,n),()=>{n.off(),this.active.delete(t)}}async reconnect(){if(!this.disposed&&!this.reconnecting){this.reconnecting=!0;try{await this.rawConnect();for(let e of this.active.values())e.off(),e.off=e.make()}finally{this.reconnecting=!1}}}subscribeRoomState(e,t){return this.track(()=>this.raw.subscribeRoomState(e,t))}subscribeRoomMyState(e,t){return this.track(()=>this.raw.subscribeRoomMyState(e,t))}subscribeRoomAllUserStates(e,t){return this.track(()=>this.raw.subscribeRoomAllUserStates(e,e=>{let n={};for(let t of e??[]){if(!t||typeof t.account!=`string`||t.__leaved)continue;let{account:e,__updated:r,__leaved:i,...a}=t;n[e]=a}t(n)}))}subscribeRoomCollection(e,t,n){return this.track(()=>this.raw.subscribeRoomCollection(e,t,({items:e})=>{let t={};for(let n of e??[])n&&typeof n.__id==`string`&&(t[n.__id]=n);n(t)}))}onRoomMessage(e,t,n){return this.track(()=>this.raw.onRoomMessage(e,t,n))}onRoomUserJoin(e,t){return this.track(()=>this.raw.onRoomUserJoin(e,t))}onRoomUserLeave(e,t){return this.track(()=>this.raw.onRoomUserLeave(e,t))}subscribeGlobalState(e){return this.track(()=>this.raw.subscribeGlobalState(e))}subscribeGlobalMyState(e){return this.track(()=>this.raw.subscribeGlobalMyState(e))}subscribeGlobalUserState(e,t){return this.track(()=>this.raw.subscribeGlobalUserState(e,t))}subscribeGlobalCollection(e,t){return this.track(()=>this.raw.subscribeGlobalCollection(e,({items:e})=>{let n={};for(let t of e??[])t&&typeof t.__id==`string`&&(n[t.__id]=t);t(n)}))}subscribeAsset(e,t){return this.track(()=>this.raw.subscribeAsset(e,t))}onGlobalMessage(e,t){return this.track(()=>this.raw.onGlobalMessage(e,t))}};export{t as createAgent8Server};
1
+ import{n as e}from"./index-BYCso8Bf.js";async function t(t){return new n((await e(()=>import(`./GameServer-C56iOUgF.js`),[],import.meta.url)).GameServer,t)}var n=class{raw;active=new Map;reconnecting=!1;disposed=!1;constructor(e,t){this.raw=new e({...t})}get account(){return this.raw.account}get connected(){return this.raw.connected}connect(){return this.raw.connected?Promise.resolve(!0):(this.disposed=!1,this.rawConnect())}rawConnect(){return this.raw.connect({onDisconnect:()=>void this.reconnect()})}disconnect(){this.disposed=!0;for(let e of this.active.values())e.off();return this.active.clear(),this.raw.disconnect()}remoteFunction(e,t,n){return this.raw.remoteFunction(e,t,n)}track(e){let t=Symbol(`sub`),n={make:e,off:e()};return this.active.set(t,n),()=>{n.off(),this.active.delete(t)}}async reconnect(){if(!this.disposed&&!this.reconnecting){this.reconnecting=!0;try{await this.rawConnect();for(let e of this.active.values())e.off(),e.off=e.make()}finally{this.reconnecting=!1}}}subscribeRoomState(e,t){return this.track(()=>this.raw.subscribeRoomState(e,t))}subscribeRoomMyState(e,t){return this.track(()=>this.raw.subscribeRoomMyState(e,t))}subscribeRoomAllUserStates(e,t){return this.track(()=>this.raw.subscribeRoomAllUserStates(e,e=>{let n={};for(let t of e??[]){if(!t||typeof t.account!=`string`||t.__leaved)continue;let{account:e,__updated:r,__leaved:i,...a}=t;n[e]=a}t(n)}))}subscribeRoomCollection(e,t,n){return this.track(()=>this.raw.subscribeRoomCollection(e,t,({items:e})=>{let t={};for(let n of e??[])n&&typeof n.__id==`string`&&(t[n.__id]=n);n(t)}))}onRoomMessage(e,t,n){return this.track(()=>this.raw.onRoomMessage(e,t,n))}onRoomUserJoin(e,t){return this.track(()=>this.raw.onRoomUserJoin(e,t))}onRoomUserLeave(e,t){return this.track(()=>this.raw.onRoomUserLeave(e,t))}subscribeGlobalState(e){return this.track(()=>this.raw.subscribeGlobalState(e))}subscribeGlobalMyState(e){return this.track(()=>this.raw.subscribeGlobalMyState(e))}subscribeGlobalUserState(e,t){return this.track(()=>this.raw.subscribeGlobalUserState(e,t))}subscribeGlobalCollection(e,t){return this.track(()=>this.raw.subscribeGlobalCollection(e,({items:e})=>{let n={};for(let t of e??[])t&&typeof t.__id==`string`&&(n[t.__id]=t);t(n)}))}subscribeAsset(e,t){return this.track(()=>this.raw.subscribeAsset(e,t))}onGlobalMessage(e,t){return this.track(()=>this.raw.onGlobalMessage(e,t))}};export{t as createAgent8Server};
@@ -1,3 +1,3 @@
1
- import{i as e,r as t,t as n}from"./index-BWCudoz1.js";function r(e,t,n,r,i,a,o=180,s=120){let c=Math.max(o,n),l=Math.max(s,r);return{x:Math.min(Math.max(0,e),Math.max(0,i-c)),y:Math.min(Math.max(0,t),Math.max(0,a-l)),w:c,h:l}}function i(e,t){for(let[n,r]of Object.entries(t))e.style[n]=r}var a=`rgba(18, 20, 26, 0.92)`,o=`1px solid rgba(255,255,255,0.14)`,s=`12px ui-monospace, SFMono-Regular, Menlo, monospace`,c=class{host;el;body;onClose=()=>{};x;y;w;h;constructor(e,t,n,r){this.host=t,this.x=r.x,this.y=r.y,this.w=r.w,this.h=r.h,this.el=e.createElement(`div`),i(this.el,{position:`absolute`,background:a,border:o,borderRadius:`8px`,color:`rgba(255,255,255,0.88)`,font:s,display:`flex`,flexDirection:`column`,overflow:`hidden`,zIndex:`40`,pointerEvents:`auto`,boxShadow:`0 8px 28px rgba(0,0,0,0.45)`});let c=e.createElement(`div`);c.textContent=n,i(c,{padding:`6px 28px 6px 10px`,background:`rgba(255,255,255,0.07)`,cursor:`move`,userSelect:`none`,touchAction:`none`,fontWeight:`700`}),this.el.appendChild(c);let l=e.createElement(`div`);l.textContent=`×`,l.title=`close`,i(l,{position:`absolute`,top:`2px`,right:`8px`,cursor:`pointer`,fontSize:`16px`,lineHeight:`20px`,opacity:`0.7`}),l.addEventListener(`click`,()=>this.onClose()),this.el.appendChild(l),this.body=e.createElement(`div`),i(this.body,{flex:`1`,overflow:`auto`,padding:`8px 10px`}),this.el.appendChild(this.body);let u=e.createElement(`div`);u.textContent=`◢`,i(u,{position:`absolute`,right:`2px`,bottom:`0`,cursor:`nwse-resize`,opacity:`0.5`,userSelect:`none`,touchAction:`none`}),this.el.appendChild(u),this.wireDrag(c,(e,t)=>{this.x+=e,this.y+=t,this.layout()}),this.wireDrag(u,(e,t)=>{this.w+=e,this.h+=t,this.layout()}),this.layout(),t.appendChild(this.el)}remove(){this.el.remove()}layout(){let e=this.host.getBoundingClientRect(),t=r(this.x,this.y,this.w,this.h,e.width,e.height);this.x=t.x,this.y=t.y,this.w=t.w,this.h=t.h,i(this.el,{left:`${t.x}px`,top:`${t.y}px`,width:`${t.w}px`,height:`${t.h}px`})}wireDrag(e,t){let n=null,r=0,i=0;e.addEventListener(`pointerdown`,t=>{n=t.pointerId,r=t.clientX,i=t.clientY,e.setPointerCapture?.(t.pointerId)}),e.addEventListener(`pointermove`,e=>{e.pointerId===n&&(t(e.clientX-r,e.clientY-i),r=e.clientX,i=e.clientY)});let a=e=>{e.pointerId===n&&(n=null)};e.addEventListener(`pointerup`,a),e.addEventListener(`pointercancel`,a)}},l=96,u=200,d=8192;function f(e){return Array.isArray(e)?`Array(${e.length})`:`Object(${Object.keys(e).length} keys)`}function p(e,t){if(Array.isArray(e)&&e.some(e=>typeof e==`object`&&!!e)){let t=e.slice(0,u).map(e=>JSON.stringify(e)),n=e.length-u;return t.join(`
1
+ import{i as e,r as t,t as n}from"./index-BYCso8Bf.js";function r(e,t,n,r,i,a,o=180,s=120){let c=Math.max(o,n),l=Math.max(s,r);return{x:Math.min(Math.max(0,e),Math.max(0,i-c)),y:Math.min(Math.max(0,t),Math.max(0,a-l)),w:c,h:l}}function i(e,t){for(let[n,r]of Object.entries(t))e.style[n]=r}var a=`rgba(18, 20, 26, 0.92)`,o=`1px solid rgba(255,255,255,0.14)`,s=`12px ui-monospace, SFMono-Regular, Menlo, monospace`,c=class{host;el;body;onClose=()=>{};x;y;w;h;constructor(e,t,n,r){this.host=t,this.x=r.x,this.y=r.y,this.w=r.w,this.h=r.h,this.el=e.createElement(`div`),i(this.el,{position:`absolute`,background:a,border:o,borderRadius:`8px`,color:`rgba(255,255,255,0.88)`,font:s,display:`flex`,flexDirection:`column`,overflow:`hidden`,zIndex:`40`,pointerEvents:`auto`,boxShadow:`0 8px 28px rgba(0,0,0,0.45)`});let c=e.createElement(`div`);c.textContent=n,i(c,{padding:`6px 28px 6px 10px`,background:`rgba(255,255,255,0.07)`,cursor:`move`,userSelect:`none`,touchAction:`none`,fontWeight:`700`}),this.el.appendChild(c);let l=e.createElement(`div`);l.textContent=`×`,l.title=`close`,i(l,{position:`absolute`,top:`2px`,right:`8px`,cursor:`pointer`,fontSize:`16px`,lineHeight:`20px`,opacity:`0.7`}),l.addEventListener(`click`,()=>this.onClose()),this.el.appendChild(l),this.body=e.createElement(`div`),i(this.body,{flex:`1`,overflow:`auto`,padding:`8px 10px`}),this.el.appendChild(this.body);let u=e.createElement(`div`);u.textContent=`◢`,i(u,{position:`absolute`,right:`2px`,bottom:`0`,cursor:`nwse-resize`,opacity:`0.5`,userSelect:`none`,touchAction:`none`}),this.el.appendChild(u),this.wireDrag(c,(e,t)=>{this.x+=e,this.y+=t,this.layout()}),this.wireDrag(u,(e,t)=>{this.w+=e,this.h+=t,this.layout()}),this.layout(),t.appendChild(this.el)}remove(){this.el.remove()}layout(){let e=this.host.getBoundingClientRect(),t=r(this.x,this.y,this.w,this.h,e.width,e.height);this.x=t.x,this.y=t.y,this.w=t.w,this.h=t.h,i(this.el,{left:`${t.x}px`,top:`${t.y}px`,width:`${t.w}px`,height:`${t.h}px`})}wireDrag(e,t){let n=null,r=0,i=0;e.addEventListener(`pointerdown`,t=>{n=t.pointerId,r=t.clientX,i=t.clientY,e.setPointerCapture?.(t.pointerId)}),e.addEventListener(`pointermove`,e=>{e.pointerId===n&&(t(e.clientX-r,e.clientY-i),r=e.clientX,i=e.clientY)});let a=e=>{e.pointerId===n&&(n=null)};e.addEventListener(`pointerup`,a),e.addEventListener(`pointercancel`,a)}},l=96,u=200,d=8192;function f(e){return Array.isArray(e)?`Array(${e.length})`:`Object(${Object.keys(e).length} keys)`}function p(e,t){if(Array.isArray(e)&&e.some(e=>typeof e==`object`&&!!e)){let t=e.slice(0,u).map(e=>JSON.stringify(e)),n=e.length-u;return t.join(`
2
2
  `)+(n>0?`\n… ${n} more`:``)}return t.length>d?`${t.slice(0,d)} … (${t.length-d} more chars)`:t}function m(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function h(e,t={}){let n=t.doc??(typeof document<`u`?document:null);if(!n)return null;let r=t.container??(typeof document<`u`?document.body:null);return!r||typeof r.appendChild!=`function`?null:new v(e,r,n,t.statsSource,t.actions)}var g=300,_=[`log`,`info`,`warn`,`error`,`debug`],v=class{engine;container;doc;statsSource;actions;panels=new Map;cleanups=[];menuButton;dropdown=null;selected=null;collapsedFlags=new Map;statsChip=null;logRows=[];levelEnabled={debug:!0,info:!0,warn:!0,error:!0};consoleCapture=!1;consolePatched=[];frame=0;editing=0;detailOpen=new WeakMap;hovering=!1;constructor(e,t,n,r,a=[]){this.engine=e,this.container=t,this.doc=n,this.statsSource=r,this.actions=a,this.menuButton=n.createElement(`div`),this.menuButton.textContent=`☰ debug`,i(this.menuButton,{position:`absolute`,top:`8px`,left:`8px`,padding:`4px 10px`,background:`rgba(18,20,26,0.85)`,border:`1px solid rgba(255,255,255,0.18)`,borderRadius:`6px`,color:`rgba(255,255,255,0.85)`,font:`12px ui-monospace, Menlo, monospace`,cursor:`pointer`,userSelect:`none`,zIndex:`50`,pointerEvents:`auto`}),this.menuButton.addEventListener(`click`,()=>this.toggleDropdown()),t.style.position||(t.style.position=`relative`),t.appendChild(this.menuButton),this.cleanups.push(e.log.added.connect(e=>{this.pushLog({level:e.level,source:`engine`,text:e.parts.map(x).join(` `)})})),this.cleanups.push(e.sceneChanged.connect(()=>{this.selected=null,this.applyColliderScope(),this.renderExplorer(),this.renderInspector()})),this.cleanups.push(e.updated.connect(()=>{this.frame+=1,this.frame%30==0&&(this.renderExplorer(),this.renderStats(),this.editing===0&&!this.hovering&&this.renderInspector())}))}isOpen(e){return e===`colliders`?this.colliderMode!==`off`:e===`stats`?this.statsChip!==null:this.panels.has(e)}colliderMode=`off`;setColliders(e){this.colliderMode=e,this.applyColliderScope()}applyColliderScope(){let e=this.colliderMode;for(let t of n(`2d`).concat(n(`3d`)))t.debugDraw=e!==`off`,t.debugScope=e===`selected`?this.selected:null}open(e){if(e===`stats`){this.openStatsChip();return}if(this.panels.has(e))return;let t=new c(this.doc,this.container,{explorer:`Explorer`,inspector:`Inspector`,logs:`Logs`}[e],{explorer:{x:12,y:44,w:240,h:320},inspector:{x:264,y:44,w:280,h:320},logs:{x:12,y:380,w:532,h:200}}[e]);t.onClose=()=>this.close(e),e===`inspector`&&(t.body.addEventListener(`pointerenter`,()=>{this.hovering=!0}),t.body.addEventListener(`pointerleave`,()=>{this.hovering=!1})),this.panels.set(e,t),e===`explorer`&&this.renderExplorer(),e===`inspector`&&this.renderInspector(),e===`logs`&&this.renderLogs()}close(e){if(e===`inspector`&&(this.hovering=!1),e===`stats`){this.statsChip?.remove(),this.statsChip=null;return}let t=this.panels.get(e);t&&(t.remove(),this.panels.delete(e))}toggle(e){if(e===`colliders`){this.setColliders({off:`all`,all:`selected`,selected:`off`}[this.colliderMode]);return}this.isOpen(e)?this.close(e):this.open(e)}setLevelEnabled(e,t){this.levelEnabled[e]=t,this.renderLogs()}setConsoleCapture(e){if(e!==this.consoleCapture)if(this.consoleCapture=e,e){this.renderLogs();let e=console;for(let t of _){let n=e[t];e[t]=(...e)=>{n.apply(console,e);let r=t===`log`?`info`:t;this.pushLog({level:r,source:`console`,text:e.map(x).join(` `)})},this.consolePatched.push(()=>{e[t]=n})}}else{for(let e of this.consolePatched)e();this.consolePatched=[],this.renderLogs()}}dispose(){this.engine.debugSelection=null,this.setColliders(`off`),this.setConsoleCapture(!1);for(let e of this.cleanups)e();for(let e of[...this.panels.keys()])this.close(e);this.close(`stats`),this.dropdown?.remove(),this.dropdown=null,this.menuButton.remove()}menuLabel(e,t){let n=e===`colliders`&&this.colliderMode!==`off`?` · ${this.colliderMode}`:``;return`${this.isOpen(e)?`✓ `:``}${t}${n}`}toggleDropdown(){if(this.dropdown){this.dropdown.remove(),this.dropdown=null;return}let e=this.doc.createElement(`div`);i(e,{position:`absolute`,top:`34px`,left:`8px`,background:`rgba(18,20,26,0.95)`,border:`1px solid rgba(255,255,255,0.18)`,borderRadius:`6px`,font:`12px ui-monospace, Menlo, monospace`,color:`rgba(255,255,255,0.85)`,zIndex:`60`,pointerEvents:`auto`,overflow:`hidden`});for(let[t,n]of[[`explorer`,`Explorer`],[`inspector`,`Inspector`],[`logs`,`Logs`],[`stats`,`Stats`],[`colliders`,`Colliders`]]){let r=this.doc.createElement(`div`);r.textContent=this.menuLabel(t,n),i(r,{padding:`6px 14px`,cursor:`pointer`,userSelect:`none`}),r.addEventListener(`click`,()=>{if(this.toggle(t),t===`colliders`){r.textContent=this.menuLabel(t,n);return}this.dropdown?.remove(),this.dropdown=null}),e.appendChild(r)}for(let t of this.actions){let n=this.doc.createElement(`div`);n.textContent=t.label,i(n,{padding:`6px 14px`,cursor:`pointer`,userSelect:`none`,borderTop:`1px solid rgba(255,255,255,0.14)`,color:`rgba(158,232,220,0.95)`}),n.addEventListener(`click`,()=>{this.dropdown?.remove(),this.dropdown=null,t.run()}),e.appendChild(n)}this.container.appendChild(e),this.dropdown=e}openStatsChip(){if(this.statsChip)return;let e=this.doc.createElement(`div`);i(e,{position:`absolute`,top:`8px`,right:`8px`,padding:`4px 10px`,background:`rgba(18,20,26,0.85)`,border:`1px solid rgba(255,255,255,0.18)`,borderRadius:`6px`,color:`rgba(255,255,255,0.85)`,font:`12px ui-monospace, Menlo, monospace`,textAlign:`right`,whiteSpace:`pre`,userSelect:`none`,pointerEvents:`none`,zIndex:`70`}),this.container.appendChild(e),this.statsChip=e,this.renderStats()}renderStats(){let e=this.statsChip;if(!e)return;let t=this.engine.stats(),n=this.statsSource?.()??{},r=[`nodes ${t.nodes}`,...n.triangles===void 0?[]:[`tris ${b(n.triangles)}`],...n.drawCalls===void 0?[]:[`calls ${n.drawCalls}`]].join(` · `);e.textContent=`${Math.round(t.fps)} fps · ${t.frameMs.toFixed(1)} ms\n${r}`}renderExplorer(){let e=this.panels.get(`explorer`);if(!e)return;let t=e.body.scrollTop;y(e.body);let n=this.engine.scene?.root;if(!n){e.body.scrollTop=t;return}let r=(e,t)=>{let n=e.constructor,a=e.children.length>0,o=this.collapsedFlags.get(e)===!0,s=this.doc.createElement(`div`);i(s,{display:`flex`,alignItems:`center`,cursor:`pointer`,padding:`1px 2px`,borderRadius:`3px`,background:e===this.selected?`rgba(110,160,255,0.25)`:`transparent`});let c=this.doc.createElement(`span`);c.textContent=a?o?`▸`:`▾`:`·`,i(c,{width:`14px`,flex:`none`,textAlign:`center`,opacity:a?`0.85`:`0.25`,userSelect:`none`}),a&&c.addEventListener(`click`,t=>{t.stopPropagation?.(),this.collapsedFlags.set(e,!o),this.renderExplorer()}),s.appendChild(c);let l=this.doc.createElement(`span`);l.textContent=e.name,i(l,{whiteSpace:`nowrap`}),s.appendChild(l);let u=this.doc.createElement(`span`);if(u.textContent=` ${n.typeName}`,i(u,{opacity:`0.45`,whiteSpace:`nowrap`,fontSize:`10px`}),s.appendChild(u),a&&o){let t=this.doc.createElement(`span`);t.textContent=` (${e.children.length})`,i(t,{opacity:`0.35`,fontSize:`10px`}),s.appendChild(t)}if(s.addEventListener(`click`,()=>{this.selected=e,this.engine.debugSelection=e,this.applyColliderScope(),this.open(`inspector`),this.renderExplorer(),this.renderInspector()}),t.appendChild(s),a&&!o){let n=this.doc.createElement(`div`);i(n,{marginLeft:`8px`,paddingLeft:`8px`,borderLeft:`1px solid rgba(255,255,255,0.14)`});for(let t of e.children)r(t,n);t.appendChild(n)}};r(n,e.body),e.body.scrollTop=t}renderInspector(){let e=this.panels.get(`inspector`);if(!e)return;let n=e.body.scrollTop;y(e.body);let r=this.selected;if(r&&r.tree===null&&(this.selected=null,this.engine.debugSelection=null,this.applyColliderScope(),r=null),!r){let t=this.doc.createElement(`div`);t.textContent=`select a node in the Explorer`,i(t,{opacity:`0.6`}),e.body.appendChild(t);return}let a=r.constructor,o=this.doc.createElement(`div`);if(o.textContent=`${r.getPath()} · ${a.typeName}${r.uid?` · ${r.uid}`:``}`,i(o,{fontWeight:`700`,marginBottom:`6px`,whiteSpace:`pre-wrap`}),e.body.appendChild(o),r.groups.size>0){let t=this.doc.createElement(`div`);t.textContent=`groups: ${[...r.groups].join(`, `)}`,i(t,{opacity:`0.7`,marginBottom:`6px`}),e.body.appendChild(t)}let s=t(a),c=r;for(let t of Object.keys(s)){let n=s[t];this.renderValueRow(e.body,r,t,{read:()=>c[t],write:e=>{c[t]=e},options:n?.options,variants:n?.variants})}e.body.scrollTop=n}renderValueRow(t,n,r,a){let o=a.read(),s=a.options,c={get[r](){return a.read()},set[r](e){a.write(e)}},u=this.doc.createElement(`div`);i(u,{display:`flex`,gap:`6px`,alignItems:`center`,margin:`2px 0`});let d=this.doc.createElement(`div`);d.textContent=r,i(d,{minWidth:`84px`,opacity:`0.75`}),u.appendChild(d);let h=(e,t)=>{let a=this.doc.createElement(`input`);return a.type=`number`,a.value=String(e),i(a,S(`70px`)),this.trackEditing(a),a.addEventListener(`change`,()=>{let e=Number(a.value);Number.isFinite(e)?t(e):a.value=String(n[r])}),a};if(typeof o==`number`)u.appendChild(h(o,e=>{c[r]=e}));else if(typeof o==`boolean`){let e=this.doc.createElement(`input`);e.type=`checkbox`,e.checked=o,this.trackEditing(e),e.addEventListener(`change`,()=>{c[r]=e.checked}),u.appendChild(e)}else if(typeof o==`string`&&s&&s.length>0){let e=this.doc.createElement(`select`);for(let t of s.includes(o)?s:[o,...s]){let n=this.doc.createElement(`option`);n.value=t,n.textContent=t,t===o&&(n.selected=!0),e.appendChild(n)}e.value=o,this.trackEditing(e),e.addEventListener(`change`,()=>{c[r]=e.value}),i(e,S(`110px`)),u.appendChild(e)}else if(typeof o==`string`){let e=this.doc.createElement(`input`);e.type=`text`,e.value=o,this.trackEditing(e),i(e,S(`140px`)),e.addEventListener(`change`,()=>{c[r]=e.value}),u.appendChild(e)}else if(Array.isArray(o)&&o.length<=8&&o.every(e=>typeof e==`number`))for(let e=0;e<o.length;e++)u.appendChild(h(o[e],t=>{let n=[...c[r]];n[e]=t,c[r]=n}));else if(m(o)){let s=this.doc.createElement(`div`);i(s,{marginLeft:`10px`,paddingLeft:`8px`,borderLeft:`1px solid rgba(255,255,255,0.14)`});let c=a.variants?.tag,l=Object.keys(o);c&&!l.includes(c)&&l.unshift(c);let d=a.path??r;for(let t of l){let r=t===c;this.renderValueRow(s,n,t,{path:`${d}.${t}`,read:()=>a.read()[t]??(r?``:null),write:n=>{if(r&&a.variants){let t=a.variants.byTag[String(n)];if(t!==void 0){a.write(e(t));return}}a.write({...a.read(),[t]:n})},options:r&&a.variants?Object.keys(a.variants.byTag):void 0})}t.appendChild(u),t.appendChild(s);return}else{let s=JSON.stringify(e(o));if(s.length<=l){let e=this.doc.createElement(`div`);e.textContent=s,i(e,{opacity:`0.65`,whiteSpace:`pre-wrap`,wordBreak:`break-all`}),u.appendChild(e)}else{let e=a.path??r,c=this.detailOpen.get(n)?.has(e)??!1,l=this.doc.createElement(`div`);if(l.textContent=`${c?`▾`:`▸`} ${f(o)}`,i(l,{opacity:`0.75`,cursor:`pointer`,userSelect:`none`}),l.addEventListener(`click`,()=>{let t=this.detailOpen.get(n);t||(t=new Set,this.detailOpen.set(n,t)),c?t.delete(e):t.add(e),this.renderInspector()}),u.appendChild(l),t.appendChild(u),c){let e=this.doc.createElement(`div`);e.textContent=p(o,s),i(e,{opacity:`0.6`,whiteSpace:`pre-wrap`,wordBreak:`break-all`,marginLeft:`10px`,paddingLeft:`8px`,borderLeft:`1px solid rgba(255,255,255,0.14)`}),t.appendChild(e)}return}}t.appendChild(u)}trackEditing(e){e.addEventListener(`focus`,()=>{this.editing+=1}),e.addEventListener(`blur`,()=>{this.editing=Math.max(0,this.editing-1)})}pushLog(e){this.logRows.push(e),this.logRows.length>g&&this.logRows.splice(0,this.logRows.length-g),this.renderLogs()}renderLogs(){let e=this.panels.get(`logs`);if(!e)return;y(e.body);let t=this.doc.createElement(`div`);i(t,{display:`flex`,gap:`8px`,marginBottom:`4px`,flexWrap:`wrap`});for(let e of[`debug`,`info`,`warn`,`error`]){let n=this.doc.createElement(`div`);n.textContent=`${this.levelEnabled[e]?`✓`:`·`}${e}`,i(n,{cursor:`pointer`,opacity:this.levelEnabled[e]?`1`:`0.45`}),n.addEventListener(`click`,()=>this.setLevelEnabled(e,!this.levelEnabled[e])),t.appendChild(n)}let n=this.doc.createElement(`div`);n.textContent=`${this.consoleCapture?`✓`:`·`}console`,i(n,{cursor:`pointer`,marginLeft:`auto`}),n.addEventListener(`click`,()=>this.setConsoleCapture(!this.consoleCapture)),t.appendChild(n),e.body.appendChild(t);let r={debug:`rgba(255,255,255,0.5)`,info:`rgba(255,255,255,0.85)`,warn:`#ffc861`,error:`#ff6b6b`};for(let t of this.logRows){if(!this.levelEnabled[t.level])continue;let n=this.doc.createElement(`div`);n.textContent=`[${t.source===`console`?`console`:t.level}] ${t.text}`,i(n,{color:r[t.level],whiteSpace:`pre-wrap`}),e.body.appendChild(n)}}};function y(e){for(let t of[...e.children])t.remove()}function b(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(1)}k`:String(e)}function x(e){if(typeof e==`string`)return e;if(e instanceof Error){let t=e.stack?.split(`
3
3
  `)[1]?.trim();return`${e.name}: ${e.message}${t?` (${t})`:``}`}try{let t=JSON.stringify(e);return t===`{}`||t===void 0?String(e):t}catch{return String(e)}}function S(e){return{width:e,background:`rgba(255,255,255,0.08)`,border:`1px solid rgba(255,255,255,0.2)`,borderRadius:`4px`,color:`inherit`,font:`inherit`,padding:`2px 4px`}}export{h as attachDebugOverlay};