@fps-games/editor-deployment 0.2.3-beta.16 → 0.2.3-beta.17

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.
@@ -1,6 +1,6 @@
1
1
  FPS Game Editor deployment npm package
2
- Version: 0.2.3-beta.16
3
- Commit: 17e03e1197f5c45694b60088447dfd660421761f
2
+ Version: 0.2.3-beta.17
3
+ Commit: f4357398f69d40f89e0395c5dbcec85d5db3c8c1
4
4
 
5
5
  This package contains compiled third-party dependencies declared by the source repository.
6
6
  The authoritative dependency names, versions, notices, and license metadata are recorded in
package/manifest.json CHANGED
@@ -2,17 +2,17 @@
2
2
  "schemaVersion": 3,
3
3
  "artifactKind": "fps-editor-deployment-package",
4
4
  "packageName": "@fps-games/editor-deployment",
5
- "version": "0.2.3-beta.16",
6
- "commitSha": "17e03e1197f5c45694b60088447dfd660421761f",
5
+ "version": "0.2.3-beta.17",
6
+ "commitSha": "f4357398f69d40f89e0395c5dbcec85d5db3c8c1",
7
7
  "node": {
8
8
  "range": ">=24 <27",
9
9
  "bundled": false
10
10
  },
11
11
  "build": {
12
12
  "packageName": "@fps-games/editor",
13
- "version": "0.2.3-beta.16",
14
- "buildId": "0.2.3-beta.16-0e1f90ca07b8",
15
- "distHash": "0e1f90ca07b8347387d4f230f60607a73af89724718106e229409aba66639aa8"
13
+ "version": "0.2.3-beta.17",
14
+ "buildId": "0.2.3-beta.17-2a9bfc6588c3",
15
+ "distHash": "2a9bfc6588c35936a72b007e0a7b95e586249460ed0405ff1752d4a7797a302c"
16
16
  },
17
17
  "binaries": {
18
18
  "prepare": "bin/fps-editor-prepare.mjs",
@@ -45,7 +45,7 @@
45
45
  {
46
46
  "path": "licenses/THIRD_PARTY_NOTICES.txt",
47
47
  "size": 361,
48
- "sha256": "df5cbed256db2ffda49d897ffe7e48d6058272609472f0e484773509a38aa2f6"
48
+ "sha256": "0f95f444c589c97e67091d24382f1ba18a4ac8ab416061b573c777f646d64539"
49
49
  },
50
50
  {
51
51
  "path": "public/assets/abstractAudioBus-B_nOEXGJ.js",
@@ -1628,19 +1628,19 @@
1628
1628
  "sha256": "90aa7a97454a456b51041d0ffd95e58764299fd83075d786b81634c31514f6c1"
1629
1629
  },
1630
1630
  {
1631
- "path": "public/assets/index-Cv7z0zVA.js",
1632
- "size": 31877,
1633
- "sha256": "7b847b3710dc1d1050de6530fbe44b1027e1b6ca5d7f14f166379dc933e6531d"
1631
+ "path": "public/assets/index-ChyK2lhc.js",
1632
+ "size": 38012,
1633
+ "sha256": "da640fecf6e6400527e3d9744ecb79bf4b86b822ad5187b223f34d46b7afa8b3"
1634
1634
  },
1635
1635
  {
1636
- "path": "public/assets/index-Cv7z0zVA.js.br",
1637
- "size": 9244,
1638
- "sha256": "04ea3cf8c77e1649cf792695515d4270fcf2b7f3921978b2b7bd2190708bd3e7"
1636
+ "path": "public/assets/index-ChyK2lhc.js.br",
1637
+ "size": 11083,
1638
+ "sha256": "d6fa68136f1df007763b8c38dd2d7a07826236bd30434f609ac5ace26c208315"
1639
1639
  },
1640
1640
  {
1641
- "path": "public/assets/index-Cv7z0zVA.js.gz",
1642
- "size": 10564,
1643
- "sha256": "2e9c29c013e4046523d5f7d31eb614e2beb4b59972929b46d64b89d7b825261f"
1641
+ "path": "public/assets/index-ChyK2lhc.js.gz",
1642
+ "size": 12709,
1643
+ "sha256": "c0104480168f6a7cea4dbc8f309d7e05e2f4b7a9ed03f53abaa0461f25c3d4cb"
1644
1644
  },
1645
1645
  {
1646
1646
  "path": "public/assets/index-Xd6hsly2.js",
@@ -2118,34 +2118,34 @@
2118
2118
  "sha256": "c98a82244f857667386c5836c68291e4d1264538921d2dfbf71128a4d9bc9e53"
2119
2119
  },
2120
2120
  {
2121
- "path": "public/assets/playable-sdk-DO95mXOf.js",
2122
- "size": 144789,
2123
- "sha256": "0a90f9e3e19042063856e61a09e098fd8bd7358fa47ba3f859ef601906f3cc6e"
2121
+ "path": "public/assets/playable-sdk-D42v8kWc.js",
2122
+ "size": 144909,
2123
+ "sha256": "f3fd1447501671cd0d1d8614ff8d177618f18a32eede98dbf58bda08baed5f6f"
2124
2124
  },
2125
2125
  {
2126
- "path": "public/assets/playable-sdk-DO95mXOf.js.br",
2127
- "size": 34644,
2128
- "sha256": "752eb9bde8a6b30a6852432cffc630b6eddfaae5e549c878bdf6d9630c60b655"
2126
+ "path": "public/assets/playable-sdk-D42v8kWc.js.br",
2127
+ "size": 34645,
2128
+ "sha256": "e9e4f285283dc5a8aa609fa95e15a859767ac21fb366c8dda853bae3c009b0b3"
2129
2129
  },
2130
2130
  {
2131
- "path": "public/assets/playable-sdk-DO95mXOf.js.gz",
2132
- "size": 41985,
2133
- "sha256": "f02d2627125a0a7dbfffc7ab0ac08704ba41a73d2f3da5cefd4caf081b2baaf1"
2131
+ "path": "public/assets/playable-sdk-D42v8kWc.js.gz",
2132
+ "size": 42007,
2133
+ "sha256": "209b86802445ec76cc08bc48f9d2f0e4470718830b3330c4f1b689b89f93b5d3"
2134
2134
  },
2135
2135
  {
2136
- "path": "public/assets/playable-standard-project-Do0uyGjy.js",
2137
- "size": 3597913,
2138
- "sha256": "afba3b4584375c35c06b4abec09023bb819a2e187e11b3110dfff8bfa986eefd"
2136
+ "path": "public/assets/playable-standard-project-DgsY-0An.js",
2137
+ "size": 3603305,
2138
+ "sha256": "dc4166f8c5ff6240021ee476273d39d6d8d4fd2d2b5000e5a8f52558df99bb63"
2139
2139
  },
2140
2140
  {
2141
- "path": "public/assets/playable-standard-project-Do0uyGjy.js.br",
2142
- "size": 746628,
2143
- "sha256": "bdc5ec2e27ae8b892996e8416137b580f567ebc4a466cdabdfedd025738f14b5"
2141
+ "path": "public/assets/playable-standard-project-DgsY-0An.js.br",
2142
+ "size": 748001,
2143
+ "sha256": "a14b015554a23078c35545cb235b1f1872fa6ac2cd25eeb53e44a3f2608b2e46"
2144
2144
  },
2145
2145
  {
2146
- "path": "public/assets/playable-standard-project-Do0uyGjy.js.gz",
2147
- "size": 963457,
2148
- "sha256": "b72f71a0d6b28361a78e109a5d57b2acc23a4f8f2b30d3c9cec323d89b7912e9"
2146
+ "path": "public/assets/playable-standard-project-DgsY-0An.js.gz",
2147
+ "size": 964876,
2148
+ "sha256": "3924c34b752b37797770f888c25c81b4902168131fb31b21473c1634c630134f"
2149
2149
  },
2150
2150
  {
2151
2151
  "path": "public/assets/rgbdDecode.fragment-Cf7NitgJ.js",
@@ -2645,33 +2645,33 @@
2645
2645
  {
2646
2646
  "path": "public/index.html",
2647
2647
  "size": 1027,
2648
- "sha256": "e79be89c3d499dfa8dd3b1bf646d395f40407752747132c5f88bcf8d936ca1d2"
2648
+ "sha256": "fffc61f844f2d600b85832739b95131ce3aeb455ec51b5c18296c5da00cd8afe"
2649
2649
  },
2650
2650
  {
2651
2651
  "path": "public/index.html.br",
2652
- "size": 394,
2653
- "sha256": "ab3ba9654d0f49ebd8b5d71472a877d700070e09e773b526005ac68d714813be"
2652
+ "size": 395,
2653
+ "sha256": "2125f09c4db96749152e3c2eba8ddf70be354fd6f0d06afb75b16a8c2d053760"
2654
2654
  },
2655
2655
  {
2656
2656
  "path": "public/index.html.gz",
2657
- "size": 558,
2658
- "sha256": "c11411cb1e9808a8c8095f297503709e6c1cc239c35f4b463130893681171be4"
2657
+ "size": 555,
2658
+ "sha256": "61cd6dcfe9d1e474770d8d789e74fdd192058c0789d5343052c73fbb225fc46d"
2659
2659
  },
2660
2660
  {
2661
2661
  "path": "runtime/editor-control-plane.mjs",
2662
- "size": 19897,
2663
- "sha256": "fca765de6ac4b71ae0d8409f9e074e70941db4916dca56597d5df9a1c1e8ade5"
2662
+ "size": 27378,
2663
+ "sha256": "18d15113b56aae6c9a36b2f36bc236a9b28ddb29dde1f704445b2347c05c8052"
2664
2664
  },
2665
2665
  {
2666
2666
  "path": "worker/editor-service-worker.mjs",
2667
- "size": 621334,
2668
- "sha256": "b36a6b8dd71c1545c6918f481a817025ad7aa92726fb3e878e4d587aa3825e63"
2667
+ "size": 622765,
2668
+ "sha256": "d8065330b1b84874da70000fb9320696b57c57a416f5eea724a6a7e7fb080b77"
2669
2669
  }
2670
2670
  ],
2671
2671
  "sizes": {
2672
- "packagePayloadBytes": 16799340,
2673
- "browserRawBytes": 11093102,
2674
- "browserGzipBytes": 2702652,
2675
- "browserBrotliBytes": 2108188
2672
+ "packagePayloadBytes": 16826696,
2673
+ "browserRawBytes": 11104749,
2674
+ "browserGzipBytes": 2706235,
2675
+ "browserBrotliBytes": 2111402
2676
2676
  }
2677
2677
  }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@fps-games/editor-deployment",
3
- "version": "0.2.3-beta.16",
3
+ "version": "0.2.3-beta.17",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@fps-games/editor-deployment",
9
- "version": "0.2.3-beta.16",
9
+ "version": "0.2.3-beta.17",
10
10
  "bin": {
11
11
  "fps-editor-prepare": "bin/fps-editor-prepare.mjs",
12
12
  "fps-editor-server": "bin/fps-editor-server.mjs",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fps-games/editor-deployment",
3
- "version": "0.2.3-beta.16",
3
+ "version": "0.2.3-beta.17",
4
4
  "type": "module",
5
5
  "description": "Prebuilt FPS Game Editor control plane, browser client, and project preparation tools.",
6
6
  "repository": {
@@ -30,12 +30,12 @@
30
30
  "node": ">=24 <27"
31
31
  },
32
32
  "devDependencies": {
33
- "@fps-games/editor": "0.2.3-beta.16",
34
- "@fps-games/editor-core": "0.2.3-beta.16",
35
- "@fps-games/editor-playable-sdk": "0.2.3-beta.16",
36
- "@fps-games/editor-protocol": "0.2.3-beta.16",
33
+ "@fps-games/editor": "0.2.3-beta.17",
34
+ "@fps-games/editor-core": "0.2.3-beta.17",
35
+ "@fps-games/editor-playable-sdk": "0.2.3-beta.17",
36
+ "@fps-games/editor-protocol": "0.2.3-beta.17",
37
37
  "@fps-games/engine": "0.0.1-beta.21",
38
- "@fps-games/plugin-hierarchy": "0.2.3-beta.16",
38
+ "@fps-games/plugin-hierarchy": "0.2.3-beta.17",
39
39
  "@fps-games/plugin-sdk": "0.1.0-beta.2"
40
40
  },
41
41
  "publishConfig": {
@@ -0,0 +1 @@
1
+ import{fE as pe,fD as fe,a4 as me,eu as he,mv as ge,iX as be,fv as ye,ca as we,jO as Se,hX as Ie}from"./playable-standard-project-DgsY-0An.js";import{registerFpsEditorContribution as Me}from"@fps-games/editor-core/plugin-host";import"./hemisphericLight-C4swwL68.js";(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))i(o);new MutationObserver(o=>{for(const r of o)if(r.type==="childList")for(const s of r.addedNodes)s.tagName==="LINK"&&s.rel==="modulepreload"&&i(s)}).observe(document,{childList:!0,subtree:!0});function n(o){const r={};return o.integrity&&(r.integrity=o.integrity),o.referrerPolicy&&(r.referrerPolicy=o.referrerPolicy),o.crossOrigin==="use-credentials"?r.credentials="include":o.crossOrigin==="anonymous"?r.credentials="omit":r.credentials="same-origin",r}function i(o){if(o.ep)return;o.ep=!0;const r=n(o);fetch(o.href,r)}})();const Ee="0.2.3-beta.17",ee="fps.plugin.hierarchy";function _e(){return pe({id:ee,version:Ee,apiVersion:1,requires:{},provides:{features:["fps.editor.hierarchy"]},entries:{editor:"./editor"},environmentContracts:{editor:{requires:{services:["fps.editor.contributions"]},provides:{}}},deploymentConstraints:{allowedTargets:["editor"]}})}const je=fe({pluginId:ee,environment:"editor",register(e){Me(e,{id:me,kind:"hierarchy",value:he()})}}),Ae=1e3,xe=5e3,Pe="Project I/O health request failed.";function ve(e){const t=Fe(e.endpointBase),n=B(e.pollIntervalMs,Ae),i=B(e.requestTimeoutMs,xe);let o=$e(e.initial),r=!1,s=null,a=null;const d=new Set,f=c=>{if(!Ce(o,c)){o=c;for(const w of d)w(c)}},u=()=>{r||(s=e.ownerWindow.setTimeout(p,n))},p=async()=>{if(s=null,r)return;const c=new AbortController;a=c;const w=e.ownerWindow.setTimeout(()=>c.abort(),i);try{const S=await e.fetchJson(`${t}/health`,{cache:"no-store",signal:c.signal});f(Oe(S))}catch{r||f(Object.freeze({ready:!1,generation:o.generation,reason:Pe}))}finally{e.ownerWindow.clearTimeout(w),a===c&&(a=null),u()}};return u(),Object.freeze({availability:Object.freeze({getAvailability:()=>o,subscribeAvailability(c){return r?()=>{}:(d.add(c),()=>d.delete(c))}}),stop(){r||(r=!0,s!==null&&e.ownerWindow.clearTimeout(s),s=null,a?.abort(),a=null,d.clear())}})}function Oe(e){if(!e||typeof e!="object"||Array.isArray(e))throw new Error("Project I/O health response must be an object.");const t=e;if(t.schemaVersion!==1||t.kind!=="project-io"||typeof t.ready!="boolean"||!Number.isSafeInteger(t.generation)||t.status!=="ready"&&t.status!=="unavailable")throw new Error("Project I/O health response is invalid.");const n=String(t.generation);return t.ready&&t.status==="ready"?Object.freeze({ready:!0,generation:n}):Object.freeze({ready:!1,generation:n,reason:typeof t.reason=="string"&&t.reason.trim()?t.reason:"Project I/O is unavailable."})}function $e(e){const t=e.generation?.trim();if(!t)throw new Error("Project I/O initial generation is required.");return e.ready?Object.freeze({ready:!0,generation:t}):Object.freeze({ready:!1,generation:t,reason:e.reason?.trim()||"Project I/O is unavailable."})}function Ce(e,t){return e.ready===t.ready&&e.generation===t.generation&&(e.ready||t.ready||e.reason===t.reason)}function Fe(e){const t=typeof e=="string"?e.trim().replace(/\/$/,""):"";if(!t)throw new Error("Project I/O endpoint is required.");return t}function B(e,t){return Number.isSafeInteger(e)&&e>0?e:t}function Re(e,t,n,i){const o=i.__FPS_EDITOR_RUNTIME_TUNING__;if(!o||o.projectId!==e)return()=>{};const r=i.crypto?.randomUUID?.()??`browser_${Date.now().toString(36)}_${Math.random().toString(36).slice(2)}`;let s=!1;const a=new AbortController;return(async()=>{for(;!s;)try{const f=await i.fetch(`${o.endpointBase}/consumer/poll`,{method:"POST",headers:{"x-fps-editor-runtime-tuning-token":o.token,"x-fps-editor-runtime-tuning-consumer":r},cache:"no-store",signal:a.signal}),u=await f.json().catch(()=>null);if(!f.ok||!u||typeof u.requestId!="string"){s||await V(i,500);continue}const p=await Te(e,t,u.intent,n);await i.fetch(`${o.endpointBase}/consumer/result`,{method:"POST",headers:{"content-type":"application/json","x-fps-editor-runtime-tuning-token":o.token,"x-fps-editor-runtime-tuning-consumer":r},body:JSON.stringify({requestId:u.requestId,result:p}),cache:"no-store",signal:a.signal})}catch{s||await V(i,750)}})(),()=>{s=!0,a.abort()}}async function Te(e,t,n,i){const o=De(n,e);if(!o)return{ok:!1,code:"runtime_tuning_invalid_intent",message:"调参请求不符合 Camera/Light 固定字段。"};const r=i?.()??null;if(i&&!Ne(o,r))return{ok:!1,code:"runtime_tuning_stale_binding",message:"Runtime 调参绑定与当前编辑器文档不一致。请刷新 Runtime 后重试。",phase:"apply",draftApplied:!1};let s;try{s=await t({capabilityId:"inspector.properties.patchMany",input:{targets:o.targets.map(d=>({objectId:d.targetId,changes:Object.entries(ke(d,r)).map(([f,u])=>({path:f,value:u}))}))}})}catch{return{ok:!1,code:"runtime_tuning_apply_failed",message:"编辑器应用调参时发生异常。",phase:"apply",draftApplied:!1}}if(s.outcome!=="applied"&&s.outcome!=="no-op")return{ok:!1,code:s.diagnostics[0]?.code??"runtime_tuning_rejected",message:q(s.diagnostics[0]?.message,"编辑器拒绝了该调参请求。"),phase:"apply",draftApplied:!1,...typeof s.draft?.dirty=="boolean"?{dirty:s.draft.dirty}:{}};let a;try{a=await t({capabilityId:"document.save",input:{}})}catch{return{ok:!1,code:"runtime_tuning_save_failed",message:"保存发生异常;编辑器中保留了未保存的修改。",phase:"save",draftApplied:s.outcome==="applied",dirty:s.draft?.dirty??!0}}return a.outcome!=="applied"&&a.outcome!=="no-op"?{ok:!1,code:a.diagnostics[0]?.code??"runtime_tuning_save_failed",message:q(a.diagnostics[0]?.message,"保存失败;编辑器中保留了未保存的修改。"),phase:"save",draftApplied:!0,dirty:a.draft?.dirty??!0}:{ok:!0,phase:"save",draftApplied:!0,dirty:a.draft?.dirty??!1,receipt:Le(a.output)}}function ke(e,t){return e.role!=="camera"||typeof e.changes["camera.fov"]!="number"||t?.scene.gameObjects.find(i=>i.id===e.targetId)?.camera?.projection!=="perspective"?e.changes:{...e.changes,"camera.fov":e.changes["camera.fov"]*180/Math.PI}}function Ne(e,t){const n=t?.meta?.authoringSource?.sourceId;if(!n||e.targets.some(o=>o.sourceId!==n))return!1;const i=new Map(t.scene.gameObjects.map(o=>[o.id,o]));return e.targets.every(o=>{const r=i.get(o.targetId);return r?o.role==="camera"?r.camera?.projection==="orthographic"||r.camera?.projection==="perspective":o.role==="environment-light"?r.light?.type==="hemispheric":r.light?.type==="directional":!1})}function De(e,t){if(!e||typeof e!="object"||Array.isArray(e))return null;const n=e;if(!k(n,["projectId","kind","targets"]))return null;const i=n.targets;if(n.projectId!==t||n.kind!=="camera"&&n.kind!=="light"||!Array.isArray(i)||i.length!==(n.kind==="camera"?1:2))return null;const o=n.kind==="camera"?new Set(["camera"]):new Set(["environment-light","directional-light"]),r=new Set,s=i.map(a=>{if(!a||typeof a!="object"||Array.isArray(a))return null;const d=a;if(!k(d,["role","targetId","sourceId","changes"]))return null;const f=typeof d.role=="string"?d.role:"";if(!o.has(f)||r.has(f))return null;r.add(f);const u=typeof d.targetId=="string"?d.targetId.trim():"",p=typeof d.sourceId=="string"?d.sourceId.trim():"";if(!u||!p||!d.changes||typeof d.changes!="object"||Array.isArray(d.changes))return null;const c=Object.entries(d.changes);return c.length>0&&c.length<=24&&c.every(([w,S])=>ze(f,w,S))?{role:f,targetId:u,sourceId:p,changes:Object.fromEntries(c)}:null});return r.size===o.size&&s.every(a=>a!==null)?{projectId:t,kind:n.kind,targets:s}:null}const Ue=new Set(["camera.alpha","camera.beta","camera.radius","camera.orthoSize","camera.fov","camera.minZ","camera.maxZ","camera.inertia"]);function ze(e,t,n){return e==="camera"?t==="camera.projection"?n==="orthographic"||n==="perspective":t==="camera.targetOffset"?R(n,["x","y","z"]):t==="camera.targetScreenOffset"?R(n,["x","y"]):Ue.has(t)&&typeof n=="number"&&Number.isFinite(n):e==="environment-light"?t==="enabled"?typeof n=="boolean":t==="light.intensity"?typeof n=="number"&&Number.isFinite(n):(t==="light.diffuseColor"||t==="light.groundColor")&&R(n,["r","g","b"]):e==="directional-light"?t==="enabled"?typeof n=="boolean":t==="light.intensity"?typeof n=="number"&&Number.isFinite(n):t==="light.diffuseColor"?R(n,["r","g","b"]):t==="transform.rotation"&&R(n,["x","y","z"]):!1}function R(e,t){if(!e||typeof e!="object"||Array.isArray(e))return!1;const n=e;return k(n,t)&&t.every(i=>typeof n[i]=="number"&&Number.isFinite(n[i]))}function k(e,t){const n=new Set(t);return Object.keys(e).every(i=>n.has(i))}function Le(e){if(!e||typeof e!="object"||Array.isArray(e))return{};const t=e,n=t.receipt&&typeof t.receipt=="object"&&!Array.isArray(t.receipt)?t.receipt:t,i={};for(const[o,r]of Object.entries(n))["version","updatedAt","sceneUrl"].includes(o)&&(typeof r=="string"||typeof r=="number")&&(i[o]=r);return i}function q(e,t){return typeof e!="string"?t:e.replace(/\/(?:Users|home|private|var|tmp)(?:\/[^\s"'<>]+)+/giu,"[redacted-path]").replace(/\b([a-z-]*(?:token|secret|authorization)[a-z-]*)\s*[:=]\s*[^\s,;]+/giu,"$1=[redacted]").replace(/\b[A-Z]:\\(?:[^\s"'<>]+\\)*[^\s"'<>]+/gu,"[redacted-path]").slice(0,320)}function V(e,t){return new Promise(n=>e.setTimeout(n,t))}async function Be(e){let t=null,n=!1,i=Promise.resolve(),o=null;const r=e.container.ownerDocument,s=r.defaultView??window;let a=null,d=null;if(!e.projectIOAvailability&&e.projectIOInitialAvailability&&e.authoringEndpointBase){const l=e.authoringFetchJson??(async(m,g)=>{const y=await s.fetch(m,g),M=await y.json().catch(()=>null);if(!y.ok)throw new Error(`Project I/O health request failed (${y.status}).`);return M});a=ve({endpointBase:e.authoringEndpointBase,initial:e.projectIOInitialAvailability,ownerWindow:s,fetchJson:l})}const f=e.projectIOAvailability??a?.availability,u=r.createElement("canvas");u.id="renderCanvas",u.style.cssText="display:block;width:100%;height:100%;touch-action:none;outline:none";const p=()=>{d?.(),d=null,o?.(),o=null,u.remove()},c=l=>{const m=i.then(l,l);return i=m.catch(()=>{}),m},w=()=>{const l=t?.getHost()?.harness.getBrowserAuthoringApi();if(!l)throw new Error("Browser Editor API is unavailable.");return l},S=async(l,m)=>{const g=t?.getHost();if(!g)throw new Error("Editor host is unavailable for asset import.");const y=m?g.harness.projectAssetDropPoint({space:"scene-view-normalized",x:m.x,y:m.y}):null,M=l.objectId??ye([],`${l.assetName??l.projectAssetId??"asset"}_${we()}`),b=await g.harness.executeBrowserAuthoringCapability({capabilityId:"asset.importAndPlace",input:{...l,objectId:M,...y?{position:y}:{}}});if(b.outcome!=="applied"&&b.outcome!=="no-op")throw new Error(b.diagnostics[0]?.message??"Browser asset import and placement failed.")};async function h(){if(n)return;let l=null;try{const m=ge(e.projectDefinition);o?.(),o=qe(s,e.runtimeAssetBaseUrl),u.parentNode!==e.container&&e.container.appendChild(u);const g=_e(),y=Object.freeze({environment:"editor",buildTarget:"editor",manifests:Object.freeze([g]),entries:Object.freeze([{pluginId:g.id,config:null,load:async()=>je}]),pluginConfigs:Object.freeze({...Object.fromEntries(m.plugins.map(b=>[b.pluginId,b.config])),[g.id]:null})});if(l=await be(m.project,{root:e.container,window:s,authoringEndpointBase:e.authoringEndpointBase,authoringFetchJson:e.authoringFetchJson,projectIOAvailability:f,...e.agentDocumentSave?{agentDocumentSave:e.agentDocumentSave}:{},onExternalAssetDrop:e.onExternalAssetDrop?async b=>{const F=await e.onExternalAssetDrop?.(b);F&&await S(F,{x:b.point.sceneX,y:b.point.sceneY})}:void 0,projectMode:{async enterEditorMode(){},...e.onEnterPlayMode?{enterPlayMode:e.onEnterPlayMode}:{}},pluginModule:y,getCanvas:()=>u,...e.materialShaderDefinitions?{materialShaderDefinitions:e.materialShaderDefinitions}:{},...e.materialProjectionAdapters?{materialProjectionAdapters:e.materialProjectionAdapters}:{}}),n){await l.dispose(),p();return}t=l,await l.enterEditor(),d=Re(m.project.projectId,b=>l.getHost().harness.executeBrowserAuthoringCapability(b),()=>l?.getHost()?.harness.getWorkingDocument()??null,s);const M=s.__FPS_EDITOR_SYSTEM_FUNCTIONAL_REGISTER__;typeof M=="function"&&M(Object.freeze({readDraft(){const b=t?.getHost()?.harness,F=b?.getWorkingDocument(),z=b?.getPersistedDocument(),L=b?.getDocumentState();return F&&z&&L?Object.freeze({summary:L,workingDocument:F,persistedDocument:z}):null}}))}catch(m){t===l&&(t=null);let g=null;try{await l?.dispose()}catch(y){g=y}finally{p()}if(g){const y=g instanceof Error?g.message:String(g),M=new Error(`Editor mount failed and cleanup also failed: ${y}`);throw Object.assign(M,{cause:m,cleanupError:g}),M}throw m}}try{await c(h)}catch(l){throw a?.stop(),a=null,l}return{getApi:w,async save(){const l=t?.getHost();if(!l)return!1;const m=await l.harness.executeBrowserAuthoringCapability({capabilityId:"document.save",input:{}});return m.outcome==="applied"||m.outcome==="no-op"},reload(){return c(async()=>{const l=t;t=null,d?.(),d=null;try{await l?.dispose()}finally{p()}await h()})},async importAsset({point:l,...m}){await S(m,l)},dispose(){return n=!0,a?.stop(),a=null,c(async()=>{s.__FPS_EDITOR_SYSTEM_FUNCTIONAL_REGISTER__?.(null);const l=t;t=null,d?.(),d=null;try{await l?.dispose()}finally{p()}})}}}function qe(e,t){const n=e,i=Object.getOwnPropertyDescriptor(n,"__FPS_EDITOR_RUNTIME_URL__");t&&(n.__FPS_EDITOR_RUNTIME_URL__=t);let o=!1;return()=>{o||(o=!0,t&&n.__FPS_EDITOR_RUNTIME_URL__===t&&(i?Object.defineProperty(n,"__FPS_EDITOR_RUNTIME_URL__",i):delete n.__FPS_EDITOR_RUNTIME_URL__))}}const E=(e,t)=>({kind:"number",...e!=null?{min:e}:{},...t!=null?{max:t}:{}}),A={kind:"texture"},H={kind:"color"},Ve={kind:"enum",values:["lit","unlit"]},He={kind:"enum",values:["opaque","mask","blend"]},te={lightingModel:Ve,baseColor:{kind:"object",properties:{color:H,texture:A,brightness:E(0),saturation:E(0),contrast:E(0),hue:E(-180,180)}},normal:{kind:"object",properties:{texture:A,strength:E(0)}},emission:{kind:"object",properties:{color:H,intensity:E(0),texture:A,maskTexture:A}},alpha:{kind:"object",properties:{mode:He,opacity:E(0,1),cutoff:E(0,1),texture:A}}},Ge={kind:"object",properties:{...te,metallic:E(0,1),roughness:E(0,1),metallicRoughness:{kind:"object",properties:{texture:A}},occlusion:{kind:"object",properties:{texture:A,strength:E(0)}}}},Ke={kind:"object",properties:te},Je={lightingModel:"lit",baseColor:{color:{r:1,g:1,b:1},brightness:1,saturation:1,contrast:1,hue:0},metallic:0,roughness:1,emission:{color:{r:0,g:0,b:0},intensity:0}},We={lightingModel:"lit",baseColor:{color:{r:1,g:1,b:1},brightness:1,saturation:1,contrast:1,hue:0},emission:{color:{r:0,g:0,b:0},intensity:0}},G=[{id:"surface",title:"Surface",order:40},{id:"geometry",title:"Geometry",order:50},{id:"emission",title:"Emission",order:60},{id:"alpha",title:"Alpha",order:70}],x={path:"properties.lightingModel",operator:"equals",value:"lit",inactiveReasonKey:"litMaterial"},re=[O("properties.lightingModel","surface",1,"enum","assetLightingModel","lightingModel","lit",{options:[{value:"lit",labelKey:"assetLightingModelLit"},{value:"unlit",labelKey:"assetLightingModelUnlit"}],binding:"lightingModel",updateClass:"define"}),O("properties.baseColor.color","surface",2,"color","assetBaseColor","baseColor",{r:1,g:1,b:1},{binding:"baseColor.color"}),$("properties.baseColor.texture.textureAssetId","properties.baseColor.texture","surface",3,"assetBaseTexture","baseTexture","baseColor.texture"),_("properties.baseColor.brightness","surface",4,"assetBrightness","brightness",1,{softMin:0,softMax:4,step:.05,conditions:[P("properties.baseColor.texture.textureAssetId","baseTexture")]}),_("properties.baseColor.saturation","surface",5,"assetSaturation","saturation",1,{softMin:0,softMax:2,step:.05,conditions:[P("properties.baseColor.texture.textureAssetId","baseTexture")]}),_("properties.baseColor.contrast","surface",6,"assetContrast","contrast",1,{softMin:0,softMax:2,step:.05,conditions:[P("properties.baseColor.texture.textureAssetId","baseTexture")]}),_("properties.baseColor.hue","surface",7,"assetHue","hue",0,{step:1,conditions:[P("properties.baseColor.texture.textureAssetId","baseTexture")]}),$("properties.normal.texture.textureAssetId","properties.normal.texture","geometry",10,"assetNormalTexture","normalTexture","normal.texture",[x]),_("properties.normal.strength","geometry",11,"assetNormalStrength","normalStrength",1,{softMin:0,softMax:4,step:.05,conditions:[x,P("properties.normal.texture.textureAssetId","normalTexture")]}),O("properties.emission.color","emission",50,"color","assetEmissionColor","emissionColor",{r:0,g:0,b:0},{binding:"emission.color"}),_("properties.emission.intensity","emission",51,"assetEmissionIntensity","emissionIntensity",0,{softMin:0,softMax:8,step:.05}),$("properties.emission.texture.textureAssetId","properties.emission.texture","emission",52,"assetEmissionTexture","emissionTexture","emission.texture"),O("properties.alpha.mode","alpha",60,"enum","assetAlphaMode","alphaMode","opaque",{options:[{value:"opaque",labelKey:"assetAlphaModeOpaque"},{value:"mask",labelKey:"assetAlphaModeMask"},{value:"blend",labelKey:"assetAlphaModeBlend"}],binding:"alpha.mode",updateClass:"pipeline"}),_("properties.alpha.opacity","alpha",61,"assetAlphaOpacity","alphaOpacity",1,{step:.05,conditions:[{path:"properties.alpha.mode",operator:"equals",value:"blend",inactiveReasonKey:"alphaBlend"}]}),_("properties.alpha.cutoff","alpha",62,"assetAlphaCutoff","alphaCutoff",.5,{step:.01,conditions:[{path:"properties.alpha.mode",operator:"equals",value:"mask",inactiveReasonKey:"alphaMask"}]}),$("properties.alpha.texture.textureAssetId","properties.alpha.texture","alpha",63,"assetAlphaTexture","alphaTexture","alpha.texture",[{path:"properties.alpha.mode",operator:"not-equals",value:"opaque",inactiveReasonKey:"alphaTransparency"}])],Ze=[...re,_("properties.metallic","geometry",20,"assetMetallic","metallic",0,{step:.05,conditions:[x]}),_("properties.roughness","geometry",21,"assetRoughness","roughness",1,{step:.05,conditions:[x]}),$("properties.metallicRoughness.texture.textureAssetId","properties.metallicRoughness.texture","geometry",22,"assetMetallicRoughnessTexture","metallicRoughnessTexture","metallicRoughness.texture",[x]),$("properties.occlusion.texture.textureAssetId","properties.occlusion.texture","geometry",23,"assetOcclusionTexture","occlusionTexture","occlusion.texture",[x]),_("properties.occlusion.strength","geometry",24,"assetOcclusionStrength","occlusionStrength",1,{softMin:0,softMax:4,step:.05,conditions:[x,P("properties.occlusion.texture.textureAssetId","occlusionTexture")]})],ne=[{shaderId:"fps.builtin.pbr",version:1,runtimeKind:"pbr",displayName:"PBR",propertiesSchema:Ge,defaultProperties:Je,inspector:{sections:G,fields:Ze}},{shaderId:"fps.builtin.standard",version:1,runtimeKind:"standard",displayName:"Standard",propertiesSchema:Ke,defaultProperties:We,inspector:{sections:G,fields:re}}];oe(ne);function oe(e){const t=new Map;for(const i of e){Ye(i,t);const o=Xe(i);t.set(i.shaderId,ce(o))}const n=Object.freeze([...t.values()]);return Object.freeze({get(i){return typeof i=="string"?t.get(i)??null:null},list(){return n}})}function O(e,t,n,i,o,r,s,a){return{path:e,sectionId:t,order:n,control:i,labelKey:o,tooltipKey:r,defaultValue:s,updateClass:"uniform",...a}}function _(e,t,n,i,o,r,s={}){return O(e,t,n,"number",i,o,r,{binding:e.replace(/^properties\./,""),step:s.step??.05,displayPrecision:2,precision:2,...s})}function $(e,t,n,i,o,r,s,a){return O(e,n,i,"texture",o,r,"",{schemaPath:t,binding:s,updateClass:"texture",...a?{conditions:a}:{}})}function P(e,t){return{path:e,operator:"truthy",inactiveReasonKey:t}}function Ye(e,t){if(!Se(e.shaderId)&&!Ie(e.shaderId))throw new Error("Material Shader Definition shaderId must be a supported built-in id or a lowercase namespaced project id.");if(!Number.isInteger(e.version)||e.version<=0)throw new Error(`Material Shader Definition ${e.shaderId} must use a positive integer version.`);if(t.has(e.shaderId))throw new Error(`Duplicate Material Shader Definition: ${e.shaderId}`);if(e.sourceFile!=null&&!et(e.sourceFile))throw new Error(`Material Shader Definition ${e.shaderId} sourceFile must be a safe project-relative path.`);ie(e.shaderId,e.propertiesSchema,"properties");const n=[];if(se(e.propertiesSchema,e.defaultProperties,"properties",n),n.length>0){const r=n[0];throw new Error(`Material Shader Definition ${e.shaderId} default ${r.path} ${r.message}.`)}const i=new Set;for(const r of e.inspector.sections){if(!r.id.trim()||i.has(r.id))throw new Error(`Material Shader Definition ${e.shaderId} contains an invalid or duplicate section: ${r.id}`);i.add(r.id)}const o=new Set;for(const r of e.inspector.fields){if(!r.path.startsWith("properties.")||o.has(r.path))throw new Error(`Material Shader Definition ${e.shaderId} contains an invalid or duplicate field: ${r.path}`);if(!i.has(r.sectionId))throw new Error(`Material Shader Definition ${e.shaderId} field ${r.path} references an unknown section.`);Qe(e,r),o.add(r.path)}}function Xe(e){const t=structuredClone(e);return{...t,inspector:{...t.inspector,fields:t.inspector.fields.map(n=>{if(n.control!=="number")return n;const i=ae(t.propertiesSchema,n.schemaPath??n.path);return i?.kind!=="number"?n:{...n,...i.min!=null?{min:i.min}:{},...i.max!=null?{max:i.max}:{}}})}}}function Qe(e,t){const n=[["min",t.min],["max",t.max],["softMin",t.softMin],["softMax",t.softMax]];for(const[o,r]of n)if(r!=null&&!Number.isFinite(r))throw new Error(`Material Shader Definition ${e.shaderId} field ${t.path} ${o} must be finite.`);if(t.control!=="number"){if(n.some(([,o])=>o!=null))throw new Error(`Material Shader Definition ${e.shaderId} field ${t.path} uses numeric ranges with a non-number control.`);return}const i=ae(e.propertiesSchema,t.schemaPath??t.path);if(i?.kind!=="number")throw new Error(`Material Shader Definition ${e.shaderId} field ${t.path} must reference a number schema.`);for(const[o,r,s]of[["min",t.min,i.min],["max",t.max,i.max]])if(r!=null&&r!==s)throw new Error(`Material Shader Definition ${e.shaderId} field ${t.path} ${o} must match propertiesSchema.`);if(t.softMin!=null&&t.softMax!=null&&t.softMin>t.softMax)throw new Error(`Material Shader Definition ${e.shaderId} field ${t.path} softMin must not exceed softMax.`);if(i.min!=null&&t.softMin!=null&&t.softMin<i.min)throw new Error(`Material Shader Definition ${e.shaderId} field ${t.path} softMin must not be below the schema minimum.`);if(i.max!=null&&t.softMax!=null&&t.softMax>i.max)throw new Error(`Material Shader Definition ${e.shaderId} field ${t.path} softMax must not exceed the schema maximum.`)}function ie(e,t,n){if(t.kind==="object"){for(const[i,o]of Object.entries(t.properties))ie(e,o,`${n}.${i}`);return}if(t.kind==="number"){if(t.min!=null&&!Number.isFinite(t.min))throw new Error(`Material Shader Definition ${e} number field ${n} min must be finite.`);if(t.max!=null&&!Number.isFinite(t.max))throw new Error(`Material Shader Definition ${e} number field ${n} max must be finite.`);if(t.min!=null&&t.max!=null&&t.min>t.max)throw new Error(`Material Shader Definition ${e} number field ${n} min must not exceed max.`);return}if(t.kind==="color"&&t.channels!=null&&t.channels!==3&&t.channels!==4)throw new Error(`Material Shader Definition ${e} color field ${n} channels must be 3 or 4.`)}function et(e){const t=e.trim();return!t||t.startsWith("/")||t.includes("\\")||t.includes(":")?!1:!t.split("/").includes("..")}function tt(e){const t=e.trim();return t.startsWith("properties.")?t:`properties.${t}`}function ae(e,t){const n=tt(t).replace(/^properties\./,"").split(".").filter(Boolean);if(n.length===0)return null;let i=e;for(const o of n){if(i.kind!=="object")return null;const r=i.properties[o];if(!r)return null;i=r}return i}function se(e,t,n,i){if(e.kind==="object"){if(!N(t)){i.push({path:n,message:"must be an object"});return}for(const r of Object.keys(t))Object.prototype.hasOwnProperty.call(e.properties,r)||i.push({path:`${n}.${r}`,message:"is not supported by the selected shader"});for(const[r,s]of Object.entries(e.properties))t[r]!==void 0&&se(s,t[r],`${n}.${r}`,i);return}if(e.kind==="number"){if(typeof t!="number"||!Number.isFinite(t)){i.push({path:n,message:"must be a finite number"});return}e.min!=null&&t<e.min&&i.push({path:n,message:`must be greater than or equal to ${e.min}`}),e.max!=null&&t>e.max&&i.push({path:n,message:`must be less than or equal to ${e.max}`});return}if(e.kind==="boolean"){typeof t!="boolean"&&i.push({path:n,message:"must be a boolean"});return}if(e.kind==="string"){t!==null&&typeof t!="string"?i.push({path:n,message:"must be a string"}):t===null&&!e.nullable&&i.push({path:n,message:"must not be null"});return}if(e.kind==="enum"){(typeof t!="string"||!e.values.includes(t))&&i.push({path:n,message:`must be one of: ${e.values.join(", ")}`});return}if(e.kind==="color"){const r=e.channels===4?["r","g","b","a"]:["r","g","b"];K(t,n,r,i,e.channels===4?"an RGBA object":"an RGB object");return}if(e.kind==="vec2"||e.kind==="vec3"){K(t,n,e.kind==="vec2"?["x","y"]:["x","y","z"],i,`a ${e.kind} object`);return}if(t===null)return;if(!N(t)){i.push({path:n,message:"must be a texture reference object or null"});return}Object.keys(t).some(r=>r!=="url"&&r!=="textureAssetId")&&i.push({path:n,message:"must contain only url or textureAssetId"});for(const r of["url","textureAssetId"]){const s=t[r];s!==void 0&&(typeof s!="string"||!s.trim())&&i.push({path:`${n}.${r}`,message:"must be a non-empty string"})}}function K(e,t,n,i,o){if(!N(e)){i.push({path:t,message:`must be ${o}`});return}Object.keys(e).some(r=>!n.includes(r))&&i.push({path:t,message:`must contain only ${n.join(", ")}`});for(const r of n)(typeof e[r]!="number"||!Number.isFinite(e[r]))&&i.push({path:`${t}.${r}`,message:"must be a finite number"})}function ce(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){Object.freeze(e);for(const t of Object.values(e))ce(t)}return e}function N(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}const rt=Object.freeze([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),nt=Object.freeze([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]);function D(e){return it(new TextEncoder().encode(e))}function ot(e){return`sha256:${D(JSON.stringify(e))}`}function it(e){const t=Math.ceil((e.length+9)/64)*64,n=new Uint8Array(t);n.set(e),n[e.length]=128;const i=new DataView(n.buffer);i.setUint32(t-8,Math.floor(e.length/536870912),!1),i.setUint32(t-4,e.length*8>>>0,!1);const o=[...rt],r=new Uint32Array(64);for(let s=0;s<n.length;s+=64){for(let h=0;h<16;h+=1)r[h]=i.getUint32(s+h*4,!1);for(let h=16;h<64;h+=1){const l=r[h-15],m=r[h-2],g=j(l,7)^j(l,18)^l>>>3,y=j(m,17)^j(m,19)^m>>>10;r[h]=r[h-16]+g+r[h-7]+y>>>0}let[a,d,f,u,p,c,w,S]=o;for(let h=0;h<64;h+=1){const l=j(p,6)^j(p,11)^j(p,25),m=p&c^~p&w,g=S+l+m+nt[h]+r[h]>>>0,y=j(a,2)^j(a,13)^j(a,22),M=a&d^a&f^d&f,b=y+M>>>0;S=w,w=c,c=p,p=u+g>>>0,u=f,f=d,d=a,a=g+b>>>0}o[0]=o[0]+a>>>0,o[1]=o[1]+d>>>0,o[2]=o[2]+f>>>0,o[3]=o[3]+u>>>0,o[4]=o[4]+p>>>0,o[5]=o[5]+c>>>0,o[6]=o[6]+w>>>0,o[7]=o[7]+S>>>0}return o.map(s=>s.toString(16).padStart(8,"0")).join("")}function j(e,t){return e>>>t|e<<32-t}const at="fps.plugin.materials";function st(e){const t=e?.[at];if(t==null)return null;if(!v(t)||t.schemaVersion!==1||typeof t.snapshotId!="string"||!Array.isArray(t.shaders))throw new Error("Materials Plugin snapshot is invalid. Run fps-editor-prepare again.");const n=structuredClone(t);return ct(n),de(n)}function le(e){return oe([...ne,...e?.shaders.map(t=>t.definition)??[]])}function ct(e){if(!/^sha256:[a-f0-9]{64}$/.test(e.snapshotId)||e.shaders.length===0)throw new Error("Materials Plugin snapshot identity is invalid. Run fps-editor-prepare again.");for(const n of e.shaders)if(!v(n)||!v(n.definition)||!v(n.program))throw new Error("Materials Plugin Shader snapshot is invalid. Run fps-editor-prepare again.");le(e);for(const n of e.shaders){const{definition:i,program:o}=n;if(o.shaderId!==i.shaderId||o.definitionVersion!==i.version)throw new Error(`Material snapshot Definition identity does not match its program: ${i.shaderId}`);if(o.language!=="glsl"||!J(o.vertexSourcePath)||!J(o.fragmentSourcePath)||!/^[a-f0-9]{64}$/.test(o.vertexSourceHash)||!/^[a-f0-9]{64}$/.test(o.fragmentSourceHash)||typeof o.vertexSource!="string"||!o.vertexSource.trim()||typeof o.fragmentSource!="string"||!o.fragmentSource.trim())throw new Error(`Material snapshot program is invalid: ${i.shaderId}`);if(D(o.vertexSource)!==o.vertexSourceHash||D(o.fragmentSource)!==o.fragmentSourceHash)throw new Error(`Material snapshot source hash does not match its GLSL content: ${i.shaderId}`);if(!Array.isArray(o.attributes)||o.attributes.length===0||o.attributes.some(r=>!/^[A-Za-z_][A-Za-z0-9_]*$/.test(r))||new Set(o.attributes).size!==o.attributes.length)throw new Error(`Material snapshot attributes are invalid: ${i.shaderId}`);if(!["opaque","combine","add"].includes(o.alphaMode)||!v(o.enumUniformValues)||!v(o.frame)||!["on-demand","continuous"].includes(o.frame.mode))throw new Error(`Material snapshot rendering policy is invalid: ${i.shaderId}`)}const t={schemaVersion:e.schemaVersion,shaders:e.shaders};if(ot(t)!==e.snapshotId)throw new Error("Materials Plugin snapshot payload does not match its identity. Run fps-editor-prepare again.")}function J(e){return typeof e=="string"&&!!e&&!e.startsWith("/")&&!e.includes("\\")&&!e.includes(":")&&e.split("/").every(t=>!!t&&t!=="."&&t!=="..")}function de(e){if(!e||typeof e!="object"||Object.isFrozen(e))return e;for(const t of Object.values(e))de(t);return Object.freeze(e)}function v(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function lt(e){let t=0;const n=new WeakMap;return Object.freeze(e.shaders.map(({definition:i,program:o})=>Object.freeze({shaderId:i.shaderId,definitionVersion:i.version,snapshotId:e.snapshotId,createMaterial(r){const s=r.babylon,a=`${ht(i.shaderId)}-${t+=1}`;if(!s.Effect?.ShadersStore||!s.ShaderMaterial||!s.StandardMaterial||!s.Color3)throw new Error(`Babylon ShaderMaterial is unavailable for ${i.shaderId}.`);W(i,r.definitionVersion),s.Effect.ShadersStore[`${a}VertexShader`]=o.vertexSource,s.Effect.ShadersStore[`${a}FragmentShader`]=o.fragmentSource;const d=i.inspector.fields.filter(l=>l.updateClass==="uniform").map(l=>l.binding),f=[...new Set(["world","worldViewProjection",...o.frame.timeUniform?[o.frame.timeUniform]:[],...o.frame.cameraPositionUniform?[o.frame.cameraPositionUniform]:[],...d])];let u;try{u=new s.ShaderMaterial(a,r.scene,{vertex:a,fragment:a},{attributes:o.attributes,uniforms:f,needAlphaBlending:o.alphaMode!=="opaque"}),u.backFaceCulling=o.alphaMode==="opaque",u.alphaMode=o.alphaMode==="add"?s.Constants.ALPHA_ADD:o.alphaMode==="combine"?s.Constants.ALPHA_COMBINE:s.Constants.ALPHA_DISABLE,Z(s,u,i,o,r.properties)}catch(l){throw delete s.Effect.ShadersStore[`${a}VertexShader`],delete s.Effect.ShadersStore[`${a}FragmentShader`],u?.dispose?.(),l}const p=dt(s,r.scene,a),c={material:u,mesh:r.mesh,setMaterial:r.setMaterial,placeholder:p,compiled:!1,disposed:!1,failed:!1,failure:null,compilation:null,invalidateFrameParticipant:null,shaderName:a,shadersStore:s.Effect.ShadersStore};n.set(p,c),n.set(u,c);const w=()=>{c.disposed||c.failed||c.compiled||(c.compiled=!0,c.setMaterial(c.material),pt(c.mesh))},S=l=>{c.disposed||c.failed||(c.failed=!0,c.failure=l,c.invalidateFrameParticipant?.(),c.setMaterial(c.placeholder),ut(c.mesh,{code:"material.shaderCompilationFailed",severity:"error",shaderId:i.shaderId,definitionVersion:i.version,snapshotId:e.snapshotId,message:String(l??"Shader compilation failed.").slice(0,2048)}))};u.onCompiled=()=>{queueMicrotask(()=>{w()})},u.onError=(l,m)=>{S(m)};try{if(typeof u.forceCompilationAsync!="function")throw new Error("Babylon ShaderMaterial.forceCompilationAsync() is unavailable.");c.compilation=Promise.resolve(u.forceCompilationAsync(c.mesh)).then(()=>{if(c.failed)throw c.failure;w()}).catch(l=>{throw S(l),l})}catch(l){S(l),c.compilation=Promise.reject(l)}c.compilation.catch(()=>{}),p.forceCompilationAsync=()=>c.compilation;const h=p.dispose.bind(p);return p.dispose=(...l)=>{c.disposed||(c.disposed=!0,c.invalidateFrameParticipant?.(),delete c.shadersStore[`${c.shaderName}VertexShader`],delete c.shadersStore[`${c.shaderName}FragmentShader`],c.material.dispose?.(),h(...l))},p},updateMaterial(r){const s=r.babylon,a=Y(r.material)?n.get(r.material):void 0;return!a||a.disposed||a.failed?!1:(W(i,r.definitionVersion),Z(s,a.material,i,o,r.properties),!0)},...o.frame.mode==="continuous"?{createFrameParticipant(r){const s=r.babylon,a=Y(r.material)?n.get(r.material):void 0;if(!a)throw new Error(`ShaderMaterial state is unavailable for ${i.shaderId}.`);let d=!1;const f=new Set;return a.invalidateFrameParticipant=()=>{for(const u of[...f])u()},{frameMode:"continuous",resolveFrameMode(){return a.failed||a.disposed||d?"on-demand":"continuous"},isActive(){return!a.failed&&!a.disposed&&!d},onFrameModeChanged(u){return f.add(u),()=>f.delete(u)},updateFrame(u){if(!(a.failed||a.disposed||d)&&(o.frame.timeUniform&&a.material.setFloat(o.frame.timeUniform,u.elapsedSeconds),o.frame.cameraPositionUniform)){const p=r.scene.activeCamera;a.material.setVector3(o.frame.cameraPositionUniform,p?.globalPosition??p?.position??s.Vector3.Zero())}},dispose(){d||(d=!0,f.clear(),a.invalidateFrameParticipant&&(a.invalidateFrameParticipant=null))}}}}:{}})))}function W(e,t){if(t!==e.version)throw Object.assign(new Error(`Material Definition version mismatch for ${e.shaderId}: expected ${e.version}, received ${String(t)}.`),{code:"material.shaderDefinitionVersionMismatch",shaderId:e.shaderId,expectedVersion:e.version,actualVersion:t})}function dt(e,t,n){const i=new e.StandardMaterial(`${n}.diagnostic`,t);return i.diffuseColor=new e.Color3(.8,.02,.45),i.emissiveColor=new e.Color3(.35,0,.12),i.specularColor=new e.Color3(0,0,0),i.backFaceCulling=!1,i}function ut(e,t){const n=C(e.metadata)?e.metadata:{},i=C(n.editorProjection)?n.editorProjection:{};e.metadata={...n,editorProjection:{...i,materialDiagnostic:Object.freeze({...t})}}}function pt(e){if(!C(e.metadata)||!C(e.metadata.editorProjection)||!Object.prototype.hasOwnProperty.call(e.metadata.editorProjection,"materialDiagnostic"))return;const t={...e.metadata.editorProjection};delete t.materialDiagnostic,e.metadata={...e.metadata,editorProjection:t}}function Z(e,t,n,i,o){for(const r of n.inspector.fields){if(r.updateClass!=="uniform")continue;const s=mt(o,r.path.replace(/^properties\./,""));if(r.control==="number")t.setFloat(r.binding,I(s,r.path));else if(r.control==="boolean")t.setFloat(r.binding,s===!0?1:0);else if(r.control==="enum"){const a=i.enumUniformValues[r.path],d=typeof s=="string"?a?.[s]:void 0;if(!Number.isFinite(d))throw new Error(`Enum uniform value is not mapped: ${r.path}=${String(s)}`);t.setFloat(r.binding,d)}else if(r.control==="color"){const a=T(s,r.path);ft(n,r.path)===4?t.setColor4(r.binding,new e.Color4(I(a.r,`${r.path}.r`),I(a.g,`${r.path}.g`),I(a.b,`${r.path}.b`),I(a.a,`${r.path}.a`))):t.setColor3(r.binding,new e.Color3(I(a.r,`${r.path}.r`),I(a.g,`${r.path}.g`),I(a.b,`${r.path}.b`)))}else if(r.control==="vec2"){const a=T(s,r.path);t.setVector2(r.binding,new e.Vector2(I(a.x,`${r.path}.x`),I(a.y,`${r.path}.y`)))}else if(r.control==="vec3"){const a=T(s,r.path);t.setVector3(r.binding,new e.Vector3(I(a.x,`${r.path}.x`),I(a.y,`${r.path}.y`),I(a.z,`${r.path}.z`)))}else throw new Error(`Unsupported ShaderMaterial uniform control: ${r.path} (${r.control})`)}}function ft(e,t){let n=e.propertiesSchema;for(const i of t.replace(/^properties\./,"").split(".")){if(n.kind!=="object"||!n.properties[i])return 3;n=n.properties[i]}return n.kind==="color"&&n.channels===4?4:3}function mt(e,t){let n=e;for(const i of t.split(".").filter(Boolean)){if(!C(n))return;n=n[i]}return n}function T(e,t){if(!C(e))throw new Error(`Material property must be an object: ${t}`);return e}function I(e,t){if(typeof e!="number"||!Number.isFinite(e))throw new Error(`Material property must be a finite number: ${t}`);return e}function ht(e){return e.replace(/[^a-z0-9_-]/gi,"_")}function Y(e){return!!e&&typeof e=="object"}function C(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}const ue=window.__FPS_EDITOR_PROJECT_DEFINITION__;if(!ue)throw new Error("Editor Project definition was not provided by the control plane.");const U=st(window.__FPS_EDITOR_PLUGIN_SNAPSHOTS__),gt=le(U),X=U?lt(U):void 0,Q=()=>{const e=window.__FPS_EDITOR_PROJECT_IO__,t=String(e?.generation??0);return e?.status==="ready"?{ready:!0,generation:t}:{ready:!1,generation:t,reason:e?.reason??"Project I/O is unavailable."}},bt=await Be({container:document.body,projectDefinition:ue,agentDocumentSave:window.__FPS_EDITOR_CONFIG__?.agentDocumentSave,runtimeAssetBaseUrl:window.location.origin,projectIOAvailability:{getAvailability:Q,subscribeAvailability(e){const t=()=>e(Q());return window.addEventListener("fps-editor:project-io-availability-changed",t),()=>window.removeEventListener("fps-editor:project-io-availability-changed",t)}},async onEnterPlayMode(){const e=window.__FPS_EDITOR_RUNTIME_URL__;if(!e)throw new Error("Editor Runtime URL was not provided by the control plane.");window.location.assign(e)},materialShaderDefinitions:gt,...X?{materialProjectionAdapters:X}:{}});window.addEventListener("pagehide",()=>void bt.dispose(),{once:!0});