incanto 0.78.2 → 0.79.1

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 (43) hide show
  1. package/assets/backdrops/sky_gradient.png +0 -0
  2. package/assets/catalog.json +8 -0
  3. package/dist/2d.js +4 -4
  4. package/dist/3d.d.ts +39 -0
  5. package/dist/3d.js +5 -5
  6. package/dist/{agent8-B-bh3n0X.js → agent8---rIaJ3j.js} +1 -1
  7. package/dist/{create-game-BMIPKrQW.js → create-game-CtYQT8Uk.js} +6 -6
  8. package/dist/{create-game-Dai5vfVu.js → create-game-Cxx820o9.js} +67 -9
  9. package/dist/debug.d.ts +9 -0
  10. package/dist/debug.js +48 -7
  11. package/dist/editor.js +37 -25
  12. package/dist/{environment-presets-e_9YCnGu.js → environment-presets-fGpZHUab.js} +3 -3
  13. package/dist/{gameplay-Bfff_beb.js → gameplay-CplbZE7c.js} +1 -1
  14. package/dist/gameplay.js +2 -2
  15. package/dist/index.js +4 -4
  16. package/dist/net.js +2 -2
  17. package/dist/{physics-2d-Tuf5LAyq.js → physics-2d-Cm1DIjk2.js} +3 -3
  18. package/dist/{physics-3d-C5MOujfQ.js → physics-3d-CwJzo3fP.js} +3 -3
  19. package/dist/{picking-DIwE48sU.js → picking-DxHiUoLo.js} +2 -2
  20. package/dist/{pose-ByFB_J3O.js → pose-O50uVW-j.js} +18 -1
  21. package/dist/react.js +1 -1
  22. package/dist/{register-B768Qedj.js → register-CIDbUbFG.js} +1 -1
  23. package/dist/{register-7E3P1gz6.js → register-l4ZWcLwD.js} +3 -3
  24. package/dist/{replay-DrqQ6dZj.js → replay-CooHM9lL.js} +2 -2
  25. package/dist/{split-screen-B-dIcQsQ.js → split-screen-BRbSkBMO.js} +3 -3
  26. package/dist/{src-rS7AyeKD.js → src-3rJ6QSfX.js} +1 -1
  27. package/dist/{test-CVbxnXlv.js → test-Def33MoL.js} +13 -13
  28. package/dist/test.js +2 -2
  29. package/dist/vite.js +3 -3
  30. package/editor/assets/{agent8-DA-I5qhv.js → agent8-q_2WV8pw.js} +1 -1
  31. package/editor/assets/debug-DepFCl1d.js +3 -0
  32. package/editor/assets/{index-Db74LZY-.js → index-QEwr2eXD.js} +102 -102
  33. package/editor/index.html +1 -1
  34. package/package.json +1 -1
  35. package/skills/incanto-assets.md +15 -0
  36. package/skills/incanto-building-3d-games.md +39 -0
  37. package/templates-app/beacon-isle-3d/package.json +1 -1
  38. package/templates-app/molehill-2d/package.json +1 -1
  39. package/templates-app/platformer-2d/package.json +1 -1
  40. package/templates-app/star-survivor/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
  43. package/editor/assets/debug-99tEPoGm.js +0 -3
package/dist/gameplay.js CHANGED
@@ -1,3 +1,3 @@
1
- import { i as worldPosition, n as localFromWorld, r as worldDirection } from "./pose-ByFB_J3O.js";
2
- import { A as Lifetime, B as FollowCamera, C as Pickup, D as Oscillate, E as PathFollow, F as Interactable, G as phaseOf, H as FloatAway, I as GroupCamera, J as Collector, K as DamageOnContact, L as GameFlow, M as Cooldown, N as hitStop, O as MoveTo, P as screenFlash, R as goToScene, S as PrefabShelf, T as Patrol, U as FaceTarget, W as DayNight, X as ChaseCamera, Y as Checkpoint, Z as Chase, _t as Health, a as Wander, b as SavePoint, c as ballisticPath, d as Sight, gt as Blast, i as WaveSpawner, j as CameraShake, k as Mount, l as maxRangeAim, n as registerGameplayBehaviors, o as Turret, q as Currency, r as ZombieAI, s as ballisticAim, t as GAMEPLAY_BEHAVIORS, u as Spawner, w as Phases, x as Projectile, y as ScoreKeeper, z as restartScene } from "./gameplay-Bfff_beb.js";
1
+ import { i as worldPosition, n as localFromWorld, r as worldDirection } from "./pose-O50uVW-j.js";
2
+ import { A as Lifetime, B as FollowCamera, C as Pickup, D as Oscillate, E as PathFollow, F as Interactable, G as phaseOf, H as FloatAway, I as GroupCamera, J as Collector, K as DamageOnContact, L as GameFlow, M as Cooldown, N as hitStop, O as MoveTo, P as screenFlash, R as goToScene, S as PrefabShelf, T as Patrol, U as FaceTarget, W as DayNight, X as ChaseCamera, Y as Checkpoint, Z as Chase, _t as Health, a as Wander, b as SavePoint, c as ballisticPath, d as Sight, gt as Blast, i as WaveSpawner, j as CameraShake, k as Mount, l as maxRangeAim, n as registerGameplayBehaviors, o as Turret, q as Currency, r as ZombieAI, s as ballisticAim, t as GAMEPLAY_BEHAVIORS, u as Spawner, w as Phases, x as Projectile, y as ScoreKeeper, z as restartScene } from "./gameplay-CplbZE7c.js";
3
3
  export { Blast, CameraShake, Chase, ChaseCamera, Checkpoint, Collector, Cooldown, Currency, DamageOnContact, DayNight, FaceTarget, FloatAway, FollowCamera, GAMEPLAY_BEHAVIORS, GameFlow, GroupCamera, Health, Interactable, Lifetime, Mount, MoveTo, Oscillate, PathFollow, Patrol, Phases, Pickup, PrefabShelf, Projectile, SavePoint, ScoreKeeper, Sight, Spawner, Turret, Wander, WaveSpawner, ZombieAI, ballisticAim, ballisticPath, goToScene, hitStop, localFromWorld, maxRangeAim, phaseOf, registerGameplayBehaviors, restartScene, screenFlash, worldDirection, worldPosition };
package/dist/index.js CHANGED
@@ -1,13 +1,13 @@
1
1
  import { n as jsonEquals, r as jsonKind, t as jsonClone } from "./json-CfTjpvW8.js";
2
- import { $ as Node, A as isConstRef, B as resolveOrderGroups, C as serializeNode, F as SceneTree, G as HudLayer, I as createSaveStore, J as UiBanner, M as computeViewport, N as resolveViewport, P as newUid, R as ORDER_GROUP_BASE, S as Scene, V as InputMap, X as UiText, Y as UiBar, at as Behavior, b as loadScene, c as captureBehaviors, ct as behaviorSignals, d as duplicateNode, dt as registerBehavior, ft as registeredBehaviors, it as parseNodePath, j as resolveConstants, k as CONST_REF_KEY, l as restoreBehaviors, lt as clearBehaviors, nt as nodeRefWarnings, o as SaveSlots, pt as Signal, rt as resolveRefInJson, s as behaviorsWithoutSave, st as behaviorSchema, tt as describeRefProblem, u as savesWithoutUid, ut as getBehavior, w as SCENE_FORMAT, z as effectiveOrder } from "./pose-ByFB_J3O.js";
3
- import { A as BASE_LOCALE, B as spatialPan, D as suggestQuality, E as readDeviceHints, F as translationKey, G as MusicManager, H as SFX_PRESET_NAMES, I as SfxEngine, J as fadeGain, K as WebAudioMusicBackend, L as isAudioContextAvailable, M as T_PREFIX, N as suggestLocale, O as LogManager, R as ROLLOFF_MODELS, S as Settings, U as sfxDuration, V as SFX_PRESETS, W as synthSfx, Y as AudioBuses, _ as UiButton, a as UiImage, b as Engine, c as UiPanel, d as UiSelect, f as UiSlider, g as Respawn, h as Timer, i as UiFrameCapSelect, j as Localization, k as EffectLog, l as UiQualitySelect, m as UiVolumeSlider, n as UiWaypoint, o as UiLanguageSelect, p as UiToggle, q as crossfadeGains, r as UiMinimap, s as UiMuteToggle, t as registerCoreNodes, u as UiRenderScaleSelect, v as UiDialogue, w as qualityEnvironment, y as AudioPlayer, z as spatialGain } from "./register-B768Qedj.js";
2
+ import { $ as Node, A as isConstRef, B as resolveOrderGroups, C as serializeNode, F as SceneTree, G as HudLayer, I as createSaveStore, J as UiBanner, M as computeViewport, N as resolveViewport, P as newUid, R as ORDER_GROUP_BASE, S as Scene, V as InputMap, X as UiText, Y as UiBar, at as Behavior, b as loadScene, c as captureBehaviors, ct as behaviorSignals, d as duplicateNode, dt as registerBehavior, ft as registeredBehaviors, it as parseNodePath, j as resolveConstants, k as CONST_REF_KEY, l as restoreBehaviors, lt as clearBehaviors, nt as nodeRefWarnings, o as SaveSlots, pt as Signal, rt as resolveRefInJson, s as behaviorsWithoutSave, st as behaviorSchema, tt as describeRefProblem, u as savesWithoutUid, ut as getBehavior, w as SCENE_FORMAT, z as effectiveOrder } from "./pose-O50uVW-j.js";
3
+ import { A as BASE_LOCALE, B as spatialPan, D as suggestQuality, E as readDeviceHints, F as translationKey, G as MusicManager, H as SFX_PRESET_NAMES, I as SfxEngine, J as fadeGain, K as WebAudioMusicBackend, L as isAudioContextAvailable, M as T_PREFIX, N as suggestLocale, O as LogManager, R as ROLLOFF_MODELS, S as Settings, U as sfxDuration, V as SFX_PRESETS, W as synthSfx, Y as AudioBuses, _ as UiButton, a as UiImage, b as Engine, c as UiPanel, d as UiSelect, f as UiSlider, g as Respawn, h as Timer, i as UiFrameCapSelect, j as Localization, k as EffectLog, l as UiQualitySelect, m as UiVolumeSlider, n as UiWaypoint, o as UiLanguageSelect, p as UiToggle, q as crossfadeGains, r as UiMinimap, s as UiMuteToggle, t as registerCoreNodes, u as UiRenderScaleSelect, v as UiDialogue, w as qualityEnvironment, y as AudioPlayer, z as spatialGain } from "./register-CIDbUbFG.js";
4
4
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
5
5
  import { t as Rng } from "./rng-CDOMybym.js";
6
- import { n as startRecording, r as auditScene, t as replay } from "./replay-DrqQ6dZj.js";
6
+ import { n as startRecording, r as auditScene, t as replay } from "./replay-CooHM9lL.js";
7
7
  import { c as getNodeSchema, f as mergeStaticSignals, i as joystickVector, l as getNodeSignals, m as registeredTypes, n as attachTouchControls, o as clearRegistry, p as registerNode, s as createNode, t as TouchControls, u as getNodeType } from "./touch-CioTZB-y.js";
8
8
  import { t as showBootFailure } from "./boot-failure-CKYrEcGF.js";
9
9
  import { a as logText, i as logReport, o as parseDrive, r as resolveRendering, t as isWebGLAvailable } from "./webgl-unavailable-C8aDbGmR.js";
10
10
  import { t as createNoise2D } from "./noise-D3nPpmFg.js";
11
11
  import { a as PARTICLE_PRESETS, i as ParticleSim, n as resolveFrames, o as PARTICLE_PRESET_NAMES, s as applyParticlePreset, t as resolveAnimation } from "./sprite-animation-SQa5gIu2.js";
12
- import { a as findPath, i as preloadUrls, n as assetUrls, o as gridFromRows, r as preloadSceneAssets, t as VERSION } from "./src-rS7AyeKD.js";
12
+ import { a as findPath, i as preloadUrls, n as assetUrls, o as gridFromRows, r as preloadSceneAssets, t as VERSION } from "./src-3rJ6QSfX.js";
13
13
  export { AudioBuses, AudioPlayer, BASE_LOCALE, Behavior, CONST_REF_KEY, EffectLog, Engine, HudLayer, IncantoError, InputMap, Localization, LogManager, MusicManager, Node, ORDER_GROUP_BASE, PARTICLE_PRESETS, PARTICLE_PRESET_NAMES, ParticleSim, ROLLOFF_MODELS, Respawn, Rng, SCENE_FORMAT, SFX_PRESETS, SFX_PRESET_NAMES, SaveSlots, Scene, SceneTree, Settings, SfxEngine, Signal, T_PREFIX, Timer, TouchControls, UiBanner, UiBar, UiButton, UiDialogue, UiFrameCapSelect, UiImage, UiLanguageSelect, UiMinimap, UiMuteToggle, UiPanel, UiQualitySelect, UiRenderScaleSelect, UiSelect, UiSlider, UiText, UiToggle, UiVolumeSlider, UiWaypoint, VERSION, WebAudioMusicBackend, applyParticlePreset, assetUrls, attachTouchControls, auditScene, behaviorSchema, behaviorSignals, behaviorsWithoutSave, captureBehaviors, clearBehaviors, clearRegistry, computeViewport, createNode, createNoise2D, createSaveStore, crossfadeGains, describeRefProblem, duplicateNode, effectiveOrder, fadeGain, findPath, getBehavior, getNodeSchema, getNodeSignals, getNodeType, gridFromRows, isAudioContextAvailable, isConstRef, isWebGLAvailable, joystickVector, jsonClone, jsonEquals, jsonKind, loadScene, logReport, logText, mergeStaticSignals, newUid, nodeRefWarnings, parseDrive, parseNodePath, preloadSceneAssets, preloadUrls, qualityEnvironment, readDeviceHints, registerBehavior, registerCoreNodes, registerNode, registeredBehaviors, registeredTypes, replay, resolveAnimation, resolveConstants, resolveFrames, resolveOrderGroups, resolveRefInJson, resolveRendering, resolveViewport, restoreBehaviors, savesWithoutUid, serializeNode, sfxDuration, showBootFailure, spatialGain, spatialPan, startRecording, suggestLocale, suggestQuality, synthSfx, translationKey };
package/dist/net.js CHANGED
@@ -1,3 +1,3 @@
1
- import { n as createAgent8Server } from "./agent8-B-bh3n0X.js";
2
- import { a as NetworkManager, d as createLocalGameServer, f as LoopbackHub, l as LocalGameServer, n as registerNodesNet, o as applySyncPatch, p as LoopbackTransport, r as NetworkSpawner, t as createSplitScreen, u as LocalGameServerTransport } from "./split-screen-B-dIcQsQ.js";
1
+ import { n as createAgent8Server } from "./agent8---rIaJ3j.js";
2
+ import { a as NetworkManager, d as createLocalGameServer, f as LoopbackHub, l as LocalGameServer, n as registerNodesNet, o as applySyncPatch, p as LoopbackTransport, r as NetworkSpawner, t as createSplitScreen, u as LocalGameServerTransport } from "./split-screen-BRbSkBMO.js";
3
3
  export { LocalGameServer, LocalGameServerTransport, LoopbackHub, LoopbackTransport, NetworkManager, NetworkSpawner, applySyncPatch, createAgent8Server, createLocalGameServer, createSplitScreen, registerNodesNet };
@@ -1,10 +1,10 @@
1
1
  import { o as __exportAll } from "./json-CfTjpvW8.js";
2
- import { et as diagnose } from "./pose-ByFB_J3O.js";
2
+ import { et as diagnose } from "./pose-O50uVW-j.js";
3
3
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
4
- import { _ as Node2D, f as Area2D, g as StaticBody2D, h as RigidBody2D, m as PhysicsBody2D, p as CharacterBody2D, v as validateCollider2D } from "./gameplay-Bfff_beb.js";
4
+ import { _ as Node2D, f as Area2D, g as StaticBody2D, h as RigidBody2D, m as PhysicsBody2D, p as CharacterBody2D, v as validateCollider2D } from "./gameplay-CplbZE7c.js";
5
5
  import { n as registerDebugSource } from "./debug-draw-BM3DsvtT.js";
6
6
  import { n as jointContacts, t as withoutRapierInitNoise } from "./quiet-rapier-C6fW4zcW.js";
7
- import { p as Joint2D } from "./register-7E3P1gz6.js";
7
+ import { p as Joint2D } from "./register-l4ZWcLwD.js";
8
8
  //#region src/2d/physics/physics-2d.ts
9
9
  var physics_2d_exports = /* @__PURE__ */ __exportAll({
10
10
  Physics2D: () => Physics2D,
@@ -1,10 +1,10 @@
1
1
  import { o as __exportAll } from "./json-CfTjpvW8.js";
2
- import { et as diagnose } from "./pose-ByFB_J3O.js";
2
+ import { et as diagnose } from "./pose-O50uVW-j.js";
3
3
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
4
- import { $ as Water3D, at as PhysicsBody3D, ct as Node3D, it as CharacterBody3D, lt as validateCollider3D, ot as RigidBody3D, rt as Area3D, st as StaticBody3D } from "./gameplay-Bfff_beb.js";
4
+ import { $ as Water3D, at as PhysicsBody3D, ct as Node3D, it as CharacterBody3D, lt as validateCollider3D, ot as RigidBody3D, rt as Area3D, st as StaticBody3D } from "./gameplay-CplbZE7c.js";
5
5
  import { n as registerDebugSource } from "./debug-draw-BM3DsvtT.js";
6
6
  import { n as jointContacts, t as withoutRapierInitNoise } from "./quiet-rapier-C6fW4zcW.js";
7
- import { B as InstancedMesh3D, F as Terrain3D, H as buildMeshGeometry, z as Joint3D } from "./environment-presets-e_9YCnGu.js";
7
+ import { B as InstancedMesh3D, F as Terrain3D, H as buildMeshGeometry, z as Joint3D } from "./environment-presets-fGpZHUab.js";
8
8
  import { Euler, Matrix4, Quaternion, Vector3 } from "three";
9
9
  //#region src/3d/physics/collider-lines.ts
10
10
  /**
@@ -1,5 +1,5 @@
1
- import { i as worldPosition } from "./pose-ByFB_J3O.js";
2
- import { y as AudioPlayer } from "./register-B768Qedj.js";
1
+ import { i as worldPosition } from "./pose-O50uVW-j.js";
2
+ import { y as AudioPlayer } from "./register-CIDbUbFG.js";
3
3
  import { i as logReport, o as parseDrive } from "./webgl-unavailable-C8aDbGmR.js";
4
4
  import { a as frameSignature, i as frameImage, o as frameStats } from "./frame-report-D-_7YF2G.js";
5
5
  //#region src/core/audio-errors.ts
@@ -3800,10 +3800,27 @@ function parseEnvironment3D(env) {
3800
3800
  clouds: parseClouds(env?.clouds),
3801
3801
  bloom: parseBloom(env?.bloom),
3802
3802
  post: parsePost(env?.post),
3803
- shadows: parseShadows(env?.shadows)
3803
+ shadows: parseShadows(env?.shadows),
3804
+ skybox: parseSkybox(env?.skybox)
3804
3805
  };
3805
3806
  }
3806
3807
  /**
3808
+ * `skybox` was read straight by the renderer as `=== true`, so a string sat
3809
+ * in a valid scene doing nothing. Now a string is an image to show — and the
3810
+ * one shape that is neither a boolean nor a file is a bare word (`"yes"`,
3811
+ * `"on"`, `"hdri"`), which would be fetched verbatim and 404 into a black
3812
+ * sky with nothing to grep for. A path has a `/` or a `.`; a url has both.
3813
+ */
3814
+ function parseSkybox(value) {
3815
+ if (value === void 0 || value === false) return null;
3816
+ if (value === true) return true;
3817
+ if (typeof value === "string" && value !== "" && /[./]/.test(value)) return value;
3818
+ throw new IncantoError("BAD_FORMAT", `environment.skybox must be true (show the hdri/preset that lights the scene) or an image url or path to show as the backdrop (.jpg/.png/.webp, or .hdr), got ${JSON.stringify(value)}.`, {
3819
+ prop: "skybox",
3820
+ validOptions: ["true", "<image url or path>"]
3821
+ });
3822
+ }
3823
+ /**
3807
3824
  * `ambient` is not part of the parsed config — the renderer reads it straight —
3808
3825
  * so it was the one object block in `environment` with nothing checking its
3809
3826
  * keys, while `sky`, `fog`, `clouds`, `bloom`, `post`, `shadows` and
package/dist/react.js CHANGED
@@ -156,7 +156,7 @@ function IncantoCanvas(props) {
156
156
  pointer: latest.pointer,
157
157
  ...keyboard !== void 0 ? { keyboard } : {}
158
158
  };
159
- const next = await (_gameFactory ?? (mode === "3d" ? async (o) => (await import("./create-game-Dai5vfVu.js").then((n) => n.n)).createGame3D(o) : async (o) => (await import("./create-game-BMIPKrQW.js").then((n) => n.n)).createGame2D(o)))(opts);
159
+ const next = await (_gameFactory ?? (mode === "3d" ? async (o) => (await import("./create-game-Cxx820o9.js").then((n) => n.n)).createGame3D(o) : async (o) => (await import("./create-game-CtYQT8Uk.js").then((n) => n.n)).createGame2D(o)))(opts);
160
160
  if (disposed) {
161
161
  next.dispose();
162
162
  return;
@@ -1,5 +1,5 @@
1
1
  import { o as __exportAll } from "./json-CfTjpvW8.js";
2
- import { $ as Node, B as resolveOrderGroups, G as HudLayer, I as createSaveStore, J as UiBanner, K as HudWidgetBase, Q as requireText, R as ORDER_GROUP_BASE, V as InputMap, W as FITS, X as UiText, Y as UiBar, a as ENGINE_STATE_KEY, c as captureBehaviors, et as diagnose, i as worldPosition, l as restoreBehaviors, pt as Signal, q as TAPPABLE, r as worldDirection, t as hasPosition } from "./pose-ByFB_J3O.js";
2
+ import { $ as Node, B as resolveOrderGroups, G as HudLayer, I as createSaveStore, J as UiBanner, K as HudWidgetBase, Q as requireText, R as ORDER_GROUP_BASE, V as InputMap, W as FITS, X as UiText, Y as UiBar, a as ENGINE_STATE_KEY, c as captureBehaviors, et as diagnose, i as worldPosition, l as restoreBehaviors, pt as Signal, q as TAPPABLE, r as worldDirection, t as hasPosition } from "./pose-O50uVW-j.js";
3
3
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
4
4
  import { t as Rng } from "./rng-CDOMybym.js";
5
5
  import { p as registerNode } from "./touch-CioTZB-y.js";
@@ -1,9 +1,9 @@
1
- import { $ as Node, et as diagnose, i as worldPosition, n as localFromWorld } from "./pose-ByFB_J3O.js";
2
- import { P as translateOn, t as registerCoreNodes } from "./register-B768Qedj.js";
1
+ import { $ as Node, et as diagnose, i as worldPosition, n as localFromWorld } from "./pose-O50uVW-j.js";
2
+ import { P as translateOn, t as registerCoreNodes } from "./register-CIDbUbFG.js";
3
3
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
4
4
  import { c as getNodeSchema, p as registerNode } from "./touch-CioTZB-y.js";
5
5
  import { i as ParticleSim, n as resolveFrames, o as PARTICLE_PRESET_NAMES, r as validateAnimations, s as applyParticlePreset, t as resolveAnimation } from "./sprite-animation-SQa5gIu2.js";
6
- import { Q as tolerateUnknownAction, V as effectRng, _ as Node2D, f as Area2D, g as StaticBody2D, h as RigidBody2D, m as PhysicsBody2D, p as CharacterBody2D, vt as findHealth } from "./gameplay-Bfff_beb.js";
6
+ import { Q as tolerateUnknownAction, V as effectRng, _ as Node2D, f as Area2D, g as StaticBody2D, h as RigidBody2D, m as PhysicsBody2D, p as CharacterBody2D, vt as findHealth } from "./gameplay-CplbZE7c.js";
7
7
  import { t as checkSheetGrid } from "./sheet-grid-Cea343VO.js";
8
8
  import { AdditiveBlending, BufferAttribute, BufferGeometry, CanvasTexture, Color, DynamicDrawUsage, Group, InstancedMesh, Matrix4, Mesh, MeshBasicMaterial, NearestFilter, NormalBlending, PlaneGeometry, SRGBColorSpace } from "three";
9
9
  //#region src/2d/nodes/joint-2d.ts
@@ -1,5 +1,5 @@
1
- import { H as handlerShadowWarnings, K as HudWidgetBase, U as sceneDimension, nt as nodeRefWarnings } from "./pose-ByFB_J3O.js";
2
- import { F as translationKey } from "./register-B768Qedj.js";
1
+ import { H as handlerShadowWarnings, K as HudWidgetBase, U as sceneDimension, nt as nodeRefWarnings } from "./pose-O50uVW-j.js";
2
+ import { F as translationKey } from "./register-CIDbUbFG.js";
3
3
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
4
4
  import { u as getNodeType } from "./touch-CioTZB-y.js";
5
5
  //#region src/core/light-types.ts
@@ -1,6 +1,6 @@
1
1
  import { n as jsonEquals, t as jsonClone } from "./json-CfTjpvW8.js";
2
- import { $ as Node, _ as stripUids, b as loadScene, et as diagnose, h as rebuildOptions, m as markTemplateName, p as markCloned, pt as Signal, y as buildSceneSubtree } from "./pose-ByFB_J3O.js";
3
- import { b as Engine, t as registerCoreNodes } from "./register-B768Qedj.js";
2
+ import { $ as Node, _ as stripUids, b as loadScene, et as diagnose, h as rebuildOptions, m as markTemplateName, p as markCloned, pt as Signal, y as buildSceneSubtree } from "./pose-O50uVW-j.js";
3
+ import { b as Engine, t as registerCoreNodes } from "./register-CIDbUbFG.js";
4
4
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
5
5
  import { p as registerNode } from "./touch-CioTZB-y.js";
6
6
  //#region src/net/loopback.ts
@@ -1150,7 +1150,7 @@ function applySyncPatch(root, patch, setProp, onMissingNode) {
1150
1150
  }
1151
1151
  }
1152
1152
  async function createDefaultTransport(config, diagnostics) {
1153
- const { createAgent8Server } = await import("./agent8-B-bh3n0X.js").then((n) => n.t);
1153
+ const { createAgent8Server } = await import("./agent8---rIaJ3j.js").then((n) => n.t);
1154
1154
  return createAgent8Server(config, diagnostics);
1155
1155
  }
1156
1156
  //#endregion
@@ -199,6 +199,6 @@ async function preloadSceneAssets(assets, title) {
199
199
  //#endregion
200
200
  //#region src/index.ts
201
201
  /** Engine version. Kept in sync with package.json by the release pipeline. */
202
- const VERSION = "0.78.2";
202
+ const VERSION = "0.79.1";
203
203
  //#endregion
204
204
  export { findPath as a, preloadUrls as i, assetUrls as n, gridFromRows as o, preloadSceneAssets as r, VERSION as t };
@@ -1,14 +1,14 @@
1
1
  import { n as jsonEquals, t as jsonClone } from "./json-CfTjpvW8.js";
2
- import { G as HudLayer, K as HudWidgetBase, L as resetMemorySaves, N as resolveViewport, b as loadScene, dt as registerBehavior, f as isCloned, i as worldPosition, ot as StubBehavior } from "./pose-ByFB_J3O.js";
3
- import { b as Engine } from "./register-B768Qedj.js";
2
+ import { G as HudLayer, K as HudWidgetBase, L as resetMemorySaves, N as resolveViewport, b as loadScene, dt as registerBehavior, f as isCloned, i as worldPosition, ot as StubBehavior } from "./pose-O50uVW-j.js";
3
+ import { b as Engine } from "./register-CIDbUbFG.js";
4
4
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
5
5
  import { t as Rng } from "./rng-CDOMybym.js";
6
- import { a as LIGHT_NODE_TYPES, n as startRecording } from "./replay-DrqQ6dZj.js";
6
+ import { a as LIGHT_NODE_TYPES, n as startRecording } from "./replay-CooHM9lL.js";
7
7
  import { c as getNodeSchema, d as mergeStaticProps, u as getNodeType } from "./touch-CioTZB-y.js";
8
- import { n as registerGameplayBehaviors } from "./gameplay-Bfff_beb.js";
9
- import { t as registerNodes2D } from "./register-7E3P1gz6.js";
10
- import { n as registerNodes3D, t as resolveEnvironmentHdri } from "./environment-presets-e_9YCnGu.js";
11
- import { a as NetworkManager, c as readSyncKey, i as sanitizeName, n as registerNodesNet, r as NetworkSpawner, s as findOwnerNode, t as createSplitScreen } from "./split-screen-B-dIcQsQ.js";
8
+ import { n as registerGameplayBehaviors } from "./gameplay-CplbZE7c.js";
9
+ import { t as registerNodes2D } from "./register-l4ZWcLwD.js";
10
+ import { n as registerNodes3D, t as resolveEnvironmentHdri } from "./environment-presets-fGpZHUab.js";
11
+ import { a as NetworkManager, c as readSyncKey, i as sanitizeName, n as registerNodesNet, r as NetworkSpawner, s as findOwnerNode, t as createSplitScreen } from "./split-screen-BRbSkBMO.js";
12
12
  import { Box3, Euler, Frustum, Matrix4, PerspectiveCamera, Quaternion, Ray, Vector3 } from "three";
13
13
  //#region src/core/asset-urls.ts
14
14
  /** Keys inside a `material` object that hold a texture URL. */
@@ -3858,8 +3858,8 @@ async function playMultiplayer(opts) {
3858
3858
  */
3859
3859
  async function joinLate(server, first, opts) {
3860
3860
  try {
3861
- const { Engine } = await import("./register-B768Qedj.js").then((n) => n.x);
3862
- const { loadScene } = await import("./pose-ByFB_J3O.js").then((n) => n.x);
3861
+ const { Engine } = await import("./register-CIDbUbFG.js").then((n) => n.x);
3862
+ const { loadScene } = await import("./pose-O50uVW-j.js").then((n) => n.x);
3863
3863
  const { jsonClone } = await import("./json-CfTjpvW8.js").then((n) => n.i);
3864
3864
  const engine = new Engine(opts.seed !== void 0 ? { seed: opts.seed + 999 } : {});
3865
3865
  engine.setScene(loadScene(jsonClone(opts.scene), {
@@ -4467,10 +4467,10 @@ async function runScript(json, opts) {
4467
4467
  if (opts.locale) engine.locale.locale = opts.locale;
4468
4468
  const physics = opts.physics ?? "auto";
4469
4469
  if (physics === "2d" || physics === "auto" && scene.dimension === "2d") {
4470
- const { enablePhysics2D } = await import("./physics-2d-Tuf5LAyq.js").then((n) => n.r);
4470
+ const { enablePhysics2D } = await import("./physics-2d-Cm1DIjk2.js").then((n) => n.r);
4471
4471
  await enablePhysics2D(engine);
4472
4472
  } else if (physics === "3d" || physics === "auto" && scene.dimension === "3d") {
4473
- const { enablePhysics3D } = await import("./physics-3d-C5MOujfQ.js").then((n) => n.r);
4473
+ const { enablePhysics3D } = await import("./physics-3d-CwJzo3fP.js").then((n) => n.r);
4474
4474
  await enablePhysics3D(engine);
4475
4475
  }
4476
4476
  const failures = [];
@@ -4755,10 +4755,10 @@ async function createPlaySession(json, opts = {}) {
4755
4755
  engine.setScene(scene);
4756
4756
  const physics = opts.physics ?? "auto";
4757
4757
  if (physics === "2d" || physics === "auto" && scene.dimension === "2d") {
4758
- const { enablePhysics2D } = await import("./physics-2d-Tuf5LAyq.js").then((n) => n.r);
4758
+ const { enablePhysics2D } = await import("./physics-2d-Cm1DIjk2.js").then((n) => n.r);
4759
4759
  await enablePhysics2D(engine);
4760
4760
  } else if (physics === "3d" || physics === "auto" && scene.dimension === "3d") {
4761
- const { enablePhysics3D } = await import("./physics-3d-C5MOujfQ.js").then((n) => n.r);
4761
+ const { enablePhysics3D } = await import("./physics-3d-CwJzo3fP.js").then((n) => n.r);
4762
4762
  await enablePhysics3D(engine);
4763
4763
  }
4764
4764
  const stepMs = 1e3 / (opts.fixedHz ?? 60);
package/dist/test.js CHANGED
@@ -1,3 +1,3 @@
1
- import { i as instancedScenes, r as auditScene } from "./replay-DrqQ6dZj.js";
2
- import { A as geometricPicker, C as facingReport, D as playtest, E as findPlayer, F as sceneAssetUrls, M as pointAtNode, N as describeFraming, O as playtestFailed, P as framingText, S as collectionProblems, T as failingReplays, _ as feelReport, a as registerAllNodes, b as takeCollectionSnapshots, c as feelsRung, d as ladderVerdict, f as saysRung, g as playMultiplayer, h as multiplayText, i as findFloatingProps, j as geometricView, k as playtestText, l as firstLine, m as multiplayProblems, n as createPlaySession, o as runScript, p as unmeasuredPlays, r as describeCapture, s as validateScene, t as captureScene, u as ladderText, v as feelText, w as facingText, x as agreementProblems, y as takeAgreementSnapshots } from "./test-CVbxnXlv.js";
1
+ import { i as instancedScenes, r as auditScene } from "./replay-CooHM9lL.js";
2
+ import { A as geometricPicker, C as facingReport, D as playtest, E as findPlayer, F as sceneAssetUrls, M as pointAtNode, N as describeFraming, O as playtestFailed, P as framingText, S as collectionProblems, T as failingReplays, _ as feelReport, a as registerAllNodes, b as takeCollectionSnapshots, c as feelsRung, d as ladderVerdict, f as saysRung, g as playMultiplayer, h as multiplayText, i as findFloatingProps, j as geometricView, k as playtestText, l as firstLine, m as multiplayProblems, n as createPlaySession, o as runScript, p as unmeasuredPlays, r as describeCapture, s as validateScene, t as captureScene, u as ladderText, v as feelText, w as facingText, x as agreementProblems, y as takeAgreementSnapshots } from "./test-Def33MoL.js";
3
3
  export { agreementProblems, auditScene, captureScene, collectionProblems, createPlaySession, describeCapture, describeFraming, facingReport, facingText, failingReplays, feelReport, feelText, feelsRung, findFloatingProps, findPlayer, firstLine, framingText, geometricPicker, geometricView, instancedScenes, ladderText, ladderVerdict, multiplayProblems, multiplayText, playMultiplayer, playtest, playtestFailed, playtestText, pointAtNode, registerAllNodes, runScript, saysRung, sceneAssetUrls, takeAgreementSnapshots, takeCollectionSnapshots, unmeasuredPlays, validateScene };
package/dist/vite.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { a as parseJsonText } from "./json-CfTjpvW8.js";
2
- import { P as newUid } from "./pose-ByFB_J3O.js";
2
+ import { P as newUid } from "./pose-O50uVW-j.js";
3
3
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
4
- import { t as VERSION } from "./src-rS7AyeKD.js";
4
+ import { t as VERSION } from "./src-3rJ6QSfX.js";
5
5
  import { n as diffSignatures } from "./frame-report-D-_7YF2G.js";
6
- import { s as validateScene } from "./test-CVbxnXlv.js";
6
+ import { s as validateScene } from "./test-Def33MoL.js";
7
7
  import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
8
8
  import { basename, dirname, extname, join, normalize, relative, resolve, sep } from "node:path";
9
9
  import { fileURLToPath } from "node:url";
@@ -1 +1 @@
1
- import{i as e,n as t}from"./index-Db74LZY-.js";async function n(e,n){return new a((await t(()=>import(`./GameServer-C56iOUgF.js`),[],import.meta.url)).GameServer,e,{diagnostics:n})}var r=[500,1e3,2e3,4e3,8e3],i=8,a=class{raw;active=new Map;reconnecting=!1;disposed=!1;diagnostics;wait;constructor(e,t,n){this.diagnostics=n?.diagnostics??null,this.wait=n?.wait??(e=>new Promise(t=>{setTimeout(t,e)})),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{for(let t=0;t<i;t++){let n=!1,i=null;try{n=await this.rawConnect()!==!1}catch(e){i=e}if(this.disposed)return;if(n){for(let e of this.active.values())e.off(),e.off=e.make();t>0&&e(this.diagnostics,`info`,`[incanto] multiplayer reconnected after ${t+1} attempts.`);return}t===0&&e(this.diagnostics,`warn`,`[incanto] the multiplayer connection dropped and the server would not take it back${i?` (${i instanceof Error?i.message:String(i)})`:``}. Retrying — other players cannot see this one until it comes back.`);let a=r[Math.min(t,r.length-1)]??8e3;if(await this.wait(a),this.disposed)return}e(this.diagnostics,`error`,`[incanto] multiplayer gave up after ${i} reconnect attempts — this client is offline and the others cannot see it. Call connect() again to retry.`)}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{n as createAgent8Server};
1
+ import{i as e,n as t}from"./index-QEwr2eXD.js";async function n(e,n){return new a((await t(()=>import(`./GameServer-C56iOUgF.js`),[],import.meta.url)).GameServer,e,{diagnostics:n})}var r=[500,1e3,2e3,4e3,8e3],i=8,a=class{raw;active=new Map;reconnecting=!1;disposed=!1;diagnostics;wait;constructor(e,t,n){this.diagnostics=n?.diagnostics??null,this.wait=n?.wait??(e=>new Promise(t=>{setTimeout(t,e)})),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{for(let t=0;t<i;t++){let n=!1,i=null;try{n=await this.rawConnect()!==!1}catch(e){i=e}if(this.disposed)return;if(n){for(let e of this.active.values())e.off(),e.off=e.make();t>0&&e(this.diagnostics,`info`,`[incanto] multiplayer reconnected after ${t+1} attempts.`);return}t===0&&e(this.diagnostics,`warn`,`[incanto] the multiplayer connection dropped and the server would not take it back${i?` (${i instanceof Error?i.message:String(i)})`:``}. Retrying — other players cannot see this one until it comes back.`);let a=r[Math.min(t,r.length-1)]??8e3;if(await this.wait(a),this.disposed)return}e(this.diagnostics,`error`,`[incanto] multiplayer gave up after ${i} reconnect attempts — this client is offline and the others cannot see it. Call connect() again to retry.`)}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{n as createAgent8Server};
@@ -0,0 +1,3 @@
1
+ import{a as e,o as t,r as n,t as r}from"./index-QEwr2eXD.js";function i(e,t,n,r=1){let i=Math.min(e.x0,e.x1)*r,a=Math.max(e.x0,e.x1)*r,o=Math.min(e.y0,e.y1)*r,s=Math.max(e.y0,e.y1)*r,c=Math.max(0,Math.min(Math.round(i),t-1)),l=Math.max(0,Math.min(Math.round(o),n-1));return{x:c,y:l,w:Math.max(1,Math.min(Math.round(a-i),t-c)),h:Math.max(1,Math.min(Math.round(s-o),n-l))}}function a(e,t,n,r){let{x:i,y:a,w:o,h:s}=r,c=new Uint8ClampedArray(o*s*4);for(let n=0;n<s;n++){let r=((a+n)*t+i)*4,s=n*o*4;c.set(e.subarray(r,r+o*4),s)}return{pixels:c,width:o,height:s}}function o(e){if(!e)return`// no scene loaded`;let t=e.source??e;return JSON.stringify(t,null,2)}async function s(e){let t=globalThis.navigator;if(!t?.clipboard?.writeText)return!1;try{return await t.clipboard.writeText(e),!0}catch{return!1}}async function c(e,t){let n=globalThis,r=n.navigator?.clipboard?.write;if(!r||!n.ImageData||!n.ClipboardItem)return!1;try{let i=e.createElement(`canvas`);i.width=t.width,i.height=t.height;let a=i.getContext(`2d`);if(!a)return!1;a.putImageData(new n.ImageData(t.pixels,t.width,t.height),0,0);let o=await new Promise(e=>i.toBlob(e,`image/png`));return o?(await r.call(n.navigator?.clipboard,[new n.ClipboardItem({"image/png":o})]),!0):!1}catch{return!1}}var l=[`nw`,`n`,`ne`,`e`,`se`,`s`,`sw`,`w`],u={nw:[0,0],n:[.5,0],ne:[1,0],e:[1,.5],se:[1,1],s:[.5,1],sw:[0,1],w:[0,.5]},d={nw:`nwse-resize`,se:`nwse-resize`,ne:`nesw-resize`,sw:`nesw-resize`,n:`ns-resize`,s:`ns-resize`,e:`ew-resize`,w:`ew-resize`},f=(e,t,n)=>Math.max(t,Math.min(n,e));function p(e){return{x:Math.min(e.x0,e.x1),y:Math.min(e.y0,e.y1),w:Math.abs(e.x1-e.x0),h:Math.abs(e.y1-e.y0)}}function m(e,t,n,r,i,a){let o=e.x,s=e.y,c=e.x+e.w,l=e.y+e.h;return t.includes(`w`)&&(o=f(o+n,0,i)),t.includes(`e`)&&(c=f(c+n,0,i)),t.includes(`n`)&&(s=f(s+r,0,a)),t.includes(`s`)&&(l=f(l+r,0,a)),{x:Math.min(o,c),y:Math.min(s,l),w:Math.max(1,Math.abs(c-o)),h:Math.max(1,Math.abs(l-s))}}function h(e,t,n,r,i){return{...e,x:f(e.x+t,0,Math.max(0,r-e.w)),y:f(e.y+n,0,Math.max(0,i-e.h))}}function g(e,t,n,r,i,a=8){let o=f(e.x+e.w/2-t/2,a,Math.max(a,r-t-a)),s=e.y+e.h+a,c=e.y-n-a;return{x:o,y:s+n<=i-a?s:c>=a?c:f(s,a,Math.max(a,i-n-a))}}function _(e,t){let n=e?.clientWidth??0,r=e?.clientHeight??0;return n>0&&r>0?{w:n,h:r}:{w:t.documentElement?.clientWidth??0,h:t.documentElement?.clientHeight??0}}function v(e,t,n,r,i,a,o=180,s=120){let c=Math.max(o,n),l=Math.max(s,r);return{x:i>0?Math.min(Math.max(0,e),Math.max(0,i-c)):e,y:a>0?Math.min(Math.max(0,t),Math.max(0,a-l)):t,w:c,h:l}}function y(e,t,n,r,i,a=4){let o=Math.min(Math.max(0,e.x),Math.max(0,r-t)),s=e.y+e.h+a,c=e.y-n-a;return s+n<=i?{x:o,y:s}:c>=0?{x:o,y:c}:{x:o,y:Math.min(Math.max(0,s),Math.max(0,i-n))}}function b(e,t,n){let r=e=>{e.key===`Escape`&&n()},i=e=>{let r=e.target;if(r){for(let e of t)if(e&&(e===r||e.contains?.(r)))return;n()}};return e.addEventListener?.(`keydown`,r),e.addEventListener?.(`pointerdown`,i),()=>{e.removeEventListener?.(`keydown`,r),e.removeEventListener?.(`pointerdown`,i)}}function x(e,t){for(let[n,r]of Object.entries(t))e.style[n]=r}var S=`rgba(18, 20, 26, 0.92)`,C=`1px solid rgba(255,255,255,0.14)`,w=`12px ui-monospace, SFMono-Regular, Menlo, monospace`,T=class{doc;host;el;body;onClose=()=>{};x;y;w;h;constructor(e,t,n,r){this.doc=e,this.host=t,this.x=r.x,this.y=r.y,this.w=r.w,this.h=r.h,this.el=e.createElement(`div`),x(this.el,{position:`absolute`,background:S,border:C,borderRadius:`8px`,color:`rgba(255,255,255,0.88)`,font:w,display:`flex`,flexDirection:`column`,overflow:`hidden`,zIndex:`40`,pointerEvents:`auto`,boxShadow:`0 8px 28px rgba(0,0,0,0.45)`});let i=e.createElement(`div`);i.textContent=n,x(i,{padding:`6px 28px 6px 10px`,background:`rgba(255,255,255,0.07)`,cursor:`move`,userSelect:`none`,touchAction:`none`,fontWeight:`700`}),this.el.appendChild(i);let a=e.createElement(`div`);a.textContent=`×`,a.title=`close`,x(a,{position:`absolute`,top:`2px`,right:`8px`,cursor:`pointer`,fontSize:`16px`,lineHeight:`20px`,opacity:`0.7`}),a.addEventListener(`click`,()=>this.onClose()),this.el.appendChild(a),this.body=e.createElement(`div`),x(this.body,{flex:`1`,overflow:`auto`,padding:`8px 10px`}),this.el.appendChild(this.body);let o=e.createElement(`div`);o.textContent=`◢`,x(o,{position:`absolute`,right:`2px`,bottom:`0`,cursor:`nwse-resize`,opacity:`0.5`,userSelect:`none`,touchAction:`none`}),this.el.appendChild(o),this.wireDrag(i,(e,t)=>{this.x+=e,this.y+=t,this.layout()}),this.wireDrag(o,(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,this.doc),t=v(this.x,this.y,this.w,this.h,e.w,e.h);this.x=t.x,this.y=t.y,this.w=t.w,this.h=t.h,x(this.el,{left:`${t.x}px`,top:`${t.y}px`,width:`${t.w}px`,height:`${t.h}px`})}wireDrag(e,t){let r=null,i=0,a=0;e.addEventListener(`pointerdown`,t=>{r=t.pointerId,i=t.clientX,a=t.clientY,n(e,t.pointerId)}),e.addEventListener(`pointermove`,e=>{e.pointerId===r&&(t(e.clientX-i,e.clientY-a),i=e.clientX,a=e.clientY)});let o=e=>{e.pointerId===r&&(r=null)};e.addEventListener(`pointerup`,o),e.addEventListener(`pointercancel`,o)}},E=4,D=`#6ee7dc`,O=`rgba(18,20,26,0.94)`,k=`12px ui-monospace, Menlo, monospace`;function A(e){let{doc:t,container:r}=e,i=t.createElement(`div`);x(i,{position:`absolute`,inset:`0`,cursor:`crosshair`,zIndex:`80`,pointerEvents:`auto`,userSelect:`none`,touchAction:`none`});let a=t.createElement(`div`);x(a,{position:`absolute`,inset:`0`,background:`rgba(10,14,20,0.35)`,pointerEvents:`none`}),i.appendChild(a);let o=t.createElement(`div`);x(o,{position:`absolute`,outline:`1px solid ${D}`,boxShadow:`0 0 0 9999px rgba(10,14,20,0.35)`,cursor:`grab`,display:`none`,pointerEvents:`auto`}),i.appendChild(o);let s=t.createElement(`div`);x(s,{position:`absolute`,padding:`2px 6px`,borderRadius:`4px`,background:O,color:D,font:k,pointerEvents:`none`,display:`none`,whiteSpace:`nowrap`}),i.appendChild(s);let c=t.createElement(`div`);c.textContent=`drag to select · Esc to cancel`,x(c,{position:`absolute`,top:`10px`,left:`50%`,transform:`translateX(-50%)`,padding:`4px 10px`,borderRadius:`6px`,background:O,color:`rgba(255,255,255,0.85)`,font:k,pointerEvents:`none`,whiteSpace:`nowrap`}),i.appendChild(c);let f=null,_=`idle`,v={x:0,y:0},y={x:0,y:0,w:0,h:0},b=()=>({w:r.clientWidth||1,h:r.clientHeight||1});for(let e of l){let n=t.createElement(`div`),[r,i]=u[e];x(n,{position:`absolute`,left:`${r*100}%`,top:`${i*100}%`,width:`10px`,height:`10px`,marginLeft:`-5px`,marginTop:`-5px`,borderRadius:`2px`,background:D,border:`1px solid rgba(10,14,20,0.75)`,cursor:d[e],pointerEvents:`auto`}),n.addEventListener(`pointerdown`,t=>{A(t,e)}),o.appendChild(n)}let S=t.createElement(`div`);x(S,{position:`absolute`,display:`none`,gap:`6px`,padding:`6px`,borderRadius:`8px`,background:O,border:`1px solid rgba(255,255,255,0.18)`,font:k,pointerEvents:`auto`,whiteSpace:`nowrap`,boxShadow:`0 4px 16px rgba(0,0,0,0.45)`});let C=(e,n,r)=>{let i=t.createElement(`div`);return i.textContent=e,x(i,{padding:`5px 10px`,borderRadius:`5px`,cursor:`pointer`,color:n?`#08121a`:`rgba(255,255,255,0.85)`,background:n?D:`rgba(255,255,255,0.08)`,userSelect:`none`}),i.addEventListener(`pointerdown`,e=>{w(e),r()}),i};S.appendChild(C(`Copy to clipboard`,!0,()=>P())),S.appendChild(C(`Cancel`,!1,()=>L())),i.appendChild(S);function w(e){e.preventDefault?.(),e.stopPropagation?.()}function T(e){let t=e,n=r.getBoundingClientRect?.()??{left:0,top:0};return{x:(t.clientX??0)-n.left,y:(t.clientY??0)-n.top}}function A(e,t){w(e),v=T(e),_=t,t===`create`?f={x:v.x,y:v.y,w:0,h:0}:f&&(y=f),x(S,{display:`none`}),x(o,{cursor:t===`move`?`grabbing`:`crosshair`});let r=e.pointerId;r!==void 0&&n(i,r),j()}function j(){if(!f){x(o,{display:`none`}),x(s,{display:`none`}),x(a,{display:`block`});return}x(a,{display:`none`}),x(o,{display:`block`,left:`${f.x}px`,top:`${f.y}px`,width:`${f.w}px`,height:`${f.h}px`});let t=e.scale();s.textContent=`${Math.round(f.w*t)}×${Math.round(f.h*t)}`;let n=f.y-24;x(s,{display:`block`,left:`${Math.max(2,f.x)}px`,top:`${n>=2?n:f.y+4}px`})}function M(){if(!f||f.w<E||f.h<E)return;x(S,{display:`flex`});let e=b(),t=S.offsetWidth||200,n=S.offsetHeight||36,r=g(f,t,n,e.w,e.h);x(S,{left:`${r.x}px`,top:`${r.y}px`})}i.addEventListener(`pointerdown`,e=>{A(e,`create`)}),o.addEventListener(`pointerdown`,e=>{A(e,`move`)}),i.addEventListener(`pointermove`,e=>{if(_===`idle`||!f)return;let t=T(e),n=b();if(_===`create`){let e=p({x0:v.x,y0:v.y,x1:t.x,y1:t.y});f={x:Math.max(0,Math.min(e.x,n.w)),y:Math.max(0,Math.min(e.y,n.h)),w:Math.min(e.w,n.w-Math.max(0,Math.min(e.x,n.w))),h:Math.min(e.h,n.h-Math.max(0,Math.min(e.y,n.h)))}}else f=_===`move`?h(y,t.x-v.x,t.y-v.y,n.w,n.h):m(y,_,t.x-v.x,t.y-v.y,n.w,n.h);j()});let N=()=>{_!==`idle`&&(_===`create`&&f&&(f.w<E||f.h<E)&&(f=null),_=`idle`,x(o,{cursor:`grab`}),c.textContent=f?`drag the handles or the middle · Enter to copy · Esc to cancel`:`drag to select · Esc to cancel`,j(),M())};i.addEventListener(`pointerup`,N),i.addEventListener(`pointercancel`,N);function P(){let t=f;L(),t&&e.onCopy(t)}let F=e=>{let t=e.key;t===`Escape`?L():t===`Enter`&&f&&P()};t.addEventListener?.(`keydown`,F);let I=!1;function L(){I||(I=!0,t.removeEventListener?.(`keydown`,F),i.remove(),e.onClose())}return r.appendChild(i),{element:i,close:L}}var j=96,M=200,N=8192;function P(e){return Array.isArray(e)?`Array(${e.length})`:`Object(${Object.keys(e).length} keys)`}function F(e,t){if(Array.isArray(e)&&e.some(e=>typeof e==`object`&&!!e)){let t=e.slice(0,M).map(e=>JSON.stringify(e)),n=e.length-M;return t.join(`
2
+ `)+(n>0?`\n… ${n} more`:``)}return t.length>N?`${t.slice(0,N)} … (${t.length-N} more chars)`:t}function I(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}var L=2,R=4;function z(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 H(e,r,n,t.statsSource,t.actions,t.frameSource)}var B=300,V=[`log`,`info`,`warn`,`error`,`debug`],H=class{engine;container;doc;statsSource;actions;frameSource;panels=new Map;cleanups=[];menuButton;dropdown=null;dismissDropdown=null;menuPos={x:8,y:8};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;resumeScale=1;timeEls=null;hovering=!1;constructor(e,t,n,r,i=[],a){this.engine=e,this.container=t,this.doc=n,this.statsSource=r,this.actions=i,this.frameSource=a,this.menuButton=n.createElement(`div`),this.menuButton.textContent=`☰ debug`,x(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.bindMenuDrag(),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(G).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(),this.syncTime())}))}isOpen(e){return e===`copyScene`||e===`captureRegion`?!1: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 r(`2d`).concat(r(`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)){e===`explorer`&&this.renderExplorer(),e===`inspector`&&this.renderInspector(),e===`logs`&&this.renderLogs(),e===`time`&&this.renderTime();return}let t=new T(this.doc,this.container,{explorer:`Explorer`,inspector:`Inspector`,logs:`Logs`,time:`Time`}[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},time:{x:556,y:44,w:260,h:150}}[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(),e===`time`&&this.renderTime()}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===`copyScene`){this.copyScene();return}if(e===`captureRegion`){this.captureRegion();return}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 V){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(G).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.closeDropdown(),this.menuButton.remove()}menuLabel(e,t){let n=e===`colliders`&&this.colliderMode!==`off`?` · ${this.colliderMode}`:``;return`${this.isOpen(e)?`✓ `:``}${t}${n}`}bindMenuDrag(){let e=null,t=!1;this.menuButton.addEventListener(`pointerdown`,n=>{let r=n;e={x:r.clientX??0,y:r.clientY??0,bx:this.menuPos.x,by:this.menuPos.y},t=!1,r.pointerId!==void 0&&this.menuButton.setPointerCapture?.(r.pointerId)}),this.menuButton.addEventListener(`pointermove`,n=>{if(!e)return;let r=n,i=(r.clientX??0)-e.x,a=(r.clientY??0)-e.y;!t&&Math.hypot(i,a)<R||(t||(t=!0,this.closeDropdown(),x(this.menuButton,{cursor:`grabbing`})),this.moveMenuButton(e.bx+i,e.by+a))});let n=()=>{if(!e)return;let n=t;e=null,t=!1,x(this.menuButton,{cursor:`pointer`}),n||this.toggleDropdown()};this.menuButton.addEventListener(`pointerup`,n),this.menuButton.addEventListener(`pointercancel`,n)}moveMenuButton(e,t){let n=this.menuButton,r=_(this.container,this.doc),i=v(e,t,n.offsetWidth??0,n.offsetHeight??0,r.w,r.h,0,0);this.menuPos={x:i.x,y:i.y},x(this.menuButton,{left:`${i.x}px`,top:`${i.y}px`})}closeDropdown(){this.dismissDropdown?.(),this.dismissDropdown=null,this.dropdown?.remove(),this.dropdown=null}toggleDropdown(){if(this.dropdown){this.closeDropdown();return}let e=this.doc.createElement(`div`);x(e,{position:`absolute`,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`],[`time`,`Time`],[`copyScene`,`Copy scene JSON`],[`captureRegion`,`Capture region`],[`stats`,`Stats`],[`colliders`,`Colliders`]]){let r=this.doc.createElement(`div`);r.textContent=this.menuLabel(t,n),x(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.closeDropdown()}),e.appendChild(r)}for(let t of this.actions){let n=this.doc.createElement(`div`);n.textContent=t.label,x(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.closeDropdown(),t.run()}),e.appendChild(n)}this.container.appendChild(e),this.dropdown=e;let t=e,n=this.menuButton,r=_(this.container,this.doc),i=y({x:this.menuPos.x,y:this.menuPos.y,w:n.offsetWidth??0,h:n.offsetHeight??26},t.offsetWidth??0,t.offsetHeight??0,r.w,r.h);x(e,{left:`${i.x}px`,top:`${i.y}px`}),this.dismissDropdown=b(this.doc,[e,this.menuButton],()=>this.closeDropdown())}openStatsChip(){if(this.statsChip)return;let e=this.doc.createElement(`div`);x(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 ${W(n.triangles)}`],...n.drawCalls===void 0?[]:[`calls ${n.drawCalls}`]].join(` · `),i=t.phases,a=`\nphys ${i.fixedMs.toFixed(1)} · logic ${i.updateMs.toFixed(1)} · draw ${i.renderMs.toFixed(1)} · other ${i.otherMs.toFixed(1)}`;e.textContent=`${Math.round(t.fps)} fps · ${t.frameMs.toFixed(1)} ms\n${r}${a}`}renderExplorer(){let e=this.panels.get(`explorer`);if(!e)return;let t=e.body.scrollTop;U(e.body);let n=this.engine.scene?.root;if(!n){e.body.scrollTop=t;return}let r=(e,t)=>{let n=e.constructor,i=e.children.length>0,a=this.collapsedFlags.get(e)===!0,o=this.doc.createElement(`div`);x(o,{display:`flex`,alignItems:`center`,cursor:`pointer`,padding:`1px 2px`,borderRadius:`3px`,background:e===this.selected?`rgba(110,160,255,0.25)`:`transparent`});let s=this.doc.createElement(`span`);s.textContent=i?a?`▸`:`▾`:`·`,x(s,{width:`14px`,flex:`none`,textAlign:`center`,opacity:i?`0.85`:`0.25`,userSelect:`none`}),i&&s.addEventListener(`click`,t=>{t.stopPropagation?.(),this.collapsedFlags.set(e,!a),this.renderExplorer()}),o.appendChild(s);let c=this.doc.createElement(`span`);c.textContent=e.name,x(c,{whiteSpace:`nowrap`}),o.appendChild(c);let l=this.doc.createElement(`span`);if(l.textContent=` ${n.typeName}`,x(l,{opacity:`0.45`,whiteSpace:`nowrap`,fontSize:`10px`}),o.appendChild(l),i&&a){let t=this.doc.createElement(`span`);t.textContent=` (${e.children.length})`,x(t,{opacity:`0.35`,fontSize:`10px`}),o.appendChild(t)}if(o.addEventListener(`click`,()=>{this.selected=e,this.engine.debugSelection=e,this.applyColliderScope(),this.open(`inspector`),this.renderExplorer(),this.renderInspector()}),t.appendChild(o),i&&!a){let n=this.doc.createElement(`div`);x(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 t=this.panels.get(`inspector`);if(!t)return;let n=t.body.scrollTop;U(t.body);let r=this.selected;if(r&&r.tree===null&&(this.selected=null,this.engine.debugSelection=null,this.applyColliderScope(),r=null),!r){let e=this.doc.createElement(`div`);e.textContent=`select a node in the Explorer`,x(e,{opacity:`0.6`}),t.body.appendChild(e);return}let i=r.constructor,a=this.doc.createElement(`div`);if(a.textContent=`${r.getPath()} · ${i.typeName}${r.uid?` · ${r.uid}`:``}`,x(a,{fontWeight:`700`,marginBottom:`6px`,whiteSpace:`pre-wrap`}),t.body.appendChild(a),r.groups.size>0){let e=this.doc.createElement(`div`);e.textContent=`groups: ${[...r.groups].join(`, `)}`,x(e,{opacity:`0.7`,marginBottom:`6px`}),t.body.appendChild(e)}let o=e(i),s=r;for(let e of Object.keys(o)){let n=o[e];this.renderValueRow(t.body,r,e,{read:()=>s[e],write:t=>{s[e]=t},options:n?.options,variants:n?.variants})}t.body.scrollTop=n}renderValueRow(e,n,r,i){let a=i.read(),o=i.options,s={get[r](){return i.read()},set[r](e){i.write(e)}},c=this.doc.createElement(`div`);x(c,{display:`flex`,gap:`6px`,alignItems:`center`,margin:`2px 0`});let l=this.doc.createElement(`div`);l.textContent=r,x(l,{minWidth:`84px`,opacity:`0.75`}),c.appendChild(l);let u=(e,t)=>{let i=this.doc.createElement(`input`);return i.type=`number`,i.value=String(e),x(i,q(`70px`)),this.trackEditing(i),i.addEventListener(`change`,()=>{let e=Number(i.value);Number.isFinite(e)?t(e):i.value=String(n[r])}),i};if(typeof a==`number`)c.appendChild(u(a,e=>{s[r]=e}));else if(typeof a==`boolean`){let e=this.doc.createElement(`input`);e.type=`checkbox`,e.checked=a,this.trackEditing(e),e.addEventListener(`change`,()=>{s[r]=e.checked}),c.appendChild(e)}else if(typeof a==`string`&&o&&o.length>0){let e=this.doc.createElement(`select`);for(let t of o.includes(a)?o:[a,...o]){let n=this.doc.createElement(`option`);n.value=t,n.textContent=t,t===a&&(n.selected=!0),e.appendChild(n)}e.value=a,this.trackEditing(e),e.addEventListener(`change`,()=>{s[r]=e.value}),x(e,q(`110px`)),c.appendChild(e)}else if(typeof a==`string`){let e=this.doc.createElement(`input`);e.type=`text`,e.value=a,this.trackEditing(e),x(e,q(`140px`)),e.addEventListener(`change`,()=>{s[r]=e.value}),c.appendChild(e)}else if(Array.isArray(a)&&a.length<=8&&a.every(e=>typeof e==`number`))for(let e=0;e<a.length;e++)c.appendChild(u(a[e],t=>{let n=[...s[r]];n[e]=t,s[r]=n}));else if(I(a)){let o=this.doc.createElement(`div`);x(o,{marginLeft:`10px`,paddingLeft:`8px`,borderLeft:`1px solid rgba(255,255,255,0.14)`});let s=i.variants?.tag,l=Object.keys(a);s&&!l.includes(s)&&l.unshift(s);let u=i.path??r;for(let e of l){let r=e===s;this.renderValueRow(o,n,e,{path:`${u}.${e}`,read:()=>i.read()[e]??(r?``:null),write:n=>{if(r&&i.variants){let e=i.variants.byTag[String(n)];if(e!==void 0){i.write(t(e));return}}i.write({...i.read(),[e]:n})},options:r&&i.variants?Object.keys(i.variants.byTag):void 0})}e.appendChild(c),e.appendChild(o);return}else{let o=JSON.stringify(t(a));if(o.length<=j){let e=this.doc.createElement(`div`);e.textContent=o,x(e,{opacity:`0.65`,whiteSpace:`pre-wrap`,wordBreak:`break-all`}),c.appendChild(e)}else{let t=i.path??r,s=this.detailOpen.get(n)?.has(t)??!1,l=this.doc.createElement(`div`);if(l.textContent=`${s?`▾`:`▸`} ${P(a)}`,x(l,{opacity:`0.75`,cursor:`pointer`,userSelect:`none`}),l.addEventListener(`click`,()=>{let e=this.detailOpen.get(n);e||(e=new Set,this.detailOpen.set(n,e)),s?e.delete(t):e.add(t),this.renderInspector()}),c.appendChild(l),e.appendChild(c),s){let t=this.doc.createElement(`div`);t.textContent=F(a,o),x(t,{opacity:`0.6`,whiteSpace:`pre-wrap`,wordBreak:`break-all`,marginLeft:`10px`,paddingLeft:`8px`,borderLeft:`1px solid rgba(255,255,255,0.14)`}),e.appendChild(t)}return}}e.appendChild(c)}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>B&&this.logRows.splice(0,this.logRows.length-B),this.renderLogs()}async copyScene(){let e=await s(o(this.engine.scene??null));return this.toast(e?`scene JSON copied`:`could not reach the clipboard`),e}captureRegion(){this.capture||=(this.captureScale=globalThis.devicePixelRatio??1,this.frameSource?.().then(e=>{this.captureScale=e.width/Math.max(1,this.container.clientWidth||e.width)}).catch(()=>{}),A({doc:this.doc,container:this.container,scale:()=>this.captureScale,onCopy:e=>void this.copyRegion({x0:e.x,y0:e.y,x1:e.x+e.w,y1:e.y+e.h}),onClose:()=>{this.capture=null}}))}capture=null;captureScale=1;async copyRegion(e){let t=this.frameSource;if(!t)return this.toast(`no renderer to capture from`),!1;try{let n=await t(),r=n.width/Math.max(1,this.container.clientWidth||n.width),o=i(e,n.width,n.height,r),s=a(n.pixels,n.width,n.height,o),l=await c(this.doc,s);return this.toast(l?`copied ${s.width}×${s.height}`:`could not copy the image`),l}catch(e){return this.toast(`capture failed: ${e instanceof Error?e.message:String(e)}`),!1}}toast(e){let t=this.doc.createElement(`div`);t.textContent=e,x(t,{position:`absolute`,bottom:`16px`,left:`50%`,transform:`translateX(-50%)`,padding:`6px 12px`,borderRadius:`6px`,background:`rgba(18,20,26,0.92)`,color:`rgba(255,255,255,0.9)`,font:`12px ui-monospace, Menlo, monospace`,zIndex:`90`,pointerEvents:`none`}),this.container.appendChild(t),setTimeout(()=>t.remove(),1800)}setTimeScale(e){Number.isFinite(e)&&(this.engine.timeScale=Math.max(0,e),this.syncTime())}setPaused(e){e?(this.engine.timeScale>0&&(this.resumeScale=this.engine.timeScale),this.engine.timeScale=0):this.engine.timeScale=this.resumeScale>0?this.resumeScale:1,this.syncTime()}get paused(){return this.engine.timeScale===0}nextFrame(){this.paused||this.setPaused(!0),this.engine.step({ignorePause:!0}),this.syncTime()}syncTime(){let e=this.timeEls;if(!e)return;let t=this.engine.timeScale,n=String(Math.round(t*1e3)/1e3);this.editing===0&&(e.slider.value=String(Math.min(t,L)),e.box.value=n),e.readout.textContent=`timeScale ${n}${this.paused?` · paused`:``}`,e.pause.textContent=this.paused?`▶ Resume`:`⏸ Pause`}renderTime(){let e=this.panels.get(`time`);if(!e)return;U(e.body),this.timeEls=null;let t=this.doc.createElement(`div`);x(t,{marginBottom:`6px`,opacity:`0.85`}),e.body.appendChild(t);let n=this.doc.createElement(`input`);n.type=`range`,n.min=`0`,n.max=String(L),n.step=`0.05`,n.value=String(Math.min(this.engine.timeScale,L)),x(n,{width:`100%`,marginBottom:`6px`}),this.trackEditing(n),n.addEventListener(`input`,()=>this.setTimeScale(Number(n.value))),e.body.appendChild(n);let r=this.doc.createElement(`div`);x(r,{display:`flex`,gap:`6px`,alignItems:`center`,marginBottom:`8px`});let i=this.doc.createElement(`input`);i.type=`number`,i.min=`0`,i.step=`0.05`,i.value=String(this.engine.timeScale),x(i,q(`72px`)),this.trackEditing(i),i.addEventListener(`change`,()=>{let e=Number(i.value);Number.isFinite(e)&&this.setTimeScale(e),this.syncTimeAfterEdit()}),r.appendChild(i);for(let e of[.25,.5,1,2]){let t=this.doc.createElement(`div`);t.textContent=`${e}×`,x(t,{cursor:`pointer`,opacity:`0.7`,padding:`2px 4px`}),t.addEventListener(`click`,()=>this.setTimeScale(e)),r.appendChild(t)}e.body.appendChild(r);let a=this.doc.createElement(`div`);x(a,{display:`flex`,gap:`8px`});let o=this.doc.createElement(`div`);x(o,K()),o.addEventListener(`click`,()=>this.setPaused(!this.paused)),a.appendChild(o);let s=this.doc.createElement(`div`);s.textContent=`⏭ Next frame`,s.title=`Pauses, then advances one fixed step`,x(s,K()),s.addEventListener(`click`,()=>this.nextFrame()),a.appendChild(s),e.body.appendChild(a),this.timeEls={slider:n,box:i,readout:t,pause:o},this.syncTime()}syncTimeAfterEdit(){let e=this.timeEls;if(!e)return;let t=this.engine.timeScale;e.slider.value=String(Math.min(t,L)),e.box.value=String(Math.round(t*1e3)/1e3)}renderLogs(){let e=this.panels.get(`logs`);if(!e)return;U(e.body);let t=this.doc.createElement(`div`);x(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}`,x(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`,x(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}`,x(n,{color:r[t.level],whiteSpace:`pre-wrap`}),e.body.appendChild(n)}}};function U(e){for(let t of[...e.children])t.remove()}function W(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(1)}k`:String(e)}function G(e){if(typeof e==`string`)return e;if(e instanceof Error){let t=e.stack?.split(`
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 K(){return{background:`rgba(255,255,255,0.08)`,border:`1px solid rgba(255,255,255,0.2)`,borderRadius:`4px`,padding:`4px 8px`,cursor:`pointer`,userSelect:`none`}}function q(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{z as attachDebugOverlay};