@fps-games/editor-deployment 0.2.3-beta.20 → 0.2.3-beta.21

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.20
3
- Commit: 0deb03759c8a7fa9a8f4f4dc6151f48699c7bede
2
+ Version: 0.2.3-beta.21
3
+ Commit: b8cb2bed4f09ccc0b90f7950d222bc15f431bcf3
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": 5,
3
3
  "artifactKind": "fps-editor-deployment-package",
4
4
  "packageName": "@fps-games/editor-deployment",
5
- "version": "0.2.3-beta.20",
6
- "commitSha": "0deb03759c8a7fa9a8f4f4dc6151f48699c7bede",
5
+ "version": "0.2.3-beta.21",
6
+ "commitSha": "b8cb2bed4f09ccc0b90f7950d222bc15f431bcf3",
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.20",
14
- "buildId": "0.2.3-beta.20-ee599b064e9f",
15
- "distHash": "ee599b064e9f805a5f2ac19be9a1e01d03c0d8eae5ee57e628c1f8c21642c3ab"
13
+ "version": "0.2.3-beta.21",
14
+ "buildId": "0.2.3-beta.21-f571dc1fc40e",
15
+ "distHash": "f571dc1fc40ec7ba94b5ec3f91a1a15d1c4c72fe4cbb0f296fdc734e967431e2"
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": "1726cb455bb7331777ffe86c4f8343862fca2f369e71afbfa0736345abf7a97c"
48
+ "sha256": "b7bcefe263470931193c8afb9e85b33a3bc260cccec717528ae2bcdde3e067e6"
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-CSRKtiw4.js",
1631
+ "path": "public/assets/index-igN1GVhI.js",
1632
1632
  "size": 38246,
1633
- "sha256": "75d531fe4451740c35a7e4009078ae46dccbac243020da3f417b4b47da0e5b8f"
1633
+ "sha256": "6910be7253d14c015166a99d1ffe07077b5eeca95b79afe987a79adc89ac7277"
1634
1634
  },
1635
1635
  {
1636
- "path": "public/assets/index-CSRKtiw4.js.br",
1637
- "size": 11174,
1638
- "sha256": "cedeee607ef9cb5dd92ff775f70e8abd3dca607619cc59ff04e807d9d0c56627"
1636
+ "path": "public/assets/index-igN1GVhI.js.br",
1637
+ "size": 11169,
1638
+ "sha256": "a603eb6e2a021abb954e8b199ecc0c994a9aa53fafb9c1fba6a8e5fda1120f6e"
1639
1639
  },
1640
1640
  {
1641
- "path": "public/assets/index-CSRKtiw4.js.gz",
1642
- "size": 12833,
1643
- "sha256": "54320cbe9b6d1c6a1ccaf7fc22585514ecf67517d1f01a5f43e64488ac4d57c2"
1641
+ "path": "public/assets/index-igN1GVhI.js.gz",
1642
+ "size": 12834,
1643
+ "sha256": "7f756a6f5245ec5e0c386454f2e21375286cbe4427373ef547a945cd49d46367"
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-CxfjVWHL.js",
2121
+ "path": "public/assets/playable-sdk-B8_VwaXx.js",
2122
2122
  "size": 145378,
2123
- "sha256": "a22f3c8a4a76f14c9b0f5c1e1c659312e0b82709cbd3be88ecb9814848abbca4"
2123
+ "sha256": "3887d8a9db478f14e26bea00e83adf51a06720847446c3185dbbe5f7ac4e83c7"
2124
2124
  },
2125
2125
  {
2126
- "path": "public/assets/playable-sdk-CxfjVWHL.js.br",
2127
- "size": 34726,
2128
- "sha256": "7fb34267dbf2638f48772cd8bb00011f58792bf2a5be1cffa7363df4f4659a03"
2126
+ "path": "public/assets/playable-sdk-B8_VwaXx.js.br",
2127
+ "size": 34746,
2128
+ "sha256": "438240ada5808422f12ece4b761dd1d6fe0ad2840af5d4c42de0f0c1a894e72b"
2129
2129
  },
2130
2130
  {
2131
- "path": "public/assets/playable-sdk-CxfjVWHL.js.gz",
2131
+ "path": "public/assets/playable-sdk-B8_VwaXx.js.gz",
2132
2132
  "size": 42132,
2133
- "sha256": "3d0906af6eae5ba1a168f2479b0456e8b6110e84eb99f1424ab0967bc82e7c55"
2133
+ "sha256": "d8ba6727dd5725efbc389e13fe9688d22d67bb3b12736fac46831a966079c6c2"
2134
2134
  },
2135
2135
  {
2136
- "path": "public/assets/playable-standard-project-ZSBdsTD4.js",
2137
- "size": 3640652,
2138
- "sha256": "cfd863863ef27041bbda5b669536069cf7822d5429fe3bb6536d5165fdf7bc44"
2136
+ "path": "public/assets/playable-standard-project-X3XQewnw.js",
2137
+ "size": 3640812,
2138
+ "sha256": "6585f60453029e6da4f2da594eb233f0f4d3a84a353a85513bd615bd117f1f41"
2139
2139
  },
2140
2140
  {
2141
- "path": "public/assets/playable-standard-project-ZSBdsTD4.js.br",
2142
- "size": 755336,
2143
- "sha256": "853f0bcb983110799610803bf48e118da634514f859230d9614e4a498bdce0b5"
2141
+ "path": "public/assets/playable-standard-project-X3XQewnw.js.br",
2142
+ "size": 755432,
2143
+ "sha256": "c044b2734d3731722645d2a1506693cc6076a65184b9dd90019181b89705a68a"
2144
2144
  },
2145
2145
  {
2146
- "path": "public/assets/playable-standard-project-ZSBdsTD4.js.gz",
2147
- "size": 976020,
2148
- "sha256": "b30a586131ce550755c68647b254879ac06282cf75722600dd3adfb5668ffeca"
2146
+ "path": "public/assets/playable-standard-project-X3XQewnw.js.gz",
2147
+ "size": 976073,
2148
+ "sha256": "0862315f32a61dc059a33b8443c96397cf520c410a3ebbe5d9dccb9d29761de7"
2149
2149
  },
2150
2150
  {
2151
2151
  "path": "public/assets/rgbdDecode.fragment-Cf7NitgJ.js",
@@ -2645,17 +2645,17 @@
2645
2645
  {
2646
2646
  "path": "public/index.html",
2647
2647
  "size": 1027,
2648
- "sha256": "29df4589aa756d76bdfd8347b1c5ce1ae791c1e25ff885101318f549ddc2e523"
2648
+ "sha256": "905cf0616038a78b783f4b4596d76cbab950776723de3bc745afca66b8605682"
2649
2649
  },
2650
2650
  {
2651
2651
  "path": "public/index.html.br",
2652
- "size": 392,
2653
- "sha256": "9d7d0a2751c5f18c03db65c482a4b6c8a8bf876697c0e4816c65f631c8cb680a"
2652
+ "size": 390,
2653
+ "sha256": "659e04e23a90b32429ecedc7feb5ec58fb7ccf07d81b48719a28c95af38984d0"
2654
2654
  },
2655
2655
  {
2656
2656
  "path": "public/index.html.gz",
2657
- "size": 559,
2658
- "sha256": "016797fb927bf44bc55dfaa203d9ad1dbd9b2394a347b61b1933ab6b9a83f6f0"
2657
+ "size": 557,
2658
+ "sha256": "ea6c286b448fc3e112f68415b1ae03fbe20a96952135554073ed7d0fb80126b1"
2659
2659
  },
2660
2660
  {
2661
2661
  "path": "runtime/editor-control-plane.mjs",
@@ -2669,9 +2669,9 @@
2669
2669
  }
2670
2670
  ],
2671
2671
  "sizes": {
2672
- "packagePayloadBytes": 16893483,
2673
- "browserRawBytes": 11142799,
2674
- "browserGzipBytes": 2717632,
2675
- "browserBrotliBytes": 2118906
2672
+ "packagePayloadBytes": 16893804,
2673
+ "browserRawBytes": 11142959,
2674
+ "browserGzipBytes": 2717684,
2675
+ "browserBrotliBytes": 2119015
2676
2676
  }
2677
2677
  }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@fps-games/editor-deployment",
3
- "version": "0.2.3-beta.20",
3
+ "version": "0.2.3-beta.21",
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.20",
9
+ "version": "0.2.3-beta.21",
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.20",
3
+ "version": "0.2.3-beta.21",
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.20",
34
- "@fps-games/editor-core": "0.2.3-beta.20",
35
- "@fps-games/editor-playable-sdk": "0.2.3-beta.20",
36
- "@fps-games/editor-protocol": "0.2.3-beta.20",
37
- "@fps-games/engine": "0.0.1-beta.22",
38
- "@fps-games/plugin-hierarchy": "0.2.3-beta.20",
33
+ "@fps-games/editor": "0.2.3-beta.21",
34
+ "@fps-games/editor-core": "0.2.3-beta.21",
35
+ "@fps-games/editor-playable-sdk": "0.2.3-beta.21",
36
+ "@fps-games/editor-protocol": "0.2.3-beta.21",
37
+ "@fps-games/engine": "0.0.1-beta.23",
38
+ "@fps-games/plugin-hierarchy": "0.2.3-beta.21",
39
39
  "@fps-games/plugin-sdk": "0.1.0-beta.2"
40
40
  },
41
41
  "publishConfig": {
@@ -1 +1 @@
1
- import{fI as fe,fH as me,a5 as he,ex as ge,mE as be,j0 as ye,fz as we,cd as Se,jV as Ie,h$ as Me}from"./playable-standard-project-ZSBdsTD4.js";import{registerFpsEditorContribution as Ee}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 _e="0.2.3-beta.20",te="fps.plugin.hierarchy";function je(){return fe({id:te,version:_e,apiVersion:1,requires:{},provides:{features:["fps.editor.hierarchy"]},entries:{editor:"./editor"},environmentContracts:{editor:{requires:{services:["fps.editor.contributions"]},provides:{}}},deploymentConstraints:{allowedTargets:["editor"]}})}const Ae=me({pluginId:te,environment:"editor",register(e){Ee(e,{id:he,kind:"hierarchy",value:ge()})}}),xe=1e3,Pe=5e3,ve="Project I/O health request failed.";function Oe(e){const t=Fe(e.endpointBase),n=q(e.pollIntervalMs,xe),i=q(e.requestTimeoutMs,Pe);let o=Ce(e.initial),r=!1,s=null,a=null;const u=new Set,p=c=>{if(!Te(o,c)){o=c;for(const y of u)y(c)}},d=()=>{r||(s=e.ownerWindow.setTimeout(f,n))},f=async()=>{if(s=null,r)return;const c=new AbortController;a=c;const y=e.ownerWindow.setTimeout(()=>c.abort(),i);try{const b=await e.fetchJson(`${t}/health`,{cache:"no-store",signal:c.signal});p($e(b))}catch{r||p(Object.freeze({ready:!1,generation:o.generation,reason:ve}))}finally{e.ownerWindow.clearTimeout(y),a===c&&(a=null),d()}};return d(),Object.freeze({availability:Object.freeze({getAvailability:()=>o,subscribeAvailability(c){return r?()=>{}:(u.add(c),()=>u.delete(c))}}),stop(){r||(r=!0,s!==null&&e.ownerWindow.clearTimeout(s),s=null,a?.abort(),a=null,u.clear())}})}function $e(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 Ce(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 Te(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 q(e,t){return Number.isSafeInteger(e)&&e>0?e:t}const R=new WeakMap;function Re(e,t,n,i,o){const r=o??i.__FPS_EDITOR_RUNTIME_TUNING__;if(!r||r.projectId!==e)return()=>{};const s=R.get(i)??new Map,a=s.get(e),u=a?.consumerId??i.crypto?.randomUUID?.()??`browser_${Date.now().toString(36)}_${Math.random().toString(36).slice(2)}`;a?.stop(),R.set(i,s);let p=!1;const d=new AbortController,f=async()=>{for(;!p;)try{const y=await i.fetch(`${r.endpointBase}/consumer/poll`,{method:"POST",headers:{"x-fps-editor-runtime-tuning-token":r.token,"x-fps-editor-runtime-tuning-consumer":u},cache:"no-store",signal:d.signal}),b=await y.json().catch(()=>null);if(!y.ok||!b||typeof b.requestId!="string"){p||await H(i,500);continue}const h=await ke(e,t,b.intent,n);await i.fetch(`${r.endpointBase}/consumer/result`,{method:"POST",headers:{"content-type":"application/json","x-fps-editor-runtime-tuning-token":r.token,"x-fps-editor-runtime-tuning-consumer":u},body:JSON.stringify({requestId:b.requestId,result:h}),cache:"no-store",signal:d.signal})}catch{p||await H(i,750)}},c=()=>{p||(p=!0,d.abort(),s.get(e)?.stop===c&&(s.delete(e),s.size===0&&R.delete(i)))};return s.set(e,{consumerId:u,stop:c}),f(),c}async function ke(e,t,n,i){const o=Ue(n,e);if(!o)return{ok:!1,code:"runtime_tuning_invalid_intent",message:"调参请求不符合 Camera/Light 固定字段。"};const r=i?.()??null;if(i&&!De(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(u=>({objectId:u.targetId,changes:Object.entries(Ne(u,r)).map(([p,d])=>({path:p,value:d}))}))}})}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:V(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:V(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:Be(a.output)}}function Ne(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 De(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 Ue(e,t){if(!e||typeof e!="object"||Array.isArray(e))return null;const n=e;if(!N(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 u=a;if(!N(u,["role","targetId","sourceId","changes"]))return null;const p=typeof u.role=="string"?u.role:"";if(!o.has(p)||r.has(p))return null;r.add(p);const d=typeof u.targetId=="string"?u.targetId.trim():"",f=typeof u.sourceId=="string"?u.sourceId.trim():"";if(!d||!f||!u.changes||typeof u.changes!="object"||Array.isArray(u.changes))return null;const c=Object.entries(u.changes);return c.length>0&&c.length<=24&&c.every(([y,b])=>Le(p,y,b))?{role:p,targetId:d,sourceId:f,changes:Object.fromEntries(c)}:null});return r.size===o.size&&s.every(a=>a!==null)?{projectId:t,kind:n.kind,targets:s}:null}const ze=new Set(["camera.alpha","camera.beta","camera.radius","camera.orthoSize","camera.fov","camera.minZ","camera.maxZ","camera.inertia"]);function Le(e,t,n){return e==="camera"?t==="camera.projection"?n==="orthographic"||n==="perspective":t==="camera.targetOffset"?F(n,["x","y","z"]):t==="camera.targetScreenOffset"?F(n,["x","y"]):ze.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")&&F(n,["r","g","b"]):e==="directional-light"?t==="enabled"?typeof n=="boolean":t==="light.intensity"?typeof n=="number"&&Number.isFinite(n):t==="light.diffuseColor"?F(n,["r","g","b"]):t==="transform.rotation"&&F(n,["x","y","z"]):!1}function F(e,t){if(!e||typeof e!="object"||Array.isArray(e))return!1;const n=e;return N(n,t)&&t.every(i=>typeof n[i]=="number"&&Number.isFinite(n[i]))}function N(e,t){const n=new Set(t);return Object.keys(e).every(i=>n.has(i))}function Be(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 V(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 H(e,t){return new Promise(n=>e.setTimeout(n,t))}async function qe(e){let t=null,n=!1,i=Promise.resolve(),o=null;const r=e.container.ownerDocument,s=r.defaultView??window;let a=null,u=null;if(!e.projectIOAvailability&&e.projectIOInitialAvailability&&e.authoringEndpointBase){const l=e.authoringFetchJson??(async(m,g)=>{const S=await s.fetch(m,g),M=await S.json().catch(()=>null);if(!S.ok)throw new Error(`Project I/O health request failed (${S.status}).`);return M});a=Oe({endpointBase:e.authoringEndpointBase,initial:e.projectIOInitialAvailability,ownerWindow:s,fetchJson:l})}const p=e.projectIOAvailability??a?.availability,d=r.createElement("canvas");d.id="renderCanvas",d.style.cssText="display:block;width:100%;height:100%;touch-action:none;outline:none";const f=()=>{u?.(),u=null,o?.(),o=null,d.remove()},c=l=>{const m=i.then(l,l);return i=m.catch(()=>{}),m},y=()=>{const l=t?.getHost()?.harness.getBrowserAuthoringApi();if(!l)throw new Error("Browser Editor API is unavailable.");return l},b=async(l,m)=>{const g=t?.getHost();if(!g)throw new Error("Editor host is unavailable for asset import.");const S=m?g.harness.projectAssetDropPoint({space:"scene-view-normalized",x:m.x,y:m.y}):null,M=l.objectId??we([],`${l.assetName??l.projectAssetId??"asset"}_${Se()}`),w=await g.harness.executeBrowserAuthoringCapability({capabilityId:"asset.importAndPlace",input:{...l,objectId:M,...S?{position:S}:{}}});if(w.outcome!=="applied"&&w.outcome!=="no-op")throw new Error(w.diagnostics[0]?.message??"Browser asset import and placement failed.")};async function h(){if(n)return;let l=null;try{const m=be(e.projectDefinition);o?.(),o=Ve(s,e.runtimeAssetBaseUrl),d.parentNode!==e.container&&e.container.appendChild(d);const g=je(),S=Object.freeze({environment:"editor",buildTarget:"editor",manifests:Object.freeze([g]),entries:Object.freeze([{pluginId:g.id,config:null,load:async()=>Ae}]),pluginConfigs:Object.freeze({...Object.fromEntries(m.plugins.map(w=>[w.pluginId,w.config])),[g.id]:null})});if(l=await ye(m.project,{root:e.container,window:s,authoringEndpointBase:e.authoringEndpointBase,authoringFetchJson:e.authoringFetchJson,projectIOAvailability:p,...e.agentDocumentSave?{agentDocumentSave:e.agentDocumentSave}:{},projectIO:e.projectIO,onExternalAssetDrop:e.onExternalAssetDrop?async w=>{const T=await e.onExternalAssetDrop?.(w);T&&await b(T,{x:w.point.sceneX,y:w.point.sceneY})}:void 0,projectMode:{async enterEditorMode(){},...e.onEnterPlayMode?{enterPlayMode:e.onEnterPlayMode}:{}},pluginModule:S,getCanvas:()=>d,...e.materialShaderDefinitions?{materialShaderDefinitions:e.materialShaderDefinitions}:{},...e.materialProjectionAdapters?{materialProjectionAdapters:e.materialProjectionAdapters}:{}}),n){await l.dispose(),f();return}t=l,await l.enterEditor(),u=Re(m.project.projectId,w=>l.getHost().harness.executeBrowserAuthoringCapability(w),()=>l?.getHost()?.harness.getWorkingDocument()??null,s,e.runtimeTuning);const M=s.__FPS_EDITOR_SYSTEM_FUNCTIONAL_REGISTER__;typeof M=="function"&&M(Object.freeze({readDraft(){const w=t?.getHost()?.harness,T=w?.getWorkingDocument(),L=w?.getPersistedDocument(),B=w?.getDocumentState();return T&&L&&B?Object.freeze({summary:B,workingDocument:T,persistedDocument:L}):null}}))}catch(m){t===l&&(t=null);let g=null;try{await l?.dispose()}catch(S){g=S}finally{f()}if(g){const S=g instanceof Error?g.message:String(g),M=new Error(`Editor mount failed and cleanup also failed: ${S}`);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:y,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,u?.(),u=null;try{await l?.dispose()}finally{f()}await h()})},async importAsset({point:l,...m}){await b(m,l)},dispose(){return n=!0,a?.stop(),a=null,c(async()=>{s.__FPS_EDITOR_SYSTEM_FUNCTIONAL_REGISTER__?.(null);const l=t;t=null,u?.(),u=null;try{await l?.dispose()}finally{f()}})}}}function Ve(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"},G={kind:"color"},He={kind:"enum",values:["lit","unlit"]},Ge={kind:"enum",values:["opaque","mask","blend"]},re={lightingModel:He,baseColor:{kind:"object",properties:{color:G,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:G,intensity:E(0),texture:A,maskTexture:A}},alpha:{kind:"object",properties:{mode:Ge,opacity:E(0,1),cutoff:E(0,1),texture:A}}},Ke={kind:"object",properties:{...re,metallic:E(0,1),roughness:E(0,1),metallicRoughness:{kind:"object",properties:{texture:A}},occlusion:{kind:"object",properties:{texture:A,strength:E(0)}}}},Je={kind:"object",properties:re},We={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}},Ze={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}},K=[{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"},ne=[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"}])],Ye=[...ne,_("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")]})],oe=[{shaderId:"fps.builtin.pbr",version:1,runtimeKind:"pbr",displayName:"PBR",propertiesSchema:Ke,defaultProperties:We,inspector:{sections:K,fields:Ye}},{shaderId:"fps.builtin.standard",version:1,runtimeKind:"standard",displayName:"Standard",propertiesSchema:Je,defaultProperties:Ze,inspector:{sections:K,fields:ne}}];ie(oe);function ie(e){const t=new Map;for(const i of e){Qe(i,t);const o=Xe(i);t.set(i.shaderId,le(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 Qe(e,t){if(!Ie(e.shaderId)&&!Me(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&&!tt(e.sourceFile))throw new Error(`Material Shader Definition ${e.shaderId} sourceFile must be a safe project-relative path.`);ae(e.shaderId,e.propertiesSchema,"properties");const n=[];if(ce(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.`);et(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=se(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 et(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=se(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 ae(e,t,n){if(t.kind==="object"){for(const[i,o]of Object.entries(t.properties))ae(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 tt(e){const t=e.trim();return!t||t.startsWith("/")||t.includes("\\")||t.includes(":")?!1:!t.split("/").includes("..")}function rt(e){const t=e.trim();return t.startsWith("properties.")?t:`properties.${t}`}function se(e,t){const n=rt(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 ce(e,t,n,i){if(e.kind==="object"){if(!D(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&&ce(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"];J(t,n,r,i,e.channels===4?"an RGBA object":"an RGB object");return}if(e.kind==="vec2"||e.kind==="vec3"){J(t,n,e.kind==="vec2"?["x","y"]:["x","y","z"],i,`a ${e.kind} object`);return}if(t===null)return;if(!D(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 J(e,t,n,i,o){if(!D(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 le(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){Object.freeze(e);for(const t of Object.values(e))le(t)}return e}function D(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}const nt=Object.freeze([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),ot=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 U(e){return at(new TextEncoder().encode(e))}function it(e){return`sha256:${U(JSON.stringify(e))}`}function at(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=[...nt],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,S=j(m,17)^j(m,19)^m>>>10;r[h]=r[h-16]+g+r[h-7]+S>>>0}let[a,u,p,d,f,c,y,b]=o;for(let h=0;h<64;h+=1){const l=j(f,6)^j(f,11)^j(f,25),m=f&c^~f&y,g=b+l+m+ot[h]+r[h]>>>0,S=j(a,2)^j(a,13)^j(a,22),M=a&u^a&p^u&p,w=S+M>>>0;b=y,y=c,c=f,f=d+g>>>0,d=p,p=u,u=a,a=g+w>>>0}o[0]=o[0]+a>>>0,o[1]=o[1]+u>>>0,o[2]=o[2]+p>>>0,o[3]=o[3]+d>>>0,o[4]=o[4]+f>>>0,o[5]=o[5]+c>>>0,o[6]=o[6]+y>>>0,o[7]=o[7]+b>>>0}return o.map(s=>s.toString(16).padStart(8,"0")).join("")}function j(e,t){return e>>>t|e<<32-t}const st="fps.plugin.materials";function ct(e){const t=e?.[st];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 lt(n),de(n)}function ue(e){return ie([...oe,...e?.shaders.map(t=>t.definition)??[]])}function lt(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.");ue(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"||!W(o.vertexSourcePath)||!W(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(U(o.vertexSource)!==o.vertexSourceHash||U(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(it(t)!==e.snapshotId)throw new Error("Materials Plugin snapshot payload does not match its identity. Run fps-editor-prepare again.")}function W(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 ut(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=`${gt(i.shaderId)}-${t+=1}`;if(!s.Effect?.ShadersStore||!s.ShaderMaterial||!s.StandardMaterial||!s.Color3)throw new Error(`Babylon ShaderMaterial is unavailable for ${i.shaderId}.`);Z(i,r.definitionVersion),s.Effect.ShadersStore[`${a}VertexShader`]=o.vertexSource,s.Effect.ShadersStore[`${a}FragmentShader`]=o.fragmentSource;const u=i.inspector.fields.filter(l=>l.updateClass==="uniform").map(l=>l.binding),p=[...new Set(["world","worldViewProjection",...o.frame.timeUniform?[o.frame.timeUniform]:[],...o.frame.cameraPositionUniform?[o.frame.cameraPositionUniform]:[],...u])];let d;try{d=new s.ShaderMaterial(a,r.scene,{vertex:a,fragment:a},{attributes:o.attributes,uniforms:p,needAlphaBlending:o.alphaMode!=="opaque"}),d.backFaceCulling=o.alphaMode==="opaque",d.alphaMode=o.alphaMode==="add"?s.Constants.ALPHA_ADD:o.alphaMode==="combine"?s.Constants.ALPHA_COMBINE:s.Constants.ALPHA_DISABLE,Y(s,d,i,o,r.properties)}catch(l){throw delete s.Effect.ShadersStore[`${a}VertexShader`],delete s.Effect.ShadersStore[`${a}FragmentShader`],d?.dispose?.(),l}const f=dt(s,r.scene,a),c={material:d,mesh:r.mesh,setMaterial:r.setMaterial,placeholder:f,compiled:!1,disposed:!1,failed:!1,failure:null,compilation:null,invalidateFrameParticipant:null,shaderName:a,shadersStore:s.Effect.ShadersStore};n.set(f,c),n.set(d,c);const y=()=>{c.disposed||c.failed||c.compiled||(c.compiled=!0,c.setMaterial(c.material),ft(c.mesh))},b=l=>{c.disposed||c.failed||(c.failed=!0,c.failure=l,c.invalidateFrameParticipant?.(),c.setMaterial(c.placeholder),pt(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)}))};d.onCompiled=()=>{queueMicrotask(()=>{y()})},d.onError=(l,m)=>{b(m)};try{if(typeof d.forceCompilationAsync!="function")throw new Error("Babylon ShaderMaterial.forceCompilationAsync() is unavailable.");c.compilation=Promise.resolve(d.forceCompilationAsync(c.mesh)).then(()=>{if(c.failed)throw c.failure;y()}).catch(l=>{throw b(l),l})}catch(l){b(l),c.compilation=Promise.reject(l)}c.compilation.catch(()=>{}),f.forceCompilationAsync=()=>c.compilation;const h=f.dispose.bind(f);return f.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))},f},updateMaterial(r){const s=r.babylon,a=Q(r.material)?n.get(r.material):void 0;return!a||a.disposed||a.failed?!1:(Z(i,r.definitionVersion),Y(s,a.material,i,o,r.properties),!0)},...o.frame.mode==="continuous"?{createFrameParticipant(r){const s=r.babylon,a=Q(r.material)?n.get(r.material):void 0;if(!a)throw new Error(`ShaderMaterial state is unavailable for ${i.shaderId}.`);let u=!1;const p=new Set;return a.invalidateFrameParticipant=()=>{for(const d of[...p])d()},{frameMode:"continuous",resolveFrameMode(){return a.failed||a.disposed||u?"on-demand":"continuous"},isActive(){return!a.failed&&!a.disposed&&!u},onFrameModeChanged(d){return p.add(d),()=>p.delete(d)},updateFrame(d){if(!(a.failed||a.disposed||u)&&(o.frame.timeUniform&&a.material.setFloat(o.frame.timeUniform,d.elapsedSeconds),o.frame.cameraPositionUniform)){const f=r.scene.activeCamera;a.material.setVector3(o.frame.cameraPositionUniform,f?.globalPosition??f?.position??s.Vector3.Zero())}},dispose(){u||(u=!0,p.clear(),a.invalidateFrameParticipant&&(a.invalidateFrameParticipant=null))}}}}:{}})))}function Z(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 pt(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 ft(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 Y(e,t,n,i,o){for(const r of n.inspector.fields){if(r.updateClass!=="uniform")continue;const s=ht(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],u=typeof s=="string"?a?.[s]:void 0;if(!Number.isFinite(u))throw new Error(`Enum uniform value is not mapped: ${r.path}=${String(s)}`);t.setFloat(r.binding,u)}else if(r.control==="color"){const a=k(s,r.path);mt(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=k(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=k(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 mt(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 ht(e,t){let n=e;for(const i of t.split(".").filter(Boolean)){if(!C(n))return;n=n[i]}return n}function k(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 gt(e){return e.replace(/[^a-z0-9_-]/gi,"_")}function Q(e){return!!e&&typeof e=="object"}function C(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}const pe=window.__FPS_EDITOR_PROJECT_DEFINITION__;if(!pe)throw new Error("Editor Project definition was not provided by the control plane.");const z=ct(window.__FPS_EDITOR_PLUGIN_SNAPSHOTS__),bt=ue(z),X=z?ut(z):void 0,ee=()=>{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."}},yt=await qe({container:document.body,projectDefinition:pe,agentDocumentSave:window.__FPS_EDITOR_CONFIG__?.agentDocumentSave,runtimeAssetBaseUrl:window.location.origin,projectIOAvailability:{getAvailability:ee,subscribeAvailability(e){const t=()=>e(ee());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:bt,...X?{materialProjectionAdapters:X}:{}});window.addEventListener("pagehide",()=>void yt.dispose(),{once:!0});
1
+ import{fI as fe,fH as me,a5 as he,ex as ge,mE as be,j0 as ye,fz as we,cd as Se,jV as Ie,h$ as Me}from"./playable-standard-project-X3XQewnw.js";import{registerFpsEditorContribution as Ee}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 _e="0.2.3-beta.21",te="fps.plugin.hierarchy";function je(){return fe({id:te,version:_e,apiVersion:1,requires:{},provides:{features:["fps.editor.hierarchy"]},entries:{editor:"./editor"},environmentContracts:{editor:{requires:{services:["fps.editor.contributions"]},provides:{}}},deploymentConstraints:{allowedTargets:["editor"]}})}const Ae=me({pluginId:te,environment:"editor",register(e){Ee(e,{id:he,kind:"hierarchy",value:ge()})}}),xe=1e3,Pe=5e3,ve="Project I/O health request failed.";function Oe(e){const t=Fe(e.endpointBase),n=q(e.pollIntervalMs,xe),i=q(e.requestTimeoutMs,Pe);let o=Ce(e.initial),r=!1,s=null,a=null;const u=new Set,p=c=>{if(!Te(o,c)){o=c;for(const y of u)y(c)}},d=()=>{r||(s=e.ownerWindow.setTimeout(f,n))},f=async()=>{if(s=null,r)return;const c=new AbortController;a=c;const y=e.ownerWindow.setTimeout(()=>c.abort(),i);try{const b=await e.fetchJson(`${t}/health`,{cache:"no-store",signal:c.signal});p($e(b))}catch{r||p(Object.freeze({ready:!1,generation:o.generation,reason:ve}))}finally{e.ownerWindow.clearTimeout(y),a===c&&(a=null),d()}};return d(),Object.freeze({availability:Object.freeze({getAvailability:()=>o,subscribeAvailability(c){return r?()=>{}:(u.add(c),()=>u.delete(c))}}),stop(){r||(r=!0,s!==null&&e.ownerWindow.clearTimeout(s),s=null,a?.abort(),a=null,u.clear())}})}function $e(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 Ce(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 Te(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 q(e,t){return Number.isSafeInteger(e)&&e>0?e:t}const R=new WeakMap;function Re(e,t,n,i,o){const r=o??i.__FPS_EDITOR_RUNTIME_TUNING__;if(!r||r.projectId!==e)return()=>{};const s=R.get(i)??new Map,a=s.get(e),u=a?.consumerId??i.crypto?.randomUUID?.()??`browser_${Date.now().toString(36)}_${Math.random().toString(36).slice(2)}`;a?.stop(),R.set(i,s);let p=!1;const d=new AbortController,f=async()=>{for(;!p;)try{const y=await i.fetch(`${r.endpointBase}/consumer/poll`,{method:"POST",headers:{"x-fps-editor-runtime-tuning-token":r.token,"x-fps-editor-runtime-tuning-consumer":u},cache:"no-store",signal:d.signal}),b=await y.json().catch(()=>null);if(!y.ok||!b||typeof b.requestId!="string"){p||await H(i,500);continue}const h=await ke(e,t,b.intent,n);await i.fetch(`${r.endpointBase}/consumer/result`,{method:"POST",headers:{"content-type":"application/json","x-fps-editor-runtime-tuning-token":r.token,"x-fps-editor-runtime-tuning-consumer":u},body:JSON.stringify({requestId:b.requestId,result:h}),cache:"no-store",signal:d.signal})}catch{p||await H(i,750)}},c=()=>{p||(p=!0,d.abort(),s.get(e)?.stop===c&&(s.delete(e),s.size===0&&R.delete(i)))};return s.set(e,{consumerId:u,stop:c}),f(),c}async function ke(e,t,n,i){const o=Ue(n,e);if(!o)return{ok:!1,code:"runtime_tuning_invalid_intent",message:"调参请求不符合 Camera/Light 固定字段。"};const r=i?.()??null;if(i&&!De(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(u=>({objectId:u.targetId,changes:Object.entries(Ne(u,r)).map(([p,d])=>({path:p,value:d}))}))}})}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:V(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:V(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:Be(a.output)}}function Ne(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 De(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 Ue(e,t){if(!e||typeof e!="object"||Array.isArray(e))return null;const n=e;if(!N(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 u=a;if(!N(u,["role","targetId","sourceId","changes"]))return null;const p=typeof u.role=="string"?u.role:"";if(!o.has(p)||r.has(p))return null;r.add(p);const d=typeof u.targetId=="string"?u.targetId.trim():"",f=typeof u.sourceId=="string"?u.sourceId.trim():"";if(!d||!f||!u.changes||typeof u.changes!="object"||Array.isArray(u.changes))return null;const c=Object.entries(u.changes);return c.length>0&&c.length<=24&&c.every(([y,b])=>Le(p,y,b))?{role:p,targetId:d,sourceId:f,changes:Object.fromEntries(c)}:null});return r.size===o.size&&s.every(a=>a!==null)?{projectId:t,kind:n.kind,targets:s}:null}const ze=new Set(["camera.alpha","camera.beta","camera.radius","camera.orthoSize","camera.fov","camera.minZ","camera.maxZ","camera.inertia"]);function Le(e,t,n){return e==="camera"?t==="camera.projection"?n==="orthographic"||n==="perspective":t==="camera.targetOffset"?F(n,["x","y","z"]):t==="camera.targetScreenOffset"?F(n,["x","y"]):ze.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")&&F(n,["r","g","b"]):e==="directional-light"?t==="enabled"?typeof n=="boolean":t==="light.intensity"?typeof n=="number"&&Number.isFinite(n):t==="light.diffuseColor"?F(n,["r","g","b"]):t==="transform.rotation"&&F(n,["x","y","z"]):!1}function F(e,t){if(!e||typeof e!="object"||Array.isArray(e))return!1;const n=e;return N(n,t)&&t.every(i=>typeof n[i]=="number"&&Number.isFinite(n[i]))}function N(e,t){const n=new Set(t);return Object.keys(e).every(i=>n.has(i))}function Be(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 V(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 H(e,t){return new Promise(n=>e.setTimeout(n,t))}async function qe(e){let t=null,n=!1,i=Promise.resolve(),o=null;const r=e.container.ownerDocument,s=r.defaultView??window;let a=null,u=null;if(!e.projectIOAvailability&&e.projectIOInitialAvailability&&e.authoringEndpointBase){const l=e.authoringFetchJson??(async(m,g)=>{const S=await s.fetch(m,g),M=await S.json().catch(()=>null);if(!S.ok)throw new Error(`Project I/O health request failed (${S.status}).`);return M});a=Oe({endpointBase:e.authoringEndpointBase,initial:e.projectIOInitialAvailability,ownerWindow:s,fetchJson:l})}const p=e.projectIOAvailability??a?.availability,d=r.createElement("canvas");d.id="renderCanvas",d.style.cssText="display:block;width:100%;height:100%;touch-action:none;outline:none";const f=()=>{u?.(),u=null,o?.(),o=null,d.remove()},c=l=>{const m=i.then(l,l);return i=m.catch(()=>{}),m},y=()=>{const l=t?.getHost()?.harness.getBrowserAuthoringApi();if(!l)throw new Error("Browser Editor API is unavailable.");return l},b=async(l,m)=>{const g=t?.getHost();if(!g)throw new Error("Editor host is unavailable for asset import.");const S=m?g.harness.projectAssetDropPoint({space:"scene-view-normalized",x:m.x,y:m.y}):null,M=l.objectId??we([],`${l.assetName??l.projectAssetId??"asset"}_${Se()}`),w=await g.harness.executeBrowserAuthoringCapability({capabilityId:"asset.importAndPlace",input:{...l,objectId:M,...S?{position:S}:{}}});if(w.outcome!=="applied"&&w.outcome!=="no-op")throw new Error(w.diagnostics[0]?.message??"Browser asset import and placement failed.")};async function h(){if(n)return;let l=null;try{const m=be(e.projectDefinition);o?.(),o=Ve(s,e.runtimeAssetBaseUrl),d.parentNode!==e.container&&e.container.appendChild(d);const g=je(),S=Object.freeze({environment:"editor",buildTarget:"editor",manifests:Object.freeze([g]),entries:Object.freeze([{pluginId:g.id,config:null,load:async()=>Ae}]),pluginConfigs:Object.freeze({...Object.fromEntries(m.plugins.map(w=>[w.pluginId,w.config])),[g.id]:null})});if(l=await ye(m.project,{root:e.container,window:s,authoringEndpointBase:e.authoringEndpointBase,authoringFetchJson:e.authoringFetchJson,projectIOAvailability:p,...e.agentDocumentSave?{agentDocumentSave:e.agentDocumentSave}:{},projectIO:e.projectIO,onExternalAssetDrop:e.onExternalAssetDrop?async w=>{const T=await e.onExternalAssetDrop?.(w);T&&await b(T,{x:w.point.sceneX,y:w.point.sceneY})}:void 0,projectMode:{async enterEditorMode(){},...e.onEnterPlayMode?{enterPlayMode:e.onEnterPlayMode}:{}},pluginModule:S,getCanvas:()=>d,...e.materialShaderDefinitions?{materialShaderDefinitions:e.materialShaderDefinitions}:{},...e.materialProjectionAdapters?{materialProjectionAdapters:e.materialProjectionAdapters}:{}}),n){await l.dispose(),f();return}t=l,await l.enterEditor(),u=Re(m.project.projectId,w=>l.getHost().harness.executeBrowserAuthoringCapability(w),()=>l?.getHost()?.harness.getWorkingDocument()??null,s,e.runtimeTuning);const M=s.__FPS_EDITOR_SYSTEM_FUNCTIONAL_REGISTER__;typeof M=="function"&&M(Object.freeze({readDraft(){const w=t?.getHost()?.harness,T=w?.getWorkingDocument(),L=w?.getPersistedDocument(),B=w?.getDocumentState();return T&&L&&B?Object.freeze({summary:B,workingDocument:T,persistedDocument:L}):null}}))}catch(m){t===l&&(t=null);let g=null;try{await l?.dispose()}catch(S){g=S}finally{f()}if(g){const S=g instanceof Error?g.message:String(g),M=new Error(`Editor mount failed and cleanup also failed: ${S}`);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:y,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,u?.(),u=null;try{await l?.dispose()}finally{f()}await h()})},async importAsset({point:l,...m}){await b(m,l)},dispose(){return n=!0,a?.stop(),a=null,c(async()=>{s.__FPS_EDITOR_SYSTEM_FUNCTIONAL_REGISTER__?.(null);const l=t;t=null,u?.(),u=null;try{await l?.dispose()}finally{f()}})}}}function Ve(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"},G={kind:"color"},He={kind:"enum",values:["lit","unlit"]},Ge={kind:"enum",values:["opaque","mask","blend"]},re={lightingModel:He,baseColor:{kind:"object",properties:{color:G,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:G,intensity:E(0),texture:A,maskTexture:A}},alpha:{kind:"object",properties:{mode:Ge,opacity:E(0,1),cutoff:E(0,1),texture:A}}},Ke={kind:"object",properties:{...re,metallic:E(0,1),roughness:E(0,1),metallicRoughness:{kind:"object",properties:{texture:A}},occlusion:{kind:"object",properties:{texture:A,strength:E(0)}}}},Je={kind:"object",properties:re},We={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}},Ze={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}},K=[{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"},ne=[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"}])],Ye=[...ne,_("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")]})],oe=[{shaderId:"fps.builtin.pbr",version:1,runtimeKind:"pbr",displayName:"PBR",propertiesSchema:Ke,defaultProperties:We,inspector:{sections:K,fields:Ye}},{shaderId:"fps.builtin.standard",version:1,runtimeKind:"standard",displayName:"Standard",propertiesSchema:Je,defaultProperties:Ze,inspector:{sections:K,fields:ne}}];ie(oe);function ie(e){const t=new Map;for(const i of e){Qe(i,t);const o=Xe(i);t.set(i.shaderId,le(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 Qe(e,t){if(!Ie(e.shaderId)&&!Me(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&&!tt(e.sourceFile))throw new Error(`Material Shader Definition ${e.shaderId} sourceFile must be a safe project-relative path.`);ae(e.shaderId,e.propertiesSchema,"properties");const n=[];if(ce(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.`);et(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=se(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 et(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=se(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 ae(e,t,n){if(t.kind==="object"){for(const[i,o]of Object.entries(t.properties))ae(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 tt(e){const t=e.trim();return!t||t.startsWith("/")||t.includes("\\")||t.includes(":")?!1:!t.split("/").includes("..")}function rt(e){const t=e.trim();return t.startsWith("properties.")?t:`properties.${t}`}function se(e,t){const n=rt(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 ce(e,t,n,i){if(e.kind==="object"){if(!D(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&&ce(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"];J(t,n,r,i,e.channels===4?"an RGBA object":"an RGB object");return}if(e.kind==="vec2"||e.kind==="vec3"){J(t,n,e.kind==="vec2"?["x","y"]:["x","y","z"],i,`a ${e.kind} object`);return}if(t===null)return;if(!D(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 J(e,t,n,i,o){if(!D(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 le(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){Object.freeze(e);for(const t of Object.values(e))le(t)}return e}function D(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}const nt=Object.freeze([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),ot=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 U(e){return at(new TextEncoder().encode(e))}function it(e){return`sha256:${U(JSON.stringify(e))}`}function at(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=[...nt],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,S=j(m,17)^j(m,19)^m>>>10;r[h]=r[h-16]+g+r[h-7]+S>>>0}let[a,u,p,d,f,c,y,b]=o;for(let h=0;h<64;h+=1){const l=j(f,6)^j(f,11)^j(f,25),m=f&c^~f&y,g=b+l+m+ot[h]+r[h]>>>0,S=j(a,2)^j(a,13)^j(a,22),M=a&u^a&p^u&p,w=S+M>>>0;b=y,y=c,c=f,f=d+g>>>0,d=p,p=u,u=a,a=g+w>>>0}o[0]=o[0]+a>>>0,o[1]=o[1]+u>>>0,o[2]=o[2]+p>>>0,o[3]=o[3]+d>>>0,o[4]=o[4]+f>>>0,o[5]=o[5]+c>>>0,o[6]=o[6]+y>>>0,o[7]=o[7]+b>>>0}return o.map(s=>s.toString(16).padStart(8,"0")).join("")}function j(e,t){return e>>>t|e<<32-t}const st="fps.plugin.materials";function ct(e){const t=e?.[st];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 lt(n),de(n)}function ue(e){return ie([...oe,...e?.shaders.map(t=>t.definition)??[]])}function lt(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.");ue(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"||!W(o.vertexSourcePath)||!W(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(U(o.vertexSource)!==o.vertexSourceHash||U(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(it(t)!==e.snapshotId)throw new Error("Materials Plugin snapshot payload does not match its identity. Run fps-editor-prepare again.")}function W(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 ut(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=`${gt(i.shaderId)}-${t+=1}`;if(!s.Effect?.ShadersStore||!s.ShaderMaterial||!s.StandardMaterial||!s.Color3)throw new Error(`Babylon ShaderMaterial is unavailable for ${i.shaderId}.`);Z(i,r.definitionVersion),s.Effect.ShadersStore[`${a}VertexShader`]=o.vertexSource,s.Effect.ShadersStore[`${a}FragmentShader`]=o.fragmentSource;const u=i.inspector.fields.filter(l=>l.updateClass==="uniform").map(l=>l.binding),p=[...new Set(["world","worldViewProjection",...o.frame.timeUniform?[o.frame.timeUniform]:[],...o.frame.cameraPositionUniform?[o.frame.cameraPositionUniform]:[],...u])];let d;try{d=new s.ShaderMaterial(a,r.scene,{vertex:a,fragment:a},{attributes:o.attributes,uniforms:p,needAlphaBlending:o.alphaMode!=="opaque"}),d.backFaceCulling=o.alphaMode==="opaque",d.alphaMode=o.alphaMode==="add"?s.Constants.ALPHA_ADD:o.alphaMode==="combine"?s.Constants.ALPHA_COMBINE:s.Constants.ALPHA_DISABLE,Y(s,d,i,o,r.properties)}catch(l){throw delete s.Effect.ShadersStore[`${a}VertexShader`],delete s.Effect.ShadersStore[`${a}FragmentShader`],d?.dispose?.(),l}const f=dt(s,r.scene,a),c={material:d,mesh:r.mesh,setMaterial:r.setMaterial,placeholder:f,compiled:!1,disposed:!1,failed:!1,failure:null,compilation:null,invalidateFrameParticipant:null,shaderName:a,shadersStore:s.Effect.ShadersStore};n.set(f,c),n.set(d,c);const y=()=>{c.disposed||c.failed||c.compiled||(c.compiled=!0,c.setMaterial(c.material),ft(c.mesh))},b=l=>{c.disposed||c.failed||(c.failed=!0,c.failure=l,c.invalidateFrameParticipant?.(),c.setMaterial(c.placeholder),pt(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)}))};d.onCompiled=()=>{queueMicrotask(()=>{y()})},d.onError=(l,m)=>{b(m)};try{if(typeof d.forceCompilationAsync!="function")throw new Error("Babylon ShaderMaterial.forceCompilationAsync() is unavailable.");c.compilation=Promise.resolve(d.forceCompilationAsync(c.mesh)).then(()=>{if(c.failed)throw c.failure;y()}).catch(l=>{throw b(l),l})}catch(l){b(l),c.compilation=Promise.reject(l)}c.compilation.catch(()=>{}),f.forceCompilationAsync=()=>c.compilation;const h=f.dispose.bind(f);return f.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))},f},updateMaterial(r){const s=r.babylon,a=Q(r.material)?n.get(r.material):void 0;return!a||a.disposed||a.failed?!1:(Z(i,r.definitionVersion),Y(s,a.material,i,o,r.properties),!0)},...o.frame.mode==="continuous"?{createFrameParticipant(r){const s=r.babylon,a=Q(r.material)?n.get(r.material):void 0;if(!a)throw new Error(`ShaderMaterial state is unavailable for ${i.shaderId}.`);let u=!1;const p=new Set;return a.invalidateFrameParticipant=()=>{for(const d of[...p])d()},{frameMode:"continuous",resolveFrameMode(){return a.failed||a.disposed||u?"on-demand":"continuous"},isActive(){return!a.failed&&!a.disposed&&!u},onFrameModeChanged(d){return p.add(d),()=>p.delete(d)},updateFrame(d){if(!(a.failed||a.disposed||u)&&(o.frame.timeUniform&&a.material.setFloat(o.frame.timeUniform,d.elapsedSeconds),o.frame.cameraPositionUniform)){const f=r.scene.activeCamera;a.material.setVector3(o.frame.cameraPositionUniform,f?.globalPosition??f?.position??s.Vector3.Zero())}},dispose(){u||(u=!0,p.clear(),a.invalidateFrameParticipant&&(a.invalidateFrameParticipant=null))}}}}:{}})))}function Z(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 pt(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 ft(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 Y(e,t,n,i,o){for(const r of n.inspector.fields){if(r.updateClass!=="uniform")continue;const s=ht(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],u=typeof s=="string"?a?.[s]:void 0;if(!Number.isFinite(u))throw new Error(`Enum uniform value is not mapped: ${r.path}=${String(s)}`);t.setFloat(r.binding,u)}else if(r.control==="color"){const a=k(s,r.path);mt(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=k(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=k(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 mt(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 ht(e,t){let n=e;for(const i of t.split(".").filter(Boolean)){if(!C(n))return;n=n[i]}return n}function k(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 gt(e){return e.replace(/[^a-z0-9_-]/gi,"_")}function Q(e){return!!e&&typeof e=="object"}function C(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}const pe=window.__FPS_EDITOR_PROJECT_DEFINITION__;if(!pe)throw new Error("Editor Project definition was not provided by the control plane.");const z=ct(window.__FPS_EDITOR_PLUGIN_SNAPSHOTS__),bt=ue(z),X=z?ut(z):void 0,ee=()=>{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."}},yt=await qe({container:document.body,projectDefinition:pe,agentDocumentSave:window.__FPS_EDITOR_CONFIG__?.agentDocumentSave,runtimeAssetBaseUrl:window.location.origin,projectIOAvailability:{getAvailability:ee,subscribeAvailability(e){const t=()=>e(ee());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:bt,...X?{materialProjectionAdapters:X}:{}});window.addEventListener("pagehide",()=>void yt.dispose(),{once:!0});