incanto 0.69.0 → 0.70.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/_behaviors-loader.mjs +22 -0
- package/bin/_read-json.mjs +28 -0
- package/bin/incanto-assets.mjs +5 -4
- package/bin/incanto-check.mjs +58 -31
- package/bin/incanto-editor.mjs +128 -5
- package/bin/incanto-env.mjs +3 -2
- package/bin/incanto-feel.mjs +24 -13
- package/bin/incanto-frame.mjs +8 -1
- package/bin/incanto-multiplay.mjs +11 -9
- package/bin/incanto-new.mjs +105 -10
- package/bin/incanto-play.mjs +158 -16
- package/bin/incanto-playtest.mjs +66 -23
- package/bin/incanto-skills.mjs +14 -2
- package/bin/incanto-verify.mjs +125 -44
- package/bin/incanto.mjs +3 -2
- package/dist/2d.d.ts +281 -34
- package/dist/2d.js +4 -4
- package/dist/3d.d.ts +157 -9
- package/dist/3d.js +7 -7
- package/dist/{agent8-CvsfVskX.js → agent8-CmNF01gA.js} +61 -8
- package/dist/{audio-player-C0j2k-yB.d.ts → audio-player-DaMxqfNE.d.ts} +2 -2
- package/dist/{behavior-rm8vVzu_.d.ts → behavior-DZExDn9o.d.ts} +744 -46
- package/dist/{create-game-CwxEDlCm.js → create-game-Bwvh6q8A.js} +142 -59
- package/dist/{create-game-CvJ1wSRP.js → create-game-C7ffQWW7.js} +97 -47
- package/dist/debug.d.ts +1 -1
- package/dist/debug.js +2 -3
- package/dist/diagnostics-Cu85N3tL.d.ts +12 -0
- package/dist/{editor-switch-CnIOiyNJ.d.ts → editor-switch-CFU9mCec.d.ts} +22 -13
- package/dist/editor.js +1065 -863
- package/dist/env.d.ts +1 -1
- package/dist/env.js +5 -3
- package/dist/{environment-presets-BO-7XoFV.js → environment-presets-D6Q5BxeE.js} +298 -45
- package/dist/{gameplay-D1KixWK8.js → gameplay-BfHkuzVb.js} +809 -211
- package/dist/gameplay.d.ts +187 -7
- package/dist/gameplay.js +1 -1
- package/dist/{heightmap-CRK0M4jT.js → heightmap-BYgD5Edk.js} +1 -1
- package/dist/index.d.ts +156 -13
- package/dist/index.js +10 -12
- package/dist/json-CfTjpvW8.js +67 -0
- package/dist/{loader-DadV2QCT.d.ts → loader-Cff09LMm.d.ts} +2 -2
- package/dist/net.d.ts +27 -3
- package/dist/net.js +2 -2
- package/dist/{noise-CGUMx44x.js → noise-D3nPpmFg.js} +1 -1
- package/dist/{physics-2d-CF5yyjbj.js → physics-2d-CE0Qvy3V.js} +136 -11
- package/dist/{physics-3d-DbYaEcZy.js → physics-3d-CpH-2gn5.js} +104 -23
- package/dist/{teardown-CMqFVxO9.js → picking-CQJ_PJKh.js} +103 -12
- package/dist/react.d.ts +2 -2
- package/dist/react.js +2 -2
- package/dist/{register-mmfugpaQ.js → register-6DYnKZcy.js} +546 -817
- package/dist/{register-DbVArsns.js → register-Bkk0wSDB.js} +332 -23
- package/dist/{replay-BEHLDcQV.js → replay-DjAkAzMq.js} +224 -14
- package/dist/{replay-BQfkX4x7.d.ts → replay-Dmw-PKQu.d.ts} +20 -3
- package/dist/{schema-B6ugCV1Q.d.ts → rng-Bb-IutXB.d.ts} +38 -21
- package/dist/{rng-DP-SR7eg.js → rng-CDOMybym.js} +22 -0
- package/dist/{loader-DZE7B07H.js → save-slots-BXVg148r.js} +4570 -2322
- package/dist/{split-screen-Cg76MCV5.d.ts → split-screen--k-XpBjr.d.ts} +36 -4
- package/dist/{split-screen-CauMwu6y.js → split-screen-PL78oVXP.js} +159 -26
- package/dist/{sprite-animation-CY-mrr1L.js → sprite-animation-CqR2o3SA.js} +39 -8
- package/dist/{src-CYEu-_S9.js → src-Cxfiv1Hg.js} +2 -17
- package/dist/test-iHYVUcDK.js +4036 -0
- package/dist/test.d.ts +531 -30
- package/dist/test.js +3 -3
- package/dist/touch-BnCyPA0G.js +519 -0
- package/dist/vite.d.ts +20 -37
- package/dist/vite.js +176 -6
- package/dist/{webgl-unavailable-Z5_g8x9H.js → webgl-unavailable-C8aDbGmR.js} +44 -0
- package/editor/assets/agent8-D0MS174y.js +1 -0
- package/editor/assets/{debug-CMULinBW.js → debug-BnXkKuYu.js} +2 -2
- package/editor/assets/index-CIu3uc3l.js +11046 -0
- package/editor/index.html +1 -1
- package/package.json +4 -14
- package/schemas/scene.schema.json +30 -3
- package/skills/incanto-3d-character.md +14 -1
- package/skills/incanto-3d-models.md +12 -0
- package/skills/incanto-assets.md +9 -1
- package/skills/incanto-audio.md +8 -2
- package/skills/incanto-behaviors-and-scripts.md +83 -6
- package/skills/incanto-building-2d-games.md +77 -8
- package/skills/incanto-building-3d-games.md +58 -4
- package/skills/incanto-editor.md +46 -7
- package/skills/incanto-environment.md +19 -1
- package/skills/incanto-game-feel.md +70 -0
- package/skills/incanto-gameplay-behaviors.md +109 -19
- package/skills/incanto-hud.md +128 -7
- package/skills/incanto-localization.md +13 -5
- package/skills/incanto-multiplayer.md +83 -3
- package/skills/incanto-node-reference.md +222 -58
- package/skills/incanto-performance.md +52 -0
- package/skills/incanto-physics-and-input.md +123 -24
- package/skills/incanto-playtesting.md +78 -2
- package/skills/incanto-save-slots.md +161 -6
- package/skills/incanto-scene-json-authoring.md +69 -12
- package/skills/incanto-verifying-your-game.md +196 -10
- package/skills/incanto-web-integration.md +28 -0
- package/skills/incanto-your-first-game.md +3 -1
- package/templates-app/beacon-isle-3d/generate-world.ts +77 -9
- package/templates-app/beacon-isle-3d/package.json +2 -2
- package/templates-app/beacon-isle-3d/src/behaviors.ts +22 -0
- package/templates-app/beacon-isle-3d/src/game.scene.json +103 -378
- package/templates-app/beacon-isle-3d/src/main.ts +11 -1
- package/templates-app/beacon-isle-3d/tsconfig.json +1 -1
- package/templates-app/beacon-isle-3d/verify.ts +3 -1
- package/templates-app/molehill-2d/.incanto/playtest/lost-seed1.json +4277 -0
- package/templates-app/molehill-2d/PROJECT/Context.md +58 -0
- package/templates-app/molehill-2d/PROJECT/Requirements.md +39 -0
- package/templates-app/molehill-2d/PROJECT/Status.md +27 -0
- package/templates-app/molehill-2d/PROJECT/Structure.md +48 -0
- package/templates-app/molehill-2d/docs/project-2d-rules.md +44 -0
- package/templates-app/molehill-2d/index.html +73 -0
- package/templates-app/molehill-2d/package.json +23 -0
- package/templates-app/molehill-2d/src/behaviors.ts +198 -0
- package/templates-app/molehill-2d/src/game.scene.json +1255 -0
- package/templates-app/molehill-2d/src/main.ts +41 -0
- package/templates-app/molehill-2d/tsconfig.json +13 -0
- package/templates-app/molehill-2d/verify.ts +247 -0
- package/templates-app/molehill-2d/vite.config.ts +12 -0
- package/templates-app/platformer-2d/package.json +2 -2
- package/templates-app/platformer-2d/src/game.scene.json +128 -600
- package/templates-app/platformer-2d/src/main.ts +11 -1
- package/templates-app/platformer-2d/tsconfig.json +1 -1
- package/templates-app/star-survivor/package.json +2 -2
- package/templates-app/star-survivor/src/game.scene.json +41 -195
- package/templates-app/star-survivor/src/main.ts +11 -1
- package/templates-app/star-survivor/tsconfig.json +1 -1
- package/templates-app/tps-3d/PROJECT/Context.md +1 -1
- package/templates-app/tps-3d/package.json +2 -2
- package/templates-app/tps-3d/src/behaviors.ts +19 -1
- package/templates-app/tps-3d/src/game.scene.json +78 -217
- package/templates-app/tps-3d/src/main.ts +13 -2
- package/templates-app/tps-3d/tsconfig.json +1 -1
- package/templates-app/village-quest-3d/.incanto/playtest/swapped-seed1.json +1735 -0
- package/templates-app/village-quest-3d/package.json +2 -2
- package/templates-app/village-quest-3d/src/behaviors.ts +21 -0
- package/templates-app/village-quest-3d/src/grove.scene.json +54 -221
- package/templates-app/village-quest-3d/src/main.ts +11 -1
- package/templates-app/village-quest-3d/src/village.scene.json +199 -838
- package/templates-app/village-quest-3d/tsconfig.json +1 -1
- package/templates-app/village-quest-3d/verify.ts +14 -1
- package/dist/duplicate-Dj4L-5AA.js +0 -22
- package/dist/json-CwwhxQgb.js +0 -36
- package/dist/registry-CF70EArN.js +0 -212
- package/dist/rolldown-runtime-D7D4PA-g.js +0 -13
- package/dist/test-D6ISmuFE.js +0 -2383
- package/dist/touch-DEAmqGdf.js +0 -225
- package/editor/assets/agent8-BDvaZMQJ.js +0 -1
- package/editor/assets/index-CZIRr5EL.js +0 -10958
package/dist/editor.js
CHANGED
|
@@ -5,33 +5,33 @@ import { registerGameplayBehaviors as A } from "incanto/gameplay";
|
|
|
5
5
|
import { registerNodesNet as ee } from "incanto/net";
|
|
6
6
|
import { GENERATORS as te, runGenerator as j } from "incanto/env";
|
|
7
7
|
//#region src/format-json.ts
|
|
8
|
-
var ne = 80,
|
|
9
|
-
function
|
|
10
|
-
return `${
|
|
8
|
+
var ne = 80, re = " ";
|
|
9
|
+
function M(e) {
|
|
10
|
+
return `${ie(e, 0)}\n`;
|
|
11
11
|
}
|
|
12
|
-
function
|
|
12
|
+
function ie(e, t) {
|
|
13
13
|
if (typeof e != "object" || !e) return JSON.stringify(e);
|
|
14
|
-
let n =
|
|
14
|
+
let n = N(e);
|
|
15
15
|
if (t * 2 + n.length <= ne) return n;
|
|
16
|
-
let r =
|
|
17
|
-
if (Array.isArray(e)) return e.length === 0 ? "[]" : `[\n${e.map((e) => r +
|
|
16
|
+
let r = re.repeat(t + 1), i = re.repeat(t);
|
|
17
|
+
if (Array.isArray(e)) return e.length === 0 ? "[]" : `[\n${e.map((e) => r + ie(e, t + 1)).join(",\n")}\n${i}]`;
|
|
18
18
|
let a = Object.entries(e);
|
|
19
|
-
return a.length === 0 ? "{}" : `{\n${a.map(([e, n]) => `${r}${JSON.stringify(e)}: ${
|
|
19
|
+
return a.length === 0 ? "{}" : `{\n${a.map(([e, n]) => `${r}${JSON.stringify(e)}: ${ie(n, t + 1)}`).join(",\n")}\n${i}}`;
|
|
20
20
|
}
|
|
21
|
-
function
|
|
21
|
+
function N(e) {
|
|
22
22
|
if (typeof e != "object" || !e) return JSON.stringify(e);
|
|
23
|
-
if (Array.isArray(e)) return e.length === 0 ? "[]" : `[${e.map(
|
|
23
|
+
if (Array.isArray(e)) return e.length === 0 ? "[]" : `[${e.map(N).join(", ")}]`;
|
|
24
24
|
let t = Object.entries(e);
|
|
25
|
-
return t.length === 0 ? "{}" : `{ ${t.map(([e, t]) => `${JSON.stringify(e)}: ${
|
|
25
|
+
return t.length === 0 ? "{}" : `{ ${t.map(([e, t]) => `${JSON.stringify(e)}: ${N(t)}`).join(", ")} }`;
|
|
26
26
|
}
|
|
27
27
|
//#endregion
|
|
28
28
|
//#region src/library-api.ts
|
|
29
|
-
var
|
|
29
|
+
var ae = class extends Error {
|
|
30
30
|
needsToken = !0;
|
|
31
31
|
constructor(e = "the asset library needs a Verse8 access token") {
|
|
32
32
|
super(e), this.name = "LibraryAuthError";
|
|
33
33
|
}
|
|
34
|
-
},
|
|
34
|
+
}, P = {
|
|
35
35
|
"": ["3d", "2d"],
|
|
36
36
|
"3d": [
|
|
37
37
|
"characters",
|
|
@@ -46,11 +46,11 @@ var ie = class extends Error {
|
|
|
46
46
|
"2d": ["sprite_characters", "projects"]
|
|
47
47
|
};
|
|
48
48
|
function oe(e) {
|
|
49
|
-
return
|
|
49
|
+
return P[e.join("/")] ?? [];
|
|
50
50
|
}
|
|
51
51
|
function se(e) {
|
|
52
52
|
if (e.length === 0) return [];
|
|
53
|
-
let t =
|
|
53
|
+
let t = P[e.slice(0, -1).join("/")];
|
|
54
54
|
return t ? t.filter((t) => !e.includes(t)) : [];
|
|
55
55
|
}
|
|
56
56
|
var ce = 12;
|
|
@@ -223,7 +223,7 @@ async function Ie(e) {
|
|
|
223
223
|
async function Le(e, t) {
|
|
224
224
|
await je(await fetch(Fe(t), {
|
|
225
225
|
method: "PUT",
|
|
226
|
-
body:
|
|
226
|
+
body: M(e)
|
|
227
227
|
}));
|
|
228
228
|
}
|
|
229
229
|
async function Re(e, t) {
|
|
@@ -234,7 +234,7 @@ async function Re(e, t) {
|
|
|
234
234
|
});
|
|
235
235
|
e.keyword?.trim() && n.set("keyword", e.keyword.trim());
|
|
236
236
|
let r = await fetch(`/api/library?${n}`, { headers: t ? { "x-incanto-v8-token": t } : {} });
|
|
237
|
-
if (r.status === 401) throw new
|
|
237
|
+
if (r.status === 401) throw new ae((await r.json().catch(() => ({}))).error);
|
|
238
238
|
return await (await je(r)).json();
|
|
239
239
|
}
|
|
240
240
|
var ze = {
|
|
@@ -1876,11 +1876,22 @@ var en = {
|
|
|
1876
1876
|
ko: "groups — 조회용 태그"
|
|
1877
1877
|
},
|
|
1878
1878
|
body: {
|
|
1879
|
-
en: "
|
|
1879
|
+
en: "A LIST of names. Game code finds nodes with tree-wide queries like getNodesInGroup(\"coins\"), and triggers can filter by group (e.g. only react to \"player\"). Type a name and press Enter. For key-values a node carries (what KIND of thing it is, what it is worth) use `tags`, below.",
|
|
1880
1880
|
ko: "자유 형식 태그입니다. 게임 코드가 getNodesInGroup(\"coins\")처럼 트리 전체에서 노드를 찾고, 트리거는 그룹으로 거릅니다(예: \"player\"에만 반응). 이름을 입력하고 Enter를 누르세요."
|
|
1881
1881
|
},
|
|
1882
1882
|
example: "triggerEnter → if (other.isInGroup(\"player\")) collect()"
|
|
1883
1883
|
},
|
|
1884
|
+
tags: {
|
|
1885
|
+
title: {
|
|
1886
|
+
en: "tags — free-form identity JSON",
|
|
1887
|
+
ko: "tags — 자유 형식 식별 JSON"
|
|
1888
|
+
},
|
|
1889
|
+
body: {
|
|
1890
|
+
en: "Not groups. `groups` is a LIST of names you query the tree by; `tags` is an OBJECT of key-values the node carries for your game logic — what kind of thing it is and what it is worth. Connections filter on them (`filter: {tag: {kind: \"ITEM\"}}`), and a behavior reads `node.tags`. Anything JSON: numbers, strings, nested objects. A rhythm chart lives here — one note node per beat, `{\"beat\": 4, \"lane\": 0}`.",
|
|
1891
|
+
ko: "groups와 다릅니다. `groups`는 트리를 조회하는 이름 목록이고, `tags`는 노드가 지니는 키-값 객체입니다 — 무엇이며 얼마나 값어치가 있는지. 연결이 이것으로 거르고(`filter: {tag: {kind: \"ITEM\"}}`), 비헤이비어는 `node.tags`로 읽습니다. JSON이면 무엇이든 됩니다 — 숫자, 문자열, 중첩 객체."
|
|
1892
|
+
},
|
|
1893
|
+
example: "{\"kind\": \"ITEM\", \"value\": 10}"
|
|
1894
|
+
},
|
|
1884
1895
|
script: {
|
|
1885
1896
|
title: {
|
|
1886
1897
|
en: "script — attach YOUR game logic",
|
|
@@ -2337,14 +2348,25 @@ function Pn(e, t) {
|
|
|
2337
2348
|
}
|
|
2338
2349
|
//#endregion
|
|
2339
2350
|
//#region src/tilemap-paint.ts
|
|
2340
|
-
function Fn(e, t, n, r) {
|
|
2351
|
+
function Fn(e, t, n, r, i = 1, a = 1) {
|
|
2341
2352
|
return {
|
|
2342
|
-
cx: Math.floor((n - e.x) / t),
|
|
2343
|
-
cy: Math.floor((r - e.y) / t)
|
|
2353
|
+
cx: Math.floor((n - e.x) / (t * (i || 1))),
|
|
2354
|
+
cy: Math.floor((r - e.y) / (t * (a || 1)))
|
|
2344
2355
|
};
|
|
2345
2356
|
}
|
|
2346
2357
|
function In(e, t, n, r) {
|
|
2347
2358
|
if (t < 0 || n < 0 || r.length !== 1) return null;
|
|
2359
|
+
if (e.some((e) => Array.isArray(e))) {
|
|
2360
|
+
let i = Number(r);
|
|
2361
|
+
if (!Number.isInteger(i) || i < 0) return null;
|
|
2362
|
+
let a = e.map((e) => Array.isArray(e) ? [...e] : [...e].map((e) => Number(e) || 0)), o = Math.max(t + 1, ...a.map((e) => e.length)), s = Math.max(n + 1, a.length), c = [];
|
|
2363
|
+
for (let e = 0; e < s; e++) {
|
|
2364
|
+
let r = a[e] ?? [];
|
|
2365
|
+
for (; r.length < o;) r.push(-1);
|
|
2366
|
+
e === n && (r[t] = i), c.push(r);
|
|
2367
|
+
}
|
|
2368
|
+
return c;
|
|
2369
|
+
}
|
|
2348
2370
|
let i = e.map((e) => typeof e == "string" ? e : e.map((e) => e >= 0 && e <= 9 ? String(e) : ".").join("")), a = Math.max(t + 1, ...i.map((e) => e.length)), o = Math.max(n + 1, i.length), s = [];
|
|
2349
2371
|
for (let e = 0; e < o; e++) {
|
|
2350
2372
|
let o = i[e] ?? "";
|
|
@@ -2384,7 +2406,7 @@ var Vn = [
|
|
|
2384
2406
|
"environment"
|
|
2385
2407
|
];
|
|
2386
2408
|
function Hn(e, t, n) {
|
|
2387
|
-
e.appendChild(
|
|
2409
|
+
e.appendChild(Or("scene")), e.appendChild(Nr("name", String(t.working.name ?? ""), (e) => {
|
|
2388
2410
|
t.mutate(() => {
|
|
2389
2411
|
t.working.name = e;
|
|
2390
2412
|
});
|
|
@@ -2398,13 +2420,13 @@ function Hn(e, t, n) {
|
|
|
2398
2420
|
t.mutate(() => {
|
|
2399
2421
|
t.working.dimension = r.value;
|
|
2400
2422
|
});
|
|
2401
|
-
}), e.appendChild(
|
|
2423
|
+
}), e.appendChild(V("dimension", r));
|
|
2402
2424
|
let i = document.createElement("input");
|
|
2403
2425
|
i.type = "checkbox", i.checked = t.working.fragment === !0, i.addEventListener("change", () => {
|
|
2404
2426
|
t.mutate(() => {
|
|
2405
2427
|
i.checked ? t.working.fragment = !0 : delete t.working.fragment;
|
|
2406
2428
|
});
|
|
2407
|
-
}), e.appendChild(
|
|
2429
|
+
}), e.appendChild(V("fragment", i)), e.appendChild(Or("physics", "physics"));
|
|
2408
2430
|
let a = (t.working.physics ?? {}).gravity ?? (t.working.dimension === "3d" ? [
|
|
2409
2431
|
0,
|
|
2410
2432
|
-9.81,
|
|
@@ -2414,7 +2436,7 @@ function Hn(e, t, n) {
|
|
|
2414
2436
|
-9.81,
|
|
2415
2437
|
0
|
|
2416
2438
|
] : [0, 980];
|
|
2417
|
-
e.appendChild(
|
|
2439
|
+
e.appendChild(Fr("gravity", a, (e) => {
|
|
2418
2440
|
t.mutate(() => {
|
|
2419
2441
|
if (JSON.stringify(e) === JSON.stringify(o)) {
|
|
2420
2442
|
let e = { ...t.working.physics };
|
|
@@ -2424,8 +2446,8 @@ function Hn(e, t, n) {
|
|
|
2424
2446
|
gravity: e
|
|
2425
2447
|
};
|
|
2426
2448
|
});
|
|
2427
|
-
})), e.appendChild(
|
|
2428
|
-
for (let n of Vn) e.appendChild(
|
|
2449
|
+
})), e.appendChild(Or("environment")), Un(e, t), e.appendChild(Or("constants")), yr(e, t, n), e.appendChild(Or("strings")), Sr(e, t, n), e.appendChild(Or("draw order bands")), vr(e, t), e.appendChild(Or("advanced"));
|
|
2450
|
+
for (let n of Vn) e.appendChild(Lr(n, t.working[n], (e) => {
|
|
2429
2451
|
t.mutate(() => {
|
|
2430
2452
|
e === void 0 ? delete t.working[n] : t.working[n] = e;
|
|
2431
2453
|
});
|
|
@@ -2450,7 +2472,7 @@ function Un(e, t) {
|
|
|
2450
2472
|
color: e === "" ? void 0 : e
|
|
2451
2473
|
};
|
|
2452
2474
|
t.color === void 0 && delete t.color, r({ ambient: Object.keys(t).length ? t : void 0 });
|
|
2453
|
-
})), e.appendChild(
|
|
2475
|
+
})), e.appendChild(Pr("ambient power", n.ambient?.intensity ?? 0, (e) => {
|
|
2454
2476
|
r({ ambient: {
|
|
2455
2477
|
...n.ambient,
|
|
2456
2478
|
intensity: e
|
|
@@ -2466,7 +2488,7 @@ function Un(e, t) {
|
|
|
2466
2488
|
}, o = document.createElement("input");
|
|
2467
2489
|
o.type = "checkbox", o.checked = i.antialias !== !1, o.addEventListener("change", () => {
|
|
2468
2490
|
a({ antialias: o.checked ? void 0 : !1 });
|
|
2469
|
-
}), e.appendChild(
|
|
2491
|
+
}), e.appendChild(V("antialias", o));
|
|
2470
2492
|
let s = document.createElement("select");
|
|
2471
2493
|
for (let [e, t] of [
|
|
2472
2494
|
["", "1 — soft hiDPI upscale (default)"],
|
|
@@ -2478,7 +2500,7 @@ function Un(e, t) {
|
|
|
2478
2500
|
}
|
|
2479
2501
|
s.addEventListener("change", () => {
|
|
2480
2502
|
a({ pixelRatio: s.value === "" ? void 0 : s.value === "device" ? "device" : Number(s.value) });
|
|
2481
|
-
}), e.appendChild(
|
|
2503
|
+
}), e.appendChild(V("pixel ratio", s));
|
|
2482
2504
|
}
|
|
2483
2505
|
function Wn(e, t, n) {
|
|
2484
2506
|
let r = document.createElement("div");
|
|
@@ -2488,7 +2510,7 @@ function Wn(e, t, n) {
|
|
|
2488
2510
|
let a = document.createElement("input");
|
|
2489
2511
|
return a.type = "text", a.className = "mono", a.placeholder = "unset", a.value = t, i.addEventListener("input", () => {
|
|
2490
2512
|
a.value = i.value;
|
|
2491
|
-
}), i.addEventListener("change", () => n(i.value)), a.addEventListener("change", () => n(a.value.trim())), r.append(i, a),
|
|
2513
|
+
}), i.addEventListener("change", () => n(i.value)), a.addEventListener("change", () => n(a.value.trim())), r.append(i, a), V(e, r);
|
|
2492
2514
|
}
|
|
2493
2515
|
function Gn(e, t) {
|
|
2494
2516
|
let n = document.createElement("div");
|
|
@@ -2503,10 +2525,10 @@ function Gn(e, t) {
|
|
|
2503
2525
|
let n = { ...o };
|
|
2504
2526
|
t === void 0 || t === "" ? delete n[e] : n[e] = t, s(Object.keys(n).length === 0 ? !0 : n);
|
|
2505
2527
|
}, l = document.createElement("input");
|
|
2506
|
-
if (l.type = "checkbox", l.checked = a, l.addEventListener("change", () => s(l.checked)), n.appendChild(
|
|
2507
|
-
n.appendChild(Wn("murk color", String(o.color ?? ""), (e) => c("color", e))), n.appendChild(
|
|
2528
|
+
if (l.type = "checkbox", l.checked = a, l.addEventListener("change", () => s(l.checked)), n.appendChild(V("enabled", l)), a) {
|
|
2529
|
+
n.appendChild(Wn("murk color", String(o.color ?? ""), (e) => c("color", e))), n.appendChild(Pr("visibility (m)", Number(o.visibility ?? 22), (e) => c("visibility", e === 22 ? void 0 : e), () => c("visibility", void 0)));
|
|
2508
2530
|
let e = document.createElement("input");
|
|
2509
|
-
e.type = "checkbox", e.checked = (o.caustics ?? !0) !== !1, e.addEventListener("change", () => c("caustics", e.checked ? void 0 : !1)), n.appendChild(
|
|
2531
|
+
e.type = "checkbox", e.checked = (o.caustics ?? !0) !== !1, e.addEventListener("change", () => c("caustics", e.checked ? void 0 : !1)), n.appendChild(V("caustics", e));
|
|
2510
2532
|
}
|
|
2511
2533
|
return n;
|
|
2512
2534
|
}
|
|
@@ -2529,13 +2551,13 @@ function Kn(e, t, n) {
|
|
|
2529
2551
|
};
|
|
2530
2552
|
r.appendChild(Wn("color", String(a.color ?? ""), (e) => o("color", e))), r.appendChild(Xn("roughness", Number(a.roughness ?? 1), (e) => o("roughness", e))), r.appendChild(Xn("metalness", Number(a.metalness ?? 0), (e) => o("metalness", e))), r.appendChild(Wn("emissive", String(a.emissive ?? ""), (e) => o("emissive", e))), r.appendChild(Xn("emissive power", Number(a.emissiveIntensity ?? 1), (e) => o("emissiveIntensity", e === 1 ? void 0 : e), 2)), r.appendChild(Xn("opacity", Number(a.opacity ?? 1), (e) => o("opacity", e === 1 ? void 0 : e))), r.appendChild(Xn("clearcoat", Number(a.clearcoat ?? 0), (e) => o("clearcoat", e === 0 ? void 0 : e))), r.appendChild(Xn("clearcoat rough", Number(a.clearcoatRoughness ?? 0), (e) => o("clearcoatRoughness", e === 0 ? void 0 : e))), r.appendChild(Xn("reflection", Number(a.envMapIntensity ?? 1), (e) => o("envMapIntensity", e === 1 ? void 0 : e), 3));
|
|
2531
2553
|
let s = document.createElement("input");
|
|
2532
|
-
s.type = "checkbox", s.checked = a.wireframe === !0, s.addEventListener("change", () => o("wireframe", s.checked || void 0)), r.appendChild(
|
|
2554
|
+
s.type = "checkbox", s.checked = a.wireframe === !0, s.addEventListener("change", () => o("wireframe", s.checked || void 0)), r.appendChild(V("wireframe", s));
|
|
2533
2555
|
let c = document.createElement("input");
|
|
2534
|
-
c.type = "checkbox", c.checked = a.flatShading === !0, c.addEventListener("change", () => o("flatShading", c.checked || void 0)), r.appendChild(
|
|
2556
|
+
c.type = "checkbox", c.checked = a.flatShading === !0, c.addEventListener("change", () => o("flatShading", c.checked || void 0)), r.appendChild(V("flatShading", c));
|
|
2535
2557
|
let l = document.createElement("input");
|
|
2536
2558
|
l.type = "checkbox", l.checked = a.depthTest === !1, l.addEventListener("change", () => {
|
|
2537
2559
|
o("depthTest", l.checked ? !1 : void 0), o("depthWrite", l.checked ? !1 : void 0);
|
|
2538
|
-
}), r.appendChild(
|
|
2560
|
+
}), r.appendChild(V("draw on top (decal)", l)), r.appendChild(B("map (texture)", String(a.map ?? ""), ur((e) => zn(e) && !e.name.includes("normal") && !e.name.includes("roughness")), (e) => o("map", e.trim()), {
|
|
2539
2561
|
placeholder: "built-in or custom URL",
|
|
2540
2562
|
library: {
|
|
2541
2563
|
kind: "image",
|
|
@@ -2543,7 +2565,7 @@ function Kn(e, t, n) {
|
|
|
2543
2565
|
shelf: ["3d", "textures"]
|
|
2544
2566
|
},
|
|
2545
2567
|
ctx: n
|
|
2546
|
-
})), r.appendChild(
|
|
2568
|
+
})), r.appendChild(B("normal map", String(a.normalMap ?? ""), ur((e) => zn(e) && e.name.includes("normal")), (e) => o("normalMap", e.trim()), {
|
|
2547
2569
|
placeholder: "built-in or custom URL",
|
|
2548
2570
|
library: {
|
|
2549
2571
|
kind: "image",
|
|
@@ -2552,7 +2574,7 @@ function Kn(e, t, n) {
|
|
|
2552
2574
|
},
|
|
2553
2575
|
ctx: n
|
|
2554
2576
|
}));
|
|
2555
|
-
let u = !!(a.map || a.normalMap), d = Array.isArray(a.repeat) ? a.repeat : [1, 1], f =
|
|
2577
|
+
let u = !!(a.map || a.normalMap), d = Array.isArray(a.repeat) ? a.repeat : [1, 1], f = Fr("repeat [u,v]", [d[0] ?? 1, d[1] ?? 1], (e) => {
|
|
2556
2578
|
let [t, n] = e;
|
|
2557
2579
|
!Number.isFinite(t) || !Number.isFinite(n) || t === 1 && n === 1 || !t && !n ? o("repeat", void 0) : o("repeat", [t, n]);
|
|
2558
2580
|
});
|
|
@@ -2574,7 +2596,7 @@ function Jn(e, t, n, r) {
|
|
|
2574
2596
|
let o = document.createElement("strong");
|
|
2575
2597
|
o.textContent = "animation", a.appendChild(o), i.appendChild(a);
|
|
2576
2598
|
let s = String(t.props?.animation ?? "");
|
|
2577
|
-
if (i.appendChild(
|
|
2599
|
+
if (i.appendChild(B("clip", s, n.animationsForSelection().map((e) => ({
|
|
2578
2600
|
label: e,
|
|
2579
2601
|
value: e,
|
|
2580
2602
|
hint: e.startsWith("$") ? "scene asset" : "clip in this model"
|
|
@@ -2592,23 +2614,30 @@ function Jn(e, t, n, r) {
|
|
|
2592
2614
|
let a = document.createElement("div");
|
|
2593
2615
|
return a.className = "muted-note", a.textContent = "Pick a clip and it plays as soon as the scene loads — no script needed.", i.appendChild(a), i.appendChild(Yn(e, t, n, r)), i;
|
|
2594
2616
|
}
|
|
2595
|
-
i.appendChild(
|
|
2617
|
+
i.appendChild(wr(e, t, "animationLoop", r.animationLoop?.default ?? !0, void 0, "loop"));
|
|
2596
2618
|
let c = Xn("speed", Number(t.props?.animationSpeed ?? 1), (n) => z(e, t, "animationSpeed", n, 1), 3, -3);
|
|
2597
2619
|
c.title = "1 = as authored · 0 freezes the pose · negative plays backwards (a closing door is an opening one reversed).", i.appendChild(c);
|
|
2598
|
-
let l =
|
|
2620
|
+
let l = wr(e, t, "animationOffset", r.animationOffset?.default ?? 0, void 0, "offset (s)");
|
|
2599
2621
|
return l.title = "Seconds into the clip to start at. Give copies different offsets so a row of torches stops flickering in lockstep.", i.appendChild(l), i.appendChild(Yn(e, t, n, r)), i;
|
|
2600
2622
|
}
|
|
2601
2623
|
function Yn(e, t, n, r) {
|
|
2602
2624
|
let i = document.createElement("details");
|
|
2603
2625
|
i.className = "anim-upper", t.props?.animationUpper && (i.open = !0);
|
|
2604
2626
|
let a = document.createElement("summary");
|
|
2605
|
-
return a.textContent = "upper-body layer", a.title = "Play a second clip on the upper body only — attack while running, wave while walking.", i.appendChild(a), i.appendChild(
|
|
2627
|
+
return a.textContent = "upper-body layer", a.title = "Play a second clip on the upper body only — attack while running, wave while walking.", i.appendChild(a), i.appendChild(B("clip", String(t.props?.animationUpper ?? ""), n.animationsForSelection().map((e) => ({
|
|
2606
2628
|
label: e,
|
|
2607
2629
|
value: e
|
|
2608
2630
|
})), (n) => z(e, t, "animationUpper", n.trim(), ""), {
|
|
2609
2631
|
placeholder: "empty = off",
|
|
2632
|
+
library: {
|
|
2633
|
+
kind: "model",
|
|
2634
|
+
target: "animationUpper",
|
|
2635
|
+
shelf: ["3d", "animations"],
|
|
2636
|
+
asAsset: !0,
|
|
2637
|
+
assetType: "animation"
|
|
2638
|
+
},
|
|
2610
2639
|
ctx: n
|
|
2611
|
-
})), i.appendChild(
|
|
2640
|
+
})), i.appendChild(wr(e, t, "animationUpperLoop", r.animationUpperLoop?.default ?? !1, void 0, "loop")), i.appendChild(wr(e, t, "upperBodyRoot", r.upperBodyRoot?.default ?? "Spine", void 0, "root bone")), i;
|
|
2612
2641
|
}
|
|
2613
2642
|
function Xn(e, t, n, r = 1, i = 0) {
|
|
2614
2643
|
let a = document.createElement("div");
|
|
@@ -2620,21 +2649,21 @@ function Xn(e, t, n, r = 1, i = 0) {
|
|
|
2620
2649
|
s.value = o.value;
|
|
2621
2650
|
}), o.addEventListener("change", () => n(Number(o.value))), s.addEventListener("change", () => {
|
|
2622
2651
|
o.value = s.value, n(Number(s.value));
|
|
2623
|
-
}), a.append(o, s),
|
|
2652
|
+
}), a.append(o, s), V(e, a);
|
|
2624
2653
|
}
|
|
2625
2654
|
function Zn(e, t, n, r) {
|
|
2626
|
-
if (e.appendChild(
|
|
2655
|
+
if (e.appendChild(Or(n.type ?? "instance")), e.appendChild(Qn(n)), e.appendChild(Nr("name", n.name ?? "", (e) => {
|
|
2627
2656
|
e.trim() === "" || t.selection === null || t.renameNode(t.selection, e.trim());
|
|
2628
|
-
})), n.type === "TileMap2D" && r?.paint && e.appendChild(
|
|
2657
|
+
})), n.type === "TileMap2D" && r?.paint && e.appendChild(Ir(n, r.paint)), n.type) {
|
|
2629
2658
|
let i;
|
|
2630
2659
|
try {
|
|
2631
2660
|
i = s(n.type);
|
|
2632
2661
|
} catch {
|
|
2633
2662
|
i = {};
|
|
2634
2663
|
}
|
|
2635
|
-
for (let [a, o] of Object.entries(i)) if (a === "collider") e.appendChild(
|
|
2664
|
+
for (let [a, o] of Object.entries(i)) if (a === "collider") e.appendChild(or(t, n, o.default));
|
|
2636
2665
|
else if (a === "material") e.appendChild(Kn(t, n, r));
|
|
2637
|
-
else if (n.type === "ModelInstance3D" && a === "model" && r) e.appendChild(
|
|
2666
|
+
else if (n.type === "ModelInstance3D" && a === "model" && r) e.appendChild(B("model", String(n.props?.model ?? ""), r.modelRefs().map((e) => ({
|
|
2638
2667
|
label: e,
|
|
2639
2668
|
value: e,
|
|
2640
2669
|
hint: "scene asset"
|
|
@@ -2648,9 +2677,9 @@ function Zn(e, t, n, r) {
|
|
|
2648
2677
|
},
|
|
2649
2678
|
ctx: r
|
|
2650
2679
|
}));
|
|
2651
|
-
else if (n.type === "BoneAttachment3D" && a === "bone" && r?.bonesForSelection) e.appendChild(
|
|
2680
|
+
else if (n.type === "BoneAttachment3D" && a === "bone" && r?.bonesForSelection) e.appendChild(cr("bone", String(n.props?.bone ?? ""), r.bonesForSelection(String(n.props?.target ?? "")), (e) => z(t, n, "bone", e, "")));
|
|
2652
2681
|
else if (n.type === "ModelInstance3D" && a === "animation" && r) e.appendChild(Jn(t, n, r, i));
|
|
2653
|
-
else if (!(n.type === "ModelInstance3D" && qn.has(a))) if ((n.type === "Sprite3D" || n.type === "AnimatedSprite3D") && (a === "texture" || a === "sheet")) e.appendChild(
|
|
2682
|
+
else if (!(n.type === "ModelInstance3D" && qn.has(a))) if ((n.type === "Sprite3D" || n.type === "AnimatedSprite3D") && (a === "texture" || a === "sheet")) e.appendChild(B(a === "sheet" ? "sheet (image URL)" : "texture (image URL)", String(n.props?.[a] ?? ""), ur((e) => e.kind === "character" || e.kind === "item"), (e) => z(t, n, a, e.trim(), ""), {
|
|
2654
2683
|
placeholder: "image URL — empty hides the sprite",
|
|
2655
2684
|
library: {
|
|
2656
2685
|
kind: "image",
|
|
@@ -2659,7 +2688,7 @@ function Zn(e, t, n, r) {
|
|
|
2659
2688
|
},
|
|
2660
2689
|
ctx: r
|
|
2661
2690
|
}));
|
|
2662
|
-
else if (n.type === "TileMap2D" && a === "texture") e.appendChild(
|
|
2691
|
+
else if (n.type === "TileMap2D" && a === "texture") e.appendChild(B("texture (atlas $ref)", String(n.props?.texture ?? ""), (r?.assetRefs?.(["texture", "spritesheet"]) ?? []).map((e) => ({
|
|
2663
2692
|
label: e,
|
|
2664
2693
|
value: e,
|
|
2665
2694
|
hint: "scene asset"
|
|
@@ -2674,7 +2703,7 @@ function Zn(e, t, n, r) {
|
|
|
2674
2703
|
},
|
|
2675
2704
|
ctx: r
|
|
2676
2705
|
}));
|
|
2677
|
-
else if (n.type === "Tree3D" && a === "leafTexture") e.appendChild(
|
|
2706
|
+
else if (n.type === "Tree3D" && a === "leafTexture") e.appendChild(B("leaf texture", String(n.props?.leafTexture ?? ""), ur((e) => e.name.startsWith("leaves_")), (e) => z(t, n, "leafTexture", e.trim(), ""), {
|
|
2678
2707
|
placeholder: "default (per-type) or URL",
|
|
2679
2708
|
library: {
|
|
2680
2709
|
kind: "image",
|
|
@@ -2683,11 +2712,11 @@ function Zn(e, t, n, r) {
|
|
|
2683
2712
|
},
|
|
2684
2713
|
ctx: r
|
|
2685
2714
|
}));
|
|
2686
|
-
else if (n.type === "Terrain3D" && a === "textureBase") e.appendChild(
|
|
2715
|
+
else if (n.type === "Terrain3D" && a === "textureBase") e.appendChild(B("texture base", String(n.props?.textureBase ?? o.default ?? ""), fr, (e) => z(t, n, "textureBase", e.trim(), o.default), { placeholder: "splat texture base URL" }));
|
|
2687
2716
|
else if (n.type === "AnimatedSprite2D" && a === "sheet" || n.type === "Sprite2D" && a === "texture") {
|
|
2688
2717
|
let i = a === "sheet";
|
|
2689
2718
|
e.appendChild(pr(t, n, a, r, i));
|
|
2690
|
-
} else n.type === "AudioPlayer" && a === "src" ? e.appendChild(
|
|
2719
|
+
} else n.type === "AudioPlayer" && a === "src" ? e.appendChild(B("src (audio file)", String(n.props?.src ?? ""), dr(), (e) => z(t, n, "src", e.trim(), ""), {
|
|
2691
2720
|
placeholder: "built-in or custom URL — or use preset",
|
|
2692
2721
|
note: "For zero-asset SFX, set the `preset` prop instead of src.",
|
|
2693
2722
|
library: {
|
|
@@ -2695,11 +2724,11 @@ function Zn(e, t, n, r) {
|
|
|
2695
2724
|
target: "audio src"
|
|
2696
2725
|
},
|
|
2697
2726
|
ctx: r
|
|
2698
|
-
})) : n.type === "Flowers3D" && a === "varieties" ? e.appendChild(mr(t, n)) : n.type === "Water3D" && a === "underwater" ? e.appendChild(Gn(t, n)) : e.appendChild(
|
|
2727
|
+
})) : n.type === "Flowers3D" && a === "varieties" ? e.appendChild(mr(t, n)) : n.type === "Water3D" && a === "underwater" ? e.appendChild(Gn(t, n)) : e.appendChild(wr(t, n, a, o.default, o.options, void 0, o.nodePath === !0, o.kinds));
|
|
2699
2728
|
}
|
|
2700
|
-
if (e.appendChild(
|
|
2729
|
+
if (e.appendChild(Or("structure")), e.appendChild($n(t, n)), e.appendChild(er(t, n)), e.appendChild(tr(t, n)), e.appendChild(ar(t, n)), t.selection) {
|
|
2701
2730
|
let n = Sn(t, t.selection);
|
|
2702
|
-
n && (e.appendChild(
|
|
2731
|
+
n && (e.appendChild(Or("connections", "connections")), e.appendChild(n));
|
|
2703
2732
|
}
|
|
2704
2733
|
}
|
|
2705
2734
|
function Qn(e) {
|
|
@@ -2725,7 +2754,7 @@ function $n(e, t) {
|
|
|
2725
2754
|
r.append("groups ", an("groups"));
|
|
2726
2755
|
let i = document.createElement("div");
|
|
2727
2756
|
i.className = "chips";
|
|
2728
|
-
for (let n of t.groups ?? []) i.appendChild(
|
|
2757
|
+
for (let n of t.groups ?? []) i.appendChild(kr(n, () => {
|
|
2729
2758
|
e.mutate(() => {
|
|
2730
2759
|
t.groups = (t.groups ?? []).filter((e) => e !== n), t.groups.length === 0 && delete t.groups;
|
|
2731
2760
|
});
|
|
@@ -2740,6 +2769,14 @@ function $n(e, t) {
|
|
|
2740
2769
|
}), i.appendChild(a), i.addEventListener("click", () => a.focus()), n.append(r, i), n;
|
|
2741
2770
|
}
|
|
2742
2771
|
function er(e, t) {
|
|
2772
|
+
let n = Lr("tags", t.tags, (n) => {
|
|
2773
|
+
e.mutate(() => {
|
|
2774
|
+
n === void 0 ? delete t.tags : t.tags = n;
|
|
2775
|
+
});
|
|
2776
|
+
}, "{\"kind\": \"ITEM\", \"value\": 10}", (e) => typeof e == "object" && !!e && !Array.isArray(e)), r = n.querySelector("span");
|
|
2777
|
+
return r && r.append(" ", an("tags")), n;
|
|
2778
|
+
}
|
|
2779
|
+
function tr(e, t) {
|
|
2743
2780
|
let n = document.createElement("div");
|
|
2744
2781
|
n.className = "subcard";
|
|
2745
2782
|
let i = document.createElement("div");
|
|
@@ -2761,19 +2798,19 @@ function er(e, t) {
|
|
|
2761
2798
|
let i = document.createElement("button");
|
|
2762
2799
|
return i.type = "button", i.className = "ghost", i.textContent = "+ attach behavior", i.addEventListener("click", () => {
|
|
2763
2800
|
e.mutate(() => {
|
|
2764
|
-
t.script = { name:
|
|
2801
|
+
t.script = { name: nr()[0] ?? "MyBehavior" };
|
|
2765
2802
|
});
|
|
2766
2803
|
}), n.append(r, i), n;
|
|
2767
2804
|
}
|
|
2768
|
-
let s = o.name ?? "", c =
|
|
2769
|
-
n.appendChild(
|
|
2805
|
+
let s = o.name ?? "", c = nr();
|
|
2806
|
+
n.appendChild(Ar("name", s, c, (n) => {
|
|
2770
2807
|
e.mutate(() => {
|
|
2771
2808
|
t.script.name = n, delete t.script.props;
|
|
2772
2809
|
});
|
|
2773
2810
|
}));
|
|
2774
2811
|
let l = c.includes(s) ? r(s) : null;
|
|
2775
|
-
if (l && Object.keys(l).length > 0) for (let [r, i] of Object.entries(l)) n.appendChild(
|
|
2776
|
-
else n.appendChild(
|
|
2812
|
+
if (l && Object.keys(l).length > 0) for (let [r, i] of Object.entries(l)) n.appendChild(rr(e, t, r, i.default, i.options, i.nodePath === !0));
|
|
2813
|
+
else n.appendChild(Lr("props", o.props, (n) => {
|
|
2777
2814
|
e.mutate(() => {
|
|
2778
2815
|
n === void 0 ? delete t.script.props : t.script.props = n;
|
|
2779
2816
|
});
|
|
@@ -2781,10 +2818,10 @@ function er(e, t) {
|
|
|
2781
2818
|
let u = document.createElement("div");
|
|
2782
2819
|
return u.className = "muted-note", u.textContent = l ? "Shipped with the engine — these props are its own." : "Not a built-in: this is a TypeScript class in your game. ? has the boilerplate.", n.appendChild(u), n;
|
|
2783
2820
|
}
|
|
2784
|
-
function
|
|
2821
|
+
function nr() {
|
|
2785
2822
|
return [...h()].sort();
|
|
2786
2823
|
}
|
|
2787
|
-
function
|
|
2824
|
+
function rr(e, t, n, r, i, a = !1) {
|
|
2788
2825
|
let o = (t.script?.props ?? {})[n] ?? r, s = (i) => {
|
|
2789
2826
|
e.mutate(() => {
|
|
2790
2827
|
let e = t.script;
|
|
@@ -2793,17 +2830,17 @@ function nr(e, t, n, r, i, a = !1) {
|
|
|
2793
2830
|
JSON.stringify(i) === JSON.stringify(r) ? delete a[n] : a[n] = i, Object.keys(a).length === 0 && delete e.props;
|
|
2794
2831
|
});
|
|
2795
2832
|
};
|
|
2796
|
-
if (i && i.length > 0) return
|
|
2833
|
+
if (i && i.length > 0) return Ar(n, String(o), [...i], (e) => s(e));
|
|
2797
2834
|
if (typeof r == "boolean") {
|
|
2798
2835
|
let e = document.createElement("input");
|
|
2799
|
-
return e.type = "checkbox", e.checked = !!o, e.addEventListener("change", () => s(e.checked)),
|
|
2836
|
+
return e.type = "checkbox", e.checked = !!o, e.addEventListener("change", () => s(e.checked)), V(n, e);
|
|
2800
2837
|
}
|
|
2801
|
-
return typeof r == "number" ?
|
|
2838
|
+
return typeof r == "number" ? Pr(n, Number(o), (e) => s(e)) : typeof r == "string" ? a ? ir(e, n, String(o), (e) => s(e)) : Nr(n, String(o), (e) => s(e)) : Lr(n, o, (e) => s(e === void 0 ? r : e));
|
|
2802
2839
|
}
|
|
2803
|
-
function
|
|
2840
|
+
function ir(e, t, n, r) {
|
|
2804
2841
|
let i = e.working.root, a = e.selection ?? [], o = document.createElement("input");
|
|
2805
2842
|
o.type = "text", o.value = n, o.placeholder = "%Player, ../Skin, /root/Level/Goal";
|
|
2806
|
-
let s = `nodepath-${
|
|
2843
|
+
let s = `nodepath-${sr++}`;
|
|
2807
2844
|
o.setAttribute("list", s);
|
|
2808
2845
|
let c = document.createElement("datalist");
|
|
2809
2846
|
c.id = s;
|
|
@@ -2812,7 +2849,7 @@ function rr(e, t, n, r) {
|
|
|
2812
2849
|
t.value = e, c.appendChild(t);
|
|
2813
2850
|
}
|
|
2814
2851
|
o.addEventListener("change", () => r(o.value.trim()));
|
|
2815
|
-
let l =
|
|
2852
|
+
let l = V(t, o);
|
|
2816
2853
|
l.appendChild(c);
|
|
2817
2854
|
let u = n === "" ? null : Dn(i, a, n);
|
|
2818
2855
|
if (!u || u.ok) return l;
|
|
@@ -2825,7 +2862,7 @@ function rr(e, t, n, r) {
|
|
|
2825
2862
|
let f = document.createElement("div");
|
|
2826
2863
|
return f.append(l, d), f;
|
|
2827
2864
|
}
|
|
2828
|
-
function
|
|
2865
|
+
function ar(e, t) {
|
|
2829
2866
|
let n = document.createElement("div");
|
|
2830
2867
|
n.className = "subcard";
|
|
2831
2868
|
let r = document.createElement("div");
|
|
@@ -2842,10 +2879,10 @@ function ir(e, t) {
|
|
|
2842
2879
|
sync: i?.sync ?? ["position"]
|
|
2843
2880
|
};
|
|
2844
2881
|
});
|
|
2845
|
-
}), n.appendChild(
|
|
2882
|
+
}), n.appendChild(V("mode", a)), i?.mode === "owner") {
|
|
2846
2883
|
let r = document.createElement("div");
|
|
2847
2884
|
r.className = "chips";
|
|
2848
|
-
for (let n of i.sync ?? []) r.appendChild(
|
|
2885
|
+
for (let n of i.sync ?? []) r.appendChild(kr(n, () => {
|
|
2849
2886
|
e.mutate(() => {
|
|
2850
2887
|
t.network.sync = (i.sync ?? []).filter((e) => e !== n);
|
|
2851
2888
|
});
|
|
@@ -2861,7 +2898,7 @@ function ir(e, t) {
|
|
|
2861
2898
|
let o = document.createElement("label");
|
|
2862
2899
|
o.className = "field wide";
|
|
2863
2900
|
let s = document.createElement("span");
|
|
2864
|
-
s.textContent = "sync keys", o.append(s, r), n.appendChild(o), n.appendChild(
|
|
2901
|
+
s.textContent = "sync keys", o.append(s, r), n.appendChild(o), n.appendChild(Pr("throttle ms", i.throttleMs ?? 50, (n) => {
|
|
2865
2902
|
e.mutate(() => {
|
|
2866
2903
|
t.network.throttleMs = n;
|
|
2867
2904
|
});
|
|
@@ -2869,7 +2906,7 @@ function ir(e, t) {
|
|
|
2869
2906
|
}
|
|
2870
2907
|
return n;
|
|
2871
2908
|
}
|
|
2872
|
-
function
|
|
2909
|
+
function or(e, t, n) {
|
|
2873
2910
|
let r = document.createElement("div");
|
|
2874
2911
|
r.className = "subcard";
|
|
2875
2912
|
let i = document.createElement("div");
|
|
@@ -2921,23 +2958,23 @@ function ar(e, t, n) {
|
|
|
2921
2958
|
radius: a.radius ?? 12,
|
|
2922
2959
|
height: a.height ?? 16
|
|
2923
2960
|
});
|
|
2924
|
-
}), r.appendChild(
|
|
2961
|
+
}), r.appendChild(V("shape", l)), a.shape === "rect" || a.shape === "box" ? r.appendChild(Fr("size", a.size ?? (s ? [
|
|
2925
2962
|
1,
|
|
2926
2963
|
1,
|
|
2927
2964
|
1
|
|
2928
2965
|
] : [32, 32]), (e) => o({
|
|
2929
2966
|
...a,
|
|
2930
2967
|
size: e
|
|
2931
|
-
}))) : a.shape === "circle" || a.shape === "sphere" ? r.appendChild(
|
|
2968
|
+
}))) : a.shape === "circle" || a.shape === "sphere" ? r.appendChild(Pr("radius", a.radius ?? (s ? .5 : 16), (e) => o({
|
|
2932
2969
|
...a,
|
|
2933
2970
|
radius: e
|
|
2934
|
-
}))) : a.shape === "capsule" && (r.appendChild(
|
|
2971
|
+
}))) : a.shape === "capsule" && (r.appendChild(Pr("radius", a.radius ?? 12, (e) => o({
|
|
2935
2972
|
...a,
|
|
2936
2973
|
radius: e
|
|
2937
|
-
}))), r.appendChild(
|
|
2974
|
+
}))), r.appendChild(Pr("height", a.height ?? 16, (e) => o({
|
|
2938
2975
|
...a,
|
|
2939
2976
|
height: e
|
|
2940
|
-
})))), a.shape && r.appendChild(
|
|
2977
|
+
})))), a.shape && r.appendChild(Fr("offset", a.offset ?? (s ? [
|
|
2941
2978
|
0,
|
|
2942
2979
|
0,
|
|
2943
2980
|
0
|
|
@@ -2951,11 +2988,11 @@ function z(e, t, n, r, i) {
|
|
|
2951
2988
|
t.props ||= {}, JSON.stringify(r) === JSON.stringify(i) ? (delete t.props[n], Object.keys(t.props).length === 0 && delete t.props) : t.props[n] = r;
|
|
2952
2989
|
});
|
|
2953
2990
|
}
|
|
2954
|
-
var
|
|
2955
|
-
function
|
|
2991
|
+
var sr = 0;
|
|
2992
|
+
function cr(e, t, n, r) {
|
|
2956
2993
|
let i = document.createElement("input");
|
|
2957
2994
|
i.type = "text", i.value = t;
|
|
2958
|
-
let a = `suggest-${
|
|
2995
|
+
let a = `suggest-${sr++}`;
|
|
2959
2996
|
i.setAttribute("list", a);
|
|
2960
2997
|
let o = document.createElement("datalist");
|
|
2961
2998
|
o.id = a;
|
|
@@ -2964,11 +3001,11 @@ function sr(e, t, n, r) {
|
|
|
2964
3001
|
t.value = e, o.appendChild(t);
|
|
2965
3002
|
}
|
|
2966
3003
|
i.addEventListener("change", () => r(i.value.trim()));
|
|
2967
|
-
let s =
|
|
3004
|
+
let s = V(e, i);
|
|
2968
3005
|
return s.appendChild(o), s;
|
|
2969
3006
|
}
|
|
2970
|
-
var
|
|
2971
|
-
function
|
|
3007
|
+
var lr = 0;
|
|
3008
|
+
function B(e, t, n, r, i = {}) {
|
|
2972
3009
|
let a = document.createElement("label");
|
|
2973
3010
|
a.className = "field wide asset-field";
|
|
2974
3011
|
let o = document.createElement("span");
|
|
@@ -3035,7 +3072,7 @@ function lr(e, t, n, r, i = {}) {
|
|
|
3035
3072
|
let e = document.createElement("div");
|
|
3036
3073
|
e.className = "muted-note asset-note", e.textContent = i.note, a.appendChild(e);
|
|
3037
3074
|
}
|
|
3038
|
-
return s.id = `asset-input-${
|
|
3075
|
+
return s.id = `asset-input-${lr++}`, a.htmlFor = s.id, a;
|
|
3039
3076
|
}
|
|
3040
3077
|
function ur(e) {
|
|
3041
3078
|
return Rn.filter(e).map((e) => ({
|
|
@@ -3069,7 +3106,7 @@ function pr(e, t, n, r, i) {
|
|
|
3069
3106
|
value: `$${e.name}`,
|
|
3070
3107
|
hint: `${e.kind} · creates a scene asset (${e.animation ? "spritesheet" : "texture"})`
|
|
3071
3108
|
});
|
|
3072
|
-
return
|
|
3109
|
+
return B(i ? "sheet" : "texture", a, s, (i) => {
|
|
3073
3110
|
let a = i.startsWith("$") && c.find((e) => `$${e.name}` === i);
|
|
3074
3111
|
if (a && r?.addAsset) {
|
|
3075
3112
|
let i = {
|
|
@@ -3175,7 +3212,7 @@ function vr(e, t) {
|
|
|
3175
3212
|
}
|
|
3176
3213
|
for (let t of i) {
|
|
3177
3214
|
let n = document.createElement("div");
|
|
3178
|
-
n.className = "const-row", n.appendChild(
|
|
3215
|
+
n.className = "const-row", n.appendChild(Pr(t, r[t] ?? 0, (e) => a({
|
|
3179
3216
|
...r,
|
|
3180
3217
|
[t]: e
|
|
3181
3218
|
})));
|
|
@@ -3226,7 +3263,7 @@ function yr(e, t, n) {
|
|
|
3226
3263
|
}
|
|
3227
3264
|
for (let t of i) {
|
|
3228
3265
|
let n = document.createElement("div");
|
|
3229
|
-
n.className = "const-row", n.appendChild(
|
|
3266
|
+
n.className = "const-row", n.appendChild(Cr(t, r[t], (e) => a(t, e)));
|
|
3230
3267
|
let i = document.createElement("button");
|
|
3231
3268
|
i.type = "button", i.className = "const-del", i.textContent = "✕", i.title = `delete constant "${t}"`, i.addEventListener("click", () => s(t)), n.appendChild(i), e.appendChild(n);
|
|
3232
3269
|
}
|
|
@@ -3245,54 +3282,161 @@ function yr(e, t, n) {
|
|
|
3245
3282
|
e && (t.working.constants ?? {})[e] === void 0 && (a(e, (hr.find(([e]) => e === u.value)?.[1] ?? (() => 0))()), l.value = "");
|
|
3246
3283
|
}), c.append(l, u, d), e.appendChild(c);
|
|
3247
3284
|
}
|
|
3248
|
-
|
|
3285
|
+
var br = "en";
|
|
3286
|
+
function xr(e, t) {
|
|
3287
|
+
let n = `@t:${t}`, r = 0, i = (e) => {
|
|
3288
|
+
if (typeof e == "string") {
|
|
3289
|
+
for (let t of e.split(",")) t.trim() === n && (r += 1);
|
|
3290
|
+
return;
|
|
3291
|
+
}
|
|
3292
|
+
if (Array.isArray(e)) for (let t of e) i(t);
|
|
3293
|
+
else if (e && typeof e == "object") for (let t of Object.values(e)) i(t);
|
|
3294
|
+
};
|
|
3295
|
+
for (let [t, n] of Object.entries(e)) t !== "strings" && i(n);
|
|
3296
|
+
return r;
|
|
3297
|
+
}
|
|
3298
|
+
function Sr(e, t, n) {
|
|
3299
|
+
let r = t.working.strings ?? {}, i = Object.keys(r);
|
|
3300
|
+
i.includes(br) || i.unshift(br);
|
|
3301
|
+
let a = [...new Set(i.flatMap((e) => Object.keys(r[e] ?? {})))].sort(), o = (e) => {
|
|
3302
|
+
t.mutate(() => {
|
|
3303
|
+
let n = {};
|
|
3304
|
+
for (let [e, r] of Object.entries(t.working.strings ?? {})) n[e] = { ...r };
|
|
3305
|
+
e(n), Object.keys(n).length === 0 ? delete t.working.strings : t.working.strings = n;
|
|
3306
|
+
});
|
|
3307
|
+
}, s = document.createElement("div");
|
|
3308
|
+
s.className = "strings-langs";
|
|
3309
|
+
let c = document.createElement("span");
|
|
3310
|
+
c.className = "strings-langs-label", c.textContent = "languages", s.appendChild(c);
|
|
3311
|
+
for (let e of i) {
|
|
3312
|
+
let t = document.createElement("span");
|
|
3313
|
+
if (t.className = "strings-lang-chip", t.textContent = e, e === br) t.title = "the base language — everything falls back to this";
|
|
3314
|
+
else {
|
|
3315
|
+
let i = document.createElement("button");
|
|
3316
|
+
i.type = "button", i.className = "strings-locale-del", i.textContent = "✕", i.title = `remove the ${e} translation`, i.addEventListener("click", () => {
|
|
3317
|
+
let t = Object.keys(r[e] ?? {}).length, i = () => {
|
|
3318
|
+
o((t) => {
|
|
3319
|
+
delete t[e];
|
|
3320
|
+
});
|
|
3321
|
+
};
|
|
3322
|
+
t > 0 && n?.confirm ? n.confirm(`Delete the ${e} translation and its ${t} string${t === 1 ? "" : "s"}?`, "delete", i) : i();
|
|
3323
|
+
}), t.appendChild(i);
|
|
3324
|
+
}
|
|
3325
|
+
s.appendChild(t);
|
|
3326
|
+
}
|
|
3327
|
+
if (e.appendChild(s), a.length === 0) {
|
|
3328
|
+
let t = document.createElement("div");
|
|
3329
|
+
t.className = "hint", t.textContent = "No strings yet. A text prop can say \"@t:menu.start\" instead of a literal; add that key here and give it words.", e.appendChild(t);
|
|
3330
|
+
}
|
|
3331
|
+
for (let s of a) {
|
|
3332
|
+
let a = document.createElement("div");
|
|
3333
|
+
a.className = "strings-key-row";
|
|
3334
|
+
let c = document.createElement("span");
|
|
3335
|
+
c.className = "strings-key", c.textContent = s, c.title = `@t:${s}`, a.appendChild(c);
|
|
3336
|
+
let l = document.createElement("button");
|
|
3337
|
+
l.type = "button", l.className = "const-del", l.textContent = "✕", l.title = `delete the "${s}" string in every language`, l.addEventListener("click", () => {
|
|
3338
|
+
let e = () => {
|
|
3339
|
+
o((e) => {
|
|
3340
|
+
for (let t of Object.values(e)) delete t[s];
|
|
3341
|
+
});
|
|
3342
|
+
}, r = xr(t.working, s);
|
|
3343
|
+
if (r > 0 && n?.confirm) {
|
|
3344
|
+
n.confirm(`"@t:${s}" is used by ${r} prop${r === 1 ? "" : "s"}, which will paint the key itself. Delete it anyway?`, "delete", e);
|
|
3345
|
+
return;
|
|
3346
|
+
}
|
|
3347
|
+
e();
|
|
3348
|
+
}), a.appendChild(l), e.appendChild(a);
|
|
3349
|
+
let u = r[br]?.[s];
|
|
3350
|
+
for (let t of i) {
|
|
3351
|
+
let n = r[t]?.[s], i = document.createElement("div");
|
|
3352
|
+
i.className = "strings-row";
|
|
3353
|
+
let a = document.createElement("span");
|
|
3354
|
+
a.className = "strings-lang-tag", a.textContent = t, i.appendChild(a);
|
|
3355
|
+
let c = document.createElement("input");
|
|
3356
|
+
c.type = "text", c.className = "strings-cell", c.dataset.locale = t, c.dataset.key = s, c.value = n ?? "", n === void 0 && (t === br ? (c.classList.add("strings-missing-base"), c.placeholder = s, c.title = `no base text — "${s}" itself will be painted`) : (c.classList.add("strings-fallback"), c.placeholder = u === void 0 ? s : `\u2192 ${u}`, c.title = "not translated — falls back to English silently")), c.addEventListener("change", () => {
|
|
3357
|
+
let e = c.value;
|
|
3358
|
+
o((n) => {
|
|
3359
|
+
let r = n[t] ?? {};
|
|
3360
|
+
e === "" ? delete r[s] : r[s] = e, n[t] = r;
|
|
3361
|
+
});
|
|
3362
|
+
}), i.appendChild(c), e.appendChild(i);
|
|
3363
|
+
}
|
|
3364
|
+
}
|
|
3365
|
+
let l = document.createElement("div");
|
|
3366
|
+
l.className = "const-add";
|
|
3367
|
+
let u = document.createElement("input");
|
|
3368
|
+
u.type = "text", u.placeholder = "new key (e.g. menu.start)";
|
|
3369
|
+
let d = document.createElement("button");
|
|
3370
|
+
d.type = "button", d.textContent = "+ key", d.addEventListener("click", () => {
|
|
3371
|
+
let e = u.value.trim();
|
|
3372
|
+
e && r[br]?.[e] === void 0 && (o((t) => {
|
|
3373
|
+
let n = t[br] ?? {};
|
|
3374
|
+
n[e] = e, t[br] = n;
|
|
3375
|
+
}), u.value = "");
|
|
3376
|
+
}), l.append(u, d), e.appendChild(l);
|
|
3377
|
+
let f = document.createElement("div");
|
|
3378
|
+
f.className = "const-add";
|
|
3379
|
+
let p = document.createElement("input");
|
|
3380
|
+
p.type = "text", p.placeholder = "new language (e.g. ko)";
|
|
3381
|
+
let m = document.createElement("button");
|
|
3382
|
+
m.type = "button", m.textContent = "+ language", m.addEventListener("click", () => {
|
|
3383
|
+
let e = p.value.trim();
|
|
3384
|
+
!e || i.includes(e) || (o((t) => {
|
|
3385
|
+
t[e] = {}, t[br] ??= {};
|
|
3386
|
+
}), p.value = "");
|
|
3387
|
+
}), f.append(p, m), e.appendChild(f);
|
|
3388
|
+
}
|
|
3389
|
+
function Cr(e, t, n) {
|
|
3249
3390
|
let r = d(t);
|
|
3250
|
-
if (r === "number") return
|
|
3391
|
+
if (r === "number") return Pr(e, t, (e) => n(e), () => n(0));
|
|
3251
3392
|
if (r === "boolean") {
|
|
3252
3393
|
let r = document.createElement("input");
|
|
3253
|
-
return r.type = "checkbox", r.checked = t === !0, r.addEventListener("change", () => n(r.checked)),
|
|
3394
|
+
return r.type = "checkbox", r.checked = t === !0, r.addEventListener("change", () => n(r.checked)), V(e, r);
|
|
3254
3395
|
}
|
|
3255
|
-
return r === "array" && Array.isArray(t) && t.every((e) => typeof e == "number") ?
|
|
3396
|
+
return r === "array" && Array.isArray(t) && t.every((e) => typeof e == "number") ? Fr(e, t, (e) => n(e)) : r === "string" ? Nr(e, String(t), (e) => n(e)) : Lr(e, t, (e) => n(e ?? null), JSON.stringify(t));
|
|
3256
3397
|
}
|
|
3257
|
-
function
|
|
3258
|
-
let
|
|
3398
|
+
function wr(e, t, n, r, i, a, o = !1, s) {
|
|
3399
|
+
let c = t.props?.[n] ?? r, l = d(r), f = l === "number" || l === "boolean" || l === "string" || l === "array", p = (i) => {
|
|
3259
3400
|
let a = u(i);
|
|
3260
3401
|
e.mutate(() => {
|
|
3261
3402
|
t.props ||= {};
|
|
3262
3403
|
let e = t.props;
|
|
3263
3404
|
JSON.stringify(i) === JSON.stringify(r) ? (delete e[n], Object.keys(e).length === 0 && delete t.props) : e[n] = i;
|
|
3264
|
-
}, e.selection &&
|
|
3405
|
+
}, e.selection && f && !a ? {
|
|
3265
3406
|
path: e.selection,
|
|
3266
3407
|
key: n,
|
|
3267
3408
|
value: i
|
|
3268
3409
|
} : void 0);
|
|
3269
|
-
},
|
|
3270
|
-
if (u(
|
|
3271
|
-
let
|
|
3272
|
-
if (c
|
|
3273
|
-
|
|
3410
|
+
}, m = Tr(e, l, r);
|
|
3411
|
+
if (u(c)) return Er(n, c["@const"], m, p, r);
|
|
3412
|
+
let h = (e) => m.length > 0 ? Dr(e, m, p) : e;
|
|
3413
|
+
if (s && s.length > 1 && d(c) !== l) return Lr(a ?? n, c, (e) => {
|
|
3414
|
+
p(e === void 0 ? r : e);
|
|
3415
|
+
}, JSON.stringify(r));
|
|
3416
|
+
if (l === "number") return h(Pr(a ?? n, c, (e) => p(e), () => p(r)));
|
|
3417
|
+
if (l === "boolean") {
|
|
3274
3418
|
let e = document.createElement("input");
|
|
3275
|
-
return e.type = "checkbox", e.checked =
|
|
3419
|
+
return e.type = "checkbox", e.checked = c === !0, e.addEventListener("change", () => p(e.checked)), h(V(a ?? n, e));
|
|
3276
3420
|
}
|
|
3277
|
-
if (
|
|
3421
|
+
if (l === "string") {
|
|
3278
3422
|
if (i && i.length > 0) {
|
|
3279
|
-
let t = n === "orderGroup" ?
|
|
3280
|
-
return
|
|
3423
|
+
let t = n === "orderGroup" ? Mr(e) : [];
|
|
3424
|
+
return h(Ar(a ?? n, String(c ?? ""), t.length > 0 ? [...i, ...t] : i, (e) => p(e), n === "orderGroup" ? (t) => jr(t, e) : void 0));
|
|
3281
3425
|
}
|
|
3282
|
-
return
|
|
3426
|
+
return h(o ? ir(e, a ?? n, String(c ?? ""), (e) => p(e)) : Nr(a ?? n, String(c ?? ""), (e) => p(e)));
|
|
3283
3427
|
}
|
|
3284
|
-
return
|
|
3285
|
-
|
|
3428
|
+
return l === "array" && Array.isArray(r) && r.length > 0 && r.every((e) => typeof e == "number") ? h(Fr(n, c ?? r, (e) => p(e))) : Lr(n, c === r ? void 0 : c, (e) => {
|
|
3429
|
+
p(e === void 0 ? r : e);
|
|
3286
3430
|
}, JSON.stringify(r));
|
|
3287
3431
|
}
|
|
3288
|
-
function
|
|
3432
|
+
function Tr(e, t, n) {
|
|
3289
3433
|
let r = e.working.constants ?? {};
|
|
3290
3434
|
return Object.keys(r).filter((e) => {
|
|
3291
3435
|
let i = r[e];
|
|
3292
3436
|
return d(i) === t ? t === "array" && Array.isArray(n) && Array.isArray(i) ? i.length === n.length : !0 : !1;
|
|
3293
3437
|
});
|
|
3294
3438
|
}
|
|
3295
|
-
function
|
|
3439
|
+
function Er(e, t, n, r, i) {
|
|
3296
3440
|
let a = document.createElement("select"), o = n.includes(t) ? n : [t, ...n];
|
|
3297
3441
|
for (let e of o) {
|
|
3298
3442
|
let n = document.createElement("option");
|
|
@@ -3302,10 +3446,10 @@ function Cr(e, t, n, r, i) {
|
|
|
3302
3446
|
s.value = "", s.textContent = "↺ custom value", a.appendChild(s), a.addEventListener("change", () => {
|
|
3303
3447
|
r(a.value ? { "@const": a.value } : i);
|
|
3304
3448
|
});
|
|
3305
|
-
let c =
|
|
3449
|
+
let c = V(`🔗 ${e}`, a);
|
|
3306
3450
|
return c.classList.add("const-bound"), c;
|
|
3307
3451
|
}
|
|
3308
|
-
function
|
|
3452
|
+
function Dr(e, t, n) {
|
|
3309
3453
|
let r = document.createElement("select");
|
|
3310
3454
|
r.className = "const-picker", r.title = "Bind to a named constant";
|
|
3311
3455
|
let i = document.createElement("option");
|
|
@@ -3318,13 +3462,13 @@ function wr(e, t, n) {
|
|
|
3318
3462
|
r.value && n({ "@const": r.value });
|
|
3319
3463
|
}), e.classList.add("has-const-picker"), e.appendChild(r), e;
|
|
3320
3464
|
}
|
|
3321
|
-
function
|
|
3465
|
+
function Or(e, t) {
|
|
3322
3466
|
let n = document.createElement("div");
|
|
3323
3467
|
n.className = "section-title", n.textContent = e, t && n.appendChild(an(t));
|
|
3324
3468
|
let r = document.createElement("span");
|
|
3325
3469
|
return r.className = "rule", n.appendChild(r), n;
|
|
3326
3470
|
}
|
|
3327
|
-
function
|
|
3471
|
+
function kr(e, t) {
|
|
3328
3472
|
let n = document.createElement("span");
|
|
3329
3473
|
n.className = "chip", n.textContent = e;
|
|
3330
3474
|
let r = document.createElement("button");
|
|
@@ -3332,13 +3476,13 @@ function Er(e, t) {
|
|
|
3332
3476
|
e.stopPropagation(), t();
|
|
3333
3477
|
}), n.appendChild(r), n;
|
|
3334
3478
|
}
|
|
3335
|
-
function
|
|
3479
|
+
function V(e, t) {
|
|
3336
3480
|
let n = document.createElement("label");
|
|
3337
3481
|
n.className = "field";
|
|
3338
3482
|
let r = document.createElement("span");
|
|
3339
3483
|
return r.textContent = e, n.append(r, t), n;
|
|
3340
3484
|
}
|
|
3341
|
-
function
|
|
3485
|
+
function Ar(e, t, n, r, i) {
|
|
3342
3486
|
let a = document.createElement("select");
|
|
3343
3487
|
for (let e of n.includes(t) ? n : [t, ...n]) {
|
|
3344
3488
|
let n = document.createElement("option");
|
|
@@ -3346,23 +3490,23 @@ function Dr(e, t, n, r, i) {
|
|
|
3346
3490
|
let r = i?.(e);
|
|
3347
3491
|
n.textContent = r ? `${e} (${r})` : e, e === t && (n.selected = !0), a.appendChild(n);
|
|
3348
3492
|
}
|
|
3349
|
-
return a.addEventListener("change", () => r(a.value)),
|
|
3493
|
+
return a.addEventListener("change", () => r(a.value)), V(e, a);
|
|
3350
3494
|
}
|
|
3351
|
-
function
|
|
3495
|
+
function jr(e, t) {
|
|
3352
3496
|
let r = {
|
|
3353
3497
|
...n,
|
|
3354
3498
|
...t.working.orderGroups ?? {}
|
|
3355
3499
|
}[e];
|
|
3356
3500
|
return r === void 0 ? "unknown — sorts as default" : String(r);
|
|
3357
3501
|
}
|
|
3358
|
-
function
|
|
3502
|
+
function Mr(e) {
|
|
3359
3503
|
return Object.keys(e.working.orderGroups ?? {});
|
|
3360
3504
|
}
|
|
3361
|
-
function
|
|
3505
|
+
function Nr(e, t, n) {
|
|
3362
3506
|
let r = document.createElement("input");
|
|
3363
|
-
return r.type = "text", r.value = t, r.addEventListener("change", () => n(r.value)),
|
|
3507
|
+
return r.type = "text", r.value = t, r.addEventListener("change", () => n(r.value)), V(e, r);
|
|
3364
3508
|
}
|
|
3365
|
-
function
|
|
3509
|
+
function Pr(e, t, n, r) {
|
|
3366
3510
|
let i = document.createElement("input");
|
|
3367
3511
|
return i.type = "number", i.step = "any", i.value = String(t), i.addEventListener("change", () => {
|
|
3368
3512
|
if (i.value.trim() === "") {
|
|
@@ -3371,9 +3515,9 @@ function jr(e, t, n, r) {
|
|
|
3371
3515
|
}
|
|
3372
3516
|
let e = Number(i.value);
|
|
3373
3517
|
Number.isFinite(e) && n(e);
|
|
3374
|
-
}),
|
|
3518
|
+
}), V(e, i);
|
|
3375
3519
|
}
|
|
3376
|
-
function
|
|
3520
|
+
function Fr(e, t, n) {
|
|
3377
3521
|
let r = document.createElement("div");
|
|
3378
3522
|
r.className = "vector-row";
|
|
3379
3523
|
let i = [...t];
|
|
@@ -3383,9 +3527,9 @@ function Mr(e, t, n) {
|
|
|
3383
3527
|
let e = Number(a.value);
|
|
3384
3528
|
Number.isFinite(e) && (i[t] = e, n([...i]));
|
|
3385
3529
|
}), r.appendChild(a);
|
|
3386
|
-
}),
|
|
3530
|
+
}), V(e, r);
|
|
3387
3531
|
}
|
|
3388
|
-
function
|
|
3532
|
+
function Ir(e, t) {
|
|
3389
3533
|
let n = document.createElement("div");
|
|
3390
3534
|
n.className = "field wide tile-paint";
|
|
3391
3535
|
let r = document.createElement("button");
|
|
@@ -3404,33 +3548,37 @@ function Nr(e, t) {
|
|
|
3404
3548
|
let c = document.createElement("div");
|
|
3405
3549
|
return c.className = "paint-hint", c.textContent = "grid grows right/down; digits map to atlas tiles, others need legend", n.appendChild(c), n;
|
|
3406
3550
|
}
|
|
3407
|
-
function
|
|
3408
|
-
let
|
|
3409
|
-
|
|
3410
|
-
let e =
|
|
3551
|
+
function Lr(e, t, n, r = "", i) {
|
|
3552
|
+
let a = document.createElement("textarea");
|
|
3553
|
+
a.rows = 3, a.placeholder = r, a.value = t === void 0 ? "" : JSON.stringify(t, null, 2), a.addEventListener("change", () => {
|
|
3554
|
+
let e = a.value.trim();
|
|
3411
3555
|
if (e === "") {
|
|
3412
|
-
|
|
3556
|
+
a.classList.remove("invalid"), n(void 0);
|
|
3413
3557
|
return;
|
|
3414
3558
|
}
|
|
3415
3559
|
try {
|
|
3416
3560
|
let t = JSON.parse(e);
|
|
3417
|
-
i
|
|
3561
|
+
if (i && !i(t)) {
|
|
3562
|
+
a.classList.add("invalid");
|
|
3563
|
+
return;
|
|
3564
|
+
}
|
|
3565
|
+
a.classList.remove("invalid"), n(t);
|
|
3418
3566
|
} catch {
|
|
3419
|
-
|
|
3567
|
+
a.classList.add("invalid");
|
|
3420
3568
|
}
|
|
3421
3569
|
});
|
|
3422
|
-
let
|
|
3423
|
-
return
|
|
3570
|
+
let o = V(e, a);
|
|
3571
|
+
return o.className = "field wide", o;
|
|
3424
3572
|
}
|
|
3425
|
-
var
|
|
3426
|
-
function
|
|
3573
|
+
var Rr = 1e3, zr = 1001, Br = 1002, Vr = 1006, Hr = 1008, Ur = 1009, Wr = 1023, Gr = 2300, Kr = 2301, qr = 2302, Jr = 2303, Yr = 2400, Xr = 2401, Zr = 2402, Qr = "srgb", $r = "srgb-linear", ei = "linear", ti = "srgb", ni = 2e3;
|
|
3574
|
+
function ri(e) {
|
|
3427
3575
|
return ArrayBuffer.isView(e) && !(e instanceof DataView);
|
|
3428
3576
|
}
|
|
3429
|
-
function
|
|
3577
|
+
function ii(e) {
|
|
3430
3578
|
return document.createElementNS("http://www.w3.org/1999/xhtml", e);
|
|
3431
3579
|
}
|
|
3432
|
-
var
|
|
3433
|
-
function
|
|
3580
|
+
var ai = {}, oi = null;
|
|
3581
|
+
function si(e) {
|
|
3434
3582
|
let t = e[0];
|
|
3435
3583
|
if (typeof t == "string" && t.startsWith("TSL:")) {
|
|
3436
3584
|
let t = e[1];
|
|
@@ -3438,29 +3586,29 @@ function ii(e) {
|
|
|
3438
3586
|
}
|
|
3439
3587
|
return e;
|
|
3440
3588
|
}
|
|
3441
|
-
function
|
|
3442
|
-
e =
|
|
3589
|
+
function H(...e) {
|
|
3590
|
+
e = si(e);
|
|
3443
3591
|
let t = "THREE." + e.shift();
|
|
3444
|
-
if (
|
|
3592
|
+
if (oi) oi("warn", t, ...e);
|
|
3445
3593
|
else {
|
|
3446
3594
|
let n = e[0];
|
|
3447
3595
|
n && n.isStackTrace ? console.warn(n.getError(t)) : console.warn(t, ...e);
|
|
3448
3596
|
}
|
|
3449
3597
|
}
|
|
3450
|
-
function
|
|
3451
|
-
e =
|
|
3598
|
+
function U(...e) {
|
|
3599
|
+
e = si(e);
|
|
3452
3600
|
let t = "THREE." + e.shift();
|
|
3453
|
-
if (
|
|
3601
|
+
if (oi) oi("error", t, ...e);
|
|
3454
3602
|
else {
|
|
3455
3603
|
let n = e[0];
|
|
3456
3604
|
n && n.isStackTrace ? console.error(n.getError(t)) : console.error(t, ...e);
|
|
3457
3605
|
}
|
|
3458
3606
|
}
|
|
3459
|
-
function
|
|
3607
|
+
function ci(...e) {
|
|
3460
3608
|
let t = e.join(" ");
|
|
3461
|
-
t in
|
|
3609
|
+
t in ai || (ai[t] = !0, H(...e));
|
|
3462
3610
|
}
|
|
3463
|
-
var
|
|
3611
|
+
var li = class {
|
|
3464
3612
|
addEventListener(e, t) {
|
|
3465
3613
|
this._listeners === void 0 && (this._listeners = {});
|
|
3466
3614
|
let n = this._listeners;
|
|
@@ -3490,22 +3638,22 @@ var oi = class {
|
|
|
3490
3638
|
e.target = null;
|
|
3491
3639
|
}
|
|
3492
3640
|
}
|
|
3493
|
-
},
|
|
3641
|
+
}, W = /* @__PURE__ */ "00.01.02.03.04.05.06.07.08.09.0a.0b.0c.0d.0e.0f.10.11.12.13.14.15.16.17.18.19.1a.1b.1c.1d.1e.1f.20.21.22.23.24.25.26.27.28.29.2a.2b.2c.2d.2e.2f.30.31.32.33.34.35.36.37.38.39.3a.3b.3c.3d.3e.3f.40.41.42.43.44.45.46.47.48.49.4a.4b.4c.4d.4e.4f.50.51.52.53.54.55.56.57.58.59.5a.5b.5c.5d.5e.5f.60.61.62.63.64.65.66.67.68.69.6a.6b.6c.6d.6e.6f.70.71.72.73.74.75.76.77.78.79.7a.7b.7c.7d.7e.7f.80.81.82.83.84.85.86.87.88.89.8a.8b.8c.8d.8e.8f.90.91.92.93.94.95.96.97.98.99.9a.9b.9c.9d.9e.9f.a0.a1.a2.a3.a4.a5.a6.a7.a8.a9.aa.ab.ac.ad.ae.af.b0.b1.b2.b3.b4.b5.b6.b7.b8.b9.ba.bb.bc.bd.be.bf.c0.c1.c2.c3.c4.c5.c6.c7.c8.c9.ca.cb.cc.cd.ce.cf.d0.d1.d2.d3.d4.d5.d6.d7.d8.d9.da.db.dc.dd.de.df.e0.e1.e2.e3.e4.e5.e6.e7.e8.e9.ea.eb.ec.ed.ee.ef.f0.f1.f2.f3.f4.f5.f6.f7.f8.f9.fa.fb.fc.fd.fe.ff".split(".");
|
|
3494
3642
|
Math.PI / 180, 180 / Math.PI;
|
|
3495
|
-
function
|
|
3643
|
+
function ui() {
|
|
3496
3644
|
let e = Math.random() * 4294967295 | 0, t = Math.random() * 4294967295 | 0, n = Math.random() * 4294967295 | 0, r = Math.random() * 4294967295 | 0;
|
|
3497
|
-
return (
|
|
3645
|
+
return (W[e & 255] + W[e >> 8 & 255] + W[e >> 16 & 255] + W[e >> 24 & 255] + "-" + W[t & 255] + W[t >> 8 & 255] + "-" + W[t >> 16 & 15 | 64] + W[t >> 24 & 255] + "-" + W[n & 63 | 128] + W[n >> 8 & 255] + "-" + W[n >> 16 & 255] + W[n >> 24 & 255] + W[r & 255] + W[r >> 8 & 255] + W[r >> 16 & 255] + W[r >> 24 & 255]).toLowerCase();
|
|
3498
3646
|
}
|
|
3499
|
-
function
|
|
3647
|
+
function G(e, t, n) {
|
|
3500
3648
|
return Math.max(t, Math.min(n, e));
|
|
3501
3649
|
}
|
|
3502
|
-
function
|
|
3650
|
+
function di(e, t) {
|
|
3503
3651
|
return (e % t + t) % t;
|
|
3504
3652
|
}
|
|
3505
|
-
function
|
|
3653
|
+
function fi(e, t, n) {
|
|
3506
3654
|
return (1 - n) * e + n * t;
|
|
3507
3655
|
}
|
|
3508
|
-
var
|
|
3656
|
+
var pi = class e {
|
|
3509
3657
|
static {
|
|
3510
3658
|
e.prototype.isVector2 = !0;
|
|
3511
3659
|
}
|
|
@@ -3605,14 +3753,14 @@ var ui = class e {
|
|
|
3605
3753
|
return this.x = Math.max(this.x, e.x), this.y = Math.max(this.y, e.y), this;
|
|
3606
3754
|
}
|
|
3607
3755
|
clamp(e, t) {
|
|
3608
|
-
return this.x =
|
|
3756
|
+
return this.x = G(this.x, e.x, t.x), this.y = G(this.y, e.y, t.y), this;
|
|
3609
3757
|
}
|
|
3610
3758
|
clampScalar(e, t) {
|
|
3611
|
-
return this.x =
|
|
3759
|
+
return this.x = G(this.x, e, t), this.y = G(this.y, e, t), this;
|
|
3612
3760
|
}
|
|
3613
3761
|
clampLength(e, t) {
|
|
3614
3762
|
let n = this.length();
|
|
3615
|
-
return this.divideScalar(n || 1).multiplyScalar(
|
|
3763
|
+
return this.divideScalar(n || 1).multiplyScalar(G(n, e, t));
|
|
3616
3764
|
}
|
|
3617
3765
|
floor() {
|
|
3618
3766
|
return this.x = Math.floor(this.x), this.y = Math.floor(this.y), this;
|
|
@@ -3654,7 +3802,7 @@ var ui = class e {
|
|
|
3654
3802
|
let t = Math.sqrt(this.lengthSq() * e.lengthSq());
|
|
3655
3803
|
if (t === 0) return Math.PI / 2;
|
|
3656
3804
|
let n = this.dot(e) / t;
|
|
3657
|
-
return Math.acos(
|
|
3805
|
+
return Math.acos(G(n, -1, 1));
|
|
3658
3806
|
}
|
|
3659
3807
|
distanceTo(e) {
|
|
3660
3808
|
return Math.sqrt(this.distanceToSquared(e));
|
|
@@ -3697,7 +3845,7 @@ var ui = class e {
|
|
|
3697
3845
|
*[Symbol.iterator]() {
|
|
3698
3846
|
yield this.x, yield this.y;
|
|
3699
3847
|
}
|
|
3700
|
-
},
|
|
3848
|
+
}, mi = class {
|
|
3701
3849
|
constructor(e = 0, t = 0, n = 0, r = 1) {
|
|
3702
3850
|
this.isQuaternion = !0, this._x = e, this._y = t, this._z = n, this._w = r;
|
|
3703
3851
|
}
|
|
@@ -3776,7 +3924,7 @@ var ui = class e {
|
|
|
3776
3924
|
case "XZY":
|
|
3777
3925
|
this._x = d * l * u - c * f * p, this._y = c * f * u - d * l * p, this._z = c * l * p + d * f * u, this._w = c * l * u + d * f * p;
|
|
3778
3926
|
break;
|
|
3779
|
-
default:
|
|
3927
|
+
default: H("Quaternion: .setFromEuler() encountered an unknown order: " + a);
|
|
3780
3928
|
}
|
|
3781
3929
|
return t === !0 && this._onChangeCallback(), this;
|
|
3782
3930
|
}
|
|
@@ -3806,7 +3954,7 @@ var ui = class e {
|
|
|
3806
3954
|
return n < 1e-8 ? (n = 0, Math.abs(e.x) > Math.abs(e.z) ? (this._x = -e.y, this._y = e.x, this._z = 0, this._w = n) : (this._x = 0, this._y = -e.z, this._z = e.y, this._w = n)) : (this._x = e.y * t.z - e.z * t.y, this._y = e.z * t.x - e.x * t.z, this._z = e.x * t.y - e.y * t.x, this._w = n), this.normalize();
|
|
3807
3955
|
}
|
|
3808
3956
|
angleTo(e) {
|
|
3809
|
-
return 2 * Math.acos(Math.abs(
|
|
3957
|
+
return 2 * Math.acos(Math.abs(G(this.dot(e), -1, 1)));
|
|
3810
3958
|
}
|
|
3811
3959
|
rotateTowards(e, t) {
|
|
3812
3960
|
let n = this.angleTo(e);
|
|
@@ -3885,7 +4033,7 @@ var ui = class e {
|
|
|
3885
4033
|
*[Symbol.iterator]() {
|
|
3886
4034
|
yield this._x, yield this._y, yield this._z, yield this._w;
|
|
3887
4035
|
}
|
|
3888
|
-
},
|
|
4036
|
+
}, K = class e {
|
|
3889
4037
|
static {
|
|
3890
4038
|
e.prototype.isVector3 = !0;
|
|
3891
4039
|
}
|
|
@@ -3967,10 +4115,10 @@ var ui = class e {
|
|
|
3967
4115
|
return this.x = e.x * t.x, this.y = e.y * t.y, this.z = e.z * t.z, this;
|
|
3968
4116
|
}
|
|
3969
4117
|
applyEuler(e) {
|
|
3970
|
-
return this.applyQuaternion(
|
|
4118
|
+
return this.applyQuaternion(gi.setFromEuler(e));
|
|
3971
4119
|
}
|
|
3972
4120
|
applyAxisAngle(e, t) {
|
|
3973
|
-
return this.applyQuaternion(
|
|
4121
|
+
return this.applyQuaternion(gi.setFromAxisAngle(e, t));
|
|
3974
4122
|
}
|
|
3975
4123
|
applyMatrix3(e) {
|
|
3976
4124
|
let t = this.x, n = this.y, r = this.z, i = e.elements;
|
|
@@ -4010,14 +4158,14 @@ var ui = class e {
|
|
|
4010
4158
|
return this.x = Math.max(this.x, e.x), this.y = Math.max(this.y, e.y), this.z = Math.max(this.z, e.z), this;
|
|
4011
4159
|
}
|
|
4012
4160
|
clamp(e, t) {
|
|
4013
|
-
return this.x =
|
|
4161
|
+
return this.x = G(this.x, e.x, t.x), this.y = G(this.y, e.y, t.y), this.z = G(this.z, e.z, t.z), this;
|
|
4014
4162
|
}
|
|
4015
4163
|
clampScalar(e, t) {
|
|
4016
|
-
return this.x =
|
|
4164
|
+
return this.x = G(this.x, e, t), this.y = G(this.y, e, t), this.z = G(this.z, e, t), this;
|
|
4017
4165
|
}
|
|
4018
4166
|
clampLength(e, t) {
|
|
4019
4167
|
let n = this.length();
|
|
4020
|
-
return this.divideScalar(n || 1).multiplyScalar(
|
|
4168
|
+
return this.divideScalar(n || 1).multiplyScalar(G(n, e, t));
|
|
4021
4169
|
}
|
|
4022
4170
|
floor() {
|
|
4023
4171
|
return this.x = Math.floor(this.x), this.y = Math.floor(this.y), this.z = Math.floor(this.z), this;
|
|
@@ -4072,16 +4220,16 @@ var ui = class e {
|
|
|
4072
4220
|
return this.copy(e).multiplyScalar(n);
|
|
4073
4221
|
}
|
|
4074
4222
|
projectOnPlane(e) {
|
|
4075
|
-
return
|
|
4223
|
+
return hi.copy(this).projectOnVector(e), this.sub(hi);
|
|
4076
4224
|
}
|
|
4077
4225
|
reflect(e) {
|
|
4078
|
-
return this.sub(
|
|
4226
|
+
return this.sub(hi.copy(e).multiplyScalar(2 * this.dot(e)));
|
|
4079
4227
|
}
|
|
4080
4228
|
angleTo(e) {
|
|
4081
4229
|
let t = Math.sqrt(this.lengthSq() * e.lengthSq());
|
|
4082
4230
|
if (t === 0) return Math.PI / 2;
|
|
4083
4231
|
let n = this.dot(e) / t;
|
|
4084
|
-
return Math.acos(
|
|
4232
|
+
return Math.acos(G(n, -1, 1));
|
|
4085
4233
|
}
|
|
4086
4234
|
distanceTo(e) {
|
|
4087
4235
|
return Math.sqrt(this.distanceToSquared(e));
|
|
@@ -4148,7 +4296,7 @@ var ui = class e {
|
|
|
4148
4296
|
*[Symbol.iterator]() {
|
|
4149
4297
|
yield this.x, yield this.y, yield this.z;
|
|
4150
4298
|
}
|
|
4151
|
-
},
|
|
4299
|
+
}, hi = /*@__PURE__*/ new K(), gi = /*@__PURE__*/ new mi(), _i = class e {
|
|
4152
4300
|
static {
|
|
4153
4301
|
e.prototype.isMatrix3 = !0;
|
|
4154
4302
|
}
|
|
@@ -4223,13 +4371,13 @@ var ui = class e {
|
|
|
4223
4371
|
return this.set(n * s, n * c, -n * (s * a + c * o) + a + e, -r * c, r * s, -r * (-c * a + s * o) + o + t, 0, 0, 1), this;
|
|
4224
4372
|
}
|
|
4225
4373
|
scale(e, t) {
|
|
4226
|
-
return this.premultiply(
|
|
4374
|
+
return this.premultiply(vi.makeScale(e, t)), this;
|
|
4227
4375
|
}
|
|
4228
4376
|
rotate(e) {
|
|
4229
|
-
return this.premultiply(
|
|
4377
|
+
return this.premultiply(vi.makeRotation(-e)), this;
|
|
4230
4378
|
}
|
|
4231
4379
|
translate(e, t) {
|
|
4232
|
-
return this.premultiply(
|
|
4380
|
+
return this.premultiply(vi.makeTranslation(e, t)), this;
|
|
4233
4381
|
}
|
|
4234
4382
|
makeTranslation(e, t) {
|
|
4235
4383
|
return e.isVector2 ? this.set(1, 0, e.x, 0, 1, e.y, 0, 0, 1) : this.set(1, 0, e, 0, 1, t, 0, 0, 1), this;
|
|
@@ -4257,14 +4405,14 @@ var ui = class e {
|
|
|
4257
4405
|
clone() {
|
|
4258
4406
|
return new this.constructor().fromArray(this.elements);
|
|
4259
4407
|
}
|
|
4260
|
-
},
|
|
4261
|
-
function
|
|
4408
|
+
}, vi = /*@__PURE__*/ new _i(), yi = /*@__PURE__*/ new _i().set(.4123908, .3575843, .1804808, .212639, .7151687, .0721923, .0193308, .1191948, .9505322), bi = /*@__PURE__*/ new _i().set(3.2409699, -1.5373832, -.4986108, -.9692436, 1.8759675, .0415551, .0556301, -.203977, 1.0569715);
|
|
4409
|
+
function xi() {
|
|
4262
4410
|
let e = {
|
|
4263
4411
|
enabled: !0,
|
|
4264
|
-
workingColorSpace:
|
|
4412
|
+
workingColorSpace: $r,
|
|
4265
4413
|
spaces: {},
|
|
4266
4414
|
convert: function(e, t, n) {
|
|
4267
|
-
return this.enabled === !1 || t === n || !t || !n ? e : (this.spaces[t].transfer === "srgb" && (e.r =
|
|
4415
|
+
return this.enabled === !1 || t === n || !t || !n ? e : (this.spaces[t].transfer === "srgb" && (e.r = Si(e.r), e.g = Si(e.g), e.b = Si(e.b)), this.spaces[t].primaries !== this.spaces[n].primaries && (e.applyMatrix3(this.spaces[t].toXYZ), e.applyMatrix3(this.spaces[n].fromXYZ)), this.spaces[n].transfer === "srgb" && (e.r = Ci(e.r), e.g = Ci(e.g), e.b = Ci(e.b)), e);
|
|
4268
4416
|
},
|
|
4269
4417
|
workingToColorSpace: function(e, t) {
|
|
4270
4418
|
return this.convert(e, this.workingColorSpace, t);
|
|
@@ -4276,7 +4424,7 @@ function vi() {
|
|
|
4276
4424
|
return this.spaces[e].primaries;
|
|
4277
4425
|
},
|
|
4278
4426
|
getTransfer: function(e) {
|
|
4279
|
-
return e === "" ?
|
|
4427
|
+
return e === "" ? ei : this.spaces[e].transfer;
|
|
4280
4428
|
},
|
|
4281
4429
|
getToneMappingMode: function(e) {
|
|
4282
4430
|
return this.spaces[e].outputColorSpaceConfig.toneMappingMode || "standard";
|
|
@@ -4297,10 +4445,10 @@ function vi() {
|
|
|
4297
4445
|
return this.spaces[e].workingColorSpaceConfig.unpackColorSpace;
|
|
4298
4446
|
},
|
|
4299
4447
|
fromWorkingColorSpace: function(t, n) {
|
|
4300
|
-
return
|
|
4448
|
+
return ci("ColorManagement: .fromWorkingColorSpace() has been renamed to .workingToColorSpace()."), e.workingToColorSpace(t, n);
|
|
4301
4449
|
},
|
|
4302
4450
|
toWorkingColorSpace: function(t, n) {
|
|
4303
|
-
return
|
|
4451
|
+
return ci("ColorManagement: .toWorkingColorSpace() has been renamed to .colorSpaceToWorking()."), e.colorSpaceToWorking(t, n);
|
|
4304
4452
|
}
|
|
4305
4453
|
}, t = [
|
|
4306
4454
|
.64,
|
|
@@ -4315,68 +4463,68 @@ function vi() {
|
|
|
4315
4463
|
.0722
|
|
4316
4464
|
], r = [.3127, .329];
|
|
4317
4465
|
return e.define({
|
|
4318
|
-
[
|
|
4466
|
+
[$r]: {
|
|
4319
4467
|
primaries: t,
|
|
4320
4468
|
whitePoint: r,
|
|
4321
|
-
transfer:
|
|
4322
|
-
toXYZ:
|
|
4323
|
-
fromXYZ:
|
|
4469
|
+
transfer: ei,
|
|
4470
|
+
toXYZ: yi,
|
|
4471
|
+
fromXYZ: bi,
|
|
4324
4472
|
luminanceCoefficients: n,
|
|
4325
|
-
workingColorSpaceConfig: { unpackColorSpace:
|
|
4326
|
-
outputColorSpaceConfig: { drawingBufferColorSpace:
|
|
4473
|
+
workingColorSpaceConfig: { unpackColorSpace: Qr },
|
|
4474
|
+
outputColorSpaceConfig: { drawingBufferColorSpace: Qr }
|
|
4327
4475
|
},
|
|
4328
|
-
[
|
|
4476
|
+
[Qr]: {
|
|
4329
4477
|
primaries: t,
|
|
4330
4478
|
whitePoint: r,
|
|
4331
|
-
transfer:
|
|
4332
|
-
toXYZ:
|
|
4333
|
-
fromXYZ:
|
|
4479
|
+
transfer: ti,
|
|
4480
|
+
toXYZ: yi,
|
|
4481
|
+
fromXYZ: bi,
|
|
4334
4482
|
luminanceCoefficients: n,
|
|
4335
|
-
outputColorSpaceConfig: { drawingBufferColorSpace:
|
|
4483
|
+
outputColorSpaceConfig: { drawingBufferColorSpace: Qr }
|
|
4336
4484
|
}
|
|
4337
4485
|
}), e;
|
|
4338
4486
|
}
|
|
4339
|
-
var
|
|
4340
|
-
function
|
|
4487
|
+
var q = /*@__PURE__*/ xi();
|
|
4488
|
+
function Si(e) {
|
|
4341
4489
|
return e < .04045 ? e * .0773993808 : (e * .9478672986 + .0521327014) ** 2.4;
|
|
4342
4490
|
}
|
|
4343
|
-
function
|
|
4491
|
+
function Ci(e) {
|
|
4344
4492
|
return e < .0031308 ? e * 12.92 : 1.055 * e ** .41666 - .055;
|
|
4345
4493
|
}
|
|
4346
|
-
var
|
|
4494
|
+
var wi, Ti = class {
|
|
4347
4495
|
static getDataURL(e, t = "image/png") {
|
|
4348
4496
|
if (/^data:/i.test(e.src) || typeof HTMLCanvasElement > "u") return e.src;
|
|
4349
4497
|
let n;
|
|
4350
4498
|
if (e instanceof HTMLCanvasElement) n = e;
|
|
4351
4499
|
else {
|
|
4352
|
-
|
|
4353
|
-
let t =
|
|
4354
|
-
e instanceof ImageData ? t.putImageData(e, 0, 0) : t.drawImage(e, 0, 0, e.width, e.height), n =
|
|
4500
|
+
wi === void 0 && (wi = ii("canvas")), wi.width = e.width, wi.height = e.height;
|
|
4501
|
+
let t = wi.getContext("2d");
|
|
4502
|
+
e instanceof ImageData ? t.putImageData(e, 0, 0) : t.drawImage(e, 0, 0, e.width, e.height), n = wi;
|
|
4355
4503
|
}
|
|
4356
4504
|
return n.toDataURL(t);
|
|
4357
4505
|
}
|
|
4358
4506
|
static sRGBToLinear(e) {
|
|
4359
4507
|
if (typeof HTMLImageElement < "u" && e instanceof HTMLImageElement || typeof HTMLCanvasElement < "u" && e instanceof HTMLCanvasElement || typeof ImageBitmap < "u" && e instanceof ImageBitmap) {
|
|
4360
|
-
let t =
|
|
4508
|
+
let t = ii("canvas");
|
|
4361
4509
|
t.width = e.width, t.height = e.height;
|
|
4362
4510
|
let n = t.getContext("2d");
|
|
4363
4511
|
n.drawImage(e, 0, 0, e.width, e.height);
|
|
4364
4512
|
let r = n.getImageData(0, 0, e.width, e.height), i = r.data;
|
|
4365
|
-
for (let e = 0; e < i.length; e++) i[e] =
|
|
4513
|
+
for (let e = 0; e < i.length; e++) i[e] = Si(i[e] / 255) * 255;
|
|
4366
4514
|
return n.putImageData(r, 0, 0), t;
|
|
4367
4515
|
} else if (e.data) {
|
|
4368
4516
|
let t = e.data.slice(0);
|
|
4369
|
-
for (let e = 0; e < t.length; e++) t instanceof Uint8Array || t instanceof Uint8ClampedArray ? t[e] = Math.floor(
|
|
4517
|
+
for (let e = 0; e < t.length; e++) t instanceof Uint8Array || t instanceof Uint8ClampedArray ? t[e] = Math.floor(Si(t[e] / 255) * 255) : t[e] = Si(t[e]);
|
|
4370
4518
|
return {
|
|
4371
4519
|
data: t,
|
|
4372
4520
|
width: e.width,
|
|
4373
4521
|
height: e.height
|
|
4374
4522
|
};
|
|
4375
|
-
} else return
|
|
4523
|
+
} else return H("ImageUtils.sRGBToLinear(): Unsupported image type. No color space conversion applied."), e;
|
|
4376
4524
|
}
|
|
4377
|
-
},
|
|
4525
|
+
}, Ei = 0, Di = class {
|
|
4378
4526
|
constructor(e = null) {
|
|
4379
|
-
this.isSource = !0, Object.defineProperty(this, "id", { value:
|
|
4527
|
+
this.isSource = !0, Object.defineProperty(this, "id", { value: Ei++ }), this.uuid = ui(), this.data = e, this.dataReady = !0, this.version = 0;
|
|
4380
4528
|
}
|
|
4381
4529
|
getSize(e) {
|
|
4382
4530
|
let t = this.data;
|
|
@@ -4396,33 +4544,33 @@ var xi, Si = class {
|
|
|
4396
4544
|
let e;
|
|
4397
4545
|
if (Array.isArray(r)) {
|
|
4398
4546
|
e = [];
|
|
4399
|
-
for (let t = 0, n = r.length; t < n; t++) r[t].isDataTexture ? e.push(
|
|
4400
|
-
} else e =
|
|
4547
|
+
for (let t = 0, n = r.length; t < n; t++) r[t].isDataTexture ? e.push(Oi(r[t].image)) : e.push(Oi(r[t]));
|
|
4548
|
+
} else e = Oi(r);
|
|
4401
4549
|
n.url = e;
|
|
4402
4550
|
}
|
|
4403
4551
|
return t || (e.images[this.uuid] = n), n;
|
|
4404
4552
|
}
|
|
4405
4553
|
};
|
|
4406
|
-
function
|
|
4407
|
-
return typeof HTMLImageElement < "u" && e instanceof HTMLImageElement || typeof HTMLCanvasElement < "u" && e instanceof HTMLCanvasElement || typeof ImageBitmap < "u" && e instanceof ImageBitmap ?
|
|
4554
|
+
function Oi(e) {
|
|
4555
|
+
return typeof HTMLImageElement < "u" && e instanceof HTMLImageElement || typeof HTMLCanvasElement < "u" && e instanceof HTMLCanvasElement || typeof ImageBitmap < "u" && e instanceof ImageBitmap ? Ti.getDataURL(e) : e.data ? {
|
|
4408
4556
|
data: Array.from(e.data),
|
|
4409
4557
|
width: e.width,
|
|
4410
4558
|
height: e.height,
|
|
4411
4559
|
type: e.data.constructor.name
|
|
4412
|
-
} : (
|
|
4560
|
+
} : (H("Texture: Unable to serialize Texture."), {});
|
|
4413
4561
|
}
|
|
4414
|
-
var
|
|
4415
|
-
constructor(t = e.DEFAULT_IMAGE, n = e.DEFAULT_MAPPING, r =
|
|
4416
|
-
super(), this.isTexture = !0, Object.defineProperty(this, "id", { value:
|
|
4562
|
+
var ki = 0, Ai = /*@__PURE__*/ new K(), ji = class e extends li {
|
|
4563
|
+
constructor(t = e.DEFAULT_IMAGE, n = e.DEFAULT_MAPPING, r = zr, i = zr, a = Vr, o = Hr, s = Wr, c = Ur, l = e.DEFAULT_ANISOTROPY, u = "") {
|
|
4564
|
+
super(), this.isTexture = !0, Object.defineProperty(this, "id", { value: ki++ }), this.uuid = ui(), this.name = "", this.source = new Di(t), this.mipmaps = [], this.mapping = n, this.channel = 0, this.wrapS = r, this.wrapT = i, this.magFilter = a, this.minFilter = o, this.anisotropy = l, this.format = s, this.internalFormat = null, this.type = c, this.offset = new pi(0, 0), this.repeat = new pi(1, 1), this.center = new pi(0, 0), this.rotation = 0, this.matrixAutoUpdate = !0, this.matrix = new _i(), this.generateMipmaps = !0, this.premultiplyAlpha = !1, this.flipY = !0, this.unpackAlignment = 4, this.colorSpace = u, this.userData = {}, this.updateRanges = [], this.version = 0, this.onUpdate = null, this.renderTarget = null, this.isRenderTargetTexture = !1, this.isArrayTexture = !!(t && t.depth && t.depth > 1), this.pmremVersion = 0, this.normalized = !1;
|
|
4417
4565
|
}
|
|
4418
4566
|
get width() {
|
|
4419
|
-
return this.source.getSize(
|
|
4567
|
+
return this.source.getSize(Ai).x;
|
|
4420
4568
|
}
|
|
4421
4569
|
get height() {
|
|
4422
|
-
return this.source.getSize(
|
|
4570
|
+
return this.source.getSize(Ai).y;
|
|
4423
4571
|
}
|
|
4424
4572
|
get depth() {
|
|
4425
|
-
return this.source.getSize(
|
|
4573
|
+
return this.source.getSize(Ai).z;
|
|
4426
4574
|
}
|
|
4427
4575
|
get image() {
|
|
4428
4576
|
return this.source.data;
|
|
@@ -4452,12 +4600,12 @@ var Ei = 0, Di = /*@__PURE__*/ new G(), Oi = class e extends oi {
|
|
|
4452
4600
|
for (let t in e) {
|
|
4453
4601
|
let n = e[t];
|
|
4454
4602
|
if (n === void 0) {
|
|
4455
|
-
|
|
4603
|
+
H(`Texture.setValues(): parameter '${t}' has value of undefined.`);
|
|
4456
4604
|
continue;
|
|
4457
4605
|
}
|
|
4458
4606
|
let r = this[t];
|
|
4459
4607
|
if (r === void 0) {
|
|
4460
|
-
|
|
4608
|
+
H(`Texture.setValues(): property '${t}' does not exist.`);
|
|
4461
4609
|
continue;
|
|
4462
4610
|
}
|
|
4463
4611
|
r && n && r.isVector2 && n.isVector2 || r && n && r.isVector3 && n.isVector3 || r && n && r.isMatrix3 && n.isMatrix3 ? r.copy(n) : this[t] = n;
|
|
@@ -4503,24 +4651,24 @@ var Ei = 0, Di = /*@__PURE__*/ new G(), Oi = class e extends oi {
|
|
|
4503
4651
|
transformUv(e) {
|
|
4504
4652
|
if (this.mapping !== 300) return e;
|
|
4505
4653
|
if (e.applyMatrix3(this.matrix), e.x < 0 || e.x > 1) switch (this.wrapS) {
|
|
4506
|
-
case
|
|
4654
|
+
case Rr:
|
|
4507
4655
|
e.x -= Math.floor(e.x);
|
|
4508
4656
|
break;
|
|
4509
|
-
case
|
|
4657
|
+
case zr:
|
|
4510
4658
|
e.x = e.x < 0 ? 0 : 1;
|
|
4511
4659
|
break;
|
|
4512
|
-
case
|
|
4660
|
+
case Br:
|
|
4513
4661
|
Math.abs(Math.floor(e.x) % 2) === 1 ? e.x = Math.ceil(e.x) - e.x : e.x -= Math.floor(e.x);
|
|
4514
4662
|
break;
|
|
4515
4663
|
}
|
|
4516
4664
|
if (e.y < 0 || e.y > 1) switch (this.wrapT) {
|
|
4517
|
-
case
|
|
4665
|
+
case Rr:
|
|
4518
4666
|
e.y -= Math.floor(e.y);
|
|
4519
4667
|
break;
|
|
4520
|
-
case
|
|
4668
|
+
case zr:
|
|
4521
4669
|
e.y = e.y < 0 ? 0 : 1;
|
|
4522
4670
|
break;
|
|
4523
|
-
case
|
|
4671
|
+
case Br:
|
|
4524
4672
|
Math.abs(Math.floor(e.y) % 2) === 1 ? e.y = Math.ceil(e.y) - e.y : e.y -= Math.floor(e.y);
|
|
4525
4673
|
break;
|
|
4526
4674
|
}
|
|
@@ -4533,7 +4681,7 @@ var Ei = 0, Di = /*@__PURE__*/ new G(), Oi = class e extends oi {
|
|
|
4533
4681
|
e === !0 && this.pmremVersion++;
|
|
4534
4682
|
}
|
|
4535
4683
|
};
|
|
4536
|
-
|
|
4684
|
+
ji.DEFAULT_IMAGE = null, ji.DEFAULT_MAPPING = 300, ji.DEFAULT_ANISOTROPY = 1, class e {
|
|
4537
4685
|
static {
|
|
4538
4686
|
e.prototype.isVector4 = !0;
|
|
4539
4687
|
}
|
|
@@ -4667,14 +4815,14 @@ Oi.DEFAULT_IMAGE = null, Oi.DEFAULT_MAPPING = 300, Oi.DEFAULT_ANISOTROPY = 1, cl
|
|
|
4667
4815
|
return this.x = Math.max(this.x, e.x), this.y = Math.max(this.y, e.y), this.z = Math.max(this.z, e.z), this.w = Math.max(this.w, e.w), this;
|
|
4668
4816
|
}
|
|
4669
4817
|
clamp(e, t) {
|
|
4670
|
-
return this.x =
|
|
4818
|
+
return this.x = G(this.x, e.x, t.x), this.y = G(this.y, e.y, t.y), this.z = G(this.z, e.z, t.z), this.w = G(this.w, e.w, t.w), this;
|
|
4671
4819
|
}
|
|
4672
4820
|
clampScalar(e, t) {
|
|
4673
|
-
return this.x =
|
|
4821
|
+
return this.x = G(this.x, e, t), this.y = G(this.y, e, t), this.z = G(this.z, e, t), this.w = G(this.w, e, t), this;
|
|
4674
4822
|
}
|
|
4675
4823
|
clampLength(e, t) {
|
|
4676
4824
|
let n = this.length();
|
|
4677
|
-
return this.divideScalar(n || 1).multiplyScalar(
|
|
4825
|
+
return this.divideScalar(n || 1).multiplyScalar(G(n, e, t));
|
|
4678
4826
|
}
|
|
4679
4827
|
floor() {
|
|
4680
4828
|
return this.x = Math.floor(this.x), this.y = Math.floor(this.y), this.z = Math.floor(this.z), this.w = Math.floor(this.w), this;
|
|
@@ -4734,7 +4882,7 @@ Oi.DEFAULT_IMAGE = null, Oi.DEFAULT_MAPPING = 300, Oi.DEFAULT_ANISOTROPY = 1, cl
|
|
|
4734
4882
|
yield this.x, yield this.y, yield this.z, yield this.w;
|
|
4735
4883
|
}
|
|
4736
4884
|
};
|
|
4737
|
-
var
|
|
4885
|
+
var Mi = class e {
|
|
4738
4886
|
static {
|
|
4739
4887
|
e.prototype.isMatrix4 = !0;
|
|
4740
4888
|
}
|
|
@@ -4788,7 +4936,7 @@ var ki = class e {
|
|
|
4788
4936
|
}
|
|
4789
4937
|
extractRotation(e) {
|
|
4790
4938
|
if (e.determinant() === 0) return this.identity();
|
|
4791
|
-
let t = this.elements, n = e.elements, r = 1 /
|
|
4939
|
+
let t = this.elements, n = e.elements, r = 1 / Ni.setFromMatrixColumn(e, 0).length(), i = 1 / Ni.setFromMatrixColumn(e, 1).length(), a = 1 / Ni.setFromMatrixColumn(e, 2).length();
|
|
4792
4940
|
return t[0] = n[0] * r, t[1] = n[1] * r, t[2] = n[2] * r, t[3] = 0, t[4] = n[4] * i, t[5] = n[5] * i, t[6] = n[6] * i, t[7] = 0, t[8] = n[8] * a, t[9] = n[9] * a, t[10] = n[10] * a, t[11] = 0, t[12] = 0, t[13] = 0, t[14] = 0, t[15] = 1, this;
|
|
4793
4941
|
}
|
|
4794
4942
|
makeRotationFromEuler(e) {
|
|
@@ -4815,11 +4963,11 @@ var ki = class e {
|
|
|
4815
4963
|
return t[3] = 0, t[7] = 0, t[11] = 0, t[12] = 0, t[13] = 0, t[14] = 0, t[15] = 1, this;
|
|
4816
4964
|
}
|
|
4817
4965
|
makeRotationFromQuaternion(e) {
|
|
4818
|
-
return this.compose(
|
|
4966
|
+
return this.compose(Pi, e, Fi);
|
|
4819
4967
|
}
|
|
4820
4968
|
lookAt(e, t, n) {
|
|
4821
4969
|
let r = this.elements;
|
|
4822
|
-
return
|
|
4970
|
+
return Y.subVectors(e, t), Y.lengthSq() === 0 && (Y.z = 1), Y.normalize(), Ii.crossVectors(n, Y), Ii.lengthSq() === 0 && (Math.abs(n.z) === 1 ? Y.x += 1e-4 : Y.z += 1e-4, Y.normalize(), Ii.crossVectors(n, Y)), Ii.normalize(), Li.crossVectors(Y, Ii), r[0] = Ii.x, r[4] = Li.x, r[8] = Y.x, r[1] = Ii.y, r[5] = Li.y, r[9] = Y.y, r[2] = Ii.z, r[6] = Li.z, r[10] = Y.z, this;
|
|
4823
4971
|
}
|
|
4824
4972
|
multiply(e) {
|
|
4825
4973
|
return this.multiplyMatrices(this, e);
|
|
@@ -4828,8 +4976,8 @@ var ki = class e {
|
|
|
4828
4976
|
return this.multiplyMatrices(e, this);
|
|
4829
4977
|
}
|
|
4830
4978
|
multiplyMatrices(e, t) {
|
|
4831
|
-
let n = e.elements, r = t.elements, i = this.elements, a = n[0], o = n[4], s = n[8], c = n[12], l = n[1], u = n[5], d = n[9], f = n[13], p = n[2], m = n[6], h = n[10], g = n[14], _ = n[3], v = n[7], y = n[11], b = n[15], x = r[0], S = r[4], C = r[8], w = r[12], T = r[1], E = r[5], D = r[9], O = r[13], k = r[2], A = r[6], ee = r[10], te = r[14], j = r[3], ne = r[7],
|
|
4832
|
-
return i[0] = a * x + o * T + s * k + c * j, i[4] = a * S + o * E + s * A + c * ne, i[8] = a * C + o * D + s * ee + c *
|
|
4979
|
+
let n = e.elements, r = t.elements, i = this.elements, a = n[0], o = n[4], s = n[8], c = n[12], l = n[1], u = n[5], d = n[9], f = n[13], p = n[2], m = n[6], h = n[10], g = n[14], _ = n[3], v = n[7], y = n[11], b = n[15], x = r[0], S = r[4], C = r[8], w = r[12], T = r[1], E = r[5], D = r[9], O = r[13], k = r[2], A = r[6], ee = r[10], te = r[14], j = r[3], ne = r[7], re = r[11], M = r[15];
|
|
4980
|
+
return i[0] = a * x + o * T + s * k + c * j, i[4] = a * S + o * E + s * A + c * ne, i[8] = a * C + o * D + s * ee + c * re, i[12] = a * w + o * O + s * te + c * M, i[1] = l * x + u * T + d * k + f * j, i[5] = l * S + u * E + d * A + f * ne, i[9] = l * C + u * D + d * ee + f * re, i[13] = l * w + u * O + d * te + f * M, i[2] = p * x + m * T + h * k + g * j, i[6] = p * S + m * E + h * A + g * ne, i[10] = p * C + m * D + h * ee + g * re, i[14] = p * w + m * O + h * te + g * M, i[3] = _ * x + v * T + y * k + b * j, i[7] = _ * S + v * E + y * A + b * ne, i[11] = _ * C + v * D + y * ee + b * re, i[15] = _ * w + v * O + y * te + b * M, this;
|
|
4833
4981
|
}
|
|
4834
4982
|
multiplyScalar(e) {
|
|
4835
4983
|
let t = this.elements;
|
|
@@ -4895,12 +5043,12 @@ var ki = class e {
|
|
|
4895
5043
|
e.x = r[12], e.y = r[13], e.z = r[14];
|
|
4896
5044
|
let i = this.determinant();
|
|
4897
5045
|
if (i === 0) return n.set(1, 1, 1), t.identity(), this;
|
|
4898
|
-
let a =
|
|
4899
|
-
i < 0 && (a = -a),
|
|
5046
|
+
let a = Ni.set(r[0], r[1], r[2]).length(), o = Ni.set(r[4], r[5], r[6]).length(), s = Ni.set(r[8], r[9], r[10]).length();
|
|
5047
|
+
i < 0 && (a = -a), J.copy(this);
|
|
4900
5048
|
let c = 1 / a, l = 1 / o, u = 1 / s;
|
|
4901
|
-
return
|
|
5049
|
+
return J.elements[0] *= c, J.elements[1] *= c, J.elements[2] *= c, J.elements[4] *= l, J.elements[5] *= l, J.elements[6] *= l, J.elements[8] *= u, J.elements[9] *= u, J.elements[10] *= u, t.setFromRotationMatrix(J), n.x = a, n.y = o, n.z = s, this;
|
|
4902
5050
|
}
|
|
4903
|
-
makePerspective(e, t, n, r, i, a, o =
|
|
5051
|
+
makePerspective(e, t, n, r, i, a, o = ni, s = !1) {
|
|
4904
5052
|
let c = this.elements, l = 2 * i / (t - e), u = 2 * i / (n - r), d = (t + e) / (t - e), f = (n + r) / (n - r), p, m;
|
|
4905
5053
|
if (s) p = i / (a - i), m = a * i / (a - i);
|
|
4906
5054
|
else if (o === 2e3) p = -(a + i) / (a - i), m = -2 * a * i / (a - i);
|
|
@@ -4908,7 +5056,7 @@ var ki = class e {
|
|
|
4908
5056
|
else throw Error("THREE.Matrix4.makePerspective(): Invalid coordinate system: " + o);
|
|
4909
5057
|
return c[0] = l, c[4] = 0, c[8] = d, c[12] = 0, c[1] = 0, c[5] = u, c[9] = f, c[13] = 0, c[2] = 0, c[6] = 0, c[10] = p, c[14] = m, c[3] = 0, c[7] = 0, c[11] = -1, c[15] = 0, this;
|
|
4910
5058
|
}
|
|
4911
|
-
makeOrthographic(e, t, n, r, i, a, o =
|
|
5059
|
+
makeOrthographic(e, t, n, r, i, a, o = ni, s = !1) {
|
|
4912
5060
|
let c = this.elements, l = 2 / (t - e), u = 2 / (n - r), d = -(t + e) / (t - e), f = -(n + r) / (n - r), p, m;
|
|
4913
5061
|
if (s) p = 1 / (a - i), m = a / (a - i);
|
|
4914
5062
|
else if (o === 2e3) p = -2 / (a - i), m = -(a + i) / (a - i);
|
|
@@ -4929,7 +5077,7 @@ var ki = class e {
|
|
|
4929
5077
|
let n = this.elements;
|
|
4930
5078
|
return e[t] = n[0], e[t + 1] = n[1], e[t + 2] = n[2], e[t + 3] = n[3], e[t + 4] = n[4], e[t + 5] = n[5], e[t + 6] = n[6], e[t + 7] = n[7], e[t + 8] = n[8], e[t + 9] = n[9], e[t + 10] = n[10], e[t + 11] = n[11], e[t + 12] = n[12], e[t + 13] = n[13], e[t + 14] = n[14], e[t + 15] = n[15], e;
|
|
4931
5079
|
}
|
|
4932
|
-
},
|
|
5080
|
+
}, Ni = /*@__PURE__*/ new K(), J = /*@__PURE__*/ new Mi(), Pi = /*@__PURE__*/ new K(0, 0, 0), Fi = /*@__PURE__*/ new K(1, 1, 1), Ii = /*@__PURE__*/ new K(), Li = /*@__PURE__*/ new K(), Y = /*@__PURE__*/ new K(), Ri = /*@__PURE__*/ new Mi(), zi = /*@__PURE__*/ new mi(), Bi = class e {
|
|
4933
5081
|
constructor(t = 0, n = 0, r = 0, i = e.DEFAULT_ORDER) {
|
|
4934
5082
|
this.isEuler = !0, this._x = t, this._y = n, this._z = r, this._order = i;
|
|
4935
5083
|
}
|
|
@@ -4970,35 +5118,35 @@ var ki = class e {
|
|
|
4970
5118
|
let r = e.elements, i = r[0], a = r[4], o = r[8], s = r[1], c = r[5], l = r[9], u = r[2], d = r[6], f = r[10];
|
|
4971
5119
|
switch (t) {
|
|
4972
5120
|
case "XYZ":
|
|
4973
|
-
this._y = Math.asin(
|
|
5121
|
+
this._y = Math.asin(G(o, -1, 1)), Math.abs(o) < .9999999 ? (this._x = Math.atan2(-l, f), this._z = Math.atan2(-a, i)) : (this._x = Math.atan2(d, c), this._z = 0);
|
|
4974
5122
|
break;
|
|
4975
5123
|
case "YXZ":
|
|
4976
|
-
this._x = Math.asin(-
|
|
5124
|
+
this._x = Math.asin(-G(l, -1, 1)), Math.abs(l) < .9999999 ? (this._y = Math.atan2(o, f), this._z = Math.atan2(s, c)) : (this._y = Math.atan2(-u, i), this._z = 0);
|
|
4977
5125
|
break;
|
|
4978
5126
|
case "ZXY":
|
|
4979
|
-
this._x = Math.asin(
|
|
5127
|
+
this._x = Math.asin(G(d, -1, 1)), Math.abs(d) < .9999999 ? (this._y = Math.atan2(-u, f), this._z = Math.atan2(-a, c)) : (this._y = 0, this._z = Math.atan2(s, i));
|
|
4980
5128
|
break;
|
|
4981
5129
|
case "ZYX":
|
|
4982
|
-
this._y = Math.asin(-
|
|
5130
|
+
this._y = Math.asin(-G(u, -1, 1)), Math.abs(u) < .9999999 ? (this._x = Math.atan2(d, f), this._z = Math.atan2(s, i)) : (this._x = 0, this._z = Math.atan2(-a, c));
|
|
4983
5131
|
break;
|
|
4984
5132
|
case "YZX":
|
|
4985
|
-
this._z = Math.asin(
|
|
5133
|
+
this._z = Math.asin(G(s, -1, 1)), Math.abs(s) < .9999999 ? (this._x = Math.atan2(-l, c), this._y = Math.atan2(-u, i)) : (this._x = 0, this._y = Math.atan2(o, f));
|
|
4986
5134
|
break;
|
|
4987
5135
|
case "XZY":
|
|
4988
|
-
this._z = Math.asin(-
|
|
5136
|
+
this._z = Math.asin(-G(a, -1, 1)), Math.abs(a) < .9999999 ? (this._x = Math.atan2(d, c), this._y = Math.atan2(o, i)) : (this._x = Math.atan2(-l, f), this._y = 0);
|
|
4989
5137
|
break;
|
|
4990
|
-
default:
|
|
5138
|
+
default: H("Euler: .setFromRotationMatrix() encountered an unknown order: " + t);
|
|
4991
5139
|
}
|
|
4992
5140
|
return this._order = t, n === !0 && this._onChangeCallback(), this;
|
|
4993
5141
|
}
|
|
4994
5142
|
setFromQuaternion(e, t, n) {
|
|
4995
|
-
return
|
|
5143
|
+
return Ri.makeRotationFromQuaternion(e), this.setFromRotationMatrix(Ri, t, n);
|
|
4996
5144
|
}
|
|
4997
5145
|
setFromVector3(e, t = this._order) {
|
|
4998
5146
|
return this.set(e.x, e.y, e.z, t);
|
|
4999
5147
|
}
|
|
5000
5148
|
reorder(e) {
|
|
5001
|
-
return
|
|
5149
|
+
return zi.setFromEuler(this), this.setFromQuaternion(zi, e);
|
|
5002
5150
|
}
|
|
5003
5151
|
equals(e) {
|
|
5004
5152
|
return e._x === this._x && e._y === this._y && e._z === this._z && e._order === this._order;
|
|
@@ -5017,8 +5165,8 @@ var ki = class e {
|
|
|
5017
5165
|
yield this._x, yield this._y, yield this._z, yield this._order;
|
|
5018
5166
|
}
|
|
5019
5167
|
};
|
|
5020
|
-
|
|
5021
|
-
var
|
|
5168
|
+
Bi.DEFAULT_ORDER = "XYZ";
|
|
5169
|
+
var Vi = class {
|
|
5022
5170
|
constructor() {
|
|
5023
5171
|
this.mask = 1;
|
|
5024
5172
|
}
|
|
@@ -5046,16 +5194,16 @@ var Ri = class {
|
|
|
5046
5194
|
isEnabled(e) {
|
|
5047
5195
|
return (this.mask & (1 << e | 0)) != 0;
|
|
5048
5196
|
}
|
|
5049
|
-
},
|
|
5197
|
+
}, Hi = 0, Ui = /*@__PURE__*/ new K(), Wi = /*@__PURE__*/ new mi(), Gi = /*@__PURE__*/ new Mi(), Ki = /*@__PURE__*/ new K(), qi = /*@__PURE__*/ new K(), Ji = /*@__PURE__*/ new K(), Yi = /*@__PURE__*/ new mi(), Xi = /*@__PURE__*/ new K(1, 0, 0), Zi = /*@__PURE__*/ new K(0, 1, 0), Qi = /*@__PURE__*/ new K(0, 0, 1), $i = { type: "added" }, ea = { type: "removed" }, ta = {
|
|
5050
5198
|
type: "childadded",
|
|
5051
5199
|
child: null
|
|
5052
|
-
},
|
|
5200
|
+
}, na = {
|
|
5053
5201
|
type: "childremoved",
|
|
5054
5202
|
child: null
|
|
5055
|
-
},
|
|
5203
|
+
}, ra = class e extends li {
|
|
5056
5204
|
constructor() {
|
|
5057
|
-
super(), this.isObject3D = !0, Object.defineProperty(this, "id", { value:
|
|
5058
|
-
let t = new
|
|
5205
|
+
super(), this.isObject3D = !0, Object.defineProperty(this, "id", { value: Hi++ }), this.uuid = ui(), this.name = "", this.type = "Object3D", this.parent = null, this.children = [], this.up = e.DEFAULT_UP.clone();
|
|
5206
|
+
let t = new K(), n = new Bi(), r = new mi(), i = new K(1, 1, 1);
|
|
5059
5207
|
function a() {
|
|
5060
5208
|
r.setFromEuler(n, !1);
|
|
5061
5209
|
}
|
|
@@ -5083,9 +5231,9 @@ var Ri = class {
|
|
|
5083
5231
|
enumerable: !0,
|
|
5084
5232
|
value: i
|
|
5085
5233
|
},
|
|
5086
|
-
modelViewMatrix: { value: new
|
|
5087
|
-
normalMatrix: { value: new
|
|
5088
|
-
}), this.matrix = new
|
|
5234
|
+
modelViewMatrix: { value: new Mi() },
|
|
5235
|
+
normalMatrix: { value: new _i() }
|
|
5236
|
+
}), this.matrix = new Mi(), this.matrixWorld = new Mi(), this.matrixAutoUpdate = e.DEFAULT_MATRIX_AUTO_UPDATE, this.matrixWorldAutoUpdate = e.DEFAULT_MATRIX_WORLD_AUTO_UPDATE, this.matrixWorldNeedsUpdate = !1, this.layers = new Vi(), this.visible = !0, this.castShadow = !1, this.receiveShadow = !1, this.frustumCulled = !0, this.renderOrder = 0, this.animations = [], this.customDepthMaterial = void 0, this.customDistanceMaterial = void 0, this.static = !1, this.userData = {}, this.pivot = null;
|
|
5089
5237
|
}
|
|
5090
5238
|
onBeforeShadow() {}
|
|
5091
5239
|
onAfterShadow() {}
|
|
@@ -5110,49 +5258,49 @@ var Ri = class {
|
|
|
5110
5258
|
this.quaternion.copy(e);
|
|
5111
5259
|
}
|
|
5112
5260
|
rotateOnAxis(e, t) {
|
|
5113
|
-
return
|
|
5261
|
+
return Wi.setFromAxisAngle(e, t), this.quaternion.multiply(Wi), this;
|
|
5114
5262
|
}
|
|
5115
5263
|
rotateOnWorldAxis(e, t) {
|
|
5116
|
-
return
|
|
5264
|
+
return Wi.setFromAxisAngle(e, t), this.quaternion.premultiply(Wi), this;
|
|
5117
5265
|
}
|
|
5118
5266
|
rotateX(e) {
|
|
5119
|
-
return this.rotateOnAxis(
|
|
5267
|
+
return this.rotateOnAxis(Xi, e);
|
|
5120
5268
|
}
|
|
5121
5269
|
rotateY(e) {
|
|
5122
|
-
return this.rotateOnAxis(
|
|
5270
|
+
return this.rotateOnAxis(Zi, e);
|
|
5123
5271
|
}
|
|
5124
5272
|
rotateZ(e) {
|
|
5125
|
-
return this.rotateOnAxis(
|
|
5273
|
+
return this.rotateOnAxis(Qi, e);
|
|
5126
5274
|
}
|
|
5127
5275
|
translateOnAxis(e, t) {
|
|
5128
|
-
return
|
|
5276
|
+
return Ui.copy(e).applyQuaternion(this.quaternion), this.position.add(Ui.multiplyScalar(t)), this;
|
|
5129
5277
|
}
|
|
5130
5278
|
translateX(e) {
|
|
5131
|
-
return this.translateOnAxis(
|
|
5279
|
+
return this.translateOnAxis(Xi, e);
|
|
5132
5280
|
}
|
|
5133
5281
|
translateY(e) {
|
|
5134
|
-
return this.translateOnAxis(
|
|
5282
|
+
return this.translateOnAxis(Zi, e);
|
|
5135
5283
|
}
|
|
5136
5284
|
translateZ(e) {
|
|
5137
|
-
return this.translateOnAxis(
|
|
5285
|
+
return this.translateOnAxis(Qi, e);
|
|
5138
5286
|
}
|
|
5139
5287
|
localToWorld(e) {
|
|
5140
5288
|
return this.updateWorldMatrix(!0, !1), e.applyMatrix4(this.matrixWorld);
|
|
5141
5289
|
}
|
|
5142
5290
|
worldToLocal(e) {
|
|
5143
|
-
return this.updateWorldMatrix(!0, !1), e.applyMatrix4(
|
|
5291
|
+
return this.updateWorldMatrix(!0, !1), e.applyMatrix4(Gi.copy(this.matrixWorld).invert());
|
|
5144
5292
|
}
|
|
5145
5293
|
lookAt(e, t, n) {
|
|
5146
|
-
e.isVector3 ?
|
|
5294
|
+
e.isVector3 ? Ki.copy(e) : Ki.set(e, t, n);
|
|
5147
5295
|
let r = this.parent;
|
|
5148
|
-
this.updateWorldMatrix(!0, !1),
|
|
5296
|
+
this.updateWorldMatrix(!0, !1), qi.setFromMatrixPosition(this.matrixWorld), this.isCamera || this.isLight ? Gi.lookAt(qi, Ki, this.up) : Gi.lookAt(Ki, qi, this.up), this.quaternion.setFromRotationMatrix(Gi), r && (Gi.extractRotation(r.matrixWorld), Wi.setFromRotationMatrix(Gi), this.quaternion.premultiply(Wi.invert()));
|
|
5149
5297
|
}
|
|
5150
5298
|
add(e) {
|
|
5151
5299
|
if (arguments.length > 1) {
|
|
5152
5300
|
for (let e = 0; e < arguments.length; e++) this.add(arguments[e]);
|
|
5153
5301
|
return this;
|
|
5154
5302
|
}
|
|
5155
|
-
return e === this ? (
|
|
5303
|
+
return e === this ? (U("Object3D.add: object can't be added as a child of itself.", e), this) : (e && e.isObject3D ? (e.removeFromParent(), e.parent = this, this.children.push(e), e.dispatchEvent($i), ta.child = e, this.dispatchEvent(ta), ta.child = null) : U("Object3D.add: object not an instance of THREE.Object3D.", e), this);
|
|
5156
5304
|
}
|
|
5157
5305
|
remove(e) {
|
|
5158
5306
|
if (arguments.length > 1) {
|
|
@@ -5160,7 +5308,7 @@ var Ri = class {
|
|
|
5160
5308
|
return this;
|
|
5161
5309
|
}
|
|
5162
5310
|
let t = this.children.indexOf(e);
|
|
5163
|
-
return t !== -1 && (e.parent = null, this.children.splice(t, 1), e.dispatchEvent(
|
|
5311
|
+
return t !== -1 && (e.parent = null, this.children.splice(t, 1), e.dispatchEvent(ea), na.child = e, this.dispatchEvent(na), na.child = null), this;
|
|
5164
5312
|
}
|
|
5165
5313
|
removeFromParent() {
|
|
5166
5314
|
let e = this.parent;
|
|
@@ -5170,7 +5318,7 @@ var Ri = class {
|
|
|
5170
5318
|
return this.remove(...this.children);
|
|
5171
5319
|
}
|
|
5172
5320
|
attach(e) {
|
|
5173
|
-
return this.updateWorldMatrix(!0, !1),
|
|
5321
|
+
return this.updateWorldMatrix(!0, !1), Gi.copy(this.matrixWorld).invert(), e.parent !== null && (e.parent.updateWorldMatrix(!0, !1), Gi.multiply(e.parent.matrixWorld)), e.applyMatrix4(Gi), e.removeFromParent(), e.parent = this, this.children.push(e), e.updateWorldMatrix(!1, !0), e.dispatchEvent($i), ta.child = e, this.dispatchEvent(ta), ta.child = null, this;
|
|
5174
5322
|
}
|
|
5175
5323
|
getObjectById(e) {
|
|
5176
5324
|
return this.getObjectByProperty("id", e);
|
|
@@ -5195,10 +5343,10 @@ var Ri = class {
|
|
|
5195
5343
|
return this.updateWorldMatrix(!0, !1), e.setFromMatrixPosition(this.matrixWorld);
|
|
5196
5344
|
}
|
|
5197
5345
|
getWorldQuaternion(e) {
|
|
5198
|
-
return this.updateWorldMatrix(!0, !1), this.matrixWorld.decompose(
|
|
5346
|
+
return this.updateWorldMatrix(!0, !1), this.matrixWorld.decompose(qi, e, Ji), e;
|
|
5199
5347
|
}
|
|
5200
5348
|
getWorldScale(e) {
|
|
5201
|
-
return this.updateWorldMatrix(!0, !1), this.matrixWorld.decompose(
|
|
5349
|
+
return this.updateWorldMatrix(!0, !1), this.matrixWorld.decompose(qi, Yi, e), e;
|
|
5202
5350
|
}
|
|
5203
5351
|
getWorldDirection(e) {
|
|
5204
5352
|
this.updateWorldMatrix(!0, !1);
|
|
@@ -5321,8 +5469,8 @@ var Ri = class {
|
|
|
5321
5469
|
return this;
|
|
5322
5470
|
}
|
|
5323
5471
|
};
|
|
5324
|
-
|
|
5325
|
-
var
|
|
5472
|
+
ra.DEFAULT_UP = /*@__PURE__*/ new K(0, 1, 0), ra.DEFAULT_MATRIX_AUTO_UPDATE = !0, ra.DEFAULT_MATRIX_WORLD_AUTO_UPDATE = !0;
|
|
5473
|
+
var ia = {
|
|
5326
5474
|
aliceblue: 15792383,
|
|
5327
5475
|
antiquewhite: 16444375,
|
|
5328
5476
|
aqua: 65535,
|
|
@@ -5471,19 +5619,19 @@ var ta = {
|
|
|
5471
5619
|
whitesmoke: 16119285,
|
|
5472
5620
|
yellow: 16776960,
|
|
5473
5621
|
yellowgreen: 10145074
|
|
5474
|
-
},
|
|
5622
|
+
}, aa = {
|
|
5475
5623
|
h: 0,
|
|
5476
5624
|
s: 0,
|
|
5477
5625
|
l: 0
|
|
5478
|
-
},
|
|
5626
|
+
}, oa = {
|
|
5479
5627
|
h: 0,
|
|
5480
5628
|
s: 0,
|
|
5481
5629
|
l: 0
|
|
5482
5630
|
};
|
|
5483
|
-
function
|
|
5631
|
+
function sa(e, t, n) {
|
|
5484
5632
|
return n < 0 && (n += 1), n > 1 && --n, n < 1 / 6 ? e + (t - e) * 6 * n : n < 1 / 2 ? t : n < 2 / 3 ? e + (t - e) * 6 * (2 / 3 - n) : e;
|
|
5485
5633
|
}
|
|
5486
|
-
var
|
|
5634
|
+
var ca = class {
|
|
5487
5635
|
constructor(e, t, n) {
|
|
5488
5636
|
return this.isColor = !0, this.r = 1, this.g = 1, this.b = 1, this.set(e, t, n);
|
|
5489
5637
|
}
|
|
@@ -5497,23 +5645,23 @@ var aa = class {
|
|
|
5497
5645
|
setScalar(e) {
|
|
5498
5646
|
return this.r = e, this.g = e, this.b = e, this;
|
|
5499
5647
|
}
|
|
5500
|
-
setHex(e, t =
|
|
5501
|
-
return e = Math.floor(e), this.r = (e >> 16 & 255) / 255, this.g = (e >> 8 & 255) / 255, this.b = (e & 255) / 255,
|
|
5648
|
+
setHex(e, t = Qr) {
|
|
5649
|
+
return e = Math.floor(e), this.r = (e >> 16 & 255) / 255, this.g = (e >> 8 & 255) / 255, this.b = (e & 255) / 255, q.colorSpaceToWorking(this, t), this;
|
|
5502
5650
|
}
|
|
5503
|
-
setRGB(e, t, n, r =
|
|
5504
|
-
return this.r = e, this.g = t, this.b = n,
|
|
5651
|
+
setRGB(e, t, n, r = q.workingColorSpace) {
|
|
5652
|
+
return this.r = e, this.g = t, this.b = n, q.colorSpaceToWorking(this, r), this;
|
|
5505
5653
|
}
|
|
5506
|
-
setHSL(e, t, n, r =
|
|
5507
|
-
if (e =
|
|
5654
|
+
setHSL(e, t, n, r = q.workingColorSpace) {
|
|
5655
|
+
if (e = di(e, 1), t = G(t, 0, 1), n = G(n, 0, 1), t === 0) this.r = this.g = this.b = n;
|
|
5508
5656
|
else {
|
|
5509
5657
|
let r = n <= .5 ? n * (1 + t) : n + t - n * t, i = 2 * n - r;
|
|
5510
|
-
this.r =
|
|
5658
|
+
this.r = sa(i, r, e + 1 / 3), this.g = sa(i, r, e), this.b = sa(i, r, e - 1 / 3);
|
|
5511
5659
|
}
|
|
5512
|
-
return
|
|
5660
|
+
return q.colorSpaceToWorking(this, r), this;
|
|
5513
5661
|
}
|
|
5514
|
-
setStyle(e, t =
|
|
5662
|
+
setStyle(e, t = Qr) {
|
|
5515
5663
|
function n(t) {
|
|
5516
|
-
t !== void 0 && parseFloat(t) < 1 &&
|
|
5664
|
+
t !== void 0 && parseFloat(t) < 1 && H("Color: Alpha component of " + e + " will be ignored.");
|
|
5517
5665
|
}
|
|
5518
5666
|
let r;
|
|
5519
5667
|
if (r = /^(\w+)\(([^\)]*)\)/.exec(e)) {
|
|
@@ -5528,19 +5676,19 @@ var aa = class {
|
|
|
5528
5676
|
case "hsla":
|
|
5529
5677
|
if (i = /^\s*(\d*\.?\d+)\s*,\s*(\d*\.?\d+)\%\s*,\s*(\d*\.?\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(o)) return n(i[4]), this.setHSL(parseFloat(i[1]) / 360, parseFloat(i[2]) / 100, parseFloat(i[3]) / 100, t);
|
|
5530
5678
|
break;
|
|
5531
|
-
default:
|
|
5679
|
+
default: H("Color: Unknown color model " + e);
|
|
5532
5680
|
}
|
|
5533
5681
|
} else if (r = /^\#([A-Fa-f\d]+)$/.exec(e)) {
|
|
5534
5682
|
let n = r[1], i = n.length;
|
|
5535
5683
|
if (i === 3) return this.setRGB(parseInt(n.charAt(0), 16) / 15, parseInt(n.charAt(1), 16) / 15, parseInt(n.charAt(2), 16) / 15, t);
|
|
5536
5684
|
if (i === 6) return this.setHex(parseInt(n, 16), t);
|
|
5537
|
-
|
|
5685
|
+
H("Color: Invalid hex color " + e);
|
|
5538
5686
|
} else if (e && e.length > 0) return this.setColorName(e, t);
|
|
5539
5687
|
return this;
|
|
5540
5688
|
}
|
|
5541
|
-
setColorName(e, t =
|
|
5542
|
-
let n =
|
|
5543
|
-
return n === void 0 ?
|
|
5689
|
+
setColorName(e, t = Qr) {
|
|
5690
|
+
let n = ia[e.toLowerCase()];
|
|
5691
|
+
return n === void 0 ? H("Color: Unknown color " + e) : this.setHex(n, t), this;
|
|
5544
5692
|
}
|
|
5545
5693
|
clone() {
|
|
5546
5694
|
return new this.constructor(this.r, this.g, this.b);
|
|
@@ -5549,10 +5697,10 @@ var aa = class {
|
|
|
5549
5697
|
return this.r = e.r, this.g = e.g, this.b = e.b, this;
|
|
5550
5698
|
}
|
|
5551
5699
|
copySRGBToLinear(e) {
|
|
5552
|
-
return this.r =
|
|
5700
|
+
return this.r = Si(e.r), this.g = Si(e.g), this.b = Si(e.b), this;
|
|
5553
5701
|
}
|
|
5554
5702
|
copyLinearToSRGB(e) {
|
|
5555
|
-
return this.r =
|
|
5703
|
+
return this.r = Ci(e.r), this.g = Ci(e.g), this.b = Ci(e.b), this;
|
|
5556
5704
|
}
|
|
5557
5705
|
convertSRGBToLinear() {
|
|
5558
5706
|
return this.copySRGBToLinear(this), this;
|
|
@@ -5560,15 +5708,15 @@ var aa = class {
|
|
|
5560
5708
|
convertLinearToSRGB() {
|
|
5561
5709
|
return this.copyLinearToSRGB(this), this;
|
|
5562
5710
|
}
|
|
5563
|
-
getHex(e =
|
|
5564
|
-
return
|
|
5711
|
+
getHex(e = Qr) {
|
|
5712
|
+
return q.workingToColorSpace(X.copy(this), e), Math.round(G(X.r * 255, 0, 255)) * 65536 + Math.round(G(X.g * 255, 0, 255)) * 256 + Math.round(G(X.b * 255, 0, 255));
|
|
5565
5713
|
}
|
|
5566
|
-
getHexString(e =
|
|
5714
|
+
getHexString(e = Qr) {
|
|
5567
5715
|
return ("000000" + this.getHex(e).toString(16)).slice(-6);
|
|
5568
5716
|
}
|
|
5569
|
-
getHSL(e, t =
|
|
5570
|
-
|
|
5571
|
-
let n =
|
|
5717
|
+
getHSL(e, t = q.workingColorSpace) {
|
|
5718
|
+
q.workingToColorSpace(X.copy(this), t);
|
|
5719
|
+
let n = X.r, r = X.g, i = X.b, a = Math.max(n, r, i), o = Math.min(n, r, i), s, c, l = (o + a) / 2;
|
|
5572
5720
|
if (o === a) s = 0, c = 0;
|
|
5573
5721
|
else {
|
|
5574
5722
|
let e = a - o;
|
|
@@ -5587,16 +5735,16 @@ var aa = class {
|
|
|
5587
5735
|
}
|
|
5588
5736
|
return e.h = s, e.s = c, e.l = l, e;
|
|
5589
5737
|
}
|
|
5590
|
-
getRGB(e, t =
|
|
5591
|
-
return
|
|
5738
|
+
getRGB(e, t = q.workingColorSpace) {
|
|
5739
|
+
return q.workingToColorSpace(X.copy(this), t), e.r = X.r, e.g = X.g, e.b = X.b, e;
|
|
5592
5740
|
}
|
|
5593
|
-
getStyle(e =
|
|
5594
|
-
|
|
5595
|
-
let t =
|
|
5741
|
+
getStyle(e = Qr) {
|
|
5742
|
+
q.workingToColorSpace(X.copy(this), e);
|
|
5743
|
+
let t = X.r, n = X.g, r = X.b;
|
|
5596
5744
|
return e === "srgb" ? `rgb(${Math.round(t * 255)},${Math.round(n * 255)},${Math.round(r * 255)})` : `color(${e} ${t.toFixed(3)} ${n.toFixed(3)} ${r.toFixed(3)})`;
|
|
5597
5745
|
}
|
|
5598
5746
|
offsetHSL(e, t, n) {
|
|
5599
|
-
return this.getHSL(
|
|
5747
|
+
return this.getHSL(aa), this.setHSL(aa.h + e, aa.s + t, aa.l + n);
|
|
5600
5748
|
}
|
|
5601
5749
|
add(e) {
|
|
5602
5750
|
return this.r += e.r, this.g += e.g, this.b += e.b, this;
|
|
@@ -5623,8 +5771,8 @@ var aa = class {
|
|
|
5623
5771
|
return this.r = e.r + (t.r - e.r) * n, this.g = e.g + (t.g - e.g) * n, this.b = e.b + (t.b - e.b) * n, this;
|
|
5624
5772
|
}
|
|
5625
5773
|
lerpHSL(e, t) {
|
|
5626
|
-
this.getHSL(
|
|
5627
|
-
let n =
|
|
5774
|
+
this.getHSL(aa), e.getHSL(oa);
|
|
5775
|
+
let n = fi(aa.h, oa.h, t), r = fi(aa.s, oa.s, t), i = fi(aa.l, oa.l, t);
|
|
5628
5776
|
return this.setHSL(n, r, i), this;
|
|
5629
5777
|
}
|
|
5630
5778
|
setFromVector3(e) {
|
|
@@ -5652,10 +5800,10 @@ var aa = class {
|
|
|
5652
5800
|
*[Symbol.iterator]() {
|
|
5653
5801
|
yield this.r, yield this.g, yield this.b;
|
|
5654
5802
|
}
|
|
5655
|
-
},
|
|
5656
|
-
|
|
5657
|
-
var
|
|
5658
|
-
constructor(e = new
|
|
5803
|
+
}, X = /*@__PURE__*/ new ca();
|
|
5804
|
+
ca.NAMES = ia;
|
|
5805
|
+
var la = class {
|
|
5806
|
+
constructor(e = new K(Infinity, Infinity, Infinity), t = new K(-Infinity, -Infinity, -Infinity)) {
|
|
5659
5807
|
this.isBox3 = !0, this.min = e, this.max = t;
|
|
5660
5808
|
}
|
|
5661
5809
|
set(e, t) {
|
|
@@ -5663,12 +5811,12 @@ var oa = class {
|
|
|
5663
5811
|
}
|
|
5664
5812
|
setFromArray(e) {
|
|
5665
5813
|
this.makeEmpty();
|
|
5666
|
-
for (let t = 0, n = e.length; t < n; t += 3) this.expandByPoint(
|
|
5814
|
+
for (let t = 0, n = e.length; t < n; t += 3) this.expandByPoint(da.fromArray(e, t));
|
|
5667
5815
|
return this;
|
|
5668
5816
|
}
|
|
5669
5817
|
setFromBufferAttribute(e) {
|
|
5670
5818
|
this.makeEmpty();
|
|
5671
|
-
for (let t = 0, n = e.count; t < n; t++) this.expandByPoint(
|
|
5819
|
+
for (let t = 0, n = e.count; t < n; t++) this.expandByPoint(da.fromBufferAttribute(e, t));
|
|
5672
5820
|
return this;
|
|
5673
5821
|
}
|
|
5674
5822
|
setFromPoints(e) {
|
|
@@ -5677,7 +5825,7 @@ var oa = class {
|
|
|
5677
5825
|
return this;
|
|
5678
5826
|
}
|
|
5679
5827
|
setFromCenterAndSize(e, t) {
|
|
5680
|
-
let n =
|
|
5828
|
+
let n = da.copy(t).multiplyScalar(.5);
|
|
5681
5829
|
return this.min.copy(e).sub(n), this.max.copy(e).add(n), this;
|
|
5682
5830
|
}
|
|
5683
5831
|
setFromObject(e, t = !1) {
|
|
@@ -5715,8 +5863,8 @@ var oa = class {
|
|
|
5715
5863
|
let n = e.geometry;
|
|
5716
5864
|
if (n !== void 0) {
|
|
5717
5865
|
let r = n.getAttribute("position");
|
|
5718
|
-
if (t === !0 && r !== void 0 && e.isInstancedMesh !== !0) for (let t = 0, n = r.count; t < n; t++) e.isMesh === !0 ? e.getVertexPosition(t,
|
|
5719
|
-
else e.boundingBox === void 0 ? (n.boundingBox === null && n.computeBoundingBox(),
|
|
5866
|
+
if (t === !0 && r !== void 0 && e.isInstancedMesh !== !0) for (let t = 0, n = r.count; t < n; t++) e.isMesh === !0 ? e.getVertexPosition(t, da) : da.fromBufferAttribute(r, t), da.applyMatrix4(e.matrixWorld), this.expandByPoint(da);
|
|
5867
|
+
else e.boundingBox === void 0 ? (n.boundingBox === null && n.computeBoundingBox(), fa.copy(n.boundingBox)) : (e.boundingBox === null && e.computeBoundingBox(), fa.copy(e.boundingBox)), fa.applyMatrix4(e.matrixWorld), this.union(fa);
|
|
5720
5868
|
}
|
|
5721
5869
|
let r = e.children;
|
|
5722
5870
|
for (let e = 0, n = r.length; e < n; e++) this.expandByObject(r[e], t);
|
|
@@ -5735,7 +5883,7 @@ var oa = class {
|
|
|
5735
5883
|
return e.max.x >= this.min.x && e.min.x <= this.max.x && e.max.y >= this.min.y && e.min.y <= this.max.y && e.max.z >= this.min.z && e.min.z <= this.max.z;
|
|
5736
5884
|
}
|
|
5737
5885
|
intersectsSphere(e) {
|
|
5738
|
-
return this.clampPoint(e.center,
|
|
5886
|
+
return this.clampPoint(e.center, da), da.distanceToSquared(e.center) <= e.radius * e.radius;
|
|
5739
5887
|
}
|
|
5740
5888
|
intersectsPlane(e) {
|
|
5741
5889
|
let t, n;
|
|
@@ -5743,37 +5891,37 @@ var oa = class {
|
|
|
5743
5891
|
}
|
|
5744
5892
|
intersectsTriangle(e) {
|
|
5745
5893
|
if (this.isEmpty()) return !1;
|
|
5746
|
-
this.getCenter(
|
|
5894
|
+
this.getCenter(ya), ba.subVectors(this.max, ya), pa.subVectors(e.a, ya), ma.subVectors(e.b, ya), ha.subVectors(e.c, ya), ga.subVectors(ma, pa), _a.subVectors(ha, ma), va.subVectors(pa, ha);
|
|
5747
5895
|
let t = [
|
|
5748
5896
|
0,
|
|
5749
|
-
-
|
|
5750
|
-
|
|
5897
|
+
-ga.z,
|
|
5898
|
+
ga.y,
|
|
5751
5899
|
0,
|
|
5752
|
-
-
|
|
5753
|
-
|
|
5900
|
+
-_a.z,
|
|
5901
|
+
_a.y,
|
|
5754
5902
|
0,
|
|
5755
|
-
-
|
|
5756
|
-
|
|
5757
|
-
|
|
5903
|
+
-va.z,
|
|
5904
|
+
va.y,
|
|
5905
|
+
ga.z,
|
|
5758
5906
|
0,
|
|
5759
|
-
-
|
|
5760
|
-
|
|
5907
|
+
-ga.x,
|
|
5908
|
+
_a.z,
|
|
5761
5909
|
0,
|
|
5762
|
-
-
|
|
5763
|
-
|
|
5910
|
+
-_a.x,
|
|
5911
|
+
va.z,
|
|
5764
5912
|
0,
|
|
5765
|
-
-
|
|
5766
|
-
-
|
|
5767
|
-
|
|
5913
|
+
-va.x,
|
|
5914
|
+
-ga.y,
|
|
5915
|
+
ga.x,
|
|
5768
5916
|
0,
|
|
5769
|
-
-
|
|
5770
|
-
|
|
5917
|
+
-_a.y,
|
|
5918
|
+
_a.x,
|
|
5771
5919
|
0,
|
|
5772
|
-
-
|
|
5773
|
-
|
|
5920
|
+
-va.y,
|
|
5921
|
+
va.x,
|
|
5774
5922
|
0
|
|
5775
5923
|
];
|
|
5776
|
-
return !
|
|
5924
|
+
return !Ca(t, pa, ma, ha, ba) || (t = [
|
|
5777
5925
|
1,
|
|
5778
5926
|
0,
|
|
5779
5927
|
0,
|
|
@@ -5783,20 +5931,20 @@ var oa = class {
|
|
|
5783
5931
|
0,
|
|
5784
5932
|
0,
|
|
5785
5933
|
1
|
|
5786
|
-
], !
|
|
5787
|
-
|
|
5788
|
-
|
|
5789
|
-
|
|
5790
|
-
],
|
|
5934
|
+
], !Ca(t, pa, ma, ha, ba)) ? !1 : (xa.crossVectors(ga, _a), t = [
|
|
5935
|
+
xa.x,
|
|
5936
|
+
xa.y,
|
|
5937
|
+
xa.z
|
|
5938
|
+
], Ca(t, pa, ma, ha, ba));
|
|
5791
5939
|
}
|
|
5792
5940
|
clampPoint(e, t) {
|
|
5793
5941
|
return t.copy(e).clamp(this.min, this.max);
|
|
5794
5942
|
}
|
|
5795
5943
|
distanceToPoint(e) {
|
|
5796
|
-
return this.clampPoint(e,
|
|
5944
|
+
return this.clampPoint(e, da).distanceTo(e);
|
|
5797
5945
|
}
|
|
5798
5946
|
getBoundingSphere(e) {
|
|
5799
|
-
return this.isEmpty() ? e.makeEmpty() : (this.getCenter(e.center), e.radius = this.getSize(
|
|
5947
|
+
return this.isEmpty() ? e.makeEmpty() : (this.getCenter(e.center), e.radius = this.getSize(da).length() * .5), e;
|
|
5800
5948
|
}
|
|
5801
5949
|
intersect(e) {
|
|
5802
5950
|
return this.min.max(e.min), this.max.min(e.max), this.isEmpty() && this.makeEmpty(), this;
|
|
@@ -5805,7 +5953,7 @@ var oa = class {
|
|
|
5805
5953
|
return this.min.min(e.min), this.max.max(e.max), this;
|
|
5806
5954
|
}
|
|
5807
5955
|
applyMatrix4(e) {
|
|
5808
|
-
return this.isEmpty() ? this : (
|
|
5956
|
+
return this.isEmpty() ? this : (ua[0].set(this.min.x, this.min.y, this.min.z).applyMatrix4(e), ua[1].set(this.min.x, this.min.y, this.max.z).applyMatrix4(e), ua[2].set(this.min.x, this.max.y, this.min.z).applyMatrix4(e), ua[3].set(this.min.x, this.max.y, this.max.z).applyMatrix4(e), ua[4].set(this.max.x, this.min.y, this.min.z).applyMatrix4(e), ua[5].set(this.max.x, this.min.y, this.max.z).applyMatrix4(e), ua[6].set(this.max.x, this.max.y, this.min.z).applyMatrix4(e), ua[7].set(this.max.x, this.max.y, this.max.z).applyMatrix4(e), this.setFromPoints(ua), this);
|
|
5809
5957
|
}
|
|
5810
5958
|
translate(e) {
|
|
5811
5959
|
return this.min.add(e), this.max.add(e), this;
|
|
@@ -5822,28 +5970,28 @@ var oa = class {
|
|
|
5822
5970
|
fromJSON(e) {
|
|
5823
5971
|
return this.min.fromArray(e.min), this.max.fromArray(e.max), this;
|
|
5824
5972
|
}
|
|
5825
|
-
},
|
|
5826
|
-
/*@__PURE__*/ new
|
|
5827
|
-
/*@__PURE__*/ new
|
|
5828
|
-
/*@__PURE__*/ new
|
|
5829
|
-
/*@__PURE__*/ new
|
|
5830
|
-
/*@__PURE__*/ new
|
|
5831
|
-
/*@__PURE__*/ new
|
|
5832
|
-
/*@__PURE__*/ new
|
|
5833
|
-
/*@__PURE__*/ new
|
|
5834
|
-
],
|
|
5835
|
-
function
|
|
5973
|
+
}, ua = [
|
|
5974
|
+
/*@__PURE__*/ new K(),
|
|
5975
|
+
/*@__PURE__*/ new K(),
|
|
5976
|
+
/*@__PURE__*/ new K(),
|
|
5977
|
+
/*@__PURE__*/ new K(),
|
|
5978
|
+
/*@__PURE__*/ new K(),
|
|
5979
|
+
/*@__PURE__*/ new K(),
|
|
5980
|
+
/*@__PURE__*/ new K(),
|
|
5981
|
+
/*@__PURE__*/ new K()
|
|
5982
|
+
], da = /*@__PURE__*/ new K(), fa = /*@__PURE__*/ new la(), pa = /*@__PURE__*/ new K(), ma = /*@__PURE__*/ new K(), ha = /*@__PURE__*/ new K(), ga = /*@__PURE__*/ new K(), _a = /*@__PURE__*/ new K(), va = /*@__PURE__*/ new K(), ya = /*@__PURE__*/ new K(), ba = /*@__PURE__*/ new K(), xa = /*@__PURE__*/ new K(), Sa = /*@__PURE__*/ new K();
|
|
5983
|
+
function Ca(e, t, n, r, i) {
|
|
5836
5984
|
for (let a = 0, o = e.length - 3; a <= o; a += 3) {
|
|
5837
|
-
|
|
5838
|
-
let o = i.x * Math.abs(
|
|
5985
|
+
Sa.fromArray(e, a);
|
|
5986
|
+
let o = i.x * Math.abs(Sa.x) + i.y * Math.abs(Sa.y) + i.z * Math.abs(Sa.z), s = t.dot(Sa), c = n.dot(Sa), l = r.dot(Sa);
|
|
5839
5987
|
if (Math.max(-Math.max(s, c, l), Math.min(s, c, l)) > o) return !1;
|
|
5840
5988
|
}
|
|
5841
5989
|
return !0;
|
|
5842
5990
|
}
|
|
5843
|
-
function
|
|
5991
|
+
function wa(e, t) {
|
|
5844
5992
|
return !e || e.constructor === t ? e : typeof t.BYTES_PER_ELEMENT == "number" ? new t(e) : Array.prototype.slice.call(e);
|
|
5845
5993
|
}
|
|
5846
|
-
var
|
|
5994
|
+
var Ta = class {
|
|
5847
5995
|
constructor(e, t, n, r) {
|
|
5848
5996
|
this.parameterPositions = e, this._cachedIndex = 0, this.resultBuffer = r === void 0 ? new t.constructor(n) : r, this.sampleValues = t, this.valueSize = n, this.settings = null, this.DefaultSettings_ = {};
|
|
5849
5997
|
}
|
|
@@ -5901,29 +6049,29 @@ var xa = class {
|
|
|
5901
6049
|
throw Error("call to abstract method");
|
|
5902
6050
|
}
|
|
5903
6051
|
intervalChanged_() {}
|
|
5904
|
-
},
|
|
6052
|
+
}, Ea = class extends Ta {
|
|
5905
6053
|
constructor(e, t, n, r) {
|
|
5906
6054
|
super(e, t, n, r), this._weightPrev = -0, this._offsetPrev = -0, this._weightNext = -0, this._offsetNext = -0, this.DefaultSettings_ = {
|
|
5907
|
-
endingStart:
|
|
5908
|
-
endingEnd:
|
|
6055
|
+
endingStart: Yr,
|
|
6056
|
+
endingEnd: Yr
|
|
5909
6057
|
};
|
|
5910
6058
|
}
|
|
5911
6059
|
intervalChanged_(e, t, n) {
|
|
5912
6060
|
let r = this.parameterPositions, i = e - 2, a = e + 1, o = r[i], s = r[a];
|
|
5913
6061
|
if (o === void 0) switch (this.getSettings_().endingStart) {
|
|
5914
|
-
case
|
|
6062
|
+
case Xr:
|
|
5915
6063
|
i = e, o = 2 * t - n;
|
|
5916
6064
|
break;
|
|
5917
|
-
case
|
|
6065
|
+
case Zr:
|
|
5918
6066
|
i = r.length - 2, o = t + r[i] - r[i + 1];
|
|
5919
6067
|
break;
|
|
5920
6068
|
default: i = e, o = n;
|
|
5921
6069
|
}
|
|
5922
6070
|
if (s === void 0) switch (this.getSettings_().endingEnd) {
|
|
5923
|
-
case
|
|
6071
|
+
case Xr:
|
|
5924
6072
|
a = e, s = 2 * n - t;
|
|
5925
6073
|
break;
|
|
5926
|
-
case
|
|
6074
|
+
case Zr:
|
|
5927
6075
|
a = 1, s = n + r[1] - r[0];
|
|
5928
6076
|
break;
|
|
5929
6077
|
default: a = e - 1, s = t;
|
|
@@ -5936,7 +6084,7 @@ var xa = class {
|
|
|
5936
6084
|
for (let e = 0; e !== o; ++e) i[e] = g * a[l + e] + _ * a[c + e] + v * a[s + e] + y * a[u + e];
|
|
5937
6085
|
return i;
|
|
5938
6086
|
}
|
|
5939
|
-
},
|
|
6087
|
+
}, Da = class extends Ta {
|
|
5940
6088
|
constructor(e, t, n, r) {
|
|
5941
6089
|
super(e, t, n, r);
|
|
5942
6090
|
}
|
|
@@ -5945,14 +6093,14 @@ var xa = class {
|
|
|
5945
6093
|
for (let e = 0; e !== o; ++e) i[e] = a[c + e] * u + a[s + e] * l;
|
|
5946
6094
|
return i;
|
|
5947
6095
|
}
|
|
5948
|
-
},
|
|
6096
|
+
}, Oa = class extends Ta {
|
|
5949
6097
|
constructor(e, t, n, r) {
|
|
5950
6098
|
super(e, t, n, r);
|
|
5951
6099
|
}
|
|
5952
6100
|
interpolate_(e) {
|
|
5953
6101
|
return this.copySampleValue_(e - 1);
|
|
5954
6102
|
}
|
|
5955
|
-
},
|
|
6103
|
+
}, ka = class extends Ta {
|
|
5956
6104
|
interpolate_(e, t, n, r) {
|
|
5957
6105
|
let i = this.resultBuffer, a = this.sampleValues, o = this.valueSize, s = e * o, c = s - o, l = this.settings || this.DefaultSettings_, u = l.inTangents, d = l.outTangents;
|
|
5958
6106
|
if (!u || !d) {
|
|
@@ -5975,11 +6123,11 @@ var xa = class {
|
|
|
5975
6123
|
}
|
|
5976
6124
|
return i;
|
|
5977
6125
|
}
|
|
5978
|
-
},
|
|
6126
|
+
}, Aa = class {
|
|
5979
6127
|
constructor(e, t, n, r) {
|
|
5980
6128
|
if (e === void 0) throw Error("THREE.KeyframeTrack: track name is undefined");
|
|
5981
6129
|
if (t === void 0 || t.length === 0) throw Error("THREE.KeyframeTrack: no keyframes in track named " + e);
|
|
5982
|
-
this.name = e, this.times =
|
|
6130
|
+
this.name = e, this.times = wa(t, this.TimeBufferType), this.values = wa(n, this.ValueBufferType), this.setInterpolation(r || this.DefaultInterpolation);
|
|
5983
6131
|
}
|
|
5984
6132
|
static toJSON(e) {
|
|
5985
6133
|
let t = e.constructor, n;
|
|
@@ -5987,8 +6135,8 @@ var xa = class {
|
|
|
5987
6135
|
else {
|
|
5988
6136
|
n = {
|
|
5989
6137
|
name: e.name,
|
|
5990
|
-
times:
|
|
5991
|
-
values:
|
|
6138
|
+
times: wa(e.times, Array),
|
|
6139
|
+
values: wa(e.values, Array)
|
|
5992
6140
|
};
|
|
5993
6141
|
let t = e.getInterpolation();
|
|
5994
6142
|
t !== e.DefaultInterpolation && (n.interpolation = t);
|
|
@@ -5996,31 +6144,31 @@ var xa = class {
|
|
|
5996
6144
|
return n.type = e.ValueTypeName, n;
|
|
5997
6145
|
}
|
|
5998
6146
|
InterpolantFactoryMethodDiscrete(e) {
|
|
5999
|
-
return new
|
|
6147
|
+
return new Oa(this.times, this.values, this.getValueSize(), e);
|
|
6000
6148
|
}
|
|
6001
6149
|
InterpolantFactoryMethodLinear(e) {
|
|
6002
|
-
return new
|
|
6150
|
+
return new Da(this.times, this.values, this.getValueSize(), e);
|
|
6003
6151
|
}
|
|
6004
6152
|
InterpolantFactoryMethodSmooth(e) {
|
|
6005
|
-
return new
|
|
6153
|
+
return new Ea(this.times, this.values, this.getValueSize(), e);
|
|
6006
6154
|
}
|
|
6007
6155
|
InterpolantFactoryMethodBezier(e) {
|
|
6008
|
-
let t = new
|
|
6156
|
+
let t = new ka(this.times, this.values, this.getValueSize(), e);
|
|
6009
6157
|
return this.settings && (t.settings = this.settings), t;
|
|
6010
6158
|
}
|
|
6011
6159
|
setInterpolation(e) {
|
|
6012
6160
|
let t;
|
|
6013
6161
|
switch (e) {
|
|
6014
|
-
case
|
|
6162
|
+
case Gr:
|
|
6015
6163
|
t = this.InterpolantFactoryMethodDiscrete;
|
|
6016
6164
|
break;
|
|
6017
|
-
case
|
|
6165
|
+
case Kr:
|
|
6018
6166
|
t = this.InterpolantFactoryMethodLinear;
|
|
6019
6167
|
break;
|
|
6020
|
-
case
|
|
6168
|
+
case qr:
|
|
6021
6169
|
t = this.InterpolantFactoryMethodSmooth;
|
|
6022
6170
|
break;
|
|
6023
|
-
case
|
|
6171
|
+
case Jr:
|
|
6024
6172
|
t = this.InterpolantFactoryMethodBezier;
|
|
6025
6173
|
break;
|
|
6026
6174
|
}
|
|
@@ -6028,16 +6176,16 @@ var xa = class {
|
|
|
6028
6176
|
let t = "unsupported interpolation for " + this.ValueTypeName + " keyframe track named " + this.name;
|
|
6029
6177
|
if (this.createInterpolant === void 0) if (e !== this.DefaultInterpolation) this.setInterpolation(this.DefaultInterpolation);
|
|
6030
6178
|
else throw Error(t);
|
|
6031
|
-
return
|
|
6179
|
+
return H("KeyframeTrack:", t), this;
|
|
6032
6180
|
}
|
|
6033
6181
|
return this.createInterpolant = t, this;
|
|
6034
6182
|
}
|
|
6035
6183
|
getInterpolation() {
|
|
6036
6184
|
switch (this.createInterpolant) {
|
|
6037
|
-
case this.InterpolantFactoryMethodDiscrete: return
|
|
6038
|
-
case this.InterpolantFactoryMethodLinear: return
|
|
6039
|
-
case this.InterpolantFactoryMethodSmooth: return
|
|
6040
|
-
case this.InterpolantFactoryMethodBezier: return
|
|
6185
|
+
case this.InterpolantFactoryMethodDiscrete: return Gr;
|
|
6186
|
+
case this.InterpolantFactoryMethodLinear: return Kr;
|
|
6187
|
+
case this.InterpolantFactoryMethodSmooth: return qr;
|
|
6188
|
+
case this.InterpolantFactoryMethodBezier: return Jr;
|
|
6041
6189
|
}
|
|
6042
6190
|
}
|
|
6043
6191
|
getValueSize() {
|
|
@@ -6070,33 +6218,33 @@ var xa = class {
|
|
|
6070
6218
|
}
|
|
6071
6219
|
validate() {
|
|
6072
6220
|
let e = !0, t = this.getValueSize();
|
|
6073
|
-
t - Math.floor(t) !== 0 && (
|
|
6221
|
+
t - Math.floor(t) !== 0 && (U("KeyframeTrack: Invalid value size in track.", this), e = !1);
|
|
6074
6222
|
let n = this.times, r = this.values, i = n.length;
|
|
6075
|
-
i === 0 && (
|
|
6223
|
+
i === 0 && (U("KeyframeTrack: Track is empty.", this), e = !1);
|
|
6076
6224
|
let a = null;
|
|
6077
6225
|
for (let t = 0; t !== i; t++) {
|
|
6078
6226
|
let r = n[t];
|
|
6079
6227
|
if (typeof r == "number" && isNaN(r)) {
|
|
6080
|
-
|
|
6228
|
+
U("KeyframeTrack: Time is not a valid number.", this, t, r), e = !1;
|
|
6081
6229
|
break;
|
|
6082
6230
|
}
|
|
6083
6231
|
if (a !== null && a > r) {
|
|
6084
|
-
|
|
6232
|
+
U("KeyframeTrack: Out of order keys.", this, t, r, a), e = !1;
|
|
6085
6233
|
break;
|
|
6086
6234
|
}
|
|
6087
6235
|
a = r;
|
|
6088
6236
|
}
|
|
6089
|
-
if (r !== void 0 &&
|
|
6237
|
+
if (r !== void 0 && ri(r)) for (let t = 0, n = r.length; t !== n; ++t) {
|
|
6090
6238
|
let n = r[t];
|
|
6091
6239
|
if (isNaN(n)) {
|
|
6092
|
-
|
|
6240
|
+
U("KeyframeTrack: Value is not a valid number.", this, t, n), e = !1;
|
|
6093
6241
|
break;
|
|
6094
6242
|
}
|
|
6095
6243
|
}
|
|
6096
6244
|
return e;
|
|
6097
6245
|
}
|
|
6098
6246
|
optimize() {
|
|
6099
|
-
let e = this.times.slice(), t = this.values.slice(), n = this.getValueSize(), r = this.getInterpolation() ===
|
|
6247
|
+
let e = this.times.slice(), t = this.values.slice(), n = this.getValueSize(), r = this.getInterpolation() === qr, i = e.length - 1, a = 1;
|
|
6100
6248
|
for (let o = 1; o < i; ++o) {
|
|
6101
6249
|
let i = !1, s = e[o];
|
|
6102
6250
|
if (s !== e[o + 1] && (o !== 1 || s !== e[0])) if (r) i = !0;
|
|
@@ -6131,56 +6279,56 @@ var xa = class {
|
|
|
6131
6279
|
return r.createInterpolant = this.createInterpolant, r;
|
|
6132
6280
|
}
|
|
6133
6281
|
};
|
|
6134
|
-
|
|
6135
|
-
var
|
|
6282
|
+
Aa.prototype.ValueTypeName = "", Aa.prototype.TimeBufferType = Float32Array, Aa.prototype.ValueBufferType = Float32Array, Aa.prototype.DefaultInterpolation = Kr;
|
|
6283
|
+
var ja = class extends Aa {
|
|
6136
6284
|
constructor(e, t, n) {
|
|
6137
6285
|
super(e, t, n);
|
|
6138
6286
|
}
|
|
6139
6287
|
};
|
|
6140
|
-
|
|
6141
|
-
var
|
|
6288
|
+
ja.prototype.ValueTypeName = "bool", ja.prototype.ValueBufferType = Array, ja.prototype.DefaultInterpolation = Gr, ja.prototype.InterpolantFactoryMethodLinear = void 0, ja.prototype.InterpolantFactoryMethodSmooth = void 0;
|
|
6289
|
+
var Ma = class extends Aa {
|
|
6142
6290
|
constructor(e, t, n, r) {
|
|
6143
6291
|
super(e, t, n, r);
|
|
6144
6292
|
}
|
|
6145
6293
|
};
|
|
6146
|
-
|
|
6147
|
-
var
|
|
6294
|
+
Ma.prototype.ValueTypeName = "color";
|
|
6295
|
+
var Na = class extends Aa {
|
|
6148
6296
|
constructor(e, t, n, r) {
|
|
6149
6297
|
super(e, t, n, r);
|
|
6150
6298
|
}
|
|
6151
6299
|
};
|
|
6152
|
-
|
|
6153
|
-
var
|
|
6300
|
+
Na.prototype.ValueTypeName = "number";
|
|
6301
|
+
var Pa = class extends Ta {
|
|
6154
6302
|
constructor(e, t, n, r) {
|
|
6155
6303
|
super(e, t, n, r);
|
|
6156
6304
|
}
|
|
6157
6305
|
interpolate_(e, t, n, r) {
|
|
6158
6306
|
let i = this.resultBuffer, a = this.sampleValues, o = this.valueSize, s = (n - t) / (r - t), c = e * o;
|
|
6159
|
-
for (let e = c + o; c !== e; c += 4)
|
|
6307
|
+
for (let e = c + o; c !== e; c += 4) mi.slerpFlat(i, 0, a, c - o, a, c, s);
|
|
6160
6308
|
return i;
|
|
6161
6309
|
}
|
|
6162
|
-
},
|
|
6310
|
+
}, Fa = class extends Aa {
|
|
6163
6311
|
constructor(e, t, n, r) {
|
|
6164
6312
|
super(e, t, n, r);
|
|
6165
6313
|
}
|
|
6166
6314
|
InterpolantFactoryMethodLinear(e) {
|
|
6167
|
-
return new
|
|
6315
|
+
return new Pa(this.times, this.values, this.getValueSize(), e);
|
|
6168
6316
|
}
|
|
6169
6317
|
};
|
|
6170
|
-
|
|
6171
|
-
var
|
|
6318
|
+
Fa.prototype.ValueTypeName = "quaternion", Fa.prototype.InterpolantFactoryMethodSmooth = void 0;
|
|
6319
|
+
var Ia = class extends Aa {
|
|
6172
6320
|
constructor(e, t, n) {
|
|
6173
6321
|
super(e, t, n);
|
|
6174
6322
|
}
|
|
6175
6323
|
};
|
|
6176
|
-
|
|
6177
|
-
var
|
|
6324
|
+
Ia.prototype.ValueTypeName = "string", Ia.prototype.ValueBufferType = Array, Ia.prototype.DefaultInterpolation = Gr, Ia.prototype.InterpolantFactoryMethodLinear = void 0, Ia.prototype.InterpolantFactoryMethodSmooth = void 0;
|
|
6325
|
+
var La = class extends Aa {
|
|
6178
6326
|
constructor(e, t, n, r) {
|
|
6179
6327
|
super(e, t, n, r);
|
|
6180
6328
|
}
|
|
6181
6329
|
};
|
|
6182
|
-
|
|
6183
|
-
var
|
|
6330
|
+
La.prototype.ValueTypeName = "vector";
|
|
6331
|
+
var Ra = /*@__PURE__*/ new class {
|
|
6184
6332
|
constructor(e, t, n) {
|
|
6185
6333
|
let r = this, i = !1, a = 0, o = 0, s, c = [];
|
|
6186
6334
|
this.onStart = void 0, this.onLoad = e, this.onProgress = t, this.onError = n, this._abortController = null, this.itemStart = function(e) {
|
|
@@ -6211,9 +6359,9 @@ var Pa = /*@__PURE__*/ new class {
|
|
|
6211
6359
|
get abortController() {
|
|
6212
6360
|
return this._abortController ||= new AbortController(), this._abortController;
|
|
6213
6361
|
}
|
|
6214
|
-
}(),
|
|
6362
|
+
}(), za = class {
|
|
6215
6363
|
constructor(e) {
|
|
6216
|
-
this.manager = e === void 0 ?
|
|
6364
|
+
this.manager = e === void 0 ? Ra : e, this.crossOrigin = "anonymous", this.withCredentials = !1, this.path = "", this.resourcePath = "", this.requestHeader = {}, typeof __THREE_DEVTOOLS__ < "u" && __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("observe", { detail: this }));
|
|
6217
6365
|
}
|
|
6218
6366
|
load() {}
|
|
6219
6367
|
loadAsync(e, t) {
|
|
@@ -6242,13 +6390,13 @@ var Pa = /*@__PURE__*/ new class {
|
|
|
6242
6390
|
return this;
|
|
6243
6391
|
}
|
|
6244
6392
|
};
|
|
6245
|
-
|
|
6246
|
-
var
|
|
6393
|
+
za.DEFAULT_MATERIAL_NAME = "__DEFAULT";
|
|
6394
|
+
var Ba = "\\[\\]\\.:\\/", Va = /* @__PURE__ */ RegExp("[\\[\\]\\.:\\/]", "g"), Ha = "[^\\[\\]\\.:\\/]", Ua = "[^" + Ba.replace("\\.", "") + "]", Wa = /*@__PURE__*/ "((?:WC+[\\/:])*)".replace("WC", Ha), Ga = /*@__PURE__*/ "(WCOD+)?".replace("WCOD", Ua), Ka = /*@__PURE__*/ "(?:\\.(WC+)(?:\\[(.+)\\])?)?".replace("WC", Ha), qa = /*@__PURE__*/ "\\.(WC+)(?:\\[(.+)\\])?".replace("WC", Ha), Ja = RegExp("^" + Wa + Ga + Ka + qa + "$"), Ya = [
|
|
6247
6395
|
"material",
|
|
6248
6396
|
"materials",
|
|
6249
6397
|
"bones",
|
|
6250
6398
|
"map"
|
|
6251
|
-
],
|
|
6399
|
+
], Xa = class {
|
|
6252
6400
|
constructor(e, t, n) {
|
|
6253
6401
|
let r = n || Z.parseTrackName(t);
|
|
6254
6402
|
this._targetGroup = e, this._bindings = e.subscribe_(t, r);
|
|
@@ -6278,10 +6426,10 @@ var Ia = "\\[\\]\\.:\\/", La = /* @__PURE__ */ RegExp("[\\[\\]\\.:\\/]", "g"), R
|
|
|
6278
6426
|
return t && t.isAnimationObjectGroup ? new e.Composite(t, n, r) : new e(t, n, r);
|
|
6279
6427
|
}
|
|
6280
6428
|
static sanitizeNodeName(e) {
|
|
6281
|
-
return e.replace(/\s/g, "_").replace(
|
|
6429
|
+
return e.replace(/\s/g, "_").replace(Va, "");
|
|
6282
6430
|
}
|
|
6283
6431
|
static parseTrackName(e) {
|
|
6284
|
-
let t =
|
|
6432
|
+
let t = Ja.exec(e);
|
|
6285
6433
|
if (t === null) throw Error("PropertyBinding: Cannot parse trackName: " + e);
|
|
6286
6434
|
let n = {
|
|
6287
6435
|
nodeName: t[2],
|
|
@@ -6292,7 +6440,7 @@ var Ia = "\\[\\]\\.:\\/", La = /* @__PURE__ */ RegExp("[\\[\\]\\.:\\/]", "g"), R
|
|
|
6292
6440
|
}, r = n.nodeName && n.nodeName.lastIndexOf(".");
|
|
6293
6441
|
if (r !== void 0 && r !== -1) {
|
|
6294
6442
|
let e = n.nodeName.substring(r + 1);
|
|
6295
|
-
|
|
6443
|
+
Ya.indexOf(e) !== -1 && (n.nodeName = n.nodeName.substring(0, r), n.objectName = e);
|
|
6296
6444
|
}
|
|
6297
6445
|
if (n.propertyName === null || n.propertyName.length === 0) throw Error("PropertyBinding: can not parse propertyName from trackName: " + e);
|
|
6298
6446
|
return n;
|
|
@@ -6382,7 +6530,7 @@ var Ia = "\\[\\]\\.:\\/", La = /* @__PURE__ */ RegExp("[\\[\\]\\.:\\/]", "g"), R
|
|
|
6382
6530
|
bind() {
|
|
6383
6531
|
let t = this.node, n = this.parsedPath, r = n.objectName, i = n.propertyName, a = n.propertyIndex;
|
|
6384
6532
|
if (t || (t = e.findNode(this.rootNode, n.nodeName), this.node = t), this.getValue = this._getValue_unavailable, this.setValue = this._setValue_unavailable, !t) {
|
|
6385
|
-
|
|
6533
|
+
H("PropertyBinding: No target node found for track: " + this.path + ".");
|
|
6386
6534
|
return;
|
|
6387
6535
|
}
|
|
6388
6536
|
if (r) {
|
|
@@ -6390,18 +6538,18 @@ var Ia = "\\[\\]\\.:\\/", La = /* @__PURE__ */ RegExp("[\\[\\]\\.:\\/]", "g"), R
|
|
|
6390
6538
|
switch (r) {
|
|
6391
6539
|
case "materials":
|
|
6392
6540
|
if (!t.material) {
|
|
6393
|
-
|
|
6541
|
+
U("PropertyBinding: Can not bind to material as node does not have a material.", this);
|
|
6394
6542
|
return;
|
|
6395
6543
|
}
|
|
6396
6544
|
if (!t.material.materials) {
|
|
6397
|
-
|
|
6545
|
+
U("PropertyBinding: Can not bind to material.materials as node.material does not have a materials array.", this);
|
|
6398
6546
|
return;
|
|
6399
6547
|
}
|
|
6400
6548
|
t = t.material.materials;
|
|
6401
6549
|
break;
|
|
6402
6550
|
case "bones":
|
|
6403
6551
|
if (!t.skeleton) {
|
|
6404
|
-
|
|
6552
|
+
U("PropertyBinding: Can not bind to bones as node does not have a skeleton.", this);
|
|
6405
6553
|
return;
|
|
6406
6554
|
}
|
|
6407
6555
|
t = t.skeleton.bones;
|
|
@@ -6416,25 +6564,25 @@ var Ia = "\\[\\]\\.:\\/", La = /* @__PURE__ */ RegExp("[\\[\\]\\.:\\/]", "g"), R
|
|
|
6416
6564
|
break;
|
|
6417
6565
|
}
|
|
6418
6566
|
if (!t.material) {
|
|
6419
|
-
|
|
6567
|
+
U("PropertyBinding: Can not bind to material as node does not have a material.", this);
|
|
6420
6568
|
return;
|
|
6421
6569
|
}
|
|
6422
6570
|
if (!t.material.map) {
|
|
6423
|
-
|
|
6571
|
+
U("PropertyBinding: Can not bind to material.map as node.material does not have a map.", this);
|
|
6424
6572
|
return;
|
|
6425
6573
|
}
|
|
6426
6574
|
t = t.material.map;
|
|
6427
6575
|
break;
|
|
6428
6576
|
default:
|
|
6429
6577
|
if (t[r] === void 0) {
|
|
6430
|
-
|
|
6578
|
+
U("PropertyBinding: Can not bind to objectName of node undefined.", this);
|
|
6431
6579
|
return;
|
|
6432
6580
|
}
|
|
6433
6581
|
t = t[r];
|
|
6434
6582
|
}
|
|
6435
6583
|
if (e !== void 0) {
|
|
6436
6584
|
if (t[e] === void 0) {
|
|
6437
|
-
|
|
6585
|
+
U("PropertyBinding: Trying to bind to objectIndex of objectName, but is undefined.", this, t);
|
|
6438
6586
|
return;
|
|
6439
6587
|
}
|
|
6440
6588
|
t = t[e];
|
|
@@ -6443,7 +6591,7 @@ var Ia = "\\[\\]\\.:\\/", La = /* @__PURE__ */ RegExp("[\\[\\]\\.:\\/]", "g"), R
|
|
|
6443
6591
|
let o = t[i];
|
|
6444
6592
|
if (o === void 0) {
|
|
6445
6593
|
let e = n.nodeName;
|
|
6446
|
-
|
|
6594
|
+
U("PropertyBinding: Trying to update property for track: " + e + "." + i + " but it wasn't found.", t);
|
|
6447
6595
|
return;
|
|
6448
6596
|
}
|
|
6449
6597
|
let s = this.Versioning.None;
|
|
@@ -6452,11 +6600,11 @@ var Ia = "\\[\\]\\.:\\/", La = /* @__PURE__ */ RegExp("[\\[\\]\\.:\\/]", "g"), R
|
|
|
6452
6600
|
if (a !== void 0) {
|
|
6453
6601
|
if (i === "morphTargetInfluences") {
|
|
6454
6602
|
if (!t.geometry) {
|
|
6455
|
-
|
|
6603
|
+
U("PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.", this);
|
|
6456
6604
|
return;
|
|
6457
6605
|
}
|
|
6458
6606
|
if (!t.geometry.morphAttributes) {
|
|
6459
|
-
|
|
6607
|
+
U("PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphAttributes.", this);
|
|
6460
6608
|
return;
|
|
6461
6609
|
}
|
|
6462
6610
|
t.morphTargetDictionary[a] !== void 0 && (a = t.morphTargetDictionary[a]);
|
|
@@ -6469,7 +6617,7 @@ var Ia = "\\[\\]\\.:\\/", La = /* @__PURE__ */ RegExp("[\\[\\]\\.:\\/]", "g"), R
|
|
|
6469
6617
|
this.node = null, this.getValue = this._getValue_unbound, this.setValue = this._setValue_unbound;
|
|
6470
6618
|
}
|
|
6471
6619
|
};
|
|
6472
|
-
Z.Composite =
|
|
6620
|
+
Z.Composite = Xa, Z.prototype.BindingType = {
|
|
6473
6621
|
Direct: 0,
|
|
6474
6622
|
EntireArray: 1,
|
|
6475
6623
|
ArrayElement: 2,
|
|
@@ -6527,37 +6675,37 @@ Z.Composite = Ka, Z.prototype.BindingType = {
|
|
|
6527
6675
|
let i = this.elements;
|
|
6528
6676
|
return i[0] = e, i[2] = t, i[1] = n, i[3] = r, this;
|
|
6529
6677
|
}
|
|
6530
|
-
}, typeof __THREE_DEVTOOLS__ < "u" && __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("register", { detail: { revision: "184" } })), typeof window < "u" && (window.__THREE__ ?
|
|
6678
|
+
}, typeof __THREE_DEVTOOLS__ < "u" && __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("register", { detail: { revision: "184" } })), typeof window < "u" && (window.__THREE__ ? H("WARNING: Multiple instances of Three.js being imported.") : window.__THREE__ = "184");
|
|
6531
6679
|
//#endregion
|
|
6532
6680
|
//#region src/model-preview.ts
|
|
6533
|
-
var
|
|
6681
|
+
var Za = 2.4, Qa = 1.35, $a = [
|
|
6534
6682
|
0,
|
|
6535
6683
|
.5,
|
|
6536
6684
|
0
|
|
6537
|
-
],
|
|
6538
|
-
function
|
|
6539
|
-
return Math.abs(e.height -
|
|
6685
|
+
], eo = 60 * Math.PI / 180, to = 1;
|
|
6686
|
+
function no(e) {
|
|
6687
|
+
return Math.abs(e.height - to) < to * .25;
|
|
6540
6688
|
}
|
|
6541
|
-
function
|
|
6689
|
+
function ro(e, t, n = 1.25) {
|
|
6542
6690
|
let r = e.scene?.root.getNodesByName(t)[0];
|
|
6543
6691
|
if (!r) return null;
|
|
6544
6692
|
let i = r._ensureObject3D();
|
|
6545
6693
|
i.updateWorldMatrix(!0, !0);
|
|
6546
|
-
let a = new
|
|
6694
|
+
let a = new la().setFromObject(i, !0);
|
|
6547
6695
|
if (a.isEmpty()) return null;
|
|
6548
|
-
let o = a.getSize(new
|
|
6696
|
+
let o = a.getSize(new K()), s = a.getCenter(new K()), c = Math.max(o.x, o.y, o.z);
|
|
6549
6697
|
return !Number.isFinite(c) || c <= 0 ? null : {
|
|
6550
6698
|
target: [
|
|
6551
6699
|
s.x,
|
|
6552
6700
|
s.y,
|
|
6553
6701
|
s.z
|
|
6554
6702
|
],
|
|
6555
|
-
distance: c / 2 / Math.tan(
|
|
6703
|
+
distance: c / 2 / Math.tan(eo / 2) * n,
|
|
6556
6704
|
height: o.y
|
|
6557
6705
|
};
|
|
6558
6706
|
}
|
|
6559
|
-
var
|
|
6560
|
-
function
|
|
6707
|
+
var io = "https://agent8-games.verse8.io/assets/3d/characters/realistic style/base-model.glb";
|
|
6708
|
+
function ao(e) {
|
|
6561
6709
|
let t = { model: {
|
|
6562
6710
|
type: "model",
|
|
6563
6711
|
url: e.model
|
|
@@ -6592,8 +6740,8 @@ function to(e) {
|
|
|
6592
6740
|
current: !0,
|
|
6593
6741
|
position: [
|
|
6594
6742
|
0,
|
|
6595
|
-
|
|
6596
|
-
|
|
6743
|
+
Qa,
|
|
6744
|
+
Za
|
|
6597
6745
|
]
|
|
6598
6746
|
}
|
|
6599
6747
|
},
|
|
@@ -6622,7 +6770,7 @@ function to(e) {
|
|
|
6622
6770
|
}
|
|
6623
6771
|
};
|
|
6624
6772
|
}
|
|
6625
|
-
var
|
|
6773
|
+
var oo = (e, t) => e !== null && e.model === t.model && e.clip === t.clip, so = class {
|
|
6626
6774
|
canvas = null;
|
|
6627
6775
|
engine = null;
|
|
6628
6776
|
renderer = null;
|
|
@@ -6639,7 +6787,7 @@ var no = (e, t) => e !== null && e.model === t.model && e.clip === t.clip, ro =
|
|
|
6639
6787
|
let t = document.createElement("div");
|
|
6640
6788
|
t.className = "lib-preview3d";
|
|
6641
6789
|
let n = this.ensure();
|
|
6642
|
-
return t.appendChild(n),
|
|
6790
|
+
return t.appendChild(n), oo(this.subject, e) || (this.subject = e, this.aimed = e.clip !== void 0, this.framing = null, this.locked = !1, this.measureUntil = performance.now() + 4e3, this.load(e)), this.start(), t;
|
|
6643
6791
|
}
|
|
6644
6792
|
detach() {
|
|
6645
6793
|
this.stop(), this.canvas?.remove();
|
|
@@ -6665,7 +6813,7 @@ var no = (e, t) => e !== null && e.model === t.model && e.clip === t.clip, ro =
|
|
|
6665
6813
|
}
|
|
6666
6814
|
load(e) {
|
|
6667
6815
|
if (this.engine) try {
|
|
6668
|
-
this.engine.setScene(f(
|
|
6816
|
+
this.engine.setScene(f(ao(e)));
|
|
6669
6817
|
} catch (t) {
|
|
6670
6818
|
console.warn("[incanto] library preview could not load", e, t);
|
|
6671
6819
|
}
|
|
@@ -6679,17 +6827,17 @@ var no = (e, t) => e !== null && e.model === t.model && e.clip === t.clip, ro =
|
|
|
6679
6827
|
let i = this.renderer;
|
|
6680
6828
|
if (!i) return;
|
|
6681
6829
|
if (this.engine && !this.locked) {
|
|
6682
|
-
let e =
|
|
6683
|
-
e && (this.framing = e,
|
|
6830
|
+
let e = ro(this.engine, "Model");
|
|
6831
|
+
e && (this.framing = e, no(e) && (this.locked = !0)), this.framing && n > this.measureUntil && (this.locked = !0);
|
|
6684
6832
|
}
|
|
6685
|
-
let a = this.framing, o = a ? a.distance :
|
|
6833
|
+
let a = this.framing, o = a ? a.distance : Za, s = a ? a.target[1] + o * .25 : Qa;
|
|
6686
6834
|
i.viewOverride = {
|
|
6687
6835
|
position: [
|
|
6688
6836
|
(a?.target[0] ?? 0) + Math.sin(this.angle) * o,
|
|
6689
6837
|
s,
|
|
6690
6838
|
(a?.target[2] ?? 0) + Math.cos(this.angle) * o
|
|
6691
6839
|
],
|
|
6692
|
-
target: a ? a.target :
|
|
6840
|
+
target: a ? a.target : $a
|
|
6693
6841
|
}, this.engine?.tick(n);
|
|
6694
6842
|
};
|
|
6695
6843
|
this.raf = requestAnimationFrame(t);
|
|
@@ -6697,11 +6845,11 @@ var no = (e, t) => e !== null && e.model === t.model && e.clip === t.clip, ro =
|
|
|
6697
6845
|
stop() {
|
|
6698
6846
|
this.raf && cancelAnimationFrame(this.raf), this.raf = 0;
|
|
6699
6847
|
}
|
|
6700
|
-
},
|
|
6848
|
+
}, co = 192, lo = .9, uo = 1.05, fo = .88, po = [
|
|
6701
6849
|
0,
|
|
6702
6850
|
.5,
|
|
6703
6851
|
0
|
|
6704
|
-
],
|
|
6852
|
+
], mo = 3, ho = 30, go = 3e4, _o = 12, vo = 20, yo = 60, bo = (e) => `${e.model}|${e.clip ?? ""}`, xo = class {
|
|
6705
6853
|
jobs = /* @__PURE__ */ new Map();
|
|
6706
6854
|
queue = [];
|
|
6707
6855
|
running = !1;
|
|
@@ -6713,7 +6861,7 @@ var no = (e, t) => e !== null && e.model === t.model && e.clip === t.clip, ro =
|
|
|
6713
6861
|
disposed = !1;
|
|
6714
6862
|
pace = 0;
|
|
6715
6863
|
get(e) {
|
|
6716
|
-
let t =
|
|
6864
|
+
let t = bo(e), n = this.jobs.get(t);
|
|
6717
6865
|
if (n) return n;
|
|
6718
6866
|
let r = new Promise((n) => {
|
|
6719
6867
|
this.queue.push({
|
|
@@ -6745,40 +6893,40 @@ var no = (e, t) => e !== null && e.model === t.model && e.clip === t.clip, ro =
|
|
|
6745
6893
|
async draw(e) {
|
|
6746
6894
|
if (this.disposed) return null;
|
|
6747
6895
|
let { engine: t, renderer: n, canvas: r } = this.ensure();
|
|
6748
|
-
(!this.held.has(e.model) && this.held.size >=
|
|
6896
|
+
(!this.held.has(e.model) && this.held.size >= _o || this.clipsHeld >= yo) && (n.assets.dispose(), this.held.clear(), this.clipsHeld = 0), this.held.add(e.model), e.clip && (this.clipsHeld += 1);
|
|
6749
6897
|
try {
|
|
6750
|
-
t.setScene(f(
|
|
6898
|
+
t.setScene(f(ao(e)));
|
|
6751
6899
|
} catch {
|
|
6752
6900
|
return null;
|
|
6753
6901
|
}
|
|
6754
6902
|
let i = !1, a = () => {
|
|
6755
|
-
let e =
|
|
6756
|
-
e && (i =
|
|
6757
|
-
let r = e ? e.distance :
|
|
6903
|
+
let e = ro(t, "Model", 1.15);
|
|
6904
|
+
e && (i = no(e));
|
|
6905
|
+
let r = e ? e.distance : uo;
|
|
6758
6906
|
n.viewOverride = {
|
|
6759
6907
|
position: [
|
|
6760
|
-
(e?.target[0] ?? 0) + Math.sin(
|
|
6761
|
-
e ? e.target[1] + r * .25 :
|
|
6762
|
-
(e?.target[2] ?? 0) + Math.cos(
|
|
6908
|
+
(e?.target[0] ?? 0) + Math.sin(lo) * r,
|
|
6909
|
+
e ? e.target[1] + r * .25 : fo,
|
|
6910
|
+
(e?.target[2] ?? 0) + Math.cos(lo) * r
|
|
6763
6911
|
],
|
|
6764
|
-
target: e ? e.target :
|
|
6912
|
+
target: e ? e.target : po
|
|
6765
6913
|
};
|
|
6766
6914
|
};
|
|
6767
6915
|
a();
|
|
6768
|
-
let o = Date.now() +
|
|
6916
|
+
let o = Date.now() + go;
|
|
6769
6917
|
for (; !this.disposed;) {
|
|
6770
|
-
t.tick(await
|
|
6918
|
+
t.tick(await So());
|
|
6771
6919
|
let r = n.assets.getModel(e.model), i = e.clip ? n.assets.getAnimation(e.clip) : null;
|
|
6772
6920
|
if (r.status === "error" || i?.status === "error") return null;
|
|
6773
6921
|
if (r.status === "ready" && (!i || i.status === "ready")) break;
|
|
6774
6922
|
if (Date.now() > o) return null;
|
|
6775
6923
|
}
|
|
6776
|
-
let s = e.clip ?
|
|
6777
|
-
for (let e = 0; e < s && !this.disposed; e++) t.tick(await
|
|
6924
|
+
let s = e.clip ? ho : mo;
|
|
6925
|
+
for (let e = 0; e < s && !this.disposed; e++) t.tick(await So());
|
|
6778
6926
|
if (this.disposed) return null;
|
|
6779
6927
|
a();
|
|
6780
|
-
for (let e = 0; e <
|
|
6781
|
-
return this.disposed || (t.tick(await
|
|
6928
|
+
for (let e = 0; e < vo && !i && !this.disposed; e++) t.tick(await So()), a();
|
|
6929
|
+
return this.disposed || (t.tick(await So()), this.disposed) ? null : r.toDataURL("image/webp", .85);
|
|
6782
6930
|
}
|
|
6783
6931
|
ensure() {
|
|
6784
6932
|
if (this.canvas && this.engine && this.renderer) return {
|
|
@@ -6787,7 +6935,7 @@ var no = (e, t) => e !== null && e.model === t.model && e.clip === t.clip, ro =
|
|
|
6787
6935
|
renderer: this.renderer
|
|
6788
6936
|
};
|
|
6789
6937
|
let e = document.createElement("canvas");
|
|
6790
|
-
e.width =
|
|
6938
|
+
e.width = co, e.height = co;
|
|
6791
6939
|
let n = new t({ scheduler: () => () => {} }), r = new D({
|
|
6792
6940
|
canvas: e,
|
|
6793
6941
|
engine: n,
|
|
@@ -6801,8 +6949,8 @@ var no = (e, t) => e !== null && e.model === t.model && e.clip === t.clip, ro =
|
|
|
6801
6949
|
renderer: r
|
|
6802
6950
|
};
|
|
6803
6951
|
}
|
|
6804
|
-
},
|
|
6805
|
-
async function
|
|
6952
|
+
}, So = () => new Promise((e) => requestAnimationFrame(e)), Co = "incanto-editor-v8-token", wo = 24;
|
|
6953
|
+
async function To(e, t, n) {
|
|
6806
6954
|
if (!Oe(e.url) || n !== "spritesheet" && n !== "texture") return null;
|
|
6807
6955
|
try {
|
|
6808
6956
|
let n = x(await (await fetch(e.url)).json(), {
|
|
@@ -6817,7 +6965,7 @@ async function xo(e, t, n) {
|
|
|
6817
6965
|
return console.warn("[incanto] not a usable sprite config:", e.url, t), null;
|
|
6818
6966
|
}
|
|
6819
6967
|
}
|
|
6820
|
-
async function
|
|
6968
|
+
async function Eo(e, t) {
|
|
6821
6969
|
let n = async (t) => {
|
|
6822
6970
|
let n = await fetch(t, {
|
|
6823
6971
|
method: "POST",
|
|
@@ -6846,20 +6994,20 @@ async function So(e, t) {
|
|
|
6846
6994
|
}
|
|
6847
6995
|
throw Error("sign-in timed out — try again");
|
|
6848
6996
|
}
|
|
6849
|
-
function
|
|
6997
|
+
function Do() {
|
|
6850
6998
|
try {
|
|
6851
|
-
return localStorage.getItem(
|
|
6999
|
+
return localStorage.getItem(Co) ?? "";
|
|
6852
7000
|
} catch {
|
|
6853
7001
|
return "";
|
|
6854
7002
|
}
|
|
6855
7003
|
}
|
|
6856
|
-
var
|
|
6857
|
-
function
|
|
7004
|
+
var Oo = io;
|
|
7005
|
+
function ko(e) {
|
|
6858
7006
|
try {
|
|
6859
|
-
e ? localStorage.setItem(
|
|
7007
|
+
e ? localStorage.setItem(Co, e) : localStorage.removeItem(Co);
|
|
6860
7008
|
} catch {}
|
|
6861
7009
|
}
|
|
6862
|
-
function
|
|
7010
|
+
function Ao(e, t) {
|
|
6863
7011
|
return new Promise((n) => {
|
|
6864
7012
|
let r = [...t.shelf ?? []], i = "", a = 1, o = !1, s = [], c = [], l = null, u = !1, d = !1, f = document.createElement("div");
|
|
6865
7013
|
f.className = "lib-backdrop";
|
|
@@ -6895,8 +7043,8 @@ function Eo(e, t) {
|
|
|
6895
7043
|
E.className = "lib-sentinel", E.setAttribute("aria-hidden", "true"), S.append(w, C, T);
|
|
6896
7044
|
let D = document.createElement("aside");
|
|
6897
7045
|
D.className = "lib-detail", b.append(x, S, D);
|
|
6898
|
-
let O = new
|
|
6899
|
-
d || (d = !0, O.dispose(),
|
|
7046
|
+
let O = new so(), k = (e) => {
|
|
7047
|
+
d || (d = !0, O.dispose(), ae.dispose(), ce?.disconnect(), document.removeEventListener("keydown", A, !0), f.remove(), n(e));
|
|
6900
7048
|
}, A = (e) => {
|
|
6901
7049
|
e.key === "Escape" && (e.stopPropagation(), k(null));
|
|
6902
7050
|
};
|
|
@@ -6945,43 +7093,43 @@ function Eo(e, t) {
|
|
|
6945
7093
|
tags: t,
|
|
6946
7094
|
page: 1,
|
|
6947
7095
|
limit: 1
|
|
6948
|
-
},
|
|
7096
|
+
}, Do() || void 0), i = r.total ?? r.items.length;
|
|
6949
7097
|
if (j.set(n, i), d) return;
|
|
6950
7098
|
te();
|
|
6951
7099
|
} catch {
|
|
6952
7100
|
j.delete(n);
|
|
6953
7101
|
}
|
|
6954
7102
|
}
|
|
6955
|
-
},
|
|
6956
|
-
model:
|
|
7103
|
+
}, re = (e) => ye(e) ? {
|
|
7104
|
+
model: M,
|
|
6957
7105
|
clip: e.url
|
|
6958
|
-
} : { model: e.url },
|
|
7106
|
+
} : { model: e.url }, M = Oo, ie = () => {
|
|
6959
7107
|
let e = document.createElement("div");
|
|
6960
7108
|
e.className = "lib-charpick";
|
|
6961
7109
|
let t = document.createElement("label");
|
|
6962
7110
|
t.className = "lib-charpick-label", t.textContent = "playing on";
|
|
6963
7111
|
let n = document.createElement("input");
|
|
6964
|
-
n.type = "text", n.value =
|
|
7112
|
+
n.type = "text", n.value = M, n.spellcheck = !1, n.placeholder = "a character GLB url", n.title = M;
|
|
6965
7113
|
let r = document.createElement("button");
|
|
6966
7114
|
r.type = "button", r.className = "ghost", r.textContent = "apply";
|
|
6967
7115
|
let i = document.createElement("button");
|
|
6968
7116
|
i.type = "button", i.className = "ghost", i.textContent = "base", i.title = "back to the base character";
|
|
6969
7117
|
let a = (e) => {
|
|
6970
7118
|
let t = e.trim();
|
|
6971
|
-
if (!(!t || t ===
|
|
6972
|
-
|
|
6973
|
-
for (let e of s) ye(e) &&
|
|
6974
|
-
|
|
7119
|
+
if (!(!t || t === M)) {
|
|
7120
|
+
M = t, Oo = t, ae.cancelPending();
|
|
7121
|
+
for (let e of s) ye(e) && P.delete(e.url);
|
|
7122
|
+
N(), F();
|
|
6975
7123
|
}
|
|
6976
7124
|
};
|
|
6977
7125
|
return r.addEventListener("click", () => a(n.value)), n.addEventListener("keydown", (e) => {
|
|
6978
7126
|
e.key === "Enter" && (e.preventDefault(), a(n.value));
|
|
6979
7127
|
}), i.addEventListener("click", () => {
|
|
6980
|
-
n.value =
|
|
7128
|
+
n.value = io, a(io);
|
|
6981
7129
|
}), e.append(t, n, r, i), e;
|
|
6982
|
-
},
|
|
7130
|
+
}, N = () => {
|
|
6983
7131
|
if (D.textContent = "", O.detach(), !l) {
|
|
6984
|
-
|
|
7132
|
+
ae.setPace(0);
|
|
6985
7133
|
let e = document.createElement("div");
|
|
6986
7134
|
e.className = "lib-empty", e.textContent = "pick an asset to preview it", D.appendChild(e);
|
|
6987
7135
|
return;
|
|
@@ -6995,12 +7143,12 @@ function Eo(e, t) {
|
|
|
6995
7143
|
} else if (r === "audio") {
|
|
6996
7144
|
let t = document.createElement("audio");
|
|
6997
7145
|
t.controls = !0, t.src = e.url, n.appendChild(t);
|
|
6998
|
-
} else if (r === "model") n.appendChild(O.mount(
|
|
7146
|
+
} else if (r === "model") n.appendChild(O.mount(re(e))), ae.setPace(ye(e) ? 300 : 0);
|
|
6999
7147
|
else {
|
|
7000
7148
|
let t = document.createElement("div");
|
|
7001
7149
|
t.className = "lib-empty", t.textContent = `no preview for ${me(e.url) || "this file"}`, n.appendChild(t);
|
|
7002
7150
|
}
|
|
7003
|
-
if (D.appendChild(n), ye(e) && D.appendChild(
|
|
7151
|
+
if (D.appendChild(n), ye(e) && D.appendChild(ie()), Oe(e.url)) {
|
|
7004
7152
|
let e = document.createElement("p");
|
|
7005
7153
|
e.className = "lib-desc lib-note", e.textContent = "Sprite config — picking it declares the sheet AND wires its named animations onto the node.", D.appendChild(e);
|
|
7006
7154
|
}
|
|
@@ -7056,24 +7204,24 @@ function Eo(e, t) {
|
|
|
7056
7204
|
return;
|
|
7057
7205
|
}
|
|
7058
7206
|
(async () => {
|
|
7059
|
-
let n = Se(e), r = await
|
|
7207
|
+
let n = Se(e), r = await To(e, n, t.assetType), i = r?.asset ?? De(e, t.kind, t.assetType), a = t.onAsset?.(e, i, n) ?? e.url;
|
|
7060
7208
|
r && t.onProps?.(r.props), k(a);
|
|
7061
7209
|
})();
|
|
7062
7210
|
}), d.appendChild(p), D.appendChild(d);
|
|
7063
|
-
},
|
|
7211
|
+
}, ae = new xo(), P = /* @__PURE__ */ new Map(), oe = (e, t) => {
|
|
7064
7212
|
e.textContent = "";
|
|
7065
7213
|
let n = document.createElement("img");
|
|
7066
7214
|
n.src = t, n.alt = "", e.appendChild(n);
|
|
7067
7215
|
}, se = (e) => {
|
|
7068
7216
|
let t = e.dataset.model;
|
|
7069
|
-
if (!t ||
|
|
7217
|
+
if (!t || P.has(t)) return;
|
|
7070
7218
|
let n = s.find((e) => e.url === t);
|
|
7071
|
-
|
|
7219
|
+
P.set(t, null), ae.get(n ? re(n) : { model: t }).then((e) => {
|
|
7072
7220
|
if (!e) {
|
|
7073
|
-
|
|
7221
|
+
P.delete(t);
|
|
7074
7222
|
return;
|
|
7075
7223
|
}
|
|
7076
|
-
if (
|
|
7224
|
+
if (P.set(t, e), !d) for (let n of C.querySelectorAll(`[data-model="${CSS.escape(t)}"]`)) oe(n, e);
|
|
7077
7225
|
});
|
|
7078
7226
|
}, ce = typeof IntersectionObserver > "u" ? null : new IntersectionObserver((e) => {
|
|
7079
7227
|
for (let t of e) t.isIntersecting && (ce?.unobserve(t.target), se(t.target));
|
|
@@ -7097,11 +7245,11 @@ function Eo(e, t) {
|
|
|
7097
7245
|
let e = document.createElement("img");
|
|
7098
7246
|
e.src = o ? ke(n.url) : n.url, e.alt = "", e.loading = "lazy", i.appendChild(e);
|
|
7099
7247
|
} else if (a === "model") {
|
|
7100
|
-
let t =
|
|
7248
|
+
let t = P.get(n.url);
|
|
7101
7249
|
if (t) oe(i, t);
|
|
7102
7250
|
else {
|
|
7103
7251
|
let t = Je("ModelInstance3D");
|
|
7104
|
-
t.classList.add("lib-glyph"), i.appendChild(t), i.dataset.model = n.url,
|
|
7252
|
+
t.classList.add("lib-glyph"), i.appendChild(t), i.dataset.model = n.url, P.has(n.url) || e.push(i);
|
|
7105
7253
|
}
|
|
7106
7254
|
} else {
|
|
7107
7255
|
let e = Je(a === "audio" ? "AudioPlayer" : "ModelInstance3D");
|
|
@@ -7113,11 +7261,11 @@ function Eo(e, t) {
|
|
|
7113
7261
|
}
|
|
7114
7262
|
let s = document.createElement("span");
|
|
7115
7263
|
s.className = "lib-card-name", s.textContent = xe(n), r.append(i, s), r.title = be(n, t.kind, t.assetType) ?? n.description ?? n.url, r.addEventListener("click", () => {
|
|
7116
|
-
l = n, F(),
|
|
7264
|
+
l = n, F(), N();
|
|
7117
7265
|
}), C.appendChild(r);
|
|
7118
7266
|
}
|
|
7119
7267
|
if (o && !u && (C.appendChild(E), requestAnimationFrame(Te)), ce) for (let t of e) ce.observe(t);
|
|
7120
|
-
else for (let t of e.slice(0,
|
|
7268
|
+
else for (let t of e.slice(0, wo)) se(t);
|
|
7121
7269
|
T.hidden = !o || u;
|
|
7122
7270
|
}, de = null, fe = !1, pe = (e) => {
|
|
7123
7271
|
C.textContent = "", T.hidden = !0, de?.abort();
|
|
@@ -7134,24 +7282,24 @@ function Eo(e, t) {
|
|
|
7134
7282
|
let s = document.createElement("div");
|
|
7135
7283
|
s.className = "lib-token-row", s.append(o), t.append(n, r, s, i), C.appendChild(t), o.addEventListener("click", () => {
|
|
7136
7284
|
let e = new AbortController();
|
|
7137
|
-
de?.abort(), de = e, o.disabled = !0, i.textContent = "asking Verse8 for a code…",
|
|
7285
|
+
de?.abort(), de = e, o.disabled = !0, i.textContent = "asking Verse8 for a code…", Eo(e.signal, (e) => {
|
|
7138
7286
|
i.textContent = e;
|
|
7139
7287
|
}).then((t) => {
|
|
7140
|
-
e.signal.aborted || (
|
|
7288
|
+
e.signal.aborted || (ko(t), fe = !0, i.textContent = "signed in — loading the catalog…", a = 1, _e(!1));
|
|
7141
7289
|
}).catch((t) => {
|
|
7142
7290
|
e.signal.aborted || (o.disabled = !1, i.textContent = t instanceof Error ? t.message : String(t));
|
|
7143
7291
|
});
|
|
7144
7292
|
});
|
|
7145
7293
|
}, _e = async (n) => {
|
|
7146
7294
|
if (!(!e.library || u)) {
|
|
7147
|
-
u = !0, w.textContent = n ? "loading more…" : `loading ${ue(r)}…`, n || (s = [], l = null,
|
|
7295
|
+
u = !0, w.textContent = n ? "loading more…" : `loading ${ue(r)}…`, n || (s = [], l = null, ae.cancelPending(), F(), N()), te();
|
|
7148
7296
|
try {
|
|
7149
7297
|
let l = await e.library({
|
|
7150
7298
|
tags: r,
|
|
7151
7299
|
keyword: i.trim() || void 0,
|
|
7152
7300
|
page: a,
|
|
7153
|
-
limit:
|
|
7154
|
-
},
|
|
7301
|
+
limit: wo
|
|
7302
|
+
}, Do() || void 0);
|
|
7155
7303
|
if (d) return;
|
|
7156
7304
|
u = !1, s = n ? [...s, ...l.items] : l.items, c = s, o = l.hasNext;
|
|
7157
7305
|
let f = l.total === void 0 ? "" : ` of ${l.total}`, p = s.filter((e) => ge(e.url, t.kind)).length, m = p === s.length ? "" : ` · ${p} fit this field`;
|
|
@@ -7182,21 +7330,21 @@ function Eo(e, t) {
|
|
|
7182
7330
|
i = v.value, clearTimeout(Ee), Ee = window.setTimeout(() => {
|
|
7183
7331
|
a = 1, _e(!1);
|
|
7184
7332
|
}, 350);
|
|
7185
|
-
}), te(),
|
|
7333
|
+
}), te(), N(), document.body.appendChild(f), v.focus(), _e(!1);
|
|
7186
7334
|
});
|
|
7187
7335
|
}
|
|
7188
7336
|
//#endregion
|
|
7189
7337
|
//#region src/scene-tree.ts
|
|
7190
|
-
var
|
|
7191
|
-
function
|
|
7338
|
+
var jo = ".scene.json";
|
|
7339
|
+
function Mo(e) {
|
|
7192
7340
|
let t = e.split("/").pop() ?? e;
|
|
7193
|
-
return t.endsWith(
|
|
7341
|
+
return t.endsWith(jo) ? t.slice(0, -11) : t;
|
|
7194
7342
|
}
|
|
7195
|
-
function
|
|
7343
|
+
function No(e) {
|
|
7196
7344
|
let t = e.lastIndexOf("/");
|
|
7197
7345
|
return t === -1 ? "" : e.slice(0, t);
|
|
7198
7346
|
}
|
|
7199
|
-
function
|
|
7347
|
+
function Po(e, t) {
|
|
7200
7348
|
return {
|
|
7201
7349
|
path: e,
|
|
7202
7350
|
name: t,
|
|
@@ -7204,31 +7352,31 @@ function Ao(e, t) {
|
|
|
7204
7352
|
files: []
|
|
7205
7353
|
};
|
|
7206
7354
|
}
|
|
7207
|
-
function
|
|
7208
|
-
let t =
|
|
7355
|
+
function Fo(e) {
|
|
7356
|
+
let t = Po("", "");
|
|
7209
7357
|
for (let n of e) {
|
|
7210
7358
|
let e = n.rel.split("/");
|
|
7211
7359
|
if (!e.pop()) continue;
|
|
7212
7360
|
let r = t;
|
|
7213
7361
|
for (let t of e) {
|
|
7214
7362
|
let e = r.path ? `${r.path}/${t}` : t, n = r.dirs.get(t);
|
|
7215
|
-
n || (n =
|
|
7363
|
+
n || (n = Po(e, t), r.dirs.set(t, n)), r = n;
|
|
7216
7364
|
}
|
|
7217
7365
|
r.files.push(n);
|
|
7218
7366
|
}
|
|
7219
7367
|
return t;
|
|
7220
7368
|
}
|
|
7221
|
-
function
|
|
7369
|
+
function Io(e) {
|
|
7222
7370
|
let t = e.files.length;
|
|
7223
|
-
for (let n of e.dirs.values()) t +=
|
|
7371
|
+
for (let n of e.dirs.values()) t += Io(n);
|
|
7224
7372
|
return t;
|
|
7225
7373
|
}
|
|
7226
|
-
function
|
|
7374
|
+
function Lo(e) {
|
|
7227
7375
|
let t = e.files.filter((e) => e.scene).length;
|
|
7228
|
-
for (let n of e.dirs.values()) t +=
|
|
7376
|
+
for (let n of e.dirs.values()) t += Lo(n);
|
|
7229
7377
|
return t;
|
|
7230
7378
|
}
|
|
7231
|
-
function
|
|
7379
|
+
function Ro(e) {
|
|
7232
7380
|
let t = e, n = e.name;
|
|
7233
7381
|
for (; t.files.length === 0 && t.dirs.size === 1;) {
|
|
7234
7382
|
let e = [...t.dirs.values()][0];
|
|
@@ -7240,16 +7388,16 @@ function Po(e) {
|
|
|
7240
7388
|
label: n
|
|
7241
7389
|
};
|
|
7242
7390
|
}
|
|
7243
|
-
function
|
|
7244
|
-
let t =
|
|
7391
|
+
function zo(e) {
|
|
7392
|
+
let t = No(e ?? "").split("/").filter(Boolean), n = [], r = "";
|
|
7245
7393
|
for (let e of t) r = r ? `${r}/${e}` : e, n.push(r);
|
|
7246
7394
|
return n;
|
|
7247
7395
|
}
|
|
7248
|
-
function
|
|
7396
|
+
function Bo(e, t = {}) {
|
|
7249
7397
|
let n = (t.query ?? "").trim().toLowerCase(), r = n ? e.filter((e) => e.rel.toLowerCase().includes(n)) : e, i = t.expanded ?? /* @__PURE__ */ new Set(), a = [], o = (e, r) => {
|
|
7250
7398
|
let s = [...e.dirs.values()].sort((e, t) => e.name.localeCompare(t.name));
|
|
7251
7399
|
for (let e of s) {
|
|
7252
|
-
let { dir: t, label: s } =
|
|
7400
|
+
let { dir: t, label: s } = Ro(e), c = Io(t);
|
|
7253
7401
|
if (c === 0) continue;
|
|
7254
7402
|
let l = n !== "" || i.has(t.path);
|
|
7255
7403
|
a.push({
|
|
@@ -7258,31 +7406,31 @@ function Io(e, t = {}) {
|
|
|
7258
7406
|
label: s,
|
|
7259
7407
|
depth: r,
|
|
7260
7408
|
count: c,
|
|
7261
|
-
scenes:
|
|
7409
|
+
scenes: Lo(t),
|
|
7262
7410
|
open: l
|
|
7263
7411
|
}), l && o(t, r + 1);
|
|
7264
7412
|
}
|
|
7265
|
-
let c = [...e.files].sort((e, t) =>
|
|
7413
|
+
let c = [...e.files].sort((e, t) => Mo(e.rel).localeCompare(Mo(t.rel)));
|
|
7266
7414
|
for (let e of c) a.push({
|
|
7267
7415
|
kind: "scene",
|
|
7268
7416
|
entry: e,
|
|
7269
|
-
label:
|
|
7270
|
-
folder:
|
|
7417
|
+
label: Mo(e.rel),
|
|
7418
|
+
folder: No(e.rel),
|
|
7271
7419
|
depth: r,
|
|
7272
7420
|
current: e.rel === t.current
|
|
7273
7421
|
});
|
|
7274
7422
|
};
|
|
7275
|
-
return o(
|
|
7423
|
+
return o(Fo(r), 0), a;
|
|
7276
7424
|
}
|
|
7277
|
-
function
|
|
7278
|
-
let n = new Set(
|
|
7279
|
-
if (e.length <= 24) for (let t of e) for (let e of
|
|
7425
|
+
function Vo(e, t) {
|
|
7426
|
+
let n = new Set(zo(t));
|
|
7427
|
+
if (e.length <= 24) for (let t of e) for (let e of zo(t.rel)) n.add(e);
|
|
7280
7428
|
return n;
|
|
7281
7429
|
}
|
|
7282
|
-
function
|
|
7430
|
+
function Ho(e) {
|
|
7283
7431
|
return typeof e != "number" || !Number.isFinite(e) || e < 0 ? "" : e < 1e3 ? `${e} B` : e < 1e3 * 1e3 ? `${(e / 1e3).toFixed(1)} kB` : `${(e / 1e3 / 1e3).toFixed(1)} MB`;
|
|
7284
7432
|
}
|
|
7285
|
-
function
|
|
7433
|
+
function Uo(e, t) {
|
|
7286
7434
|
if (typeof e != "number" || !Number.isFinite(e) || e <= 0) return "";
|
|
7287
7435
|
let n = Math.round((t - e) / 1e3);
|
|
7288
7436
|
if (n < 90) return "just now";
|
|
@@ -7291,49 +7439,53 @@ function zo(e, t) {
|
|
|
7291
7439
|
let i = Math.round(r / 60);
|
|
7292
7440
|
return i < 24 ? `${i}h ago` : i < 48 ? "yesterday" : new Date(e).toISOString().slice(0, 10);
|
|
7293
7441
|
}
|
|
7294
|
-
function
|
|
7442
|
+
function Wo(e, t = "new-level") {
|
|
7295
7443
|
let n = e ? e.kind === "folder" ? e.path : e.folder : "";
|
|
7296
|
-
return n ? `${n}/${t}${
|
|
7444
|
+
return n ? `${n}/${t}${jo}` : `${t}${jo}`;
|
|
7297
7445
|
}
|
|
7298
7446
|
//#endregion
|
|
7299
7447
|
//#region src/scene-browser.ts
|
|
7300
|
-
function
|
|
7448
|
+
function Go(e, t) {
|
|
7301
7449
|
let n = document.createElement("span");
|
|
7302
7450
|
return n.className = e, n.textContent = t, n;
|
|
7303
7451
|
}
|
|
7304
|
-
function
|
|
7452
|
+
function Ko(e, t, n = () => Date.now()) {
|
|
7305
7453
|
let r = [], i = /* @__PURE__ */ new Set(), a = [], o = 0, s = !0, c = !1, l = () => {
|
|
7306
7454
|
let l = t.current();
|
|
7307
|
-
|
|
7455
|
+
a = Bo(r, {
|
|
7308
7456
|
expanded: i,
|
|
7309
7457
|
query: e.search.value,
|
|
7310
7458
|
current: l
|
|
7311
|
-
}), o >= a.length && (o = a.length - 1), o < 0 && (o = 0)
|
|
7459
|
+
}), o >= a.length && (o = a.length - 1), o < 0 && (o = 0);
|
|
7460
|
+
let d = () => {
|
|
7461
|
+
let e = a.findIndex((e) => e.kind === "scene" && !e.entry.notScene);
|
|
7462
|
+
if (e >= 0) return e;
|
|
7463
|
+
let t = a.findIndex((e) => e.kind === "folder");
|
|
7464
|
+
return t >= 0 ? t : Math.max(0, a.findIndex((e) => e.kind === "scene"));
|
|
7465
|
+
};
|
|
7466
|
+
if (s) {
|
|
7312
7467
|
let e = a.findIndex((e) => e.kind === "scene" && e.current);
|
|
7313
|
-
o = e >= 0 ? e :
|
|
7314
|
-
} else
|
|
7315
|
-
let e = a.findIndex((e) => e.kind === "scene");
|
|
7316
|
-
o = e >= 0 ? e : 0, c = !1;
|
|
7317
|
-
}
|
|
7468
|
+
o = e >= 0 ? e : d(), s = !1, c = !1;
|
|
7469
|
+
} else c &&= (o = d(), !1);
|
|
7318
7470
|
if (e.list.textContent = "", a.length === 0) {
|
|
7319
7471
|
let t = document.createElement("div");
|
|
7320
7472
|
t.className = "scene-empty", t.textContent = r.length ? `no scene matches “${e.search.value.trim()}”` : "no .json files in this project yet — create a scene below", e.list.appendChild(t);
|
|
7321
7473
|
}
|
|
7322
|
-
let
|
|
7474
|
+
let f = n();
|
|
7323
7475
|
a.forEach((n, r) => {
|
|
7324
7476
|
let i = document.createElement("div");
|
|
7325
7477
|
i.className = n.kind === "folder" ? "scene-row scene-folder" : "scene-row", i.style.paddingLeft = `${6 + n.depth * 14}px`, r === o && i.classList.add("active");
|
|
7326
|
-
let a =
|
|
7327
|
-
n.kind === "folder" ? (a.classList.add("chevron"), n.open || a.classList.add("collapsed"), a.appendChild(Ye())) : a.textContent = "◇", i.append(a,
|
|
7478
|
+
let a = Go("scene-caret", "");
|
|
7479
|
+
n.kind === "folder" ? (a.classList.add("chevron"), n.open || a.classList.add("collapsed"), a.appendChild(Ye())) : a.textContent = "◇", i.append(a, Go("scene-name", n.label), Go("scene-meta", n.kind === "folder" ? n.scenes > 0 ? `${n.scenes} scene${n.scenes === 1 ? "" : "s"}` : `${n.count} file${n.count === 1 ? "" : "s"}` : [
|
|
7328
7480
|
n.entry.scene ? [n.entry.scene.dimension, `${n.entry.scene.nodes} node${n.entry.scene.nodes === 1 ? "" : "s"}`].filter(Boolean).join(" · ") : "not a scene",
|
|
7329
|
-
|
|
7330
|
-
|
|
7481
|
+
Uo(n.entry.modified, f),
|
|
7482
|
+
Ho(n.entry.size)
|
|
7331
7483
|
].filter(Boolean).join(" · "))), n.kind === "scene" && (n.current && i.classList.add("current"), n.entry.notScene ? (i.classList.add("not-scene"), i.title = `${n.entry.rel}\n\nnot a scene: ${n.entry.notScene}`) : i.title = n.entry.rel), i.addEventListener("click", () => {
|
|
7332
7484
|
o = r, n.kind === "folder" ? u(n.path) : t.open(n.entry);
|
|
7333
7485
|
}), e.list.appendChild(i);
|
|
7334
7486
|
});
|
|
7335
|
-
let
|
|
7336
|
-
e.count.textContent =
|
|
7487
|
+
let p = r.length, m = a.filter((e) => e.kind === "scene").length;
|
|
7488
|
+
e.count.textContent = p === 0 ? "" : m === p ? `${p}` : `${m} / ${p}`, e.path.placeholder = Wo(a[o]), e.list.querySelector(".active")?.scrollIntoView({ block: "nearest" });
|
|
7337
7489
|
}, u = (e) => {
|
|
7338
7490
|
i.has(e) ? i.delete(e) : i.add(e), l();
|
|
7339
7491
|
}, d = (e) => {
|
|
@@ -7370,15 +7522,15 @@ function Ho(e, t, n = () => Date.now()) {
|
|
|
7370
7522
|
n.className = "scene-empty", n.textContent = `could not list scenes: ${t instanceof Error ? t.message : String(t)}`, e.list.appendChild(n), e.count.textContent = "";
|
|
7371
7523
|
return;
|
|
7372
7524
|
}
|
|
7373
|
-
if (i.size === 0) i =
|
|
7374
|
-
else for (let e of
|
|
7525
|
+
if (i.size === 0) i = Vo(r, t.current());
|
|
7526
|
+
else for (let e of zo(t.current())) i.add(e);
|
|
7375
7527
|
s = !0, l(), e.search.focus(), e.search.select();
|
|
7376
7528
|
} };
|
|
7377
7529
|
}
|
|
7378
7530
|
//#endregion
|
|
7379
7531
|
//#region src/shell.ts
|
|
7380
|
-
var Uo = "\n<header id=\"topbar\">\n <div class=\"brand\">\n <span class=\"brand-mark\">in</span>\n <strong>incanto</strong><span class=\"brand-sub\">editor</span>\n </div>\n <div id=\"file-chip\" title=\"\">\n <svg aria-hidden=\"true\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"/><path d=\"M14 2v6h6\"/></svg>\n <span id=\"file-path\"></span>\n </div>\n <span id=\"engine-version\" class=\"pill\"></span>\n <span class=\"spacer\"></span>\n <button type=\"button\" id=\"lang-btn\" class=\"ghost\" title=\"Language / 언어\">\n <span id=\"lang-current\">EN</span>\n <svg aria-hidden=\"true\" width=\"9\" height=\"9\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"><path d=\"m6 9 6 6 6-6\"/></svg>\n </button>\n <button type=\"button\" id=\"docs-btn\" class=\"ghost\" title=\"Node documentation\">\n <svg aria-hidden=\"true\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M4 19.5A2.5 2.5 0 0 1 6.5 17H20\"/><path d=\"M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z\"/></svg>\n docs\n </button>\n <button type=\"button\" id=\"scenes-btn\" class=\"ghost\" hidden>\n <svg aria-hidden=\"true\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M3 7V5a2 2 0 0 1 2-2h2M17 3h2a2 2 0 0 1 2 2v2M21 17v2a2 2 0 0 1-2 2h-2M7 21H5a2 2 0 0 1-2-2v-2\"/></svg>\n scenes\n </button>\n <button type=\"button\" id=\"fit-btn\" class=\"ghost\" title=\"Frame the selected node — or the whole scene when nothing is selected (F)\">⌖ frame</button>\n <button type=\"button\" id=\"undo-btn\" class=\"ghost\" title=\"Undo (Ctrl/Cmd+Z)\" disabled>↩ undo</button>\n <button type=\"button\" id=\"play-btn\" class=\"play\" title=\"Run the scene with physics + input\">\n <svg aria-hidden=\"true\" width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M8 5v14l11-7z\"/></svg>\n play\n </button>\n <button type=\"button\" id=\"save-btn\" class=\"primary\" disabled>save</button>\n</header>\n<div id=\"error-banner\" hidden>\n <span id=\"error-text\"></span>\n <button type=\"button\" id=\"error-close\" title=\"Dismiss (Esc)\">✕</button>\n</div>\n<div id=\"play-notice\" hidden></div>\n<div id=\"edit-notice\" hidden></div>\n<main>\n <aside id=\"tree-pane\">\n <button type=\"button\" class=\"pane-title explorer-section section-toggle\" data-section=\"assets\">\n <span class=\"chev\"><svg aria-hidden=\"true\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\"><path d=\"m6 9 6 6 6-6\"/></svg></span> assets\n <span class=\"spacer\"></span>\n <span id=\"group-add-btn\" class=\"ghost section-add\" title=\"Add a group (folder)\" role=\"button\">\n <svg aria-hidden=\"true\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M3 6a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\"/><path d=\"M12 11v6M9 14h6\"/></svg>\n </span>\n <span id=\"asset-add-btn\" class=\"ghost section-add\" title=\"Add an asset\" role=\"button\">+</span>\n </button>\n <div id=\"asset-tree\" data-body=\"assets\"></div>\n <button type=\"button\" class=\"pane-title explorer-section section-toggle\" data-section=\"scene\">\n <span class=\"chev\"><svg aria-hidden=\"true\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\"><path d=\"m6 9 6 6 6-6\"/></svg></span> scene\n </button>\n <div id=\"scene-body\" data-body=\"scene\">\n <div id=\"tree\"></div>\n <div id=\"tree-actions\">\n <select id=\"add-type\" title=\"Node type to add\"></select>\n <button type=\"button\" id=\"add-btn\" class=\"ghost\" title=\"Add child to the selected node\">+</button>\n <button type=\"button\" id=\"generate-btn\" class=\"ghost\" title=\"Generate an environment under the selected node\">\n <svg aria-hidden=\"true\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M12 3v4M12 17v4M3 12h4M17 12h4M5.6 5.6l2.8 2.8M15.6 15.6l2.8 2.8M18.4 5.6l-2.8 2.8M8.4 15.6l-2.8 2.8\"/></svg>\n </button>\n <button type=\"button\" id=\"delete-btn\" class=\"ghost danger\" title=\"Delete the selected node\">✕</button>\n </div>\n </div>\n </aside>\n <section id=\"viewport-pane\">\n <div id=\"mode-toolbar\">\n <button type=\"button\" id=\"tool-move\" class=\"tool active\" title=\"Move (W)\">\n <svg aria-hidden=\"true\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M12 2v20M2 12h20M8 6l4-4 4 4M8 18l4 4 4-4M6 8l-4 4 4 4M18 8l4 4-4 4\"/></svg>\n </button>\n <button type=\"button\" id=\"tool-rotate\" class=\"tool\" title=\"Rotate (E)\">\n <svg aria-hidden=\"true\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M21 12a9 9 0 1 1-3-6.7\"/><path d=\"M21 3v5h-5\"/></svg>\n </button>\n <button type=\"button\" id=\"tool-scale\" class=\"tool\" title=\"Scale (R)\">\n <svg aria-hidden=\"true\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M21 3 9 15\"/><path d=\"M21 8V3h-5\"/><rect x=\"3\" y=\"13\" width=\"8\" height=\"8\" rx=\"1\"/></svg>\n </button>\n <span class=\"tool-divider\"></span>\n <button type=\"button\" id=\"tool-colliders\" class=\"tool active\" title=\"Show colliders\">\n <svg aria-hidden=\"true\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-dasharray=\"3 2\"><rect x=\"4\" y=\"4\" width=\"16\" height=\"16\" rx=\"2\"/></svg>\n </button>\n </div>\n <canvas id=\"viewport\"></canvas>\n <canvas id=\"overlay\"></canvas>\n <canvas id=\"play-canvas\" hidden></canvas>\n <div id=\"hints-dock\">\n <div id=\"hints\" class=\"hints\">\n <span><b>click</b> select</span><span><b>drag</b> move</span><span><b>wheel</b> zoom</span><span><b>W/E/R</b> move/rotate/scale</span><span><b>⇧</b> snap</span><span><b>right-drag</b> pan</span><span><b>F</b> frame selected</span>\n </div>\n <div id=\"hints-3d\" class=\"hints\" hidden>\n <span><b>drag</b> orbit</span><span><b>right-drag</b> pan</span><span><b>wheel</b> zoom</span><span><b>W/E/R</b> mode</span><span><b>⇧</b> snap</span><span><b>F</b> frame selected</span><span><b>0</b> game cam</span>\n </div>\n <button type=\"button\" id=\"hints-toggle\" title=\"Controls\">\n <svg aria-hidden=\"true\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\"><rect x=\"2\" y=\"6\" width=\"20\" height=\"12\" rx=\"2\"/><path d=\"M6 10h.01M10 10h.01M14 10h.01M18 10h.01M6 14h.01M18 14h.01M9 14h6\"/></svg>\n </button>\n </div>\n <button type=\"button\" id=\"gameview-btn\" class=\"ghost\" title=\"View through the game camera — exactly what running the scene shows (0)\">\n <svg aria-hidden=\"true\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M3 7h12v10H3z\"/><path d=\"M15 10l6-3v10l-6-3\"/></svg>\n game cam\n </button>\n </section>\n <aside id=\"inspector-pane\">\n <div class=\"pane-title\">inspector</div>\n <div id=\"inspector\"></div>\n </aside>\n</main>\n<div id=\"picker\" hidden>\n <div id=\"picker-card\">\n <div class=\"pane-title picker-title\">\n open a scene\n <button type=\"button\" id=\"picker-close\" title=\"Close (Esc)\">✕</button>\n </div>\n <div id=\"picker-find\">\n <input id=\"picker-search\" type=\"search\" placeholder=\"filter — ↑↓ move · → open · ⏎ load\" />\n <span id=\"picker-count\"></span>\n </div>\n <div id=\"picker-list\"></div>\n <div id=\"picker-new\">\n <input id=\"picker-path\" type=\"text\" placeholder=\"src/new-level.scene.json\" />\n <button type=\"button\" id=\"picker-create\" class=\"primary\">create</button>\n </div>\n </div>\n</div>\n<div id=\"docs\" hidden>\n <div id=\"docs-card\">\n <div class=\"pane-title picker-title\">\n incanto nodes\n <button type=\"button\" id=\"docs-close\" title=\"Close (Esc)\">✕</button>\n </div>\n <div id=\"docs-layout\">\n <nav id=\"docs-tabs\"></nav>\n <div id=\"docs-body\"></div>\n </div>\n </div>\n</div>\n<div id=\"confirm\" hidden>\n <div id=\"confirm-card\">\n <div class=\"pane-title picker-title\">\n <span id=\"confirm-title\">still referenced</span>\n <button type=\"button\" id=\"confirm-close\" title=\"Close (Esc)\">✕</button>\n </div>\n <div id=\"confirm-body\">\n <div id=\"confirm-text\"></div>\n <div id=\"confirm-list\"></div>\n </div>\n <div id=\"confirm-actions\">\n <button type=\"button\" id=\"confirm-cancel\" class=\"ghost\">cancel</button>\n <button type=\"button\" id=\"confirm-alt\" class=\"ghost\" hidden>save & open</button>\n <button type=\"button\" id=\"confirm-delete\">unlink & delete</button>\n </div>\n </div>\n</div>\n<div id=\"generate\" hidden>\n <div id=\"generate-card\">\n <div class=\"pane-title picker-title\">\n generate environment\n <button type=\"button\" id=\"generate-close\" title=\"Close (Esc)\">✕</button>\n </div>\n <div id=\"generate-body\"></div>\n <div id=\"generate-actions\">\n <span id=\"generate-status\"></span>\n <button type=\"button\" id=\"generate-cancel\" class=\"ghost\">cancel</button>\n <button type=\"button\" id=\"generate-insert\" class=\"primary\">insert</button>\n </div>\n </div>\n</div>\n<div id=\"popover\" hidden></div>\n", Wo = Math.PI / 180, Go = 180 / Math.PI;
|
|
7381
|
-
function
|
|
7532
|
+
var qo = "\n<header id=\"topbar\">\n <div class=\"brand\">\n <span class=\"brand-mark\">in</span>\n <strong>incanto</strong><span class=\"brand-sub\">editor</span>\n </div>\n <div id=\"file-chip\" title=\"\">\n <svg aria-hidden=\"true\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"/><path d=\"M14 2v6h6\"/></svg>\n <span id=\"file-path\"></span>\n </div>\n <span id=\"engine-version\" class=\"pill\"></span>\n <span class=\"spacer\"></span>\n <button type=\"button\" id=\"lang-btn\" class=\"ghost\" title=\"Language / 언어\">\n <span id=\"lang-current\">EN</span>\n <svg aria-hidden=\"true\" width=\"9\" height=\"9\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"><path d=\"m6 9 6 6 6-6\"/></svg>\n </button>\n <button type=\"button\" id=\"docs-btn\" class=\"ghost\" title=\"Node documentation\">\n <svg aria-hidden=\"true\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M4 19.5A2.5 2.5 0 0 1 6.5 17H20\"/><path d=\"M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z\"/></svg>\n docs\n </button>\n <button type=\"button\" id=\"scenes-btn\" class=\"ghost\" hidden>\n <svg aria-hidden=\"true\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M3 7V5a2 2 0 0 1 2-2h2M17 3h2a2 2 0 0 1 2 2v2M21 17v2a2 2 0 0 1-2 2h-2M7 21H5a2 2 0 0 1-2-2v-2\"/></svg>\n scenes\n </button>\n <button type=\"button\" id=\"fit-btn\" class=\"ghost\" title=\"Frame the selected node — or the whole scene when nothing is selected (F)\">⌖ frame</button>\n <button type=\"button\" id=\"undo-btn\" class=\"ghost\" title=\"Undo (Ctrl/Cmd+Z)\" disabled>↩ undo</button>\n <button type=\"button\" id=\"play-btn\" class=\"play\" title=\"Run the scene with physics + input\">\n <svg aria-hidden=\"true\" width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M8 5v14l11-7z\"/></svg>\n play\n </button>\n <button type=\"button\" id=\"save-btn\" class=\"primary\" disabled>save</button>\n</header>\n<div id=\"error-banner\" hidden>\n <span id=\"error-text\"></span>\n <button type=\"button\" id=\"error-close\" title=\"Dismiss (Esc)\">✕</button>\n</div>\n<div id=\"play-notice\" hidden></div>\n<div id=\"edit-notice\" hidden></div>\n<main>\n <aside id=\"tree-pane\">\n <button type=\"button\" class=\"pane-title explorer-section section-toggle\" data-section=\"assets\">\n <span class=\"chev\"><svg aria-hidden=\"true\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\"><path d=\"m6 9 6 6 6-6\"/></svg></span> assets\n <span class=\"spacer\"></span>\n <span id=\"group-add-btn\" class=\"ghost section-add\" title=\"Add a group (folder)\" role=\"button\">\n <svg aria-hidden=\"true\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M3 6a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\"/><path d=\"M12 11v6M9 14h6\"/></svg>\n </span>\n <span id=\"asset-add-btn\" class=\"ghost section-add\" title=\"Add an asset\" role=\"button\">+</span>\n </button>\n <div id=\"asset-tree\" data-body=\"assets\"></div>\n <button type=\"button\" class=\"pane-title explorer-section section-toggle\" data-section=\"scene\">\n <span class=\"chev\"><svg aria-hidden=\"true\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\"><path d=\"m6 9 6 6 6-6\"/></svg></span> scene\n </button>\n <div id=\"scene-body\" data-body=\"scene\">\n <div id=\"tree\"></div>\n <div id=\"tree-actions\">\n <select id=\"add-type\" title=\"Node type to add\"></select>\n <button type=\"button\" id=\"add-btn\" class=\"ghost\" title=\"Add child to the selected node\">+</button>\n <button type=\"button\" id=\"generate-btn\" class=\"ghost\" title=\"Generate an environment under the selected node\">\n <svg aria-hidden=\"true\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M12 3v4M12 17v4M3 12h4M17 12h4M5.6 5.6l2.8 2.8M15.6 15.6l2.8 2.8M18.4 5.6l-2.8 2.8M8.4 15.6l-2.8 2.8\"/></svg>\n </button>\n <button type=\"button\" id=\"delete-btn\" class=\"ghost danger\" title=\"Delete the selected node\">✕</button>\n </div>\n </div>\n </aside>\n <section id=\"viewport-pane\">\n <div id=\"mode-toolbar\">\n <button type=\"button\" id=\"tool-move\" class=\"tool active\" title=\"Move (W)\">\n <svg aria-hidden=\"true\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M12 2v20M2 12h20M8 6l4-4 4 4M8 18l4 4 4-4M6 8l-4 4 4 4M18 8l4 4-4 4\"/></svg>\n </button>\n <button type=\"button\" id=\"tool-rotate\" class=\"tool\" title=\"Rotate (E)\">\n <svg aria-hidden=\"true\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M21 12a9 9 0 1 1-3-6.7\"/><path d=\"M21 3v5h-5\"/></svg>\n </button>\n <button type=\"button\" id=\"tool-scale\" class=\"tool\" title=\"Scale (R)\">\n <svg aria-hidden=\"true\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M21 3 9 15\"/><path d=\"M21 8V3h-5\"/><rect x=\"3\" y=\"13\" width=\"8\" height=\"8\" rx=\"1\"/></svg>\n </button>\n <span class=\"tool-divider\"></span>\n <button type=\"button\" id=\"tool-colliders\" class=\"tool active\" title=\"Show colliders\">\n <svg aria-hidden=\"true\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-dasharray=\"3 2\"><rect x=\"4\" y=\"4\" width=\"16\" height=\"16\" rx=\"2\"/></svg>\n </button>\n </div>\n <canvas id=\"viewport\"></canvas>\n <canvas id=\"overlay\"></canvas>\n <canvas id=\"play-canvas\" hidden></canvas>\n <div id=\"hints-dock\">\n <div id=\"hints\" class=\"hints\">\n <span><b>click</b> select</span><span><b>drag</b> move</span><span><b>wheel</b> zoom</span><span><b>W/E/R</b> move/rotate/scale</span><span><b>⇧</b> snap</span><span><b>right-drag</b> pan</span><span><b>F</b> frame selected</span>\n </div>\n <div id=\"hints-3d\" class=\"hints\" hidden>\n <span><b>drag</b> orbit</span><span><b>right-drag</b> pan</span><span><b>wheel</b> zoom</span><span><b>W/E/R</b> mode</span><span><b>⇧</b> snap</span><span><b>F</b> frame selected</span><span><b>0</b> game cam</span>\n </div>\n <button type=\"button\" id=\"hints-toggle\" title=\"Controls\">\n <svg aria-hidden=\"true\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\"><rect x=\"2\" y=\"6\" width=\"20\" height=\"12\" rx=\"2\"/><path d=\"M6 10h.01M10 10h.01M14 10h.01M18 10h.01M6 14h.01M18 14h.01M9 14h6\"/></svg>\n </button>\n </div>\n <button type=\"button\" id=\"gameview-btn\" class=\"ghost\" title=\"View through the game camera — exactly what running the scene shows (0)\">\n <svg aria-hidden=\"true\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M3 7h12v10H3z\"/><path d=\"M15 10l6-3v10l-6-3\"/></svg>\n game cam\n </button>\n </section>\n <aside id=\"inspector-pane\">\n <div class=\"pane-title\">inspector</div>\n <div id=\"inspector\"></div>\n </aside>\n</main>\n<div id=\"picker\" hidden>\n <div id=\"picker-card\">\n <div class=\"pane-title picker-title\">\n open a scene\n <button type=\"button\" id=\"picker-close\" title=\"Close (Esc)\">✕</button>\n </div>\n <div id=\"picker-find\">\n <input id=\"picker-search\" type=\"search\" placeholder=\"filter — ↑↓ move · → open · ⏎ load\" />\n <span id=\"picker-count\"></span>\n </div>\n <div id=\"picker-list\"></div>\n <div id=\"picker-new\">\n <input id=\"picker-path\" type=\"text\" placeholder=\"src/new-level.scene.json\" />\n <button type=\"button\" id=\"picker-create\" class=\"primary\">create</button>\n </div>\n </div>\n</div>\n<div id=\"docs\" hidden>\n <div id=\"docs-card\">\n <div class=\"pane-title picker-title\">\n incanto nodes\n <button type=\"button\" id=\"docs-close\" title=\"Close (Esc)\">✕</button>\n </div>\n <div id=\"docs-layout\">\n <nav id=\"docs-tabs\"></nav>\n <div id=\"docs-body\"></div>\n </div>\n </div>\n</div>\n<div id=\"confirm\" hidden>\n <div id=\"confirm-card\">\n <div class=\"pane-title picker-title\">\n <span id=\"confirm-title\">still referenced</span>\n <button type=\"button\" id=\"confirm-close\" title=\"Close (Esc)\">✕</button>\n </div>\n <div id=\"confirm-body\">\n <div id=\"confirm-text\"></div>\n <div id=\"confirm-list\"></div>\n </div>\n <div id=\"confirm-actions\">\n <button type=\"button\" id=\"confirm-cancel\" class=\"ghost\">cancel</button>\n <button type=\"button\" id=\"confirm-alt\" class=\"ghost\" hidden>save & open</button>\n <button type=\"button\" id=\"confirm-delete\">unlink & delete</button>\n </div>\n </div>\n</div>\n<div id=\"generate\" hidden>\n <div id=\"generate-card\">\n <div class=\"pane-title picker-title\">\n generate environment\n <button type=\"button\" id=\"generate-close\" title=\"Close (Esc)\">✕</button>\n </div>\n <div id=\"generate-body\"></div>\n <div id=\"generate-actions\">\n <span id=\"generate-status\"></span>\n <button type=\"button\" id=\"generate-cancel\" class=\"ghost\">cancel</button>\n <button type=\"button\" id=\"generate-insert\" class=\"primary\">insert</button>\n </div>\n </div>\n</div>\n<div id=\"popover\" hidden></div>\n", Jo = Math.PI / 180, Yo = 180 / Math.PI;
|
|
7533
|
+
function Xo(e) {
|
|
7382
7534
|
let t = typeof e.type == "string" ? e.type : "";
|
|
7383
7535
|
if (!t) return 0;
|
|
7384
7536
|
let n;
|
|
@@ -7390,50 +7542,50 @@ function Ko(e) {
|
|
|
7390
7542
|
let r = n.position?.default;
|
|
7391
7543
|
return Array.isArray(r) ? r.length === 2 ? 2 : r.length === 3 ? 3 : 0 : 0;
|
|
7392
7544
|
}
|
|
7393
|
-
function
|
|
7545
|
+
function Zo(e, t) {
|
|
7394
7546
|
return Array.isArray(e) ? t.map((t, n) => typeof e[n] == "number" ? e[n] : t) : [...t];
|
|
7395
7547
|
}
|
|
7396
|
-
function
|
|
7397
|
-
let [n, r, i] =
|
|
7548
|
+
function Qo(e, t) {
|
|
7549
|
+
let [n, r, i] = Zo(e, t);
|
|
7398
7550
|
return [
|
|
7399
7551
|
n ?? t[0],
|
|
7400
7552
|
r ?? t[1],
|
|
7401
7553
|
i ?? t[2]
|
|
7402
7554
|
];
|
|
7403
7555
|
}
|
|
7404
|
-
function
|
|
7405
|
-
let [n, r] =
|
|
7556
|
+
function $o(e, t) {
|
|
7557
|
+
let [n, r] = Zo(e, t);
|
|
7406
7558
|
return [n ?? t[0], r ?? t[1]];
|
|
7407
7559
|
}
|
|
7408
|
-
function
|
|
7409
|
-
let t =
|
|
7560
|
+
function es(e) {
|
|
7561
|
+
let t = Xo(e), n = new Mi();
|
|
7410
7562
|
if (t === 0) return n;
|
|
7411
7563
|
let r = e.props ?? {};
|
|
7412
7564
|
if (t === 2) {
|
|
7413
|
-
let [e, t] =
|
|
7414
|
-
return n.compose(new
|
|
7565
|
+
let [e, t] = $o(r.position, [0, 0]), [i, a] = $o(r.scale, [1, 1]), o = typeof r.rotation == "number" ? r.rotation : 0;
|
|
7566
|
+
return n.compose(new K(e, t, 0), new mi().setFromEuler(new Bi(0, 0, o * Jo, "XYZ")), new K(i || 1, a || 1, 1));
|
|
7415
7567
|
}
|
|
7416
|
-
let [i, a, o] =
|
|
7568
|
+
let [i, a, o] = Qo(r.position, [
|
|
7417
7569
|
0,
|
|
7418
7570
|
0,
|
|
7419
7571
|
0
|
|
7420
|
-
]), [s, c, l] =
|
|
7572
|
+
]), [s, c, l] = Qo(r.rotation, [
|
|
7421
7573
|
0,
|
|
7422
7574
|
0,
|
|
7423
7575
|
0
|
|
7424
|
-
]), [u, d, f] =
|
|
7576
|
+
]), [u, d, f] = Qo(r.scale, [
|
|
7425
7577
|
1,
|
|
7426
7578
|
1,
|
|
7427
7579
|
1
|
|
7428
7580
|
]);
|
|
7429
|
-
return n.compose(new
|
|
7581
|
+
return n.compose(new K(i, a, o), new mi().setFromEuler(new Bi(s * Jo, c * Jo, l * Jo, "XYZ")), new K(u || 1, d || 1, f || 1));
|
|
7430
7582
|
}
|
|
7431
|
-
function
|
|
7432
|
-
let n =
|
|
7583
|
+
function ts(e, t) {
|
|
7584
|
+
let n = es(e), r = e;
|
|
7433
7585
|
for (let e of t) {
|
|
7434
7586
|
let t = r.children?.[e];
|
|
7435
7587
|
if (!t) break;
|
|
7436
|
-
n.multiply(
|
|
7588
|
+
n.multiply(es(t)), r = t;
|
|
7437
7589
|
}
|
|
7438
7590
|
return n;
|
|
7439
7591
|
}
|
|
@@ -7441,15 +7593,15 @@ function Q(e) {
|
|
|
7441
7593
|
let t = Math.round(e * 1e4) / 1e4;
|
|
7442
7594
|
return Object.is(t, -0) ? 0 : t;
|
|
7443
7595
|
}
|
|
7444
|
-
function
|
|
7445
|
-
let r =
|
|
7596
|
+
function ns(e, t, n) {
|
|
7597
|
+
let r = Xo(e);
|
|
7446
7598
|
if (r === 0) return;
|
|
7447
|
-
let i = new
|
|
7599
|
+
let i = new Mi().copy(t).invert().multiply(n), a = new K(), o = new mi(), s = new K();
|
|
7448
7600
|
i.decompose(a, o, s);
|
|
7449
|
-
let c = new
|
|
7601
|
+
let c = new Bi().setFromQuaternion(o, "XYZ"), l = e.props ?? {}, u = (e, t, n) => {
|
|
7450
7602
|
JSON.stringify(t) === JSON.stringify(n) ? delete l[e] : l[e] = t;
|
|
7451
7603
|
};
|
|
7452
|
-
r === 2 ? (u("position", [Q(a.x), Q(a.y)], [0, 0]), u("rotation", Q(c.z *
|
|
7604
|
+
r === 2 ? (u("position", [Q(a.x), Q(a.y)], [0, 0]), u("rotation", Q(c.z * Yo), 0), u("scale", [Q(s.x), Q(s.y)], [1, 1])) : (u("position", [
|
|
7453
7605
|
Q(a.x),
|
|
7454
7606
|
Q(a.y),
|
|
7455
7607
|
Q(a.z)
|
|
@@ -7458,9 +7610,9 @@ function Qo(e, t, n) {
|
|
|
7458
7610
|
0,
|
|
7459
7611
|
0
|
|
7460
7612
|
]), u("rotation", [
|
|
7461
|
-
Q(c.x *
|
|
7462
|
-
Q(c.y *
|
|
7463
|
-
Q(c.z *
|
|
7613
|
+
Q(c.x * Yo),
|
|
7614
|
+
Q(c.y * Yo),
|
|
7615
|
+
Q(c.z * Yo)
|
|
7464
7616
|
], [
|
|
7465
7617
|
0,
|
|
7466
7618
|
0,
|
|
@@ -7477,7 +7629,7 @@ function Qo(e, t, n) {
|
|
|
7477
7629
|
}
|
|
7478
7630
|
//#endregion
|
|
7479
7631
|
//#region src/rename-refs.ts
|
|
7480
|
-
function
|
|
7632
|
+
function rs(e, t) {
|
|
7481
7633
|
let n = [String(e.name ?? "")], r = e;
|
|
7482
7634
|
for (let e of t) {
|
|
7483
7635
|
let t = r.children?.[e];
|
|
@@ -7486,7 +7638,7 @@ function $o(e, t) {
|
|
|
7486
7638
|
}
|
|
7487
7639
|
return n;
|
|
7488
7640
|
}
|
|
7489
|
-
function
|
|
7641
|
+
function is(e, t, n, r) {
|
|
7490
7642
|
if (e === "" || e === ".") return null;
|
|
7491
7643
|
let i = n[n.length - 1];
|
|
7492
7644
|
if (i === void 0 || i === r) return null;
|
|
@@ -7509,7 +7661,7 @@ function es(e, t, n, r) {
|
|
|
7509
7661
|
let p = [...o];
|
|
7510
7662
|
return p[f] = r, (a ? "/" : "") + p.join("/");
|
|
7511
7663
|
}
|
|
7512
|
-
function
|
|
7664
|
+
function as(e) {
|
|
7513
7665
|
let t = (e) => Object.entries(e).filter(([, e]) => e?.nodePath).map(([e]) => e), n = typeof e.type == "string" ? e.type : "", i = [];
|
|
7514
7666
|
if (n) try {
|
|
7515
7667
|
i = t(s(n));
|
|
@@ -7523,31 +7675,31 @@ function ts(e) {
|
|
|
7523
7675
|
script: o
|
|
7524
7676
|
};
|
|
7525
7677
|
}
|
|
7526
|
-
function
|
|
7678
|
+
function os(e, t, n) {
|
|
7527
7679
|
let r = e.root;
|
|
7528
|
-
if (!r || t.length === 0) return r && t.length === 0 ?
|
|
7529
|
-
let i =
|
|
7680
|
+
if (!r || t.length === 0) return r && t.length === 0 ? ss(e, r, n) : [];
|
|
7681
|
+
let i = rs(r, t), a = cs(r, t);
|
|
7530
7682
|
if (!a) return [];
|
|
7531
|
-
let o =
|
|
7683
|
+
let o = ls(e, r, i, n);
|
|
7532
7684
|
return a.name = n, o;
|
|
7533
7685
|
}
|
|
7534
|
-
function
|
|
7535
|
-
let r =
|
|
7686
|
+
function ss(e, t, n) {
|
|
7687
|
+
let r = ls(e, t, [String(t.name ?? "")], n);
|
|
7536
7688
|
return t.name = n, r;
|
|
7537
7689
|
}
|
|
7538
|
-
function
|
|
7690
|
+
function cs(e, t) {
|
|
7539
7691
|
let n = e;
|
|
7540
7692
|
for (let e of t) if (n = n?.children?.[e], !n) return null;
|
|
7541
7693
|
return n ?? null;
|
|
7542
7694
|
}
|
|
7543
|
-
function
|
|
7695
|
+
function ls(e, t, n, r) {
|
|
7544
7696
|
let i = [], a = String(t.name ?? ""), o = e.connections;
|
|
7545
7697
|
Array.isArray(o) && o.forEach((e, t) => {
|
|
7546
7698
|
let o = e;
|
|
7547
7699
|
for (let e of ["from", "to"]) {
|
|
7548
7700
|
let s = o[e];
|
|
7549
7701
|
if (typeof s != "string") continue;
|
|
7550
|
-
let c =
|
|
7702
|
+
let c = is(s, [a], n, r);
|
|
7551
7703
|
c !== null && (o[e] = c, i.push({
|
|
7552
7704
|
where: `connections[${t}].${e}`,
|
|
7553
7705
|
from: s,
|
|
@@ -7556,7 +7708,7 @@ function as(e, t, n, r) {
|
|
|
7556
7708
|
}
|
|
7557
7709
|
});
|
|
7558
7710
|
let s = (a, o) => {
|
|
7559
|
-
let c =
|
|
7711
|
+
let c = as(a), l = a.script, d = [[
|
|
7560
7712
|
a.props,
|
|
7561
7713
|
c.props,
|
|
7562
7714
|
""
|
|
@@ -7568,7 +7720,7 @@ function as(e, t, n, r) {
|
|
|
7568
7720
|
for (let [a, s, c] of d) if (a) for (let l of s) {
|
|
7569
7721
|
let s = a[l], d = `${o.join("/")}.${c}${l}`;
|
|
7570
7722
|
if (typeof s == "string") {
|
|
7571
|
-
let e =
|
|
7723
|
+
let e = is(s, o, n, r);
|
|
7572
7724
|
e !== null && (a[l] = e, i.push({
|
|
7573
7725
|
where: d,
|
|
7574
7726
|
from: s,
|
|
@@ -7576,25 +7728,25 @@ function as(e, t, n, r) {
|
|
|
7576
7728
|
}));
|
|
7577
7729
|
} else Array.isArray(s) ? s.forEach((e, t) => {
|
|
7578
7730
|
if (typeof e != "string") return;
|
|
7579
|
-
let a =
|
|
7731
|
+
let a = is(e, o, n, r);
|
|
7580
7732
|
a !== null && (s[t] = a, i.push({
|
|
7581
7733
|
where: `${d}[${t}]`,
|
|
7582
7734
|
from: e,
|
|
7583
7735
|
to: a
|
|
7584
7736
|
}));
|
|
7585
|
-
}) : u(s) &&
|
|
7737
|
+
}) : u(s) && us(e, t, s, n, r, d, i);
|
|
7586
7738
|
}
|
|
7587
7739
|
let f = a.children ?? [];
|
|
7588
7740
|
for (let e of f) s(e, [...o, String(e.name ?? "")]);
|
|
7589
7741
|
};
|
|
7590
7742
|
return s(t, [a]), i;
|
|
7591
7743
|
}
|
|
7592
|
-
function
|
|
7744
|
+
function us(e, t, n, r, i, a, o) {
|
|
7593
7745
|
let s = n["@const"];
|
|
7594
7746
|
if (typeof s != "string") return;
|
|
7595
7747
|
let c = e.constants, l = c?.[s];
|
|
7596
7748
|
if (typeof l != "string" || !l.startsWith("%") && !l.startsWith("/")) return;
|
|
7597
|
-
let u =
|
|
7749
|
+
let u = is(l, [String(t.name ?? "")], r, i);
|
|
7598
7750
|
u !== null && (c[s] = u, o.push({
|
|
7599
7751
|
where: `constants.${s} (${a})`,
|
|
7600
7752
|
from: l,
|
|
@@ -7603,7 +7755,7 @@ function os(e, t, n, r, i, a, o) {
|
|
|
7603
7755
|
}
|
|
7604
7756
|
//#endregion
|
|
7605
7757
|
//#region src/state.ts
|
|
7606
|
-
var
|
|
7758
|
+
var ds = class {
|
|
7607
7759
|
working;
|
|
7608
7760
|
selection = [];
|
|
7609
7761
|
extra = [];
|
|
@@ -7631,7 +7783,7 @@ var ss = class {
|
|
|
7631
7783
|
undoStack = [];
|
|
7632
7784
|
listeners = /* @__PURE__ */ new Set();
|
|
7633
7785
|
constructor(e) {
|
|
7634
|
-
this.working = e, this.working.root &&
|
|
7786
|
+
this.working = e, this.working.root && fs(this.working.root), this.original = JSON.stringify(this.working);
|
|
7635
7787
|
}
|
|
7636
7788
|
get dirty() {
|
|
7637
7789
|
return JSON.stringify(this.working) !== this.original;
|
|
@@ -7664,8 +7816,8 @@ var ss = class {
|
|
|
7664
7816
|
renameNode(e, t) {
|
|
7665
7817
|
let n = this.nodeAt(e);
|
|
7666
7818
|
if (!n) return null;
|
|
7667
|
-
let r = this.parentOf(e), i = r ?
|
|
7668
|
-
return i === n.name ? [] : this.transact(() =>
|
|
7819
|
+
let r = this.parentOf(e), i = r ? xs(r, t, n) : t;
|
|
7820
|
+
return i === n.name ? [] : this.transact(() => os(this.working, e, i));
|
|
7669
7821
|
}
|
|
7670
7822
|
priorError(e) {
|
|
7671
7823
|
if (!this.validator) return null;
|
|
@@ -7679,35 +7831,35 @@ var ss = class {
|
|
|
7679
7831
|
return this.moveNodes([e], t, n)?.[0] ?? null;
|
|
7680
7832
|
}
|
|
7681
7833
|
moveNodes(e, t, n) {
|
|
7682
|
-
let r =
|
|
7834
|
+
let r = _s(e).filter((e) => e.length > 0);
|
|
7683
7835
|
if (r.length === 0) return null;
|
|
7684
7836
|
for (let e of r) if (e.length <= t.length && e.every((e, n) => e === t[n])) return null;
|
|
7685
7837
|
let i = this.working.root, a = r.map((e) => this.nodeAt(e)).filter((e) => e !== null);
|
|
7686
7838
|
if (a.length !== r.length) return null;
|
|
7687
7839
|
let o = this.nodeAt(t);
|
|
7688
7840
|
if (!o || a.includes(o)) return null;
|
|
7689
|
-
let s = r.map((e) =>
|
|
7841
|
+
let s = r.map((e) => ts(i, e));
|
|
7690
7842
|
return this.transact(() => {
|
|
7691
|
-
for (let e of a)
|
|
7843
|
+
for (let e of a) ys(i, e);
|
|
7692
7844
|
let e, t;
|
|
7693
7845
|
if (n === "into") e = o, e.children ||= [], t = e.children.length;
|
|
7694
7846
|
else {
|
|
7695
|
-
let r =
|
|
7847
|
+
let r = vs(i, o);
|
|
7696
7848
|
if (!r) return null;
|
|
7697
7849
|
e = r.parent, t = r.index + +(n === "after");
|
|
7698
7850
|
}
|
|
7699
7851
|
let r = [];
|
|
7700
7852
|
a.forEach((n, r) => {
|
|
7701
|
-
n.name =
|
|
7853
|
+
n.name = xs(e, n.name ?? "Node"), e.children?.splice(t + r, 0, n);
|
|
7702
7854
|
});
|
|
7703
7855
|
for (let e of a) {
|
|
7704
|
-
let t =
|
|
7856
|
+
let t = bs(i, e);
|
|
7705
7857
|
if (!t) return null;
|
|
7706
7858
|
r.push(t);
|
|
7707
7859
|
}
|
|
7708
7860
|
return r.forEach((e, t) => {
|
|
7709
7861
|
let n = s[t], r = a[t];
|
|
7710
|
-
!n || !r ||
|
|
7862
|
+
!n || !r || ns(r, ts(i, e.slice(0, -1)), n);
|
|
7711
7863
|
}), r;
|
|
7712
7864
|
});
|
|
7713
7865
|
}
|
|
@@ -7716,17 +7868,17 @@ var ss = class {
|
|
|
7716
7868
|
let t = this.nodeAt(e), n = this.parentOf(e);
|
|
7717
7869
|
return !t || !n?.children ? null : this.transact(() => {
|
|
7718
7870
|
let r = JSON.parse(JSON.stringify(t));
|
|
7719
|
-
r.name =
|
|
7871
|
+
r.name = xs(n, t.name ?? "Node"), ps(r);
|
|
7720
7872
|
let i = e[e.length - 1] + 1;
|
|
7721
7873
|
return n.children?.splice(i, 0, r), [...e.slice(0, -1), i];
|
|
7722
7874
|
});
|
|
7723
7875
|
}
|
|
7724
7876
|
removeNodes(e) {
|
|
7725
|
-
let t =
|
|
7877
|
+
let t = _s(e).filter((e) => e.length > 0);
|
|
7726
7878
|
if (t.length === 0) return !1;
|
|
7727
7879
|
let n = this.working.root, r = t.map((e) => this.nodeAt(e)).filter((e) => e !== null);
|
|
7728
7880
|
return this.transact(() => {
|
|
7729
|
-
for (let e of r)
|
|
7881
|
+
for (let e of r) ys(n, e);
|
|
7730
7882
|
return !0;
|
|
7731
7883
|
}) === !0;
|
|
7732
7884
|
}
|
|
@@ -7736,16 +7888,16 @@ var ss = class {
|
|
|
7736
7888
|
insertNode(e, t) {
|
|
7737
7889
|
if (!this.working.root) {
|
|
7738
7890
|
let t = JSON.parse(JSON.stringify(e));
|
|
7739
|
-
return
|
|
7891
|
+
return ps(t), this.transact(() => (this.working.root = t, []));
|
|
7740
7892
|
}
|
|
7741
7893
|
let n = this.nodeAt(t);
|
|
7742
7894
|
return n ? this.transact(() => {
|
|
7743
7895
|
let r = JSON.parse(JSON.stringify(e));
|
|
7744
|
-
return r.name =
|
|
7896
|
+
return r.name = xs(n, r.name ?? "Node"), ps(r), n.children ||= [], n.children.push(r), [...t, n.children.length - 1];
|
|
7745
7897
|
}) : null;
|
|
7746
7898
|
}
|
|
7747
7899
|
findRemovalReferences(e) {
|
|
7748
|
-
let t =
|
|
7900
|
+
let t = _s(e).filter((e) => e.length > 0), n = this.working.root, r = t.map((e) => this.nodeAt(e)).filter((e) => e !== null), i = /* @__PURE__ */ new Set(), a = [];
|
|
7749
7901
|
for (let e of t) {
|
|
7750
7902
|
let t = [], r = n;
|
|
7751
7903
|
for (let n of e) {
|
|
@@ -7835,9 +7987,9 @@ var ss = class {
|
|
|
7835
7987
|
return s;
|
|
7836
7988
|
}
|
|
7837
7989
|
removeNodesUnlinking(e) {
|
|
7838
|
-
let t = this.findRemovalReferences(e), n =
|
|
7990
|
+
let t = this.findRemovalReferences(e), n = _s(e).filter((e) => e.length > 0), r = this.working.root, i = n.map((e) => this.nodeAt(e)).filter((e) => e !== null), a = new Set(t.filter((e) => e.kind === "uid").map((e) => e.value)), o = new Set(t.filter((e) => e.kind === "connection").map((e) => e.connectionIndex));
|
|
7839
7991
|
return this.transact(() => {
|
|
7840
|
-
o.size > 0 && (this.working.connections = (this.working.connections ?? []).filter((e, t) => !o.has(t))), a.size > 0 &&
|
|
7992
|
+
o.size > 0 && (this.working.connections = (this.working.connections ?? []).filter((e, t) => !o.has(t))), a.size > 0 && ms(this.working, a, i);
|
|
7841
7993
|
for (let e of t) {
|
|
7842
7994
|
if (e.kind !== "prop" || !e.prop || e.prop.required) continue;
|
|
7843
7995
|
let t = this.nodeAt(e.prop.path);
|
|
@@ -7845,7 +7997,7 @@ var ss = class {
|
|
|
7845
7997
|
let n = e.prop.bag === "props" ? t.props : t.script?.props;
|
|
7846
7998
|
n && delete n[e.prop.key];
|
|
7847
7999
|
}
|
|
7848
|
-
for (let e of i)
|
|
8000
|
+
for (let e of i) ys(r, e);
|
|
7849
8001
|
return !0;
|
|
7850
8002
|
}) === !0;
|
|
7851
8003
|
}
|
|
@@ -7854,7 +8006,7 @@ var ss = class {
|
|
|
7854
8006
|
this.reset(e), this.original = t;
|
|
7855
8007
|
}
|
|
7856
8008
|
reset(e) {
|
|
7857
|
-
this.working = e, this.working.root &&
|
|
8009
|
+
this.working = e, this.working.root && fs(this.working.root), this.original = JSON.stringify(this.working), this.undoStack = [], this.selection = [], this.emit();
|
|
7858
8010
|
}
|
|
7859
8011
|
markSaved() {
|
|
7860
8012
|
this.original = JSON.stringify(this.working), this.emit();
|
|
@@ -7886,7 +8038,7 @@ var ss = class {
|
|
|
7886
8038
|
return this.pendingGroups.delete(e) && this.pendingGroups.add(t), this.selectedGroup = t, this.mutate(() => {
|
|
7887
8039
|
for (let i of r) {
|
|
7888
8040
|
let r = `${t}/${i.slice(e.length + 1)}`;
|
|
7889
|
-
n[r] = n[i], delete n[i],
|
|
8041
|
+
n[r] = n[i], delete n[i], hs(this.working, `$${i}`, `$${r}`);
|
|
7890
8042
|
}
|
|
7891
8043
|
}), r.length === 0 && this.emit(), !0;
|
|
7892
8044
|
}
|
|
@@ -7898,7 +8050,7 @@ var ss = class {
|
|
|
7898
8050
|
renameAssetKey(e, t) {
|
|
7899
8051
|
let n = this.assetMap();
|
|
7900
8052
|
return !(e in n) || !t || t === e || t in n ? !1 : (this.selectedAsset = t, this.mutate(() => {
|
|
7901
|
-
n[t] = n[e], delete n[e],
|
|
8053
|
+
n[t] = n[e], delete n[e], hs(this.working, `$${e}`, `$${t}`);
|
|
7902
8054
|
}), !0);
|
|
7903
8055
|
}
|
|
7904
8056
|
deleteGroup(e) {
|
|
@@ -7924,7 +8076,7 @@ var ss = class {
|
|
|
7924
8076
|
this.emit();
|
|
7925
8077
|
}
|
|
7926
8078
|
allSelections() {
|
|
7927
|
-
return [...this.selection === null ? [] : [this.selection, ...this.extra]].sort(
|
|
8079
|
+
return [...this.selection === null ? [] : [this.selection, ...this.extra]].sort(gs);
|
|
7928
8080
|
}
|
|
7929
8081
|
isSelected(e) {
|
|
7930
8082
|
let t = e.join(".");
|
|
@@ -7937,67 +8089,67 @@ var ss = class {
|
|
|
7937
8089
|
for (let e of this.listeners) e();
|
|
7938
8090
|
}
|
|
7939
8091
|
};
|
|
7940
|
-
function
|
|
8092
|
+
function fs(e) {
|
|
7941
8093
|
(typeof e.uid != "string" || e.uid === "") && (e.uid = p());
|
|
7942
|
-
for (let t of e.children ?? [])
|
|
8094
|
+
for (let t of e.children ?? []) fs(t);
|
|
7943
8095
|
}
|
|
7944
|
-
function
|
|
8096
|
+
function ps(e) {
|
|
7945
8097
|
e.uid = p();
|
|
7946
|
-
for (let t of e.children ?? [])
|
|
8098
|
+
for (let t of e.children ?? []) ps(t);
|
|
7947
8099
|
}
|
|
7948
|
-
function
|
|
8100
|
+
function ms(e, t, n) {
|
|
7949
8101
|
if (Array.isArray(e)) {
|
|
7950
|
-
for (let r = e.length - 1; r >= 0; r--) typeof e[r] == "string" && t.has(e[r]) ? e.splice(r, 1) :
|
|
8102
|
+
for (let r = e.length - 1; r >= 0; r--) typeof e[r] == "string" && t.has(e[r]) ? e.splice(r, 1) : ms(e[r], t, n);
|
|
7951
8103
|
return;
|
|
7952
8104
|
}
|
|
7953
8105
|
if (typeof e == "object" && e) {
|
|
7954
8106
|
if (n.includes(e)) return;
|
|
7955
|
-
for (let [r, i] of Object.entries(e)) r !== "uid" && (typeof i == "string" && t.has(i) ? delete e[r] :
|
|
8107
|
+
for (let [r, i] of Object.entries(e)) r !== "uid" && (typeof i == "string" && t.has(i) ? delete e[r] : ms(i, t, n));
|
|
7956
8108
|
}
|
|
7957
8109
|
}
|
|
7958
|
-
function
|
|
8110
|
+
function hs(e, t, n) {
|
|
7959
8111
|
if (Array.isArray(e)) {
|
|
7960
8112
|
e.forEach((r, i) => {
|
|
7961
|
-
r === t ? e[i] = n :
|
|
8113
|
+
r === t ? e[i] = n : hs(r, t, n);
|
|
7962
8114
|
});
|
|
7963
8115
|
return;
|
|
7964
8116
|
}
|
|
7965
|
-
if (typeof e == "object" && e) for (let [r, i] of Object.entries(e)) i === t ? e[r] = n :
|
|
8117
|
+
if (typeof e == "object" && e) for (let [r, i] of Object.entries(e)) i === t ? e[r] = n : hs(i, t, n);
|
|
7966
8118
|
}
|
|
7967
|
-
function
|
|
8119
|
+
function gs(e, t) {
|
|
7968
8120
|
for (let n = 0; n < Math.min(e.length, t.length); n++) if (e[n] !== t[n]) return e[n] - t[n];
|
|
7969
8121
|
return e.length - t.length;
|
|
7970
8122
|
}
|
|
7971
|
-
function
|
|
7972
|
-
let t = [...e].sort(
|
|
8123
|
+
function _s(e) {
|
|
8124
|
+
let t = [...e].sort(gs), n = [];
|
|
7973
8125
|
for (let e of t) n.some((t) => t.length <= e.length && t.every((t, n) => t === e[n])) || n.push(e);
|
|
7974
8126
|
return n;
|
|
7975
8127
|
}
|
|
7976
|
-
function
|
|
8128
|
+
function vs(e, t) {
|
|
7977
8129
|
let n = e.children?.indexOf(t) ?? -1;
|
|
7978
8130
|
if (n >= 0) return {
|
|
7979
8131
|
parent: e,
|
|
7980
8132
|
index: n
|
|
7981
8133
|
};
|
|
7982
8134
|
for (let n of e.children ?? []) {
|
|
7983
|
-
let e =
|
|
8135
|
+
let e = vs(n, t);
|
|
7984
8136
|
if (e) return e;
|
|
7985
8137
|
}
|
|
7986
8138
|
return null;
|
|
7987
8139
|
}
|
|
7988
|
-
function
|
|
7989
|
-
let n =
|
|
8140
|
+
function ys(e, t) {
|
|
8141
|
+
let n = vs(e, t);
|
|
7990
8142
|
n?.parent.children?.splice(n.index, 1);
|
|
7991
8143
|
}
|
|
7992
|
-
function
|
|
8144
|
+
function bs(e, t) {
|
|
7993
8145
|
if (e === t) return [];
|
|
7994
8146
|
for (let [n, r] of (e.children ?? []).entries()) {
|
|
7995
|
-
let e =
|
|
8147
|
+
let e = bs(r, t);
|
|
7996
8148
|
if (e) return [n, ...e];
|
|
7997
8149
|
}
|
|
7998
8150
|
return null;
|
|
7999
8151
|
}
|
|
8000
|
-
function
|
|
8152
|
+
function xs(e, t, n) {
|
|
8001
8153
|
let r = new Set((e.children ?? []).filter((e) => e !== n).map((e) => e.name));
|
|
8002
8154
|
if (!r.has(t)) return t;
|
|
8003
8155
|
let i = 2;
|
|
@@ -8006,21 +8158,51 @@ function _s(e, t, n) {
|
|
|
8006
8158
|
}
|
|
8007
8159
|
//#endregion
|
|
8008
8160
|
//#region src/styles.ts
|
|
8009
|
-
var vs = "\n/* ─── incanto editor · design system ──────────────────────────────────────── */\n:root {\n --bg-0: #0b0d14;\n --bg-1: #10131d;\n --bg-2: #161a27;\n --bg-3: #1d2231;\n --line: #262c3e;\n --line-strong: #343c54;\n --text: #e2e6f0;\n --text-dim: #9aa3bd;\n --text-faint: #5d6680;\n --accent: #6ee7dc;\n --accent-deep: #14b8a6;\n --violet: #a78bfa;\n --amber: #fbbf24;\n --rose: #fb7185;\n --green: #86efac;\n --shadow: 0 12px 40px rgba(0, 0, 0, 0.55);\n --r-sm: 6px;\n --r-md: 10px;\n color-scheme: dark;\n}\n* {\n box-sizing: border-box;\n}\n/* A button rule of \"display: inline-flex\" outranks the UA's [hidden] rule, so\n a button hidden from JS stays on screen. Say it once, loudly, here. */\n[hidden] {\n display: none !important;\n}\nhtml,\nbody {\n margin: 0;\n height: 100%;\n overflow: hidden;\n background: var(--bg-0);\n color: var(--text);\n font:\n 13px / 1.55 \"Inter\",\n -apple-system,\n \"Segoe UI\",\n system-ui,\n sans-serif;\n -webkit-font-smoothing: antialiased;\n}\ncode,\ntextarea,\n.mono {\n font-family: ui-monospace, \"SF Mono\", Menlo, monospace;\n}\n\n/* ─── top bar ─── */\n#topbar {\n display: flex;\n flex: none;\n align-items: center;\n gap: 10px;\n height: 46px;\n padding: 0 14px;\n background: linear-gradient(to bottom, var(--bg-2), var(--bg-1));\n border-bottom: 1px solid var(--line);\n}\n.brand {\n display: flex;\n align-items: baseline;\n gap: 7px;\n margin-right: 6px;\n}\n.brand-mark {\n display: inline-grid;\n place-items: center;\n width: 22px;\n height: 22px;\n border-radius: 6px;\n background: linear-gradient(135deg, var(--accent), var(--accent-deep));\n color: #07211d;\n font-weight: 800;\n font-size: 11px;\n align-self: center;\n}\n.brand strong {\n font-weight: 700;\n letter-spacing: 0.2px;\n}\n.brand-sub {\n color: var(--text-faint);\n font-size: 12px;\n}\n#file-chip {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n border: 1px solid var(--line);\n border-radius: 999px;\n background: var(--bg-1);\n color: var(--text-dim);\n font-size: 12px;\n max-width: 320px;\n}\n#file-path {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.pill {\n padding: 2px 9px;\n border-radius: 999px;\n background: var(--bg-3);\n color: var(--text-faint);\n font-size: 11px;\n font-family: ui-monospace, Menlo, monospace;\n}\n.spacer {\n flex: 1;\n}\n\n/* ─── buttons & controls ─── */\nbutton {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font: inherit;\n font-size: 12.5px;\n font-weight: 600;\n padding: 6px 12px;\n border-radius: var(--r-sm);\n border: 1px solid transparent;\n background: transparent;\n color: var(--text);\n cursor: pointer;\n transition:\n background 0.12s,\n border-color 0.12s,\n color 0.12s,\n opacity 0.12s;\n}\nbutton:disabled {\n opacity: 0.35;\n cursor: default;\n}\nbutton.ghost {\n border-color: var(--line);\n background: var(--bg-1);\n color: var(--text-dim);\n}\nbutton.ghost:not(:disabled):hover {\n border-color: var(--line-strong);\n color: var(--text);\n}\nbutton.ghost.danger:not(:disabled):hover {\n border-color: var(--rose);\n color: var(--rose);\n}\nbutton.primary {\n background: linear-gradient(135deg, var(--accent), var(--accent-deep));\n color: #06201c;\n}\nbutton.primary:not(:disabled):hover {\n filter: brightness(1.1);\n}\nbutton.play {\n border-color: var(--green);\n color: var(--green);\n background: rgba(134, 239, 172, 0.08);\n}\nbutton.play:not(:disabled):hover {\n background: rgba(134, 239, 172, 0.16);\n}\nbutton.play.stop {\n border-color: var(--rose);\n color: var(--rose);\n background: rgba(251, 113, 133, 0.1);\n}\ninput,\nselect,\ntextarea {\n font: inherit;\n font-size: 12.5px;\n color: var(--text);\n background: var(--bg-0);\n border: 1px solid var(--line);\n border-radius: var(--r-sm);\n padding: 6px 9px;\n transition: border-color 0.12s;\n min-width: 0;\n}\nselect {\n /*\n * padding cannot move the NATIVE dropdown arrow — the browser pins it to\n * the edge. Draw our own chevron, inset to mirror the left text padding.\n */\n appearance: none;\n padding-right: 30px;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239aa3bd' stroke-width='2.4'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 9px center;\n background-size: 12px;\n}\ninput:focus,\nselect:focus,\ntextarea:focus {\n outline: none;\n border-color: var(--accent-deep);\n}\ntextarea {\n resize: vertical;\n font-size: 12px;\n line-height: 1.5;\n}\ntextarea.invalid {\n border-color: var(--rose);\n background: rgba(251, 113, 133, 0.05);\n}\n\n/* ─── banners ─── */\n#error-banner {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 8px 10px 8px 14px;\n background: rgba(251, 113, 133, 0.1);\n color: var(--rose);\n border-bottom: 1px solid rgba(251, 113, 133, 0.35);\n max-height: 110px;\n overflow: auto;\n font-family: ui-monospace, Menlo, monospace;\n font-size: 12px;\n}\n#error-text {\n flex: 1;\n white-space: pre-wrap;\n}\n#error-close {\n flex: none;\n padding: 0 6px;\n color: var(--rose);\n opacity: 0.65;\n font-size: 13px;\n line-height: 1.4;\n}\n#error-close:hover {\n opacity: 1;\n}\n#edit-notice {\n padding: 7px 14px;\n background: rgba(147, 197, 253, 0.08);\n color: #93c5fd;\n border-bottom: 1px solid rgba(147, 197, 253, 0.25);\n font-size: 12px;\n}\n#play-notice {\n padding: 7px 14px;\n background: rgba(134, 239, 172, 0.08);\n color: var(--green);\n border-bottom: 1px solid rgba(134, 239, 172, 0.25);\n font-size: 12px;\n}\n\n/* ─── layout ─── */\n/* The editor's root owns the window — on its own page AND mounted over a\n running game, where the host's <body> is some game's and says nothing about\n how tall a percentage is. Fixing it to the viewport gives every pane below a\n definite height in both cases; without it main's percentage height has\n nothing to resolve against, main grows to its CONTENT, and the viewport\n canvas is sized to a scene tree three thousand pixels tall. */\n.incanto-editor-root {\n position: fixed;\n inset: 0;\n z-index: 30;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n background: var(--bg-0);\n color: var(--text);\n font:\n 13px / 1.55 \"Inter\",\n -apple-system,\n \"Segoe UI\",\n system-ui,\n sans-serif;\n -webkit-font-smoothing: antialiased;\n}\nmain {\n display: flex;\n flex: 1;\n min-height: 0;\n}\n#tree-pane {\n width: 256px;\n display: flex;\n flex-direction: column;\n background: var(--bg-1);\n border-right: 1px solid var(--line);\n}\n#inspector-pane {\n width: 336px;\n overflow-y: auto;\n background: var(--bg-1);\n border-left: 1px solid var(--line);\n}\n#viewport-pane {\n flex: 1;\n position: relative;\n background:\n radial-gradient(1200px 500px at 50% -10%, rgba(110, 231, 220, 0.05), transparent), var(--bg-0);\n overflow: hidden;\n}\n#viewport,\n#overlay,\n#play-canvas {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n}\n#overlay {\n cursor: crosshair;\n}\n#play-canvas {\n z-index: 3;\n}\n#hints-dock {\n position: absolute;\n bottom: 12px;\n right: 16px;\n z-index: 4;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n#hints-toggle {\n width: 40px;\n height: 40px;\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n border: 1px solid var(--line-strong);\n background: rgba(16, 19, 29, 0.88);\n color: var(--text-dim);\n backdrop-filter: blur(6px);\n}\n#hints-toggle:hover {\n color: var(--accent);\n border-color: var(--accent-deep);\n}\n#hints-dock.open #hints-toggle {\n color: var(--accent);\n}\n.hints {\n max-width: 0;\n opacity: 0;\n overflow: hidden;\n white-space: nowrap;\n transition:\n max-width 0.22s ease,\n opacity 0.18s ease,\n padding 0.22s ease;\n padding: 5px 0;\n display: flex;\n gap: 14px;\n border-radius: 999px;\n background: rgba(16, 19, 29, 0.85);\n border: 1px solid transparent;\n color: var(--text-faint);\n font-size: 11px;\n pointer-events: none;\n backdrop-filter: blur(6px);\n}\n.hints b {\n color: var(--text-dim);\n font-weight: 600;\n}\n.pane-title {\n padding: 9px 14px 7px;\n font-size: 10.5px;\n font-weight: 700;\n letter-spacing: 1.6px;\n text-transform: uppercase;\n color: var(--text-faint);\n border-bottom: 1px solid var(--line);\n}\n\n/* ─── tree ─── */\n#tree {\n flex: 1;\n overflow-y: auto;\n padding: 8px;\n}\n.tree-row {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 3px 8px 3px 4px;\n border-radius: var(--r-sm);\n cursor: pointer;\n white-space: nowrap;\n overflow: hidden;\n color: var(--text-dim);\n border: 1px solid transparent;\n position: relative;\n}\n.chevron {\n display: inline-flex;\n align-items: center;\n transition: transform 0.12s;\n}\n.chevron.collapsed {\n transform: rotate(-90deg);\n}\n.chevron-legacy {\n flex: none;\n width: 14px;\n text-align: center;\n color: var(--text-faint);\n font-size: 9px;\n cursor: pointer;\n user-select: none;\n}\n.chevron.leaf {\n cursor: default;\n opacity: 0.35;\n}\n.chevron:not(.leaf):hover {\n color: var(--accent);\n}\n.tree-children {\n margin-left: 11px;\n padding-left: 8px;\n border-left: 1px solid var(--line);\n}\n.tree-row.dragging {\n opacity: 0.4;\n}\n.tree-row.drop-into {\n background: rgba(110, 231, 220, 0.14);\n border-color: var(--accent);\n}\n.tree-row.drop-before::before,\n.tree-row.drop-after::after {\n content: \"\";\n position: absolute;\n left: 4px;\n right: 4px;\n height: 2px;\n border-radius: 2px;\n background: var(--accent);\n}\n.tree-row.drop-before::before {\n top: -1px;\n}\n.tree-row.drop-after::after {\n bottom: -1px;\n}\n.tree-row:hover {\n background: var(--bg-2);\n color: var(--text);\n}\n.tree-row.selected {\n background: rgba(110, 231, 220, 0.1);\n border-color: rgba(110, 231, 220, 0.3);\n color: var(--accent);\n}\n.tree-name {\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.tree-icon {\n flex: none;\n display: inline-grid;\n place-items: center;\n width: 17px;\n height: 17px;\n border-radius: 4px;\n cursor: help;\n}\n.tree-icon:hover {\n background: var(--bg-3);\n}\n.cat-core {\n background: rgba(167, 139, 250, 0.15);\n color: var(--violet);\n}\n.cat-2d {\n background: rgba(110, 231, 220, 0.12);\n color: var(--accent);\n}\n.cat-3d {\n background: rgba(251, 191, 36, 0.12);\n color: var(--amber);\n}\n.cat-body {\n background: rgba(134, 239, 172, 0.12);\n color: var(--green);\n}\n.cat-net {\n background: rgba(251, 113, 133, 0.12);\n color: var(--rose);\n}\n.scene-row {\n margin-bottom: 6px;\n color: var(--text-faint);\n}\n.scene-row.selected {\n color: var(--accent);\n}\n#tree-actions {\n display: flex;\n gap: 7px;\n padding: 10px;\n border-top: 1px solid var(--line);\n}\n#add-type {\n flex: 1;\n}\n\n/* ─── inspector ─── */\n#inspector {\n padding: 12px 14px 40px;\n}\n.section-title {\n display: flex;\n align-items: center;\n gap: 7px;\n margin: 16px 0 8px;\n font-size: 11px;\n font-weight: 700;\n letter-spacing: 1.4px;\n text-transform: uppercase;\n color: var(--accent);\n}\n.section-title:first-child {\n margin-top: 2px;\n}\n.section-title .rule {\n flex: 1;\n height: 1px;\n background: var(--line);\n}\n.field {\n display: grid;\n grid-template-columns: 92px 1fr;\n align-items: center;\n gap: 8px;\n margin-bottom: 7px;\n}\n/* A grid item's default min-width is auto: it refuses to shrink below its\n content's MIN-CONTENT width. One nowrap asset description was enough to push\n a whole field past the inspector — and no max-width: 100% further down can\n fix it, because 100% is then 100% of the already-grown track. The clamp has\n to come from here. */\n.field > * {\n min-width: 0;\n}\n.field > span {\n font-size: 11.5px;\n color: var(--text-dim);\n display: flex;\n align-items: center;\n gap: 5px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.field.wide {\n grid-template-columns: 1fr;\n}\n.field.wide > span {\n margin-bottom: 2px;\n}\n.vector-row {\n display: flex;\n gap: 6px;\n}\n.vector-row input {\n width: 100%;\n}\n.help-btn {\n flex: none;\n width: 15px;\n height: 15px;\n padding: 0;\n border-radius: 50%;\n border: 1px solid var(--line-strong);\n color: var(--text-faint);\n font-size: 10px;\n font-weight: 700;\n justify-content: center;\n}\n.help-btn:hover {\n border-color: var(--accent);\n color: var(--accent);\n}\n.chips {\n display: flex;\n flex-wrap: wrap;\n gap: 5px;\n padding: 5px 7px;\n border: 1px solid var(--line);\n border-radius: var(--r-sm);\n background: var(--bg-0);\n cursor: text;\n}\n.chip {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 1px 8px;\n border-radius: 999px;\n background: rgba(110, 231, 220, 0.12);\n color: var(--accent);\n font-size: 11.5px;\n}\n.chip button {\n padding: 0;\n font-size: 12px;\n color: inherit;\n opacity: 0.7;\n}\n.chips input {\n flex: 1;\n min-width: 70px;\n border: none;\n background: transparent;\n padding: 2px;\n}\n.chips input:focus {\n outline: none;\n}\n.subcard {\n border: 1px solid var(--line);\n border-radius: var(--r-md);\n background: var(--bg-2);\n padding: 10px;\n margin-bottom: 10px;\n}\n.subcard .field {\n grid-template-columns: 78px 1fr;\n}\n/* .field.wide is declared EARLIER and at equal specificity, so the rule above\n silently won inside a card: a full-width field (the asset picker) went back\n to two columns and its dropdown panel — a third grid child — was auto-placed\n into the 78px label column, four times too narrow to read. */\n.subcard .field.wide {\n grid-template-columns: 1fr;\n}\n.subcard .field.wide.has-const-picker {\n grid-template-columns: 1fr auto;\n}\n.subcard-head {\n display: flex;\n align-items: center;\n gap: 7px;\n margin-bottom: 8px;\n font-size: 11.5px;\n font-weight: 600;\n color: var(--text-dim);\n}\n.subcard-head .spacer {\n flex: 1;\n}\n.linklike {\n padding: 2px 6px;\n font-size: 11px;\n color: var(--accent);\n font-weight: 600;\n}\n.linklike:hover {\n text-decoration: underline;\n}\n.muted-note {\n font-size: 11px;\n color: var(--text-faint);\n margin: -2px 0 8px;\n}\n\n/* ─── asset picker ─── */\n.asset-control {\n display: flex;\n gap: 6px;\n align-items: center;\n}\n.asset-control input {\n flex: 1;\n min-width: 0;\n}\n.asset-toggle {\n flex: none;\n /* square and matched to the input beside it. The base control rule's 9px of\n side padding does not fit a 26px box, which left the chevron off-centre in\n a button that looked taller than it was wide. */\n width: 30px;\n height: 30px;\n padding: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n border: 1px solid var(--line);\n border-radius: var(--r-sm);\n background: var(--bg-1);\n color: var(--text-dim);\n font-size: 11px;\n}\n.asset-toggle:hover {\n border-color: var(--accent);\n color: var(--accent);\n}\n.asset-panel {\n min-width: 0;\n margin-top: 6px;\n border: 1px solid var(--line-strong);\n border-radius: var(--r-sm);\n background: var(--bg-0);\n padding: 6px;\n}\n.asset-search {\n width: 100%;\n margin-bottom: 6px;\n}\n.asset-options {\n display: flex;\n flex-direction: column;\n gap: 3px;\n min-width: 0;\n max-height: 220px;\n overflow-y: auto;\n}\nbutton.asset-option {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 1px;\n /* A flex ITEM has the same auto-min-width default as a grid item, so this is\n what stops one long description widening the whole panel.\n overflow-x, NOT overflow: plain hidden also removes the automatic\n MINIMUM SIZE on the block axis, and this button is an item of a\n max-height scroll container — so every row shrank to fit 220px instead of\n scrolling, collapsing 46px rows to 16px with the text squashed to 1px.\n flex: none is the other half: items in a capped column must keep their\n height and let the container scroll. */\n min-width: 0;\n overflow-x: clip;\n flex: none;\n padding: 5px 8px;\n text-align: left;\n border: 1px solid transparent;\n border-radius: var(--r-sm);\n background: var(--bg-2);\n color: var(--text);\n width: 100%;\n}\nbutton.asset-option:hover {\n border-color: var(--accent);\n background: var(--bg-3);\n}\nbutton.asset-option strong {\n font-size: 11.5px;\n font-weight: 600;\n /* asset keys are short today and a long one must still not widen the panel */\n max-width: 100%;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\nbutton.asset-option small {\n font-size: 10px;\n color: var(--text-faint);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 100%;\n}\n.asset-empty {\n font-size: 11px;\n color: var(--text-faint);\n padding: 4px 8px;\n}\n.asset-note {\n margin-top: 5px;\n}\n.varieties {\n cursor: default;\n}\n.variety-opt {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n font-size: 11.5px;\n color: var(--text-dim);\n cursor: pointer;\n}\n.variety-opt input[type=\"checkbox\"] {\n width: auto;\n}\n\n/* ─── popover (help) ─── */\n#popover {\n position: fixed;\n z-index: 50;\n width: 300px;\n /* A topic longer than the window still has to be readable to the end: the\n positioner pins it to the top and this lets the rest scroll. */\n max-height: calc(100vh - 16px);\n overflow-y: auto;\n overscroll-behavior: contain;\n background: var(--bg-3);\n border: 1px solid var(--line-strong);\n border-radius: var(--r-md);\n box-shadow: var(--shadow);\n padding: 12px 14px;\n font-size: 12px;\n color: var(--text-dim);\n}\n#popover h4 {\n margin: 0 0 6px;\n font-size: 12.5px;\n color: var(--text);\n}\n#popover code {\n background: var(--bg-0);\n padding: 1px 5px;\n border-radius: 4px;\n font-size: 11px;\n color: var(--accent);\n}\n#popover pre {\n margin: 8px 0 0;\n padding: 8px 10px;\n background: var(--bg-0);\n border-radius: var(--r-sm);\n font-size: 11px;\n line-height: 1.5;\n overflow-x: auto;\n color: var(--text-dim);\n}\n#popover .pop-actions {\n margin-top: 8px;\n display: flex;\n justify-content: flex-end;\n}\n\n/* ─── picker ─── */\n#picker {\n position: fixed;\n inset: 0;\n background: rgba(7, 9, 14, 0.78);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 40;\n backdrop-filter: blur(4px);\n}\n#picker[hidden] {\n display: none;\n}\n#picker-card {\n width: 460px;\n max-height: 72vh;\n background: var(--bg-2);\n border: 1px solid var(--line-strong);\n border-radius: 14px;\n box-shadow: var(--shadow);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n#picker-list {\n flex: 1;\n overflow-y: auto;\n padding: 6px;\n min-height: 120px;\n}\n#picker-list .tree-row {\n padding: 9px 12px;\n font-family: ui-monospace, Menlo, monospace;\n font-size: 12.5px;\n}\n#picker-find {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px;\n border-bottom: 1px solid var(--line);\n}\n#picker-search {\n flex: 1;\n}\n#picker-count {\n font-size: 11px;\n color: var(--text-faint);\n font-variant-numeric: tabular-nums;\n}\n/* one row of the project explorer: caret, name, and the facts, right-aligned */\n.scene-row {\n display: flex;\n align-items: center;\n gap: 7px;\n padding: 6px 10px 6px 6px;\n border-radius: 7px;\n cursor: pointer;\n font-size: 12.5px;\n user-select: none;\n}\n.scene-row:hover {\n background: var(--bg-3);\n}\n.scene-row.active {\n background: var(--bg-3);\n outline: 1px solid var(--line-strong);\n}\n.scene-name {\n font-family: ui-monospace, Menlo, monospace;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.scene-folder .scene-name {\n color: var(--text-dim);\n}\n.scene-row.current .scene-name {\n color: var(--accent);\n}\n.scene-caret {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 13px;\n flex: none;\n color: var(--text-faint);\n font-size: 9px;\n line-height: 1;\n}\n.scene-folder .scene-caret {\n color: var(--text-dim);\n}\n.scene-meta {\n margin-left: auto;\n padding-left: 10px;\n flex: none;\n font-size: 10.5px;\n color: var(--text-faint);\n font-variant-numeric: tabular-nums;\n}\n/* a JSON that is not a scene: still there, still clickable, visibly not one */\n.scene-row.not-scene .scene-name,\n.scene-row.not-scene .scene-meta {\n color: var(--text-faint);\n}\n.scene-row.not-scene .scene-caret {\n opacity: 0.4;\n}\n.scene-empty {\n padding: 22px 12px;\n text-align: center;\n color: var(--text-faint);\n font-size: 12px;\n}\n#picker-new {\n display: flex;\n gap: 8px;\n padding: 12px;\n border-top: 1px solid var(--line);\n}\n#picker-path {\n flex: 1;\n font-family: ui-monospace, Menlo, monospace;\n}\n\n/* ─── scrollbars ─── */\n::-webkit-scrollbar {\n width: 9px;\n height: 9px;\n}\n::-webkit-scrollbar-thumb {\n background: var(--line-strong);\n border-radius: 99px;\n border: 2px solid var(--bg-1);\n}\n::-webkit-scrollbar-track {\n background: transparent;\n}\n\nbody.playing #tree-pane,\nbody.playing #inspector-pane {\n pointer-events: none;\n opacity: 0.45;\n filter: saturate(0.6);\n transition: opacity 0.2s;\n}\n\n.rename-input {\n flex: 1;\n min-width: 0;\n padding: 1px 6px;\n font-size: 12.5px;\n}\n.balloon {\n position: fixed;\n z-index: 60;\n max-width: 230px;\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 8px 11px;\n background: var(--bg-3);\n border: 1px solid var(--line-strong);\n border-radius: var(--r-md);\n box-shadow: var(--shadow);\n font-size: 11.5px;\n color: var(--text-dim);\n}\n.balloon .balloon-title {\n color: var(--accent);\n font-size: 12px;\n font-weight: 700;\n}\n.context-menu {\n position: fixed;\n z-index: 60;\n min-width: 190px;\n padding: 5px;\n background: var(--bg-3);\n border: 1px solid var(--line-strong);\n border-radius: var(--r-md);\n box-shadow: var(--shadow);\n display: flex;\n flex-direction: column;\n}\n.menu-item {\n justify-content: space-between;\n padding: 6px 10px;\n border-radius: var(--r-sm);\n font-weight: 500;\n color: var(--text);\n}\n.menu-item:not(:disabled):hover {\n background: var(--bg-2);\n}\n.menu-item.danger:not(:disabled):hover {\n color: var(--rose);\n}\n.menu-item kbd {\n font-size: 10px;\n color: var(--text-faint);\n font-family: inherit;\n}\n.menu-divider {\n height: 1px;\n margin: 4px 6px;\n background: var(--line);\n}\n/* The play menu is a choice, not a command list: each row carries a label and\n the sentence that says what actually happens, stacked. */\n.play-menu {\n width: 290px;\n gap: 2px;\n}\n.play-menu-item {\n flex-direction: column;\n align-items: flex-start;\n gap: 2px;\n padding: 8px 10px;\n text-align: left;\n}\n.play-menu-hint {\n font-size: 11px;\n font-weight: 400;\n line-height: 1.35;\n color: var(--text-faint);\n}\n\n.hints[hidden] {\n display: none;\n}\n#hints-dock.open .hints:not([hidden]) {\n max-width: 1100px;\n opacity: 1;\n padding: 5px 14px;\n border-color: var(--line);\n}\nbody.playing #hints-dock {\n display: none;\n}\n\n#gameview-btn {\n position: absolute;\n top: 104px;\n right: 18px;\n z-index: 4;\n font-size: 11.5px;\n padding: 4px 10px;\n backdrop-filter: blur(6px);\n background: rgba(16, 19, 29, 0.8);\n}\n\n.field input[type=\"checkbox\"] {\n justify-self: start;\n width: 15px;\n height: 15px;\n accent-color: var(--accent-deep);\n cursor: pointer;\n}\n\n.picker-title {\n display: flex;\n align-items: center;\n justify-content: space-between;\n}\n#picker-close {\n padding: 0 4px;\n font-size: 12px;\n color: var(--text-faint);\n border: none;\n background: none;\n}\n#picker-close:hover {\n color: var(--text);\n}\n\n.uid-row {\n display: flex;\n gap: 6px;\n}\n.uid-row input {\n flex: 1;\n min-width: 0;\n font-size: 11.5px;\n}\n.uid-row .ghost {\n padding: 4px 8px;\n}\n#confirm {\n position: fixed;\n inset: 0;\n background: rgba(7, 9, 14, 0.78);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 70;\n backdrop-filter: blur(4px);\n}\n#confirm[hidden] {\n display: none;\n}\n#confirm-card {\n width: 480px;\n max-height: 70vh;\n display: flex;\n flex-direction: column;\n background: var(--bg-2);\n border: 1px solid var(--line-strong);\n border-radius: 14px;\n box-shadow: var(--shadow);\n overflow: hidden;\n}\n#confirm-body {\n padding: 14px;\n color: var(--text-dim);\n font-size: 12.5px;\n overflow-y: auto;\n}\n#confirm-list:empty {\n display: none; /* the group-delete confirm has no reference list */\n}\n#confirm-list {\n margin: 10px 0 0;\n padding: 10px 12px;\n background: var(--bg-0);\n border-radius: var(--r-sm);\n font-family: ui-monospace, Menlo, monospace;\n font-size: 11.5px;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n#confirm-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 12px 14px;\n border-top: 1px solid var(--line);\n}\n#confirm-delete {\n border-color: var(--rose);\n color: var(--rose);\n background: rgba(251, 113, 133, 0.08);\n}\n#confirm-delete:hover {\n background: rgba(251, 113, 133, 0.16);\n}\n\n.color-row {\n display: flex;\n gap: 6px;\n align-items: center;\n}\n.color-row input[type=\"color\"] {\n width: 30px;\n height: 26px;\n padding: 2px;\n cursor: pointer;\n}\n.color-row input[type=\"text\"] {\n flex: 1;\n min-width: 0;\n font-size: 11.5px;\n}\n.slider-row {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n.slider-row input[type=\"range\"] {\n flex: 1;\n accent-color: var(--accent-deep);\n padding: 0;\n border: none;\n background: transparent;\n}\n.slider-row input[type=\"number\"] {\n width: 64px;\n}\n.asset-row {\n display: flex;\n align-items: center;\n gap: 7px;\n padding: 5px 8px;\n border-radius: var(--r-sm);\n cursor: pointer;\n}\n.asset-row:hover,\n.asset-row.open {\n background: var(--bg-3);\n}\n.asset-key {\n color: var(--accent);\n}\n.asset-url {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--text-faint);\n font-size: 11px;\n font-family: ui-monospace, Menlo, monospace;\n}\n.danger-link {\n color: var(--text-faint);\n}\n.danger-link:hover {\n color: var(--rose);\n}\n.asset-editor {\n margin: 2px 0 10px;\n padding: 10px;\n border: 1px solid var(--line);\n border-radius: var(--r-sm);\n background: var(--bg-0);\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.asset-editor .field {\n grid-template-columns: 52px 1fr;\n margin-bottom: 4px;\n}\n/* A row carrying the library button has THREE cells. Without this the button is\n a third child of a two-column grid: it wraps onto a second row INSIDE the\n label column, gets 52px to live in, and crushes \"📚 library\" against its own\n borders — which reads as a button with no padding, and no amount of padding\n fixes it. */\n.field.has-lib {\n grid-template-columns: 92px 1fr auto;\n}\n.asset-editor .field.has-lib {\n grid-template-columns: 52px 1fr auto;\n}\n.subcard .field.has-lib {\n grid-template-columns: 78px 1fr auto;\n}\n.meta-row {\n display: grid;\n grid-template-columns: 1fr 1fr 24px;\n gap: 6px;\n align-items: center;\n}\n.meta-row input {\n font-size: 11.5px;\n padding: 4px 7px;\n}\n\n#docs {\n position: fixed;\n inset: 0;\n background: rgba(7, 9, 14, 0.8);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 60;\n backdrop-filter: blur(5px);\n}\n#docs[hidden] {\n display: none;\n}\n#docs-card {\n width: min(920px, 92vw);\n height: min(680px, 88vh);\n background: var(--bg-2);\n border: 1px solid var(--line-strong);\n border-radius: 14px;\n box-shadow: var(--shadow);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n#docs-layout {\n display: flex;\n flex: 1;\n min-height: 0;\n}\n#docs-tabs {\n width: 168px;\n border-right: 1px solid var(--line);\n padding: 10px;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.docs-tab {\n justify-content: flex-start;\n padding: 7px 12px;\n border-radius: var(--r-sm);\n color: var(--text-dim);\n font-weight: 500;\n}\n.docs-tab:hover {\n background: var(--bg-3);\n color: var(--text);\n}\n.docs-tab.active {\n background: rgba(110, 231, 220, 0.1);\n color: var(--accent);\n font-weight: 700;\n}\n#docs-body {\n flex: 1;\n overflow-y: auto;\n padding: 18px 24px 40px;\n}\n#docs-body h2 {\n margin: 0 0 6px;\n font-size: 18px;\n}\n#docs-body h3 {\n margin: 18px 0 4px;\n font-size: 13.5px;\n color: var(--accent);\n}\n#docs-body p {\n margin: 4px 0 10px;\n color: var(--text-dim);\n line-height: 1.7;\n font-size: 13px;\n}\n.docs-intro {\n padding: 10px 14px;\n background: var(--bg-1);\n border: 1px solid var(--line);\n border-radius: var(--r-md);\n}\n.docs-node {\n border: 1px solid var(--line);\n border-radius: var(--r-md);\n margin-bottom: 8px;\n overflow: hidden;\n}\n.docs-node.open {\n border-color: var(--line-strong);\n}\n.docs-node-head {\n width: 100%;\n display: flex;\n align-items: center;\n gap: 9px;\n padding: 9px 12px;\n border-radius: 0;\n text-align: left;\n}\n.docs-node-head:hover {\n background: var(--bg-3);\n}\n.docs-node-head strong {\n font-size: 13px;\n}\n.docs-summary {\n color: var(--text-faint);\n font-size: 12px;\n font-weight: 400;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.docs-detail {\n padding: 4px 14px 12px;\n border-top: 1px solid var(--line);\n background: var(--bg-1);\n}\n.docs-props {\n width: 100%;\n border-collapse: collapse;\n margin-top: 8px;\n font-size: 11.5px;\n}\n.docs-props th {\n text-align: left;\n color: var(--text-faint);\n font-weight: 600;\n padding: 4px 8px;\n border-bottom: 1px solid var(--line);\n}\n.docs-props td {\n padding: 3px 8px;\n border-bottom: 1px solid var(--line);\n color: var(--text-dim);\n}\n\n#mode-toolbar {\n position: absolute;\n top: 12px;\n left: 12px;\n z-index: 4;\n display: flex;\n gap: 4px;\n padding: 4px;\n border-radius: var(--r-md);\n background: rgba(16, 19, 29, 0.85);\n border: 1px solid var(--line);\n backdrop-filter: blur(6px);\n}\n.tool {\n width: 30px;\n height: 28px;\n justify-content: center;\n padding: 0;\n border-radius: var(--r-sm);\n color: var(--text-faint);\n}\n.tool:hover {\n color: var(--text);\n background: var(--bg-3);\n}\n.tool.active {\n background: rgba(110, 231, 220, 0.14);\n color: var(--accent);\n}\n\n.lang-menu {\n min-width: 130px;\n}\n.lang-check {\n color: var(--accent);\n font-weight: 700;\n}\n\n.explorer-section {\n display: flex;\n align-items: center;\n justify-content: space-between;\n border-top: 1px solid var(--line);\n margin-top: 4px;\n}\n.explorer-section .ghost {\n padding: 1px 8px;\n}\n#asset-tree {\n padding: 2px 8px 10px;\n overflow-y: auto;\n max-height: 30%;\n}\n.explorer-empty {\n padding: 4px 10px;\n font-size: 11px;\n}\n.asset-row .asset-key {\n color: var(--accent);\n font-family: ui-monospace, Menlo, monospace;\n}\n/* an asset the renderer could not fetch: the node is fine, the art is not */\n.asset-row.asset-failed .asset-key {\n color: #f87171;\n text-decoration: underline dotted #f87171;\n}\n.asset-icon-texture {\n color: #f0abfc;\n}\n.asset-icon-spritesheet {\n color: #fbbf24;\n}\n.asset-icon-model {\n color: #7aa2ff;\n}\n.asset-icon-animation {\n color: #86efac;\n}\n.uid-value {\n display: flex;\n align-items: center;\n gap: 7px;\n min-width: 0;\n}\n.uid-value code {\n font-family: ui-monospace, Menlo, monospace;\n font-size: 11px;\n color: var(--text-dim);\n letter-spacing: 0.3px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.uid-copy {\n padding: 3px 5px;\n border: none;\n background: none;\n border-radius: var(--r-sm);\n color: var(--text-faint);\n line-height: 0;\n}\n.uid-copy:hover {\n color: var(--text);\n background: var(--bg-3);\n}\n.uid-copy.copied {\n color: var(--accent);\n font-size: 10px;\n line-height: 1;\n}\n\n.section-toggle {\n width: 100%;\n height: 30px; /* IDENTICAL header height for ASSETS and SCENE */\n box-sizing: border-box;\n padding-top: 0;\n padding-bottom: 0;\n display: flex;\n align-items: center;\n justify-content: flex-start;\n gap: 6px;\n text-align: left;\n cursor: pointer;\n background: var(--bg-1);\n border: none;\n border-top: 1px solid var(--line-strong);\n border-bottom: 1px solid var(--line);\n border-radius: 0;\n}\n.section-toggle:hover {\n color: var(--text);\n}\n.section-toggle .chev {\n display: inline-flex;\n transition: transform 0.12s;\n color: var(--text-dim);\n}\n.section-toggle.collapsed .chev {\n transform: rotate(-90deg);\n}\n.section-add {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 20px;\n padding: 0 6px;\n font-size: 13px;\n color: var(--text-dim);\n border: 1px solid var(--line-strong);\n border-radius: var(--r-sm);\n background: var(--bg-2);\n}\n.section-add:hover {\n background: var(--bg-3);\n color: var(--accent);\n border-color: var(--accent-deep);\n}\n[data-body][hidden],\naside#tree-pane #scene-body[hidden] {\n /* outranks the #scene-body flex rule — [hidden] must always win */\n display: none;\n}\n#scene-body {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n}\n.asset-folder {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n color: var(--text-dim);\n cursor: pointer;\n border-radius: var(--r-sm);\n}\n.asset-folder:hover {\n background: var(--bg-3);\n}\n.asset-folder .chev {\n display: inline-flex;\n color: var(--text-dim);\n transition: transform 0.12s;\n}\n.asset-folder.collapsed .chev {\n transform: rotate(-90deg);\n}\n.asset-folder svg {\n color: #e7c66a;\n}\n.asset-row.grouped {\n margin-left: 18px;\n}\n\n.asset-folder .count {\n margin-left: auto;\n color: var(--text-faint);\n font-size: 10.5px;\n}\n.asset-folder.selected {\n background: rgba(110, 231, 220, 0.08);\n color: var(--accent);\n}\n.asset-folder.drop-target,\n#asset-tree.drop-target {\n outline: 1.5px dashed var(--accent);\n outline-offset: -2px;\n border-radius: var(--r-sm);\n}\n.asset-row[draggable=\"true\"] {\n cursor: grab;\n}\n\nbody.playing #mode-toolbar,\nbody.playing #gameview-btn {\n display: none; /* gizmo tools and the free-cam escape make no sense mid-play */\n}\n\n.tool-divider {\n width: 1px;\n height: 18px;\n background: var(--line);\n margin: 0 2px;\n align-self: center;\n}\n\n/* ─── generate dialog ─── */\n#generate {\n position: fixed;\n inset: 0;\n background: rgba(7, 9, 14, 0.78);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 70;\n backdrop-filter: blur(4px);\n}\n#generate[hidden] {\n display: none;\n}\n#generate-card {\n width: 420px;\n max-height: 78vh;\n display: flex;\n flex-direction: column;\n background: var(--bg-2);\n border: 1px solid var(--line-strong);\n border-radius: 14px;\n box-shadow: var(--shadow);\n overflow: hidden;\n}\n#generate-body {\n padding: 14px;\n overflow-y: auto;\n}\n#generate-body .gen-hint {\n margin: 0 0 12px;\n font-size: 11.5px;\n color: var(--text-faint);\n}\n#generate-body .gen-desc {\n margin: 2px 0 12px;\n font-size: 11.5px;\n color: var(--text-dim);\n}\n#generate-params {\n padding-top: 2px;\n border-top: 1px solid var(--line);\n}\n#generate-params .field:first-child {\n margin-top: 10px;\n}\n.gen-seed-row {\n display: flex;\n gap: 6px;\n}\n.gen-seed-row input {\n flex: 1;\n min-width: 0;\n}\n.gen-seed-row .ghost {\n padding: 4px 9px;\n}\n#generate-actions {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n padding: 12px 14px;\n border-top: 1px solid var(--line);\n}\n#generate-status {\n margin-right: auto;\n font-size: 11px;\n color: var(--rose);\n}\n\n/* ---- scene constants + the prop \"bind to a constant\" picker ---- */\n/* The third grid column a bound-able prop row opens for its 🔗 picker. The\n .field grid is 92px 1fr; without this the picker is auto-placed into row 2\n column 1, tucked under the label where nobody finds it. */\n.field.has-const-picker {\n grid-template-columns: 92px 1fr auto;\n}\n.field.wide.has-const-picker {\n grid-template-columns: 1fr auto;\n}\n.const-picker {\n flex: none;\n width: 30px;\n border: 1px solid var(--line);\n border-radius: var(--r-sm);\n background: var(--bg-1);\n color: var(--text-dim);\n font-size: 12px;\n /* The base select rule reserves 9px + 30px of horizontal padding for its\n drawn chevron. In a 30px box that leaves the link glyph nowhere to be, so\n the control rendered as an empty rectangle. This one has no chevron. */\n padding: 0;\n background-image: none;\n text-align: center;\n text-align-last: center;\n height: 30px;\n}\n.const-picker:hover {\n border-color: var(--accent);\n color: var(--accent);\n}\n.field.const-bound > span {\n color: var(--accent);\n}\n.const-row {\n display: flex;\n gap: 6px;\n /* NOT stretch: .field carries a 7px bottom margin, so a stretched button\n grew to cover it and stood a third taller than the input beside it. */\n align-items: center;\n}\n.const-row .field {\n flex: 1;\n min-width: 0;\n}\n.const-del {\n flex: none;\n width: 30px;\n /* square, and matched to the input it sits beside, rather than to whatever\n the row's tallest margin box happens to be */\n height: 30px;\n /* the field's own bottom margin is the row's spacing; without this the button\n sits 3.5px low against the input */\n margin-bottom: 7px;\n /* the glyph sat right of centre: the base control rule gives every button\n 9px of side padding, which a 30px box has no room for */\n padding: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n border: 1px solid var(--line);\n border-radius: var(--r-sm);\n background: var(--bg-1);\n color: var(--text-dim);\n font-size: 11px;\n}\n.const-del:hover {\n border-color: var(--rose);\n color: var(--rose);\n}\n.const-add {\n display: flex;\n gap: 6px;\n align-items: stretch;\n margin-top: 6px;\n}\n.const-add input {\n flex: 1;\n min-width: 0;\n}\n\n/* ---- TileMap2D paint brush ---- */\n.tile-paint {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.paint-toggle {\n cursor: pointer;\n border: 1px solid var(--border, #444);\n border-radius: 6px;\n background: transparent;\n color: inherit;\n padding: 6px 10px;\n font: inherit;\n}\n.paint-toggle.on {\n background: #2e6b2e;\n border-color: #4a9e4a;\n color: #fff;\n}\n.paint-palette {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n align-items: center;\n}\n.paint-chip {\n cursor: pointer;\n width: 26px;\n height: 26px;\n border-radius: 5px;\n border: 1px solid var(--border, #444);\n background: transparent;\n color: inherit;\n font: 600 13px / 1 monospace;\n}\n.paint-chip.on {\n background: #3a5a8c;\n border-color: #6a9ae0;\n color: #fff;\n}\n.paint-brush-input {\n width: 32px;\n text-align: center;\n font: 600 13px / 1 monospace;\n background: transparent;\n color: inherit;\n border: 1px solid var(--border, #444);\n border-radius: 5px;\n padding: 4px;\n}\n.paint-hint {\n font-size: 11px;\n opacity: 0.6;\n}\n\n/* ─── agent8 asset library ─── */\n.asset-lib {\n flex: none;\n height: 30px;\n /* room for the word: a bare icon next to a URL field reads as decoration,\n and nobody clicks decoration */\n padding: 0 16px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 7px;\n white-space: nowrap;\n border: 1px solid var(--line);\n border-radius: var(--r-sm);\n background: var(--bg-1);\n color: var(--fg-1);\n font-size: 12px;\n line-height: 1;\n}\n.asset-lib:hover {\n border-color: var(--accent);\n}\n.lib-backdrop {\n position: fixed;\n inset: 0;\n z-index: 70;\n display: grid;\n place-items: center;\n background: rgba(4, 6, 12, 0.72);\n backdrop-filter: blur(3px);\n}\n.lib-dialog {\n display: flex;\n flex-direction: column;\n width: min(1180px, 94vw);\n height: min(760px, 88vh);\n background: var(--bg-1);\n border: 1px solid var(--line-strong);\n border-radius: var(--r-md);\n box-shadow: var(--shadow);\n overflow: hidden;\n}\n.lib-head {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n border-bottom: 1px solid var(--line);\n background: var(--bg-2);\n}\n.lib-head strong {\n font-size: 13px;\n}\n.lib-sub {\n color: var(--accent);\n font-size: 12px;\n font-family: ui-monospace, Menlo, monospace;\n}\n.lib-search {\n margin-left: auto;\n width: 260px;\n}\n.lib-body {\n flex: 1;\n display: grid;\n grid-template-columns: 190px 1fr 320px;\n min-height: 0;\n}\n.lib-shelves {\n display: flex;\n flex-direction: column;\n min-height: 0;\n gap: 2px;\n padding: 8px 6px;\n overflow-y: auto;\n border-right: 1px solid var(--line);\n background: var(--bg-1);\n}\n.lib-shelf {\n justify-content: flex-start;\n padding: 6px 10px;\n border-radius: var(--r-sm);\n color: var(--text-dim);\n font-weight: 500;\n text-align: left;\n}\n.lib-shelf:hover {\n background: var(--bg-2);\n color: var(--text);\n}\n.lib-shelf.active {\n background: rgba(110, 231, 220, 0.12);\n color: var(--accent);\n}\n.lib-shelf.crumb {\n color: var(--text-faint);\n font-size: 11.5px;\n}\n.lib-shelf-count {\n margin-left: auto;\n color: var(--text-faint);\n font-size: 10px;\n font-family: ui-monospace, Menlo, monospace;\n}\n.lib-shelf-head {\n margin: 8px 0 2px;\n padding: 0 10px;\n color: var(--text-faint);\n font-size: 10px;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n}\n.lib-grid-pane {\n display: flex;\n flex-direction: column;\n min-width: 0;\n /* Grid items size to their content unless told not to. Without this the\n results pane grows past the dialog and takes the scrollbar with it. */\n min-height: 0;\n background: var(--bg-0);\n}\n.lib-status {\n padding: 7px 12px;\n color: var(--text-faint);\n font-size: 11.5px;\n border-bottom: 1px solid var(--line);\n}\n.lib-grid {\n flex: 1;\n /* A flex child will not shrink below its content without this, so flex:1\n plus overflow-y:auto grew the grid instead of scrolling it: the results ran\n off the bottom of the dialog with no way to reach them, and the\n infinite-scroll sentinel sat permanently in view. */\n min-height: 0;\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));\n /* Not \"auto\": once the grid has a definite height, an auto row sizes to its\n MIN-content, and a thumbnail sized by aspect-ratio contributes nothing to\n that — every row collapsed to the 14px of its filename. */\n grid-auto-rows: max-content;\n gap: 10px;\n align-content: start;\n padding: 12px;\n overflow-y: auto;\n}\n.lib-card {\n display: flex;\n flex-direction: column;\n gap: 5px;\n min-width: 0; /* grid item: without this the name pushes the card wider */\n padding: 6px;\n overflow: hidden;\n border: 1px solid var(--line);\n border-radius: var(--r-sm);\n background: var(--bg-1);\n font-weight: 500;\n}\n.lib-card:hover {\n border-color: var(--line-strong);\n}\n.lib-card.active {\n border-color: var(--accent);\n background: rgba(110, 231, 220, 0.08);\n}\n/* On the shelf, but not something this field can take. Shown — a library that\n hides most of itself is worse — just clearly second. */\n.lib-card.off-kind {\n opacity: 0.42;\n}\n.lib-card.off-kind:hover,\n.lib-card.off-kind.active {\n opacity: 1;\n}\n.lib-sentinel {\n grid-column: 1 / -1;\n height: 1px;\n}\n.lib-charpick {\n display: grid;\n grid-template-columns: auto 1fr auto auto;\n align-items: center;\n gap: 6px;\n padding: 7px 8px;\n border: 1px solid var(--line);\n border-radius: var(--r-sm);\n background: var(--bg-2);\n}\n.lib-charpick-label {\n color: var(--text-faint);\n font-size: 11px;\n white-space: nowrap;\n}\n.lib-charpick input {\n min-width: 0;\n padding: 4px 7px;\n font-size: 11px;\n font-family: ui-monospace, Menlo, monospace;\n text-overflow: ellipsis;\n}\n.lib-charpick button {\n padding: 4px 8px;\n font-size: 11px;\n}\n.lib-blocked {\n margin: 0;\n color: var(--warn, #e7c86e);\n font-size: 12px;\n line-height: 1.5;\n}\n.lib-thumb {\n display: grid;\n place-items: center;\n aspect-ratio: 1;\n border-radius: 4px;\n background: repeating-conic-gradient(var(--bg-3) 0% 25%, var(--bg-2) 0% 50%) 50% / 16px 16px;\n overflow: hidden;\n}\n.lib-thumb img {\n width: 100%;\n height: 100%;\n object-fit: contain;\n}\n.lib-glyph {\n width: 30px;\n height: 30px;\n color: var(--text-faint);\n}\n.lib-badge {\n position: absolute;\n right: 4px;\n bottom: 4px;\n padding: 1px 5px;\n border-radius: 999px;\n background: rgba(110, 231, 220, 0.16);\n color: var(--accent);\n font-size: 9px;\n font-style: normal;\n letter-spacing: 0.03em;\n}\n.lib-thumb {\n position: relative;\n}\n.lib-card-name {\n max-width: 100%;\n overflow: hidden;\n color: var(--text-dim);\n font-size: 11px;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.lib-more {\n margin: 0 12px 12px;\n}\n.lib-detail {\n display: flex;\n flex-direction: column;\n min-height: 0;\n gap: 10px;\n padding: 12px;\n overflow-y: auto;\n border-left: 1px solid var(--line);\n background: var(--bg-1);\n}\n.lib-stage {\n display: grid;\n place-items: center;\n aspect-ratio: 1;\n border: 1px solid var(--line);\n border-radius: var(--r-sm);\n background: repeating-conic-gradient(var(--bg-3) 0% 25%, var(--bg-2) 0% 50%) 50% / 18px 18px;\n overflow: hidden;\n}\n.lib-stage img {\n max-width: 100%;\n max-height: 100%;\n object-fit: contain;\n}\n.lib-preview3d,\n.lib-preview-canvas {\n width: 100%;\n height: 100%;\n display: block;\n cursor: grab;\n}\n.lib-preview-canvas:active {\n cursor: grabbing;\n}\n.lib-name {\n margin: 0;\n font-size: 13px;\n word-break: break-word;\n}\n.lib-desc {\n margin: 0;\n color: var(--text-dim);\n font-size: 12px;\n line-height: 1.5;\n}\n.lib-note {\n color: var(--accent);\n font-size: 11.5px;\n}\n.lib-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n}\n.lib-tag {\n padding: 2px 7px;\n border-radius: 999px;\n background: var(--bg-3);\n color: var(--text-faint);\n font-size: 10.5px;\n}\n.lib-facts {\n display: grid;\n grid-template-columns: 74px 1fr;\n gap: 3px 8px;\n margin: 0;\n font-size: 11.5px;\n}\n.lib-facts dt {\n color: var(--text-faint);\n}\n.lib-facts dd {\n margin: 0;\n color: var(--text-dim);\n font-family: ui-monospace, Menlo, monospace;\n}\n.lib-url {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n.lib-url code {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n padding: 5px 7px;\n border-radius: var(--r-sm);\n background: var(--bg-0);\n color: var(--text-faint);\n font-size: 10.5px;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.lib-actions {\n display: flex;\n gap: 6px;\n margin-top: auto;\n}\n.lib-actions button {\n flex: 1;\n justify-content: center;\n}\n.lib-empty,\n.lib-error {\n grid-column: 1 / -1;\n padding: 24px 12px;\n color: var(--text-faint);\n font-size: 12px;\n text-align: center;\n}\n.lib-error {\n color: var(--rose);\n}\n.lib-token {\n grid-column: 1 / -1;\n max-width: 520px;\n margin: 24px auto;\n padding: 16px;\n border: 1px solid var(--line-strong);\n border-radius: var(--r-md);\n background: var(--bg-1);\n}\n.lib-token-line {\n margin: 0 0 8px;\n font-size: 12.5px;\n}\n.lib-token-how {\n color: var(--text-faint);\n font-size: 11.5px;\n line-height: 1.6;\n}\n.lib-token-row {\n display: flex;\n gap: 6px;\n}\n.lib-token-row input {\n flex: 1;\n}\n\n/* ─── animation card ─── */\n.anim-card .slider-row {\n width: 100%;\n}\n.anim-upper {\n margin-top: 8px;\n padding-top: 8px;\n border-top: 1px solid var(--line);\n}\n.anim-upper > summary {\n color: var(--text-faint);\n font-size: 11.5px;\n cursor: pointer;\n list-style: none;\n}\n.anim-upper > summary::before {\n content: \"▸ \";\n}\n.anim-upper[open] > summary::before {\n content: \"▾ \";\n}\n.anim-upper > summary:hover {\n color: var(--text-dim);\n}\n\n/* ─── connections ─── */\n/* Signal wiring on the selected node. Dense on purpose: a row is four fields,\n and a node with a dozen connections still has to fit the inspector column. */\n.connections {\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding: 2px 0 6px;\n}\n.conn-group {\n font-size: 10px;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n opacity: 0.55;\n margin-top: 4px;\n}\n.conn-row {\n display: grid;\n grid-template-columns: 1fr 10px 1fr 1fr 18px;\n gap: 3px;\n align-items: center;\n}\n.conn-arrow {\n text-align: center;\n opacity: 0.5;\n font-size: 11px;\n}\n.conn-select,\n.conn-handler {\n min-width: 0;\n font-size: 11px;\n padding: 2px 4px;\n}\n.conn-select.dangling,\n.field input.dangling {\n border-color: #f87171;\n color: #f87171;\n}\n.conn-warn {\n font-size: 10px;\n color: #f87171;\n padding: 1px 0 3px;\n line-height: 1.35;\n}\n.conn-remove {\n border: 0;\n background: none;\n color: inherit;\n opacity: 0.4;\n cursor: pointer;\n font-size: 11px;\n padding: 0;\n}\n.conn-remove:hover {\n opacity: 1;\n color: #f87171;\n}\n.conn-add {\n padding-top: 2px;\n}\n.conn-add button {\n font-size: 11px;\n padding: 2px 8px;\n cursor: pointer;\n}\n.conn-add button:disabled {\n opacity: 0.4;\n cursor: default;\n}\n", ys = new Map(Nt.flatMap((e) => e.nodes.map((e) => [e.type, e.summary]))), bs = /* @__PURE__ */ new Set(), xs = null, Ss = null, Cs = null;
|
|
8010
|
-
|
|
8011
|
-
|
|
8012
|
-
|
|
8013
|
-
|
|
8014
|
-
|
|
8161
|
+
var Ss = "\n/* ─── incanto editor · design system ──────────────────────────────────────── */\n:root {\n --bg-0: #0b0d14;\n --bg-1: #10131d;\n --bg-2: #161a27;\n --bg-3: #1d2231;\n --line: #262c3e;\n --line-strong: #343c54;\n --text: #e2e6f0;\n --text-dim: #9aa3bd;\n --text-faint: #5d6680;\n --accent: #6ee7dc;\n --accent-deep: #14b8a6;\n --violet: #a78bfa;\n --amber: #fbbf24;\n --rose: #fb7185;\n --green: #86efac;\n --shadow: 0 12px 40px rgba(0, 0, 0, 0.55);\n --r-sm: 6px;\n --r-md: 10px;\n color-scheme: dark;\n}\n* {\n box-sizing: border-box;\n}\n/* A button rule of \"display: inline-flex\" outranks the UA's [hidden] rule, so\n a button hidden from JS stays on screen. Say it once, loudly, here. */\n[hidden] {\n display: none !important;\n}\nhtml,\nbody {\n margin: 0;\n height: 100%;\n overflow: hidden;\n background: var(--bg-0);\n color: var(--text);\n font:\n 13px / 1.55 \"Inter\",\n -apple-system,\n \"Segoe UI\",\n system-ui,\n sans-serif;\n -webkit-font-smoothing: antialiased;\n}\ncode,\ntextarea,\n.mono {\n font-family: ui-monospace, \"SF Mono\", Menlo, monospace;\n}\n\n/* ─── top bar ─── */\n#topbar {\n display: flex;\n flex: none;\n align-items: center;\n gap: 10px;\n height: 46px;\n padding: 0 14px;\n background: linear-gradient(to bottom, var(--bg-2), var(--bg-1));\n border-bottom: 1px solid var(--line);\n}\n.brand {\n display: flex;\n align-items: baseline;\n gap: 7px;\n margin-right: 6px;\n}\n.brand-mark {\n display: inline-grid;\n place-items: center;\n width: 22px;\n height: 22px;\n border-radius: 6px;\n background: linear-gradient(135deg, var(--accent), var(--accent-deep));\n color: #07211d;\n font-weight: 800;\n font-size: 11px;\n align-self: center;\n}\n.brand strong {\n font-weight: 700;\n letter-spacing: 0.2px;\n}\n.brand-sub {\n color: var(--text-faint);\n font-size: 12px;\n}\n#file-chip {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n border: 1px solid var(--line);\n border-radius: 999px;\n background: var(--bg-1);\n color: var(--text-dim);\n font-size: 12px;\n max-width: 320px;\n}\n#file-path {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.pill {\n padding: 2px 9px;\n border-radius: 999px;\n background: var(--bg-3);\n color: var(--text-faint);\n font-size: 11px;\n font-family: ui-monospace, Menlo, monospace;\n}\n.spacer {\n flex: 1;\n}\n\n/* ─── buttons & controls ─── */\nbutton {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font: inherit;\n font-size: 12.5px;\n font-weight: 600;\n padding: 6px 12px;\n border-radius: var(--r-sm);\n border: 1px solid transparent;\n background: transparent;\n color: var(--text);\n cursor: pointer;\n transition:\n background 0.12s,\n border-color 0.12s,\n color 0.12s,\n opacity 0.12s;\n}\nbutton:disabled {\n opacity: 0.35;\n cursor: default;\n}\nbutton.ghost {\n border-color: var(--line);\n background: var(--bg-1);\n color: var(--text-dim);\n}\nbutton.ghost:not(:disabled):hover {\n border-color: var(--line-strong);\n color: var(--text);\n}\nbutton.ghost.danger:not(:disabled):hover {\n border-color: var(--rose);\n color: var(--rose);\n}\nbutton.primary {\n background: linear-gradient(135deg, var(--accent), var(--accent-deep));\n color: #06201c;\n}\nbutton.primary:not(:disabled):hover {\n filter: brightness(1.1);\n}\nbutton.play {\n border-color: var(--green);\n color: var(--green);\n background: rgba(134, 239, 172, 0.08);\n}\nbutton.play:not(:disabled):hover {\n background: rgba(134, 239, 172, 0.16);\n}\nbutton.play.stop {\n border-color: var(--rose);\n color: var(--rose);\n background: rgba(251, 113, 133, 0.1);\n}\ninput,\nselect,\ntextarea {\n font: inherit;\n font-size: 12.5px;\n color: var(--text);\n background: var(--bg-0);\n border: 1px solid var(--line);\n border-radius: var(--r-sm);\n padding: 6px 9px;\n transition: border-color 0.12s;\n min-width: 0;\n}\nselect {\n /*\n * padding cannot move the NATIVE dropdown arrow — the browser pins it to\n * the edge. Draw our own chevron, inset to mirror the left text padding.\n */\n appearance: none;\n padding-right: 30px;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239aa3bd' stroke-width='2.4'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 9px center;\n background-size: 12px;\n}\ninput:focus,\nselect:focus,\ntextarea:focus {\n outline: none;\n border-color: var(--accent-deep);\n}\ntextarea {\n resize: vertical;\n font-size: 12px;\n line-height: 1.5;\n}\ntextarea.invalid {\n border-color: var(--rose);\n background: rgba(251, 113, 133, 0.05);\n}\n\n/* ─── banners ─── */\n#error-banner {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 8px 10px 8px 14px;\n background: rgba(251, 113, 133, 0.1);\n color: var(--rose);\n border-bottom: 1px solid rgba(251, 113, 133, 0.35);\n max-height: 110px;\n overflow: auto;\n font-family: ui-monospace, Menlo, monospace;\n font-size: 12px;\n}\n#error-text {\n flex: 1;\n white-space: pre-wrap;\n}\n#error-close {\n flex: none;\n padding: 0 6px;\n color: var(--rose);\n opacity: 0.65;\n font-size: 13px;\n line-height: 1.4;\n}\n#error-close:hover {\n opacity: 1;\n}\n#edit-notice {\n padding: 7px 14px;\n background: rgba(147, 197, 253, 0.08);\n color: #93c5fd;\n border-bottom: 1px solid rgba(147, 197, 253, 0.25);\n font-size: 12px;\n}\n#play-notice {\n padding: 7px 14px;\n background: rgba(134, 239, 172, 0.08);\n color: var(--green);\n border-bottom: 1px solid rgba(134, 239, 172, 0.25);\n font-size: 12px;\n}\n\n/* ─── layout ─── */\n/* The editor's root owns the window — on its own page AND mounted over a\n running game, where the host's <body> is some game's and says nothing about\n how tall a percentage is. Fixing it to the viewport gives every pane below a\n definite height in both cases; without it main's percentage height has\n nothing to resolve against, main grows to its CONTENT, and the viewport\n canvas is sized to a scene tree three thousand pixels tall. */\n.incanto-editor-root {\n position: fixed;\n inset: 0;\n z-index: 30;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n background: var(--bg-0);\n color: var(--text);\n font:\n 13px / 1.55 \"Inter\",\n -apple-system,\n \"Segoe UI\",\n system-ui,\n sans-serif;\n -webkit-font-smoothing: antialiased;\n}\nmain {\n display: flex;\n flex: 1;\n min-height: 0;\n}\n#tree-pane {\n width: 256px;\n display: flex;\n flex-direction: column;\n background: var(--bg-1);\n border-right: 1px solid var(--line);\n}\n#inspector-pane {\n width: 336px;\n overflow-y: auto;\n background: var(--bg-1);\n border-left: 1px solid var(--line);\n}\n#viewport-pane {\n flex: 1;\n position: relative;\n background:\n radial-gradient(1200px 500px at 50% -10%, rgba(110, 231, 220, 0.05), transparent), var(--bg-0);\n overflow: hidden;\n}\n#viewport,\n#overlay,\n#play-canvas {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n}\n#overlay {\n cursor: crosshair;\n}\n#play-canvas {\n z-index: 3;\n}\n#hints-dock {\n position: absolute;\n bottom: 12px;\n right: 16px;\n z-index: 4;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n#hints-toggle {\n width: 40px;\n height: 40px;\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n border: 1px solid var(--line-strong);\n background: rgba(16, 19, 29, 0.88);\n color: var(--text-dim);\n backdrop-filter: blur(6px);\n}\n#hints-toggle:hover {\n color: var(--accent);\n border-color: var(--accent-deep);\n}\n#hints-dock.open #hints-toggle {\n color: var(--accent);\n}\n.hints {\n max-width: 0;\n opacity: 0;\n overflow: hidden;\n white-space: nowrap;\n transition:\n max-width 0.22s ease,\n opacity 0.18s ease,\n padding 0.22s ease;\n padding: 5px 0;\n display: flex;\n gap: 14px;\n border-radius: 999px;\n background: rgba(16, 19, 29, 0.85);\n border: 1px solid transparent;\n color: var(--text-faint);\n font-size: 11px;\n pointer-events: none;\n backdrop-filter: blur(6px);\n}\n.hints b {\n color: var(--text-dim);\n font-weight: 600;\n}\n.pane-title {\n padding: 9px 14px 7px;\n font-size: 10.5px;\n font-weight: 700;\n letter-spacing: 1.6px;\n text-transform: uppercase;\n color: var(--text-faint);\n border-bottom: 1px solid var(--line);\n}\n\n/* ─── tree ─── */\n#tree {\n flex: 1;\n overflow-y: auto;\n padding: 8px;\n}\n.tree-row {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 3px 8px 3px 4px;\n border-radius: var(--r-sm);\n cursor: pointer;\n white-space: nowrap;\n overflow: hidden;\n color: var(--text-dim);\n border: 1px solid transparent;\n position: relative;\n}\n.chevron {\n display: inline-flex;\n align-items: center;\n transition: transform 0.12s;\n}\n.chevron.collapsed {\n transform: rotate(-90deg);\n}\n.chevron-legacy {\n flex: none;\n width: 14px;\n text-align: center;\n color: var(--text-faint);\n font-size: 9px;\n cursor: pointer;\n user-select: none;\n}\n.chevron.leaf {\n cursor: default;\n opacity: 0.35;\n}\n.chevron:not(.leaf):hover {\n color: var(--accent);\n}\n.tree-children {\n margin-left: 11px;\n padding-left: 8px;\n border-left: 1px solid var(--line);\n}\n.tree-row.dragging {\n opacity: 0.4;\n}\n.tree-row.drop-into {\n background: rgba(110, 231, 220, 0.14);\n border-color: var(--accent);\n}\n.tree-row.drop-before::before,\n.tree-row.drop-after::after {\n content: \"\";\n position: absolute;\n left: 4px;\n right: 4px;\n height: 2px;\n border-radius: 2px;\n background: var(--accent);\n}\n.tree-row.drop-before::before {\n top: -1px;\n}\n.tree-row.drop-after::after {\n bottom: -1px;\n}\n.tree-row:hover {\n background: var(--bg-2);\n color: var(--text);\n}\n.tree-row.selected {\n background: rgba(110, 231, 220, 0.1);\n border-color: rgba(110, 231, 220, 0.3);\n color: var(--accent);\n}\n.tree-name {\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.tree-icon {\n flex: none;\n display: inline-grid;\n place-items: center;\n width: 17px;\n height: 17px;\n border-radius: 4px;\n cursor: help;\n}\n.tree-icon:hover {\n background: var(--bg-3);\n}\n.cat-core {\n background: rgba(167, 139, 250, 0.15);\n color: var(--violet);\n}\n.cat-2d {\n background: rgba(110, 231, 220, 0.12);\n color: var(--accent);\n}\n.cat-3d {\n background: rgba(251, 191, 36, 0.12);\n color: var(--amber);\n}\n.cat-body {\n background: rgba(134, 239, 172, 0.12);\n color: var(--green);\n}\n.cat-net {\n background: rgba(251, 113, 133, 0.12);\n color: var(--rose);\n}\n.scene-row {\n margin-bottom: 6px;\n color: var(--text-faint);\n}\n.scene-row.selected {\n color: var(--accent);\n}\n#tree-actions {\n display: flex;\n gap: 7px;\n padding: 10px;\n border-top: 1px solid var(--line);\n}\n#add-type {\n flex: 1;\n}\n\n/* ─── inspector ─── */\n#inspector {\n padding: 12px 14px 40px;\n}\n.section-title {\n display: flex;\n align-items: center;\n gap: 7px;\n margin: 16px 0 8px;\n font-size: 11px;\n font-weight: 700;\n letter-spacing: 1.4px;\n text-transform: uppercase;\n color: var(--accent);\n}\n.section-title:first-child {\n margin-top: 2px;\n}\n.section-title .rule {\n flex: 1;\n height: 1px;\n background: var(--line);\n}\n.field {\n display: grid;\n grid-template-columns: 92px 1fr;\n align-items: center;\n gap: 8px;\n margin-bottom: 7px;\n}\n/* A grid item's default min-width is auto: it refuses to shrink below its\n content's MIN-CONTENT width. One nowrap asset description was enough to push\n a whole field past the inspector — and no max-width: 100% further down can\n fix it, because 100% is then 100% of the already-grown track. The clamp has\n to come from here. */\n.field > * {\n min-width: 0;\n}\n.field > span {\n font-size: 11.5px;\n color: var(--text-dim);\n display: flex;\n align-items: center;\n gap: 5px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.field.wide {\n grid-template-columns: 1fr;\n}\n.field.wide > span {\n margin-bottom: 2px;\n}\n.vector-row {\n display: flex;\n gap: 6px;\n}\n.vector-row input {\n width: 100%;\n}\n.help-btn {\n flex: none;\n width: 15px;\n height: 15px;\n padding: 0;\n border-radius: 50%;\n border: 1px solid var(--line-strong);\n color: var(--text-faint);\n font-size: 10px;\n font-weight: 700;\n justify-content: center;\n}\n.help-btn:hover {\n border-color: var(--accent);\n color: var(--accent);\n}\n.chips {\n display: flex;\n flex-wrap: wrap;\n gap: 5px;\n padding: 5px 7px;\n border: 1px solid var(--line);\n border-radius: var(--r-sm);\n background: var(--bg-0);\n cursor: text;\n}\n.chip {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 1px 8px;\n border-radius: 999px;\n background: rgba(110, 231, 220, 0.12);\n color: var(--accent);\n font-size: 11.5px;\n}\n.chip button {\n padding: 0;\n font-size: 12px;\n color: inherit;\n opacity: 0.7;\n}\n.chips input {\n flex: 1;\n min-width: 70px;\n border: none;\n background: transparent;\n padding: 2px;\n}\n.chips input:focus {\n outline: none;\n}\n.subcard {\n border: 1px solid var(--line);\n border-radius: var(--r-md);\n background: var(--bg-2);\n padding: 10px;\n margin-bottom: 10px;\n}\n.subcard .field {\n grid-template-columns: 78px 1fr;\n}\n/* .field.wide is declared EARLIER and at equal specificity, so the rule above\n silently won inside a card: a full-width field (the asset picker) went back\n to two columns and its dropdown panel — a third grid child — was auto-placed\n into the 78px label column, four times too narrow to read. */\n.subcard .field.wide {\n grid-template-columns: 1fr;\n}\n.subcard .field.wide.has-const-picker {\n grid-template-columns: 1fr auto;\n}\n.subcard-head {\n display: flex;\n align-items: center;\n gap: 7px;\n margin-bottom: 8px;\n font-size: 11.5px;\n font-weight: 600;\n color: var(--text-dim);\n}\n.subcard-head .spacer {\n flex: 1;\n}\n.linklike {\n padding: 2px 6px;\n font-size: 11px;\n color: var(--accent);\n font-weight: 600;\n}\n.linklike:hover {\n text-decoration: underline;\n}\n.muted-note {\n font-size: 11px;\n color: var(--text-faint);\n margin: -2px 0 8px;\n}\n\n/* ─── asset picker ─── */\n.asset-control {\n display: flex;\n gap: 6px;\n align-items: center;\n}\n.asset-control input {\n flex: 1;\n min-width: 0;\n}\n.asset-toggle {\n flex: none;\n /* square and matched to the input beside it. The base control rule's 9px of\n side padding does not fit a 26px box, which left the chevron off-centre in\n a button that looked taller than it was wide. */\n width: 30px;\n height: 30px;\n padding: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n border: 1px solid var(--line);\n border-radius: var(--r-sm);\n background: var(--bg-1);\n color: var(--text-dim);\n font-size: 11px;\n}\n.asset-toggle:hover {\n border-color: var(--accent);\n color: var(--accent);\n}\n.asset-panel {\n min-width: 0;\n margin-top: 6px;\n border: 1px solid var(--line-strong);\n border-radius: var(--r-sm);\n background: var(--bg-0);\n padding: 6px;\n}\n.asset-search {\n width: 100%;\n margin-bottom: 6px;\n}\n.asset-options {\n display: flex;\n flex-direction: column;\n gap: 3px;\n min-width: 0;\n max-height: 220px;\n overflow-y: auto;\n}\nbutton.asset-option {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 1px;\n /* A flex ITEM has the same auto-min-width default as a grid item, so this is\n what stops one long description widening the whole panel.\n overflow-x, NOT overflow: plain hidden also removes the automatic\n MINIMUM SIZE on the block axis, and this button is an item of a\n max-height scroll container — so every row shrank to fit 220px instead of\n scrolling, collapsing 46px rows to 16px with the text squashed to 1px.\n flex: none is the other half: items in a capped column must keep their\n height and let the container scroll. */\n min-width: 0;\n overflow-x: clip;\n flex: none;\n padding: 5px 8px;\n text-align: left;\n border: 1px solid transparent;\n border-radius: var(--r-sm);\n background: var(--bg-2);\n color: var(--text);\n width: 100%;\n}\nbutton.asset-option:hover {\n border-color: var(--accent);\n background: var(--bg-3);\n}\nbutton.asset-option strong {\n font-size: 11.5px;\n font-weight: 600;\n /* asset keys are short today and a long one must still not widen the panel */\n max-width: 100%;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\nbutton.asset-option small {\n font-size: 10px;\n color: var(--text-faint);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 100%;\n}\n.asset-empty {\n font-size: 11px;\n color: var(--text-faint);\n padding: 4px 8px;\n}\n.asset-note {\n margin-top: 5px;\n}\n.varieties {\n cursor: default;\n}\n.variety-opt {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n font-size: 11.5px;\n color: var(--text-dim);\n cursor: pointer;\n}\n.variety-opt input[type=\"checkbox\"] {\n width: auto;\n}\n\n/* ─── popover (help) ─── */\n#popover {\n position: fixed;\n z-index: 50;\n width: 300px;\n /* A topic longer than the window still has to be readable to the end: the\n positioner pins it to the top and this lets the rest scroll. */\n max-height: calc(100vh - 16px);\n overflow-y: auto;\n overscroll-behavior: contain;\n background: var(--bg-3);\n border: 1px solid var(--line-strong);\n border-radius: var(--r-md);\n box-shadow: var(--shadow);\n padding: 12px 14px;\n font-size: 12px;\n color: var(--text-dim);\n}\n#popover h4 {\n margin: 0 0 6px;\n font-size: 12.5px;\n color: var(--text);\n}\n#popover code {\n background: var(--bg-0);\n padding: 1px 5px;\n border-radius: 4px;\n font-size: 11px;\n color: var(--accent);\n}\n#popover pre {\n margin: 8px 0 0;\n padding: 8px 10px;\n background: var(--bg-0);\n border-radius: var(--r-sm);\n font-size: 11px;\n line-height: 1.5;\n overflow-x: auto;\n color: var(--text-dim);\n}\n#popover .pop-actions {\n margin-top: 8px;\n display: flex;\n justify-content: flex-end;\n}\n\n/* ─── picker ─── */\n#picker {\n position: fixed;\n inset: 0;\n background: rgba(7, 9, 14, 0.78);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 40;\n backdrop-filter: blur(4px);\n}\n#picker[hidden] {\n display: none;\n}\n#picker-card {\n width: 460px;\n max-height: 72vh;\n background: var(--bg-2);\n border: 1px solid var(--line-strong);\n border-radius: 14px;\n box-shadow: var(--shadow);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n#picker-list {\n flex: 1;\n overflow-y: auto;\n padding: 6px;\n min-height: 120px;\n}\n#picker-list .tree-row {\n padding: 9px 12px;\n font-family: ui-monospace, Menlo, monospace;\n font-size: 12.5px;\n}\n#picker-find {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px;\n border-bottom: 1px solid var(--line);\n}\n#picker-search {\n flex: 1;\n}\n#picker-count {\n font-size: 11px;\n color: var(--text-faint);\n font-variant-numeric: tabular-nums;\n}\n/* one row of the project explorer: caret, name, and the facts, right-aligned */\n.scene-row {\n display: flex;\n align-items: center;\n gap: 7px;\n padding: 6px 10px 6px 6px;\n border-radius: 7px;\n cursor: pointer;\n font-size: 12.5px;\n user-select: none;\n}\n.scene-row:hover {\n background: var(--bg-3);\n}\n.scene-row.active {\n background: var(--bg-3);\n outline: 1px solid var(--line-strong);\n}\n.scene-name {\n font-family: ui-monospace, Menlo, monospace;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.scene-folder .scene-name {\n color: var(--text-dim);\n}\n.scene-row.current .scene-name {\n color: var(--accent);\n}\n.scene-caret {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 13px;\n flex: none;\n color: var(--text-faint);\n font-size: 9px;\n line-height: 1;\n}\n.scene-folder .scene-caret {\n color: var(--text-dim);\n}\n.scene-meta {\n margin-left: auto;\n padding-left: 10px;\n flex: none;\n font-size: 10.5px;\n color: var(--text-faint);\n font-variant-numeric: tabular-nums;\n}\n/* a JSON that is not a scene: still there, still clickable, visibly not one */\n.scene-row.not-scene .scene-name,\n.scene-row.not-scene .scene-meta {\n color: var(--text-faint);\n}\n.scene-row.not-scene .scene-caret {\n opacity: 0.4;\n}\n.scene-empty {\n padding: 22px 12px;\n text-align: center;\n color: var(--text-faint);\n font-size: 12px;\n}\n#picker-new {\n display: flex;\n gap: 8px;\n padding: 12px;\n border-top: 1px solid var(--line);\n}\n#picker-path {\n flex: 1;\n font-family: ui-monospace, Menlo, monospace;\n}\n\n/* ─── scrollbars ─── */\n::-webkit-scrollbar {\n width: 9px;\n height: 9px;\n}\n::-webkit-scrollbar-thumb {\n background: var(--line-strong);\n border-radius: 99px;\n border: 2px solid var(--bg-1);\n}\n::-webkit-scrollbar-track {\n background: transparent;\n}\n\nbody.playing #tree-pane,\nbody.playing #inspector-pane {\n pointer-events: none;\n opacity: 0.45;\n filter: saturate(0.6);\n transition: opacity 0.2s;\n}\n\n.rename-input {\n flex: 1;\n min-width: 0;\n padding: 1px 6px;\n font-size: 12.5px;\n}\n.balloon {\n position: fixed;\n z-index: 60;\n max-width: 230px;\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 8px 11px;\n background: var(--bg-3);\n border: 1px solid var(--line-strong);\n border-radius: var(--r-md);\n box-shadow: var(--shadow);\n font-size: 11.5px;\n color: var(--text-dim);\n}\n.balloon .balloon-title {\n color: var(--accent);\n font-size: 12px;\n font-weight: 700;\n}\n.context-menu {\n position: fixed;\n z-index: 60;\n min-width: 190px;\n padding: 5px;\n background: var(--bg-3);\n border: 1px solid var(--line-strong);\n border-radius: var(--r-md);\n box-shadow: var(--shadow);\n display: flex;\n flex-direction: column;\n}\n.menu-item {\n justify-content: space-between;\n padding: 6px 10px;\n border-radius: var(--r-sm);\n font-weight: 500;\n color: var(--text);\n}\n.menu-item:not(:disabled):hover {\n background: var(--bg-2);\n}\n.menu-item.danger:not(:disabled):hover {\n color: var(--rose);\n}\n.menu-item kbd {\n font-size: 10px;\n color: var(--text-faint);\n font-family: inherit;\n}\n.menu-divider {\n height: 1px;\n margin: 4px 6px;\n background: var(--line);\n}\n/* The play menu is a choice, not a command list: each row carries a label and\n the sentence that says what actually happens, stacked. */\n.play-menu {\n width: 290px;\n gap: 2px;\n}\n.play-menu-item {\n flex-direction: column;\n align-items: flex-start;\n gap: 2px;\n padding: 8px 10px;\n text-align: left;\n}\n.play-menu-hint {\n font-size: 11px;\n font-weight: 400;\n line-height: 1.35;\n color: var(--text-faint);\n}\n\n.hints[hidden] {\n display: none;\n}\n#hints-dock.open .hints:not([hidden]) {\n max-width: 1100px;\n opacity: 1;\n padding: 5px 14px;\n border-color: var(--line);\n}\nbody.playing #hints-dock {\n display: none;\n}\n\n#gameview-btn {\n position: absolute;\n top: 104px;\n right: 18px;\n z-index: 4;\n font-size: 11.5px;\n padding: 4px 10px;\n backdrop-filter: blur(6px);\n background: rgba(16, 19, 29, 0.8);\n}\n\n.field input[type=\"checkbox\"] {\n justify-self: start;\n width: 15px;\n height: 15px;\n accent-color: var(--accent-deep);\n cursor: pointer;\n}\n\n.picker-title {\n display: flex;\n align-items: center;\n justify-content: space-between;\n}\n#picker-close {\n padding: 0 4px;\n font-size: 12px;\n color: var(--text-faint);\n border: none;\n background: none;\n}\n#picker-close:hover {\n color: var(--text);\n}\n\n.uid-row {\n display: flex;\n gap: 6px;\n}\n.uid-row input {\n flex: 1;\n min-width: 0;\n font-size: 11.5px;\n}\n.uid-row .ghost {\n padding: 4px 8px;\n}\n#confirm {\n position: fixed;\n inset: 0;\n background: rgba(7, 9, 14, 0.78);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 70;\n backdrop-filter: blur(4px);\n}\n#confirm[hidden] {\n display: none;\n}\n#confirm-card {\n width: 480px;\n max-height: 70vh;\n display: flex;\n flex-direction: column;\n background: var(--bg-2);\n border: 1px solid var(--line-strong);\n border-radius: 14px;\n box-shadow: var(--shadow);\n overflow: hidden;\n}\n#confirm-body {\n padding: 14px;\n color: var(--text-dim);\n font-size: 12.5px;\n overflow-y: auto;\n}\n#confirm-list:empty {\n display: none; /* the group-delete confirm has no reference list */\n}\n#confirm-list {\n margin: 10px 0 0;\n padding: 10px 12px;\n background: var(--bg-0);\n border-radius: var(--r-sm);\n font-family: ui-monospace, Menlo, monospace;\n font-size: 11.5px;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n#confirm-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 12px 14px;\n border-top: 1px solid var(--line);\n}\n#confirm-delete {\n border-color: var(--rose);\n color: var(--rose);\n background: rgba(251, 113, 133, 0.08);\n}\n#confirm-delete:hover {\n background: rgba(251, 113, 133, 0.16);\n}\n\n.color-row {\n display: flex;\n gap: 6px;\n align-items: center;\n}\n.color-row input[type=\"color\"] {\n width: 30px;\n height: 26px;\n padding: 2px;\n cursor: pointer;\n}\n.color-row input[type=\"text\"] {\n flex: 1;\n min-width: 0;\n font-size: 11.5px;\n}\n.slider-row {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n.slider-row input[type=\"range\"] {\n flex: 1;\n accent-color: var(--accent-deep);\n padding: 0;\n border: none;\n background: transparent;\n}\n.slider-row input[type=\"number\"] {\n width: 64px;\n}\n.asset-row {\n display: flex;\n align-items: center;\n gap: 7px;\n padding: 5px 8px;\n border-radius: var(--r-sm);\n cursor: pointer;\n}\n.asset-row:hover,\n.asset-row.open {\n background: var(--bg-3);\n}\n.asset-key {\n color: var(--accent);\n}\n.asset-url {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--text-faint);\n font-size: 11px;\n font-family: ui-monospace, Menlo, monospace;\n}\n.danger-link {\n color: var(--text-faint);\n}\n.danger-link:hover {\n color: var(--rose);\n}\n.asset-editor {\n margin: 2px 0 10px;\n padding: 10px;\n border: 1px solid var(--line);\n border-radius: var(--r-sm);\n background: var(--bg-0);\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.asset-editor .field {\n grid-template-columns: 52px 1fr;\n margin-bottom: 4px;\n}\n/* A row carrying the library button has THREE cells. Without this the button is\n a third child of a two-column grid: it wraps onto a second row INSIDE the\n label column, gets 52px to live in, and crushes \"📚 library\" against its own\n borders — which reads as a button with no padding, and no amount of padding\n fixes it. */\n.field.has-lib {\n grid-template-columns: 92px 1fr auto;\n}\n.asset-editor .field.has-lib {\n grid-template-columns: 52px 1fr auto;\n}\n.subcard .field.has-lib {\n grid-template-columns: 78px 1fr auto;\n}\n.meta-row {\n display: grid;\n grid-template-columns: 1fr 1fr 24px;\n gap: 6px;\n align-items: center;\n}\n.meta-row input {\n font-size: 11.5px;\n padding: 4px 7px;\n}\n\n#docs {\n position: fixed;\n inset: 0;\n background: rgba(7, 9, 14, 0.8);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 60;\n backdrop-filter: blur(5px);\n}\n#docs[hidden] {\n display: none;\n}\n#docs-card {\n width: min(920px, 92vw);\n height: min(680px, 88vh);\n background: var(--bg-2);\n border: 1px solid var(--line-strong);\n border-radius: 14px;\n box-shadow: var(--shadow);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n#docs-layout {\n display: flex;\n flex: 1;\n min-height: 0;\n}\n#docs-tabs {\n width: 168px;\n border-right: 1px solid var(--line);\n padding: 10px;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.docs-tab {\n justify-content: flex-start;\n padding: 7px 12px;\n border-radius: var(--r-sm);\n color: var(--text-dim);\n font-weight: 500;\n}\n.docs-tab:hover {\n background: var(--bg-3);\n color: var(--text);\n}\n.docs-tab.active {\n background: rgba(110, 231, 220, 0.1);\n color: var(--accent);\n font-weight: 700;\n}\n#docs-body {\n flex: 1;\n overflow-y: auto;\n padding: 18px 24px 40px;\n}\n#docs-body h2 {\n margin: 0 0 6px;\n font-size: 18px;\n}\n#docs-body h3 {\n margin: 18px 0 4px;\n font-size: 13.5px;\n color: var(--accent);\n}\n#docs-body p {\n margin: 4px 0 10px;\n color: var(--text-dim);\n line-height: 1.7;\n font-size: 13px;\n}\n.docs-intro {\n padding: 10px 14px;\n background: var(--bg-1);\n border: 1px solid var(--line);\n border-radius: var(--r-md);\n}\n.docs-node {\n border: 1px solid var(--line);\n border-radius: var(--r-md);\n margin-bottom: 8px;\n overflow: hidden;\n}\n.docs-node.open {\n border-color: var(--line-strong);\n}\n.docs-node-head {\n width: 100%;\n display: flex;\n align-items: center;\n gap: 9px;\n padding: 9px 12px;\n border-radius: 0;\n text-align: left;\n}\n.docs-node-head:hover {\n background: var(--bg-3);\n}\n.docs-node-head strong {\n font-size: 13px;\n}\n.docs-summary {\n color: var(--text-faint);\n font-size: 12px;\n font-weight: 400;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.docs-detail {\n padding: 4px 14px 12px;\n border-top: 1px solid var(--line);\n background: var(--bg-1);\n}\n.docs-props {\n width: 100%;\n border-collapse: collapse;\n margin-top: 8px;\n font-size: 11.5px;\n}\n.docs-props th {\n text-align: left;\n color: var(--text-faint);\n font-weight: 600;\n padding: 4px 8px;\n border-bottom: 1px solid var(--line);\n}\n.docs-props td {\n padding: 3px 8px;\n border-bottom: 1px solid var(--line);\n color: var(--text-dim);\n}\n\n#mode-toolbar {\n position: absolute;\n top: 12px;\n left: 12px;\n z-index: 4;\n display: flex;\n gap: 4px;\n padding: 4px;\n border-radius: var(--r-md);\n background: rgba(16, 19, 29, 0.85);\n border: 1px solid var(--line);\n backdrop-filter: blur(6px);\n}\n.tool {\n width: 30px;\n height: 28px;\n justify-content: center;\n padding: 0;\n border-radius: var(--r-sm);\n color: var(--text-faint);\n}\n.tool:hover {\n color: var(--text);\n background: var(--bg-3);\n}\n.tool.active {\n background: rgba(110, 231, 220, 0.14);\n color: var(--accent);\n}\n\n.lang-menu {\n min-width: 130px;\n}\n.lang-check {\n color: var(--accent);\n font-weight: 700;\n}\n\n.explorer-section {\n display: flex;\n align-items: center;\n justify-content: space-between;\n border-top: 1px solid var(--line);\n margin-top: 4px;\n}\n.explorer-section .ghost {\n padding: 1px 8px;\n}\n#asset-tree {\n padding: 2px 8px 10px;\n overflow-y: auto;\n max-height: 30%;\n}\n.explorer-empty {\n padding: 4px 10px;\n font-size: 11px;\n}\n.asset-row .asset-key {\n color: var(--accent);\n font-family: ui-monospace, Menlo, monospace;\n}\n/* an asset the renderer could not fetch: the node is fine, the art is not */\n.asset-row.asset-failed .asset-key {\n color: #f87171;\n text-decoration: underline dotted #f87171;\n}\n.asset-icon-texture {\n color: #f0abfc;\n}\n.asset-icon-spritesheet {\n color: #fbbf24;\n}\n.asset-icon-model {\n color: #7aa2ff;\n}\n.asset-icon-animation {\n color: #86efac;\n}\n.uid-value {\n display: flex;\n align-items: center;\n gap: 7px;\n min-width: 0;\n}\n.uid-value code {\n font-family: ui-monospace, Menlo, monospace;\n font-size: 11px;\n color: var(--text-dim);\n letter-spacing: 0.3px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.uid-copy {\n padding: 3px 5px;\n border: none;\n background: none;\n border-radius: var(--r-sm);\n color: var(--text-faint);\n line-height: 0;\n}\n.uid-copy:hover {\n color: var(--text);\n background: var(--bg-3);\n}\n.uid-copy.copied {\n color: var(--accent);\n font-size: 10px;\n line-height: 1;\n}\n\n.section-toggle {\n width: 100%;\n height: 30px; /* IDENTICAL header height for ASSETS and SCENE */\n box-sizing: border-box;\n padding-top: 0;\n padding-bottom: 0;\n display: flex;\n align-items: center;\n justify-content: flex-start;\n gap: 6px;\n text-align: left;\n cursor: pointer;\n background: var(--bg-1);\n border: none;\n border-top: 1px solid var(--line-strong);\n border-bottom: 1px solid var(--line);\n border-radius: 0;\n}\n.section-toggle:hover {\n color: var(--text);\n}\n.section-toggle .chev {\n display: inline-flex;\n transition: transform 0.12s;\n color: var(--text-dim);\n}\n.section-toggle.collapsed .chev {\n transform: rotate(-90deg);\n}\n.section-add {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 20px;\n padding: 0 6px;\n font-size: 13px;\n color: var(--text-dim);\n border: 1px solid var(--line-strong);\n border-radius: var(--r-sm);\n background: var(--bg-2);\n}\n.section-add:hover {\n background: var(--bg-3);\n color: var(--accent);\n border-color: var(--accent-deep);\n}\n[data-body][hidden],\naside#tree-pane #scene-body[hidden] {\n /* outranks the #scene-body flex rule — [hidden] must always win */\n display: none;\n}\n#scene-body {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n}\n.asset-folder {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n color: var(--text-dim);\n cursor: pointer;\n border-radius: var(--r-sm);\n}\n.asset-folder:hover {\n background: var(--bg-3);\n}\n.asset-folder .chev {\n display: inline-flex;\n color: var(--text-dim);\n transition: transform 0.12s;\n}\n.asset-folder.collapsed .chev {\n transform: rotate(-90deg);\n}\n.asset-folder svg {\n color: #e7c66a;\n}\n.asset-row.grouped {\n margin-left: 18px;\n}\n\n.asset-folder .count {\n margin-left: auto;\n color: var(--text-faint);\n font-size: 10.5px;\n}\n.asset-folder.selected {\n background: rgba(110, 231, 220, 0.08);\n color: var(--accent);\n}\n.asset-folder.drop-target,\n#asset-tree.drop-target {\n outline: 1.5px dashed var(--accent);\n outline-offset: -2px;\n border-radius: var(--r-sm);\n}\n.asset-row[draggable=\"true\"] {\n cursor: grab;\n}\n\nbody.playing #mode-toolbar,\nbody.playing #gameview-btn {\n display: none; /* gizmo tools and the free-cam escape make no sense mid-play */\n}\n\n.tool-divider {\n width: 1px;\n height: 18px;\n background: var(--line);\n margin: 0 2px;\n align-self: center;\n}\n\n/* ─── generate dialog ─── */\n#generate {\n position: fixed;\n inset: 0;\n background: rgba(7, 9, 14, 0.78);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 70;\n backdrop-filter: blur(4px);\n}\n#generate[hidden] {\n display: none;\n}\n#generate-card {\n width: 420px;\n max-height: 78vh;\n display: flex;\n flex-direction: column;\n background: var(--bg-2);\n border: 1px solid var(--line-strong);\n border-radius: 14px;\n box-shadow: var(--shadow);\n overflow: hidden;\n}\n#generate-body {\n padding: 14px;\n overflow-y: auto;\n}\n#generate-body .gen-hint {\n margin: 0 0 12px;\n font-size: 11.5px;\n color: var(--text-faint);\n}\n#generate-body .gen-desc {\n margin: 2px 0 12px;\n font-size: 11.5px;\n color: var(--text-dim);\n}\n#generate-params {\n padding-top: 2px;\n border-top: 1px solid var(--line);\n}\n#generate-params .field:first-child {\n margin-top: 10px;\n}\n.gen-seed-row {\n display: flex;\n gap: 6px;\n}\n.gen-seed-row input {\n flex: 1;\n min-width: 0;\n}\n.gen-seed-row .ghost {\n padding: 4px 9px;\n}\n#generate-actions {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n padding: 12px 14px;\n border-top: 1px solid var(--line);\n}\n#generate-status {\n margin-right: auto;\n font-size: 11px;\n color: var(--rose);\n}\n\n/* ---- scene constants + the prop \"bind to a constant\" picker ---- */\n/* The third grid column a bound-able prop row opens for its 🔗 picker. The\n .field grid is 92px 1fr; without this the picker is auto-placed into row 2\n column 1, tucked under the label where nobody finds it. */\n.field.has-const-picker {\n grid-template-columns: 92px 1fr auto;\n}\n.field.wide.has-const-picker {\n grid-template-columns: 1fr auto;\n}\n.const-picker {\n flex: none;\n width: 30px;\n border: 1px solid var(--line);\n border-radius: var(--r-sm);\n background: var(--bg-1);\n color: var(--text-dim);\n font-size: 12px;\n /* The base select rule reserves 9px + 30px of horizontal padding for its\n drawn chevron. In a 30px box that leaves the link glyph nowhere to be, so\n the control rendered as an empty rectangle. This one has no chevron. */\n padding: 0;\n background-image: none;\n text-align: center;\n text-align-last: center;\n height: 30px;\n}\n.const-picker:hover {\n border-color: var(--accent);\n color: var(--accent);\n}\n.field.const-bound > span {\n color: var(--accent);\n}\n.const-row {\n display: flex;\n gap: 6px;\n /* NOT stretch: .field carries a 7px bottom margin, so a stretched button\n grew to cover it and stood a third taller than the input beside it. */\n align-items: center;\n}\n.const-row .field {\n flex: 1;\n min-width: 0;\n}\n.const-del {\n flex: none;\n width: 30px;\n /* square, and matched to the input it sits beside, rather than to whatever\n the row's tallest margin box happens to be */\n height: 30px;\n /* the field's own bottom margin is the row's spacing; without this the button\n sits 3.5px low against the input */\n margin-bottom: 7px;\n /* the glyph sat right of centre: the base control rule gives every button\n 9px of side padding, which a 30px box has no room for */\n padding: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n border: 1px solid var(--line);\n border-radius: var(--r-sm);\n background: var(--bg-1);\n color: var(--text-dim);\n font-size: 11px;\n}\n.const-del:hover {\n border-color: var(--rose);\n color: var(--rose);\n}\n.const-add {\n display: flex;\n gap: 6px;\n align-items: stretch;\n margin-top: 6px;\n}\n.const-add input {\n flex: 1;\n min-width: 0;\n}\n\n/* ---- scene strings (localization) ---- */\n/* One block per key: the inspector is ~300px, and a column per language gave\n each cell 48px with three languages — measured in the real panel. */\n.strings-langs {\n display: flex;\n flex-wrap: wrap;\n gap: 5px;\n align-items: center;\n margin-bottom: 8px;\n}\n.strings-langs-label {\n font-size: 10px;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--text-faint);\n margin-right: 2px;\n}\n.strings-lang-chip {\n display: inline-flex;\n align-items: center;\n gap: 3px;\n padding: 1px 5px;\n border: 1px solid var(--line);\n border-radius: var(--r-sm);\n background: var(--bg-1);\n color: var(--text-dim);\n font-size: 10px;\n}\n.strings-locale-del {\n padding: 0 1px;\n border: 0;\n background: none;\n color: var(--text-faint);\n font-size: 9px;\n line-height: 1;\n cursor: pointer;\n}\n.strings-locale-del:hover {\n color: var(--rose);\n}\n.strings-key-row {\n display: flex;\n gap: 6px;\n align-items: center;\n margin-top: 8px;\n}\n.strings-key {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 11px;\n color: var(--accent);\n}\n.strings-key-row .const-del {\n margin-bottom: 0;\n}\n.strings-row {\n display: flex;\n gap: 6px;\n align-items: center;\n margin: 3px 0 0 10px;\n}\n.strings-lang-tag {\n flex: 0 0 22px;\n font-size: 10px;\n color: var(--text-faint);\n text-align: right;\n}\n.strings-cell {\n flex: 1;\n min-width: 0;\n}\n/* Not translated: the English it will silently fall back to, greyed. That\n fallback is the documented design, not an error — so it is dimmed, not red. */\n.strings-cell.strings-fallback::placeholder {\n color: var(--text-faint);\n font-style: italic;\n}\n/* No BASE text: nothing to fall back to, so the raw key paints on screen. */\n.strings-cell.strings-missing-base {\n border-color: var(--rose);\n}\n.strings-cell.strings-missing-base::placeholder {\n color: var(--rose);\n}\n\n/* ---- TileMap2D paint brush ---- */\n.tile-paint {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.paint-toggle {\n cursor: pointer;\n border: 1px solid var(--border, #444);\n border-radius: 6px;\n background: transparent;\n color: inherit;\n padding: 6px 10px;\n font: inherit;\n}\n.paint-toggle.on {\n background: #2e6b2e;\n border-color: #4a9e4a;\n color: #fff;\n}\n.paint-palette {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n align-items: center;\n}\n.paint-chip {\n cursor: pointer;\n width: 26px;\n height: 26px;\n border-radius: 5px;\n border: 1px solid var(--border, #444);\n background: transparent;\n color: inherit;\n font: 600 13px / 1 monospace;\n}\n.paint-chip.on {\n background: #3a5a8c;\n border-color: #6a9ae0;\n color: #fff;\n}\n.paint-brush-input {\n width: 32px;\n text-align: center;\n font: 600 13px / 1 monospace;\n background: transparent;\n color: inherit;\n border: 1px solid var(--border, #444);\n border-radius: 5px;\n padding: 4px;\n}\n.paint-hint {\n font-size: 11px;\n opacity: 0.6;\n}\n\n/* ─── agent8 asset library ─── */\n.asset-lib {\n flex: none;\n height: 30px;\n /* room for the word: a bare icon next to a URL field reads as decoration,\n and nobody clicks decoration */\n padding: 0 16px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 7px;\n white-space: nowrap;\n border: 1px solid var(--line);\n border-radius: var(--r-sm);\n background: var(--bg-1);\n color: var(--fg-1);\n font-size: 12px;\n line-height: 1;\n}\n.asset-lib:hover {\n border-color: var(--accent);\n}\n.lib-backdrop {\n position: fixed;\n inset: 0;\n z-index: 70;\n display: grid;\n place-items: center;\n background: rgba(4, 6, 12, 0.72);\n backdrop-filter: blur(3px);\n}\n.lib-dialog {\n display: flex;\n flex-direction: column;\n width: min(1180px, 94vw);\n height: min(760px, 88vh);\n background: var(--bg-1);\n border: 1px solid var(--line-strong);\n border-radius: var(--r-md);\n box-shadow: var(--shadow);\n overflow: hidden;\n}\n.lib-head {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n border-bottom: 1px solid var(--line);\n background: var(--bg-2);\n}\n.lib-head strong {\n font-size: 13px;\n}\n.lib-sub {\n color: var(--accent);\n font-size: 12px;\n font-family: ui-monospace, Menlo, monospace;\n}\n.lib-search {\n margin-left: auto;\n width: 260px;\n}\n.lib-body {\n flex: 1;\n display: grid;\n grid-template-columns: 190px 1fr 320px;\n min-height: 0;\n}\n.lib-shelves {\n display: flex;\n flex-direction: column;\n min-height: 0;\n gap: 2px;\n padding: 8px 6px;\n overflow-y: auto;\n border-right: 1px solid var(--line);\n background: var(--bg-1);\n}\n.lib-shelf {\n justify-content: flex-start;\n padding: 6px 10px;\n border-radius: var(--r-sm);\n color: var(--text-dim);\n font-weight: 500;\n text-align: left;\n}\n.lib-shelf:hover {\n background: var(--bg-2);\n color: var(--text);\n}\n.lib-shelf.active {\n background: rgba(110, 231, 220, 0.12);\n color: var(--accent);\n}\n.lib-shelf.crumb {\n color: var(--text-faint);\n font-size: 11.5px;\n}\n.lib-shelf-count {\n margin-left: auto;\n color: var(--text-faint);\n font-size: 10px;\n font-family: ui-monospace, Menlo, monospace;\n}\n.lib-shelf-head {\n margin: 8px 0 2px;\n padding: 0 10px;\n color: var(--text-faint);\n font-size: 10px;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n}\n.lib-grid-pane {\n display: flex;\n flex-direction: column;\n min-width: 0;\n /* Grid items size to their content unless told not to. Without this the\n results pane grows past the dialog and takes the scrollbar with it. */\n min-height: 0;\n background: var(--bg-0);\n}\n.lib-status {\n padding: 7px 12px;\n color: var(--text-faint);\n font-size: 11.5px;\n border-bottom: 1px solid var(--line);\n}\n.lib-grid {\n flex: 1;\n /* A flex child will not shrink below its content without this, so flex:1\n plus overflow-y:auto grew the grid instead of scrolling it: the results ran\n off the bottom of the dialog with no way to reach them, and the\n infinite-scroll sentinel sat permanently in view. */\n min-height: 0;\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));\n /* Not \"auto\": once the grid has a definite height, an auto row sizes to its\n MIN-content, and a thumbnail sized by aspect-ratio contributes nothing to\n that — every row collapsed to the 14px of its filename. */\n grid-auto-rows: max-content;\n gap: 10px;\n align-content: start;\n padding: 12px;\n overflow-y: auto;\n}\n.lib-card {\n display: flex;\n flex-direction: column;\n gap: 5px;\n min-width: 0; /* grid item: without this the name pushes the card wider */\n padding: 6px;\n overflow: hidden;\n border: 1px solid var(--line);\n border-radius: var(--r-sm);\n background: var(--bg-1);\n font-weight: 500;\n}\n.lib-card:hover {\n border-color: var(--line-strong);\n}\n.lib-card.active {\n border-color: var(--accent);\n background: rgba(110, 231, 220, 0.08);\n}\n/* On the shelf, but not something this field can take. Shown — a library that\n hides most of itself is worse — just clearly second. */\n.lib-card.off-kind {\n opacity: 0.42;\n}\n.lib-card.off-kind:hover,\n.lib-card.off-kind.active {\n opacity: 1;\n}\n.lib-sentinel {\n grid-column: 1 / -1;\n height: 1px;\n}\n.lib-charpick {\n display: grid;\n grid-template-columns: auto 1fr auto auto;\n align-items: center;\n gap: 6px;\n padding: 7px 8px;\n border: 1px solid var(--line);\n border-radius: var(--r-sm);\n background: var(--bg-2);\n}\n.lib-charpick-label {\n color: var(--text-faint);\n font-size: 11px;\n white-space: nowrap;\n}\n.lib-charpick input {\n min-width: 0;\n padding: 4px 7px;\n font-size: 11px;\n font-family: ui-monospace, Menlo, monospace;\n text-overflow: ellipsis;\n}\n.lib-charpick button {\n padding: 4px 8px;\n font-size: 11px;\n}\n.lib-blocked {\n margin: 0;\n color: var(--warn, #e7c86e);\n font-size: 12px;\n line-height: 1.5;\n}\n.lib-thumb {\n display: grid;\n place-items: center;\n aspect-ratio: 1;\n border-radius: 4px;\n background: repeating-conic-gradient(var(--bg-3) 0% 25%, var(--bg-2) 0% 50%) 50% / 16px 16px;\n overflow: hidden;\n}\n.lib-thumb img {\n width: 100%;\n height: 100%;\n object-fit: contain;\n}\n.lib-glyph {\n width: 30px;\n height: 30px;\n color: var(--text-faint);\n}\n.lib-badge {\n position: absolute;\n right: 4px;\n bottom: 4px;\n padding: 1px 5px;\n border-radius: 999px;\n background: rgba(110, 231, 220, 0.16);\n color: var(--accent);\n font-size: 9px;\n font-style: normal;\n letter-spacing: 0.03em;\n}\n.lib-thumb {\n position: relative;\n}\n.lib-card-name {\n max-width: 100%;\n overflow: hidden;\n color: var(--text-dim);\n font-size: 11px;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.lib-more {\n margin: 0 12px 12px;\n}\n.lib-detail {\n display: flex;\n flex-direction: column;\n min-height: 0;\n gap: 10px;\n padding: 12px;\n overflow-y: auto;\n border-left: 1px solid var(--line);\n background: var(--bg-1);\n}\n.lib-stage {\n display: grid;\n place-items: center;\n aspect-ratio: 1;\n border: 1px solid var(--line);\n border-radius: var(--r-sm);\n background: repeating-conic-gradient(var(--bg-3) 0% 25%, var(--bg-2) 0% 50%) 50% / 18px 18px;\n overflow: hidden;\n}\n.lib-stage img {\n max-width: 100%;\n max-height: 100%;\n object-fit: contain;\n}\n.lib-preview3d,\n.lib-preview-canvas {\n width: 100%;\n height: 100%;\n display: block;\n cursor: grab;\n}\n.lib-preview-canvas:active {\n cursor: grabbing;\n}\n.lib-name {\n margin: 0;\n font-size: 13px;\n word-break: break-word;\n}\n.lib-desc {\n margin: 0;\n color: var(--text-dim);\n font-size: 12px;\n line-height: 1.5;\n}\n.lib-note {\n color: var(--accent);\n font-size: 11.5px;\n}\n.lib-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n}\n.lib-tag {\n padding: 2px 7px;\n border-radius: 999px;\n background: var(--bg-3);\n color: var(--text-faint);\n font-size: 10.5px;\n}\n.lib-facts {\n display: grid;\n grid-template-columns: 74px 1fr;\n gap: 3px 8px;\n margin: 0;\n font-size: 11.5px;\n}\n.lib-facts dt {\n color: var(--text-faint);\n}\n.lib-facts dd {\n margin: 0;\n color: var(--text-dim);\n font-family: ui-monospace, Menlo, monospace;\n}\n.lib-url {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n.lib-url code {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n padding: 5px 7px;\n border-radius: var(--r-sm);\n background: var(--bg-0);\n color: var(--text-faint);\n font-size: 10.5px;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.lib-actions {\n display: flex;\n gap: 6px;\n margin-top: auto;\n}\n.lib-actions button {\n flex: 1;\n justify-content: center;\n}\n.lib-empty,\n.lib-error {\n grid-column: 1 / -1;\n padding: 24px 12px;\n color: var(--text-faint);\n font-size: 12px;\n text-align: center;\n}\n.lib-error {\n color: var(--rose);\n}\n.lib-token {\n grid-column: 1 / -1;\n max-width: 520px;\n margin: 24px auto;\n padding: 16px;\n border: 1px solid var(--line-strong);\n border-radius: var(--r-md);\n background: var(--bg-1);\n}\n.lib-token-line {\n margin: 0 0 8px;\n font-size: 12.5px;\n}\n.lib-token-how {\n color: var(--text-faint);\n font-size: 11.5px;\n line-height: 1.6;\n}\n.lib-token-row {\n display: flex;\n gap: 6px;\n}\n.lib-token-row input {\n flex: 1;\n}\n\n/* ─── animation card ─── */\n.anim-card .slider-row {\n width: 100%;\n}\n.anim-upper {\n margin-top: 8px;\n padding-top: 8px;\n border-top: 1px solid var(--line);\n}\n.anim-upper > summary {\n color: var(--text-faint);\n font-size: 11.5px;\n cursor: pointer;\n list-style: none;\n}\n.anim-upper > summary::before {\n content: \"▸ \";\n}\n.anim-upper[open] > summary::before {\n content: \"▾ \";\n}\n.anim-upper > summary:hover {\n color: var(--text-dim);\n}\n\n/* ─── connections ─── */\n/* Signal wiring on the selected node. Dense on purpose: a row is four fields,\n and a node with a dozen connections still has to fit the inspector column. */\n.connections {\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding: 2px 0 6px;\n}\n.conn-group {\n font-size: 10px;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n opacity: 0.55;\n margin-top: 4px;\n}\n.conn-row {\n display: grid;\n grid-template-columns: 1fr 10px 1fr 1fr 18px;\n gap: 3px;\n align-items: center;\n}\n.conn-arrow {\n text-align: center;\n opacity: 0.5;\n font-size: 11px;\n}\n.conn-select,\n.conn-handler {\n min-width: 0;\n font-size: 11px;\n padding: 2px 4px;\n}\n.conn-select.dangling,\n.field input.dangling {\n border-color: #f87171;\n color: #f87171;\n}\n.conn-warn {\n font-size: 10px;\n color: #f87171;\n padding: 1px 0 3px;\n line-height: 1.35;\n}\n.conn-remove {\n border: 0;\n background: none;\n color: inherit;\n opacity: 0.4;\n cursor: pointer;\n font-size: 11px;\n padding: 0;\n}\n.conn-remove:hover {\n opacity: 1;\n color: #f87171;\n}\n.conn-add {\n padding-top: 2px;\n}\n.conn-add button {\n font-size: 11px;\n padding: 2px 8px;\n cursor: pointer;\n}\n.conn-add button:disabled {\n opacity: 0.4;\n cursor: default;\n}\n";
|
|
8162
|
+
//#endregion
|
|
8163
|
+
//#region src/sub-scenes.ts
|
|
8164
|
+
async function Cs(e, t, n = 8) {
|
|
8165
|
+
let r = /* @__PURE__ */ new Map(), i = [e];
|
|
8166
|
+
for (let e = 0; e < n && i.length > 0; e++) {
|
|
8167
|
+
let e = /* @__PURE__ */ new Set();
|
|
8168
|
+
for (let t of i) ws(t.root, e);
|
|
8169
|
+
let n = [...e].filter((e) => !r.has(e));
|
|
8170
|
+
if (n.length === 0) break;
|
|
8171
|
+
let a = await Promise.all(n.map(async (e) => {
|
|
8172
|
+
try {
|
|
8173
|
+
return [e, await t.loadScene(e)];
|
|
8174
|
+
} catch {
|
|
8175
|
+
return [e, null];
|
|
8176
|
+
}
|
|
8177
|
+
}));
|
|
8178
|
+
i = [];
|
|
8179
|
+
for (let [e, t] of a) t && (r.set(e, t), i.push(t));
|
|
8180
|
+
}
|
|
8181
|
+
return r;
|
|
8015
8182
|
}
|
|
8016
|
-
function
|
|
8017
|
-
|
|
8183
|
+
function ws(e, t) {
|
|
8184
|
+
if (!e || typeof e != "object") return;
|
|
8185
|
+
let n = e.instance;
|
|
8186
|
+
typeof n == "string" && n !== "" && t.add(n);
|
|
8187
|
+
for (let n of e.children ?? []) ws(n, t);
|
|
8018
8188
|
}
|
|
8019
|
-
|
|
8189
|
+
//#endregion
|
|
8190
|
+
//#region src/tree.ts
|
|
8191
|
+
var Ts = new Map(Nt.flatMap((e) => e.nodes.map((e) => [e.type, e.summary]))), Es = /* @__PURE__ */ new Set(), Ds = null, Os = null, ks = null;
|
|
8020
8192
|
function As(e) {
|
|
8193
|
+
Os = e;
|
|
8194
|
+
}
|
|
8195
|
+
function js(e) {
|
|
8196
|
+
Ds = e;
|
|
8197
|
+
}
|
|
8198
|
+
function Ms(e) {
|
|
8199
|
+
ks = e;
|
|
8200
|
+
}
|
|
8201
|
+
var Ns = null, Ps = null, Fs = null;
|
|
8202
|
+
function Is(e) {
|
|
8021
8203
|
return e ? e.includes("Body") || e.includes("Area") || e.includes("Controller") ? "cat-body" : e === "NetworkSpawner" ? "cat-net" : e.endsWith("3D") ? "cat-3d" : e.endsWith("2D") || e === "Label" || e === "UILayer" ? "cat-2d" : "cat-core" : "cat-core";
|
|
8022
8204
|
}
|
|
8023
|
-
function
|
|
8205
|
+
function Ls(e, t) {
|
|
8024
8206
|
e.textContent = "";
|
|
8025
8207
|
let n = document.createElement("div");
|
|
8026
8208
|
n.className = `tree-row scene-row${t.selection === null && t.selectedAsset === null && t.selectedGroup === null && !t.addingAsset && !t.addingGroup ? " selected" : ""}`, n.textContent = `⚙ ${String(t.working.name ?? "scene")}`, n.addEventListener("click", () => t.select(null)), e.appendChild(n);
|
|
@@ -8030,54 +8212,54 @@ function js(e, t) {
|
|
|
8030
8212
|
t.className = "muted-note explorer-empty", t.textContent = "no root node — pick a type below and + to start the scene", e.appendChild(t);
|
|
8031
8213
|
return;
|
|
8032
8214
|
}
|
|
8033
|
-
|
|
8215
|
+
Vs(r, t.selection), e.appendChild(Hs(r, [], t, "")), zs(e, t.selection);
|
|
8034
8216
|
}
|
|
8035
|
-
var
|
|
8036
|
-
function
|
|
8217
|
+
var Rs = null;
|
|
8218
|
+
function zs(e, t) {
|
|
8037
8219
|
let n = JSON.stringify(t);
|
|
8038
|
-
n !==
|
|
8220
|
+
n !== Rs && (Rs = n, e.querySelector(".tree-row.selected")?.scrollIntoView?.({
|
|
8039
8221
|
block: "nearest",
|
|
8040
8222
|
inline: "nearest"
|
|
8041
8223
|
}));
|
|
8042
8224
|
}
|
|
8043
|
-
function
|
|
8044
|
-
|
|
8225
|
+
function Bs() {
|
|
8226
|
+
Rs = null;
|
|
8045
8227
|
}
|
|
8046
|
-
function
|
|
8228
|
+
function Vs(e, t) {
|
|
8047
8229
|
if (!t) return;
|
|
8048
8230
|
let n = e, r = "";
|
|
8049
8231
|
for (let e of t) {
|
|
8050
|
-
r = r ? `${r}/${n.name}` : String(n.name),
|
|
8232
|
+
r = r ? `${r}/${n.name}` : String(n.name), Es.delete(r);
|
|
8051
8233
|
let t = n.children?.[e];
|
|
8052
8234
|
if (!t) return;
|
|
8053
8235
|
n = t;
|
|
8054
8236
|
}
|
|
8055
8237
|
}
|
|
8056
|
-
function
|
|
8057
|
-
let i = r ? `${r}/${e.name}` : String(e.name), a = (e.children?.length ?? 0) > 0, o =
|
|
8238
|
+
function Hs(e, t, n, r) {
|
|
8239
|
+
let i = r ? `${r}/${e.name}` : String(e.name), a = (e.children?.length ?? 0) > 0, o = Es.has(i), s = document.createElement("div");
|
|
8058
8240
|
s.className = "tree-branch";
|
|
8059
8241
|
let c = document.createElement("div");
|
|
8060
|
-
c.className = `tree-row${n.isSelected(t) ? " selected" : ""}`, c.draggable = t.length > 0 &&
|
|
8242
|
+
c.className = `tree-row${n.isSelected(t) ? " selected" : ""}`, c.draggable = t.length > 0 && Fs !== i;
|
|
8061
8243
|
let l = document.createElement("span");
|
|
8062
8244
|
l.className = `chevron${a ? "" : " leaf"}${o ? " collapsed" : ""}`, a ? l.appendChild(Ye()) : l.textContent = "·", a && l.addEventListener("click", (e) => {
|
|
8063
|
-
e.stopPropagation(), o ?
|
|
8245
|
+
e.stopPropagation(), o ? Es.delete(i) : Es.add(i), n.select(n.selection);
|
|
8064
8246
|
});
|
|
8065
8247
|
let u = document.createElement("span");
|
|
8066
|
-
if (u.className = `tree-icon ${
|
|
8067
|
-
t.stopPropagation(),
|
|
8068
|
-
}), c.append(l, u),
|
|
8248
|
+
if (u.className = `tree-icon ${Is(e.type)}`, u.appendChild(Je(e.type)), u.title = e.type ?? "instance", u.addEventListener("click", (t) => {
|
|
8249
|
+
t.stopPropagation(), Us(u, e.type ?? "instance");
|
|
8250
|
+
}), c.append(l, u), Fs === i) {
|
|
8069
8251
|
let r = document.createElement("input");
|
|
8070
8252
|
r.className = "rename-input", r.value = e.name ?? "";
|
|
8071
8253
|
let i = () => {
|
|
8072
|
-
|
|
8254
|
+
Fs = null;
|
|
8073
8255
|
let i = r.value.trim();
|
|
8074
8256
|
if (i && i !== e.name) {
|
|
8075
8257
|
let e = n.renameNode(t, i) ?? [];
|
|
8076
|
-
e.length > 0 &&
|
|
8258
|
+
e.length > 0 && ks?.(e);
|
|
8077
8259
|
} else n.select(n.selection);
|
|
8078
8260
|
};
|
|
8079
8261
|
r.addEventListener("keydown", (e) => {
|
|
8080
|
-
e.stopPropagation(), e.key === "Enter" && i(), e.key === "Escape" && (
|
|
8262
|
+
e.stopPropagation(), e.key === "Enter" && i(), e.key === "Escape" && (Fs = null, n.select(n.selection));
|
|
8081
8263
|
});
|
|
8082
8264
|
for (let e of [
|
|
8083
8265
|
"click",
|
|
@@ -8091,38 +8273,38 @@ function Is(e, t, n, r) {
|
|
|
8091
8273
|
} else {
|
|
8092
8274
|
let r = document.createElement("span");
|
|
8093
8275
|
r.className = "tree-name", r.textContent = e.name ?? "(unnamed)", r.addEventListener("dblclick", (e) => {
|
|
8094
|
-
e.stopPropagation(),
|
|
8276
|
+
e.stopPropagation(), Fs = i, n.select(t);
|
|
8095
8277
|
}), c.appendChild(r);
|
|
8096
8278
|
}
|
|
8097
8279
|
if (c.addEventListener("click", (e) => {
|
|
8098
|
-
a && !e.metaKey && !e.ctrlKey && (o ?
|
|
8280
|
+
a && !e.metaKey && !e.ctrlKey && (o ? Es.delete(i) : Es.add(i)), n.select(t, { toggle: e.metaKey || e.ctrlKey });
|
|
8099
8281
|
}), c.addEventListener("contextmenu", (e) => {
|
|
8100
|
-
e.preventDefault(), n.isSelected(t) || n.select(t),
|
|
8101
|
-
}),
|
|
8282
|
+
e.preventDefault(), n.isSelected(t) || n.select(t), Ws(e.clientX, e.clientY, n, t, i);
|
|
8283
|
+
}), $s(c, t, n), s.appendChild(c), a && !o) {
|
|
8102
8284
|
let r = document.createElement("div");
|
|
8103
8285
|
r.className = "tree-children", (e.children ?? []).forEach((e, a) => {
|
|
8104
|
-
r.appendChild(
|
|
8286
|
+
r.appendChild(Hs(e, [...t, a], n, i));
|
|
8105
8287
|
}), s.appendChild(r);
|
|
8106
8288
|
}
|
|
8107
8289
|
return s;
|
|
8108
8290
|
}
|
|
8109
|
-
function
|
|
8110
|
-
|
|
8291
|
+
function Us(e, t) {
|
|
8292
|
+
Ys();
|
|
8111
8293
|
let n = document.createElement("div");
|
|
8112
8294
|
n.className = "balloon floating";
|
|
8113
8295
|
let r = document.createElement("span");
|
|
8114
8296
|
r.className = "balloon-title", r.textContent = t, n.appendChild(r);
|
|
8115
|
-
let i =
|
|
8297
|
+
let i = Ts.get(t);
|
|
8116
8298
|
if (i) {
|
|
8117
8299
|
let e = document.createElement("span");
|
|
8118
8300
|
e.textContent = I(i), n.appendChild(e);
|
|
8119
8301
|
}
|
|
8120
8302
|
document.body.appendChild(n);
|
|
8121
8303
|
let a = e.getBoundingClientRect();
|
|
8122
|
-
n.style.left = `${Math.min(innerWidth - 240, a.right + 8)}px`, n.style.top = `${Math.max(8, a.top - 6)}px`,
|
|
8304
|
+
n.style.left = `${Math.min(innerWidth - 240, a.right + 8)}px`, n.style.top = `${Math.max(8, a.top - 6)}px`, Xs(n);
|
|
8123
8305
|
}
|
|
8124
|
-
function
|
|
8125
|
-
|
|
8306
|
+
function Ws(e, t, n, r, i) {
|
|
8307
|
+
Ys();
|
|
8126
8308
|
let a = n.allSelections(), o = a.length === 1 && r.length > 0, s = document.createElement("div");
|
|
8127
8309
|
s.className = "context-menu floating";
|
|
8128
8310
|
let c = (e, t, n) => {
|
|
@@ -8134,52 +8316,52 @@ function Rs(e, t, n, r, i) {
|
|
|
8134
8316
|
e.textContent = n.kbd, r.appendChild(e);
|
|
8135
8317
|
}
|
|
8136
8318
|
t && r.addEventListener("click", () => {
|
|
8137
|
-
|
|
8319
|
+
Ys(), t();
|
|
8138
8320
|
}), s.appendChild(r);
|
|
8139
8321
|
};
|
|
8140
8322
|
c(`duplicate${a.length > 1 ? ` ×${a.length}` : ""}`, () => {
|
|
8141
8323
|
for (let e of [...a].reverse()) n.duplicateNode(e);
|
|
8142
|
-
}), c("frame in view",
|
|
8143
|
-
n.select(r),
|
|
8324
|
+
}), c("frame in view", Os && r.length > 0 ? () => {
|
|
8325
|
+
n.select(r), Os?.();
|
|
8144
8326
|
} : null, { kbd: "F" }), c("rename", o ? () => {
|
|
8145
|
-
|
|
8146
|
-
} : null, { kbd: "dbl-click" }), s.appendChild(
|
|
8327
|
+
Fs = i, n.select(r);
|
|
8328
|
+
} : null, { kbd: "dbl-click" }), s.appendChild(Gs()), c("cut", r.length > 0 ? () => Ks(n, !0) : null), c("copy", r.length > 0 ? () => Ks(n, !1) : null), c(`paste as child${Ps ? ` (${Ps.nodes.length})` : ""}`, Ps ? () => qs(n, r) : null), s.appendChild(Gs()), c("delete", r.length > 0 ? () => (Ds ?? ((e) => n.removeNodes(e)))(a) : null, { danger: !0 }), document.body.appendChild(s), s.style.left = `${Math.min(innerWidth - 200 - 8, e)}px`, s.style.top = `${Math.min(innerHeight - s.offsetHeight - 8, t)}px`, Xs(s);
|
|
8147
8329
|
}
|
|
8148
|
-
function
|
|
8330
|
+
function Gs() {
|
|
8149
8331
|
let e = document.createElement("div");
|
|
8150
8332
|
return e.className = "menu-divider", e;
|
|
8151
8333
|
}
|
|
8152
|
-
function
|
|
8334
|
+
function Ks(e, t) {
|
|
8153
8335
|
let n = e.allSelections().filter((e) => e.length > 0).map((t) => e.nodeAt(t)).filter((e) => e !== null);
|
|
8154
|
-
|
|
8336
|
+
Ps = {
|
|
8155
8337
|
nodes: n.map((e) => JSON.parse(JSON.stringify(e))),
|
|
8156
8338
|
cut: t ? n : null
|
|
8157
8339
|
};
|
|
8158
8340
|
}
|
|
8159
|
-
function
|
|
8160
|
-
if (
|
|
8161
|
-
for (let n of
|
|
8162
|
-
if (
|
|
8163
|
-
let t = e.working.root, n =
|
|
8164
|
-
n.length > 0 && e.removeNodes(n),
|
|
8165
|
-
nodes:
|
|
8341
|
+
function qs(e, t) {
|
|
8342
|
+
if (Ps) {
|
|
8343
|
+
for (let n of Ps.nodes) e.insertNode(n, t);
|
|
8344
|
+
if (Ps.cut) {
|
|
8345
|
+
let t = e.working.root, n = Ps.cut.map((e) => Js(t, e)).filter((e) => e !== null);
|
|
8346
|
+
n.length > 0 && e.removeNodes(n), Ps = {
|
|
8347
|
+
nodes: Ps.nodes,
|
|
8166
8348
|
cut: null
|
|
8167
8349
|
};
|
|
8168
8350
|
}
|
|
8169
8351
|
}
|
|
8170
8352
|
}
|
|
8171
|
-
function
|
|
8353
|
+
function Js(e, t) {
|
|
8172
8354
|
if (e === t) return [];
|
|
8173
8355
|
for (let [n, r] of (e.children ?? []).entries()) {
|
|
8174
|
-
let e =
|
|
8356
|
+
let e = Js(r, t);
|
|
8175
8357
|
if (e) return [n, ...e];
|
|
8176
8358
|
}
|
|
8177
8359
|
return null;
|
|
8178
8360
|
}
|
|
8179
|
-
function
|
|
8361
|
+
function Ys() {
|
|
8180
8362
|
for (let e of document.querySelectorAll(".floating")) e.remove();
|
|
8181
8363
|
}
|
|
8182
|
-
function
|
|
8364
|
+
function Xs(e) {
|
|
8183
8365
|
let t = (r) => {
|
|
8184
8366
|
e.contains(r.target) || (e.remove(), document.removeEventListener("pointerdown", t, !0), document.removeEventListener("keydown", n, !0));
|
|
8185
8367
|
}, n = (r) => {
|
|
@@ -8189,38 +8371,38 @@ function Ws(e) {
|
|
|
8189
8371
|
document.addEventListener("pointerdown", t, !0), document.addEventListener("keydown", n, !0);
|
|
8190
8372
|
}, 0);
|
|
8191
8373
|
}
|
|
8192
|
-
function
|
|
8374
|
+
function Zs(e, t) {
|
|
8193
8375
|
let n = t.getBoundingClientRect(), r = (e.clientY - n.top) / n.height;
|
|
8194
8376
|
return r < .25 ? "before" : r > .75 ? "after" : "into";
|
|
8195
8377
|
}
|
|
8196
|
-
function
|
|
8378
|
+
function Qs(e) {
|
|
8197
8379
|
e.classList.remove("drop-into", "drop-before", "drop-after");
|
|
8198
8380
|
}
|
|
8199
|
-
function
|
|
8381
|
+
function $s(e, t, n) {
|
|
8200
8382
|
e.addEventListener("dragstart", (r) => {
|
|
8201
|
-
|
|
8383
|
+
Ns = n.isSelected(t) ? n.allSelections() : [t], r.dataTransfer?.setData("text/plain", ""), r.dataTransfer && (r.dataTransfer.effectAllowed = "move"), e.classList.add("dragging");
|
|
8202
8384
|
}), e.addEventListener("dragend", () => {
|
|
8203
|
-
|
|
8385
|
+
Ns = null, e.classList.remove("dragging");
|
|
8204
8386
|
}), e.addEventListener("dragover", (n) => {
|
|
8205
|
-
if (!
|
|
8206
|
-
n.preventDefault(), n.dataTransfer && (n.dataTransfer.dropEffect = "move"),
|
|
8207
|
-
let r = t.length === 0 ? "into" :
|
|
8387
|
+
if (!Ns || Ns.some((e) => e.length <= t.length && e.every((e, n) => e === t[n]))) return;
|
|
8388
|
+
n.preventDefault(), n.dataTransfer && (n.dataTransfer.dropEffect = "move"), Qs(e);
|
|
8389
|
+
let r = t.length === 0 ? "into" : Zs(n, e);
|
|
8208
8390
|
e.classList.add(`drop-${r}`);
|
|
8209
|
-
}), e.addEventListener("dragleave", () =>
|
|
8210
|
-
if (
|
|
8391
|
+
}), e.addEventListener("dragleave", () => Qs(e)), e.addEventListener("drop", (r) => {
|
|
8392
|
+
if (Qs(e), !Ns) return;
|
|
8211
8393
|
r.preventDefault();
|
|
8212
|
-
let i = t.length === 0 ? "into" :
|
|
8213
|
-
|
|
8394
|
+
let i = t.length === 0 ? "into" : Zs(r, e), a = n.moveNodes(Ns, t, i);
|
|
8395
|
+
Ns = null, a?.[0] && n.select(a[0]);
|
|
8214
8396
|
});
|
|
8215
8397
|
}
|
|
8216
8398
|
//#endregion
|
|
8217
8399
|
//#region src/transform-gizmo.ts
|
|
8218
|
-
var
|
|
8400
|
+
var ec = {
|
|
8219
8401
|
x: "#fb7185",
|
|
8220
8402
|
y: "#86efac",
|
|
8221
8403
|
z: "#7aa2ff"
|
|
8222
8404
|
};
|
|
8223
|
-
function
|
|
8405
|
+
function tc(e, t, n) {
|
|
8224
8406
|
let r = t - e.origin.x, i = n - e.origin.y;
|
|
8225
8407
|
if (Math.abs(r) <= e.centerSize && Math.abs(i) <= e.centerSize) return { kind: "center" };
|
|
8226
8408
|
for (let t of e.axes) {
|
|
@@ -8234,11 +8416,11 @@ function Ys(e, t, n) {
|
|
|
8234
8416
|
}
|
|
8235
8417
|
return null;
|
|
8236
8418
|
}
|
|
8237
|
-
function
|
|
8419
|
+
function nc(e, t, n) {
|
|
8238
8420
|
let r = e.sx * e.sx + e.sy * e.sy;
|
|
8239
8421
|
return r < 1 ? 0 : (t * e.sx + n * e.sy) / r * e.worldPerUnit;
|
|
8240
8422
|
}
|
|
8241
|
-
function
|
|
8423
|
+
function rc(e, t, n, r = !1) {
|
|
8242
8424
|
let { origin: i, axes: a, centerSize: o } = t;
|
|
8243
8425
|
for (let t of a) {
|
|
8244
8426
|
let a = n?.kind === "axis" && n.axis === t.axis;
|
|
@@ -8249,16 +8431,16 @@ function Zs(e, t, n, r = !1) {
|
|
|
8249
8431
|
let s = n?.kind === "center";
|
|
8250
8432
|
e.globalAlpha = s ? 1 : .95, e.fillStyle = s ? "#ffffff" : "#e2e6f0", e.strokeStyle = "#0b0d14", e.lineWidth = 1.5, e.beginPath(), e.rect(i.x - o, i.y - o, o * 2, o * 2), e.fill(), e.stroke(), e.globalAlpha = 1;
|
|
8251
8433
|
}
|
|
8252
|
-
function
|
|
8434
|
+
function ic(e, t, n) {
|
|
8253
8435
|
return Math.atan2(n - e.y, t - e.x) * 180 / Math.PI;
|
|
8254
8436
|
}
|
|
8255
|
-
function
|
|
8437
|
+
function ac(e, t) {
|
|
8256
8438
|
let n = t - e;
|
|
8257
8439
|
for (; n > 180;) n -= 360;
|
|
8258
8440
|
for (; n <= -180;) n += 360;
|
|
8259
8441
|
return n;
|
|
8260
8442
|
}
|
|
8261
|
-
function
|
|
8443
|
+
function oc(e, t, n, r) {
|
|
8262
8444
|
let i = null, a = r;
|
|
8263
8445
|
for (let r of e) for (let e of r.points) {
|
|
8264
8446
|
let o = Math.hypot(t - e.x, n - e.y);
|
|
@@ -8266,11 +8448,11 @@ function ec(e, t, n, r) {
|
|
|
8266
8448
|
}
|
|
8267
8449
|
return i;
|
|
8268
8450
|
}
|
|
8269
|
-
function
|
|
8451
|
+
function sc(e, t, n) {
|
|
8270
8452
|
for (let r of t) {
|
|
8271
8453
|
if (r.points.length < 2) continue;
|
|
8272
8454
|
let t = n === r.axis;
|
|
8273
|
-
e.strokeStyle =
|
|
8455
|
+
e.strokeStyle = ec[r.axis], e.globalAlpha = t ? 1 : .75, e.lineWidth = t ? 3 : 2, e.beginPath();
|
|
8274
8456
|
let i = r.points[0];
|
|
8275
8457
|
e.moveTo(i.x, i.y);
|
|
8276
8458
|
for (let t of r.points.slice(1)) e.lineTo(t.x, t.y);
|
|
@@ -8278,14 +8460,25 @@ function tc(e, t, n) {
|
|
|
8278
8460
|
}
|
|
8279
8461
|
e.globalAlpha = 1;
|
|
8280
8462
|
}
|
|
8281
|
-
function
|
|
8463
|
+
function cc(e, t, n, r) {
|
|
8282
8464
|
e.font = "600 11px ui-monospace, Menlo, monospace";
|
|
8283
8465
|
let i = e.measureText(r).width + 14;
|
|
8284
8466
|
e.fillStyle = "rgba(16, 19, 29, 0.92)", e.strokeStyle = "rgba(110, 231, 220, 0.5)", e.lineWidth = 1, e.beginPath(), e.roundRect(t + 14, n - 26, i, 20, 5), e.fill(), e.stroke(), e.fillStyle = "#6ee7dc", e.textAlign = "left", e.textBaseline = "middle", e.fillText(r, t + 21, n - 16);
|
|
8285
8467
|
}
|
|
8286
8468
|
//#endregion
|
|
8287
8469
|
//#region src/viewport.ts
|
|
8288
|
-
var
|
|
8470
|
+
var lc = class {
|
|
8471
|
+
subScenes = /* @__PURE__ */ new Map();
|
|
8472
|
+
setSubScenes(e) {
|
|
8473
|
+
this.subScenes = e;
|
|
8474
|
+
}
|
|
8475
|
+
get resolver() {
|
|
8476
|
+
return this.subScenes.size === 0 ? {} : { resolveScene: (e) => {
|
|
8477
|
+
let t = this.subScenes.get(e);
|
|
8478
|
+
if (!t) throw Error(`no sub-scene fetched for '${e}'`);
|
|
8479
|
+
return t;
|
|
8480
|
+
} };
|
|
8481
|
+
}
|
|
8289
8482
|
engine;
|
|
8290
8483
|
editCanvas;
|
|
8291
8484
|
overlay;
|
|
@@ -8393,7 +8586,10 @@ var rc = class {
|
|
|
8393
8586
|
let n;
|
|
8394
8587
|
try {
|
|
8395
8588
|
let t = structuredClone(e);
|
|
8396
|
-
|
|
8589
|
+
Tc(t), n = f(t, {
|
|
8590
|
+
stubAllBehaviors: !0,
|
|
8591
|
+
...this.resolver
|
|
8592
|
+
});
|
|
8397
8593
|
} catch (e) {
|
|
8398
8594
|
return e instanceof Error ? e.message : String(e);
|
|
8399
8595
|
}
|
|
@@ -8409,7 +8605,7 @@ var rc = class {
|
|
|
8409
8605
|
canvas: this.editCanvas,
|
|
8410
8606
|
engine: this.engine
|
|
8411
8607
|
}), this.renderer3d.ignoreStatic = !0;
|
|
8412
|
-
let t =
|
|
8608
|
+
let t = xc(e.root);
|
|
8413
8609
|
if (t) {
|
|
8414
8610
|
let [e, n, r] = t;
|
|
8415
8611
|
this.orbit.dist = Math.max(2, Math.hypot(e, n, r)), this.orbit.yaw = Math.atan2(e, r), this.orbit.pitch = Math.asin(Math.max(-.99, Math.min(.99, n / this.orbit.dist))), this.orbit.target = [
|
|
@@ -8431,13 +8627,16 @@ var rc = class {
|
|
|
8431
8627
|
if (!e.root) return null;
|
|
8432
8628
|
try {
|
|
8433
8629
|
let t = structuredClone(e);
|
|
8434
|
-
return
|
|
8630
|
+
return Tc(t), f(t, {
|
|
8631
|
+
stubAllBehaviors: !0,
|
|
8632
|
+
...this.resolver
|
|
8633
|
+
}), null;
|
|
8435
8634
|
} catch (e) {
|
|
8436
8635
|
return e instanceof Error ? e.message : String(e);
|
|
8437
8636
|
}
|
|
8438
8637
|
}
|
|
8439
8638
|
defaultView(e) {
|
|
8440
|
-
let t =
|
|
8639
|
+
let t = Sc(e.root);
|
|
8441
8640
|
if (t) return {
|
|
8442
8641
|
cx: t[0],
|
|
8443
8642
|
cy: t[1],
|
|
@@ -8514,7 +8713,7 @@ var rc = class {
|
|
|
8514
8713
|
this.gizmoMode = e, this.cb.onModeChanged(e);
|
|
8515
8714
|
}
|
|
8516
8715
|
screen2D(e) {
|
|
8517
|
-
let t =
|
|
8716
|
+
let t = bc(e);
|
|
8518
8717
|
return this.renderer2d ? this.renderer2d.isUiNode(e) ? this.renderer2d.screenFromUi(t.x, t.y) : this.renderer2d.screenFromWorld(t.x, t.y) : t;
|
|
8519
8718
|
}
|
|
8520
8719
|
point2D(e, t, n) {
|
|
@@ -8538,13 +8737,13 @@ var rc = class {
|
|
|
8538
8737
|
sx: 64,
|
|
8539
8738
|
sy: 0,
|
|
8540
8739
|
worldPerUnit: 64 / r,
|
|
8541
|
-
color:
|
|
8740
|
+
color: ec.x
|
|
8542
8741
|
}, {
|
|
8543
8742
|
axis: "y",
|
|
8544
8743
|
sx: 0,
|
|
8545
8744
|
sy: 64,
|
|
8546
8745
|
worldPerUnit: 64 / r,
|
|
8547
|
-
color:
|
|
8746
|
+
color: ec.y
|
|
8548
8747
|
}]
|
|
8549
8748
|
};
|
|
8550
8749
|
}
|
|
@@ -8578,7 +8777,7 @@ var rc = class {
|
|
|
8578
8777
|
sx: n.x - r.x,
|
|
8579
8778
|
sy: n.y - r.y,
|
|
8580
8779
|
worldPerUnit: o,
|
|
8581
|
-
color:
|
|
8780
|
+
color: ec[e]
|
|
8582
8781
|
});
|
|
8583
8782
|
}
|
|
8584
8783
|
return {
|
|
@@ -8652,11 +8851,11 @@ var rc = class {
|
|
|
8652
8851
|
return null;
|
|
8653
8852
|
}
|
|
8654
8853
|
orbitVectors() {
|
|
8655
|
-
let { yaw: e, pitch: t, dist: n, target: r } = this.orbit, i = Math.cos(t), a = new
|
|
8854
|
+
let { yaw: e, pitch: t, dist: n, target: r } = this.orbit, i = Math.cos(t), a = new K(r[0] + n * i * Math.sin(e), r[1] + n * Math.sin(t), r[2] + n * i * Math.cos(e)), o = new K(r[0], r[1], r[2]).sub(a).normalize(), s = new K().crossVectors(o, dc).normalize();
|
|
8656
8855
|
return {
|
|
8657
8856
|
pos: a,
|
|
8658
8857
|
right: s,
|
|
8659
|
-
up: new
|
|
8858
|
+
up: new K().crossVectors(s, o).normalize(),
|
|
8660
8859
|
forward: o
|
|
8661
8860
|
};
|
|
8662
8861
|
}
|
|
@@ -8678,13 +8877,13 @@ var rc = class {
|
|
|
8678
8877
|
for (let [t] of this.pathOf) if (t instanceof S && (t.current || !e) && (e = t, t.current)) break;
|
|
8679
8878
|
let t = e ? e._ensureObject3D() : null;
|
|
8680
8879
|
if (t) {
|
|
8681
|
-
t.getWorldPosition(
|
|
8880
|
+
t.getWorldPosition(fc), pc.set(0, 0, -1).applyQuaternion(t.getWorldQuaternion(mc));
|
|
8682
8881
|
let e = Math.min(40, Math.max(3, this.orbit.dist));
|
|
8683
8882
|
this.orbit.target = [
|
|
8684
|
-
|
|
8685
|
-
|
|
8686
|
-
|
|
8687
|
-
], this.orbit.dist = e, this.orbit.yaw = Math.atan2(-
|
|
8883
|
+
fc.x + pc.x * e,
|
|
8884
|
+
fc.y + pc.y * e,
|
|
8885
|
+
fc.z + pc.z * e
|
|
8886
|
+
], this.orbit.dist = e, this.orbit.yaw = Math.atan2(-pc.x, -pc.z), this.orbit.pitch = Math.asin(Math.max(-.99, Math.min(.99, -pc.y)));
|
|
8688
8887
|
}
|
|
8689
8888
|
this.renderer3d.viewOverride = null;
|
|
8690
8889
|
return;
|
|
@@ -8704,9 +8903,9 @@ var rc = class {
|
|
|
8704
8903
|
gizmoHandles() {
|
|
8705
8904
|
let { right: e, up: t, forward: n } = this.orbitVectors(), r = this.gizmoCenter(), i = [];
|
|
8706
8905
|
for (let [a, o] of [
|
|
8707
|
-
["x", new
|
|
8708
|
-
["y", new
|
|
8709
|
-
["z", new
|
|
8906
|
+
["x", new K(1, 0, 0)],
|
|
8907
|
+
["y", new K(0, 1, 0)],
|
|
8908
|
+
["z", new K(0, 0, 1)]
|
|
8710
8909
|
]) for (let s of [1, -1]) {
|
|
8711
8910
|
let c = o.clone().multiplyScalar(s);
|
|
8712
8911
|
i.push({
|
|
@@ -8780,7 +8979,7 @@ var rc = class {
|
|
|
8780
8979
|
let t = this.overlay.clientWidth, n = this.overlay.clientHeight, r = Math.min(devicePixelRatio || 1, 2);
|
|
8781
8980
|
if ((this.overlay.width !== t * r || this.overlay.height !== n * r) && (this.overlay.width = t * r, this.overlay.height = n * r), e.setTransform(r, 0, 0, r, 0, 0), e.clearRect(0, 0, t, n), this.playing) return;
|
|
8782
8981
|
if (this.rendererDim === "3d") {
|
|
8783
|
-
this.drawGizmo(e), this.drawModeGizmo(e), this.readout &&
|
|
8982
|
+
this.drawGizmo(e), this.drawModeGizmo(e), this.readout && cc(e, this.readout.x, this.readout.y, this.readout.text);
|
|
8784
8983
|
return;
|
|
8785
8984
|
}
|
|
8786
8985
|
if (!this.renderer2d) return;
|
|
@@ -8805,16 +9004,16 @@ var rc = class {
|
|
|
8805
9004
|
]) e.fillRect(n - 3, r - 3, 6, 6);
|
|
8806
9005
|
}
|
|
8807
9006
|
}
|
|
8808
|
-
this.drawModeGizmo(e), this.readout &&
|
|
9007
|
+
this.drawModeGizmo(e), this.readout && cc(e, this.readout.x, this.readout.y, this.readout.text);
|
|
8809
9008
|
}
|
|
8810
9009
|
drawModeGizmo(e) {
|
|
8811
9010
|
if (this.gizmoMode === "rotate") {
|
|
8812
9011
|
let t = this.ringLayout();
|
|
8813
|
-
t &&
|
|
9012
|
+
t && sc(e, t.rings, this.activeRing);
|
|
8814
9013
|
return;
|
|
8815
9014
|
}
|
|
8816
9015
|
let t = this.gizmoLayout();
|
|
8817
|
-
t &&
|
|
9016
|
+
t && rc(e, t, this.gizmoActive, this.gizmoMode === "scale");
|
|
8818
9017
|
}
|
|
8819
9018
|
pointBounds(e) {
|
|
8820
9019
|
if (!this.renderer2d) return null;
|
|
@@ -8867,7 +9066,7 @@ var rc = class {
|
|
|
8867
9066
|
let e = this.overlay, t = null, n = null, r = !1, i = null, a = null, o = null, s = null, c = null, l = (t) => {
|
|
8868
9067
|
let n = this.ringLayout();
|
|
8869
9068
|
if (!n) return !1;
|
|
8870
|
-
let r =
|
|
9069
|
+
let r = oc(n.rings, t.offsetX, t.offsetY, 9);
|
|
8871
9070
|
if (!r) return !1;
|
|
8872
9071
|
let i = this.liveSelected();
|
|
8873
9072
|
if (!i) return !1;
|
|
@@ -8881,13 +9080,13 @@ var rc = class {
|
|
|
8881
9080
|
axis: r,
|
|
8882
9081
|
node: i,
|
|
8883
9082
|
origin: n.origin,
|
|
8884
|
-
startAngle:
|
|
9083
|
+
startAngle: ic(n.origin, t.offsetX, t.offsetY),
|
|
8885
9084
|
startRotation: Array.isArray(a) ? [...a] : a ?? 0,
|
|
8886
9085
|
sign: o
|
|
8887
9086
|
}, this.activeRing = r, !0;
|
|
8888
9087
|
}, u = (e) => {
|
|
8889
9088
|
if (!c) return;
|
|
8890
|
-
let { axis: t, node: n, origin: r, startAngle: i, startRotation: a, sign: o } = c, s =
|
|
9089
|
+
let { axis: t, node: n, origin: r, startAngle: i, startRotation: a, sign: o } = c, s = ac(i, ic(r, e.offsetX, e.offsetY)) * o, l = e.shiftKey || this.shiftHeld ? 15 : null, u = (e) => {
|
|
8891
9090
|
let t = e + s;
|
|
8892
9091
|
return l ? Math.round(t / l) * l : Math.round(t * 10) / 10;
|
|
8893
9092
|
}, d;
|
|
@@ -8928,7 +9127,7 @@ var rc = class {
|
|
|
8928
9127
|
if (this.gizmoMode === "rotate") return l(t);
|
|
8929
9128
|
let n = this.gizmoLayout();
|
|
8930
9129
|
if (!n) return !1;
|
|
8931
|
-
let r =
|
|
9130
|
+
let r = tc(n, t.offsetX, t.offsetY);
|
|
8932
9131
|
if (!r) return !1;
|
|
8933
9132
|
let i = this.liveSelected();
|
|
8934
9133
|
if (!i) return !1;
|
|
@@ -8953,12 +9152,12 @@ var rc = class {
|
|
|
8953
9152
|
}, f = e.shiftKey || this.shiftHeld, p = f ? u ? .5 : 10 : null, m = f ? .25 : null, h = (e) => p ? Math.round(e / p) * p : e, g = (e) => m ? Math.max(m, Math.round(e / m) * m) : e;
|
|
8954
9153
|
if (n === "scale") {
|
|
8955
9154
|
let n = Math.max(.05, 1 + (c - l) * .005), r = [...o];
|
|
8956
|
-
if (t.kind === "axis") r[d[t.axis]] =
|
|
8957
|
-
else for (let e = 0; e < r.length; e++) r[e] =
|
|
9155
|
+
if (t.kind === "axis") r[d[t.axis]] = uc(g((o[d[t.axis]] ?? 1) * n));
|
|
9156
|
+
else for (let e = 0; e < r.length; e++) r[e] = uc(g((o[e] ?? 1) * n));
|
|
8958
9157
|
i.scale = r, this.readout = {
|
|
8959
9158
|
x: e.offsetX,
|
|
8960
9159
|
y: e.offsetY,
|
|
8961
|
-
text: `×${r.map((e) =>
|
|
9160
|
+
text: `×${r.map((e) => uc(e)).join(", ")}`
|
|
8962
9161
|
};
|
|
8963
9162
|
return;
|
|
8964
9163
|
}
|
|
@@ -8966,23 +9165,23 @@ var rc = class {
|
|
|
8966
9165
|
if (t.kind === "axis") {
|
|
8967
9166
|
let e = r.axes.find((e) => e.axis === t.axis);
|
|
8968
9167
|
if (!e) return;
|
|
8969
|
-
let n =
|
|
8970
|
-
if (u) _[d[t.axis]] =
|
|
9168
|
+
let n = nc(e, c, l);
|
|
9169
|
+
if (u) _[d[t.axis]] = uc(h((a[d[t.axis]] ?? 0) + n));
|
|
8971
9170
|
else {
|
|
8972
|
-
let e =
|
|
9171
|
+
let e = vc(i, t.axis === "x" ? n : 0, t.axis === "y" ? n : 0), r = t.axis === "x" ? e.x : e.y;
|
|
8973
9172
|
_[d[t.axis]] = Math.round(h((a[d[t.axis]] ?? 0) + r));
|
|
8974
9173
|
}
|
|
8975
9174
|
} else if (u && this.renderer3d) {
|
|
8976
9175
|
let { right: e, up: t } = this.renderer3d.cameraBasis(), n = this.orbit.dist * .0016;
|
|
8977
|
-
_[0] =
|
|
9176
|
+
_[0] = uc(h((a[0] ?? 0) + (e.x * c - t.x * l) * n)), _[1] = uc(h((a[1] ?? 0) + (e.y * c - t.y * l) * n)), _[2] = uc(h((a[2] ?? 0) + (e.z * c - t.z * l) * n));
|
|
8978
9177
|
} else if (this.renderer2d) {
|
|
8979
|
-
let e = this.renderer2d.view(), t =
|
|
9178
|
+
let e = this.renderer2d.view(), t = vc(i, c / e.zoom, l / e.zoom);
|
|
8980
9179
|
_[0] = Math.round(h((a[0] ?? 0) + t.x)), _[1] = Math.round(h((a[1] ?? 0) + t.y));
|
|
8981
9180
|
}
|
|
8982
9181
|
i.position = _, this.readout = {
|
|
8983
9182
|
x: e.offsetX,
|
|
8984
9183
|
y: e.offsetY,
|
|
8985
|
-
text: `[${_.map((e) =>
|
|
9184
|
+
text: `[${_.map((e) => uc(e)).join(", ")}]`
|
|
8986
9185
|
};
|
|
8987
9186
|
}, m = () => {
|
|
8988
9187
|
if (!s) return;
|
|
@@ -9091,7 +9290,7 @@ var rc = class {
|
|
|
9091
9290
|
return;
|
|
9092
9291
|
}
|
|
9093
9292
|
if (t) {
|
|
9094
|
-
let e = this.point2D(t.node, o.offsetX, o.offsetY), n =
|
|
9293
|
+
let e = this.point2D(t.node, o.offsetX, o.offsetY), n = vc(t.node, e.x - t.startWorld.x, e.y - t.startWorld.y), r = Math.round(t.startPos[0] + n.x), i = Math.round(t.startPos[1] + n.y);
|
|
9095
9294
|
t.node.position = [r, i];
|
|
9096
9295
|
return;
|
|
9097
9296
|
}
|
|
@@ -9142,9 +9341,9 @@ var rc = class {
|
|
|
9142
9341
|
zoomToFit() {
|
|
9143
9342
|
let e = this.liveSelected();
|
|
9144
9343
|
if (this.rendererDim === "3d") {
|
|
9145
|
-
let t = new
|
|
9344
|
+
let t = new la();
|
|
9146
9345
|
for (let [n] of this.pathOf) {
|
|
9147
|
-
if (e && n !== e && !
|
|
9346
|
+
if (e && n !== e && !yc(n, e)) continue;
|
|
9148
9347
|
let r = n._object3D;
|
|
9149
9348
|
r && (t.expandByObject(r), t.expandByPoint(r.getWorldPosition($)));
|
|
9150
9349
|
}
|
|
@@ -9165,7 +9364,7 @@ var rc = class {
|
|
|
9165
9364
|
0
|
|
9166
9365
|
], this.orbit.dist = 10;
|
|
9167
9366
|
else {
|
|
9168
|
-
let e = t.getCenter(new
|
|
9367
|
+
let e = t.getCenter(new K()), n = t.getSize(new K());
|
|
9169
9368
|
this.orbit.target = [
|
|
9170
9369
|
e.x,
|
|
9171
9370
|
e.y,
|
|
@@ -9178,10 +9377,10 @@ var rc = class {
|
|
|
9178
9377
|
if (!this.renderer2d) return;
|
|
9179
9378
|
let t = this.editCanvas.clientWidth || 960, n = this.editCanvas.clientHeight || 540, r = Infinity, i = Infinity, a = -Infinity, o = -Infinity;
|
|
9180
9379
|
for (let [t] of this.pathOf) {
|
|
9181
|
-
if (e && t !== e && !
|
|
9380
|
+
if (e && t !== e && !yc(t, e)) continue;
|
|
9182
9381
|
let n = t.position;
|
|
9183
9382
|
if (!Array.isArray(n)) continue;
|
|
9184
|
-
let s =
|
|
9383
|
+
let s = bc(t);
|
|
9185
9384
|
r = Math.min(r, s.x), i = Math.min(i, s.y), a = Math.max(a, s.x), o = Math.max(o, s.y);
|
|
9186
9385
|
}
|
|
9187
9386
|
if (!Number.isFinite(r)) return;
|
|
@@ -9195,12 +9394,13 @@ var rc = class {
|
|
|
9195
9394
|
async play(e) {
|
|
9196
9395
|
if (this.playing) return null;
|
|
9197
9396
|
let n = structuredClone(e);
|
|
9198
|
-
|
|
9397
|
+
Tc(n);
|
|
9199
9398
|
let r;
|
|
9200
9399
|
try {
|
|
9201
9400
|
r = f(n, {
|
|
9202
9401
|
stubAllBehaviors: !0,
|
|
9203
|
-
declareConnectionSignals: !0
|
|
9402
|
+
declareConnectionSignals: !0,
|
|
9403
|
+
...this.resolver
|
|
9204
9404
|
});
|
|
9205
9405
|
} catch (e) {
|
|
9206
9406
|
return e instanceof Error ? e.message : String(e);
|
|
@@ -9234,25 +9434,25 @@ var rc = class {
|
|
|
9234
9434
|
this.playEngine?.input.dispose(), this.playEngine?.stop(), this.playEngine?.dispose(), this.playEngine = null, this.playPhysics?.dispose(), this.playPhysics = null, this.editUiHost && (this.editUiHost.style.display = ""), this.playRenderer?.dispose(), this.playRenderer = null, this.playCanvas.hidden = !0, this.cb.onPlayStateChanged(!1), this.lastAppliedKey = null, this.lastGood && this.apply(this.lastGood);
|
|
9235
9435
|
}
|
|
9236
9436
|
};
|
|
9237
|
-
function
|
|
9437
|
+
function uc(e) {
|
|
9238
9438
|
return Math.round(e * 100) / 100;
|
|
9239
9439
|
}
|
|
9240
|
-
var
|
|
9241
|
-
function
|
|
9440
|
+
var dc = new K(0, 1, 0), fc = new K(), pc = new K(), mc = new mi(), $ = new K(), hc = new Mi(), gc = new K(), _c = new K();
|
|
9441
|
+
function vc(e, t, n) {
|
|
9242
9442
|
let r = e._object2D?.parent;
|
|
9243
|
-
return r ? (
|
|
9244
|
-
x:
|
|
9245
|
-
y: -(
|
|
9443
|
+
return r ? (hc.copy(r.matrixWorld).invert(), gc.set(t, -n, 0).applyMatrix4(hc), _c.set(0, 0, 0).applyMatrix4(hc), {
|
|
9444
|
+
x: gc.x - _c.x,
|
|
9445
|
+
y: -(gc.y - _c.y)
|
|
9246
9446
|
}) : {
|
|
9247
9447
|
x: t,
|
|
9248
9448
|
y: n
|
|
9249
9449
|
};
|
|
9250
9450
|
}
|
|
9251
|
-
function
|
|
9451
|
+
function yc(e, t) {
|
|
9252
9452
|
for (let n = e.parent; n; n = n.parent) if (n === t) return !0;
|
|
9253
9453
|
return !1;
|
|
9254
9454
|
}
|
|
9255
|
-
function
|
|
9455
|
+
function bc(e) {
|
|
9256
9456
|
let t = e._object2D;
|
|
9257
9457
|
if (t) return t.getWorldPosition($), {
|
|
9258
9458
|
x: $.x,
|
|
@@ -9265,7 +9465,7 @@ function mc(e) {
|
|
|
9265
9465
|
y: r
|
|
9266
9466
|
};
|
|
9267
9467
|
}
|
|
9268
|
-
function
|
|
9468
|
+
function xc(e) {
|
|
9269
9469
|
if (!e) return null;
|
|
9270
9470
|
if (e.type === "Camera3D") {
|
|
9271
9471
|
let t = e.props?.position ?? [
|
|
@@ -9280,49 +9480,49 @@ function hc(e) {
|
|
|
9280
9480
|
];
|
|
9281
9481
|
}
|
|
9282
9482
|
for (let t of e.children ?? []) {
|
|
9283
|
-
let e =
|
|
9483
|
+
let e = xc(t);
|
|
9284
9484
|
if (e) return e;
|
|
9285
9485
|
}
|
|
9286
9486
|
return null;
|
|
9287
9487
|
}
|
|
9288
|
-
function
|
|
9488
|
+
function Sc(e) {
|
|
9289
9489
|
if (!e) return null;
|
|
9290
9490
|
if (e.type === "Camera2D") {
|
|
9291
9491
|
let t = e.props?.position ?? [0, 0];
|
|
9292
9492
|
return [t[0] ?? 0, t[1] ?? 0];
|
|
9293
9493
|
}
|
|
9294
9494
|
for (let t of e.children ?? []) {
|
|
9295
|
-
let e =
|
|
9495
|
+
let e = Sc(t);
|
|
9296
9496
|
if (e) return e;
|
|
9297
9497
|
}
|
|
9298
9498
|
return null;
|
|
9299
9499
|
}
|
|
9300
|
-
var
|
|
9301
|
-
function
|
|
9302
|
-
if (
|
|
9500
|
+
var Cc = null;
|
|
9501
|
+
function wc() {
|
|
9502
|
+
if (Cc) return Cc;
|
|
9303
9503
|
let e = document.createElement("canvas");
|
|
9304
9504
|
e.width = 16, e.height = 16;
|
|
9305
9505
|
let t = e.getContext("2d");
|
|
9306
9506
|
for (let e = 0; e < 2; e++) for (let n = 0; n < 2; n++) t.fillStyle = (n + e) % 2 == 0 ? "#c252c2" : "#2b2b3b", t.fillRect(n * 8, e * 8, 8, 8);
|
|
9307
|
-
return
|
|
9507
|
+
return Cc = e.toDataURL(), Cc;
|
|
9308
9508
|
}
|
|
9309
|
-
function
|
|
9509
|
+
function Tc(e) {
|
|
9310
9510
|
let t = e.assets;
|
|
9311
|
-
if (t) for (let e of Object.values(t)) typeof e?.url == "string" && !e.url.includes("/") && !e.url.includes(".") && (e.url =
|
|
9511
|
+
if (t) for (let e of Object.values(t)) typeof e?.url == "string" && !e.url.includes("/") && !e.url.includes(".") && (e.url = wc());
|
|
9312
9512
|
}
|
|
9313
9513
|
//#endregion
|
|
9314
9514
|
//#region src/main.ts
|
|
9315
|
-
var
|
|
9515
|
+
var Ec = new Set([
|
|
9316
9516
|
"Terrain3D",
|
|
9317
9517
|
"Water3D",
|
|
9318
9518
|
"River3D"
|
|
9319
9519
|
]);
|
|
9320
9520
|
m(), b(), k(), ee(), A();
|
|
9321
|
-
async function
|
|
9521
|
+
async function Dc(e = {}) {
|
|
9322
9522
|
let t = e.api ?? ze, n = [], r = document.createElement("style");
|
|
9323
|
-
r.dataset.incantoEditor = "true", r.textContent =
|
|
9523
|
+
r.dataset.incantoEditor = "true", r.textContent = Ss, document.head.appendChild(r), n.push(() => r.remove());
|
|
9324
9524
|
let i = document.createElement("div");
|
|
9325
|
-
i.className = "incanto-editor-root", i.innerHTML =
|
|
9525
|
+
i.className = "incanto-editor-root", i.innerHTML = qo, (e.host ?? document.body).appendChild(i), n.push(() => i.remove());
|
|
9326
9526
|
let a = (e) => {
|
|
9327
9527
|
let t = i.querySelector(e);
|
|
9328
9528
|
if (!t) throw Error(`missing ${e}`);
|
|
@@ -9362,7 +9562,7 @@ async function xc(e = {}) {
|
|
|
9362
9562
|
}), Ge(() => {
|
|
9363
9563
|
l(), zt(), u.select(u.selection);
|
|
9364
9564
|
});
|
|
9365
|
-
let u = new
|
|
9565
|
+
let u = new ds({
|
|
9366
9566
|
format: 1,
|
|
9367
9567
|
type: "scene",
|
|
9368
9568
|
name: "",
|
|
@@ -9391,22 +9591,22 @@ async function xc(e = {}) {
|
|
|
9391
9591
|
x: t,
|
|
9392
9592
|
y: n
|
|
9393
9593
|
};
|
|
9394
|
-
},
|
|
9395
|
-
n && (
|
|
9594
|
+
}, re = !1, M = (e, t, n = !0) => {
|
|
9595
|
+
n && (re = !1);
|
|
9396
9596
|
let r = u.selection, i = u.nodeAt(r);
|
|
9397
9597
|
if (!r || i?.type !== "TileMap2D") return;
|
|
9398
|
-
let { cx:
|
|
9399
|
-
!
|
|
9400
|
-
i.props ||= {}, i.props.cells =
|
|
9598
|
+
let a = ne(r), o = Number(i.props?.scale?.[0] ?? 1) || 1, s = Number(i.props?.scale?.[1] ?? 1) || 1, { cx: c, cy: l } = Fn(a, Number(i.props?.tileSize ?? 32), e, t, o, s), d = i.props?.cells ?? [], f = In(d, c, l, j.brush);
|
|
9599
|
+
!f || JSON.stringify(f) === JSON.stringify(d) || (u.mutate(() => {
|
|
9600
|
+
i.props ||= {}, i.props.cells = f;
|
|
9401
9601
|
}, {
|
|
9402
9602
|
path: r,
|
|
9403
9603
|
key: "cells",
|
|
9404
|
-
value:
|
|
9405
|
-
}, { coalesce:
|
|
9406
|
-
},
|
|
9604
|
+
value: f
|
|
9605
|
+
}, { coalesce: re }), re = !0);
|
|
9606
|
+
}, ie = () => {
|
|
9407
9607
|
let e = u.nodeAt(u.selection);
|
|
9408
|
-
j.on && e?.type !== "TileMap2D" && (j.on = !1),
|
|
9409
|
-
},
|
|
9608
|
+
j.on && e?.type !== "TileMap2D" && (j.on = !1), N.setPaintHandler(j.on ? M : null);
|
|
9609
|
+
}, N = new lc(a("#viewport"), a("#overlay"), a("#play-canvas"), {
|
|
9410
9610
|
onPick: (e, t) => u.select(e ?? null, t),
|
|
9411
9611
|
onNodeMoved: (e, t) => de(e, "position", t, [0, 0]),
|
|
9412
9612
|
onNodeScaled: (e, t) => de(e, "scale", t, [1, 1]),
|
|
@@ -9417,7 +9617,7 @@ async function xc(e = {}) {
|
|
|
9417
9617
|
]),
|
|
9418
9618
|
onNodeScaled3D: (e, t) => {
|
|
9419
9619
|
let n = u.nodeAt(e);
|
|
9420
|
-
if (n &&
|
|
9620
|
+
if (n && Ec.has(String(n.type))) {
|
|
9421
9621
|
O(`${n.type} '${n.name}' cannot be scaled — scale would move only the mesh. Resize it with its "size" prop in the inspector.`);
|
|
9422
9622
|
return;
|
|
9423
9623
|
}
|
|
@@ -9449,9 +9649,9 @@ async function xc(e = {}) {
|
|
|
9449
9649
|
document.body.classList.toggle("playing", e), n.push(() => document.body.classList.remove("playing")), h.classList.toggle("stop", e), h.innerHTML = e ? "<svg width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><rect x=\"6\" y=\"6\" width=\"12\" height=\"12\"/></svg> stop" : "<svg width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M8 5v14l11-7z\"/></svg> play", v.hidden = !e, e && (v.textContent = "▶ simulating — physics + input live; game scripts run only in your real game. Esc or stop to return.");
|
|
9450
9650
|
},
|
|
9451
9651
|
onError: O
|
|
9452
|
-
}),
|
|
9453
|
-
if (e ===
|
|
9454
|
-
|
|
9652
|
+
}), ae = g().sort(), P = "", oe = (e) => {
|
|
9653
|
+
if (e === P) return;
|
|
9654
|
+
P = e, y.textContent = "";
|
|
9455
9655
|
let t = e === "3d" ? [
|
|
9456
9656
|
"3D",
|
|
9457
9657
|
"3D Physics",
|
|
@@ -9473,7 +9673,7 @@ async function xc(e = {}) {
|
|
|
9473
9673
|
if (!t) continue;
|
|
9474
9674
|
let n = document.createElement("optgroup");
|
|
9475
9675
|
n.label = e;
|
|
9476
|
-
for (let e of
|
|
9676
|
+
for (let e of ae.filter(t)) {
|
|
9477
9677
|
let t = document.createElement("option");
|
|
9478
9678
|
t.value = e, t.textContent = e, n.appendChild(t);
|
|
9479
9679
|
}
|
|
@@ -9484,7 +9684,7 @@ async function xc(e = {}) {
|
|
|
9484
9684
|
oe("2d");
|
|
9485
9685
|
let se = () => {
|
|
9486
9686
|
let e = u.selection ?? [];
|
|
9487
|
-
if (
|
|
9687
|
+
if (N.validate(u.working) !== null) {
|
|
9488
9688
|
for (let e of y.querySelectorAll("option")) e.disabled = !1;
|
|
9489
9689
|
return;
|
|
9490
9690
|
}
|
|
@@ -9502,47 +9702,49 @@ async function xc(e = {}) {
|
|
|
9502
9702
|
type: t.value
|
|
9503
9703
|
});
|
|
9504
9704
|
}
|
|
9505
|
-
t.disabled =
|
|
9705
|
+
t.disabled = N.validate(n) !== null;
|
|
9506
9706
|
}
|
|
9507
9707
|
};
|
|
9508
9708
|
y.addEventListener("mousedown", se), y.addEventListener("focus", se);
|
|
9509
|
-
let ce = t.library ? (e) =>
|
|
9709
|
+
let ce = t.library ? (e) => Ao(t, {
|
|
9510
9710
|
kind: e.kind,
|
|
9511
9711
|
...e.target ? { target: e.target } : {},
|
|
9512
9712
|
...e.shelf ? { shelf: e.shelf } : {},
|
|
9513
9713
|
...e.assetType ? { assetType: e.assetType } : {},
|
|
9514
9714
|
...e.onProps ? { onProps: e.onProps } : {},
|
|
9515
|
-
...e.asAsset ? { onAsset: (e, t, n) =>
|
|
9715
|
+
...e.asAsset ? { onAsset: (e, t, n) => jc(u, n, t) } : {}
|
|
9516
9716
|
}) : void 0, le = !1, F = () => {
|
|
9517
9717
|
if (!E) return;
|
|
9518
|
-
|
|
9519
|
-
modelRefs: () =>
|
|
9520
|
-
animationsForSelection: () => u.selection ?
|
|
9521
|
-
bonesForSelection: (e) => u.selection ?
|
|
9522
|
-
assetRefs: (e) =>
|
|
9523
|
-
addAsset: (e, t) =>
|
|
9718
|
+
Ls(d, u), rt(a("#asset-tree"), u), f.textContent = "", it(f, u, Ce, ce) || Bn(f, u, {
|
|
9719
|
+
modelRefs: () => kc(u, "model"),
|
|
9720
|
+
animationsForSelection: () => u.selection ? N.modelAnimationsAt(u.selection) : [],
|
|
9721
|
+
bonesForSelection: (e) => u.selection ? N.boneNamesAt(u.selection, e) : [],
|
|
9722
|
+
assetRefs: (e) => Ac(u, e),
|
|
9723
|
+
addAsset: (e, t) => jc(u, e, t),
|
|
9524
9724
|
...ce ? { openLibrary: ce } : {},
|
|
9525
9725
|
confirm: Ce,
|
|
9526
9726
|
paint: {
|
|
9527
9727
|
active: () => j.on,
|
|
9528
9728
|
brush: () => j.brush,
|
|
9529
9729
|
toggle: () => {
|
|
9530
|
-
j.on = !j.on,
|
|
9730
|
+
j.on = !j.on, ie(), F();
|
|
9531
9731
|
},
|
|
9532
9732
|
setBrush: (e) => {
|
|
9533
9733
|
j.brush = e, F();
|
|
9534
9734
|
}
|
|
9535
9735
|
}
|
|
9536
|
-
}), oe(u.working.dimension ?? "2d"), a("#hints").hidden = (u.working.dimension ?? "2d") === "3d", a("#hints-3d").hidden = (u.working.dimension ?? "2d") !== "3d",
|
|
9736
|
+
}), oe(u.working.dimension ?? "2d"), a("#hints").hidden = (u.working.dimension ?? "2d") === "3d", a("#hints-3d").hidden = (u.working.dimension ?? "2d") !== "3d", N.setSelection(u.selection, u.extra), ie();
|
|
9537
9737
|
let e = u.pendingLivePatch;
|
|
9538
|
-
if (u.pendingLivePatch = null, !
|
|
9539
|
-
|
|
9540
|
-
|
|
9738
|
+
if (u.pendingLivePatch = null, !N.playing) if (e && N.patchProp(u.working, e.path, e.key, e.value)) {
|
|
9739
|
+
let e = N.validate(u.working);
|
|
9740
|
+
_.hidden = e === null, e !== null && O(e);
|
|
9741
|
+
} else {
|
|
9742
|
+
let e = N.apply(u.working);
|
|
9541
9743
|
_.hidden = e === null, e !== null && O(e);
|
|
9542
9744
|
}
|
|
9543
9745
|
p.disabled = !u.dirty || !u.working.root, p.title = u.working.root ? "" : "Add a root node before saving", m.disabled = !u.canUndo, u.dirty !== le && (le = u.dirty, kt.change(u.dirty));
|
|
9544
9746
|
};
|
|
9545
|
-
u.onChange(F), u.validator = (e) =>
|
|
9747
|
+
u.onChange(F), u.validator = (e) => N.validate(e), u.onError = O;
|
|
9546
9748
|
let ue = (e, t, n, r) => {
|
|
9547
9749
|
let i = u.nodeAt(e);
|
|
9548
9750
|
i && u.mutate(() => {
|
|
@@ -9562,12 +9764,12 @@ async function xc(e = {}) {
|
|
|
9562
9764
|
value: n
|
|
9563
9765
|
});
|
|
9564
9766
|
}, fe = async (e, n, r) => {
|
|
9565
|
-
|
|
9767
|
+
N.playing && N.stop();
|
|
9566
9768
|
let i = await t.loadScene(e);
|
|
9567
9769
|
T = e, C = n, w = r, E = !0;
|
|
9568
9770
|
let s = e ?? n;
|
|
9569
|
-
a("#file-chip").hidden = !s, a("#file-path").textContent = s ?? "", a("#file-chip").title = `input: ${n}\noutput: ${r}`, b.hidden = !0, k(),
|
|
9570
|
-
}, pe =
|
|
9771
|
+
a("#file-chip").hidden = !s, a("#file-path").textContent = s ?? "", a("#file-chip").title = `input: ${n}\noutput: ${r}`, N.setSubScenes(await Cs(i, t)), b.hidden = !0, k(), Bs(), u.reset(i), o.mode === "project" && n && kt.open(n, r);
|
|
9772
|
+
}, pe = Ko({
|
|
9571
9773
|
list: x,
|
|
9572
9774
|
search: a("#picker-search"),
|
|
9573
9775
|
count: a("#picker-count"),
|
|
@@ -9632,7 +9834,7 @@ async function xc(e = {}) {
|
|
|
9632
9834
|
if (e.length === 0) {
|
|
9633
9835
|
let e = u.working.root;
|
|
9634
9836
|
if (!e) return;
|
|
9635
|
-
let t =
|
|
9837
|
+
let t = Oc(e);
|
|
9636
9838
|
Ce(`This deletes the ROOT '${String(e.name ?? "")}'${t > 0 ? ` AND its ${t} descendant node${t === 1 ? "" : "s"}` : ""} — the scene goes empty, and the next node you add becomes the new root.`, "delete root", () => u.deleteRoot());
|
|
9637
9839
|
return;
|
|
9638
9840
|
}
|
|
@@ -9640,7 +9842,7 @@ async function xc(e = {}) {
|
|
|
9640
9842
|
if (n.length === 0) {
|
|
9641
9843
|
let n = e.reduce((e, t) => {
|
|
9642
9844
|
let n = u.nodeAt(t);
|
|
9643
|
-
return e + (n ?
|
|
9845
|
+
return e + (n ? Oc(n) : 0);
|
|
9644
9846
|
}, 0);
|
|
9645
9847
|
if (n > 0) {
|
|
9646
9848
|
Ce(`This deletes ${e.length > 1 ? `${e.length} nodes` : `'${String(u.nodeAt(e[0] ?? [])?.name ?? "")}'`} AND ${n} descendant node${n === 1 ? "" : "s"}.`, `delete ${e.length + n} nodes`, () => {
|
|
@@ -9689,7 +9891,7 @@ async function xc(e = {}) {
|
|
|
9689
9891
|
return;
|
|
9690
9892
|
}
|
|
9691
9893
|
be && u.removeNodesUnlinking(be.selections) && u.select(be.parentOfFirst), Te();
|
|
9692
|
-
}),
|
|
9894
|
+
}), js(ye), Ms((e) => {
|
|
9693
9895
|
te(`${I({
|
|
9694
9896
|
en: `Rename: repaired ${e.length} reference${e.length === 1 ? "" : "s"}`,
|
|
9695
9897
|
ko: `이름 변경: 참조 ${e.length}건 수정`
|
|
@@ -9709,13 +9911,13 @@ async function xc(e = {}) {
|
|
|
9709
9911
|
ye(u.allSelections().filter((e) => e.length > 0));
|
|
9710
9912
|
});
|
|
9711
9913
|
let Ee = () => {
|
|
9712
|
-
_.hidden = !0,
|
|
9914
|
+
_.hidden = !0, N.play(u.working).then((e) => {
|
|
9713
9915
|
e && O(e);
|
|
9714
9916
|
});
|
|
9715
9917
|
};
|
|
9716
9918
|
if (h.addEventListener("click", () => {
|
|
9717
|
-
if (
|
|
9718
|
-
|
|
9919
|
+
if (N.playing) {
|
|
9920
|
+
N.stop(), F();
|
|
9719
9921
|
return;
|
|
9720
9922
|
}
|
|
9721
9923
|
if (!e.onPlay) {
|
|
@@ -9763,21 +9965,21 @@ async function xc(e = {}) {
|
|
|
9763
9965
|
"move",
|
|
9764
9966
|
"rotate",
|
|
9765
9967
|
"scale"
|
|
9766
|
-
]) a(`#tool-${e}`).addEventListener("click", () =>
|
|
9767
|
-
|
|
9968
|
+
]) a(`#tool-${e}`).addEventListener("click", () => N.setMode(e));
|
|
9969
|
+
N.setMode("move");
|
|
9768
9970
|
let De = a("#tool-colliders"), Oe = "incanto-editor-show-colliders", ke = (e) => {
|
|
9769
|
-
|
|
9971
|
+
N.showColliders = e, De.classList.toggle("active", e), localStorage.setItem(Oe, e ? "" : "0");
|
|
9770
9972
|
};
|
|
9771
|
-
ke(localStorage.getItem(Oe) !== "0"), De.addEventListener("click", () => ke(!
|
|
9973
|
+
ke(localStorage.getItem(Oe) !== "0"), De.addEventListener("click", () => ke(!N.showColliders));
|
|
9772
9974
|
let Ae = a("#hints-dock"), je = "incanto-editor-hints-open";
|
|
9773
9975
|
Ae.classList.toggle("open", localStorage.getItem(je) === "1"), a("#hints-toggle").addEventListener("click", () => {
|
|
9774
9976
|
let e = Ae.classList.toggle("open");
|
|
9775
9977
|
localStorage.setItem(je, e ? "1" : "");
|
|
9776
|
-
}), a("#fit-btn").addEventListener("click", () =>
|
|
9978
|
+
}), a("#fit-btn").addEventListener("click", () => N.zoomToFit()), As(() => N.zoomToFit()), a("#gameview-btn").addEventListener("click", () => N.gameView()), t.saveScene || (p.hidden = !0), p.addEventListener("click", () => {
|
|
9777
9979
|
we();
|
|
9778
9980
|
}), m.addEventListener("click", () => u.undo());
|
|
9779
9981
|
let Me = (e) => {
|
|
9780
|
-
if (e.key === "Escape" &&
|
|
9982
|
+
if (e.key === "Escape" && N.cancelActiveDrag(), e.key === "Escape" && !_.hidden && a("#docs").hidden && ve.hidden && _e.hidden && b.hidden && !N.playing) {
|
|
9781
9983
|
k();
|
|
9782
9984
|
return;
|
|
9783
9985
|
}
|
|
@@ -9797,39 +9999,39 @@ async function xc(e = {}) {
|
|
|
9797
9999
|
ge();
|
|
9798
10000
|
return;
|
|
9799
10001
|
}
|
|
9800
|
-
if (e.key === "Escape" &&
|
|
9801
|
-
|
|
10002
|
+
if (e.key === "Escape" && N.playing) {
|
|
10003
|
+
N.stop(), F();
|
|
9802
10004
|
return;
|
|
9803
10005
|
}
|
|
9804
|
-
if (
|
|
10006
|
+
if (N.playing) return;
|
|
9805
10007
|
let t = e.target.matches("input, textarea, select");
|
|
9806
|
-
(e.metaKey || e.ctrlKey) && e.key === "z" ? (e.preventDefault(), u.undo()) : (e.metaKey || e.ctrlKey) && e.key === "s" ? (e.preventDefault(), p.disabled || p.click()) : !t && e.code === "KeyF" ?
|
|
10008
|
+
(e.metaKey || e.ctrlKey) && e.key === "z" ? (e.preventDefault(), u.undo()) : (e.metaKey || e.ctrlKey) && e.key === "s" ? (e.preventDefault(), p.disabled || p.click()) : !t && e.code === "KeyF" ? N.zoomToFit() : !t && (e.code === "Digit0" || e.code === "Numpad0") ? N.gameView() : !t && e.code === "KeyW" ? N.setMode("move") : !t && e.code === "KeyE" ? N.setMode("rotate") : !t && e.code === "KeyR" && N.setMode("scale");
|
|
9807
10009
|
};
|
|
9808
|
-
return window.addEventListener("keydown", Me), n.push(() => window.removeEventListener("keydown", Me)), F(), e.scene && u.resume(e.scene), e.camera &&
|
|
10010
|
+
return window.addEventListener("keydown", Me), n.push(() => window.removeEventListener("keydown", Me)), F(), e.scene && u.resume(e.scene), e.camera && N.setEditCamera(e.camera.position, e.camera.target), kt.ready(C, w, o.version), {
|
|
9809
10011
|
working: () => u.working,
|
|
9810
|
-
camera: () =>
|
|
10012
|
+
camera: () => N.editCamera(),
|
|
9811
10013
|
showError: O,
|
|
9812
10014
|
dispose() {
|
|
9813
|
-
|
|
10015
|
+
N.dispose();
|
|
9814
10016
|
for (let e of document.querySelectorAll(".context-menu, .balloon")) e.remove();
|
|
9815
10017
|
for (let e of n.splice(0).reverse()) e();
|
|
9816
10018
|
}
|
|
9817
10019
|
};
|
|
9818
10020
|
}
|
|
9819
|
-
function
|
|
10021
|
+
function Oc(e) {
|
|
9820
10022
|
let t = 0;
|
|
9821
|
-
for (let n of e.children ?? []) t += 1 +
|
|
10023
|
+
for (let n of e.children ?? []) t += 1 + Oc(n);
|
|
9822
10024
|
return t;
|
|
9823
10025
|
}
|
|
9824
|
-
function
|
|
10026
|
+
function kc(e, t) {
|
|
9825
10027
|
let n = e.working.assets;
|
|
9826
10028
|
return n ? Object.entries(n).filter(([, e]) => e?.type === t).map(([e]) => `$${e}`) : [];
|
|
9827
10029
|
}
|
|
9828
|
-
function
|
|
10030
|
+
function Ac(e, t) {
|
|
9829
10031
|
let n = e.working.assets;
|
|
9830
10032
|
return n ? Object.entries(n).filter(([, e]) => !t || e?.type !== void 0 && t.includes(e.type)).map(([e]) => `$${e}`) : [];
|
|
9831
10033
|
}
|
|
9832
|
-
function
|
|
10034
|
+
function jc(e, t, n) {
|
|
9833
10035
|
let r = e.working.assets ?? {};
|
|
9834
10036
|
for (let [e, t] of Object.entries(r)) if (t?.url === n.url) return `$${e}`;
|
|
9835
10037
|
let i = t;
|
|
@@ -9839,4 +10041,4 @@ function Tc(e, t, n) {
|
|
|
9839
10041
|
}), `$${i}`;
|
|
9840
10042
|
}
|
|
9841
10043
|
//#endregion
|
|
9842
|
-
export {
|
|
10044
|
+
export { M as formatSceneJson, ze as httpEditorApi, Dc as mountEditor };
|