handler-playable-sdk 1.0.89 → 1.0.90
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-M4LZRZ6U.js → chunk-NHIKK74M.js} +76 -54
- package/dist/cli/brand-dna.mjs +1 -1
- package/dist/cli/canva-import.mjs +1 -1
- package/dist/cli/cleanup-assets.mjs +1 -1
- package/dist/cli/fix-scales.mjs +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/screen-helper.mjs +1 -1
- package/dist/cli/setup-library.mjs +1 -1
- package/dist/cli/student-helper/add-logic.mjs +1 -1
- package/dist/cli/student-helper/add-object.mjs +1 -1
- package/dist/cli/student-helper/arg-parsing.mjs +1 -1
- package/dist/cli/student-helper/asset-registry.mjs +1 -1
- package/dist/cli/student-helper/bullet-system.mjs +1 -1
- package/dist/cli/student-helper/collectable-system.mjs +1 -1
- package/dist/cli/student-helper/constants.mjs +1 -1
- package/dist/cli/student-helper/drag-snap-couples.mjs +1 -1
- package/dist/cli/student-helper/endgame-screen.mjs +1 -1
- package/dist/cli/student-helper/fs-io.mjs +1 -1
- package/dist/cli/student-helper/logic-defaults.mjs +1 -1
- package/dist/cli/student-helper/print-help.mjs +1 -1
- package/dist/cli/student-helper/prompts.mjs +1 -1
- package/dist/cli/student-helper/scratch-card.mjs +1 -1
- package/dist/cli/student-helper/screen-utils.mjs +1 -1
- package/dist/cli/student-helper/snippets.mjs +1 -1
- package/dist/cli/student-helper/start-screen.mjs +1 -1
- package/dist/cli/student-helper/swerve-collect.mjs +1 -1
- package/dist/cli/student-helper/tap-destroy.mjs +1 -1
- package/dist/cli/student-helper/template-packs.mjs +1 -1
- package/dist/cli/student-helper.mjs +1 -1
- package/dist/cli/sync-screens.mjs +1 -1
- package/dist/cli/validate-assets.mjs +1 -1
- package/dist/cli/validate.mjs +1 -1
- package/dist/index.cjs +141 -119
- package/dist/index.css +9 -2
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/pixi/index.cjs +37 -17
- package/dist/pixi/index.css +9 -2
- package/dist/pixi/index.js +1 -1
- package/dist/three/index.cjs +46 -26
- package/dist/three/index.css +9 -2
- package/dist/three/index.js +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var no=Object.create;var ni=Object.defineProperty;var ao=Object.getOwnPropertyDescriptor;var so=Object.getOwnPropertyNames;var ro=Object.getPrototypeOf,oo=Object.prototype.hasOwnProperty;var be=(s,e)=>()=>(s&&(e=s(s=0)),e);var at=(s,e)=>{for(var t in e)ni(s,t,{get:e[t],enumerable:!0})},Ja=(s,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of so(e))!oo.call(s,n)&&n!==t&&ni(s,n,{get:()=>e[n],enumerable:!(i=ao(e,n))||i.enumerable});return s};var st=(s,e,t)=>(t=s!=null?no(ro(s)):{},Ja(e||!s||!s.__esModule?ni(t,"default",{value:s,enumerable:!0}):t,s)),lo=s=>Ja(ni({},"__esModule",{value:!0}),s);var ce,oi=be(()=>{"use strict";ce=class{static get(e){var t;return(t=this.store.get(e))==null?void 0:t.data}static set(e,t){this.store.set(e,{data:t})}static has(e){return this.store.has(e)}static clear(){this.store.clear()}};ce.store=new Map});function bo(){var s,e;try{let t=typeof window!="undefined"&&(document.querySelector('script[src*="inline-assets.js"]')||((e=(s=document.querySelector("script"))==null?void 0:s.textContent)==null?void 0:e.includes("inline-assets.js"))||window.INLINE_ASSETS),i=typeof window!="undefined"&&document.querySelector('link[href*="assets/"], script[src*="assets/"]');return!!(t&&!i)}catch{return!1}}async function yo(){try{if(typeof window!="undefined"){let s=await fetch("./build-settings.json");if(s.ok){let e=await s.json();return console.log("[AssetLoader] Loaded build settings:",e),e}}}catch{}return null}function vo(){try{if(typeof window!="undefined"){let s=new XMLHttpRequest;if(s.open("GET","./build-settings.json",!1),s.send(),s.status===200&&s.responseText){let e=JSON.parse(s.responseText);return console.log("[AssetLoader] Loaded build settings (sync):",e),e}}}catch{}return null}async function wo(){if(console.log(`[AssetLoader] getInlineAssets() called - Effective mode: ${Y}`),Object.keys(Ce).length>0)return console.log("[AssetLoader] Returning cached inline assets:",Object.keys(Ce)),Ce;if(typeof window!="undefined"&&window.INLINE_ASSETS)return console.log("[AssetLoader] Using pre-loaded INLINE_ASSETS from window:",Object.keys(window.INLINE_ASSETS)),Ce={...window.INLINE_ASSETS},Ce;if(!(Y==="publish"&&ye!==!1))return console.log("[AssetLoader] Inline assets disabled for this build mode."),Ce;if(!jn){let e=typeof window!="undefined"?new URL("inline-assets.js",window.location.href).href:"./inline-assets.js";console.log("[AssetLoader] Loading inline assets from:",e),jn=(async()=>{try{try{let a=await import(e+"?t="+Date.now());if(a.INLINE_ASSETS)return console.log("[AssetLoader] Loaded INLINE_ASSETS via ES module:",Object.keys(a.INLINE_ASSETS)),a.INLINE_ASSETS}catch(a){console.warn("[AssetLoader] ES module import failed, trying text parse:",a)}let t=await fetch(e);if(!t.ok)throw new Error(`HTTP ${t.status}: ${t.statusText}`);let i=await t.text();console.log("[AssetLoader] Received JS code, length:",i.length);let n=i.match(/export\s+const\s+INLINE_ASSETS\s*=\s*({[\s\S]*?});?\s*$/m);if(n)try{let a=n[1];console.log("[AssetLoader] Found INLINE_ASSETS export, parsing...");let r=new Function("return "+a)();return console.log("[AssetLoader] Parsed inline assets:",Object.keys(r)),r}catch(a){return console.warn("[AssetLoader] Failed to parse inline assets:",a),{}}else return console.warn("[AssetLoader] INLINE_ASSETS export not found in response"),console.log("[AssetLoader] JS code preview:",i.substring(0,500)),{}}catch(t){return console.warn("[AssetLoader] Failed to load inline assets:",t),{}}})()}return Ce=await jn,console.log("[AssetLoader] Final inline assets cache:",Object.keys(Ce)),Ce}function _n(s){return s===null||typeof s!="object"||(Object.freeze(s),Object.values(s).forEach(e=>_n(e))),s}function xo(s=64,e=64,t=16711680){let i=document.createElement("canvas");i.width=s,i.height=e;let n=i.getContext("2d");return n.fillStyle=`#${t.toString(16).padStart(6,"0")}`,n.fillRect(0,0,s,e),n.strokeStyle="#000",n.strokeRect(0,0,s,e),n.fillStyle="#fff",n.font="10px sans-serif",n.textAlign="center",n.fillText("MISSING",s/2,e/2),Ae.Texture.from(i)}function On(s,e){Ps.set(s,e)}var Ae,ks,Is,Ve,Y,ye,Re,Ce,jn,Ps,Ye,li=be(()=>{"use strict";Ae=require("pixi.js");oi();ks=typeof __BUILD_MODE__!="undefined"?__BUILD_MODE__:"undefined",Is=bo(),Ve=typeof window!="undefined"?window.__BUILD_SETTINGS__:null,Y=Is?"publish":ks,ye=Ve==null?void 0:Ve.assetsInlined;Ve!=null&&Ve.buildMode&&(Y=Ve.buildMode,console.log(`[AssetLoader] Build mode overridden by inline settings: ${Y}`));Re=vo();Re!=null&&Re.buildMode&&(Y=Re.buildMode,console.log(`[AssetLoader] Build mode overridden by sync settings: ${Y}`));(Re==null?void 0:Re.assetsInlined)!==void 0&&(ye=Re.assetsInlined);yo().then(s=>{s!=null&&s.buildMode&&s.buildMode!==Y&&(Y=s.buildMode,console.log(`[AssetLoader] Build mode overridden by settings: ${Y}`)),(s==null?void 0:s.assetsInlined)!==void 0&&(ye=s.assetsInlined)}).catch(()=>{});console.log(`[AssetLoader] MODULE LOADED - Compile: ${ks}, Runtime: ${Is?"publish":"dev"}, Effective: ${Y}`);Ce={},jn=null;Ps=new Map;Ye=class{static async load(e,t,i,n){let a=`${e}:${t.path}`,r=ce.get(a);if(r!==void 0)return r;console.log(`[AssetLoader] Loading asset: ${e}, type: ${t.type}, Effective mode: ${Y}`),console.log(`[AssetLoader] Window defined: ${typeof window!="undefined"}, INLINE_ASSETS exists: ${!!(typeof window!="undefined"&&window.INLINE_ASSETS)}, keys: ${typeof window!="undefined"&&window.INLINE_ASSETS?Object.keys(window.INLINE_ASSETS).length:"N/A"}`);let o=await wo(),l=o[e];if(!l&&n&&(l=o[n],l&&console.log(`[AssetLoader] Found inline data for ${e} using configId: ${n}`)),!l&&t.path){let p=t.path.split("/");if(p.length>=2){let u=p[p.length-1].split(".")[0];o[u]&&(l=o[u],console.log(`[AssetLoader] Found inline data for ${e} using assetName: ${u}`))}}if(console.log("[AssetLoader] Inline data for",e,":",l?"FOUND":"NOT FOUND"),Y==="publish"&&ye!==!1&&(console.log("[AssetLoader] \u26A0\uFE0F PUBLISH MODE DETECTED - inline assets are MANDATORY"),!l))throw new Error(`[AssetLoader] PUBLISH MODE: Inline asset required but NOT FOUND for object: ${e}, path: ${t.path}`);let d=Ps.get(t.type);if(d)try{let p=await d(t.path,l,e,i);return ce.set(a,p),p}catch(p){return this.handleFailure(e,t.type,p)}try{let p;switch(t.type){case"image":p=await this.loadImage(t.path,l);break;case"json":p=await this.loadJSON(t.path,l),p=_n(p);break;default:throw new Error(`Unknown asset type: ${t.type}`)}return ce.set(a,p),p}catch(p){return this.handleFailure(e,t.type,p)}}static async loadImage(e,t){let i=Y==="publish",n=i&&ye!==!1;if(console.log(`[AssetLoader] loadImage - Effective mode: ${Y}, isPublishMode: ${i}, inlineData: ${t?"EXISTS":"MISSING"}`),n){if(console.log("[AssetLoader] PUBLISH MODE ACTIVATED - inline assets are MANDATORY"),!t)throw new Error(`[AssetLoader] Publish mode: inline asset required but not found for object. Path: ${e}`);if(typeof t!="string"||!t.startsWith("data:"))throw new Error(`[AssetLoader] Publish mode: inline asset must be data URI string, got: ${typeof t}`);try{return await Ae.Assets.load(t)}catch(a){throw console.error("[AssetLoader] Failed to load texture from data URI:",a),a}}if(t&&typeof t=="string"&&t.startsWith("data:"))try{return await Ae.Assets.load(t)}catch(a){return console.error("[AssetLoader] Failed to load texture from data URI, falling back to path:",a),await Ae.Assets.load(e)}return await Ae.Assets.load(e)}static async loadJSON(e,t){let i=Y==="publish",n=i&&ye!==!1;if(console.log(`[AssetLoader] loadJSON - Effective mode: ${Y}, isPublishMode: ${i}, inlineData: ${t?"EXISTS":"MISSING"}`),n){if(console.log("[AssetLoader] PUBLISH MODE ACTIVATED - inline assets are MANDATORY"),!t)throw new Error(`[AssetLoader] Publish mode: inline asset required but not found for path: ${e}`);if(typeof t=="object"&&t!==null)return t;if(typeof t=="string"&&t.startsWith("data:")){let r=atob(t.split(",")[1]);return JSON.parse(r)}return JSON.parse(t)}if(t){if(typeof t=="object"&&t!==null)return t;if(typeof t=="string"&&t.startsWith("data:")){let r=atob(t.split(",")[1]);return JSON.parse(r)}return JSON.parse(t)}let a=await fetch(e);if(!a.ok)throw new Error(`JSON fetch failed: ${e}`);return a.json()}static handleFailure(e,t,i){if(Y==="dev"){let a=t==="image"?xo():_n({__placeholder:!0,type:t});return ce.set(e+":"+((i==null?void 0:i.path)||"missing"),a),a}throw i}};On("image",async(s,e)=>{let t=Y==="publish",i=t&&ye!==!1,n=Y==="brand",a=t&&ye===!1;if(console.log(`[AssetLoader] registerType('image') - Effective mode: ${Y}, isPublishMode: ${t}, isBrandMode: ${n}, inlineData: ${e?"EXISTS":"MISSING"}`),i){if(console.log("[AssetLoader] PUBLISH MODE ACTIVATED - inline assets are MANDATORY"),!e)throw new Error(`[AssetLoader] Publish mode: inline asset required but not found for path: ${s}`);if(typeof e!="string"||!e.startsWith("data:"))throw new Error(`[AssetLoader] Publish mode: inline asset must be data URI string, got: ${typeof e}`);return Ae.Assets.load(e)}let r=s;return(n||a)&&s&&!s.startsWith("assets/")&&(typeof window!="undefined"&&!document.querySelector('link[href*="assets/"], script[src*="assets/"]')&&!document.querySelector('link[href*="configs/"], script[src*="configs/"]')?(r=s,console.log(`[AssetLoader] BRAND MODE: flattened build, using path "${s}" as-is`)):(r=`assets/${s}`,console.log(`[AssetLoader] BRAND MODE: transformed path "${s}" -> "${r}"`))),Ae.Assets.load(e||r)});On("json",async(s,e)=>{let t=Y==="publish",i=t&&ye!==!1,n=Y==="brand",a=t&&ye===!1;if(console.log(`[AssetLoader] registerType('json') - Effective mode: ${Y}, isPublishMode: ${t}, isBrandMode: ${n}, inlineData: ${e?"EXISTS":"MISSING"}`),i){if(console.log("[AssetLoader] PUBLISH MODE ACTIVATED - inline assets are MANDATORY"),!e)throw new Error(`[AssetLoader] Publish mode: inline asset required but not found for path: ${s}`);return typeof e=="object"&&e!==null?e:typeof e=="string"&&e.startsWith("data:")?JSON.parse(atob(e.split(",")[1])):JSON.parse(e)}let r=s;if((n||a)&&s&&!s.startsWith("assets/")&&(typeof window!="undefined"&&!document.querySelector('link[href*="assets/"], script[src*="assets/"]')&&!document.querySelector('link[href*="configs/"], script[src*="configs/"]')?(r=s,console.log(`[AssetLoader] BRAND MODE: flattened build, using path "${s}" as-is`)):(r=`assets/${s}`,console.log(`[AssetLoader] BRAND MODE: transformed path "${s}" -> "${r}"`))),e)return typeof e=="object"&&e!==null?e:typeof e=="string"&&e.startsWith("data:")?JSON.parse(atob(e.split(",")[1])):JSON.parse(e);let o=await fetch(r);if(!o.ok)throw new Error(`JSON fetch failed: ${s}`);return o.json()})});var js={};at(js,{AssetTextures:()=>we,initAssetTextures:()=>$n});function $n(s,e){Ms.init(s,e),typeof window!="undefined"&&(window.__AssetTextures=we)}var zn,Ms,we,ct=be(()=>{"use strict";li();zn=class{constructor(){this.textures=new Map;this.readyPromise=null;this.priorityReadyPromise=null;this.priorityReadyResolve=null;this.config=null;this.app=null;this.attempted=new Set;this.waiters=new Set}init(e,t){if(this.config===e&&this.app===t&&this.priorityReadyPromise){console.log("[AssetTextures] init called with same config/app; keeping existing state");return}this.textures.clear(),this.readyPromise=null,this.priorityReadyPromise=null,this.priorityReadyResolve=null,this.attempted.clear(),this.waiters.clear(),this.priorityReadyPromise=new Promise(i=>{this.priorityReadyResolve=i}),this.config=e,this.app=t,console.log("[AssetTextures] Initialized with config, cleared previous textures")}async ready(){if(this.readyPromise){await this.readyPromise;return}if(!this.config)throw new Error("[AssetTextures] Must call init() before ready() - config is null");if(!this.app)throw new Error("[AssetTextures] Must call init() before ready() - app is null");let e=this.config,t=this.app;return this.readyPromise=(async()=>{var r;console.log("[AssetTextures] Loading all assets...");let i=new Set(["background_loading_1"]),n=[],a=[];for(let[o,l]of e.objects.entries()){let c=(r=l.render)==null?void 0:r.asset;if(!c)continue;let d=async()=>{var p;try{let u=(p=l.identity)==null?void 0:p.id;console.log(`[AssetTextures] Loading ${c.type}: ${o} (${u})`);let g=await Ye.load(o,c,t,u);this.textures.set(o,g),console.log(`[AssetTextures] \u2713 Loaded: ${o}`)}catch(u){console.error(`[AssetTextures] \u2717 Failed to load: ${o}`,u)}finally{this.attempted.add(o);try{for(let u of Array.from(this.waiters))u()}catch{}}};i.has(o)?n.push(d()):a.push(d())}n.length>0&&(console.log("[AssetTextures] Phase 1: Loading priority assets (loading screen)..."),await Promise.all(n),console.log("[AssetTextures] Phase 1: Priority assets ready")),this.priorityReadyResolve&&this.priorityReadyResolve(),console.log("[AssetTextures] Phase 2: Loading remaining assets..."),await Promise.all(a),console.log("[AssetTextures] All textures loaded:",Array.from(this.textures.keys()))})(),this.readyPromise}async priorityReady(){return this.priorityReadyPromise?this.priorityReadyPromise:Promise.resolve()}async waitFor(e,t={}){if(!this.config)throw new Error("[AssetTextures] Must call init() before waitFor() - config is null");if(!this.app)throw new Error("[AssetTextures] Must call init() before waitFor() - app is null");let n=Array.from(new Set((e||[]).filter(o=>typeof o=="string"&&o))).filter(o=>{var l,c,d,p;try{let u=(d=(c=(l=this.config)==null?void 0:l.objects)==null?void 0:c.get)==null?void 0:d.call(c,o);return!!((p=u==null?void 0:u.render)!=null&&p.asset)}catch{return!1}});if(n.length===0)return;this.ready().catch(()=>{});let a=()=>n.every(o=>this.textures.has(o)||this.attempted.has(o));if(a())return;let r=typeof t.timeoutMs=="number"?t.timeoutMs:15e3;await new Promise(o=>{let l=!1,c=()=>{l||a()&&(l=!0,this.waiters.delete(c),o())};this.waiters.add(c),c(),r>0&&setTimeout(()=>{l||(l=!0,this.waiters.delete(c),console.warn("[AssetTextures] waitFor timed out; continuing",{ids:n}),o())},r)})}get(e){return this.textures.get(e)}set(e,t){this.textures.set(e,t),console.log(`[AssetTextures] Updated texture: ${e}`)}clear(){this.textures.clear(),this.readyPromise=null,console.log("[AssetTextures] Cleared all textures")}getAllIds(){return Array.from(this.textures.keys())}},Ms=new zn,we=new Proxy(Ms,{get(s,e){return e in s&&typeof s[e]=="function"?s[e].bind(s):s.get(e)},set(s,e,t){return s.set(e,t),!0}})});var Ne={};at(Ne,{applyConfigOverride:()=>re,applyConfigOverrides:()=>$e,applyConfigsToDisk:()=>xi,clearConfigOverrides:()=>pe,clearConfigOverridesForObject:()=>Ds,configOverrideManager:()=>Ns,deepClone:()=>Q,exportConfigsAsJSON:()=>Xe,getConfigOverrides:()=>se,getConfigStateSummary:()=>De,getOverrideMode:()=>Rt,redoLastConfigChange:()=>wi,removeConfigOverride:()=>zt,resetToApplied:()=>$t,resetToOriginal:()=>Si,setOverrideMode:()=>qn,trackObjectCreation:()=>Hs,trackObjectDeletion:()=>Fs,undoLastConfigChange:()=>vi});function mi(){return typeof window=="undefined"?null:window.__editableConfig||null}function Bn(){return typeof window=="undefined"?null:window.__editableConfigBaseline||null}function Fn(s,e){var t,i;if(!s)return null;try{if(s instanceof Map)return(t=s.get(e))!=null?t:null;if(typeof s=="object")return(i=s[e])!=null?i:null}catch{}return null}function Wo(s,e,t){if(s){if(s instanceof Map){s.set(e,t);return}typeof s=="object"&&(s[e]=t)}}function Rs(s,e){for(let t of e)Ot(s,t.path,t.value)}function bi(s){var o;if(typeof window=="undefined")return;let e=mi();if(!e)return;let t=Bn(),i=(o=t?Fn(t.objects,s):null)!=null?o:Fn(e.objects,s);if(!i)return;let n=Q(i),a=se().filter(l=>l.objectId===s);try{Rs(n,a)}catch(l){console.error("[CONFIG] Failed to reapply overrides for object",s,l);return}Wo(e.objects,s,n);let r=window.applyEditableObjectConfig;if(typeof r=="function")try{r(s,n)}catch{}}function Gn(){var n;if(typeof window=="undefined")return;let s=mi();if(!(s!=null&&s.engine))return;let e=Bn(),t=Q(((n=e==null?void 0:e.engine)!=null?n:s.engine)||{}),i=se().filter(a=>!a.objectId&&!a.sceneId);try{Rs(t,i)}catch(a){console.error("[CONFIG] Failed to reapply engine overrides",a);return}try{let a=s.engine;for(let r of Object.keys(a))r in t||delete a[r];for(let[r,o]of Object.entries(t))a[r]=o}catch{s.engine=t}}function Ko(){if(typeof window=="undefined")return"unknown";let s=window;return typeof s.__HANDLER_PROJECT_ID=="string"?s.__HANDLER_PROJECT_ID:"handler-default"}function zs(){return`handler_preview_config_overrides::${Ko()}`}function Xo(){if(typeof window=="undefined")return[];try{let s=window.localStorage.getItem(zs());if(!s)return[];let e=JSON.parse(s);return Array.isArray(e)?e:[]}catch{return[]}}function yi(s){if(typeof window!="undefined")try{window.localStorage.setItem(zs(),JSON.stringify(s))}catch{}}function Rt(){return typeof window=="undefined"?!1:window.__enableConfigOverrides===!0}function qn(s){if(typeof window!="undefined"){window.__enableConfigOverrides=s;try{window.localStorage.setItem($s,s?"true":"false")}catch{}}}function re(s,e={}){var u,g;let{objectId:t,path:i,value:n}=s,{silent:a=!1,persist:r=!0,emitEvent:o=!0}=e,l=mi();if(!l){console.warn("[CONFIG] applyConfigOverride: No editable config found in window.__editableConfig");return}let c=t?(g=(u=l.objects)==null?void 0:u.get)==null?void 0:g.call(u,t):l.engine;if(!c){console.warn("[CONFIG] applyConfigOverride: Override target not found:",{objectId:t,path:i,hasObjects:!!l.objects});return}a||console.log("[CONFIG] applyConfigOverride: Target found, applying...",{objectId:t,path:i,value:n});let d;try{d=Bs(c,i),Ot(c,i,n)}catch(h){console.error("[CONFIG] applyConfigOverride failed:",{objectId:t,path:i,value:n},h);return}if(e.trackHistory!==!1){window.__configChanges=window.__configChanges||[];let h=window.__configChanges;h.push({objectId:t,path:i,oldValue:d,newValue:n,ts:Date.now()}),h.length>Un&&h.shift(),window.__configChangeRedo=[]}if(r){let h=se(),f=h.findIndex(m=>m.objectId===t&&m.sceneId===s.sceneId&&m.path===i);f>=0?h[f].value=n:h.push(s),window.__configOverrides=h,yi(h),Rt()||qn(!0)}a||console.log("[CONFIG] Applied override:",s),o&&typeof window!="undefined"&&window.dispatchEvent(new CustomEvent("config:changed",{detail:{...s,oldValue:d}}))}function $e(s,e={}){let t=e.emitEvent!==!1,i=[];for(let n of s)n!=null&&n.objectId&&typeof n.objectId=="string"&&i.push(n.objectId),re(n,{...e,emitEvent:!1});if(t&&typeof window!="undefined"){let n=Array.from(new Set(i));window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"batch",objectIds:n,count:s.length}}))}}function pe(){window.__configOverrides=[],window.__configChanges=[],window.__configChangeRedo=[],yi([]),console.log("[CONFIG] Cleared all overrides")}function Ds(s){let e=se().filter(i=>i.objectId!==s);window.__configOverrides=e,yi(e);let t=window.__configChanges||[];window.__configChanges=t.filter(i=>i.objectId!==s),bi(s),window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"clear_object",objectId:s}}))}function zt(s,e){let t=se().filter(n=>n.objectId!==s||n.path!==e);window.__configOverrides=t,yi(t);let i=window.__configChanges||[];window.__configChanges=i.filter(n=>n.objectId!==s||n.path!==e),s?bi(s):Gn(),window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"remove",objectId:s,path:e}}))}function se(){return typeof window=="undefined"?[]:(window.__configOverrides||(window.__configOverrides=Xo()),window.__configOverrides||[])}function vi(){var a;if(typeof window=="undefined")return!1;let s=window.__configChanges||[];if(s.length===0)return!1;let e=s.pop();window.__configChangeRedo=window.__configChangeRedo||[];let t=window.__configChangeRedo;if(e.changeType==="object_create"){let{screenId:r}=e.metadata||{};return e.objectId&&r&&fetch("/api/objects/delete",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:e.objectId,screenId:r})}).catch(o=>console.error("[CONFIG] Failed to delete object on undo:",o)),t.push({objectId:e.objectId,path:e.path,oldValue:e.newValue,newValue:e.oldValue,ts:Date.now(),changeType:e.changeType,metadata:e.metadata}),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),console.log("[CONFIG] Undo: Deleted object",e.objectId),!0}if(e.changeType==="object_delete"){let{screenId:r,objectConfigId:o}=e.metadata||{},l=e.oldValue;return e.objectId&&r&&l&&fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:r,instanceId:e.objectId,objectConfigId:o||((a=l==null?void 0:l.identity)==null?void 0:a.id),config:l})}).catch(c=>console.error("[CONFIG] Failed to recreate object on undo:",c)),t.push({objectId:e.objectId,path:e.path,oldValue:e.newValue,newValue:e.oldValue,ts:Date.now(),changeType:e.changeType,metadata:e.metadata}),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),console.log("[CONFIG] Undo: Recreated object",e.objectId),!0}t.push({objectId:e.objectId,path:e.path,oldValue:e.newValue,newValue:e.oldValue,ts:Date.now(),changeType:e.changeType});let i=Bn(),n=!1;if(i){let r=e.objectId?Fn(i.objects,e.objectId):i.engine;if(r){let o=Bs(r,e.path);JSON.stringify(o)===JSON.stringify(e.oldValue)&&(n=!0)}}return n?zt(e.objectId,e.path):(re({objectId:e.objectId,path:e.path,value:e.oldValue},{trackHistory:!1,persist:!0,emitEvent:!0}),e.objectId?bi(e.objectId):Gn()),console.log("[CONFIG] Undo:",e.path),!0}function wi(){var i;if(typeof window=="undefined")return!1;let s=window.__configChangeRedo||[];if(s.length===0)return!1;let e=s.pop();if(e.changeType==="object_create"){let{screenId:n,objectConfigId:a}=e.metadata||{},r=e.newValue;return e.objectId&&n&&r&&fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:n,instanceId:e.objectId,objectConfigId:a||((i=r==null?void 0:r.identity)==null?void 0:i.id),config:r})}).catch(l=>console.error("[CONFIG] Failed to recreate object on redo:",l)),window.__configChanges=window.__configChanges||[],window.__configChanges.push({objectId:e.objectId,path:e.path,oldValue:e.newValue,newValue:e.oldValue,ts:Date.now(),changeType:e.changeType,metadata:e.metadata}),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),console.log("[CONFIG] Redo: Recreated object",e.objectId),!0}if(e.changeType==="object_delete"){let{screenId:n}=e.metadata||{};return e.objectId&&n&&fetch("/api/objects/delete",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:e.objectId,screenId:n})}).catch(r=>console.error("[CONFIG] Failed to delete object on redo:",r)),window.__configChanges=window.__configChanges||[],window.__configChanges.push({objectId:e.objectId,path:e.path,oldValue:e.newValue,newValue:e.oldValue,ts:Date.now(),changeType:e.changeType,metadata:e.metadata}),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),console.log("[CONFIG] Redo: Deleted object",e.objectId),!0}return window.__configChanges=window.__configChanges||[],window.__configChanges.push({objectId:e.objectId,path:e.path,oldValue:e.newValue,newValue:e.oldValue,ts:Date.now(),changeType:e.changeType}),re({objectId:e.objectId,path:e.path,value:e.oldValue},{trackHistory:!1,persist:!0,emitEvent:!0}),e.objectId?bi(e.objectId):Gn(),console.log("[CONFIG] Redo:",e.path),!0}function Hs(s,e,t){var n;if(typeof window=="undefined")return;window.__configChanges=window.__configChanges||[];let i=window.__configChanges;i.push({objectId:s,path:"__object_create__",oldValue:null,newValue:t,ts:Date.now(),changeType:"object_create",metadata:{screenId:e,objectConfigId:(n=t==null?void 0:t.identity)==null?void 0:n.id}}),window.__configChangeRedo=[],i.length>Un&&i.shift(),console.log("[CONFIG] Tracked object creation:",s)}function Fs(s,e,t){if(typeof window=="undefined")return;window.__configChanges=window.__configChanges||[];let i=window.__configChanges;i.push({objectId:s,path:"__object_delete__",oldValue:t,newValue:null,ts:Date.now(),changeType:"object_delete",metadata:{screenId:e}}),window.__configChangeRedo=[],i.length>Un&&i.shift(),console.log("[CONFIG] Tracked object deletion:",s)}function Ot(s,e,t){var r;let i=e.split("."),n=i.pop(),a=s;for(let o of i){if(a[o]!==void 0&&typeof a[o]!="object")throw new Error(`Invalid override path: ${e} (hit primitive at ${o})`);a[o]=(r=a[o])!=null?r:{},a=a[o]}a[n]=t}function Bs(s,e){return e.split(".").reduce((t,i)=>t?t[i]:void 0,s)}function Q(s){if(s===null||typeof s!="object")return s;if(s instanceof Date)return new Date(s.getTime());if(s instanceof Set)return new Set([...s].map(t=>Q(t)));if(ArrayBuffer.isView(s))return s.slice();if(s instanceof Array)return s.map(t=>Q(t));if(s instanceof Map){let t=new Map;return s.forEach((i,n)=>t.set(n,Q(i))),t}let e={};for(let t in s)Object.prototype.hasOwnProperty.call(s,t)&&(e[t]=Q(s[t]));return e}function Xe(){let s=window.__editableConfigBaseline;if(!s){let e=window.__editableConfig;if(!e)throw new Error("Cannot export: no config loaded");return Os(e)}return Os(s)}function Os(s){let e={objects:{},scenes:{},engine:Q(s.engine||{})},t=s.objects;if(t instanceof Map)t.forEach((a,r)=>{e.objects[r]=Q(a)});else if(t&&typeof t=="object")for(let a in t)e.objects[a]=Q(t[a]);let i=s.scenes;if(i instanceof Map)i.forEach((a,r)=>{e.scenes[r]=Q(a)});else if(i&&typeof i=="object")for(let a in i)e.scenes[a]=Q(i[a]);let n=se();for(let a of n)a.objectId?(e.objects[a.objectId]||(e.objects[a.objectId]={}),Ot(e.objects[a.objectId],a.path,a.value)):a.sceneId?(e.scenes[a.sceneId]||(e.scenes[a.sceneId]={}),Ot(e.scenes[a.sceneId],a.path,a.value)):Ot(e.engine,a.path,a.value);return e}function De(){let s=se(),e=new Set;for(let t of s)t.objectId?e.add(t.objectId):e.add("__engine__");return{modifiedObjects:Array.from(e),overrideCount:s.length,hasChanges:s.length>0,overrides:s}}async function xi(s){let e=Xe(),t={};for(let[n,a]of Object.entries(e.objects)){let r=a,o=n;/^(json\.|ui\.|effects\.|engine\.)/.test(o)||(o=`json.${n}`),r&&typeof r=="object"&&(r.identity||(r.identity={}),r.identity.id=o),t[`objects/${o}.json`]=r}e.engine&&(e.engine.runtime&&(t["engine/engine.runtime.json"]=e.engine.runtime),e.engine.assets&&(t["engine/engine.assets.json"]=e.engine.assets),e.engine.splash&&(t["engine/engine.splash.json"]=e.engine.splash),e.engine.loading&&(t["engine/engine.loading.json"]=e.engine.loading),e.engine.start&&(t["engine/engine.start.json"]=e.engine.start),e.engine.tutorial&&(t["engine/engine.tutorial.json"]=e.engine.tutorial),e.engine.endgame&&(t["engine/engine.endgame.json"]=e.engine.endgame),!e.engine.runtime&&!e.engine.assets&&(t["engine/engine.json"]=e.engine));for(let[n,a]of Object.entries(e.scenes)){let r=n.startsWith("scene.")?n:`scene.${n}`;t[`scenes/${r}.json`]=a}let i=await fetch("/api/apply",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({configs:t,assets:{},hadCacheAtApply:se().length>0,versionName:s})});if(!i.ok){let n=await i.json();throw new Error(`Apply failed: ${n.error||"Unknown error"}`)}pe();try{let n=mi();n&&(window.__editableConfigBaseline=Q(n))}catch{}localStorage.setItem("handler_last_applied",Date.now().toString()),console.log("[Config Persistence] \u2705 Applied to disk successfully")}function $t(){pe(),window.location.reload()}async function Si(){if(!confirm("This will restore all configs to their original state. All uncommitted changes in cache AND applied changes will be lost. Continue?"))return;let e=await fetch("/api/reset-to-original",{method:"POST"});if(!e.ok){let t=await e.json();throw new Error(`Reset failed: ${t.error||"Unknown error"}`)}pe(),window.location.reload()}var $s,Un,Ns,ee=be(()=>{"use strict";$s="handler_preview_override_mode";if(typeof window!="undefined"){let s=window.localStorage.getItem($s);window.__enableConfigOverrides=s===null?!0:s==="true"}Un=500;Ns={getCurrentConfig(){return window.__editableConfig||null},getChanges(){return window.__configChanges||[]},clearChanges(){window.__configChanges=[],window.__configChangeRedo=[]}}});function Jo(s,e){try{if(typeof s=="object"&&s!==null)return s;if(typeof s!="string")return null;if(s.startsWith("data:")){let i=s.indexOf(",");if(i===-1)return null;let n=s.slice(0,i);if(!n.includes("application/json")&&!n.includes("text/plain"))return null;let a=s.slice(i+1),r=n.includes("base64")?typeof atob=="function"?atob(a):a:decodeURIComponent(a);return JSON.parse(r)}let t=s.trim();return t.startsWith("{")||t.startsWith("[")?JSON.parse(s):null}catch{return null}}function Zo(s){if(typeof window=="undefined"||!window.INLINE_ASSETS)return null;let e=window.INLINE_ASSETS,t=s.replace(/^\.\/+/,""),i=t.split("/").pop()||t,n=[t,i,t.replace(/\.json$/,""),i.replace(/\.json$/,"")];for(let a of n){let r=e[a];if(r){let o=Jo(r,a);if(o!==null)return o}}return null}async function Dt(s){if(Vn.has(s)&&!Yn)return console.log(`[CONFIG] Using cached config for: "${s}"`),Vn.get(s);if(console.log(`[CONFIG] loadConfigFile called with: "${s}", MODE: ${V.toUpperCase()}, CACHE: ${Yn?"DISABLED":"ENABLED"}`),V==="publish"){let i=Zo(s);return i?(console.log(`[CONFIG] \u2713 Loaded ${s} via INLINE_ASSETS`),i):(console.log(`[CONFIG] \u2139\uFE0F Optional config ${s} not in INLINE_ASSETS, skipping fetch in publish mode`),{})}V==="brand"||console.log(`[CONFIG] DEV MODE: Trying nested paths first, then flattened for "${s}"`);let e;V==="brand"?e=[`./${s.split("/").pop()||s}`,`./${s}`,`./${s.replace(/^configs\//,"")}`,`./${s.replace(/^configs\//,"").replace(/\//g,".")}`]:e=[`./${s}`,`./${s.replace(/^configs\//,"")}`,`./${s.replace(/^configs\//,"").replace(/\//g,".")}`],e=Array.from(new Set(e.flatMap(i=>i.startsWith("./")?[i,`/${i.slice(2)}`]:i.startsWith("/")?[i]:[i,`/${i}`]))),console.log("[CONFIG] Will try candidates:",e);let t=(async()=>{let i=Yn?"no-store":"force-cache";for(let n of e)try{let a=await fetch(n,{cache:i});if(!a.ok)continue;let r=await a.json();return console.log(`[CONFIG] \u2713 Loaded ${s} via ${n}`,r),r}catch(a){console.warn(`[CONFIG] \u2717 Failed to load ${n} (mode: ${V}):`,a)}return console.warn(`[CONFIG] \u2717 All attempts failed for ${s}; using defaults`),{}})();return Vn.set(s,t),t}async function Ei(){console.log("[CONFIG] Loading component schemas...");let s=["components/identity.schema.json","components/transform.schema.json","components/render.schema.json","components/motion.schema.json","components/effects.schema.json","components/interaction.schema.json","components/gameplay.rules.schema.json","components/gameplay.tuning.schema.json","components/visibility.schema.json","components/audio.schema.json","components/physics.schema.json","components/ui.schema.json"],e=new Map;for(let t of s)try{let i=V==="publish"||V==="brand"?t.split("/").pop()||t:`configs/${t}`,n=await Dt(i);n.component&&(e.set(n.component,n),console.log(`[CONFIG] \u2713 Schema loaded: ${n.component} ${V==="publish"||V==="brand"?"(flattened)":"(nested)"}`))}catch(i){console.warn(`[CONFIG] \u2717 Failed to load schema ${t}:`,i)}return console.log(`[CONFIG] Loaded ${e.size} component schemas`),e}async function He(s){console.log(`[CONFIG] Loading object config: ${s}`);let e=V==="publish"||V==="brand"?`${s}.json`:`configs/objects/${s}.json`;return await Dt(e)}async function Ci(s){let e=new Map;if(s.objects&&Array.isArray(s.objects)){for(let t of s.objects)if(t.enabled&&t.object_config)try{let i=t.instance_id;/^(json\.|ui\.|effects\.|engine\.)/.test(i)||(i=`json.${i}`);let n=await He(i);(!n||Object.keys(n).length===0)&&i!==t.instance_id&&(n=await He(t.instance_id)),!n||Object.keys(n).length===0?(console.log(`[CONFIG] No instance snapshot for ${t.instance_id}, using template ${t.object_config}`),n=await He(t.object_config)):console.log(`[CONFIG] \u2713 Loaded instance snapshot for ${t.instance_id}`),e.set(t.instance_id,{...n,instance_id:t.instance_id,object_config:t.object_config})}catch(i){console.warn(`Failed to load object ${t.object_config}:`,i)}}return e}async function Ai(){console.log("[CONFIG] Loading engine configs...");let s=["runtime","assets","splash","loading","start","tutorial","endgame"],e=await Promise.all(s.map(i=>{let n=`engine.${i}.json`,a=V==="publish"||V==="brand"?n:`configs/engine/${n}`;return Dt(a)})),t=Object.fromEntries(s.map((i,n)=>[i,e[n]]));return console.log("[CONFIG] Engine configs loaded:",Object.fromEntries(s.map(i=>{var r;let n=(r=t[i])!=null?r:{},a=Object.keys(n);return[i,a.length>0?a:"empty"]}))),t}async function Wn(){return await Dt(V==="publish"||V==="brand"?"game.prompt.json":"configs/engine/game.prompt.json")}async function Li(s="scene.main"){console.log(`[CONFIG] Loading scene config: ${s}`);let e=V==="publish"||V==="brand"?`${s}.json`:`configs/scenes/${s}.json`;return await Dt(e)}function pt(s,e){let t=[];if(!s.identity)return t.push("Missing required identity component"),{valid:!1,errors:t};let i=e.get("identity");if(i)for(let n of i.required||[])s.identity[n]||t.push(`Missing required identity field: ${n}`);for(let[n,a]of Object.entries(s)){if(n==="identity")continue;let r=e.get(n);if(r&&a&&typeof a=="object"){let o=a;for(let l of r.required||[])o[l]===void 0&&t.push(`Missing required field in ${n}: ${l}`);if(r.constraints&&typeof r.constraints=="object")for(let[l,c]of Object.entries(r.constraints)){let d=o[l];if(d!==void 0&&c&&typeof c=="object"){let p=c;typeof d=="number"&&(p.min!==void 0&&d<p.min&&t.push(`${n}.${l} value ${d} is below minimum ${p.min}`),p.max!==void 0&&d>p.max&&t.push(`${n}.${l} value ${d} is above maximum ${p.max}`))}}}}return{valid:t.length===0,errors:t}}function Je(s,e){let t={...s},i=["identity","transform","render"];for(let[n,a]of e.entries())a.defaults&&Object.keys(a.defaults).length>0&&(i.includes(n)||t[n])&&(t[n]||(t[n]={}),t[n]={...a.defaults,...t[n]});return t}function ue(s,e,t,i){return typeof s!="number"||!Number.isFinite(s)?e:Math.min(Math.max(s,t),i)}function Us(s,e){if(Array.isArray(s))return{x:ue(s[0],e.x,-2e3,2e3),y:ue(s[1],e.y,-2e3,2e3)};if(!s||typeof s!="object")return e;let{x:t,y:i}=s;return{x:ue(t,e.x,-2e3,2e3),y:ue(i,e.y,-2e3,2e3)}}function Qo(s,e){if(Array.isArray(s))return{x:ue(s[0],e.x,0,1),y:ue(s[1],e.y,0,1)};if(!s||typeof s!="object")return e;let{x:t,y:i}=s;return{x:ue(t,e.x,0,1),y:ue(i,e.y,0,1)}}function el(s){if(Array.isArray(s))return{x:ue(s[0],.5,-10,10),y:ue(s[1],.5,-10,10)};if(s&&typeof s=="object"){let{x:e,y:t}=s;return{x:ue(e,.5,-10,10),y:ue(t,.5,-10,10)}}return typeof s=="string"?s:null}async function Ie(s="scene.main",e){var l,c,d,p,u,g,h,f,m,b,y,v,w,T;console.log("[CONFIG] ===== Starting Object-Centric Config Load =====");let t=await Ei(),i=se();i.length>0&&console.log(`[CONFIG] Applying ${i.length} active overrides`);let n=await Li(s);console.log(`[CONFIG] Scene config loaded: ${((l=n.objects)==null?void 0:l.length)||0} objects`);let a=await Ai();console.log("[CONFIG] Loading object configs...");let r=await Ci(n);console.log(`[CONFIG] Loaded ${r.size} object configs:`,Array.from(r.keys()));for(let[I,M]of r.entries()){let L=Je(M,t),j=pt(L,t);j.valid||console.warn(`Object ${I} validation errors:`,j.errors),(c=L.transform)!=null&&c.position&&(L.transform.position=Us(L.transform.position,{x:0,y:0})),(d=L.transform)!=null&&d.offset&&(L.transform.offset=Us(L.transform.offset,{x:0,y:0})),((p=L.transform)==null?void 0:p.anchor)!==void 0&&(L.transform.anchor=el(L.transform.anchor)),((u=L.transform)==null?void 0:u.position_ratio)!==void 0&&L.transform.position_ratio!==null&&(L.transform.position_ratio=Qo(L.transform.position_ratio,{x:.5,y:.5})),r.set(I,L)}if(e){if(e.objects)for(let[I,M]of e.objects.entries())r.set(I,M);e.engine&&(a.runtime={...a.runtime,...e.engine.runtime},a.assets={...a.assets,...e.engine.assets},a.splash={...(g=a.splash)!=null?g:{},...(h=e.engine.splash)!=null?h:{}})}let o={objects:r,engine:a,scene:n,schemas:t,theme:{background_color:"#ffffff",text_color:"#000000",square_color:"#cccccc",cta_background:"#007bff",cta_text:"#ffffff"},gameplay:{}};return typeof window!="undefined"&&(window.__editableConfig=o,window.__editableConfigBaseline||(window.__editableConfigBaseline=Je(o,t))),i.length>0&&Rt()&&$e(i,{silent:!0,persist:!1}),console.log("[CONFIG] ===== Object-Centric Config Load Complete ====="),console.log("[CONFIG] Summary:",{schemas:Array.from(t.keys()),objects:Array.from(r.keys()),engine:{runtime:Object.keys((f=a.runtime)!=null?f:{}),assets:Object.keys((m=a.assets)!=null?m:{}),splash:Object.keys((b=a.splash)!=null?b:{}),loading:Object.keys((y=a.loading)!=null?y:{}),start:Object.keys((v=a.start)!=null?v:{}),tutorial:Object.keys((w=a.tutorial)!=null?w:{}),endgame:Object.keys((T=a.endgame)!=null?T:{})},scene:n.scene_id||"unknown"}),o}function Kn(s){var t,i,n,a,r,o,l,c,d,p,u,g,h,f,m,b,y,v,w,T,I,M,L,j,_,P,x,S,A,E,C,O,k;let e={gameplay:{},ui:{},theme:{},assets:{}};for(let[R,z]of s.objects.entries()){let D=((t=z.identity)==null?void 0:t.id)||R;D.includes("character")&&(e.gameplay.character_pos=((i=z.transform)==null?void 0:i.position)||{x:0,y:0},e.gameplay.character_scale=((n=z.transform)==null?void 0:n.scale)||1,e.gameplay.character_anim_speed=((r=(a=z.gameplay)==null?void 0:a.tuning)==null?void 0:r.anim_speed)||.003,e.gameplay.character_relief_scale=((l=(o=z.gameplay)==null?void 0:o.tuning)==null?void 0:l.relief_scale)||1.22,e.gameplay.character_relief_speed=((d=(c=z.gameplay)==null?void 0:c.tuning)==null?void 0:d.relief_speed)||.22),(D.includes("gun")||D.includes("flame"))&&(e.gameplay.gun=z.gun||{},e.gameplay.gunmuzzle=((p=z.effects)==null?void 0:p.gunmuzzle)||{},e.gameplay.muzzle_levels=((u=z.effects)==null?void 0:u.muzzle_levels)||{},e.gameplay.flame=((g=z.effects)==null?void 0:g.flame)||{}),D.includes("diamond")&&(e.gameplay.diamond=z),D.includes("ice")&&(e.gameplay.melt=z.melt||{},e.gameplay.melt_anchor=((h=z.transform)==null?void 0:h.melt_anchor)||{x:0,y:0},e.gameplay.melt_pos=((f=z.transform)==null?void 0:f.position)||{x:0,y:0},e.gameplay.hybrid_melting=((m=z.effects)==null?void 0:m.hybrid_melting)||{},e.gameplay.physics_chunks=((b=z.effects)==null?void 0:b.physics_chunks)||{},e.gameplay.melting_particles=((y=z.effects)==null?void 0:y.melting_particles)||{},e.gameplay.hard_ice=z.hard_ice||{}),D.includes("water")&&(e.gameplay.water_drops=z),D.includes("crack")&&(e.gameplay.crack=z),D.includes("hand")&&(e.gameplay.hand=((v=z.gameplay)==null?void 0:v.tuning)||{},e.gameplay.brush_start_pos=((w=z.transform)==null?void 0:w.brush_start_pos)||{x:0,y:-120},e.gameplay.hand_scale=((T=z.transform)==null?void 0:T.scale)||1.5),D.includes("hazard")&&(e.gameplay.hazard=((I=z.gameplay)==null?void 0:I.tuning)||{},e.gameplay.danger_pos=((M=z.transform)==null?void 0:M.danger_pos)||{x:0,y:235},e.gameplay.danger_pulse=((j=(L=z.gameplay)==null?void 0:L.tuning)==null?void 0:j.danger_pulse)||{},e.gameplay.hazard_height=((P=(_=z.gameplay)==null?void 0:_.tuning)==null?void 0:P.hazard_height)||140)}return e.gameplay.timeline=((x=s.engine.runtime)==null?void 0:x.timeline)||{},e.gameplay.drag_surface=((S=s.engine.runtime)==null?void 0:S.drag_surface)||{},e.gameplay.background=((A=s.engine.runtime)==null?void 0:A.background)||{},e.gameplay.ui_styles=((E=s.engine.runtime)==null?void 0:E.ui_styles)||{},e.gameplay.label_pulse=((C=s.engine.runtime)==null?void 0:C.label_pulse)||{},e.ui=((O=s.engine.runtime)==null?void 0:O.ui)||{},e.theme=((k=s.engine.runtime)==null?void 0:k.theme)||{},e.assets=s.engine.assets||{},e}var Gs,V,Vn,Yn,Xn=be(()=>{"use strict";ee();Gs=null,V="dev";if(typeof window!="undefined"){let s=window.__BUILD_SETTINGS__;if(s!=null&&s.buildMode)Gs=s,V=s.buildMode,console.log("[CONFIG] Loaded inline build settings:",s,"buildMode:",V);else try{let e=new XMLHttpRequest;if(e.open("GET","./build-settings.json",!1),e.send(),e.status===200&&e.responseText){let t=JSON.parse(e.responseText);Gs=t,V=t.buildMode||"dev",console.log("[CONFIG] Loaded build settings:",t,"buildMode:",V)}else console.log("[CONFIG] No build-settings.json found, using default buildMode:",V)}catch(e){console.log("[CONFIG] Failed to load build-settings.json:",e instanceof Error?e.message:String(e))}}console.log("[CONFIG] Final buildMode:",V);Vn=new Map,Yn=V==="dev"||typeof window!="undefined"&&window.location.search.includes("hot-reload")});function Jn(s,e){let t=[];function i(n,a,r=""){if(n!==a){if(typeof n!=typeof a){t.push(`${r}: type changed`);return}if(typeof n=="object"&&n!==null&&a!==null){let o=new Set([...Object.keys(n),...Object.keys(a)]);for(let l of o){let c=r?`${r}.${l}`:l;l in n?l in a?i(n[l],a[l],c):t.push(`${c}: removed`):t.push(`${c}: added`)}}else t.push(`${r}: changed`)}}return i(s,e),t}function Zn(s,e,t,i){let n={...t};for(let[a,r]of i.entries())n[a]&&r.defaults&&(n[a]={...r.defaults,...n[a]});return n}var Nt,Ze,Qn=be(()=>{"use strict";Nt=class{shouldFullReload(e){return e.type==="component"||e.type==="scene"}getAffectedObjects(e){return e.type==="object"&&e.objectId?[e.objectId]:[]}},Ze=class{constructor(e=1e3){this.pollingInterval=null;this.fileHashes=new Map;this.callbacks=new Map;this.intervalMs=e}watch(e,t){this.callbacks.set(e,t),this.pollingInterval===null&&(this.pollingInterval=window.setInterval(()=>{this.checkAllFiles()},this.intervalMs))}async checkAllFiles(){for(let[e,t]of this.callbacks.entries())try{let i=`${e}?t=${Date.now()}&r=${Math.random()}`,n=await fetch(i,{cache:"no-cache",headers:{"Cache-Control":"no-cache"}});if(n.ok){let a=await n.text(),r=this.hashString(a),o=this.fileHashes.get(e);if(o&&o!==r&&console.log(`[HOT-RELOAD] File changed: ${e}`),o&&o!==r){console.log(`[HOT-RELOAD] File changed: ${e}`);let l=this.determineEventType(e);t(l),this.fileHashes.set(e,r)}else o||this.fileHashes.set(e,r)}}catch(i){console.warn(`Failed to check ${e}:`,i)}}determineEventType(e){var t,i;return e.includes("/components/")?{type:"component",path:e,componentName:(t=e.split("/").pop())==null?void 0:t.replace(".schema.json","")}:e.includes("/engine/")?{type:"engine",path:e}:e.includes("/scenes/")?{type:"scene",path:e}:e.includes("/objects/")?{type:"object",path:e,objectId:(i=e.split("/").pop())==null?void 0:i.replace(".json","")}:{type:"object",path:e}}hashString(e){let t=0;for(let i=0;i<e.length;i++){let n=e.charCodeAt(i);t=(t<<5)-t+n,t=t&t}return t.toString()}unwatch(e){this.callbacks.delete(e),this.fileHashes.delete(e)}stop(){this.pollingInterval!==null&&(clearInterval(this.pollingInterval),this.pollingInterval=null),this.callbacks.clear(),this.fileHashes.clear()}}});function ta(s){if(typeof window=="undefined")return;let e=typeof ea!="undefined"&&!!ea.hot,t=window.location.search.includes("hot-reload");if(!(e||t))return;let n=null,a=!1,r=null;if(t){r=new Ze;let h=window.__configWatcher;h!=null&&h.stop&&h.stop(),window.__configWatcher=r}let o=new Set,l=h=>{var b,y;if(!r)return;let f=new Set;f.add("configs/engine/engine.runtime.json"),f.add("configs/engine/engine.assets.json"),f.add("configs/engine/engine.splash.json"),f.add("configs/scenes/scene.main.json");let m=(y=(b=h.scene)==null?void 0:b.objects)!=null?y:[];for(let v of m)v!=null&&v.object_config&&f.add(`configs/objects/${v.object_config}.json`);for(let v of o)f.has(v)||r.unwatch(v);for(let v of f)o.has(v)||r.watch(v,w=>g(w));o=f},c=new Set,d=!1,p=async h=>{let f=await He(h),m=Je(f,s.activeConfig.schemas),b=pt(m,s.activeConfig.schemas);b.valid||console.warn(`[HOT-RELOAD] ${h} validation errors:`,b.errors),await s.liveEditBridge.applyObjectConfig(h,m)};async function u(h){if(!a){a=!0;try{if(d||c.size===0){s.audioSystem.destroy();let f=await Ie("scene.main");s.setActiveConfig(f),s.gameObjectManager.updateConfig(f),s.CustomAssets.updateConfig(f),await s.CustomAssets.ready();let m=s.createAudioSystem(f);s.setAudioSystem(m),window.__audioSystem=m,await m.start(),s.liveEditBridge.rebuildIndexes(),l(f),console.log(`[GAME] Hot-reload complete (${h})`)}else{let f=Array.from(c);c.clear();for(let m of f)await p(m);console.log(`[GAME] Hot-reload updated objects: ${f.join(", ")}`)}}catch(f){console.warn("[GAME] Hot-reload failed:",f)}finally{a=!1,d=!1,c.clear()}}}function g(h){h.type==="object"&&h.objectId?c.add(h.objectId):d=!0,n&&window.clearTimeout(n),n=window.setTimeout(()=>{u(h.type)},120)}e&&ea.hot.on("config-change",()=>{g({type:"hmr"})}),t&&(l(s.activeConfig),console.log(`[GAME] Hot-reload watcher enabled (${o.size} files)`))}var ea,qs=be(()=>{"use strict";Qn();Xn();ea={}});var Vs={};at(Vs,{ConfigWatcher:()=>Ze,DefaultReloadStrategy:()=>Nt,applyDefaults:()=>Je,diffConfigs:()=>Jn,loadAllObjectConfigs:()=>Ci,loadComponentSchemas:()=>Ei,loadEngineConfig:()=>Ai,loadGamePromptConfig:()=>Wn,loadObjectCentricConfig:()=>Ie,loadObjectConfig:()=>He,loadSceneConfig:()=>Li,rehydrateObject:()=>Zn,setupHotReload:()=>ta,toLegacyFormat:()=>Kn,validateObjectConfig:()=>pt});var Ti=be(()=>{"use strict";Xn();Qn();qs()});var Ht={};at(Ht,{AssetEditorModal:()=>ra});var ra,ut=be(()=>{"use strict";ra=class{constructor(){this.modal=null;this.currentObjectId=null;this.currentPath=null;this.currentAsset="";this.onApplyCallback=null}show(e,t,i,n){this.currentObjectId=e,this.currentPath=t,this.currentAsset=i,this.onApplyCallback=n,this.createModal(e,i),document.body.appendChild(this.modal),this.attachModalListeners()}createModal(e,t){let i=document.createElement("div");i.className="asset-editor-modal",i.innerHTML=`
|
|
1
|
+
"use strict";var no=Object.create;var ni=Object.defineProperty;var ao=Object.getOwnPropertyDescriptor;var so=Object.getOwnPropertyNames;var ro=Object.getPrototypeOf,oo=Object.prototype.hasOwnProperty;var be=(r,e)=>()=>(r&&(e=r(r=0)),e);var at=(r,e)=>{for(var t in e)ni(r,t,{get:e[t],enumerable:!0})},Ja=(r,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of so(e))!oo.call(r,n)&&n!==t&&ni(r,n,{get:()=>e[n],enumerable:!(i=ao(e,n))||i.enumerable});return r};var st=(r,e,t)=>(t=r!=null?no(ro(r)):{},Ja(e||!r||!r.__esModule?ni(t,"default",{value:r,enumerable:!0}):t,r)),lo=r=>Ja(ni({},"__esModule",{value:!0}),r);var ce,oi=be(()=>{"use strict";ce=class{static get(e){var t;return(t=this.store.get(e))==null?void 0:t.data}static set(e,t){this.store.set(e,{data:t})}static has(e){return this.store.has(e)}static clear(){this.store.clear()}};ce.store=new Map});function bo(){var r,e;try{let t=typeof window!="undefined"&&(document.querySelector('script[src*="inline-assets.js"]')||((e=(r=document.querySelector("script"))==null?void 0:r.textContent)==null?void 0:e.includes("inline-assets.js"))||window.INLINE_ASSETS),i=typeof window!="undefined"&&document.querySelector('link[href*="assets/"], script[src*="assets/"]');return!!(t&&!i)}catch{return!1}}async function yo(){try{if(typeof window!="undefined"){let r=await fetch("./build-settings.json");if(r.ok){let e=await r.json();return console.log("[AssetLoader] Loaded build settings:",e),e}}}catch{}return null}function vo(){try{if(typeof window!="undefined"){let r=new XMLHttpRequest;if(r.open("GET","./build-settings.json",!1),r.send(),r.status===200&&r.responseText){let e=JSON.parse(r.responseText);return console.log("[AssetLoader] Loaded build settings (sync):",e),e}}}catch{}return null}async function wo(){if(console.log(`[AssetLoader] getInlineAssets() called - Effective mode: ${Y}`),Object.keys(Ce).length>0)return console.log("[AssetLoader] Returning cached inline assets:",Object.keys(Ce)),Ce;if(typeof window!="undefined"&&window.INLINE_ASSETS)return console.log("[AssetLoader] Using pre-loaded INLINE_ASSETS from window:",Object.keys(window.INLINE_ASSETS)),Ce={...window.INLINE_ASSETS},Ce;if(!(Y==="publish"&&ye!==!1))return console.log("[AssetLoader] Inline assets disabled for this build mode."),Ce;if(!jn){let e=typeof window!="undefined"?new URL("inline-assets.js",window.location.href).href:"./inline-assets.js";console.log("[AssetLoader] Loading inline assets from:",e),jn=(async()=>{try{try{let a=await import(e+"?t="+Date.now());if(a.INLINE_ASSETS)return console.log("[AssetLoader] Loaded INLINE_ASSETS via ES module:",Object.keys(a.INLINE_ASSETS)),a.INLINE_ASSETS}catch(a){console.warn("[AssetLoader] ES module import failed, trying text parse:",a)}let t=await fetch(e);if(!t.ok)throw new Error(`HTTP ${t.status}: ${t.statusText}`);let i=await t.text();console.log("[AssetLoader] Received JS code, length:",i.length);let n=i.match(/export\s+const\s+INLINE_ASSETS\s*=\s*({[\s\S]*?});?\s*$/m);if(n)try{let a=n[1];console.log("[AssetLoader] Found INLINE_ASSETS export, parsing...");let s=new Function("return "+a)();return console.log("[AssetLoader] Parsed inline assets:",Object.keys(s)),s}catch(a){return console.warn("[AssetLoader] Failed to parse inline assets:",a),{}}else return console.warn("[AssetLoader] INLINE_ASSETS export not found in response"),console.log("[AssetLoader] JS code preview:",i.substring(0,500)),{}}catch(t){return console.warn("[AssetLoader] Failed to load inline assets:",t),{}}})()}return Ce=await jn,console.log("[AssetLoader] Final inline assets cache:",Object.keys(Ce)),Ce}function _n(r){return r===null||typeof r!="object"||(Object.freeze(r),Object.values(r).forEach(e=>_n(e))),r}function xo(r=64,e=64,t=16711680){let i=document.createElement("canvas");i.width=r,i.height=e;let n=i.getContext("2d");return n.fillStyle=`#${t.toString(16).padStart(6,"0")}`,n.fillRect(0,0,r,e),n.strokeStyle="#000",n.strokeRect(0,0,r,e),n.fillStyle="#fff",n.font="10px sans-serif",n.textAlign="center",n.fillText("MISSING",r/2,e/2),Ae.Texture.from(i)}function On(r,e){Ps.set(r,e)}var Ae,ks,Is,Ve,Y,ye,Re,Ce,jn,Ps,Ye,li=be(()=>{"use strict";Ae=require("pixi.js");oi();ks=typeof __BUILD_MODE__!="undefined"?__BUILD_MODE__:"undefined",Is=bo(),Ve=typeof window!="undefined"?window.__BUILD_SETTINGS__:null,Y=Is?"publish":ks,ye=Ve==null?void 0:Ve.assetsInlined;Ve!=null&&Ve.buildMode&&(Y=Ve.buildMode,console.log(`[AssetLoader] Build mode overridden by inline settings: ${Y}`));Re=vo();Re!=null&&Re.buildMode&&(Y=Re.buildMode,console.log(`[AssetLoader] Build mode overridden by sync settings: ${Y}`));(Re==null?void 0:Re.assetsInlined)!==void 0&&(ye=Re.assetsInlined);yo().then(r=>{r!=null&&r.buildMode&&r.buildMode!==Y&&(Y=r.buildMode,console.log(`[AssetLoader] Build mode overridden by settings: ${Y}`)),(r==null?void 0:r.assetsInlined)!==void 0&&(ye=r.assetsInlined)}).catch(()=>{});console.log(`[AssetLoader] MODULE LOADED - Compile: ${ks}, Runtime: ${Is?"publish":"dev"}, Effective: ${Y}`);Ce={},jn=null;Ps=new Map;Ye=class{static async load(e,t,i,n){let a=`${e}:${t.path}`,s=ce.get(a);if(s!==void 0)return s;console.log(`[AssetLoader] Loading asset: ${e}, type: ${t.type}, Effective mode: ${Y}`),console.log(`[AssetLoader] Window defined: ${typeof window!="undefined"}, INLINE_ASSETS exists: ${!!(typeof window!="undefined"&&window.INLINE_ASSETS)}, keys: ${typeof window!="undefined"&&window.INLINE_ASSETS?Object.keys(window.INLINE_ASSETS).length:"N/A"}`);let o=await wo(),l=o[e];if(!l&&n&&(l=o[n],l&&console.log(`[AssetLoader] Found inline data for ${e} using configId: ${n}`)),!l&&t.path){let p=t.path.split("/");if(p.length>=2){let u=p[p.length-1].split(".")[0];o[u]&&(l=o[u],console.log(`[AssetLoader] Found inline data for ${e} using assetName: ${u}`))}}if(console.log("[AssetLoader] Inline data for",e,":",l?"FOUND":"NOT FOUND"),Y==="publish"&&ye!==!1&&(console.log("[AssetLoader] \u26A0\uFE0F PUBLISH MODE DETECTED - inline assets are MANDATORY"),!l))throw new Error(`[AssetLoader] PUBLISH MODE: Inline asset required but NOT FOUND for object: ${e}, path: ${t.path}`);let d=Ps.get(t.type);if(d)try{let p=await d(t.path,l,e,i);return ce.set(a,p),p}catch(p){return this.handleFailure(e,t.type,p)}try{let p;switch(t.type){case"image":p=await this.loadImage(t.path,l);break;case"json":p=await this.loadJSON(t.path,l),p=_n(p);break;default:throw new Error(`Unknown asset type: ${t.type}`)}return ce.set(a,p),p}catch(p){return this.handleFailure(e,t.type,p)}}static async loadImage(e,t){let i=Y==="publish",n=i&&ye!==!1;if(console.log(`[AssetLoader] loadImage - Effective mode: ${Y}, isPublishMode: ${i}, inlineData: ${t?"EXISTS":"MISSING"}`),n){if(console.log("[AssetLoader] PUBLISH MODE ACTIVATED - inline assets are MANDATORY"),!t)throw new Error(`[AssetLoader] Publish mode: inline asset required but not found for object. Path: ${e}`);if(typeof t!="string"||!t.startsWith("data:"))throw new Error(`[AssetLoader] Publish mode: inline asset must be data URI string, got: ${typeof t}`);try{return await Ae.Assets.load(t)}catch(a){throw console.error("[AssetLoader] Failed to load texture from data URI:",a),a}}if(t&&typeof t=="string"&&t.startsWith("data:"))try{return await Ae.Assets.load(t)}catch(a){return console.error("[AssetLoader] Failed to load texture from data URI, falling back to path:",a),await Ae.Assets.load(e)}return await Ae.Assets.load(e)}static async loadJSON(e,t){let i=Y==="publish",n=i&&ye!==!1;if(console.log(`[AssetLoader] loadJSON - Effective mode: ${Y}, isPublishMode: ${i}, inlineData: ${t?"EXISTS":"MISSING"}`),n){if(console.log("[AssetLoader] PUBLISH MODE ACTIVATED - inline assets are MANDATORY"),!t)throw new Error(`[AssetLoader] Publish mode: inline asset required but not found for path: ${e}`);if(typeof t=="object"&&t!==null)return t;if(typeof t=="string"&&t.startsWith("data:")){let s=atob(t.split(",")[1]);return JSON.parse(s)}return JSON.parse(t)}if(t){if(typeof t=="object"&&t!==null)return t;if(typeof t=="string"&&t.startsWith("data:")){let s=atob(t.split(",")[1]);return JSON.parse(s)}return JSON.parse(t)}let a=await fetch(e);if(!a.ok)throw new Error(`JSON fetch failed: ${e}`);return a.json()}static handleFailure(e,t,i){if(Y==="dev"){let a=t==="image"?xo():_n({__placeholder:!0,type:t});return ce.set(e+":"+((i==null?void 0:i.path)||"missing"),a),a}throw i}};On("image",async(r,e)=>{let t=Y==="publish",i=t&&ye!==!1,n=Y==="brand",a=t&&ye===!1;if(console.log(`[AssetLoader] registerType('image') - Effective mode: ${Y}, isPublishMode: ${t}, isBrandMode: ${n}, inlineData: ${e?"EXISTS":"MISSING"}`),i){if(console.log("[AssetLoader] PUBLISH MODE ACTIVATED - inline assets are MANDATORY"),!e)throw new Error(`[AssetLoader] Publish mode: inline asset required but not found for path: ${r}`);if(typeof e!="string"||!e.startsWith("data:"))throw new Error(`[AssetLoader] Publish mode: inline asset must be data URI string, got: ${typeof e}`);return Ae.Assets.load(e)}let s=r;return(n||a)&&r&&!r.startsWith("assets/")&&(typeof window!="undefined"&&!document.querySelector('link[href*="assets/"], script[src*="assets/"]')&&!document.querySelector('link[href*="configs/"], script[src*="configs/"]')?(s=r,console.log(`[AssetLoader] BRAND MODE: flattened build, using path "${r}" as-is`)):(s=`assets/${r}`,console.log(`[AssetLoader] BRAND MODE: transformed path "${r}" -> "${s}"`))),Ae.Assets.load(e||s)});On("json",async(r,e)=>{let t=Y==="publish",i=t&&ye!==!1,n=Y==="brand",a=t&&ye===!1;if(console.log(`[AssetLoader] registerType('json') - Effective mode: ${Y}, isPublishMode: ${t}, isBrandMode: ${n}, inlineData: ${e?"EXISTS":"MISSING"}`),i){if(console.log("[AssetLoader] PUBLISH MODE ACTIVATED - inline assets are MANDATORY"),!e)throw new Error(`[AssetLoader] Publish mode: inline asset required but not found for path: ${r}`);return typeof e=="object"&&e!==null?e:typeof e=="string"&&e.startsWith("data:")?JSON.parse(atob(e.split(",")[1])):JSON.parse(e)}let s=r;if((n||a)&&r&&!r.startsWith("assets/")&&(typeof window!="undefined"&&!document.querySelector('link[href*="assets/"], script[src*="assets/"]')&&!document.querySelector('link[href*="configs/"], script[src*="configs/"]')?(s=r,console.log(`[AssetLoader] BRAND MODE: flattened build, using path "${r}" as-is`)):(s=`assets/${r}`,console.log(`[AssetLoader] BRAND MODE: transformed path "${r}" -> "${s}"`))),e)return typeof e=="object"&&e!==null?e:typeof e=="string"&&e.startsWith("data:")?JSON.parse(atob(e.split(",")[1])):JSON.parse(e);let o=await fetch(s);if(!o.ok)throw new Error(`JSON fetch failed: ${r}`);return o.json()})});var js={};at(js,{AssetTextures:()=>we,initAssetTextures:()=>$n});function $n(r,e){Ms.init(r,e),typeof window!="undefined"&&(window.__AssetTextures=we)}var zn,Ms,we,ct=be(()=>{"use strict";li();zn=class{constructor(){this.textures=new Map;this.readyPromise=null;this.priorityReadyPromise=null;this.priorityReadyResolve=null;this.config=null;this.app=null;this.attempted=new Set;this.waiters=new Set}init(e,t){if(this.config===e&&this.app===t&&this.priorityReadyPromise){console.log("[AssetTextures] init called with same config/app; keeping existing state");return}this.textures.clear(),this.readyPromise=null,this.priorityReadyPromise=null,this.priorityReadyResolve=null,this.attempted.clear(),this.waiters.clear(),this.priorityReadyPromise=new Promise(i=>{this.priorityReadyResolve=i}),this.config=e,this.app=t,console.log("[AssetTextures] Initialized with config, cleared previous textures")}async ready(){if(this.readyPromise){await this.readyPromise;return}if(!this.config)throw new Error("[AssetTextures] Must call init() before ready() - config is null");if(!this.app)throw new Error("[AssetTextures] Must call init() before ready() - app is null");let e=this.config,t=this.app;return this.readyPromise=(async()=>{var s;console.log("[AssetTextures] Loading all assets...");let i=new Set(["background_loading_1"]),n=[],a=[];for(let[o,l]of e.objects.entries()){let c=(s=l.render)==null?void 0:s.asset;if(!c)continue;let d=async()=>{var p;try{let u=(p=l.identity)==null?void 0:p.id;console.log(`[AssetTextures] Loading ${c.type}: ${o} (${u})`);let g=await Ye.load(o,c,t,u);this.textures.set(o,g),console.log(`[AssetTextures] \u2713 Loaded: ${o}`)}catch(u){console.error(`[AssetTextures] \u2717 Failed to load: ${o}`,u)}finally{this.attempted.add(o);try{for(let u of Array.from(this.waiters))u()}catch{}}};i.has(o)?n.push(d()):a.push(d())}n.length>0&&(console.log("[AssetTextures] Phase 1: Loading priority assets (loading screen)..."),await Promise.all(n),console.log("[AssetTextures] Phase 1: Priority assets ready")),this.priorityReadyResolve&&this.priorityReadyResolve(),console.log("[AssetTextures] Phase 2: Loading remaining assets..."),await Promise.all(a),console.log("[AssetTextures] All textures loaded:",Array.from(this.textures.keys()))})(),this.readyPromise}async priorityReady(){return this.priorityReadyPromise?this.priorityReadyPromise:Promise.resolve()}async waitFor(e,t={}){if(!this.config)throw new Error("[AssetTextures] Must call init() before waitFor() - config is null");if(!this.app)throw new Error("[AssetTextures] Must call init() before waitFor() - app is null");let n=Array.from(new Set((e||[]).filter(o=>typeof o=="string"&&o))).filter(o=>{var l,c,d,p;try{let u=(d=(c=(l=this.config)==null?void 0:l.objects)==null?void 0:c.get)==null?void 0:d.call(c,o);return!!((p=u==null?void 0:u.render)!=null&&p.asset)}catch{return!1}});if(n.length===0)return;this.ready().catch(()=>{});let a=()=>n.every(o=>this.textures.has(o)||this.attempted.has(o));if(a())return;let s=typeof t.timeoutMs=="number"?t.timeoutMs:15e3;await new Promise(o=>{let l=!1,c=()=>{l||a()&&(l=!0,this.waiters.delete(c),o())};this.waiters.add(c),c(),s>0&&setTimeout(()=>{l||(l=!0,this.waiters.delete(c),console.warn("[AssetTextures] waitFor timed out; continuing",{ids:n}),o())},s)})}get(e){return this.textures.get(e)}set(e,t){this.textures.set(e,t),console.log(`[AssetTextures] Updated texture: ${e}`)}clear(){this.textures.clear(),this.readyPromise=null,console.log("[AssetTextures] Cleared all textures")}getAllIds(){return Array.from(this.textures.keys())}},Ms=new zn,we=new Proxy(Ms,{get(r,e){return e in r&&typeof r[e]=="function"?r[e].bind(r):r.get(e)},set(r,e,t){return r.set(e,t),!0}})});var Ne={};at(Ne,{applyConfigOverride:()=>re,applyConfigOverrides:()=>$e,applyConfigsToDisk:()=>xi,clearConfigOverrides:()=>pe,clearConfigOverridesForObject:()=>Ds,configOverrideManager:()=>Ns,deepClone:()=>Q,exportConfigsAsJSON:()=>Xe,getConfigOverrides:()=>se,getConfigStateSummary:()=>De,getOverrideMode:()=>Rt,redoLastConfigChange:()=>wi,removeConfigOverride:()=>zt,resetToApplied:()=>$t,resetToOriginal:()=>Si,setOverrideMode:()=>qn,trackObjectCreation:()=>Hs,trackObjectDeletion:()=>Fs,undoLastConfigChange:()=>vi});function mi(){return typeof window=="undefined"?null:window.__editableConfig||null}function Bn(){return typeof window=="undefined"?null:window.__editableConfigBaseline||null}function Fn(r,e){var t,i;if(!r)return null;try{if(r instanceof Map)return(t=r.get(e))!=null?t:null;if(typeof r=="object")return(i=r[e])!=null?i:null}catch{}return null}function Wo(r,e,t){if(r){if(r instanceof Map){r.set(e,t);return}typeof r=="object"&&(r[e]=t)}}function Rs(r,e){for(let t of e)Ot(r,t.path,t.value)}function bi(r){var o;if(typeof window=="undefined")return;let e=mi();if(!e)return;let t=Bn(),i=(o=t?Fn(t.objects,r):null)!=null?o:Fn(e.objects,r);if(!i)return;let n=Q(i),a=se().filter(l=>l.objectId===r);try{Rs(n,a)}catch(l){console.error("[CONFIG] Failed to reapply overrides for object",r,l);return}Wo(e.objects,r,n);let s=window.applyEditableObjectConfig;if(typeof s=="function")try{s(r,n)}catch{}}function Gn(){var n;if(typeof window=="undefined")return;let r=mi();if(!(r!=null&&r.engine))return;let e=Bn(),t=Q(((n=e==null?void 0:e.engine)!=null?n:r.engine)||{}),i=se().filter(a=>!a.objectId&&!a.sceneId);try{Rs(t,i)}catch(a){console.error("[CONFIG] Failed to reapply engine overrides",a);return}try{let a=r.engine;for(let s of Object.keys(a))s in t||delete a[s];for(let[s,o]of Object.entries(t))a[s]=o}catch{r.engine=t}}function Ko(){if(typeof window=="undefined")return"unknown";let r=window;return typeof r.__HANDLER_PROJECT_ID=="string"?r.__HANDLER_PROJECT_ID:"handler-default"}function zs(){return`handler_preview_config_overrides::${Ko()}`}function Xo(){if(typeof window=="undefined")return[];try{let r=window.localStorage.getItem(zs());if(!r)return[];let e=JSON.parse(r);return Array.isArray(e)?e:[]}catch{return[]}}function yi(r){if(typeof window!="undefined")try{window.localStorage.setItem(zs(),JSON.stringify(r))}catch{}}function Rt(){return typeof window=="undefined"?!1:window.__enableConfigOverrides===!0}function qn(r){if(typeof window!="undefined"){window.__enableConfigOverrides=r;try{window.localStorage.setItem($s,r?"true":"false")}catch{}}}function re(r,e={}){var u,g;let{objectId:t,path:i,value:n}=r,{silent:a=!1,persist:s=!0,emitEvent:o=!0}=e,l=mi();if(!l){console.warn("[CONFIG] applyConfigOverride: No editable config found in window.__editableConfig");return}let c=t?(g=(u=l.objects)==null?void 0:u.get)==null?void 0:g.call(u,t):l.engine;if(!c){console.warn("[CONFIG] applyConfigOverride: Override target not found:",{objectId:t,path:i,hasObjects:!!l.objects});return}a||console.log("[CONFIG] applyConfigOverride: Target found, applying...",{objectId:t,path:i,value:n});let d;try{d=Bs(c,i),Ot(c,i,n)}catch(h){console.error("[CONFIG] applyConfigOverride failed:",{objectId:t,path:i,value:n},h);return}if(e.trackHistory!==!1){window.__configChanges=window.__configChanges||[];let h=window.__configChanges;h.push({objectId:t,path:i,oldValue:d,newValue:n,ts:Date.now()}),h.length>Un&&h.shift(),window.__configChangeRedo=[]}if(s){let h=se(),f=h.findIndex(m=>m.objectId===t&&m.sceneId===r.sceneId&&m.path===i);f>=0?h[f].value=n:h.push(r),window.__configOverrides=h,yi(h),Rt()||qn(!0)}a||console.log("[CONFIG] Applied override:",r),o&&typeof window!="undefined"&&window.dispatchEvent(new CustomEvent("config:changed",{detail:{...r,oldValue:d}}))}function $e(r,e={}){let t=e.emitEvent!==!1,i=[];for(let n of r)n!=null&&n.objectId&&typeof n.objectId=="string"&&i.push(n.objectId),re(n,{...e,emitEvent:!1});if(t&&typeof window!="undefined"){let n=Array.from(new Set(i));window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"batch",objectIds:n,count:r.length}}))}}function pe(){window.__configOverrides=[],window.__configChanges=[],window.__configChangeRedo=[],yi([]),console.log("[CONFIG] Cleared all overrides")}function Ds(r){let e=se().filter(i=>i.objectId!==r);window.__configOverrides=e,yi(e);let t=window.__configChanges||[];window.__configChanges=t.filter(i=>i.objectId!==r),bi(r),window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"clear_object",objectId:r}}))}function zt(r,e){let t=se().filter(n=>n.objectId!==r||n.path!==e);window.__configOverrides=t,yi(t);let i=window.__configChanges||[];window.__configChanges=i.filter(n=>n.objectId!==r||n.path!==e),r?bi(r):Gn(),window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"remove",objectId:r,path:e}}))}function se(){return typeof window=="undefined"?[]:(window.__configOverrides||(window.__configOverrides=Xo()),window.__configOverrides||[])}function vi(){var a;if(typeof window=="undefined")return!1;let r=window.__configChanges||[];if(r.length===0)return!1;let e=r.pop();window.__configChangeRedo=window.__configChangeRedo||[];let t=window.__configChangeRedo;if(e.changeType==="object_create"){let{screenId:s}=e.metadata||{};return e.objectId&&s&&fetch("/api/objects/delete",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:e.objectId,screenId:s})}).catch(o=>console.error("[CONFIG] Failed to delete object on undo:",o)),t.push({objectId:e.objectId,path:e.path,oldValue:e.newValue,newValue:e.oldValue,ts:Date.now(),changeType:e.changeType,metadata:e.metadata}),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),console.log("[CONFIG] Undo: Deleted object",e.objectId),!0}if(e.changeType==="object_delete"){let{screenId:s,objectConfigId:o}=e.metadata||{},l=e.oldValue;return e.objectId&&s&&l&&fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:s,instanceId:e.objectId,objectConfigId:o||((a=l==null?void 0:l.identity)==null?void 0:a.id),config:l})}).catch(c=>console.error("[CONFIG] Failed to recreate object on undo:",c)),t.push({objectId:e.objectId,path:e.path,oldValue:e.newValue,newValue:e.oldValue,ts:Date.now(),changeType:e.changeType,metadata:e.metadata}),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),console.log("[CONFIG] Undo: Recreated object",e.objectId),!0}t.push({objectId:e.objectId,path:e.path,oldValue:e.newValue,newValue:e.oldValue,ts:Date.now(),changeType:e.changeType});let i=Bn(),n=!1;if(i){let s=e.objectId?Fn(i.objects,e.objectId):i.engine;if(s){let o=Bs(s,e.path);JSON.stringify(o)===JSON.stringify(e.oldValue)&&(n=!0)}}return n?zt(e.objectId,e.path):(re({objectId:e.objectId,path:e.path,value:e.oldValue},{trackHistory:!1,persist:!0,emitEvent:!0}),e.objectId?bi(e.objectId):Gn()),console.log("[CONFIG] Undo:",e.path),!0}function wi(){var i;if(typeof window=="undefined")return!1;let r=window.__configChangeRedo||[];if(r.length===0)return!1;let e=r.pop();if(e.changeType==="object_create"){let{screenId:n,objectConfigId:a}=e.metadata||{},s=e.newValue;return e.objectId&&n&&s&&fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:n,instanceId:e.objectId,objectConfigId:a||((i=s==null?void 0:s.identity)==null?void 0:i.id),config:s})}).catch(l=>console.error("[CONFIG] Failed to recreate object on redo:",l)),window.__configChanges=window.__configChanges||[],window.__configChanges.push({objectId:e.objectId,path:e.path,oldValue:e.newValue,newValue:e.oldValue,ts:Date.now(),changeType:e.changeType,metadata:e.metadata}),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),console.log("[CONFIG] Redo: Recreated object",e.objectId),!0}if(e.changeType==="object_delete"){let{screenId:n}=e.metadata||{};return e.objectId&&n&&fetch("/api/objects/delete",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:e.objectId,screenId:n})}).catch(s=>console.error("[CONFIG] Failed to delete object on redo:",s)),window.__configChanges=window.__configChanges||[],window.__configChanges.push({objectId:e.objectId,path:e.path,oldValue:e.newValue,newValue:e.oldValue,ts:Date.now(),changeType:e.changeType,metadata:e.metadata}),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),console.log("[CONFIG] Redo: Deleted object",e.objectId),!0}return window.__configChanges=window.__configChanges||[],window.__configChanges.push({objectId:e.objectId,path:e.path,oldValue:e.newValue,newValue:e.oldValue,ts:Date.now(),changeType:e.changeType}),re({objectId:e.objectId,path:e.path,value:e.oldValue},{trackHistory:!1,persist:!0,emitEvent:!0}),e.objectId?bi(e.objectId):Gn(),console.log("[CONFIG] Redo:",e.path),!0}function Hs(r,e,t){var n;if(typeof window=="undefined")return;window.__configChanges=window.__configChanges||[];let i=window.__configChanges;i.push({objectId:r,path:"__object_create__",oldValue:null,newValue:t,ts:Date.now(),changeType:"object_create",metadata:{screenId:e,objectConfigId:(n=t==null?void 0:t.identity)==null?void 0:n.id}}),window.__configChangeRedo=[],i.length>Un&&i.shift(),console.log("[CONFIG] Tracked object creation:",r)}function Fs(r,e,t){if(typeof window=="undefined")return;window.__configChanges=window.__configChanges||[];let i=window.__configChanges;i.push({objectId:r,path:"__object_delete__",oldValue:t,newValue:null,ts:Date.now(),changeType:"object_delete",metadata:{screenId:e}}),window.__configChangeRedo=[],i.length>Un&&i.shift(),console.log("[CONFIG] Tracked object deletion:",r)}function Ot(r,e,t){var s;let i=e.split("."),n=i.pop(),a=r;for(let o of i){if(a[o]!==void 0&&typeof a[o]!="object")throw new Error(`Invalid override path: ${e} (hit primitive at ${o})`);a[o]=(s=a[o])!=null?s:{},a=a[o]}a[n]=t}function Bs(r,e){return e.split(".").reduce((t,i)=>t?t[i]:void 0,r)}function Q(r){if(r===null||typeof r!="object")return r;if(r instanceof Date)return new Date(r.getTime());if(r instanceof Set)return new Set([...r].map(t=>Q(t)));if(ArrayBuffer.isView(r))return r.slice();if(r instanceof Array)return r.map(t=>Q(t));if(r instanceof Map){let t=new Map;return r.forEach((i,n)=>t.set(n,Q(i))),t}let e={};for(let t in r)Object.prototype.hasOwnProperty.call(r,t)&&(e[t]=Q(r[t]));return e}function Xe(){let r=window.__editableConfigBaseline;if(!r){let e=window.__editableConfig;if(!e)throw new Error("Cannot export: no config loaded");return Os(e)}return Os(r)}function Os(r){let e={objects:{},scenes:{},engine:Q(r.engine||{})},t=r.objects;if(t instanceof Map)t.forEach((a,s)=>{e.objects[s]=Q(a)});else if(t&&typeof t=="object")for(let a in t)e.objects[a]=Q(t[a]);let i=r.scenes;if(i instanceof Map)i.forEach((a,s)=>{e.scenes[s]=Q(a)});else if(i&&typeof i=="object")for(let a in i)e.scenes[a]=Q(i[a]);let n=se();for(let a of n)a.objectId?(e.objects[a.objectId]||(e.objects[a.objectId]={}),Ot(e.objects[a.objectId],a.path,a.value)):a.sceneId?(e.scenes[a.sceneId]||(e.scenes[a.sceneId]={}),Ot(e.scenes[a.sceneId],a.path,a.value)):Ot(e.engine,a.path,a.value);return e}function De(){let r=se(),e=new Set;for(let t of r)t.objectId?e.add(t.objectId):e.add("__engine__");return{modifiedObjects:Array.from(e),overrideCount:r.length,hasChanges:r.length>0,overrides:r}}async function xi(r){let e=Xe(),t={};for(let[n,a]of Object.entries(e.objects)){let s=a,o=n;/^(json\.|ui\.|effects\.|engine\.)/.test(o)||(o=`json.${n}`),s&&typeof s=="object"&&(s.identity||(s.identity={}),s.identity.id=o),t[`objects/${o}.json`]=s}e.engine&&(e.engine.runtime&&(t["engine/engine.runtime.json"]=e.engine.runtime),e.engine.assets&&(t["engine/engine.assets.json"]=e.engine.assets),e.engine.splash&&(t["engine/engine.splash.json"]=e.engine.splash),e.engine.loading&&(t["engine/engine.loading.json"]=e.engine.loading),e.engine.start&&(t["engine/engine.start.json"]=e.engine.start),e.engine.tutorial&&(t["engine/engine.tutorial.json"]=e.engine.tutorial),e.engine.endgame&&(t["engine/engine.endgame.json"]=e.engine.endgame),!e.engine.runtime&&!e.engine.assets&&(t["engine/engine.json"]=e.engine));for(let[n,a]of Object.entries(e.scenes)){let s=n.startsWith("scene.")?n:`scene.${n}`;t[`scenes/${s}.json`]=a}let i=await fetch("/api/apply",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({configs:t,assets:{},hadCacheAtApply:se().length>0,versionName:r})});if(!i.ok){let n=await i.json();throw new Error(`Apply failed: ${n.error||"Unknown error"}`)}pe();try{let n=mi();n&&(window.__editableConfigBaseline=Q(n))}catch{}localStorage.setItem("handler_last_applied",Date.now().toString()),console.log("[Config Persistence] \u2705 Applied to disk successfully")}function $t(){pe(),window.location.reload()}async function Si(){if(!confirm("This will restore all configs to their original state. All uncommitted changes in cache AND applied changes will be lost. Continue?"))return;let e=await fetch("/api/reset-to-original",{method:"POST"});if(!e.ok){let t=await e.json();throw new Error(`Reset failed: ${t.error||"Unknown error"}`)}pe(),window.location.reload()}var $s,Un,Ns,ee=be(()=>{"use strict";$s="handler_preview_override_mode";if(typeof window!="undefined"){let r=window.localStorage.getItem($s);window.__enableConfigOverrides=r===null?!0:r==="true"}Un=500;Ns={getCurrentConfig(){return window.__editableConfig||null},getChanges(){return window.__configChanges||[]},clearChanges(){window.__configChanges=[],window.__configChangeRedo=[]}}});function Jo(r,e){try{if(typeof r=="object"&&r!==null)return r;if(typeof r!="string")return null;if(r.startsWith("data:")){let i=r.indexOf(",");if(i===-1)return null;let n=r.slice(0,i);if(!n.includes("application/json")&&!n.includes("text/plain"))return null;let a=r.slice(i+1),s=n.includes("base64")?typeof atob=="function"?atob(a):a:decodeURIComponent(a);return JSON.parse(s)}let t=r.trim();return t.startsWith("{")||t.startsWith("[")?JSON.parse(r):null}catch{return null}}function Zo(r){if(typeof window=="undefined"||!window.INLINE_ASSETS)return null;let e=window.INLINE_ASSETS,t=r.replace(/^\.\/+/,""),i=t.split("/").pop()||t,n=[t,i,t.replace(/\.json$/,""),i.replace(/\.json$/,"")];for(let a of n){let s=e[a];if(s){let o=Jo(s,a);if(o!==null)return o}}return null}async function Dt(r){if(Vn.has(r)&&!Yn)return console.log(`[CONFIG] Using cached config for: "${r}"`),Vn.get(r);if(console.log(`[CONFIG] loadConfigFile called with: "${r}", MODE: ${V.toUpperCase()}, CACHE: ${Yn?"DISABLED":"ENABLED"}`),V==="publish"){let i=Zo(r);return i?(console.log(`[CONFIG] \u2713 Loaded ${r} via INLINE_ASSETS`),i):(console.log(`[CONFIG] \u2139\uFE0F Optional config ${r} not in INLINE_ASSETS, skipping fetch in publish mode`),{})}V==="brand"||console.log(`[CONFIG] DEV MODE: Trying nested paths first, then flattened for "${r}"`);let e;V==="brand"?e=[`./${r.split("/").pop()||r}`,`./${r}`,`./${r.replace(/^configs\//,"")}`,`./${r.replace(/^configs\//,"").replace(/\//g,".")}`]:e=[`./${r}`,`./${r.replace(/^configs\//,"")}`,`./${r.replace(/^configs\//,"").replace(/\//g,".")}`],e=Array.from(new Set(e.flatMap(i=>i.startsWith("./")?[i,`/${i.slice(2)}`]:i.startsWith("/")?[i]:[i,`/${i}`]))),console.log("[CONFIG] Will try candidates:",e);let t=(async()=>{let i=Yn?"no-store":"force-cache";for(let n of e)try{let a=await fetch(n,{cache:i});if(!a.ok)continue;let s=await a.json();return console.log(`[CONFIG] \u2713 Loaded ${r} via ${n}`,s),s}catch(a){console.warn(`[CONFIG] \u2717 Failed to load ${n} (mode: ${V}):`,a)}return console.warn(`[CONFIG] \u2717 All attempts failed for ${r}; using defaults`),{}})();return Vn.set(r,t),t}async function Ei(){console.log("[CONFIG] Loading component schemas...");let r=["components/identity.schema.json","components/transform.schema.json","components/render.schema.json","components/motion.schema.json","components/effects.schema.json","components/interaction.schema.json","components/gameplay.rules.schema.json","components/gameplay.tuning.schema.json","components/visibility.schema.json","components/audio.schema.json","components/physics.schema.json","components/ui.schema.json"],e=new Map;for(let t of r)try{let i=V==="publish"||V==="brand"?t.split("/").pop()||t:`configs/${t}`,n=await Dt(i);n.component&&(e.set(n.component,n),console.log(`[CONFIG] \u2713 Schema loaded: ${n.component} ${V==="publish"||V==="brand"?"(flattened)":"(nested)"}`))}catch(i){console.warn(`[CONFIG] \u2717 Failed to load schema ${t}:`,i)}return console.log(`[CONFIG] Loaded ${e.size} component schemas`),e}async function He(r){console.log(`[CONFIG] Loading object config: ${r}`);let e=V==="publish"||V==="brand"?`${r}.json`:`configs/objects/${r}.json`;return await Dt(e)}async function Ci(r){let e=new Map;if(r.objects&&Array.isArray(r.objects)){for(let t of r.objects)if(t.enabled&&t.object_config)try{let i=t.instance_id;/^(json\.|ui\.|effects\.|engine\.)/.test(i)||(i=`json.${i}`);let n=await He(i);(!n||Object.keys(n).length===0)&&i!==t.instance_id&&(n=await He(t.instance_id)),!n||Object.keys(n).length===0?(console.log(`[CONFIG] No instance snapshot for ${t.instance_id}, using template ${t.object_config}`),n=await He(t.object_config)):console.log(`[CONFIG] \u2713 Loaded instance snapshot for ${t.instance_id}`),e.set(t.instance_id,{...n,instance_id:t.instance_id,object_config:t.object_config})}catch(i){console.warn(`Failed to load object ${t.object_config}:`,i)}}return e}async function Ai(){console.log("[CONFIG] Loading engine configs...");let r=["runtime","assets","splash","loading","start","tutorial","endgame"],e=await Promise.all(r.map(i=>{let n=`engine.${i}.json`,a=V==="publish"||V==="brand"?n:`configs/engine/${n}`;return Dt(a)})),t=Object.fromEntries(r.map((i,n)=>[i,e[n]]));return console.log("[CONFIG] Engine configs loaded:",Object.fromEntries(r.map(i=>{var s;let n=(s=t[i])!=null?s:{},a=Object.keys(n);return[i,a.length>0?a:"empty"]}))),t}async function Wn(){return await Dt(V==="publish"||V==="brand"?"game.prompt.json":"configs/engine/game.prompt.json")}async function Li(r="scene.main"){console.log(`[CONFIG] Loading scene config: ${r}`);let e=V==="publish"||V==="brand"?`${r}.json`:`configs/scenes/${r}.json`;return await Dt(e)}function pt(r,e){let t=[];if(!r.identity)return t.push("Missing required identity component"),{valid:!1,errors:t};let i=e.get("identity");if(i)for(let n of i.required||[])r.identity[n]||t.push(`Missing required identity field: ${n}`);for(let[n,a]of Object.entries(r)){if(n==="identity")continue;let s=e.get(n);if(s&&a&&typeof a=="object"){let o=a;for(let l of s.required||[])o[l]===void 0&&t.push(`Missing required field in ${n}: ${l}`);if(s.constraints&&typeof s.constraints=="object")for(let[l,c]of Object.entries(s.constraints)){let d=o[l];if(d!==void 0&&c&&typeof c=="object"){let p=c;typeof d=="number"&&(p.min!==void 0&&d<p.min&&t.push(`${n}.${l} value ${d} is below minimum ${p.min}`),p.max!==void 0&&d>p.max&&t.push(`${n}.${l} value ${d} is above maximum ${p.max}`))}}}}return{valid:t.length===0,errors:t}}function Je(r,e){let t={...r},i=["identity","transform","render"];for(let[n,a]of e.entries())a.defaults&&Object.keys(a.defaults).length>0&&(i.includes(n)||t[n])&&(t[n]||(t[n]={}),t[n]={...a.defaults,...t[n]});return t}function ue(r,e,t,i){return typeof r!="number"||!Number.isFinite(r)?e:Math.min(Math.max(r,t),i)}function Us(r,e){if(Array.isArray(r))return{x:ue(r[0],e.x,-2e3,2e3),y:ue(r[1],e.y,-2e3,2e3)};if(!r||typeof r!="object")return e;let{x:t,y:i}=r;return{x:ue(t,e.x,-2e3,2e3),y:ue(i,e.y,-2e3,2e3)}}function Qo(r,e){if(Array.isArray(r))return{x:ue(r[0],e.x,0,1),y:ue(r[1],e.y,0,1)};if(!r||typeof r!="object")return e;let{x:t,y:i}=r;return{x:ue(t,e.x,0,1),y:ue(i,e.y,0,1)}}function el(r){if(Array.isArray(r))return{x:ue(r[0],.5,-10,10),y:ue(r[1],.5,-10,10)};if(r&&typeof r=="object"){let{x:e,y:t}=r;return{x:ue(e,.5,-10,10),y:ue(t,.5,-10,10)}}return typeof r=="string"?r:null}async function Ie(r="scene.main",e){var l,c,d,p,u,g,h,f,m,b,y,v,w,T;console.log("[CONFIG] ===== Starting Object-Centric Config Load =====");let t=await Ei(),i=se();i.length>0&&console.log(`[CONFIG] Applying ${i.length} active overrides`);let n=await Li(r);console.log(`[CONFIG] Scene config loaded: ${((l=n.objects)==null?void 0:l.length)||0} objects`);let a=await Ai();console.log("[CONFIG] Loading object configs...");let s=await Ci(n);console.log(`[CONFIG] Loaded ${s.size} object configs:`,Array.from(s.keys()));for(let[I,M]of s.entries()){let L=Je(M,t),j=pt(L,t);j.valid||console.warn(`Object ${I} validation errors:`,j.errors),(c=L.transform)!=null&&c.position&&(L.transform.position=Us(L.transform.position,{x:0,y:0})),(d=L.transform)!=null&&d.offset&&(L.transform.offset=Us(L.transform.offset,{x:0,y:0})),((p=L.transform)==null?void 0:p.anchor)!==void 0&&(L.transform.anchor=el(L.transform.anchor)),((u=L.transform)==null?void 0:u.position_ratio)!==void 0&&L.transform.position_ratio!==null&&(L.transform.position_ratio=Qo(L.transform.position_ratio,{x:.5,y:.5})),s.set(I,L)}if(e){if(e.objects)for(let[I,M]of e.objects.entries())s.set(I,M);e.engine&&(a.runtime={...a.runtime,...e.engine.runtime},a.assets={...a.assets,...e.engine.assets},a.splash={...(g=a.splash)!=null?g:{},...(h=e.engine.splash)!=null?h:{}})}let o={objects:s,engine:a,scene:n,schemas:t,theme:{background_color:"#ffffff",text_color:"#000000",square_color:"#cccccc",cta_background:"#007bff",cta_text:"#ffffff"},gameplay:{}};return typeof window!="undefined"&&(window.__editableConfig=o,window.__editableConfigBaseline||(window.__editableConfigBaseline=Je(o,t))),i.length>0&&Rt()&&$e(i,{silent:!0,persist:!1}),console.log("[CONFIG] ===== Object-Centric Config Load Complete ====="),console.log("[CONFIG] Summary:",{schemas:Array.from(t.keys()),objects:Array.from(s.keys()),engine:{runtime:Object.keys((f=a.runtime)!=null?f:{}),assets:Object.keys((m=a.assets)!=null?m:{}),splash:Object.keys((b=a.splash)!=null?b:{}),loading:Object.keys((y=a.loading)!=null?y:{}),start:Object.keys((v=a.start)!=null?v:{}),tutorial:Object.keys((w=a.tutorial)!=null?w:{}),endgame:Object.keys((T=a.endgame)!=null?T:{})},scene:n.scene_id||"unknown"}),o}function Kn(r){var t,i,n,a,s,o,l,c,d,p,u,g,h,f,m,b,y,v,w,T,I,M,L,j,_,P,x,S,A,E,C,O,k;let e={gameplay:{},ui:{},theme:{},assets:{}};for(let[R,z]of r.objects.entries()){let D=((t=z.identity)==null?void 0:t.id)||R;D.includes("character")&&(e.gameplay.character_pos=((i=z.transform)==null?void 0:i.position)||{x:0,y:0},e.gameplay.character_scale=((n=z.transform)==null?void 0:n.scale)||1,e.gameplay.character_anim_speed=((s=(a=z.gameplay)==null?void 0:a.tuning)==null?void 0:s.anim_speed)||.003,e.gameplay.character_relief_scale=((l=(o=z.gameplay)==null?void 0:o.tuning)==null?void 0:l.relief_scale)||1.22,e.gameplay.character_relief_speed=((d=(c=z.gameplay)==null?void 0:c.tuning)==null?void 0:d.relief_speed)||.22),(D.includes("gun")||D.includes("flame"))&&(e.gameplay.gun=z.gun||{},e.gameplay.gunmuzzle=((p=z.effects)==null?void 0:p.gunmuzzle)||{},e.gameplay.muzzle_levels=((u=z.effects)==null?void 0:u.muzzle_levels)||{},e.gameplay.flame=((g=z.effects)==null?void 0:g.flame)||{}),D.includes("diamond")&&(e.gameplay.diamond=z),D.includes("ice")&&(e.gameplay.melt=z.melt||{},e.gameplay.melt_anchor=((h=z.transform)==null?void 0:h.melt_anchor)||{x:0,y:0},e.gameplay.melt_pos=((f=z.transform)==null?void 0:f.position)||{x:0,y:0},e.gameplay.hybrid_melting=((m=z.effects)==null?void 0:m.hybrid_melting)||{},e.gameplay.physics_chunks=((b=z.effects)==null?void 0:b.physics_chunks)||{},e.gameplay.melting_particles=((y=z.effects)==null?void 0:y.melting_particles)||{},e.gameplay.hard_ice=z.hard_ice||{}),D.includes("water")&&(e.gameplay.water_drops=z),D.includes("crack")&&(e.gameplay.crack=z),D.includes("hand")&&(e.gameplay.hand=((v=z.gameplay)==null?void 0:v.tuning)||{},e.gameplay.brush_start_pos=((w=z.transform)==null?void 0:w.brush_start_pos)||{x:0,y:-120},e.gameplay.hand_scale=((T=z.transform)==null?void 0:T.scale)||1.5),D.includes("hazard")&&(e.gameplay.hazard=((I=z.gameplay)==null?void 0:I.tuning)||{},e.gameplay.danger_pos=((M=z.transform)==null?void 0:M.danger_pos)||{x:0,y:235},e.gameplay.danger_pulse=((j=(L=z.gameplay)==null?void 0:L.tuning)==null?void 0:j.danger_pulse)||{},e.gameplay.hazard_height=((P=(_=z.gameplay)==null?void 0:_.tuning)==null?void 0:P.hazard_height)||140)}return e.gameplay.timeline=((x=r.engine.runtime)==null?void 0:x.timeline)||{},e.gameplay.drag_surface=((S=r.engine.runtime)==null?void 0:S.drag_surface)||{},e.gameplay.background=((A=r.engine.runtime)==null?void 0:A.background)||{},e.gameplay.ui_styles=((E=r.engine.runtime)==null?void 0:E.ui_styles)||{},e.gameplay.label_pulse=((C=r.engine.runtime)==null?void 0:C.label_pulse)||{},e.ui=((O=r.engine.runtime)==null?void 0:O.ui)||{},e.theme=((k=r.engine.runtime)==null?void 0:k.theme)||{},e.assets=r.engine.assets||{},e}var Gs,V,Vn,Yn,Xn=be(()=>{"use strict";ee();Gs=null,V="dev";if(typeof window!="undefined"){let r=window.__BUILD_SETTINGS__;if(r!=null&&r.buildMode)Gs=r,V=r.buildMode,console.log("[CONFIG] Loaded inline build settings:",r,"buildMode:",V);else try{let e=new XMLHttpRequest;if(e.open("GET","./build-settings.json",!1),e.send(),e.status===200&&e.responseText){let t=JSON.parse(e.responseText);Gs=t,V=t.buildMode||"dev",console.log("[CONFIG] Loaded build settings:",t,"buildMode:",V)}else console.log("[CONFIG] No build-settings.json found, using default buildMode:",V)}catch(e){console.log("[CONFIG] Failed to load build-settings.json:",e instanceof Error?e.message:String(e))}}console.log("[CONFIG] Final buildMode:",V);Vn=new Map,Yn=V==="dev"||typeof window!="undefined"&&window.location.search.includes("hot-reload")});function Jn(r,e){let t=[];function i(n,a,s=""){if(n!==a){if(typeof n!=typeof a){t.push(`${s}: type changed`);return}if(typeof n=="object"&&n!==null&&a!==null){let o=new Set([...Object.keys(n),...Object.keys(a)]);for(let l of o){let c=s?`${s}.${l}`:l;l in n?l in a?i(n[l],a[l],c):t.push(`${c}: removed`):t.push(`${c}: added`)}}else t.push(`${s}: changed`)}}return i(r,e),t}function Zn(r,e,t,i){let n={...t};for(let[a,s]of i.entries())n[a]&&s.defaults&&(n[a]={...s.defaults,...n[a]});return n}var Nt,Ze,Qn=be(()=>{"use strict";Nt=class{shouldFullReload(e){return e.type==="component"||e.type==="scene"}getAffectedObjects(e){return e.type==="object"&&e.objectId?[e.objectId]:[]}},Ze=class{constructor(e=1e3){this.pollingInterval=null;this.fileHashes=new Map;this.callbacks=new Map;this.intervalMs=e}watch(e,t){this.callbacks.set(e,t),this.pollingInterval===null&&(this.pollingInterval=window.setInterval(()=>{this.checkAllFiles()},this.intervalMs))}async checkAllFiles(){for(let[e,t]of this.callbacks.entries())try{let i=`${e}?t=${Date.now()}&r=${Math.random()}`,n=await fetch(i,{cache:"no-cache",headers:{"Cache-Control":"no-cache"}});if(n.ok){let a=await n.text(),s=this.hashString(a),o=this.fileHashes.get(e);if(o&&o!==s&&console.log(`[HOT-RELOAD] File changed: ${e}`),o&&o!==s){console.log(`[HOT-RELOAD] File changed: ${e}`);let l=this.determineEventType(e);t(l),this.fileHashes.set(e,s)}else o||this.fileHashes.set(e,s)}}catch(i){console.warn(`Failed to check ${e}:`,i)}}determineEventType(e){var t,i;return e.includes("/components/")?{type:"component",path:e,componentName:(t=e.split("/").pop())==null?void 0:t.replace(".schema.json","")}:e.includes("/engine/")?{type:"engine",path:e}:e.includes("/scenes/")?{type:"scene",path:e}:e.includes("/objects/")?{type:"object",path:e,objectId:(i=e.split("/").pop())==null?void 0:i.replace(".json","")}:{type:"object",path:e}}hashString(e){let t=0;for(let i=0;i<e.length;i++){let n=e.charCodeAt(i);t=(t<<5)-t+n,t=t&t}return t.toString()}unwatch(e){this.callbacks.delete(e),this.fileHashes.delete(e)}stop(){this.pollingInterval!==null&&(clearInterval(this.pollingInterval),this.pollingInterval=null),this.callbacks.clear(),this.fileHashes.clear()}}});function ta(r){if(typeof window=="undefined")return;let e=typeof ea!="undefined"&&!!ea.hot,t=window.location.search.includes("hot-reload");if(!(e||t))return;let n=null,a=!1,s=null;if(t){s=new Ze;let h=window.__configWatcher;h!=null&&h.stop&&h.stop(),window.__configWatcher=s}let o=new Set,l=h=>{var b,y;if(!s)return;let f=new Set;f.add("configs/engine/engine.runtime.json"),f.add("configs/engine/engine.assets.json"),f.add("configs/engine/engine.splash.json"),f.add("configs/scenes/scene.main.json");let m=(y=(b=h.scene)==null?void 0:b.objects)!=null?y:[];for(let v of m)v!=null&&v.object_config&&f.add(`configs/objects/${v.object_config}.json`);for(let v of o)f.has(v)||s.unwatch(v);for(let v of f)o.has(v)||s.watch(v,w=>g(w));o=f},c=new Set,d=!1,p=async h=>{let f=await He(h),m=Je(f,r.activeConfig.schemas),b=pt(m,r.activeConfig.schemas);b.valid||console.warn(`[HOT-RELOAD] ${h} validation errors:`,b.errors),await r.liveEditBridge.applyObjectConfig(h,m)};async function u(h){if(!a){a=!0;try{if(d||c.size===0){r.audioSystem.destroy();let f=await Ie("scene.main");r.setActiveConfig(f),r.gameObjectManager.updateConfig(f),r.CustomAssets.updateConfig(f),await r.CustomAssets.ready();let m=r.createAudioSystem(f);r.setAudioSystem(m),window.__audioSystem=m,await m.start(),r.liveEditBridge.rebuildIndexes(),l(f),console.log(`[GAME] Hot-reload complete (${h})`)}else{let f=Array.from(c);c.clear();for(let m of f)await p(m);console.log(`[GAME] Hot-reload updated objects: ${f.join(", ")}`)}}catch(f){console.warn("[GAME] Hot-reload failed:",f)}finally{a=!1,d=!1,c.clear()}}}function g(h){h.type==="object"&&h.objectId?c.add(h.objectId):d=!0,n&&window.clearTimeout(n),n=window.setTimeout(()=>{u(h.type)},120)}e&&ea.hot.on("config-change",()=>{g({type:"hmr"})}),t&&(l(r.activeConfig),console.log(`[GAME] Hot-reload watcher enabled (${o.size} files)`))}var ea,qs=be(()=>{"use strict";Qn();Xn();ea={}});var Vs={};at(Vs,{ConfigWatcher:()=>Ze,DefaultReloadStrategy:()=>Nt,applyDefaults:()=>Je,diffConfigs:()=>Jn,loadAllObjectConfigs:()=>Ci,loadComponentSchemas:()=>Ei,loadEngineConfig:()=>Ai,loadGamePromptConfig:()=>Wn,loadObjectCentricConfig:()=>Ie,loadObjectConfig:()=>He,loadSceneConfig:()=>Li,rehydrateObject:()=>Zn,setupHotReload:()=>ta,toLegacyFormat:()=>Kn,validateObjectConfig:()=>pt});var Ti=be(()=>{"use strict";Xn();Qn();qs()});var Ht={};at(Ht,{AssetEditorModal:()=>ra});var ra,ut=be(()=>{"use strict";ra=class{constructor(){this.modal=null;this.currentObjectId=null;this.currentPath=null;this.currentAsset="";this.onApplyCallback=null}show(e,t,i,n){this.currentObjectId=e,this.currentPath=t,this.currentAsset=i,this.onApplyCallback=n,this.createModal(e,i),document.body.appendChild(this.modal),this.attachModalListeners()}createModal(e,t){let i=document.createElement("div");i.className="asset-editor-modal",i.innerHTML=`
|
|
2
2
|
<div class="asset-editor-card">
|
|
3
3
|
<div class="asset-editor-header">
|
|
4
4
|
<div>
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
<button class="debug-btn primary" data-modal-apply>Apply</button>
|
|
44
44
|
</div>
|
|
45
45
|
</div>
|
|
46
|
-
`,this.modal=i}attachModalListeners(){if(!this.modal)return;this.modal.querySelectorAll("[data-modal-close]").forEach(
|
|
46
|
+
`,this.modal=i}attachModalListeners(){if(!this.modal)return;this.modal.querySelectorAll("[data-modal-close]").forEach(s=>{s.addEventListener("click",()=>this.close())}),this.modal.querySelectorAll("[data-tab]").forEach(s=>{s.addEventListener("click",o=>{let c=o.target.dataset.tab;c&&this.switchTab(c)})});let i=this.modal.querySelector("[data-ai-generate]");i==null||i.addEventListener("click",()=>{this.openAiEditor("generate")});let n=this.modal.querySelector("[data-ai-edit]");n==null||n.addEventListener("click",()=>{this.openAiEditor("edit")});let a=this.modal.querySelector("[data-modal-apply]");a==null||a.addEventListener("click",()=>{this.apply()}),this.modal.addEventListener("click",s=>{s.target===this.modal&&this.close()})}switchTab(e){if(!this.modal)return;this.modal.querySelectorAll("[data-tab]").forEach(n=>{n.classList.toggle("active",n.getAttribute("data-tab")===e)}),this.modal.querySelectorAll("[data-tab-panel]").forEach(n=>{n.classList.toggle("active",n.getAttribute("data-tab-panel")===e)})}openAiEditor(e){let t=window.__openAiEditor;if(typeof t!="function"){alert("AI Editor not available. Please check your setup.");return}let i="";e==="edit"&&this.currentAsset?i=`Edit this image: ${this.currentObjectId}`:i=`Create an image for: ${this.currentObjectId}`,t(this.currentObjectId||"unknown",i,this.currentAsset,{path:this.currentPath,onApply:n=>{this.onApplyCallback&&this.onApplyCallback(n),this.close()}})}apply(){this.onApplyCallback&&this.onApplyCallback("library/placeholder.png"),this.close()}close(){this.modal&&this.modal.parentNode&&this.modal.parentNode.removeChild(this.modal),this.modal=null,this.currentObjectId=null,this.currentPath=null,this.onApplyCallback=null}}});var Ws={};at(Ws,{AssetCropModal:()=>Mi});var Mi,oa=be(()=>{"use strict";Mi=class{constructor(){this.modal=null;this.canvas=null;this.ctx=null;this.image=null;this.options=null;this.cropX=0;this.cropY=0;this.cropWidth=100;this.cropHeight=100;this.scale=1;this.panX=0;this.panY=0;this.isDragging=!1;this.dragStartX=0;this.dragStartY=0;this.lastPanX=0;this.lastPanY=0}open(e){this.options=e,this.createModal(),this.loadImage(),document.body.appendChild(this.modal)}createModal(){let e=document.createElement("div");e.className="asset-crop-modal",e.innerHTML=`
|
|
47
47
|
<div class="asset-crop-card">
|
|
48
48
|
<div class="asset-crop-header">
|
|
49
49
|
<div>
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
<button class="asset-crop-apply primary" data-action="apply">Apply Crop</button>
|
|
95
95
|
</div>
|
|
96
96
|
</div>
|
|
97
|
-
`,this.modal=e,this.attachEventListeners(),this.initializeCanvas()}initializeCanvas(){this.modal&&(this.canvas=this.modal.querySelector(".asset-crop-canvas"),this.canvas&&(this.ctx=this.canvas.getContext("2d"),this.canvas.width=400,this.canvas.height=300))}loadImage(){this.options&&(this.image=new Image,this.image.crossOrigin="anonymous",this.image.onload=()=>{this.initializeCrop(),this.render()},this.image.src=this.options.imageSrc)}initializeCrop(){var i;if(!this.image||!this.canvas)return;let e=this.image.width/this.image.height,t=this.canvas.width/this.canvas.height;e>t?(this.cropHeight=this.image.height,this.cropWidth=this.cropHeight*t,this.cropX=(this.image.width-this.cropWidth)/2,this.cropY=0):(this.cropWidth=this.image.width,this.cropHeight=this.cropWidth/t,this.cropX=0,this.cropY=(this.image.height-this.cropHeight)/2),(i=this.options)!=null&&i.aspectRatio&&this.applyAspectRatio(this.options.aspectRatio),this.fitToCanvas()}applyAspectRatio(e){if(!this.image)return;let t=this.image.width/this.image.height,i=this.cropX+this.cropWidth/2,n=this.cropY+this.cropHeight/2;e>t?(this.cropWidth=Math.min(this.image.width,this.cropHeight*e),this.cropHeight=this.cropWidth/e):(this.cropHeight=Math.min(this.image.height,this.cropWidth/e),this.cropWidth=this.cropHeight*e),this.cropX=Math.max(0,Math.min(this.image.width-this.cropWidth,i-this.cropWidth/2)),this.cropY=Math.max(0,Math.min(this.image.height-this.cropHeight,n-this.cropHeight/2))}fitToCanvas(){if(!this.image||!this.canvas)return;let e=this.canvas.width/this.cropWidth,t=this.canvas.height/this.cropHeight;this.scale=Math.min(e,t)*.9,this.panX=(this.canvas.width-this.cropWidth*this.scale)/2,this.panY=(this.canvas.height-this.cropHeight*this.scale)/2}render(){!this.ctx||!this.image||!this.canvas||(this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.ctx.save(),this.ctx.translate(this.panX,this.panY),this.ctx.scale(this.scale,this.scale),this.ctx.drawImage(this.image,-this.cropX,-this.cropY,this.image.width,this.image.height),this.ctx.restore(),this.drawCropOverlay(),this.updatePreview())}drawCropOverlay(){if(!this.ctx||!this.canvas)return;let e=this.panX,t=this.panY,i=this.cropWidth*this.scale,n=this.cropHeight*this.scale;this.ctx.fillStyle="rgba(0, 0, 0, 0.5)",this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height),this.ctx.clearRect(e,t,i,n),this.ctx.strokeStyle="#ffffff",this.ctx.lineWidth=2,this.ctx.strokeRect(e,t,i,n),this.ctx.fillStyle="#ffffff";let a=8;[[e,t],[e+i-a,t],[e,t+n-a],[e+i-a,t+n-a]].forEach(([o,l])=>{var c;(c=this.ctx)==null||c.fillRect(o,l,a,a)})}updatePreview(){if(!this.modal||!this.image)return;let e=this.modal.querySelector(".asset-crop-preview-canvas");if(!e)return;let t=e.getContext("2d");if(!t)return;let i=150;e.width=i,e.height=i;let n=i/this.cropWidth,a=i/this.cropHeight,r=Math.min(n,a),o=this.cropWidth*r,l=this.cropHeight*r,c=(i-o)/2,d=(i-l)/2;t.drawImage(this.image,this.cropX,this.cropY,this.cropWidth,this.cropHeight,c,d,o,l)}attachEventListeners(){if(!this.modal||!this.canvas)return;this.canvas.addEventListener("mousedown",this.handleMouseDown.bind(this)),this.canvas.addEventListener("mousemove",this.handleMouseMove.bind(this)),this.canvas.addEventListener("mouseup",this.handleMouseUp.bind(this)),this.canvas.addEventListener("wheel",this.handleWheel.bind(this)),this.canvas.addEventListener("touchstart",this.handleTouchStart.bind(this)),this.canvas.addEventListener("touchmove",this.handleTouchMove.bind(this)),this.canvas.addEventListener("touchend",this.handleTouchEnd.bind(this));let e=this.modal.querySelector(".asset-crop-zoom-slider");e==null||e.addEventListener("input",i=>{let n=parseFloat(i.target.value);this.setZoom(n)});let t=this.modal.querySelector(".asset-crop-aspect-select");t==null||t.addEventListener("change",i=>{let n=i.target.value;this.setAspectRatio(n)}),this.modal.addEventListener("click",i=>{switch(i.target.dataset.action){case"reset":this.reset();break;case"apply":this.applyCrop();break;case"cancel":case"close":this.close();break}}),this.modal.addEventListener("click",i=>{i.target===this.modal&&this.close()})}handleMouseDown(e){this.isDragging=!0,this.dragStartX=e.clientX,this.dragStartY=e.clientY,this.lastPanX=this.panX,this.lastPanY=this.panY,this.canvas.style.cursor="grabbing"}handleMouseMove(e){if(!this.isDragging)return;let t=e.clientX-this.dragStartX,i=e.clientY-this.dragStartY;this.panX=this.lastPanX+t,this.panY=this.lastPanY+i,this.constrainPan(),this.render()}handleMouseUp(){this.isDragging=!1,this.canvas.style.cursor="grab"}handleWheel(e){e.preventDefault();let t=e.deltaY>0?.9:1.1;this.setZoom(this.scale*t)}handleTouchStart(e){e.touches.length===1&&(this.isDragging=!0,this.dragStartX=e.touches[0].clientX,this.dragStartY=e.touches[0].clientY,this.lastPanX=this.panX,this.lastPanY=this.panY)}handleTouchMove(e){if(!this.isDragging||e.touches.length!==1)return;e.preventDefault();let t=e.touches[0].clientX-this.dragStartX,i=e.touches[0].clientY-this.dragStartY;this.panX=this.lastPanX+t,this.panY=this.lastPanY+i,this.constrainPan(),this.render()}handleTouchEnd(){this.isDragging=!1}setZoom(e){this.scale=Math.max(.1,Math.min(3,e)),this.updateZoomUI(),this.constrainPan(),this.render()}setAspectRatio(e){let t;switch(e){case"1:1":t=1;break;case"4:3":t=4/3;break;case"16:9":t=16/9;break;case"3:2":t=3/2;break;default:t=void 0}t&&this.applyAspectRatio(t),this.fitToCanvas(),this.render()}updateZoomUI(){if(!this.modal)return;let e=this.modal.querySelector(".asset-crop-zoom-value"),t=this.modal.querySelector(".asset-crop-zoom-slider");e&&(e.textContent=`${this.scale.toFixed(1)}x`),t&&(t.value=this.scale.toString())}constrainPan(){if(!this.canvas)return;let e=this.cropWidth*this.scale,t=this.cropHeight*this.scale;this.panX=Math.max(this.canvas.width-e,Math.min(0,this.panX)),this.panY=Math.max(this.canvas.height-t,Math.min(0,this.panY))}reset(){this.initializeCrop(),this.render()}applyCrop(){var n;if(!this.image||!((n=this.options)!=null&&n.onCrop))return;let e=document.createElement("canvas"),t=e.getContext("2d");if(!t)return;e.width=this.cropWidth,e.height=this.cropHeight,t.drawImage(this.image,this.cropX,this.cropY,this.cropWidth,this.cropHeight,0,0,this.cropWidth,this.cropHeight);let i=e.toDataURL("image/png");this.options.onCrop(i),this.close()}close(){this.modal&&this.modal.parentNode&&this.modal.parentNode.removeChild(this.modal);let e=this.options;this.modal=null,this.canvas=null,this.ctx=null,this.image=null,this.options=null,e!=null&&e.onCancel&&e.onCancel()}};window.openAssetCrop=function(s){new Mi().open(s)}});var Dl={};at(Dl,{COLORS:()=>Ee,ConfigWatcher:()=>Ze,DebugPanel:()=>Yt,DefaultReloadStrategy:()=>Nt,Handler:()=>me,PlayableLoadingScreen:()=>mn,PreviewShell:()=>gn,STROKE_WIDTH:()=>Fr,THEME:()=>Br,applyConfigOverride:()=>re,applyConfigOverrides:()=>$e,applyConfigsToDisk:()=>xi,applyDefaults:()=>Je,baseLottie:()=>In,bootstrap:()=>Tl,clearConfigOverrides:()=>pe,clearConfigOverridesForObject:()=>Ds,configOverrideManager:()=>Ns,createPreviewShell:()=>$a,deepClone:()=>Q,default:()=>qe,defaultPreset:()=>ki,deviceGroups:()=>aa,devicePresets:()=>na,diffConfigs:()=>Jn,exportConfigsAsJSON:()=>Xe,getConfigOverrides:()=>se,getConfigStateSummary:()=>De,getOverrideMode:()=>Rt,getPresetById:()=>Qe,getPresetsByCategory:()=>tl,loadAllObjectConfigs:()=>Ci,loadComponentSchemas:()=>Ei,loadEngineConfig:()=>Ai,loadGamePromptConfig:()=>Wn,loadObjectCentricConfig:()=>Ie,loadObjectConfig:()=>He,loadSceneConfig:()=>Li,redoLastConfigChange:()=>wi,rehydrateObject:()=>Zn,removeConfigOverride:()=>zt,resetToApplied:()=>$t,resetToOriginal:()=>Si,setBootstrapDependencies:()=>Al,setOverrideMode:()=>qn,setupHotReload:()=>ta,setupLiveEditBridge:()=>hn,toLegacyFormat:()=>Kn,trackObjectCreation:()=>Hs,trackObjectDeletion:()=>Fs,undoLastConfigChange:()=>vi,validateObjectConfig:()=>pt});module.exports=lo(Dl);var Oe={};function ai(s,e,t=!1){Oe[s]||(Oe[s]=[]),Oe[s].push({fn:e,once:t})}function An(s,e){if(Oe[s]){if(!e){delete Oe[s];return}Oe[s]=Oe[s].filter(t=>t.fn!==e)}}function si(s,...e){let t=Oe[s];if(t)for(let i of[...t])i.fn(...e),i.once&&An(s,i.fn)}function oe(s,e){ai(s,e,!0)}var K=null,he=[],rt=null;function es(s){K=s,he=[],rt!==null&&(clearTimeout(rt),rt=null)}function ts(){var s,e,t;return{endpoint:(K==null?void 0:K.endpoint)||"",transport:(K==null?void 0:K.transport)||"beacon",batchSize:(s=K==null?void 0:K.batchSize)!=null?s:10,flushIntervalMs:(e=K==null?void 0:K.flushIntervalMs)!=null?e:300,maxQueue:(t=K==null?void 0:K.maxQueue)!=null?t:200,debug:!!(K!=null&&K.debug)}}async function Za(s,e,t,i){let n=JSON.stringify(e);if(t==="beacon"&&typeof navigator!="undefined"&&typeof navigator.sendBeacon=="function")try{let a=navigator.sendBeacon(s,new Blob([n],{type:"application/json"}));i&&console.log("[handler.telemetry] beacon",a,e);return}catch(a){i&&console.warn("[handler.telemetry] beacon failed, fallback to fetch",a)}try{await fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:n,keepalive:!0}),i&&console.log("[handler.telemetry] fetch",e)}catch(a){i&&console.warn("[handler.telemetry] fetch failed",a)}}function Ln(s,e){let t=ts();if(e&&t.endpoint){if(he.push(s),he.length>t.maxQueue&&(he=he.slice(he.length-t.maxQueue)),he.length>=t.batchSize){Qa();return}rt===null&&(rt=window.setTimeout(()=>{rt=null,Qa()},t.flushIntervalMs))}}async function Qa(){let s=ts();if(!s.endpoint||he.length===0)return;let e=he.splice(0,s.batchSize);await Za(s.endpoint,{events:e},s.transport,s.debug),he.length>0&&await Za(s.endpoint,{events:he.splice(0,s.batchSize)},s.transport,s.debug)}function is(s){return Math.max(0,Math.min(1,s))}function co(s){let e=String(s!=null?s:"power2.out");if(e==="linear")return t=>t;if(e==="sine.inOut")return t=>.5-Math.cos(Math.PI*t)/2;if(e==="power2.out"||e==="easeOutQuad")return t=>1-(1-t)*(1-t);if(e.startsWith("back.out")){let t=e.match(/back\.out\(([\d.]+)\)/),i=t?Number(t[1]):1.8;return n=>1+(i+1)*Math.pow(n-1,3)+i*Math.pow(n-1,2)}return t=>1-(1-t)*(1-t)}function It(){return typeof performance!="undefined"&&performance.now?performance.now():Date.now()}function po(s,e){let t=s==null?void 0:s[e];return typeof t=="number"?t:0}function ns(s,e,t){try{s[e]=t}catch{}}function uo(s){let e=s==null?void 0:s.scale;if(!e)return null;let t=typeof e.x=="number"?e.x:1,i=typeof e.y=="number"?e.y:1;return{x:t,y:i}}function as(s,e){let t=s==null?void 0:s.scale;if(t)try{typeof t.set=="function"?t.set(e.x,e.y):(typeof t.x=="number"&&(t.x=e.x),typeof t.y=="number"&&(t.y=e.y))}catch{}}function ss(s,e){let t=uo(s);if(!t)return{from:null,to:null};let i=null,n=null;return typeof e.scale=="number"?(i=e.scale,n=e.scale):e.scale&&typeof e.scale=="object"&&(typeof e.scale.x=="number"&&(i=e.scale.x),typeof e.scale.y=="number"&&(n=e.scale.y)),typeof e.scaleX=="number"&&(i=e.scaleX),typeof e.scaleY=="number"&&(n=e.scaleY),i===null&&n===null?{from:null,to:null}:{from:{x:t.x,y:t.y},to:{x:i!=null?i:t.x,y:n!=null?n:t.y}}}function rs(){let s=new Set,e=new WeakMap,t=null,i=()=>{if(t!=null)return;t=requestAnimationFrame(()=>{t=null,o(),s.size>0&&i()})},n=d=>{var u;s.add(d);let p=(u=e.get(d.target))!=null?u:new Set;p.add(d),e.set(d.target,p),i()},a=d=>{s.delete(d);let p=e.get(d.target);p&&(p.delete(d),p.size===0&&e.delete(d.target))},r=d=>{d.killed||(d.killed=!0,a(d))},o=()=>{var p,u;let d=It();for(let g of Array.from(s)){if(g.killed||g.paused)continue;let h=d-g.startMs-g.delayMs;if(h<0)continue;let f=g.durationMs>0?h/g.durationMs:1,m=is(f),b=g.repeat>=0?g.repeat+1:1,y=g.repeat>0?Math.min(Math.floor(f),b-1):0;if(g.repeat>0&&f>=1){let T=f-y;m=is(T)}let v=g.ease(m);g.yoyo&&y%2===1&&(v=1-v);for(let T of g.props)ns(g.target,T.key,T.from+(T.to-T.from)*v);g.scaleFrom&&g.scaleTo&&as(g.target,{x:g.scaleFrom.x+(g.scaleTo.x-g.scaleFrom.x)*v,y:g.scaleFrom.y+(g.scaleTo.y-g.scaleFrom.y)*v});try{(p=g.onUpdate)==null||p.call(g)}catch{}if(f>=b){r(g);try{(u=g.onComplete)==null||u.call(g)}catch{}}}},l=(d,p,u)=>{var T;let g=Math.max(0,(typeof p.duration=="number"?p.duration:.5)*1e3),h=Math.max(0,(typeof p.delay=="number"?p.delay:0)*1e3+((T=u==null?void 0:u.delayMsOverride)!=null?T:0)),f=co(p.ease),m=typeof p.repeat=="number"?Math.max(0,p.repeat|0):0,b=p.yoyo===!0,y=new Set(["duration","delay","ease","repeat","yoyo","onUpdate","onComplete","scale","scaleX","scaleY"]),v=[];for(let I of Object.keys(p)){if(y.has(I))continue;let M=p[I];typeof M=="number"&&v.push({key:I,from:po(d,I),to:M})}let w=ss(d,p);return{target:d,startMs:It(),delayMs:h,durationMs:g,ease:f,props:v,scaleFrom:w.from,scaleTo:w.to,repeat:m,yoyo:b,onUpdate:typeof p.onUpdate=="function"?p.onUpdate:void 0,onComplete:typeof p.onComplete=="function"?p.onComplete:void 0,killed:!1,paused:!1,pauseAtMs:null}},c={to(d,p){let u=l(d,p);return n(u),{kill:()=>r(u),pause:()=>{u.paused||(u.paused=!0,u.pauseAtMs=It())},resume:()=>{var f;if(!u.paused)return;let g=(f=u.pauseAtMs)!=null?f:It(),h=It()-g;u.startMs+=h,u.paused=!1,u.pauseAtMs=null},isActive:()=>!u.killed&&!u.paused}},fromTo(d,p,u){return c.set(d,p),c.to(d,u)},set(d,p){if(!d||!p)return;for(let g of Object.keys(p)){let h=p[g];g==="scale"||g==="scaleX"||g==="scaleY"||typeof h=="number"&&ns(d,g,h)}let u=ss(d,p);u.to&&as(d,u.to)},killTweensOf(d){let p=e.get(d);if(p)for(let u of Array.from(p))r(u)},timeline(d={}){let p=[],u=0,g=!1,h=[],f=y=>{if(typeof y=="number")return Math.max(0,y*1e3);let v=typeof y=="string"?y.trim():"";return v.startsWith("+=")?u+Math.max(0,Number(v.slice(2))*1e3||0):v?Math.max(0,Number(v)*1e3||0):u},m=y=>{p.push(y);let v=Math.max(0,(typeof y.vars.duration=="number"?y.vars.duration:.5)*1e3);u=Math.max(u,y.atMs+v)},b={to(y,v,w){return m({kind:"to",target:y,vars:v,atMs:f(w)}),b},fromTo(y,v,w,T){return m({kind:"fromTo",target:y,vars:w,from:v,atMs:f(T)}),b},play(){var y,v;if(g)return b;g=!0,h=[];for(let w of p)w.kind==="fromTo"&&c.set(w.target,(y=w.from)!=null?y:{}),h.push(c.to(w.target,{...w.vars,delay:w.atMs/1e3+((v=w.vars.delay)!=null?v:0)}));return b},pause(){for(let y of h)y.pause();return b},kill(){for(let y of h)y.kill();h=[],g=!1}};return d.paused||b.play(),b}};return c}function os(){if(typeof window=="undefined")return;let s=window;if(!s.gsap)try{s.gsap=rs()}catch{}}var ls={name:"handler-playable-sdk",version:"1.0.89",type:"module",description:"Handler Playable SDK v0.1 with contract-aligned surface (root sandbox, canonical event envelope).",main:"dist/index.cjs",module:"dist/index.js",types:"dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js",require:"./dist/index.cjs"},"./pixi":{types:"./dist/pixi/index.d.ts",import:"./dist/pixi/index.js",require:"./dist/pixi/index.cjs"},"./pixi/index.css":{import:"./dist/pixi/index.css",require:"./dist/pixi/index.css"},"./three":{types:"./dist/three/index.d.ts",import:"./dist/three/index.js",require:"./dist/three/index.cjs"},"./cli":{types:"./dist/cli/index.d.ts",import:"./dist/cli/index.js",require:"./dist/cli/index.cjs"}},bin:{"handler-student-helper":"./bin/student-helper.mjs","handler-validate":"./bin/validate.mjs","handler-sync-screens":"./bin/sync-screens.mjs","handler-brand-dna":"./bin/brand-dna.mjs","handler-setup-library":"./bin/setup-library.mjs","handler-screen-helper":"./bin/screen-helper.mjs"},scripts:{prebuild:"python3 src/preview/build-css.py",build:"tsup src/index.ts src/pixi/index.ts src/three/index.ts src/cli/index.ts --format cjs,esm --dts --clean --minify --external lottie-web --external jszip && npm run create-mjs-symlinks && npm run postbuild-cli && npm run obfuscate && npm run postbuild",postbuild:"python3 src/preview/copy-css-to-dist.py","postbuild-cli":"cp src/cli/*.mjs dist/cli/ && mkdir -p dist/cli/student-helper && cp src/cli/student-helper/*.mjs dist/cli/student-helper/ && chmod +x dist/cli/*.mjs dist/cli/student-helper/*.mjs && chmod +x bin/*.mjs","create-mjs-symlinks":"cd dist && ln -sf index.js index.mjs && cd pixi && ln -sf index.js index.mjs && cd ../three && ln -sf index.js index.mjs","build:dev":"tsup src/index.ts src/pixi/index.ts src/three/index.ts src/cli/index.ts --format cjs,esm --dts --clean --external lottie-web --external jszip && npm run create-mjs-symlinks && npm run postbuild-cli",obfuscate:"javascript-obfuscator dist/pixi/index.js --output dist/pixi/index.js --config obfuscator.config.json && javascript-obfuscator dist/three/index.js --output dist/three/index.js --config obfuscator.config.json && javascript-obfuscator dist/cli/index.js --output dist/cli/index.js --config obfuscator.config.json && npm run obfuscate-cli","obfuscate-cli":'for file in dist/cli/*.mjs dist/cli/student-helper/*.mjs; do javascript-obfuscator "$file" --output "$file" --config obfuscator.config.json; done',lint:"eslint 'src/**/*.{ts,tsx}'",typecheck:"tsc --noEmit",prepublishOnly:"npm run build","publish:update":"node scripts/publish-and-update.cjs patch","publish:update:minor":"node scripts/publish-and-update.cjs minor","publish:update:major":"node scripts/publish-and-update.cjs major"},author:"Handler",license:"MIT",publishConfig:{access:"public"},repository:{type:"git",url:"https://github.com/HandlerAIGames/handler-playable-sdk.git"},files:["dist","bin","LICENSE","README.md"],peerDependencies:{"lottie-web":"^5.0.0","pixi.js":"^8.0.0",three:"^0.182.0"},peerDependenciesMeta:{"pixi.js":{optional:!0},three:{optional:!0},"lottie-web":{optional:!0}},devDependencies:{"@types/three":"^0.182.0",eslint:"^9.39.2","javascript-obfuscator":"^5.1.0","pixi.js":"8.8.1",three:"^0.182.0","ts-node":"^10.9.2",tsup:"^8.4.0",typescript:"^5.7.2","typescript-eslint":"^8.53.0"},dependencies:{"@google/genai":"^1.35.0","@google/generative-ai":"^0.24.1",jszip:"^3.10.1",sharp:"^0.34.5"}};var le=0,ho=le++,cs=le++,ds=le++,ps=le++,us=le++,gs=le++,hs=le++,fs=le++,ms=le++,bs=le++,ys=le++,vs=le++,W=ho;function ws(){return W===cs}function xs(){return W===ds}function Ss(){return W===ps}function Es(){return W===us}function ot(){return W===gs}function lt(){return W===hs}function Cs(){return W===fs}function As(){return W===ms}function Ls(){return W===bs}function Tn(){return W===ys}function kn(){return W===vs}function Ts(){let s=typeof AD_PROTOCOL!="undefined"?AD_PROTOCOL:"none",e=typeof AD_NETWORK!="undefined"?AD_NETWORK:"web_embed";if(s==="mraid")try{mraid.getState(),W=cs;return}catch{}else if(s==="dapi")try{dapi.isReady(),W=ds;return}catch{}if(e==="facebook")try{typeof FbPlayableAd!="undefined"&&(W=ps)}catch{}else if(e==="google")try{typeof ExitApi!="undefined"&&(W=us)}catch{}else if(e==="mintegral")window.gameReady&&(W=gs);else if(e==="tapjoy")window.TJ_API&&(W=hs);else if(e==="tiktok")window.openAppStore&&(W=fs);else if(e==="smadex")try{window.smxTracking&&(W=ms)}catch{}else if(e==="snapchat")try{window.ScPlayableAd&&(W=bs)}catch{}else e==="vungle"?W=ys:(s==="nucleo"||e==="nucleo")&&(W=vs)}var ri=st(require("lottie-web"),1),In=ri.default;typeof window!="undefined"&&(window.lottie=ri.default,window.__baseLottie=ri.default);var fo=require("pixi.js");var Pn=require("pixi.js");var mo=null;function Mn(s){mo=s}li();oi();var Pt=require("pixi.js");li();var So=typeof __BUILD_MODE__!="undefined"?__BUILD_MODE__:"undefined",Rn=So;if(typeof window!="undefined")try{let s=new XMLHttpRequest;if(s.open("GET","./build-settings.json",!1),s.send(),s.status===200&&s.responseText){let e=JSON.parse(s.responseText);e!=null&&e.buildMode&&(Rn=e.buildMode,console.log(`[ObjectFactory] Build mode overridden by settings: ${Rn}`))}}catch{}function Eo(s){var t,i,n,a,r;if(typeof window!="undefined"&&window.resolveAnchorVec2)return window.resolveAnchorVec2(s);let e={center:{x:.5,y:.5},"top-left":{x:0,y:0},"top-center":{x:.5,y:0},"top-right":{x:1,y:0},"center-left":{x:0,y:.5},"center-right":{x:1,y:.5},"bottom-left":{x:0,y:1},"bottom-center":{x:.5,y:1},"bottom-right":{x:1,y:1},left:{x:0,y:.5},right:{x:1,y:.5},top:{x:.5,y:0},bottom:{x:.5,y:1}};if(Array.isArray(s))return{x:(t=s[0])!=null?t:.5,y:(i=s[1])!=null?i:.5};if(s&&typeof s=="object"&&"x"in s&&"y"in s)return{x:(n=s.x)!=null?n:.5,y:(a=s.y)!=null?a:.5};if(typeof s=="string"){let o=s.trim().toLowerCase();return(r=e[o])!=null?r:{x:.5,y:.5}}return null}var ve=class{static async create(e,t,i){var l,c,d,p,u,g,h;console.log(`[ObjectFactory] create() called for: ${e}, __BUILD_MODE__: ${Rn}`);let n=(l=t==null?void 0:t.render)==null?void 0:l.asset;if(!n){console.log(`[ObjectFactory] No asset definition for: ${e}, returning empty container`);let f=new Pt.Container;return this.applyTransform(f,t==null?void 0:t.transform,t),f}let a=(c=t==null?void 0:t.identity)==null?void 0:c.id;console.log(`[ObjectFactory] Calling AssetLoader.load() for: ${e}, configId: ${a}, type: ${n.type}, path: ${n.path}`);let r=await Ye.load(e,n,i,a);console.log(`[ObjectFactory] AssetLoader.load() completed for: ${e}, rawAsset type: ${(d=r==null?void 0:r.constructor)==null?void 0:d.name}`);let o;if(n.type==="image")console.log("[ObjectFactory] Creating Sprite from texture:",r,"for object:",e),o=new Pt.Sprite(r),console.log("[ObjectFactory] Created object:",o,"type:",(p=o==null?void 0:o.constructor)==null?void 0:p.name),this.applyTransform(o,t==null?void 0:t.transform,t);else if(n.type==="json")if(console.log("[ObjectFactory] JSON asset for",e,"rawAsset type:",(u=r==null?void 0:r.constructor)==null?void 0:u.name,r),r&&(((g=r.constructor)==null?void 0:g.name)==="Container"||r instanceof Pt.Container)){console.warn("[ObjectFactory] JSON asset is Container (from cache), reloading JSON directly");let f=[n.path,`/assets/${n.path}`,`assets/${n.path}`,`../assets/${n.path}`],m=!1;for(let b of f)try{let y=await fetch(b);if(y.ok){o=await y.json(),console.log("[ObjectFactory] Reloaded JSON directly from:",b,"type:",(h=o==null?void 0:o.constructor)==null?void 0:h.name),m=!0;break}}catch{continue}m||(console.error("[ObjectFactory] Failed to reload JSON from any path"),o=r)}else o=r;else o=r,o&&typeof o=="object"&&("x"in o||"position"in o)&&this.applyTransform(o,t==null?void 0:t.transform,t);return o}static applyTransform(e,t,i){var n,a,r,o;if(!(!t||!e)&&(t.position&&("x"in e&&"y"in e?(e.x=(n=t.position.x)!=null?n:0,e.y=(a=t.position.y)!=null?a:0):"position"in e&&e.position&&e.position.set((r=t.position.x)!=null?r:0,(o=t.position.y)!=null?o:0)),t.scale!==void 0&&"scale"in e&&e.scale&&(typeof e.scale=="object"&&"set"in e.scale?e.scale.set(t.scale):e.scale=t.scale),t.rotation!==void 0&&"rotation"in e&&(e.rotation=t.rotation),t.anchor&&"anchor"in e&&e.anchor)){let l=Eo(t.anchor);l&&("set"in e.anchor?e.anchor.set(l.x,l.y):(e.anchor.x=l.x,e.anchor.y=l.y))}}};var Mt=class{constructor(){this.config=null}init(e){this.config=e}get(e){if(!this.config)throw new Error("RuntimeObjectRegistry not initialized. Call init() first.");return this.config.objects.get(e)}getAllIds(){if(!this.config)throw new Error("RuntimeObjectRegistry not initialized. Call init() first.");return Array.from(this.config.objects.keys())}has(e){return this.config?this.config.objects.has(e):!1}};var Lo=st(require("pixi.js"),1);typeof window!="undefined"&&(window.__basePixi=Lo);ct();var ci=require("pixi.js");ct();var Dn=class{constructor(){this.instanceCache=new Map;this.readyPromise=null;this.app=null;this.registry=new Mt}init(e,t){this.registry.init(e),this.app=t}updateConfig(e){this.registry.init(e),this.instanceCache.clear(),this.readyPromise=null}async ready(){this.readyPromise&&await this.readyPromise;let t=this.registry.getAllIds().filter(n=>!this.instanceCache.has(n));if(t.length===0)return;let i=async n=>{n.length&&(console.log("[Assets] Loading objects:",n),await Promise.all(n.map(async a=>{var o;let r=this.registry.get(a);if(!r){console.warn("[Assets] No config found for object:",a);return}try{let l=await ve.create(a,r,this.app);this.instanceCache.set(a,l),console.log("[Assets] Loaded object:",a,(o=l==null?void 0:l.constructor)==null?void 0:o.name)}catch(l){console.error("[Assets] Failed to load object:",a,l)}})))};return this.readyPromise=(async()=>{await i(t);let n=this.registry.getAllIds().filter(a=>!this.instanceCache.has(a));n.length>0&&(console.warn("[Assets] Retrying missing assets:",n),await i(n)),console.log("[Assets] Ready. Cached objects:",Array.from(this.instanceCache.keys()))})(),this.readyPromise}resetScene(){this.instanceCache.clear(),this.readyPromise=null}async reloadObject(e){let t=this.registry.get(e);if(t){let i=await ve.create(e,t,this.app);this.instanceCache.set(e,i)}}get(e){return this.instanceCache.get(e)}},To=new Dn,ko=new Proxy(To,{get(s,e){if(e in s&&typeof s[e]=="function")return s[e].bind(s);if(s.get(e))return s.get(e)}});ct();var Po=require("pixi.js"),Le={width:400,height:600,designWidth:400,scaleFactor:1},pi={scale:1,position:1},Hn=[];function Mo(s,e,t,i,n,a,r){Hn.push({element:s,originalScale:a,positionHelper:e,heightPercent:n}),e(s,t,i,n,a,r,!1)}function jo(){Hn.forEach(({element:s,originalScale:e,positionHelper:t,heightPercent:i})=>{let n=e*Le.scaleFactor;t(s,Le.width,Le.height,i,n,!0,!1)})}function Nn(s,e){console.log(`[SCREEN] updateScreenState called: ${s}x${e}`),Le.width=s,Le.height=e,Le.scaleFactor=Math.min(s/Le.designWidth,1.15),pi.scale=Le.scaleFactor,pi.position=1,console.log(`[SCREEN] Global multipliers - scale: ${pi.scale.toFixed(3)}`),jo()}var _t={layout:{scale_multiplier:1,position_offset:{x:0,y:0},debug_rect_visible:!0,debug_rect_color:16711680,debug_rect_thickness:4,debug_rect_scale_x:1,debug_rect_scale_y:1,screen_scale_x:1,screen_scale_y:1},engine:{scale:1,background_scale:1.05,background_offset_y:0,background_alpha:.98,label_pulse_speed:3,label_pulse_intensity:.03}};function _o(s,e,t){let i=_t[s];i&&i[e]!==void 0&&(i[e]=t,console.log(`Updated ${s}.${e} = ${t}`))}function Oo(){return _t}var Ro={center:{x:.5,y:.5},"center-center":{x:.5,y:.5},middle:{x:.5,y:.5},"middle-center":{x:.5,y:.5},"top-left":{x:0,y:0},"top-center":{x:.5,y:0},"top-right":{x:1,y:0},"bottom-left":{x:0,y:1},"bottom-center":{x:.5,y:1},"bottom-right":{x:1,y:1},"left-center":{x:0,y:.5},"right-center":{x:1,y:.5},"center-left":{x:0,y:.5},"center-right":{x:1,y:.5},left:{x:0,y:.5},right:{x:1,y:.5},top:{x:.5,y:0},bottom:{x:.5,y:1}};function di(s,e){return typeof s=="number"&&Number.isFinite(s)?s:e}function Ke(s,e={x:.5,y:.5}){var t;if(Array.isArray(s))return{x:di(s[0],e.x),y:di(s[1],e.y)};if(s&&typeof s=="object"){let i=s;return{x:di(i.x,e.x),y:di(i.y,e.y)}}if(typeof s=="string"){let i=s.trim().toLowerCase();return(t=Ro[i])!=null?t:e}return e}function ze(s,e,t,i={}){var g,h,f,m,b,y;let n=Ke(t),a=(g=i.inset)!=null?g:{},r=(h=i.padding)!=null?h:{x:0,y:0},o=((f=a.left)!=null?f:0)+r.x,l=((m=a.right)!=null?m:0)+r.x,c=((b=a.top)!=null?b:0)+r.y,d=((y=a.bottom)!=null?y:0)+r.y,p=Math.max(0,s-o-l),u=Math.max(0,e-c-d);return{x:o+p*n.x,y:c+u*n.y}}function dt(s,e,t,i={}){var f,m,b,y,v,w;let n=(f=i.inset)!=null?f:{},a=(m=i.padding)!=null?m:{x:0,y:0},r=((b=n.left)!=null?b:0)+a.x,o=((y=n.right)!=null?y:0)+a.x,l=((v=n.top)!=null?v:0)+a.y,c=((w=n.bottom)!=null?w:0)+a.y,d=Math.max(0,s-r-o),p=Math.max(0,e-l-c),u=Ke(t,{x:.5,y:.5}),g=Math.min(Math.max(u.x,0),1),h=Math.min(Math.max(u.y,0),1);return{x:r+d*g,y:l+p*h}}if(typeof window!="undefined"){let s=window.innerWidth,e=window.innerHeight,t=()=>{let i=window.innerWidth,n=window.innerHeight;(i!==s||n!==e)&&(s=i,e=n,Nn(i,n))};window.addEventListener("resize",t),window.addEventListener("orientationchange",()=>{setTimeout(t,100)}),window.mraid&&(window.mraid.addEventListener("viewableChange",t),window.mraid.addEventListener("sizeChange",t)),Nn(window.innerWidth,window.innerHeight),window.updateDebugConfig=_o,window.getDebugConfig=Oo,window.copyConfig=Vo,window.applyConfig=jt,window.applyConfigForRatio=Yo,window.positionAtBottom=_s,window.positionAtTop=Do,window.positionAtCenter=No,window.positionAtLeft=Ho,window.positionAtRight=Fo,window.positionAtBottomLeft=Bo,window.positionAtBottomRight=Go,window.positionAtTopLeft=Uo,window.positionAtTopRight=qo,window.applyPositionContract=$o,console.log("\u{1F3AE} Debug Config Functions Available:"),console.log("\u2022 updateDebugConfig(category, key, value)"),console.log("\u2022 getDebugConfig()"),console.log("\u2022 copyConfig(presetName)"),console.log("\u2022 applyConfig(config)"),console.log("\u2022 applyConfigForRatio(width, height)"),console.log("\u{1F4CD} Positioning Helpers Available (with scale):"),console.log("\u2022 positionAtBottom(element, w, h, percent, scale)"),console.log("\u2022 positionAtTop(element, w, h, percent, scale)"),console.log("\u2022 positionAtCenter(element, w, h, offsetX, offsetY, scale)"),console.log("\u2022 positionAtLeft/Right(element, w, h, percent, scale)"),console.log("\u2022 Corner positions: BottomLeft/Right, TopLeft/Right (all with scale)"),console.log("\u2022 applyPositionContract(element, w, h, contract)"),console.log("Example: positionAtCenter(mySprite, 400, 600, 0, -50, 1.2)")}function ui(s,e,t=0){return s*e+t}function gi(s,e,t=0){return s*(1-e)+t}function hi(s,e,t=0){return s*e+t}function fi(s,e,t=0){return s*(1-e)+t}function de(s,e=0){return s/2+e}function zo(s,e){return s*e}function $o(s,e,t,i){var r,o,l,c,d,p,u,g,h,f,m,b,y,v,w,T,I,M,L,j;let n=0,a=0;switch(i.type){case"top":n=de(e,(o=(r=i.offset)==null?void 0:r.x)!=null?o:0),a=ui(t,i.percent,(c=(l=i.offset)==null?void 0:l.y)!=null?c:0);break;case"bottom":n=de(e,(p=(d=i.offset)==null?void 0:d.x)!=null?p:0),a=gi(t,i.percent,(g=(u=i.offset)==null?void 0:u.y)!=null?g:0);break;case"left":n=hi(e,i.percent,(f=(h=i.offset)==null?void 0:h.x)!=null?f:0),a=de(t,(b=(m=i.offset)==null?void 0:m.y)!=null?b:0);break;case"right":n=fi(e,i.percent,(v=(y=i.offset)==null?void 0:y.x)!=null?v:0),a=de(t,(T=(w=i.offset)==null?void 0:w.y)!=null?T:0);break;case"center":n=de(e,(M=(I=i.offset)==null?void 0:I.x)!=null?M:0),a=de(t,(j=(L=i.offset)==null?void 0:L.y)!=null?j:0);break}s.position?s.position.set(n,a):(s.x=n,s.y=a),i.scale!==void 0&&i.scale!==1&&s.scale&&(typeof s.scale.set=="function"?s.scale.set(i.scale,i.scale):(s.scale.x=i.scale,s.scale.y=i.scale))}function _s(s,e,t,i=.2,n=1,a=!0,r=!1){let o=zo(t,i),l=gi(t,i/2);Te(s,de(e),l);let c=a?n*Le.scaleFactor:n;ke(s,c),r&&!Hn.find(d=>d.element===s)&&Mo(s,_s,e,t,i,n,a)}function Do(s,e,t,i=.1,n=1){Te(s,de(e),ui(t,i)),ke(s,n)}function No(s,e,t,i=0,n=0,a=1){Te(s,de(e,i),de(t,n)),ke(s,a)}function Ho(s,e,t,i=.1,n=1){Te(s,hi(e,i),de(t)),ke(s,n)}function Fo(s,e,t,i=.1,n=1){Te(s,fi(e,i),de(t)),ke(s,n)}function Bo(s,e,t,i=.05,n=.05,a=1){Te(s,hi(e,n),gi(t,i)),ke(s,a)}function Go(s,e,t,i=.05,n=.05,a=1){Te(s,fi(e,n),gi(t,i)),ke(s,a)}function Uo(s,e,t,i=.05,n=.05,a=1){Te(s,hi(e,n),ui(t,i)),ke(s,a)}function qo(s,e,t,i=.05,n=.05,a=1){Te(s,fi(e,n),ui(t,i)),ke(s,a)}function Te(s,e,t){s&&s.position?typeof s.position.set=="function"?s.position.set(e,t):(s.position.x=e,s.position.y=t):s&&(s.x=e,s.y=t)}function ke(s,e){e!==1&&s&&s.scale&&(typeof s.scale.set=="function"?s.scale.set(e,e):s.scale.x!==void 0&&s.scale.y!==void 0&&(s.scale.x=e,s.scale.y=e))}var We={default:{layout:{scale_multiplier:1,position_offset:{x:0,y:0},debug_rect_visible:!0,debug_rect_color:16711680,debug_rect_thickness:4,debug_rect_scale_x:1,debug_rect_scale_y:1,screen_scale_x:1,screen_scale_y:1},engine:{scale:1,background_scale:1.05,background_offset_y:0,background_alpha:.98,label_pulse_speed:3,label_pulse_intensity:.03}},wide:{layout:{scale_multiplier:1,position_offset:{x:0,y:0},debug_rect_visible:!0,debug_rect_color:16711680,debug_rect_thickness:4,debug_rect_scale_x:1,debug_rect_scale_y:1,screen_scale_x:.9,screen_scale_y:1.1},engine:{scale:1,background_scale:1.1,background_offset_y:0,background_alpha:.95,label_pulse_speed:3,label_pulse_intensity:.03}},square:{layout:{scale_multiplier:1,position_offset:{x:0,y:0},debug_rect_visible:!0,debug_rect_color:16711680,debug_rect_thickness:4,debug_rect_scale_x:1,debug_rect_scale_y:1,screen_scale_x:.85,screen_scale_y:.85},engine:{scale:1,background_scale:1,background_offset_y:0,background_alpha:1,label_pulse_speed:3,label_pulse_intensity:.03}},tall:{layout:{scale_multiplier:1,position_offset:{x:0,y:0},debug_rect_visible:!0,debug_rect_color:16711680,debug_rect_thickness:4,debug_rect_scale_x:1,debug_rect_scale_y:1,screen_scale_x:1.1,screen_scale_y:.9},engine:{scale:1,background_scale:.95,background_offset_y:0,background_alpha:1,label_pulse_speed:3,label_pulse_intensity:.03}}};function Vo(s){return s&&We[s]?JSON.parse(JSON.stringify(We[s])):JSON.parse(JSON.stringify(_t))}function jt(s){Object.keys(s).forEach(e=>{let t=e;_t[t]&&s[t]&&Object.assign(_t[t],s[t])}),console.log("Config applied:",s)}function Yo(s,e){let t=s/e;t>1.6?(jt(We.wide),console.log("Applied WIDE config for ratio:",t)):t<.7?(jt(We.tall),console.log("Applied TALL config for ratio:",t)):t>.8&&t<1.2?(jt(We.square),console.log("Applied SQUARE config for ratio:",t)):(jt(We.default),console.log("Applied DEFAULT config for ratio:",t))}if(typeof window!="undefined"){let s=window;s.configPresets=We,s.resolveAnchorVec2=s.resolveAnchorVec2||Ke,s.resolveScreenAnchorPoint=s.resolveScreenAnchorPoint||ze,s.resolveScreenRatioPoint=s.resolveScreenRatioPoint||dt}Ti();function X(s,e){let t=(n,a)=>a===0?n:t(a,n%a),i=t(s,e);return`${s/i}:${e/i}`}var gd=[{id:"iphone-15-pro-max",label:"iPhone 15 Pro Max",width:430,height:932,category:"iphone",ratio:X(430,932)},{id:"iphone-15-pro",label:"iPhone 15 Pro",width:393,height:852,category:"iphone",ratio:X(393,852)},{id:"iphone-15",label:"iPhone 15",width:393,height:852,category:"iphone",ratio:X(393,852)},{id:"iphone-14",label:"iPhone 14",width:390,height:844,category:"iphone",ratio:X(390,844)},{id:"iphone-se",label:"iPhone SE",width:375,height:667,category:"iphone",ratio:X(375,667)},{id:"iphone-12-mini",label:"iPhone 12 Mini",width:360,height:780,category:"iphone",ratio:X(360,780)}],hd=[{id:"pixel-8-pro",label:"Pixel 8 Pro",width:448,height:998,category:"android",ratio:X(448,998)},{id:"pixel-8",label:"Pixel 8",width:412,height:915,category:"android",ratio:X(412,915)},{id:"samsung-s24-ultra",label:"Samsung S24 Ultra",width:412,height:915,category:"android",ratio:X(412,915)},{id:"samsung-s24",label:"Samsung S24",width:360,height:780,category:"android",ratio:X(360,780)},{id:"samsung-a54",label:"Samsung A54",width:412,height:915,category:"android",ratio:X(412,915)},{id:"oneplus-12",label:"OnePlus 12",width:412,height:915,category:"android",ratio:X(412,915)}],fd=[{id:"ipad-pro-12",label:'iPad Pro 12.9"',width:1024,height:1366,category:"tablet",ratio:X(1024,1366)},{id:"ipad-pro-11",label:'iPad Pro 11"',width:834,height:1194,category:"tablet",ratio:X(834,1194)},{id:"ipad-air",label:"iPad Air",width:820,height:1180,category:"tablet",ratio:X(820,1180)},{id:"ipad-mini",label:"iPad Mini",width:768,height:1024,category:"tablet",ratio:X(768,1024)},{id:"samsung-tab-s9",label:"Samsung Tab S9",width:800,height:1280,category:"tablet",ratio:X(800,1280)}],ia=[{id:"playable-portrait",label:"Playable Portrait",width:320,height:480,category:"playable",ratio:"2:3",mraidScale:1},{id:"mraid-320x480",label:"MRAID 320\xD7480",width:320,height:480,category:"playable",ratio:"2:3",mraidScale:1},{id:"iphone-14",label:"iPhone 14",width:390,height:844,category:"playable",ratio:X(390,844),mraidScale:.7},{id:"ipad-mini",label:"iPad Mini",width:768,height:1024,category:"playable",ratio:X(768,1024),mraidScale:.7}];var na=[...ia],aa=[{category:"playable",label:"Playable Ad",devices:ia}],ki=ia[0];function Qe(s){return na.find(e=>e.id===s)||ki}function tl(s){return na.filter(e=>e.category===s)}ee();var xe=class{async updateProperty(e,t,i,n={}){var l,c,d,p,u,g,h,f,m,b,y,v;console.log("[PropertyUpdateManager] Updating:",e,t,i);let a=window.getEditableObjectConfig;if(typeof a!="function"){console.error("[PropertyUpdateManager] getEditableObjectConfig not available");return}let r=a(e);if(!r){console.error("[PropertyUpdateManager] Config not found for:",e);return}if(re({objectId:e,path:t,value:i},{persist:!0}),t==="transform"||t.startsWith("transform.")){console.log("[DEBUG FALLBACK] PropertyUpdateManager SKIP applyEditableObjectConfig (transform path)",t,e);let w=r==null?void 0:r.motion;if(w&&typeof w=="object"&&w.enabled!==!1&&(((p=w==null?void 0:w.intro)==null?void 0:p.enabled)===!0||((u=w==null?void 0:w.pulse)==null?void 0:u.enabled)===!0||((g=w==null?void 0:w.swing)==null?void 0:g.enabled)===!0||((h=w==null?void 0:w.continuousMove)==null?void 0:h.enabled)===!0||((f=w==null?void 0:w.continuousRotate)==null?void 0:f.enabled)===!0||((m=w==null?void 0:w.orbit)==null?void 0:m.enabled)===!0)){let M=window.applyEditableObjectConfig;if(typeof M=="function"){let L=window.__editableConfig,j=(v=(y=(b=L==null?void 0:L.objects)==null?void 0:b.get)==null?void 0:y.call(b,e))!=null?v:r;await M(e,j),console.log("[PropertyUpdateManager] Applied config for motion object")}}n.refreshInspector||requestAnimationFrame(()=>{window.dispatchEvent(new CustomEvent("config:changed",{detail:{objectId:e}}))})}else{let w=window.applyEditableObjectConfig;if(typeof w=="function"){let T=window.__editableConfig,I=(d=(c=(l=T==null?void 0:T.objects)==null?void 0:l.get)==null?void 0:c.call(l,e))!=null?d:r;await w(e,I),console.log("[PropertyUpdateManager] Applied config successfully")}else console.warn("[PropertyUpdateManager] applyEditableObjectConfig not available")}this.triggerRefresh(e),n.refreshInspector&&window.dispatchEvent(new CustomEvent("inspector:refresh"))}getNestedProperty(e,t){let i=t.split("."),n=e;for(let a of i)if(n&&typeof n=="object"&&a in n)n=n[a];else return;return n}triggerRefresh(e){let t=window.__refreshHierarchy;typeof t=="function"&&t(),window.dispatchEvent(new CustomEvent("inspector:property-updated",{detail:{objectId:e}}))}};function sa(s){let e=document.createElement("input");e.type="file",e.accept="image/*",e.onchange=async t=>{var a;let i=(a=t.target.files)==null?void 0:a[0];if(!i)return;let n=new FileReader;n.onload=async()=>{let r=n.result,o=s.category||"misc",c=`${(s.objectId||"new_asset").replace(/^json\./,"").replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"")||"new_asset"}_uploaded`;try{let p=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:o,filename:`${c}.png`,data:r,overwrite:!0})})).json();if(!(p!=null&&p.success)){alert(`Upload failed: ${(p==null?void 0:p.error)||"Unknown error"}`);return}let u=window.addAssetToRegistry;typeof u=="function"&&u(o,`${c}.png`);try{await fetch("/api/setup-library",{method:"POST",headers:{"Content-Type":"application/json"}})}catch{}let g=window.refreshAssetLibrary;typeof g=="function"&&await g(),await s.onApply(p.path)}catch(d){console.error("[QuickActionsBar] Upload error:",d),alert("Upload failed. Check console.")}},n.readAsDataURL(i)},e.click()}var Ii=class{constructor(){this.updateManager=new xe}async handleAction(e,t,i){console.log("[QuickActionsBar] Action:",e,t,i);let n=window.getEditableObjectConfig;if(typeof n!="function")return;let a=n(t);if(!a)return;let r=this.updateManager.getNestedProperty(a,i);if(e==="ai-convert"||e==="upload"||e==="library"){let o=i==="ui.text"||i==="render.asset.path",l=i==="render.asset.path";o&&(await this.prepareForImageConversion(t,a),e==="ai-convert"&&i!=="render.asset.path"&&(i="render.asset.path"))}switch(e){case"library":this.openLibrary(t,i,r);break;case"ai-edit":this.openAIEditor(t,i,r);break;case"upload":this.openUpload(t,i);break;case"reset":await this.resetToDefault(t,i);break;case"ai-convert":this.handleAiConvert(t,i,r);break;default:console.warn("[QuickActionsBar] Unknown action:",e)}}async prepareForImageConversion(e,t){var i,n;if(console.log("[QuickActionsBar] Preparing for image conversion:",e),t.render||(t.render={alpha:1,visible:!0}),(t.render.alpha===0||t.render.alpha===void 0)&&(t.render.alpha=1,await this.updateManager.updateProperty(e,"render.alpha",1)),(t.render.visible===!1||t.render.visible===void 0)&&(t.render.visible=!0,await this.updateManager.updateProperty(e,"render.visible",!0)),t.render.asset||(t.render.asset={type:"image",path:""}),t.render.asset.type!=="image"&&(t.render.asset.type="image",await this.updateManager.updateProperty(e,"render.asset",{type:"image",path:t.render.asset.path||""})),t.ui&&t.ui.renderMode!=="png"){await this.updateManager.updateProperty(e,"ui.renderMode","png",{refreshInspector:!0}),await this.updateManager.updateProperty(e,"render.tint","#ffffff");let r=((n=(i=t.transform)==null?void 0:i.scale)!=null?n:1)*.3;await this.updateManager.updateProperty(e,"transform.scale",r),console.log("[QuickActionsBar] Text to PNG conversion: set tint white, scale",r)}this.ensureSlotInRegistry(e,t)}ensureSlotInRegistry(e,t){var o,l,c;let i=window.getEditableAssets;if(typeof i!="function")return;let n=i();if(!n||!n.slots)return;let a=e.startsWith("json.")?e.replace("json.",""):e;if(!n.slots.some(d=>d.objectId===a||d.slotId===a)){let d=((o=t.identity)==null?void 0:o.category)||"ui";console.log("[QuickActionsBar] Adding new slot to registry for converted object:",a),n.slots.push({slotId:a,displayName:a.replace(/_/g," "),objectId:a,category:d,currentAsset:((c=(l=t.render)==null?void 0:l.asset)==null?void 0:c.path)||"",defaultAsset:"",libraryFolder:d,assetType:"image"}),n.categories&&!n.categories.includes(d)&&n.categories.push(d),n.libraryAssets&&!n.libraryAssets[d]&&(n.libraryAssets[d]=[]);let p=window.reRenderAssetLibrary;typeof p=="function"&&p()}}openLibrary(e,t,i){var a;let n=window.__debugContext;if(n){if(n.activeTab!=="library"){n.activeTab="library";let r=window.__updateWorkbenchTabs;typeof r=="function"&&r()}if(n.libraryPanel){let r=window.getEditableObjectConfig,o=r==null?void 0:r(e),l=(a=o==null?void 0:o.identity)==null?void 0:a.category;l||(l=t.split(".")[0]==="render"?"environment":"ui"),console.log("[QuickActionsBar] Highlighting library slot:",e,"category:",l),n.libraryPanel.highlightSlot(e,l)}}}openAIEditor(e,t,i){let n=window.__openAiEditor;if(typeof n=="function"){let a=t.split(".").pop()||t;n(a,`Edit ${a} for ${e}`,i,{objectId:e,path:t})}else console.warn("[QuickActionsBar] AI Editor not available")}openUpload(e,t){var r;let i=window.getEditableObjectConfig,n=i==null?void 0:i(e),a=((r=n==null?void 0:n.identity)==null?void 0:r.category)||(t.split(".")[0]==="render"?"environment":"ui");sa({objectId:e,category:a,onApply:async o=>{var g,h;let l=window.applyAssetToSlot,c=this.getFilenameFromPath(o),d=/render\.asset\.path/i.test(t)||/\.(png|jpg|jpeg|gif|webp)$/i.test(o);typeof l=="function"&&c&&d&&await l(e,c,a),await this.updateManager.updateProperty(e,t,o);let p=window.__debugContext;(h=(g=p==null?void 0:p.options)==null?void 0:g.onPropertyChange)==null||h.call(g,e,t,o);let u=window.__highlightLibrarySlot;typeof u=="function"&&setTimeout(()=>{u(e,a)},500),window.dispatchEvent(new CustomEvent("inspector:refresh"))}})}getFilenameFromPath(e){if(!e)return"";let t=e.split("?")[0].replace(/\\/g,"/");return t.split("/").pop()||t}async resetToDefault(e,t){console.log("[QuickActionsBar] Reset to default:",e,t);try{let i=await this.getDefaultValue(e,t);i!==void 0?(await this.updateManager.updateProperty(e,t,i),console.log("[QuickActionsBar] Reset to default value:",i)):alert("No default value found for this property.")}catch(i){console.error("[QuickActionsBar] Failed to reset to default:",i),alert("Failed to reset property. Check console for details.")}}async getDefaultValue(e,t){let i=t.split(".");if(i.length<2)return;let n=i[0],a=i.slice(1),r=window.__editableConfig;if(!(r!=null&&r.schemas))return;let o=null;if(r.schemas instanceof Map?o=r.schemas.get(n):typeof r.schemas=="object"&&(o=r.schemas[n]),!(o!=null&&o.defaults))return;let l=o.defaults;for(let c of a)if(l&&typeof l=="object")l=l[c];else return;return l}handleAiConvert(e,t,i){let n=window.__openAiEditor;if(typeof n=="function"){let r=`A single, high-quality, high-detail game UI icon/asset representing "${String(i||e.replace(/_/g," ").replace("json.",""))}". Modern stylized 3D rendered style, vibrant colors, soft lighting, isolated on solid magenta background, highly polished professional game art.`,o="render.asset.path";console.log("[QuickActionsBar] AI Convert for:",e,"from:",t,"to:",o),n(e,r,"",{objectId:e,path:o});let l=window.__debugContext;if(l){l.activeTab="ai";let c=window.__updateWorkbenchTabs;typeof c=="function"&&c()}}else console.warn("[QuickActionsBar] AI Editor not available")}};var il=[{value:"loading",label:"Loading"},{value:"start",label:"Start"},{value:"gameplay",label:"Gameplay"},{value:"tutorial",label:"Tutorial"},{value:"endgame",label:"Endgame"}],nl=["environment","ui","character","system","backgrounds"],al=["bg","world","ui"],Ys={SwerveMove:{speed:5,sensitivity:1,directionMode:"dominantAxis",axis:"both",bounds:{left:-400,right:400,top:-300,bottom:300}},DragToWin:{targetId:"",successDistance:80},DragSnap:{snapTargetId:"",snapDistance:40},JoystickMove:{speed:6,bounds:{left:-400,right:400,top:-300,bottom:300}}},Pi=class{constructor(){this.modal=null;this.state=null}open(e){this.state=this.createInitialState(e),this.createModal(),document.body.appendChild(this.modal),this.attachEventListeners(),this.updateStepUI()}close(){this.modal&&this.modal.parentNode&&this.modal.parentNode.removeChild(this.modal),window.__wizardAssetPicker=null,this.modal=null,this.state=null}createInitialState(e){return{step:1,objectType:"sprite",instanceId:"",displayName:"",category:"environment",screenId:e.screenId,layer:"world",positionMode:"static",anchorPreset:"center",anchorX:.5,anchorY:.5,positionX:0,positionY:0,offsetX:0,offsetY:0,scale:.2,rotation:0,zIndex:0,assetPath:"",tint:"",alpha:1,text:"",font:"brand.primary",fontSize:18,letterSpacing:0,align:"center",graphicsWidth:200,graphicsHeight:200,graphicsFill:"#FFFFFF",graphicsAlpha:1,interactionEnabled:!1,dragEnabled:!1,hoverEnabled:!1,clickEnabled:!1,logicId:"",logicPropsRaw:""}}createModal(){let e=document.createElement("div");e.className="wizard-modal",e.innerHTML=`
|
|
97
|
+
`,this.modal=e,this.attachEventListeners(),this.initializeCanvas()}initializeCanvas(){this.modal&&(this.canvas=this.modal.querySelector(".asset-crop-canvas"),this.canvas&&(this.ctx=this.canvas.getContext("2d"),this.canvas.width=400,this.canvas.height=300))}loadImage(){this.options&&(this.image=new Image,this.image.crossOrigin="anonymous",this.image.onload=()=>{this.initializeCrop(),this.render()},this.image.src=this.options.imageSrc)}initializeCrop(){var i;if(!this.image||!this.canvas)return;let e=this.image.width/this.image.height,t=this.canvas.width/this.canvas.height;e>t?(this.cropHeight=this.image.height,this.cropWidth=this.cropHeight*t,this.cropX=(this.image.width-this.cropWidth)/2,this.cropY=0):(this.cropWidth=this.image.width,this.cropHeight=this.cropWidth/t,this.cropX=0,this.cropY=(this.image.height-this.cropHeight)/2),(i=this.options)!=null&&i.aspectRatio&&this.applyAspectRatio(this.options.aspectRatio),this.fitToCanvas()}applyAspectRatio(e){if(!this.image)return;let t=this.image.width/this.image.height,i=this.cropX+this.cropWidth/2,n=this.cropY+this.cropHeight/2;e>t?(this.cropWidth=Math.min(this.image.width,this.cropHeight*e),this.cropHeight=this.cropWidth/e):(this.cropHeight=Math.min(this.image.height,this.cropWidth/e),this.cropWidth=this.cropHeight*e),this.cropX=Math.max(0,Math.min(this.image.width-this.cropWidth,i-this.cropWidth/2)),this.cropY=Math.max(0,Math.min(this.image.height-this.cropHeight,n-this.cropHeight/2))}fitToCanvas(){if(!this.image||!this.canvas)return;let e=this.canvas.width/this.cropWidth,t=this.canvas.height/this.cropHeight;this.scale=Math.min(e,t)*.9,this.panX=(this.canvas.width-this.cropWidth*this.scale)/2,this.panY=(this.canvas.height-this.cropHeight*this.scale)/2}render(){!this.ctx||!this.image||!this.canvas||(this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.ctx.save(),this.ctx.translate(this.panX,this.panY),this.ctx.scale(this.scale,this.scale),this.ctx.drawImage(this.image,-this.cropX,-this.cropY,this.image.width,this.image.height),this.ctx.restore(),this.drawCropOverlay(),this.updatePreview())}drawCropOverlay(){if(!this.ctx||!this.canvas)return;let e=this.panX,t=this.panY,i=this.cropWidth*this.scale,n=this.cropHeight*this.scale;this.ctx.fillStyle="rgba(0, 0, 0, 0.5)",this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height),this.ctx.clearRect(e,t,i,n),this.ctx.strokeStyle="#ffffff",this.ctx.lineWidth=2,this.ctx.strokeRect(e,t,i,n),this.ctx.fillStyle="#ffffff";let a=8;[[e,t],[e+i-a,t],[e,t+n-a],[e+i-a,t+n-a]].forEach(([o,l])=>{var c;(c=this.ctx)==null||c.fillRect(o,l,a,a)})}updatePreview(){if(!this.modal||!this.image)return;let e=this.modal.querySelector(".asset-crop-preview-canvas");if(!e)return;let t=e.getContext("2d");if(!t)return;let i=150;e.width=i,e.height=i;let n=i/this.cropWidth,a=i/this.cropHeight,s=Math.min(n,a),o=this.cropWidth*s,l=this.cropHeight*s,c=(i-o)/2,d=(i-l)/2;t.drawImage(this.image,this.cropX,this.cropY,this.cropWidth,this.cropHeight,c,d,o,l)}attachEventListeners(){if(!this.modal||!this.canvas)return;this.canvas.addEventListener("mousedown",this.handleMouseDown.bind(this)),this.canvas.addEventListener("mousemove",this.handleMouseMove.bind(this)),this.canvas.addEventListener("mouseup",this.handleMouseUp.bind(this)),this.canvas.addEventListener("wheel",this.handleWheel.bind(this)),this.canvas.addEventListener("touchstart",this.handleTouchStart.bind(this)),this.canvas.addEventListener("touchmove",this.handleTouchMove.bind(this)),this.canvas.addEventListener("touchend",this.handleTouchEnd.bind(this));let e=this.modal.querySelector(".asset-crop-zoom-slider");e==null||e.addEventListener("input",i=>{let n=parseFloat(i.target.value);this.setZoom(n)});let t=this.modal.querySelector(".asset-crop-aspect-select");t==null||t.addEventListener("change",i=>{let n=i.target.value;this.setAspectRatio(n)}),this.modal.addEventListener("click",i=>{switch(i.target.dataset.action){case"reset":this.reset();break;case"apply":this.applyCrop();break;case"cancel":case"close":this.close();break}}),this.modal.addEventListener("click",i=>{i.target===this.modal&&this.close()})}handleMouseDown(e){this.isDragging=!0,this.dragStartX=e.clientX,this.dragStartY=e.clientY,this.lastPanX=this.panX,this.lastPanY=this.panY,this.canvas.style.cursor="grabbing"}handleMouseMove(e){if(!this.isDragging)return;let t=e.clientX-this.dragStartX,i=e.clientY-this.dragStartY;this.panX=this.lastPanX+t,this.panY=this.lastPanY+i,this.constrainPan(),this.render()}handleMouseUp(){this.isDragging=!1,this.canvas.style.cursor="grab"}handleWheel(e){e.preventDefault();let t=e.deltaY>0?.9:1.1;this.setZoom(this.scale*t)}handleTouchStart(e){e.touches.length===1&&(this.isDragging=!0,this.dragStartX=e.touches[0].clientX,this.dragStartY=e.touches[0].clientY,this.lastPanX=this.panX,this.lastPanY=this.panY)}handleTouchMove(e){if(!this.isDragging||e.touches.length!==1)return;e.preventDefault();let t=e.touches[0].clientX-this.dragStartX,i=e.touches[0].clientY-this.dragStartY;this.panX=this.lastPanX+t,this.panY=this.lastPanY+i,this.constrainPan(),this.render()}handleTouchEnd(){this.isDragging=!1}setZoom(e){this.scale=Math.max(.1,Math.min(3,e)),this.updateZoomUI(),this.constrainPan(),this.render()}setAspectRatio(e){let t;switch(e){case"1:1":t=1;break;case"4:3":t=4/3;break;case"16:9":t=16/9;break;case"3:2":t=3/2;break;default:t=void 0}t&&this.applyAspectRatio(t),this.fitToCanvas(),this.render()}updateZoomUI(){if(!this.modal)return;let e=this.modal.querySelector(".asset-crop-zoom-value"),t=this.modal.querySelector(".asset-crop-zoom-slider");e&&(e.textContent=`${this.scale.toFixed(1)}x`),t&&(t.value=this.scale.toString())}constrainPan(){if(!this.canvas)return;let e=this.cropWidth*this.scale,t=this.cropHeight*this.scale;this.panX=Math.max(this.canvas.width-e,Math.min(0,this.panX)),this.panY=Math.max(this.canvas.height-t,Math.min(0,this.panY))}reset(){this.initializeCrop(),this.render()}applyCrop(){var n;if(!this.image||!((n=this.options)!=null&&n.onCrop))return;let e=document.createElement("canvas"),t=e.getContext("2d");if(!t)return;e.width=this.cropWidth,e.height=this.cropHeight,t.drawImage(this.image,this.cropX,this.cropY,this.cropWidth,this.cropHeight,0,0,this.cropWidth,this.cropHeight);let i=e.toDataURL("image/png");this.options.onCrop(i),this.close()}close(){this.modal&&this.modal.parentNode&&this.modal.parentNode.removeChild(this.modal);let e=this.options;this.modal=null,this.canvas=null,this.ctx=null,this.image=null,this.options=null,e!=null&&e.onCancel&&e.onCancel()}};window.openAssetCrop=function(r){new Mi().open(r)}});var Dl={};at(Dl,{COLORS:()=>Ee,ConfigWatcher:()=>Ze,DebugPanel:()=>Yt,DefaultReloadStrategy:()=>Nt,Handler:()=>me,PlayableLoadingScreen:()=>mn,PreviewShell:()=>gn,STROKE_WIDTH:()=>Fr,THEME:()=>Br,applyConfigOverride:()=>re,applyConfigOverrides:()=>$e,applyConfigsToDisk:()=>xi,applyDefaults:()=>Je,baseLottie:()=>In,bootstrap:()=>Tl,clearConfigOverrides:()=>pe,clearConfigOverridesForObject:()=>Ds,configOverrideManager:()=>Ns,createPreviewShell:()=>$a,deepClone:()=>Q,default:()=>qe,defaultPreset:()=>ki,deviceGroups:()=>aa,devicePresets:()=>na,diffConfigs:()=>Jn,exportConfigsAsJSON:()=>Xe,getConfigOverrides:()=>se,getConfigStateSummary:()=>De,getOverrideMode:()=>Rt,getPresetById:()=>Qe,getPresetsByCategory:()=>tl,loadAllObjectConfigs:()=>Ci,loadComponentSchemas:()=>Ei,loadEngineConfig:()=>Ai,loadGamePromptConfig:()=>Wn,loadObjectCentricConfig:()=>Ie,loadObjectConfig:()=>He,loadSceneConfig:()=>Li,redoLastConfigChange:()=>wi,rehydrateObject:()=>Zn,removeConfigOverride:()=>zt,resetToApplied:()=>$t,resetToOriginal:()=>Si,setBootstrapDependencies:()=>Al,setOverrideMode:()=>qn,setupHotReload:()=>ta,setupLiveEditBridge:()=>hn,toLegacyFormat:()=>Kn,trackObjectCreation:()=>Hs,trackObjectDeletion:()=>Fs,undoLastConfigChange:()=>vi,validateObjectConfig:()=>pt});module.exports=lo(Dl);var Oe={};function ai(r,e,t=!1){Oe[r]||(Oe[r]=[]),Oe[r].push({fn:e,once:t})}function An(r,e){if(Oe[r]){if(!e){delete Oe[r];return}Oe[r]=Oe[r].filter(t=>t.fn!==e)}}function si(r,...e){let t=Oe[r];if(t)for(let i of[...t])i.fn(...e),i.once&&An(r,i.fn)}function oe(r,e){ai(r,e,!0)}var K=null,he=[],rt=null;function es(r){K=r,he=[],rt!==null&&(clearTimeout(rt),rt=null)}function ts(){var r,e,t;return{endpoint:(K==null?void 0:K.endpoint)||"",transport:(K==null?void 0:K.transport)||"beacon",batchSize:(r=K==null?void 0:K.batchSize)!=null?r:10,flushIntervalMs:(e=K==null?void 0:K.flushIntervalMs)!=null?e:300,maxQueue:(t=K==null?void 0:K.maxQueue)!=null?t:200,debug:!!(K!=null&&K.debug)}}async function Za(r,e,t,i){let n=JSON.stringify(e);if(t==="beacon"&&typeof navigator!="undefined"&&typeof navigator.sendBeacon=="function")try{let a=navigator.sendBeacon(r,new Blob([n],{type:"application/json"}));i&&console.log("[handler.telemetry] beacon",a,e);return}catch(a){i&&console.warn("[handler.telemetry] beacon failed, fallback to fetch",a)}try{await fetch(r,{method:"POST",headers:{"Content-Type":"application/json"},body:n,keepalive:!0}),i&&console.log("[handler.telemetry] fetch",e)}catch(a){i&&console.warn("[handler.telemetry] fetch failed",a)}}function Ln(r,e){let t=ts();if(e&&t.endpoint){if(he.push(r),he.length>t.maxQueue&&(he=he.slice(he.length-t.maxQueue)),he.length>=t.batchSize){Qa();return}rt===null&&(rt=window.setTimeout(()=>{rt=null,Qa()},t.flushIntervalMs))}}async function Qa(){let r=ts();if(!r.endpoint||he.length===0)return;let e=he.splice(0,r.batchSize);await Za(r.endpoint,{events:e},r.transport,r.debug),he.length>0&&await Za(r.endpoint,{events:he.splice(0,r.batchSize)},r.transport,r.debug)}function is(r){return Math.max(0,Math.min(1,r))}function co(r){let e=String(r!=null?r:"power2.out");if(e==="linear")return t=>t;if(e==="sine.inOut")return t=>.5-Math.cos(Math.PI*t)/2;if(e==="power2.out"||e==="easeOutQuad")return t=>1-(1-t)*(1-t);if(e.startsWith("back.out")){let t=e.match(/back\.out\(([\d.]+)\)/),i=t?Number(t[1]):1.8;return n=>1+(i+1)*Math.pow(n-1,3)+i*Math.pow(n-1,2)}return t=>1-(1-t)*(1-t)}function It(){return typeof performance!="undefined"&&performance.now?performance.now():Date.now()}function po(r,e){let t=r==null?void 0:r[e];return typeof t=="number"?t:0}function ns(r,e,t){try{r[e]=t}catch{}}function uo(r){let e=r==null?void 0:r.scale;if(!e)return null;let t=typeof e.x=="number"?e.x:1,i=typeof e.y=="number"?e.y:1;return{x:t,y:i}}function as(r,e){let t=r==null?void 0:r.scale;if(t)try{typeof t.set=="function"?t.set(e.x,e.y):(typeof t.x=="number"&&(t.x=e.x),typeof t.y=="number"&&(t.y=e.y))}catch{}}function ss(r,e){let t=uo(r);if(!t)return{from:null,to:null};let i=null,n=null;return typeof e.scale=="number"?(i=e.scale,n=e.scale):e.scale&&typeof e.scale=="object"&&(typeof e.scale.x=="number"&&(i=e.scale.x),typeof e.scale.y=="number"&&(n=e.scale.y)),typeof e.scaleX=="number"&&(i=e.scaleX),typeof e.scaleY=="number"&&(n=e.scaleY),i===null&&n===null?{from:null,to:null}:{from:{x:t.x,y:t.y},to:{x:i!=null?i:t.x,y:n!=null?n:t.y}}}function rs(){let r=new Set,e=new WeakMap,t=null,i=()=>{if(t!=null)return;t=requestAnimationFrame(()=>{t=null,o(),r.size>0&&i()})},n=d=>{var u;r.add(d);let p=(u=e.get(d.target))!=null?u:new Set;p.add(d),e.set(d.target,p),i()},a=d=>{r.delete(d);let p=e.get(d.target);p&&(p.delete(d),p.size===0&&e.delete(d.target))},s=d=>{d.killed||(d.killed=!0,a(d))},o=()=>{var p,u;let d=It();for(let g of Array.from(r)){if(g.killed||g.paused)continue;let h=d-g.startMs-g.delayMs;if(h<0)continue;let f=g.durationMs>0?h/g.durationMs:1,m=is(f),b=g.repeat>=0?g.repeat+1:1,y=g.repeat>0?Math.min(Math.floor(f),b-1):0;if(g.repeat>0&&f>=1){let T=f-y;m=is(T)}let v=g.ease(m);g.yoyo&&y%2===1&&(v=1-v);for(let T of g.props)ns(g.target,T.key,T.from+(T.to-T.from)*v);g.scaleFrom&&g.scaleTo&&as(g.target,{x:g.scaleFrom.x+(g.scaleTo.x-g.scaleFrom.x)*v,y:g.scaleFrom.y+(g.scaleTo.y-g.scaleFrom.y)*v});try{(p=g.onUpdate)==null||p.call(g)}catch{}if(f>=b){s(g);try{(u=g.onComplete)==null||u.call(g)}catch{}}}},l=(d,p,u)=>{var T;let g=Math.max(0,(typeof p.duration=="number"?p.duration:.5)*1e3),h=Math.max(0,(typeof p.delay=="number"?p.delay:0)*1e3+((T=u==null?void 0:u.delayMsOverride)!=null?T:0)),f=co(p.ease),m=typeof p.repeat=="number"?Math.max(0,p.repeat|0):0,b=p.yoyo===!0,y=new Set(["duration","delay","ease","repeat","yoyo","onUpdate","onComplete","scale","scaleX","scaleY"]),v=[];for(let I of Object.keys(p)){if(y.has(I))continue;let M=p[I];typeof M=="number"&&v.push({key:I,from:po(d,I),to:M})}let w=ss(d,p);return{target:d,startMs:It(),delayMs:h,durationMs:g,ease:f,props:v,scaleFrom:w.from,scaleTo:w.to,repeat:m,yoyo:b,onUpdate:typeof p.onUpdate=="function"?p.onUpdate:void 0,onComplete:typeof p.onComplete=="function"?p.onComplete:void 0,killed:!1,paused:!1,pauseAtMs:null}},c={to(d,p){let u=l(d,p);return n(u),{kill:()=>s(u),pause:()=>{u.paused||(u.paused=!0,u.pauseAtMs=It())},resume:()=>{var f;if(!u.paused)return;let g=(f=u.pauseAtMs)!=null?f:It(),h=It()-g;u.startMs+=h,u.paused=!1,u.pauseAtMs=null},isActive:()=>!u.killed&&!u.paused}},fromTo(d,p,u){return c.set(d,p),c.to(d,u)},set(d,p){if(!d||!p)return;for(let g of Object.keys(p)){let h=p[g];g==="scale"||g==="scaleX"||g==="scaleY"||typeof h=="number"&&ns(d,g,h)}let u=ss(d,p);u.to&&as(d,u.to)},killTweensOf(d){let p=e.get(d);if(p)for(let u of Array.from(p))s(u)},timeline(d={}){let p=[],u=0,g=!1,h=[],f=y=>{if(typeof y=="number")return Math.max(0,y*1e3);let v=typeof y=="string"?y.trim():"";return v.startsWith("+=")?u+Math.max(0,Number(v.slice(2))*1e3||0):v?Math.max(0,Number(v)*1e3||0):u},m=y=>{p.push(y);let v=Math.max(0,(typeof y.vars.duration=="number"?y.vars.duration:.5)*1e3);u=Math.max(u,y.atMs+v)},b={to(y,v,w){return m({kind:"to",target:y,vars:v,atMs:f(w)}),b},fromTo(y,v,w,T){return m({kind:"fromTo",target:y,vars:w,from:v,atMs:f(T)}),b},play(){var y,v;if(g)return b;g=!0,h=[];for(let w of p)w.kind==="fromTo"&&c.set(w.target,(y=w.from)!=null?y:{}),h.push(c.to(w.target,{...w.vars,delay:w.atMs/1e3+((v=w.vars.delay)!=null?v:0)}));return b},pause(){for(let y of h)y.pause();return b},kill(){for(let y of h)y.kill();h=[],g=!1}};return d.paused||b.play(),b}};return c}function os(){if(typeof window=="undefined")return;let r=window;if(!r.gsap)try{r.gsap=rs()}catch{}}var ls={name:"handler-playable-sdk",version:"1.0.90",type:"module",description:"Handler Playable SDK v0.1 with contract-aligned surface (root sandbox, canonical event envelope).",main:"dist/index.cjs",module:"dist/index.js",types:"dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js",require:"./dist/index.cjs"},"./pixi":{types:"./dist/pixi/index.d.ts",import:"./dist/pixi/index.js",require:"./dist/pixi/index.cjs"},"./pixi/index.css":{import:"./dist/pixi/index.css",require:"./dist/pixi/index.css"},"./three":{types:"./dist/three/index.d.ts",import:"./dist/three/index.js",require:"./dist/three/index.cjs"},"./cli":{types:"./dist/cli/index.d.ts",import:"./dist/cli/index.js",require:"./dist/cli/index.cjs"}},bin:{"handler-student-helper":"./bin/student-helper.mjs","handler-validate":"./bin/validate.mjs","handler-sync-screens":"./bin/sync-screens.mjs","handler-brand-dna":"./bin/brand-dna.mjs","handler-setup-library":"./bin/setup-library.mjs","handler-screen-helper":"./bin/screen-helper.mjs"},scripts:{prebuild:"python3 src/preview/build-css.py",build:"tsup src/index.ts src/pixi/index.ts src/three/index.ts src/cli/index.ts --format cjs,esm --dts --clean --minify --external lottie-web --external jszip && npm run create-mjs-symlinks && npm run postbuild-cli && npm run obfuscate && npm run postbuild",postbuild:"python3 src/preview/copy-css-to-dist.py","postbuild-cli":"cp src/cli/*.mjs dist/cli/ && mkdir -p dist/cli/student-helper && cp src/cli/student-helper/*.mjs dist/cli/student-helper/ && chmod +x dist/cli/*.mjs dist/cli/student-helper/*.mjs && chmod +x bin/*.mjs","create-mjs-symlinks":"cd dist && ln -sf index.js index.mjs && cd pixi && ln -sf index.js index.mjs && cd ../three && ln -sf index.js index.mjs","build:dev":"tsup src/index.ts src/pixi/index.ts src/three/index.ts src/cli/index.ts --format cjs,esm --dts --clean --external lottie-web --external jszip && npm run create-mjs-symlinks && npm run postbuild-cli",obfuscate:"javascript-obfuscator dist/pixi/index.js --output dist/pixi/index.js --config obfuscator.config.json && javascript-obfuscator dist/three/index.js --output dist/three/index.js --config obfuscator.config.json && javascript-obfuscator dist/cli/index.js --output dist/cli/index.js --config obfuscator.config.json && npm run obfuscate-cli","obfuscate-cli":'for file in dist/cli/*.mjs dist/cli/student-helper/*.mjs; do javascript-obfuscator "$file" --output "$file" --config obfuscator.config.json; done',lint:"eslint 'src/**/*.{ts,tsx}'",typecheck:"tsc --noEmit",prepublishOnly:"npm run build","publish:update":"node scripts/publish-and-update.cjs patch","publish:update:minor":"node scripts/publish-and-update.cjs minor","publish:update:major":"node scripts/publish-and-update.cjs major"},author:"Handler",license:"MIT",publishConfig:{access:"public"},repository:{type:"git",url:"https://github.com/HandlerAIGames/handler-playable-sdk.git"},files:["dist","bin","LICENSE","README.md"],peerDependencies:{"lottie-web":"^5.0.0","pixi.js":"^8.0.0",three:"^0.182.0"},peerDependenciesMeta:{"pixi.js":{optional:!0},three:{optional:!0},"lottie-web":{optional:!0}},devDependencies:{"@types/three":"^0.182.0",eslint:"^9.39.2","javascript-obfuscator":"^5.1.0","pixi.js":"8.8.1",three:"^0.182.0","ts-node":"^10.9.2",tsup:"^8.4.0",typescript:"^5.7.2","typescript-eslint":"^8.53.0"},dependencies:{"@google/genai":"^1.35.0","@google/generative-ai":"^0.24.1",jszip:"^3.10.1",sharp:"^0.34.5"}};var le=0,ho=le++,cs=le++,ds=le++,ps=le++,us=le++,gs=le++,hs=le++,fs=le++,ms=le++,bs=le++,ys=le++,vs=le++,W=ho;function ws(){return W===cs}function xs(){return W===ds}function Ss(){return W===ps}function Es(){return W===us}function ot(){return W===gs}function lt(){return W===hs}function Cs(){return W===fs}function As(){return W===ms}function Ls(){return W===bs}function Tn(){return W===ys}function kn(){return W===vs}function Ts(){let r=typeof AD_PROTOCOL!="undefined"?AD_PROTOCOL:"none",e=typeof AD_NETWORK!="undefined"?AD_NETWORK:"web_embed";if(r==="mraid")try{mraid.getState(),W=cs;return}catch{}else if(r==="dapi")try{dapi.isReady(),W=ds;return}catch{}if(e==="facebook")try{typeof FbPlayableAd!="undefined"&&(W=ps)}catch{}else if(e==="google")try{typeof ExitApi!="undefined"&&(W=us)}catch{}else if(e==="mintegral")window.gameReady&&(W=gs);else if(e==="tapjoy")window.TJ_API&&(W=hs);else if(e==="tiktok")window.openAppStore&&(W=fs);else if(e==="smadex")try{window.smxTracking&&(W=ms)}catch{}else if(e==="snapchat")try{window.ScPlayableAd&&(W=bs)}catch{}else e==="vungle"?W=ys:(r==="nucleo"||e==="nucleo")&&(W=vs)}var ri=st(require("lottie-web"),1),In=ri.default;typeof window!="undefined"&&(window.lottie=ri.default,window.__baseLottie=ri.default);var fo=require("pixi.js");var Pn=require("pixi.js");var mo=null;function Mn(r){mo=r}li();oi();var Pt=require("pixi.js");li();var So=typeof __BUILD_MODE__!="undefined"?__BUILD_MODE__:"undefined",Rn=So;if(typeof window!="undefined")try{let r=new XMLHttpRequest;if(r.open("GET","./build-settings.json",!1),r.send(),r.status===200&&r.responseText){let e=JSON.parse(r.responseText);e!=null&&e.buildMode&&(Rn=e.buildMode,console.log(`[ObjectFactory] Build mode overridden by settings: ${Rn}`))}}catch{}function Eo(r){var t,i,n,a,s;if(typeof window!="undefined"&&window.resolveAnchorVec2)return window.resolveAnchorVec2(r);let e={center:{x:.5,y:.5},"top-left":{x:0,y:0},"top-center":{x:.5,y:0},"top-right":{x:1,y:0},"center-left":{x:0,y:.5},"center-right":{x:1,y:.5},"bottom-left":{x:0,y:1},"bottom-center":{x:.5,y:1},"bottom-right":{x:1,y:1},left:{x:0,y:.5},right:{x:1,y:.5},top:{x:.5,y:0},bottom:{x:.5,y:1}};if(Array.isArray(r))return{x:(t=r[0])!=null?t:.5,y:(i=r[1])!=null?i:.5};if(r&&typeof r=="object"&&"x"in r&&"y"in r)return{x:(n=r.x)!=null?n:.5,y:(a=r.y)!=null?a:.5};if(typeof r=="string"){let o=r.trim().toLowerCase();return(s=e[o])!=null?s:{x:.5,y:.5}}return null}var ve=class{static async create(e,t,i){var l,c,d,p,u,g,h;console.log(`[ObjectFactory] create() called for: ${e}, __BUILD_MODE__: ${Rn}`);let n=(l=t==null?void 0:t.render)==null?void 0:l.asset;if(!n){console.log(`[ObjectFactory] No asset definition for: ${e}, returning empty container`);let f=new Pt.Container;return this.applyTransform(f,t==null?void 0:t.transform,t),f}let a=(c=t==null?void 0:t.identity)==null?void 0:c.id;console.log(`[ObjectFactory] Calling AssetLoader.load() for: ${e}, configId: ${a}, type: ${n.type}, path: ${n.path}`);let s=await Ye.load(e,n,i,a);console.log(`[ObjectFactory] AssetLoader.load() completed for: ${e}, rawAsset type: ${(d=s==null?void 0:s.constructor)==null?void 0:d.name}`);let o;if(n.type==="image")console.log("[ObjectFactory] Creating Sprite from texture:",s,"for object:",e),o=new Pt.Sprite(s),console.log("[ObjectFactory] Created object:",o,"type:",(p=o==null?void 0:o.constructor)==null?void 0:p.name),this.applyTransform(o,t==null?void 0:t.transform,t);else if(n.type==="json")if(console.log("[ObjectFactory] JSON asset for",e,"rawAsset type:",(u=s==null?void 0:s.constructor)==null?void 0:u.name,s),s&&(((g=s.constructor)==null?void 0:g.name)==="Container"||s instanceof Pt.Container)){console.warn("[ObjectFactory] JSON asset is Container (from cache), reloading JSON directly");let f=[n.path,`/assets/${n.path}`,`assets/${n.path}`,`../assets/${n.path}`],m=!1;for(let b of f)try{let y=await fetch(b);if(y.ok){o=await y.json(),console.log("[ObjectFactory] Reloaded JSON directly from:",b,"type:",(h=o==null?void 0:o.constructor)==null?void 0:h.name),m=!0;break}}catch{continue}m||(console.error("[ObjectFactory] Failed to reload JSON from any path"),o=s)}else o=s;else o=s,o&&typeof o=="object"&&("x"in o||"position"in o)&&this.applyTransform(o,t==null?void 0:t.transform,t);return o}static applyTransform(e,t,i){var n,a,s,o;if(!(!t||!e)&&(t.position&&("x"in e&&"y"in e?(e.x=(n=t.position.x)!=null?n:0,e.y=(a=t.position.y)!=null?a:0):"position"in e&&e.position&&e.position.set((s=t.position.x)!=null?s:0,(o=t.position.y)!=null?o:0)),t.scale!==void 0&&"scale"in e&&e.scale&&(typeof e.scale=="object"&&"set"in e.scale?e.scale.set(t.scale):e.scale=t.scale),t.rotation!==void 0&&"rotation"in e&&(e.rotation=t.rotation),t.anchor&&"anchor"in e&&e.anchor)){let l=Eo(t.anchor);l&&("set"in e.anchor?e.anchor.set(l.x,l.y):(e.anchor.x=l.x,e.anchor.y=l.y))}}};var Mt=class{constructor(){this.config=null}init(e){this.config=e}get(e){if(!this.config)throw new Error("RuntimeObjectRegistry not initialized. Call init() first.");return this.config.objects.get(e)}getAllIds(){if(!this.config)throw new Error("RuntimeObjectRegistry not initialized. Call init() first.");return Array.from(this.config.objects.keys())}has(e){return this.config?this.config.objects.has(e):!1}};var Lo=st(require("pixi.js"),1);typeof window!="undefined"&&(window.__basePixi=Lo);ct();var ci=require("pixi.js");ct();var Dn=class{constructor(){this.instanceCache=new Map;this.readyPromise=null;this.app=null;this.registry=new Mt}init(e,t){this.registry.init(e),this.app=t}updateConfig(e){this.registry.init(e),this.instanceCache.clear(),this.readyPromise=null}async ready(){this.readyPromise&&await this.readyPromise;let t=this.registry.getAllIds().filter(n=>!this.instanceCache.has(n));if(t.length===0)return;let i=async n=>{n.length&&(console.log("[Assets] Loading objects:",n),await Promise.all(n.map(async a=>{var o;let s=this.registry.get(a);if(!s){console.warn("[Assets] No config found for object:",a);return}try{let l=await ve.create(a,s,this.app);this.instanceCache.set(a,l),console.log("[Assets] Loaded object:",a,(o=l==null?void 0:l.constructor)==null?void 0:o.name)}catch(l){console.error("[Assets] Failed to load object:",a,l)}})))};return this.readyPromise=(async()=>{await i(t);let n=this.registry.getAllIds().filter(a=>!this.instanceCache.has(a));n.length>0&&(console.warn("[Assets] Retrying missing assets:",n),await i(n)),console.log("[Assets] Ready. Cached objects:",Array.from(this.instanceCache.keys()))})(),this.readyPromise}resetScene(){this.instanceCache.clear(),this.readyPromise=null}async reloadObject(e){let t=this.registry.get(e);if(t){let i=await ve.create(e,t,this.app);this.instanceCache.set(e,i)}}get(e){return this.instanceCache.get(e)}},To=new Dn,ko=new Proxy(To,{get(r,e){if(e in r&&typeof r[e]=="function")return r[e].bind(r);if(r.get(e))return r.get(e)}});ct();var Po=require("pixi.js"),Le={width:400,height:600,designWidth:400,scaleFactor:1},pi={scale:1,position:1},Hn=[];function Mo(r,e,t,i,n,a,s){Hn.push({element:r,originalScale:a,positionHelper:e,heightPercent:n}),e(r,t,i,n,a,s,!1)}function jo(){Hn.forEach(({element:r,originalScale:e,positionHelper:t,heightPercent:i})=>{let n=e*Le.scaleFactor;t(r,Le.width,Le.height,i,n,!0,!1)})}function Nn(r,e){console.log(`[SCREEN] updateScreenState called: ${r}x${e}`),Le.width=r,Le.height=e,Le.scaleFactor=Math.min(r/Le.designWidth,1.15),pi.scale=Le.scaleFactor,pi.position=1,console.log(`[SCREEN] Global multipliers - scale: ${pi.scale.toFixed(3)}`),jo()}var _t={layout:{scale_multiplier:1,position_offset:{x:0,y:0},debug_rect_visible:!0,debug_rect_color:16711680,debug_rect_thickness:4,debug_rect_scale_x:1,debug_rect_scale_y:1,screen_scale_x:1,screen_scale_y:1},engine:{scale:1,background_scale:1.05,background_offset_y:0,background_alpha:.98,label_pulse_speed:3,label_pulse_intensity:.03}};function _o(r,e,t){let i=_t[r];i&&i[e]!==void 0&&(i[e]=t,console.log(`Updated ${r}.${e} = ${t}`))}function Oo(){return _t}var Ro={center:{x:.5,y:.5},"center-center":{x:.5,y:.5},middle:{x:.5,y:.5},"middle-center":{x:.5,y:.5},"top-left":{x:0,y:0},"top-center":{x:.5,y:0},"top-right":{x:1,y:0},"bottom-left":{x:0,y:1},"bottom-center":{x:.5,y:1},"bottom-right":{x:1,y:1},"left-center":{x:0,y:.5},"right-center":{x:1,y:.5},"center-left":{x:0,y:.5},"center-right":{x:1,y:.5},left:{x:0,y:.5},right:{x:1,y:.5},top:{x:.5,y:0},bottom:{x:.5,y:1}};function di(r,e){return typeof r=="number"&&Number.isFinite(r)?r:e}function Ke(r,e={x:.5,y:.5}){var t;if(Array.isArray(r))return{x:di(r[0],e.x),y:di(r[1],e.y)};if(r&&typeof r=="object"){let i=r;return{x:di(i.x,e.x),y:di(i.y,e.y)}}if(typeof r=="string"){let i=r.trim().toLowerCase();return(t=Ro[i])!=null?t:e}return e}function ze(r,e,t,i={}){var g,h,f,m,b,y;let n=Ke(t),a=(g=i.inset)!=null?g:{},s=(h=i.padding)!=null?h:{x:0,y:0},o=((f=a.left)!=null?f:0)+s.x,l=((m=a.right)!=null?m:0)+s.x,c=((b=a.top)!=null?b:0)+s.y,d=((y=a.bottom)!=null?y:0)+s.y,p=Math.max(0,r-o-l),u=Math.max(0,e-c-d);return{x:o+p*n.x,y:c+u*n.y}}function dt(r,e,t,i={}){var f,m,b,y,v,w;let n=(f=i.inset)!=null?f:{},a=(m=i.padding)!=null?m:{x:0,y:0},s=((b=n.left)!=null?b:0)+a.x,o=((y=n.right)!=null?y:0)+a.x,l=((v=n.top)!=null?v:0)+a.y,c=((w=n.bottom)!=null?w:0)+a.y,d=Math.max(0,r-s-o),p=Math.max(0,e-l-c),u=Ke(t,{x:.5,y:.5}),g=Math.min(Math.max(u.x,0),1),h=Math.min(Math.max(u.y,0),1);return{x:s+d*g,y:l+p*h}}if(typeof window!="undefined"){let r=window.innerWidth,e=window.innerHeight,t=()=>{let i=window.innerWidth,n=window.innerHeight;(i!==r||n!==e)&&(r=i,e=n,Nn(i,n))};window.addEventListener("resize",t),window.addEventListener("orientationchange",()=>{setTimeout(t,100)}),window.mraid&&(window.mraid.addEventListener("viewableChange",t),window.mraid.addEventListener("sizeChange",t)),Nn(window.innerWidth,window.innerHeight),window.updateDebugConfig=_o,window.getDebugConfig=Oo,window.copyConfig=Vo,window.applyConfig=jt,window.applyConfigForRatio=Yo,window.positionAtBottom=_s,window.positionAtTop=Do,window.positionAtCenter=No,window.positionAtLeft=Ho,window.positionAtRight=Fo,window.positionAtBottomLeft=Bo,window.positionAtBottomRight=Go,window.positionAtTopLeft=Uo,window.positionAtTopRight=qo,window.applyPositionContract=$o,console.log("\u{1F3AE} Debug Config Functions Available:"),console.log("\u2022 updateDebugConfig(category, key, value)"),console.log("\u2022 getDebugConfig()"),console.log("\u2022 copyConfig(presetName)"),console.log("\u2022 applyConfig(config)"),console.log("\u2022 applyConfigForRatio(width, height)"),console.log("\u{1F4CD} Positioning Helpers Available (with scale):"),console.log("\u2022 positionAtBottom(element, w, h, percent, scale)"),console.log("\u2022 positionAtTop(element, w, h, percent, scale)"),console.log("\u2022 positionAtCenter(element, w, h, offsetX, offsetY, scale)"),console.log("\u2022 positionAtLeft/Right(element, w, h, percent, scale)"),console.log("\u2022 Corner positions: BottomLeft/Right, TopLeft/Right (all with scale)"),console.log("\u2022 applyPositionContract(element, w, h, contract)"),console.log("Example: positionAtCenter(mySprite, 400, 600, 0, -50, 1.2)")}function ui(r,e,t=0){return r*e+t}function gi(r,e,t=0){return r*(1-e)+t}function hi(r,e,t=0){return r*e+t}function fi(r,e,t=0){return r*(1-e)+t}function de(r,e=0){return r/2+e}function zo(r,e){return r*e}function $o(r,e,t,i){var s,o,l,c,d,p,u,g,h,f,m,b,y,v,w,T,I,M,L,j;let n=0,a=0;switch(i.type){case"top":n=de(e,(o=(s=i.offset)==null?void 0:s.x)!=null?o:0),a=ui(t,i.percent,(c=(l=i.offset)==null?void 0:l.y)!=null?c:0);break;case"bottom":n=de(e,(p=(d=i.offset)==null?void 0:d.x)!=null?p:0),a=gi(t,i.percent,(g=(u=i.offset)==null?void 0:u.y)!=null?g:0);break;case"left":n=hi(e,i.percent,(f=(h=i.offset)==null?void 0:h.x)!=null?f:0),a=de(t,(b=(m=i.offset)==null?void 0:m.y)!=null?b:0);break;case"right":n=fi(e,i.percent,(v=(y=i.offset)==null?void 0:y.x)!=null?v:0),a=de(t,(T=(w=i.offset)==null?void 0:w.y)!=null?T:0);break;case"center":n=de(e,(M=(I=i.offset)==null?void 0:I.x)!=null?M:0),a=de(t,(j=(L=i.offset)==null?void 0:L.y)!=null?j:0);break}r.position?r.position.set(n,a):(r.x=n,r.y=a),i.scale!==void 0&&i.scale!==1&&r.scale&&(typeof r.scale.set=="function"?r.scale.set(i.scale,i.scale):(r.scale.x=i.scale,r.scale.y=i.scale))}function _s(r,e,t,i=.2,n=1,a=!0,s=!1){let o=zo(t,i),l=gi(t,i/2);Te(r,de(e),l);let c=a?n*Le.scaleFactor:n;ke(r,c),s&&!Hn.find(d=>d.element===r)&&Mo(r,_s,e,t,i,n,a)}function Do(r,e,t,i=.1,n=1){Te(r,de(e),ui(t,i)),ke(r,n)}function No(r,e,t,i=0,n=0,a=1){Te(r,de(e,i),de(t,n)),ke(r,a)}function Ho(r,e,t,i=.1,n=1){Te(r,hi(e,i),de(t)),ke(r,n)}function Fo(r,e,t,i=.1,n=1){Te(r,fi(e,i),de(t)),ke(r,n)}function Bo(r,e,t,i=.05,n=.05,a=1){Te(r,hi(e,n),gi(t,i)),ke(r,a)}function Go(r,e,t,i=.05,n=.05,a=1){Te(r,fi(e,n),gi(t,i)),ke(r,a)}function Uo(r,e,t,i=.05,n=.05,a=1){Te(r,hi(e,n),ui(t,i)),ke(r,a)}function qo(r,e,t,i=.05,n=.05,a=1){Te(r,fi(e,n),ui(t,i)),ke(r,a)}function Te(r,e,t){r&&r.position?typeof r.position.set=="function"?r.position.set(e,t):(r.position.x=e,r.position.y=t):r&&(r.x=e,r.y=t)}function ke(r,e){e!==1&&r&&r.scale&&(typeof r.scale.set=="function"?r.scale.set(e,e):r.scale.x!==void 0&&r.scale.y!==void 0&&(r.scale.x=e,r.scale.y=e))}var We={default:{layout:{scale_multiplier:1,position_offset:{x:0,y:0},debug_rect_visible:!0,debug_rect_color:16711680,debug_rect_thickness:4,debug_rect_scale_x:1,debug_rect_scale_y:1,screen_scale_x:1,screen_scale_y:1},engine:{scale:1,background_scale:1.05,background_offset_y:0,background_alpha:.98,label_pulse_speed:3,label_pulse_intensity:.03}},wide:{layout:{scale_multiplier:1,position_offset:{x:0,y:0},debug_rect_visible:!0,debug_rect_color:16711680,debug_rect_thickness:4,debug_rect_scale_x:1,debug_rect_scale_y:1,screen_scale_x:.9,screen_scale_y:1.1},engine:{scale:1,background_scale:1.1,background_offset_y:0,background_alpha:.95,label_pulse_speed:3,label_pulse_intensity:.03}},square:{layout:{scale_multiplier:1,position_offset:{x:0,y:0},debug_rect_visible:!0,debug_rect_color:16711680,debug_rect_thickness:4,debug_rect_scale_x:1,debug_rect_scale_y:1,screen_scale_x:.85,screen_scale_y:.85},engine:{scale:1,background_scale:1,background_offset_y:0,background_alpha:1,label_pulse_speed:3,label_pulse_intensity:.03}},tall:{layout:{scale_multiplier:1,position_offset:{x:0,y:0},debug_rect_visible:!0,debug_rect_color:16711680,debug_rect_thickness:4,debug_rect_scale_x:1,debug_rect_scale_y:1,screen_scale_x:1.1,screen_scale_y:.9},engine:{scale:1,background_scale:.95,background_offset_y:0,background_alpha:1,label_pulse_speed:3,label_pulse_intensity:.03}}};function Vo(r){return r&&We[r]?JSON.parse(JSON.stringify(We[r])):JSON.parse(JSON.stringify(_t))}function jt(r){Object.keys(r).forEach(e=>{let t=e;_t[t]&&r[t]&&Object.assign(_t[t],r[t])}),console.log("Config applied:",r)}function Yo(r,e){let t=r/e;t>1.6?(jt(We.wide),console.log("Applied WIDE config for ratio:",t)):t<.7?(jt(We.tall),console.log("Applied TALL config for ratio:",t)):t>.8&&t<1.2?(jt(We.square),console.log("Applied SQUARE config for ratio:",t)):(jt(We.default),console.log("Applied DEFAULT config for ratio:",t))}if(typeof window!="undefined"){let r=window;r.configPresets=We,r.resolveAnchorVec2=r.resolveAnchorVec2||Ke,r.resolveScreenAnchorPoint=r.resolveScreenAnchorPoint||ze,r.resolveScreenRatioPoint=r.resolveScreenRatioPoint||dt}Ti();function X(r,e){let t=(n,a)=>a===0?n:t(a,n%a),i=t(r,e);return`${r/i}:${e/i}`}var gd=[{id:"iphone-15-pro-max",label:"iPhone 15 Pro Max",width:430,height:932,category:"iphone",ratio:X(430,932)},{id:"iphone-15-pro",label:"iPhone 15 Pro",width:393,height:852,category:"iphone",ratio:X(393,852)},{id:"iphone-15",label:"iPhone 15",width:393,height:852,category:"iphone",ratio:X(393,852)},{id:"iphone-14",label:"iPhone 14",width:390,height:844,category:"iphone",ratio:X(390,844)},{id:"iphone-se",label:"iPhone SE",width:375,height:667,category:"iphone",ratio:X(375,667)},{id:"iphone-12-mini",label:"iPhone 12 Mini",width:360,height:780,category:"iphone",ratio:X(360,780)}],hd=[{id:"pixel-8-pro",label:"Pixel 8 Pro",width:448,height:998,category:"android",ratio:X(448,998)},{id:"pixel-8",label:"Pixel 8",width:412,height:915,category:"android",ratio:X(412,915)},{id:"samsung-s24-ultra",label:"Samsung S24 Ultra",width:412,height:915,category:"android",ratio:X(412,915)},{id:"samsung-s24",label:"Samsung S24",width:360,height:780,category:"android",ratio:X(360,780)},{id:"samsung-a54",label:"Samsung A54",width:412,height:915,category:"android",ratio:X(412,915)},{id:"oneplus-12",label:"OnePlus 12",width:412,height:915,category:"android",ratio:X(412,915)}],fd=[{id:"ipad-pro-12",label:'iPad Pro 12.9"',width:1024,height:1366,category:"tablet",ratio:X(1024,1366)},{id:"ipad-pro-11",label:'iPad Pro 11"',width:834,height:1194,category:"tablet",ratio:X(834,1194)},{id:"ipad-air",label:"iPad Air",width:820,height:1180,category:"tablet",ratio:X(820,1180)},{id:"ipad-mini",label:"iPad Mini",width:768,height:1024,category:"tablet",ratio:X(768,1024)},{id:"samsung-tab-s9",label:"Samsung Tab S9",width:800,height:1280,category:"tablet",ratio:X(800,1280)}],ia=[{id:"playable-portrait",label:"Playable Portrait",width:320,height:480,category:"playable",ratio:"2:3",mraidScale:1},{id:"mraid-320x480",label:"MRAID 320\xD7480",width:320,height:480,category:"playable",ratio:"2:3",mraidScale:1},{id:"iphone-14",label:"iPhone 14",width:390,height:844,category:"playable",ratio:X(390,844),mraidScale:.7},{id:"ipad-mini",label:"iPad Mini",width:768,height:1024,category:"playable",ratio:X(768,1024),mraidScale:.7}];var na=[...ia],aa=[{category:"playable",label:"Playable Ad",devices:ia}],ki=ia[0];function Qe(r){return na.find(e=>e.id===r)||ki}function tl(r){return na.filter(e=>e.category===r)}ee();var xe=class{async updateProperty(e,t,i,n={}){var l,c,d,p,u,g,h,f,m,b,y,v;console.log("[PropertyUpdateManager] Updating:",e,t,i);let a=window.getEditableObjectConfig;if(typeof a!="function"){console.error("[PropertyUpdateManager] getEditableObjectConfig not available");return}let s=a(e);if(!s){console.error("[PropertyUpdateManager] Config not found for:",e);return}if(re({objectId:e,path:t,value:i},{persist:!0}),t==="transform"||t.startsWith("transform.")){console.log("[DEBUG FALLBACK] PropertyUpdateManager SKIP applyEditableObjectConfig (transform path)",t,e);let w=s==null?void 0:s.motion;if(w&&typeof w=="object"&&w.enabled!==!1&&(((p=w==null?void 0:w.intro)==null?void 0:p.enabled)===!0||((u=w==null?void 0:w.pulse)==null?void 0:u.enabled)===!0||((g=w==null?void 0:w.swing)==null?void 0:g.enabled)===!0||((h=w==null?void 0:w.continuousMove)==null?void 0:h.enabled)===!0||((f=w==null?void 0:w.continuousRotate)==null?void 0:f.enabled)===!0||((m=w==null?void 0:w.orbit)==null?void 0:m.enabled)===!0)){let M=window.applyEditableObjectConfig;if(typeof M=="function"){let L=window.__editableConfig,j=(v=(y=(b=L==null?void 0:L.objects)==null?void 0:b.get)==null?void 0:y.call(b,e))!=null?v:s;await M(e,j),console.log("[PropertyUpdateManager] Applied config for motion object")}}n.refreshInspector||requestAnimationFrame(()=>{window.dispatchEvent(new CustomEvent("config:changed",{detail:{objectId:e}}))})}else{let w=window.applyEditableObjectConfig;if(typeof w=="function"){let T=window.__editableConfig,I=(d=(c=(l=T==null?void 0:T.objects)==null?void 0:l.get)==null?void 0:c.call(l,e))!=null?d:s;await w(e,I),console.log("[PropertyUpdateManager] Applied config successfully")}else console.warn("[PropertyUpdateManager] applyEditableObjectConfig not available")}this.triggerRefresh(e),n.refreshInspector&&window.dispatchEvent(new CustomEvent("inspector:refresh"))}getNestedProperty(e,t){let i=t.split("."),n=e;for(let a of i)if(n&&typeof n=="object"&&a in n)n=n[a];else return;return n}triggerRefresh(e){let t=window.__refreshHierarchy;typeof t=="function"&&t(),window.dispatchEvent(new CustomEvent("inspector:property-updated",{detail:{objectId:e}}))}};function sa(r){let e=document.createElement("input");e.type="file",e.accept="image/*",e.onchange=async t=>{var a;let i=(a=t.target.files)==null?void 0:a[0];if(!i)return;let n=new FileReader;n.onload=async()=>{let s=n.result,o=r.category||"misc",c=`${(r.objectId||"new_asset").replace(/^json\./,"").replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"")||"new_asset"}_uploaded`;try{let p=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:o,filename:`${c}.png`,data:s,overwrite:!0})})).json();if(!(p!=null&&p.success)){alert(`Upload failed: ${(p==null?void 0:p.error)||"Unknown error"}`);return}let u=window.addAssetToRegistry;typeof u=="function"&&u(o,`${c}.png`);try{await fetch("/api/setup-library",{method:"POST",headers:{"Content-Type":"application/json"}})}catch{}let g=window.refreshAssetLibrary;typeof g=="function"&&await g(),await r.onApply(p.path)}catch(d){console.error("[QuickActionsBar] Upload error:",d),alert("Upload failed. Check console.")}},n.readAsDataURL(i)},e.click()}var Ii=class{constructor(){this.updateManager=new xe}async handleAction(e,t,i){console.log("[QuickActionsBar] Action:",e,t,i);let n=window.getEditableObjectConfig;if(typeof n!="function")return;let a=n(t);if(!a)return;let s=this.updateManager.getNestedProperty(a,i);if(e==="ai-convert"||e==="upload"||e==="library"){let o=i==="ui.text"||i==="render.asset.path",l=i==="render.asset.path";o&&(await this.prepareForImageConversion(t,a),e==="ai-convert"&&i!=="render.asset.path"&&(i="render.asset.path"))}switch(e){case"library":this.openLibrary(t,i,s);break;case"ai-edit":this.openAIEditor(t,i,s);break;case"upload":this.openUpload(t,i);break;case"reset":await this.resetToDefault(t,i);break;case"ai-convert":this.handleAiConvert(t,i,s);break;default:console.warn("[QuickActionsBar] Unknown action:",e)}}async prepareForImageConversion(e,t){var i,n;if(console.log("[QuickActionsBar] Preparing for image conversion:",e),t.render||(t.render={alpha:1,visible:!0}),(t.render.alpha===0||t.render.alpha===void 0)&&(t.render.alpha=1,await this.updateManager.updateProperty(e,"render.alpha",1)),(t.render.visible===!1||t.render.visible===void 0)&&(t.render.visible=!0,await this.updateManager.updateProperty(e,"render.visible",!0)),t.render.asset||(t.render.asset={type:"image",path:""}),t.render.asset.type!=="image"&&(t.render.asset.type="image",await this.updateManager.updateProperty(e,"render.asset",{type:"image",path:t.render.asset.path||""})),t.ui&&t.ui.renderMode!=="png"){await this.updateManager.updateProperty(e,"ui.renderMode","png",{refreshInspector:!0}),await this.updateManager.updateProperty(e,"render.tint","#ffffff");let s=((n=(i=t.transform)==null?void 0:i.scale)!=null?n:1)*.3;await this.updateManager.updateProperty(e,"transform.scale",s),console.log("[QuickActionsBar] Text to PNG conversion: set tint white, scale",s)}this.ensureSlotInRegistry(e,t)}ensureSlotInRegistry(e,t){var o,l,c;let i=window.getEditableAssets;if(typeof i!="function")return;let n=i();if(!n||!n.slots)return;let a=e.startsWith("json.")?e.replace("json.",""):e;if(!n.slots.some(d=>d.objectId===a||d.slotId===a)){let d=((o=t.identity)==null?void 0:o.category)||"ui";console.log("[QuickActionsBar] Adding new slot to registry for converted object:",a),n.slots.push({slotId:a,displayName:a.replace(/_/g," "),objectId:a,category:d,currentAsset:((c=(l=t.render)==null?void 0:l.asset)==null?void 0:c.path)||"",defaultAsset:"",libraryFolder:d,assetType:"image"}),n.categories&&!n.categories.includes(d)&&n.categories.push(d),n.libraryAssets&&!n.libraryAssets[d]&&(n.libraryAssets[d]=[]);let p=window.reRenderAssetLibrary;typeof p=="function"&&p()}}openLibrary(e,t,i){var a;let n=window.__debugContext;if(n){if(n.activeTab!=="library"){n.activeTab="library";let s=window.__updateWorkbenchTabs;typeof s=="function"&&s()}if(n.libraryPanel){let s=window.getEditableObjectConfig,o=s==null?void 0:s(e),l=(a=o==null?void 0:o.identity)==null?void 0:a.category;l||(l=t.split(".")[0]==="render"?"environment":"ui"),console.log("[QuickActionsBar] Highlighting library slot:",e,"category:",l),n.libraryPanel.highlightSlot(e,l)}}}openAIEditor(e,t,i){let n=window.__openAiEditor;if(typeof n=="function"){let a=t.split(".").pop()||t;n(a,`Edit ${a} for ${e}`,i,{objectId:e,path:t})}else console.warn("[QuickActionsBar] AI Editor not available")}openUpload(e,t){var s;let i=window.getEditableObjectConfig,n=i==null?void 0:i(e),a=((s=n==null?void 0:n.identity)==null?void 0:s.category)||(t.split(".")[0]==="render"?"environment":"ui");sa({objectId:e,category:a,onApply:async o=>{var g,h;let l=window.applyAssetToSlot,c=this.getFilenameFromPath(o),d=/render\.asset\.path/i.test(t)||/\.(png|jpg|jpeg|gif|webp)$/i.test(o);typeof l=="function"&&c&&d&&await l(e,c,a),await this.updateManager.updateProperty(e,t,o);let p=window.__debugContext;(h=(g=p==null?void 0:p.options)==null?void 0:g.onPropertyChange)==null||h.call(g,e,t,o);let u=window.__highlightLibrarySlot;typeof u=="function"&&setTimeout(()=>{u(e,a)},500),window.dispatchEvent(new CustomEvent("inspector:refresh"))}})}getFilenameFromPath(e){if(!e)return"";let t=e.split("?")[0].replace(/\\/g,"/");return t.split("/").pop()||t}async resetToDefault(e,t){console.log("[QuickActionsBar] Reset to default:",e,t);try{let i=await this.getDefaultValue(e,t);i!==void 0?(await this.updateManager.updateProperty(e,t,i),console.log("[QuickActionsBar] Reset to default value:",i)):alert("No default value found for this property.")}catch(i){console.error("[QuickActionsBar] Failed to reset to default:",i),alert("Failed to reset property. Check console for details.")}}async getDefaultValue(e,t){let i=t.split(".");if(i.length<2)return;let n=i[0],a=i.slice(1),s=window.__editableConfig;if(!(s!=null&&s.schemas))return;let o=null;if(s.schemas instanceof Map?o=s.schemas.get(n):typeof s.schemas=="object"&&(o=s.schemas[n]),!(o!=null&&o.defaults))return;let l=o.defaults;for(let c of a)if(l&&typeof l=="object")l=l[c];else return;return l}handleAiConvert(e,t,i){let n=window.__openAiEditor;if(typeof n=="function"){let s=`A single, high-quality, high-detail game UI icon/asset representing "${String(i||e.replace(/_/g," ").replace("json.",""))}". Modern stylized 3D rendered style, vibrant colors, soft lighting, isolated on solid magenta background, highly polished professional game art.`,o="render.asset.path";console.log("[QuickActionsBar] AI Convert for:",e,"from:",t,"to:",o),n(e,s,"",{objectId:e,path:o});let l=window.__debugContext;if(l){l.activeTab="ai";let c=window.__updateWorkbenchTabs;typeof c=="function"&&c()}}else console.warn("[QuickActionsBar] AI Editor not available")}};var il=[{value:"loading",label:"Loading"},{value:"start",label:"Start"},{value:"gameplay",label:"Gameplay"},{value:"tutorial",label:"Tutorial"},{value:"endgame",label:"Endgame"}],nl=["environment","ui","character","system","backgrounds"],al=["bg","world","ui"],Ys={SwerveMove:{speed:5,sensitivity:1,directionMode:"dominantAxis",axis:"both",bounds:{left:-400,right:400,top:-300,bottom:300}},DragToWin:{targetId:"",successDistance:80},DragSnap:{snapTargetId:"",snapDistance:40},JoystickMove:{speed:6,bounds:{left:-400,right:400,top:-300,bottom:300}}},Pi=class{constructor(){this.modal=null;this.state=null}open(e){this.state=this.createInitialState(e),this.createModal(),document.body.appendChild(this.modal),this.attachEventListeners(),this.updateStepUI()}close(){this.modal&&this.modal.parentNode&&this.modal.parentNode.removeChild(this.modal),window.__wizardAssetPicker=null,this.modal=null,this.state=null}createInitialState(e){return{step:1,objectType:"sprite",instanceId:"",displayName:"",category:"environment",screenId:e.screenId,layer:"world",positionMode:"static",anchorPreset:"center",anchorX:.5,anchorY:.5,positionX:0,positionY:0,offsetX:0,offsetY:0,scale:.2,rotation:0,zIndex:0,assetPath:"",tint:"",alpha:1,text:"",font:"brand.primary",fontSize:18,letterSpacing:0,align:"center",graphicsWidth:200,graphicsHeight:200,graphicsFill:"#FFFFFF",graphicsAlpha:1,interactionEnabled:!1,dragEnabled:!1,hoverEnabled:!1,clickEnabled:!1,logicId:"",logicPropsRaw:""}}createModal(){let e=document.createElement("div");e.className="wizard-modal",e.innerHTML=`
|
|
98
98
|
<div class="wizard-card">
|
|
99
99
|
<div class="wizard-header">
|
|
100
100
|
<div class="wizard-title">
|
|
@@ -353,21 +353,23 @@
|
|
|
353
353
|
<span class="wizard-step-dot ${a===this.state.step?"active":a<this.state.step?"completed":""}"></span>
|
|
354
354
|
<span class="wizard-step-label">Step ${a}</span>
|
|
355
355
|
</div>
|
|
356
|
-
`});e.innerHTML=t.join("")}updateTypeSections(){if(!this.modal||!this.state)return;let e=this.state.objectType;Array.from(this.modal.querySelectorAll("[data-type-section]")).forEach(n=>{let a=n.dataset.typeSection,o=a==="sprite"&&(e==="sprite"||e==="ui-image")||a===e;n.style.display=o?"block":"none"});let i=this.modal.querySelector("[data-type-help]");if(i){let n=e==="ui-text"?"UI text uses the UI renderer with font settings.":e==="graphics"?"Graphics are simple shapes with width/height and fill.":e==="container"?"Containers are empty parents for grouping objects.":"Sprite/UI image uses image assets.";i.textContent=n}}syncFieldValues(){if(!this.modal||!this.state)return;let e=this.state;Array.from(this.modal.querySelectorAll("[data-field]")).forEach(n=>{let a=n.dataset.field;if(!a)return;let
|
|
357
|
-
`)):(t.style.display="none",t.textContent="")}updateActionButtons(){if(!this.modal||!this.state)return;let e=this.modal.querySelector('[data-action="back"]'),t=this.modal.querySelector('[data-action="next"]');e&&(e.disabled=this.state.step===1),t&&(t.textContent=this.state.step===6?"Create":"Next",t.disabled=this.state.step===6&&this.validate().length>0)}validate(){if(!this.state)return[];let e=[],t=this.state.instanceId.trim();return t||e.push("Object ID is required."),t.startsWith("json.")&&e.push('Object ID must not start with "json." (instance id only).'),t&&!/^[a-zA-Z0-9._-]+$/.test(t)&&e.push("Object ID must use letters, numbers, dot, dash, or underscore."),t&&!this.isInstanceIdUnique(t)&&e.push(`Object ID "${t}" already exists.`),(this.state.objectType==="sprite"||this.state.objectType==="ui-image")&&!this.state.assetPath.trim()&&e.push("Asset path is required for image-based objects."),this.state.objectType==="ui-text"&&!this.state.text.trim()&&e.push("Text content is required for UI Text."),e}isInstanceIdUnique(e){let t=window.getEditableObjectList;if(typeof t=="function"){let a=t();if(Array.isArray(a))return!a.includes(e)}let i=window.__HANDLER_SCREEN_INDEX,n=i==null?void 0:i.instanceToScreen;return n&&typeof n=="object"?!Object.prototype.hasOwnProperty.call(n,e):!0}buildPayload(){if(!this.state)return{};let e=this.state.instanceId.trim(),t=`json.${e}`;return{screenId:this.state.screenId,instanceId:e,objectConfigId:t,layer:this.state.layer,config:this.buildObjectConfig(t),forceSync:!0}}buildObjectConfig(e){if(!this.state)return{};let t=this.state.category||"environment",i={identity:{id:e,category:t},transform:{position:{x:this.state.positionX,y:this.state.positionY},offset:{x:this.state.offsetX,y:this.state.offsetY},scale:this.state.scale,rotation:this.state.rotation,anchor:this.state.anchorPreset==="custom"?{x:this.state.anchorX,y:this.state.anchorY}:this.state.anchorPreset,position_ratio:null,position_mode:this.state.positionMode},render:{alpha:this.state.alpha,visible:!0,tint:this.state.tint||null,z_index:this.state.zIndex},instance_id:this.state.instanceId.trim(),object_config:e};return(this.state.objectType==="sprite"||this.state.objectType==="ui-image")&&(i.render.asset={type:"image",path:this.normalizeAssetPath(this.state.assetPath.trim())}),this.state.objectType==="ui-text"&&(i.ui={kind:"text",renderMode:"text",text:this.state.text,font:this.state.font,fontSize:this.state.fontSize,letterSpacing:this.state.letterSpacing,align:this.state.align,color:this.state.tint||"#FFFFFF"},i.render.tint=null),this.state.objectType==="graphics"&&(i.effects={width:this.state.graphicsWidth,height:this.state.graphicsHeight,fill_color:this.state.graphicsFill,fill_alpha:this.state.graphicsAlpha}),this.state.interactionEnabled&&(i.interaction={enabled:!0,drag:{enabled:this.state.dragEnabled},hover:{enabled:this.state.hoverEnabled},click:{enabled:this.state.clickEnabled}}),this.state.logicId&&(i.logic={id:this.state.logicId,props:this.parseLogicProps(this.state.logicPropsRaw)}),i}parseLogicProps(e){if(!e||!e.trim())return{};try{return JSON.parse(e)}catch{return{}}}normalizeAssetPath(e){return!e||e.startsWith("raw/")?e:e.startsWith("/raw/")?e.replace(/^\/raw\//,"raw/"):e}async submit(){var i;if(!this.state)return;if(this.validate().length>0){this.updatePreview();return}let t=this.buildPayload();try{let n=await fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}),a=await n.json().catch(()=>({}));if(!n.ok||(a==null?void 0:a.success)===!1){let
|
|
358
|
-
`))||(a==null?void 0:a.error)||"Failed to create object.";alert(
|
|
356
|
+
`});e.innerHTML=t.join("")}updateTypeSections(){if(!this.modal||!this.state)return;let e=this.state.objectType;Array.from(this.modal.querySelectorAll("[data-type-section]")).forEach(n=>{let a=n.dataset.typeSection,o=a==="sprite"&&(e==="sprite"||e==="ui-image")||a===e;n.style.display=o?"block":"none"});let i=this.modal.querySelector("[data-type-help]");if(i){let n=e==="ui-text"?"UI text uses the UI renderer with font settings.":e==="graphics"?"Graphics are simple shapes with width/height and fill.":e==="container"?"Containers are empty parents for grouping objects.":"Sprite/UI image uses image assets.";i.textContent=n}}syncFieldValues(){if(!this.modal||!this.state)return;let e=this.state;Array.from(this.modal.querySelectorAll("[data-field]")).forEach(n=>{let a=n.dataset.field;if(!a)return;let s=e[a];n instanceof HTMLInputElement&&n.type==="checkbox"?n.checked=!!s:typeof s!="undefined"&&(n.value=String(s))}),Array.from(this.modal.querySelectorAll("[data-object-type]")).forEach(n=>{n.classList.toggle("selected",n.dataset.objectType===this.state.objectType)})}updatePreview(){if(!this.modal||!this.state)return;let e=this.modal.querySelector("[data-preview-json]"),t=this.modal.querySelector("[data-validation-errors]");if(!e||!t)return;let i=this.buildPayload();e.textContent=JSON.stringify(i,null,2);let n=this.validate();n.length>0?(t.style.display="block",t.textContent=n.join(`
|
|
357
|
+
`)):(t.style.display="none",t.textContent="")}updateActionButtons(){if(!this.modal||!this.state)return;let e=this.modal.querySelector('[data-action="back"]'),t=this.modal.querySelector('[data-action="next"]');e&&(e.disabled=this.state.step===1),t&&(t.textContent=this.state.step===6?"Create":"Next",t.disabled=this.state.step===6&&this.validate().length>0)}validate(){if(!this.state)return[];let e=[],t=this.state.instanceId.trim();return t||e.push("Object ID is required."),t.startsWith("json.")&&e.push('Object ID must not start with "json." (instance id only).'),t&&!/^[a-zA-Z0-9._-]+$/.test(t)&&e.push("Object ID must use letters, numbers, dot, dash, or underscore."),t&&!this.isInstanceIdUnique(t)&&e.push(`Object ID "${t}" already exists.`),(this.state.objectType==="sprite"||this.state.objectType==="ui-image")&&!this.state.assetPath.trim()&&e.push("Asset path is required for image-based objects."),this.state.objectType==="ui-text"&&!this.state.text.trim()&&e.push("Text content is required for UI Text."),e}isInstanceIdUnique(e){let t=window.getEditableObjectList;if(typeof t=="function"){let a=t();if(Array.isArray(a))return!a.includes(e)}let i=window.__HANDLER_SCREEN_INDEX,n=i==null?void 0:i.instanceToScreen;return n&&typeof n=="object"?!Object.prototype.hasOwnProperty.call(n,e):!0}buildPayload(){if(!this.state)return{};let e=this.state.instanceId.trim(),t=`json.${e}`;return{screenId:this.state.screenId,instanceId:e,objectConfigId:t,layer:this.state.layer,config:this.buildObjectConfig(t),forceSync:!0}}buildObjectConfig(e){if(!this.state)return{};let t=this.state.category||"environment",i={identity:{id:e,category:t},transform:{position:{x:this.state.positionX,y:this.state.positionY},offset:{x:this.state.offsetX,y:this.state.offsetY},scale:this.state.scale,rotation:this.state.rotation,anchor:this.state.anchorPreset==="custom"?{x:this.state.anchorX,y:this.state.anchorY}:this.state.anchorPreset,position_ratio:null,position_mode:this.state.positionMode},render:{alpha:this.state.alpha,visible:!0,tint:this.state.tint||null,z_index:this.state.zIndex},instance_id:this.state.instanceId.trim(),object_config:e};return(this.state.objectType==="sprite"||this.state.objectType==="ui-image")&&(i.render.asset={type:"image",path:this.normalizeAssetPath(this.state.assetPath.trim())}),this.state.objectType==="ui-text"&&(i.ui={kind:"text",renderMode:"text",text:this.state.text,font:this.state.font,fontSize:this.state.fontSize,letterSpacing:this.state.letterSpacing,align:this.state.align,color:this.state.tint||"#FFFFFF"},i.render.tint=null),this.state.objectType==="graphics"&&(i.effects={width:this.state.graphicsWidth,height:this.state.graphicsHeight,fill_color:this.state.graphicsFill,fill_alpha:this.state.graphicsAlpha}),this.state.interactionEnabled&&(i.interaction={enabled:!0,drag:{enabled:this.state.dragEnabled},hover:{enabled:this.state.hoverEnabled},click:{enabled:this.state.clickEnabled}}),this.state.logicId&&(i.logic={id:this.state.logicId,props:this.parseLogicProps(this.state.logicPropsRaw)}),i}parseLogicProps(e){if(!e||!e.trim())return{};try{return JSON.parse(e)}catch{return{}}}normalizeAssetPath(e){return!e||e.startsWith("raw/")?e:e.startsWith("/raw/")?e.replace(/^\/raw\//,"raw/"):e}async submit(){var i;if(!this.state)return;if(this.validate().length>0){this.updatePreview();return}let t=this.buildPayload();try{let n=await fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}),a=await n.json().catch(()=>({}));if(!n.ok||(a==null?void 0:a.success)===!1){let s=((i=a==null?void 0:a.errors)==null?void 0:i.join(`
|
|
358
|
+
`))||(a==null?void 0:a.error)||"Failed to create object.";alert(s);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),this.close()}catch(n){alert(`Failed to create object: ${n instanceof Error?n.message:String(n)}`)}}async syncScreens(){try{let e=window.__HANDLER_ACTIVE_SCREEN;await fetch("/api/sync-screens",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({force:!0,screenId:e})})}catch(e){console.warn("[AddObjectWizard] Failed to sync screens:",e)}}};var gt=class{constructor(e){this.menu=null;this.closeHandler=null;this.keyHandler=null;this.options=e}open(e){this.createMenu(),document.body.appendChild(this.menu),this.positionMenu(e),this.attachListeners()}close(){var e,t;this.menu&&this.menu.parentNode&&this.menu.parentNode.removeChild(this.menu),this.closeHandler&&(window.removeEventListener("click",this.closeHandler),this.closeHandler=null),this.keyHandler&&(window.removeEventListener("keydown",this.keyHandler),this.keyHandler=null),this.menu=null,(t=(e=this.options).onClose)==null||t.call(e)}createMenu(){let e=document.createElement("div");e.className="context-menu",e.setAttribute("data-context-menu","true"),e.innerHTML=`
|
|
359
359
|
<div class="context-menu-item" data-action="add-logic">\u2699\uFE0F Add Logic</div>
|
|
360
360
|
<div class="context-menu-separator"></div>
|
|
361
|
-
<div class="context-menu-item
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
<div class="context-menu-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
361
|
+
<div class="context-menu-item-wrapper">
|
|
362
|
+
<div class="context-menu-item has-submenu" data-action="image-menu">
|
|
363
|
+
\u{1F5BC}\uFE0F Image
|
|
364
|
+
<span class="context-menu-arrow">\u25B6</span>
|
|
365
|
+
</div>
|
|
366
|
+
<div class="context-menu-submenu" data-submenu="image-menu">
|
|
367
|
+
<div class="context-menu-item" data-action="change-image">\u{1F504} Change Image</div>
|
|
368
|
+
<div class="context-menu-item" data-action="edit-image-crop">\u2702\uFE0F Edit Image (Crop/Move)</div>
|
|
369
|
+
<div class="context-menu-item" data-action="edit-image-ai">\u2728 Edit Image with AI</div>
|
|
370
|
+
<div class="context-menu-item" data-action="upload-image">\u{1F4E4} Upload Image</div>
|
|
371
|
+
<div class="context-menu-item" data-action="go-to-library">\u{1F4DA} Go to Library</div>
|
|
372
|
+
</div>
|
|
371
373
|
</div>
|
|
372
374
|
<div class="context-menu-separator"></div>
|
|
373
375
|
<div class="context-menu-item" data-action="duplicate">\u{1F4CB} Duplicate</div>
|
|
@@ -378,11 +380,11 @@
|
|
|
378
380
|
<div class="context-menu-item" data-action="inspect">\u{1F50D} Open in Inspector</div>
|
|
379
381
|
<div class="context-menu-separator"></div>
|
|
380
382
|
<div class="context-menu-item danger" data-action="delete">\u{1F5D1}\uFE0F Delete</div>
|
|
381
|
-
`,this.menu=e}positionMenu(e){if(!this.menu)return;let{x:t,y:i}=e;this.menu.style.left=`${t}px`,this.menu.style.top=`${i}px`;let n=this.menu.getBoundingClientRect(),a=n.right-window.innerWidth,
|
|
383
|
+
`,this.menu=e}positionMenu(e){if(!this.menu)return;let{x:t,y:i}=e;this.menu.style.left=`${t}px`,this.menu.style.top=`${i}px`;let n=this.menu.getBoundingClientRect(),a=n.right-window.innerWidth,s=n.bottom-window.innerHeight;a>0&&(this.menu.style.left=`${t-a-8}px`),s>0&&(this.menu.style.top=`${i-s-8}px`)}attachListeners(){if(!this.menu)return;let e=this.menu.querySelector('[data-action="image-menu"]'),t=this.menu.querySelector('[data-submenu="image-menu"]'),i=e==null?void 0:e.parentElement;if(e&&t&&i){i.style.position="relative",e.addEventListener("mouseenter",()=>{t.style.display="block"}),t.addEventListener("mouseenter",()=>{t.style.display="block"});let n=()=>{setTimeout(()=>{!t.matches(":hover")&&!e.matches(":hover")&&(t.style.display="none")},100)};e.addEventListener("mouseleave",n),t.addEventListener("mouseleave",()=>{t.style.display="none"})}this.menu.addEventListener("click",n=>{let s=n.target.dataset.action;s&&(n.stopPropagation(),this.handleAction(s))}),this.closeHandler=n=>{let a=n.target;this.menu&&a&&this.menu.contains(a)||this.close()},window.addEventListener("click",this.closeHandler),this.keyHandler=n=>{n.key==="Escape"&&this.close()},window.addEventListener("keydown",this.keyHandler)}handleAction(e){var t,i;switch(e){case"image-menu":return;case"change-image":this.handleChangeImage();break;case"edit-image-crop":this.handleEditImageCrop();break;case"edit-image-ai":this.handleEditImageAI();break;case"upload-image":this.handleUploadImage();break;case"go-to-library":this.handleGoToLibrary();break;case"add-logic":this.handleAddLogic();break;case"duplicate":this.handleDuplicate();break;case"rename":this.handleRename();break;case"move":this.handleMove();break;case"copy":this.handleCopyConfig();break;case"inspect":this.handleOpenInspector();break;case"delete":(i=(t=this.options).onDeleteRequest)==null||i.call(t,this.options.objectId),this.close();break}}async handleDuplicate(){var n,a,s,o,l;let e=`${this.options.objectId}_copy`,t=window.prompt("New instance ID",e);if(!t)return;if(!this.isInstanceIdUnique(t)){alert(`Instance ID "${t}" already exists.`);return}let i=window.confirm(`Share config with original?
|
|
382
384
|
OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sourceId:this.options.objectId,newInstanceId:t,shareConfig:i,screenId:this.options.screenId})}),d=await c.json().catch(()=>({}));if(!c.ok||(d==null?void 0:d.success)===!1){let p=((n=d==null?void 0:d.errors)==null?void 0:n.join(`
|
|
383
|
-
`))||(d==null?void 0:d.error)||"Duplicate failed.";alert(p);return}(
|
|
384
|
-
`))||(l==null?void 0:l.error)||"Rename failed.";alert(c);return}(n=(i=this.options).onRefresh)==null||n.call(i),(
|
|
385
|
-
`))||(o==null?void 0:o.error)||"Move failed.";alert(l);return}(a=(n=this.options).onRefresh)==null||a.call(n),this.close()}catch(
|
|
385
|
+
`))||(d==null?void 0:d.error)||"Duplicate failed.";alert(p);return}(s=(a=this.options).onRefresh)==null||s.call(a),(l=(o=this.options).onSelect)==null||l.call(o,t),this.close()}catch(c){alert(`Duplicate failed: ${c instanceof Error?c.message:String(c)}`)}}async handleRename(){var t,i,n,a,s;let e=window.prompt("New instance ID",this.options.objectId);if(!(!e||e===this.options.objectId)){if(!this.isInstanceIdUnique(e)){alert(`Instance ID "${e}" already exists.`);return}try{let o=await fetch("/api/objects/rename",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:this.options.objectId,screenId:this.options.screenId,newInstanceId:e})}),l=await o.json().catch(()=>({}));if(!o.ok||(l==null?void 0:l.success)===!1){let c=((t=l==null?void 0:l.errors)==null?void 0:t.join(`
|
|
386
|
+
`))||(l==null?void 0:l.error)||"Rename failed.";alert(c);return}(n=(i=this.options).onRefresh)==null||n.call(i),(s=(a=this.options).onSelect)==null||s.call(a,e),this.close()}catch(o){alert(`Rename failed: ${o instanceof Error?o.message:String(o)}`)}}}async handleMove(){var i,n,a;let e=window.prompt("Move to screen (loading/start/gameplay/tutorial/endgame)",this.options.screenId);if(!e)return;let t=e.trim();if(!["loading","start","gameplay","tutorial","endgame"].includes(t)){alert("Invalid screen. Use: loading, start, gameplay, tutorial, endgame.");return}if(t!==this.options.screenId){if(this.options.onMoveRequest){this.options.onMoveRequest(this.options.objectId,t),this.close();return}try{let s=await fetch("/api/objects/move",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:this.options.objectId,fromScreenId:this.options.screenId,toScreenId:t})}),o=await s.json().catch(()=>({}));if(!s.ok||(o==null?void 0:o.success)===!1){let l=((i=o==null?void 0:o.errors)==null?void 0:i.join(`
|
|
387
|
+
`))||(o==null?void 0:o.error)||"Move failed.";alert(l);return}(a=(n=this.options).onRefresh)==null||a.call(n),this.close()}catch(s){alert(`Move failed: ${s instanceof Error?s.message:String(s)}`)}}}handleCopyConfig(){var n,a;let e=window.getEditableObjectConfig,t=typeof e=="function"?e(this.options.objectId):null;if(!t){let s=window.__editableObjectConfigs;s&&typeof s.get=="function"&&(t=(n=s.get(this.options.objectId))!=null?n:null)}if(!t){alert("Config not found.");return}let i=JSON.stringify(t,null,2);(a=navigator.clipboard)==null||a.writeText(i).catch(()=>{alert("Failed to copy to clipboard.")}),this.close()}handleOpenInspector(){var t,i;let e=window.__previewSelectObject;typeof e=="function"&&e(this.options.objectId),(i=(t=this.options).onSelect)==null||i.call(t,this.options.objectId),this.close()}handleChangeImage(){var i,n;let e=this.getObjectConfig(),t=((n=(i=e==null?void 0:e.render)==null?void 0:i.asset)==null?void 0:n.path)||"";Promise.resolve().then(()=>(ut(),Ht)).then(({AssetEditorModal:a})=>{new a().show(this.options.objectId,"render.asset.path",t,o=>{var c,d;let l=window.updateEditableObjectConfig;typeof l=="function"&&(l(this.options.objectId,"render.asset.path",o),(d=(c=this.options).onRefresh)==null||d.call(c))})}).catch(a=>{console.error("Failed to load AssetEditorModal:",a),this.handleGoToLibrary()}),this.close()}handleEditImageCrop(){var n,a;let e=this.getObjectConfig(),t=(a=(n=e==null?void 0:e.render)==null?void 0:n.asset)==null?void 0:a.path;if(!t){alert("No image asset found for this object."),this.close();return}let i=t.startsWith("http")||t.startsWith("data:")?t:`/assets/${t}`;Promise.resolve().then(()=>(oa(),Ws)).then(({AssetCropModal:s})=>{new s().open({imageSrc:i,onCrop:async l=>{var c,d;try{let u=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:"ui",filename:`${this.options.objectId}_cropped_${Date.now()}.png`,dataUrl:l})})).json();if(u.success&&u.path){let g=window.updateEditableObjectConfig;typeof g=="function"&&(g(this.options.objectId,"render.asset.path",u.path),(d=(c=this.options).onRefresh)==null||d.call(c))}else alert("Failed to save cropped image.")}catch(p){alert(`Failed to save cropped image: ${p instanceof Error?p.message:String(p)}`)}},onCancel:()=>{}})}).catch(s=>{console.error("Failed to load AssetCropModal:",s),alert("Crop editor not available.")}),this.close()}handleEditImageAI(){var i,n;let e=this.getObjectConfig(),t=((n=(i=e==null?void 0:e.render)==null?void 0:i.asset)==null?void 0:n.path)||"";Promise.resolve().then(()=>(ut(),Ht)).then(({AssetEditorModal:a})=>{new a().show(this.options.objectId,"render.asset.path",t,o=>{var c,d;let l=window.updateEditableObjectConfig;typeof l=="function"&&(l(this.options.objectId,"render.asset.path",o),(d=(c=this.options).onRefresh)==null||d.call(c))}),setTimeout(()=>{let o=document.querySelector('.asset-editor-tab[data-tab="ai"]');o==null||o.click()},100)}).catch(a=>{console.error("Failed to load AssetEditorModal:",a),alert("AI editor not available.")}),this.close()}handleUploadImage(){var i,n;let e=this.getObjectConfig(),t=((n=(i=e==null?void 0:e.render)==null?void 0:i.asset)==null?void 0:n.path)||"";Promise.resolve().then(()=>(ut(),Ht)).then(({AssetEditorModal:a})=>{new a().show(this.options.objectId,"render.asset.path",t,o=>{var c,d;let l=window.updateEditableObjectConfig;typeof l=="function"&&(l(this.options.objectId,"render.asset.path",o),(d=(c=this.options).onRefresh)==null||d.call(c))}),setTimeout(()=>{let o=document.querySelector('.asset-editor-tab[data-tab="upload"]');o==null||o.click()},100)}).catch(a=>{console.error("Failed to load AssetEditorModal:",a),alert("Upload not available.")}),this.close()}handleGoToLibrary(){var t;let e=window.__debugContext;if(e){(t=e.setActiveTab)==null||t.call(e,"library");let i=window.__highlightLibrarySlot;typeof i=="function"&&i(this.options.objectId)}this.close()}handleAddLogic(){this.handleOpenInspector(),setTimeout(()=>{var t,i,n;let e=document.querySelector('[data-path="logic.id"]');if(e)(t=e.focus)==null||t.call(e),(i=e.scrollIntoView)==null||i.call(e,{behavior:"smooth",block:"center"});else{let a=document.querySelector('[data-section="logic"]');(n=a==null?void 0:a.scrollIntoView)==null||n.call(a,{behavior:"smooth",block:"center"})}},100),this.close()}getObjectConfig(){var i;let e=window.getEditableObjectConfig;if(typeof e=="function")return e(this.options.objectId);let t=window.__editableObjectConfigs;return t&&typeof t.get=="function"&&(i=t.get(this.options.objectId))!=null?i:null}isInstanceIdUnique(e){let t=window.getEditableObjectList;if(typeof t=="function"){let a=t();if(Array.isArray(a))return!a.includes(e)}let i=window.__HANDLER_SCREEN_INDEX,n=i==null?void 0:i.instanceToScreen;return n&&typeof n=="object"?!Object.prototype.hasOwnProperty.call(n,e):!0}};var Ft=[{value:"loading",label:"Loading"},{value:"start",label:"Start"},{value:"gameplay",label:"Gameplay"},{value:"tutorial",label:"Tutorial"},{value:"endgame",label:"Endgame"}],ji=class{constructor(e){this.menu=null;this.closeHandler=null;this.keyHandler=null;this.templates=[];this.isLoadingTemplates=!1;this.targetScreen="gameplay";this.view="root";this.templateQuery="";this.templateGroup=null;this.options=e}getTargetScreenStorageKey(){return`handler_preview_add_menu_target_screen::${typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default"}`}async open(e){await this.loadTemplates(),this.loadTargetScreen(),this.view="root",this.templateQuery="",this.templateGroup=null,this.createMenu(),document.body.appendChild(this.menu),this.positionMenu(e),this.attachListeners()}close(){var e,t;this.menu&&this.menu.parentNode&&this.menu.parentNode.removeChild(this.menu),this.closeHandler&&(window.removeEventListener("click",this.closeHandler),this.closeHandler=null),this.keyHandler&&(window.removeEventListener("keydown",this.keyHandler),this.keyHandler=null),this.menu=null,(t=(e=this.options).onClose)==null||t.call(e)}async loadTemplates(){if(!this.isLoadingTemplates){this.isLoadingTemplates=!0;try{let e=await fetch("/api/objects/templates");if(e.ok){let t=await e.json();this.templates=Array.isArray(t.templates)?t.templates:[]}}catch(e){console.warn("[AddObjectMenu] Failed to load templates:",e),this.templates=[]}finally{this.isLoadingTemplates=!1}}}createMenu(){let e=document.createElement("div");e.className="context-menu",e.setAttribute("data-context-menu","true"),e.innerHTML=this.renderMenuHtml(),this.menu=e,this.updateTargetScreenUI()}positionMenu(e){if(!this.menu)return;let{x:t,y:i}=e;this.menu.style.left=`${t}px`,this.menu.style.top=`${i}px`;let n=this.menu.getBoundingClientRect(),a=n.right-window.innerWidth,s=n.bottom-window.innerHeight;a>0&&(this.menu.style.left=`${t-a-8}px`),s>0&&(this.menu.style.top=`${i-s-8}px`)}attachListeners(){this.menu&&(this.menu.addEventListener("click",e=>{let t=e.target,i=t==null?void 0:t.closest("[data-action]");if(!i||i.classList.contains("disabled"))return;let n=i.dataset.action;if(!n)return;if(e.preventDefault(),e.stopPropagation(),n==="set-screen"){let d=i.dataset.screenId;if(!d||!Ft.some(p=>p.value===d))return;this.setTargetScreen(d);return}if(n==="open-view"){let d=(i.dataset.view||"").trim();(d==="templates"||d==="templates-group"||d==="screens"||d==="systems"||d==="root")&&this.setView(d);return}if(n==="back"){this.setView("root");return}if(n==="open-template-group"){let d=(i.dataset.templateGroup||"").trim();if(!d)return;this.templateGroup=d,this.setView("templates-group");return}if(n==="template-pack"){let d=(i.dataset.templatePack||"").trim();(d==="ui"||d==="screen")&&this.handleInstallTemplatePack(d);return}let a=i.dataset.objectType,s=i.dataset.systemType,o=i.dataset.templateId,l=i.dataset.screenId,c=l!=null?l:this.targetScreen;n==="object"&&a?this.handleCreateObject(a,c):n==="system"&&s?this.handleCreateSystem(s,c):n==="template"&&o&&this.handleCreateFromTemplate(o,c)}),this.menu.addEventListener("input",e=>{if(!this.menu)return;let t=e.target,i=t&&t instanceof HTMLInputElement?t:null;i&&i.classList.contains("context-menu-search")&&(this.templateQuery=i.value||"",this.updateMenuContents({preserveTemplateSearchFocus:!0}))}),this.closeHandler=e=>{let t=e.target;this.menu&&t&&this.menu.contains(t)||this.close()},window.addEventListener("click",this.closeHandler),this.keyHandler=e=>{e.key==="Escape"&&this.close()},window.addEventListener("keydown",this.keyHandler))}async promptScreen(e="Select Screen"){return new Promise(t=>{var c,d,p;let i=document.createElement("div");i.className="add-menu-modal-overlay",i.innerHTML=`
|
|
386
388
|
<div class="add-menu-modal">
|
|
387
389
|
<div class="add-menu-modal-header">
|
|
388
390
|
<div class="add-menu-modal-title">${this.escapeHtml(e)}</div>
|
|
@@ -399,8 +401,8 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
|
|
|
399
401
|
<button class="add-menu-modal-btn add-menu-modal-btn-primary" type="button" data-action="confirm">Confirm</button>
|
|
400
402
|
</div>
|
|
401
403
|
</div>
|
|
402
|
-
`;let n=()=>{i.parentNode&&i.parentNode.removeChild(i)},a=()=>{let g=i.querySelector("#screen-select").value.trim();if(!g||!Ft.some(h=>h.value===g)){alert("Please select a valid screen.");return}n(),t(g)},
|
|
403
|
-
`))||(a==null?void 0:a.error)||"Failed to install templates.";alert(
|
|
404
|
+
`;let n=()=>{i.parentNode&&i.parentNode.removeChild(i)},a=()=>{let g=i.querySelector("#screen-select").value.trim();if(!g||!Ft.some(h=>h.value===g)){alert("Please select a valid screen.");return}n(),t(g)},s=()=>{n(),t(null)};i.querySelector(".add-menu-modal").addEventListener("click",u=>{u.stopPropagation()}),(c=i.querySelector('[data-action="confirm"]'))==null||c.addEventListener("click",a),(d=i.querySelector('[data-action="cancel"]'))==null||d.addEventListener("click",s),(p=i.querySelector(".add-menu-modal-close"))==null||p.addEventListener("click",s),i.addEventListener("click",u=>{u.target===i&&s()});let l=i.querySelector("#screen-select");l.addEventListener("keydown",u=>{u.key==="Enter"?(u.preventDefault(),a()):u.key==="Escape"&&(u.preventDefault(),s())}),document.body.appendChild(i),l.focus()})}loadTargetScreen(){try{let t=(window.localStorage.getItem(this.getTargetScreenStorageKey())||"").trim();Ft.some(i=>i.value===t)?this.targetScreen=t:this.targetScreen="gameplay"}catch{this.targetScreen="gameplay"}}setTargetScreen(e){this.targetScreen=e;try{window.localStorage.setItem(this.getTargetScreenStorageKey(),e)}catch{}this.updateTargetScreenUI()}updateTargetScreenUI(){let e=this.menu;if(!e)return;Array.from(e.querySelectorAll(".context-menu-screen-chip[data-screen-id]")).forEach(i=>{let n=i.dataset.screenId;i.classList.toggle("active",n===this.targetScreen)})}setView(e){var t;if(this.view=e,e!=="templates-group"&&(this.templateGroup=null),this.updateMenuContents(),e==="templates"||e==="templates-group"){let i=(t=this.menu)==null?void 0:t.querySelector(".context-menu-search");i&&i.focus()}}updateMenuContents(e){if(!this.menu)return;let t=!!(e!=null&&e.preserveTemplateSearchFocus)&&document.activeElement===this.menu.querySelector(".context-menu-search");if(this.menu.innerHTML=this.renderMenuHtml(),this.updateTargetScreenUI(),t){let i=this.menu.querySelector(".context-menu-search");i==null||i.focus(),i&&(i.selectionStart=i.selectionEnd=i.value.length)}}renderMenuHtml(){return this.view==="templates"?this.renderTemplatesView():this.view==="templates-group"?this.renderTemplatesGroupView():this.view==="screens"?this.renderScreensView():this.view==="systems"?this.renderSystemsView():this.renderRootView()}getPackTemplateIds(e){return e==="ui"?["template.ui.rotating_logo","template.ui.floating_cta_badge","template.ui.bottom_cta_button","template.ui.hand_pointer","template.ui.title_banner","template.ui.instruction_text","template.ui.score_hud"]:["template.screen.rotating_coin","template.screen.rotating_gem","template.screen.tap_destroy_target","template.screen.draggable_piece","template.screen.snap_slot","template.screen.collectable_coin","template.screen.player_swerve","template.screen.enemy_damageable"]}getMissingPackTemplateIds(e){let t=new Set(this.templates.map(i=>String(i.id||"").toLowerCase()));return this.getPackTemplateIds(e).filter(i=>!t.has(i.toLowerCase()))}async handleInstallTemplatePack(e){var t;try{let n=await fetch(e==="ui"?"/api/templates/ui":"/api/templates/screen",{method:"POST",headers:{"Content-Type":"application/json"},body:"{}"}),a=await n.json().catch(()=>({}));if(!n.ok||(a==null?void 0:a.success)===!1){let s=((t=a==null?void 0:a.errors)==null?void 0:t.join(`
|
|
405
|
+
`))||(a==null?void 0:a.error)||"Failed to install templates.";alert(s);return}await this.loadTemplates(),this.updateMenuContents()}catch(i){alert(`Failed to install templates: ${i instanceof Error?i.message:String(i)}`)}}renderRootView(){let e=this.templates.length;return`
|
|
404
406
|
${this.renderTargetScreenSection()}
|
|
405
407
|
<div class="context-menu-section-title">Objects</div>
|
|
406
408
|
<div class="context-menu-item" data-action="object" data-object-type="sprite">\u{1F5BC}\uFE0F Sprite</div>
|
|
@@ -417,7 +419,7 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
|
|
|
417
419
|
<div class="context-menu-section-title">Templates</div>
|
|
418
420
|
<input class="context-menu-search" type="text" placeholder="Search templates\u2026" value="${this.escapeHtml(this.templateQuery)}" />
|
|
419
421
|
${o||'<div class="context-menu-item disabled">No matches</div>'}
|
|
420
|
-
`}let n=i.map(
|
|
422
|
+
`}let n=i.map(s=>{var d,p;let o=(p=(d=t.get(s))==null?void 0:d.length)!=null?p:0,l=s==="UI Templates"||s==="Screen Templates";return o<=0&&!l?`<div class="context-menu-item disabled">${this.escapeHtml(s)} <span class="context-menu-subtle">0</span></div>`:`<div class="${o>0,"context-menu-item context-menu-submenu"}" data-action="open-template-group" data-template-group="${this.escapeHtml(s)}">${this.escapeHtml(s)} <span class="context-menu-subtle">${o}</span></div>`}).join(""),a=this.templates.length>0?"":'<div class="context-menu-item disabled">No templates available</div>';return`
|
|
421
423
|
<div class="context-menu-item context-menu-back" data-action="back">\u2190 Back</div>
|
|
422
424
|
<div class="context-menu-section-title">Templates</div>
|
|
423
425
|
<input class="context-menu-search" type="text" placeholder="Search templates\u2026" value="${this.escapeHtml(this.templateQuery)}" />
|
|
@@ -455,7 +457,7 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
|
|
|
455
457
|
`).join("")}
|
|
456
458
|
</div>
|
|
457
459
|
<div class="context-menu-separator"></div>
|
|
458
|
-
`}groupTemplates(e){let t=new Map,i=(n,a)=>{var o;let
|
|
460
|
+
`}groupTemplates(e){let t=new Map,i=(n,a)=>{var o;let s=(o=t.get(n))!=null?o:[];s.push(a),t.set(n,s)};return e.forEach(n=>{let a=(n.id||"").toLowerCase();return a.startsWith("template.ui.")||a.startsWith("template.start.")||a.startsWith("template.endgame.")?i("UI Templates",n):a.startsWith("template.screen.")?i("Screen Templates",n):a.includes(".template")?i("Gameplay Templates",n):a.startsWith("effects.")||a.includes("effect")?i("Effects",n):i("Other",n)}),t}async promptName(e="new_object",t="Enter Object Name"){return new Promise(i=>{var d,p,u;let n=document.createElement("div");n.className="add-menu-modal-overlay",n.innerHTML=`
|
|
459
461
|
<div class="add-menu-modal">
|
|
460
462
|
<div class="add-menu-modal-header">
|
|
461
463
|
<div class="add-menu-modal-title">${this.escapeHtml(t)}</div>
|
|
@@ -471,7 +473,7 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
|
|
|
471
473
|
<button class="add-menu-modal-btn add-menu-modal-btn-primary" type="button" data-action="confirm">Confirm</button>
|
|
472
474
|
</div>
|
|
473
475
|
</div>
|
|
474
|
-
`;let a=()=>{n.parentNode&&n.parentNode.removeChild(n)},
|
|
476
|
+
`;let a=()=>{n.parentNode&&n.parentNode.removeChild(n)},s=()=>{let h=n.querySelector("#name-input").value.trim(),f=this.sanitizeInstanceId(h);if(!f){alert("Invalid name. Use letters, numbers, dots, dashes, or underscores.");return}a(),i(f)},o=()=>{a(),i(null)};n.querySelector(".add-menu-modal").addEventListener("click",g=>{g.stopPropagation()}),(d=n.querySelector('[data-action="confirm"]'))==null||d.addEventListener("click",s),(p=n.querySelector('[data-action="cancel"]'))==null||p.addEventListener("click",o),(u=n.querySelector(".add-menu-modal-close"))==null||u.addEventListener("click",o),n.addEventListener("click",g=>{g.target===n&&o()});let c=n.querySelector("#name-input");c.addEventListener("keydown",g=>{g.key==="Enter"?(g.preventDefault(),s()):g.key==="Escape"&&(g.preventDefault(),o())}),c.select(),document.body.appendChild(n),c.focus()})}async promptSpawnerConfig(){return new Promise(e=>{var m,b,y;let t=document.createElement("div");t.className="add-menu-modal-overlay";let i="template_id",n=`${i}_spawner_1`,a="",s=JSON.stringify([{x:-120,y:-120},{x:0,y:-120},{x:120,y:-120}],null,2),o=JSON.stringify({x:[-240,240],y:[-170,-170]},null,2),l="";t.innerHTML=`
|
|
475
477
|
<div class="add-menu-modal add-menu-modal-wide">
|
|
476
478
|
<div class="add-menu-modal-header">
|
|
477
479
|
<div class="add-menu-modal-title">
|
|
@@ -560,7 +562,7 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
|
|
|
560
562
|
|
|
561
563
|
<div class="add-menu-modal-row">
|
|
562
564
|
<label class="add-menu-modal-label">Spawn Points / Area (JSON)</label>
|
|
563
|
-
<textarea class="add-menu-modal-textarea" id="spawner-spawn-points" rows="3">${this.escapeHtml(
|
|
565
|
+
<textarea class="add-menu-modal-textarea" id="spawner-spawn-points" rows="3">${this.escapeHtml(s)}</textarea>
|
|
564
566
|
<div class="add-menu-modal-hint">Used when source is "Fixed Points" or "Random Area".</div>
|
|
565
567
|
</div>
|
|
566
568
|
</div>
|
|
@@ -601,10 +603,10 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
|
|
|
601
603
|
<button class="add-menu-modal-btn add-menu-modal-btn-primary" type="button" data-action="confirm">Create Spawner</button>
|
|
602
604
|
</div>
|
|
603
605
|
</div>
|
|
604
|
-
`;let c=()=>{t.parentNode&&t.parentNode.removeChild(t)},d=t.querySelectorAll(".add-menu-modal-tab"),p=t.querySelectorAll(".add-menu-modal-tab-content");d.forEach(v=>{v.addEventListener("click",()=>{var T;let w=v.dataset.tab;d.forEach(I=>I.classList.remove("active")),p.forEach(I=>I.classList.remove("active")),v.classList.add("active"),(T=t.querySelector(`[data-tab-content="${w}"]`))==null||T.classList.add("active")})});let u=v=>{let w=v.trim();if(!w)return null;try{return JSON.parse(w)}catch{return null}},g=()=>{var G;let v=t.querySelector("#spawner-instance-id").value.trim(),w=t.querySelector("#spawner-template-id").value.trim(),T=t.querySelector("#spawner-spawn-templates").value,I=t.querySelector("#spawner-position-source").value.trim(),M=t.querySelector("#spawner-point-mode").value.trim(),L=t.querySelector("#spawner-spawn-points").value,j=t.querySelector("#spawner-pattern").value.trim(),_=Number(t.querySelector("#spawner-rate").value.trim()),P=Number(t.querySelector("#spawner-pool").value.trim()),x=Number(t.querySelector("#spawner-lifetime").value.trim()),S=t.querySelector("#spawner-return-on-invisible").checked,A=t.querySelector("#spawner-movement").value.trim(),E=Number(t.querySelector("#spawner-vel-x").value.trim()),C=Number(t.querySelector("#spawner-vel-y").value.trim()),O=t.querySelector("#spawner-velocity-range").value,k=u(T),R=Array.isArray(k)&&k.length?k:null,z=typeof((G=R==null?void 0:R[0])==null?void 0:G.templateId)=="string"?String(R[0].templateId):w;if(!v){alert("Instance ID is required.");return}if(!z){alert("Template ID is required.");return}let D={templateId:z,spawnPattern:j,spawnRate:Number.isFinite(_)?_:650,poolSize:Number.isFinite(P)?P:18,returnOnInvisible:S,positionSource:I,spawnPointMode:M,movementMode:A,lifetime:Number.isFinite(x)?x:5e3};R&&(D.spawnTemplates=R);let U=u(L);Array.isArray(U)&&(D.spawnPoints=U),Number.isFinite(E)&&Number.isFinite(C)&&(D.velocity={x:E,y:C});let F=u(O);F&&typeof F=="object"&&(D.velocityRange=F),c(),e({templateId:z,instanceId:v,spawnerProps:D})},h=()=>{c(),e(null)};t.querySelector(".add-menu-modal").addEventListener("click",v=>v.stopPropagation()),(m=t.querySelector('[data-action="confirm"]'))==null||m.addEventListener("click",g),(b=t.querySelector('[data-action="cancel"]'))==null||b.addEventListener("click",h),(y=t.querySelector(".add-menu-modal-close"))==null||y.addEventListener("click",h),t.addEventListener("click",v=>{v.target===t&&h()}),document.body.appendChild(t),t.querySelector("#spawner-instance-id").focus()})}sanitizeInstanceId(e){let t=e.trim();return!t||!/^[a-zA-Z0-9._-]+$/.test(t)?null:t}buildDefaultConfig(e,t,i){let n=`json.${t}`,a={identity:{id:n,category:e==="ui-image"||e==="ui-text"?"ui":"environment"},transform:{position:{x:0,y:0},offset:{x:0,y:0},scale:e==="sprite"||e==="ui-image"?.2:1,rotation:0,anchor:"center",position_ratio:null,position_mode:"static"},render:{alpha:1,visible:!0,tint:null,z_index:0},instance_id:t,object_config:n};return(e==="sprite"||e==="ui-image")&&(a.render.asset={type:"image",path:`raw/${i}.png`}),e==="ui-text"&&(a.ui={kind:"text",renderMode:"text",text:i,font:"brand.primary",fontSize:18,letterSpacing:0,align:"center",color:"#FFFFFF"}),e==="graphics"&&(a.effects={width:200,height:200,fill_color:"#FFFFFF",fill_alpha:1}),a}async handleCreateObject(e,t){var l,c,d;this.close();let i=t!=null?t:await this.promptScreen();if(!i)return;let n=e==="ui-text"?"text_1":e==="graphics"?"graphics_1":"sprite_1",a=await this.promptName(n);if(!a)return;let
|
|
605
|
-
`))||(u==null?void 0:u.error)||"Failed to create object.";alert(h);return}let{trackObjectCreation:g}=await Promise.resolve().then(()=>(ee(),Ne));g(
|
|
606
|
-
`))||(d==null?void 0:d.error)||"Failed to create from template.";alert(p);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(l=(o=this.options).onRefresh)==null||l.call(o)}catch(c){alert(`Failed to create from template: ${c instanceof Error?c.message:String(c)}`)}}async handleCreateSystem(e,t){var n,a,
|
|
607
|
-
`))||(C==null?void 0:C.error)||"Failed to create collectable system.";alert(O);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(
|
|
606
|
+
`;let c=()=>{t.parentNode&&t.parentNode.removeChild(t)},d=t.querySelectorAll(".add-menu-modal-tab"),p=t.querySelectorAll(".add-menu-modal-tab-content");d.forEach(v=>{v.addEventListener("click",()=>{var T;let w=v.dataset.tab;d.forEach(I=>I.classList.remove("active")),p.forEach(I=>I.classList.remove("active")),v.classList.add("active"),(T=t.querySelector(`[data-tab-content="${w}"]`))==null||T.classList.add("active")})});let u=v=>{let w=v.trim();if(!w)return null;try{return JSON.parse(w)}catch{return null}},g=()=>{var G;let v=t.querySelector("#spawner-instance-id").value.trim(),w=t.querySelector("#spawner-template-id").value.trim(),T=t.querySelector("#spawner-spawn-templates").value,I=t.querySelector("#spawner-position-source").value.trim(),M=t.querySelector("#spawner-point-mode").value.trim(),L=t.querySelector("#spawner-spawn-points").value,j=t.querySelector("#spawner-pattern").value.trim(),_=Number(t.querySelector("#spawner-rate").value.trim()),P=Number(t.querySelector("#spawner-pool").value.trim()),x=Number(t.querySelector("#spawner-lifetime").value.trim()),S=t.querySelector("#spawner-return-on-invisible").checked,A=t.querySelector("#spawner-movement").value.trim(),E=Number(t.querySelector("#spawner-vel-x").value.trim()),C=Number(t.querySelector("#spawner-vel-y").value.trim()),O=t.querySelector("#spawner-velocity-range").value,k=u(T),R=Array.isArray(k)&&k.length?k:null,z=typeof((G=R==null?void 0:R[0])==null?void 0:G.templateId)=="string"?String(R[0].templateId):w;if(!v){alert("Instance ID is required.");return}if(!z){alert("Template ID is required.");return}let D={templateId:z,spawnPattern:j,spawnRate:Number.isFinite(_)?_:650,poolSize:Number.isFinite(P)?P:18,returnOnInvisible:S,positionSource:I,spawnPointMode:M,movementMode:A,lifetime:Number.isFinite(x)?x:5e3};R&&(D.spawnTemplates=R);let U=u(L);Array.isArray(U)&&(D.spawnPoints=U),Number.isFinite(E)&&Number.isFinite(C)&&(D.velocity={x:E,y:C});let F=u(O);F&&typeof F=="object"&&(D.velocityRange=F),c(),e({templateId:z,instanceId:v,spawnerProps:D})},h=()=>{c(),e(null)};t.querySelector(".add-menu-modal").addEventListener("click",v=>v.stopPropagation()),(m=t.querySelector('[data-action="confirm"]'))==null||m.addEventListener("click",g),(b=t.querySelector('[data-action="cancel"]'))==null||b.addEventListener("click",h),(y=t.querySelector(".add-menu-modal-close"))==null||y.addEventListener("click",h),t.addEventListener("click",v=>{v.target===t&&h()}),document.body.appendChild(t),t.querySelector("#spawner-instance-id").focus()})}sanitizeInstanceId(e){let t=e.trim();return!t||!/^[a-zA-Z0-9._-]+$/.test(t)?null:t}buildDefaultConfig(e,t,i){let n=`json.${t}`,a={identity:{id:n,category:e==="ui-image"||e==="ui-text"?"ui":"environment"},transform:{position:{x:0,y:0},offset:{x:0,y:0},scale:e==="sprite"||e==="ui-image"?.2:1,rotation:0,anchor:"center",position_ratio:null,position_mode:"static"},render:{alpha:1,visible:!0,tint:null,z_index:0},instance_id:t,object_config:n};return(e==="sprite"||e==="ui-image")&&(a.render.asset={type:"image",path:`raw/${i}.png`}),e==="ui-text"&&(a.ui={kind:"text",renderMode:"text",text:i,font:"brand.primary",fontSize:18,letterSpacing:0,align:"center",color:"#FFFFFF"}),e==="graphics"&&(a.effects={width:200,height:200,fill_color:"#FFFFFF",fill_alpha:1}),a}async handleCreateObject(e,t){var l,c,d;this.close();let i=t!=null?t:await this.promptScreen();if(!i)return;let n=e==="ui-text"?"text_1":e==="graphics"?"graphics_1":"sprite_1",a=await this.promptName(n);if(!a)return;let s=a,o=this.buildDefaultConfig(e,s,a);try{let p=await fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i,instanceId:s,objectConfigId:o.identity.id,layer:e==="ui-image"||e==="ui-text"?"ui":"world",config:o,forceSync:!0})}),u=await p.json().catch(()=>({}));if(!p.ok||(u==null?void 0:u.success)===!1){let h=((l=u==null?void 0:u.errors)==null?void 0:l.join(`
|
|
607
|
+
`))||(u==null?void 0:u.error)||"Failed to create object.";alert(h);return}let{trackObjectCreation:g}=await Promise.resolve().then(()=>(ee(),Ne));g(s,i,o),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),window.dispatchEvent(new CustomEvent("config:changed")),(d=(c=this.options).onRefresh)==null||d.call(c)}catch(p){alert(`Failed to create object: ${p instanceof Error?p.message:String(p)}`)}}async handleCreateFromTemplate(e,t){var s,o,l;this.close();let i=t!=null?t:await this.promptScreen();if(!i)return;let n=e.replace(/\.template$/,"").replace(/^json\./,"").replace(/[._]/g,"_")+"_1",a=await this.promptName(n);if(a)try{let c=await fetch("/api/objects/create-from-template",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({templateId:e,instanceId:a,screenId:i,forceSync:!0})}),d=await c.json().catch(()=>({}));if(!c.ok||(d==null?void 0:d.success)===!1){let p=((s=d==null?void 0:d.errors)==null?void 0:s.join(`
|
|
608
|
+
`))||(d==null?void 0:d.error)||"Failed to create from template.";alert(p);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(l=(o=this.options).onRefresh)==null||l.call(o)}catch(c){alert(`Failed to create from template: ${c instanceof Error?c.message:String(c)}`)}}async handleCreateSystem(e,t){var n,a,s,o,l,c,d,p,u,g,h,f,m,b,y,v,w,T,I,M,L,j,_,P,x,S,A;this.close();let i=t!=null?t:await this.promptScreen();if(i){if(e==="collectable-system")try{let E=await fetch("/api/systems/collectable-system",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i})}),C=await E.json().catch(()=>({}));if(!E.ok||(C==null?void 0:C.success)===!1){let O=((n=C==null?void 0:C.errors)==null?void 0:n.join(`
|
|
609
|
+
`))||(C==null?void 0:C.error)||"Failed to create collectable system.";alert(O);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(s=(a=this.options).onRefresh)==null||s.call(a)}catch(E){alert(`Failed to create collectable system: ${E instanceof Error?E.message:String(E)}`)}if(e==="drag-snap-couples")try{let E=await fetch("/api/systems/drag-snap-couples",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i})}),C=await E.json().catch(()=>({}));if(!E.ok||(C==null?void 0:C.success)===!1){let O=((o=C==null?void 0:C.errors)==null?void 0:o.join(`
|
|
608
610
|
`))||(C==null?void 0:C.error)||"Failed to create drag-snap system.";alert(O);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(c=(l=this.options).onRefresh)==null||c.call(l)}catch(E){alert(`Failed to create drag-snap system: ${E instanceof Error?E.message:String(E)}`)}if(e==="swerve-collect")try{let E=await fetch("/api/systems/swerve-collect",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i})}),C=await E.json().catch(()=>({}));if(!E.ok||(C==null?void 0:C.success)===!1){let O=((d=C==null?void 0:C.errors)==null?void 0:d.join(`
|
|
609
611
|
`))||(C==null?void 0:C.error)||"Failed to create swerve collect system.";alert(O);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(u=(p=this.options).onRefresh)==null||u.call(p)}catch(E){alert(`Failed to create swerve collect system: ${E instanceof Error?E.message:String(E)}`)}if(e==="tap-destroy")try{let E=await fetch("/api/systems/tap-destroy",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i})}),C=await E.json().catch(()=>({}));if(!E.ok||(C==null?void 0:C.success)===!1){let O=((g=C==null?void 0:C.errors)==null?void 0:g.join(`
|
|
610
612
|
`))||(C==null?void 0:C.error)||"Failed to create tap destroy system.";alert(O);return}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),(f=(h=this.options).onRefresh)==null||f.call(h)}catch(E){alert(`Failed to create tap destroy system: ${E instanceof Error?E.message:String(E)}`)}if(e==="scratch-card")try{let E=await fetch("/api/systems/scratch-card",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i})}),C=await E.json().catch(()=>({}));if(!E.ok||(C==null?void 0:C.success)===!1){let O=((m=C==null?void 0:C.errors)==null?void 0:m.join(`
|
|
@@ -647,13 +649,13 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
|
|
|
647
649
|
</div>
|
|
648
650
|
<div class="panel-resize-handle-v" data-panel-resize-v></div>
|
|
649
651
|
</div>
|
|
650
|
-
`}initialize(e,t){var a,
|
|
652
|
+
`}initialize(e,t){var a,s,o,l,c,d,p,u;this.options=t,this.root=e.querySelector('[data-panel="scene-objects"]'),this.listContainer=(a=this.root)==null?void 0:a.querySelector("[data-object-list]"),this.searchInput=(s=this.root)==null?void 0:s.querySelector("#scene-object-search"),(o=this.searchInput)==null||o.addEventListener("input",()=>this.refreshObjects()),this.loadCollapsedGroups(),(l=this.listContainer)==null||l.addEventListener("click",g=>{var w;let h=g.target,f=h==null?void 0:h.closest("[data-collapse-key]");if(f){let T=f.dataset.collapseKey||"";if(!T)return;let I=(w=this.listContainer)==null?void 0:w.querySelector(`[data-collapse-content="${T}"]`),M=this.isCollapsed(T);I&&(I.style.display=M?"":"none"),f.textContent=M?"\u25BE":"\u25B8",this.setCollapsed(T,!M),g.preventDefault(),g.stopPropagation();return}let m=h==null?void 0:h.closest("[data-object-visibility-toggle][data-object-id]");if(m){let T=m.dataset.objectId;if(!T)return;g.preventDefault(),g.stopPropagation(),this.toggleObjectVisibility(T);return}let b=h==null?void 0:h.closest("[data-system-bundle-action][data-system-bundle-id]");if(!b)return;g.preventDefault(),g.stopPropagation();let y=b.dataset.systemBundleAction,v=b.dataset.systemBundleId;if(!(!y||!v)){if(y==="toggle-visibility"){this.toggleSystemBundleVisibility(v);return}y==="delete"&&this.deleteSystemBundle(v)}});let i=(c=this.root)==null?void 0:c.querySelector("[data-add-object]");i==null||i.addEventListener("click",g=>{g.stopPropagation();let h=i.getBoundingClientRect();this.openAddObjectMenu({x:h.left,y:h.bottom+4})});let n=(d=this.root)==null?void 0:d.querySelector("#scene-screen-filter");if(n){try{let g=window.localStorage.getItem(this.getScreenFilterStorageKey());g&&(this.screenFilter=g)}catch{}n.value=this.screenFilter;try{window.__HANDLER_ACTIVE_SCREEN=this.screenFilter,window.dispatchEvent(new CustomEvent("handler:active-screen-changed",{detail:{screen:this.screenFilter}}))}catch{}try{let g=window.__HANDLER_REFRESH_SCREEN_INDEX;typeof g=="function"&&g().catch(()=>{})}catch{}n.addEventListener("change",()=>{let g=n.value||"all";this.screenFilter=g;try{window.localStorage.setItem(this.getScreenFilterStorageKey(),this.screenFilter)}catch{}try{window.__HANDLER_ACTIVE_SCREEN=this.screenFilter,window.dispatchEvent(new CustomEvent("handler:active-screen-changed",{detail:{screen:this.screenFilter}}))}catch{}try{let h=window.__HANDLER_REFRESH_SCREEN_INDEX;typeof h=="function"&&h().catch(()=>{})}catch{}this.refreshObjects()})}(p=this.root)==null||p.addEventListener("click",g=>{let h=g.target;if(!h||h.closest("[data-context-menu]"))return;if(h.tagName==="INPUT"&&h.classList.contains("scene-object-checkbox")){let w=h.dataset.objectId;if(!w)return;g.stopPropagation(),this.toggleBatchSelect(w);return}let f=h.closest(".scene-object-item[data-object-id]");if(!f)return;let m=f.dataset.objectId;if(!m)return;let b=g.ctrlKey||g.metaKey;g.shiftKey&&this.lastSelectedIndex>=0?this.selectRange(this.lastSelectedIndex,m):b?this.toggleBatchSelect(m):this.select(m)}),(u=this.listContainer)==null||u.addEventListener("contextmenu",g=>{var w;let h=g.target,f=h==null?void 0:h.closest("[data-object-id]");if(!f)return;let m=f.dataset.objectId;if(!m)return;g.preventDefault();let b=window.getEditableObjectConfig,y=typeof b=="function"?b(m):null;if(!y){let T=window.__editableObjectConfigs;T&&typeof T.get=="function"&&(y=(w=T.get(m))!=null?w:null)}let v=this.inferScreen(m,y);this.showContextMenu(m,v,g.clientX,g.clientY)}),window.addEventListener("handler:screen-index-loaded",()=>this.refreshObjects()),window.addEventListener("handler:scene-objects-refresh",()=>this.refreshObjects())}setSelected(e){e?(this.selectedIds.clear(),this.selectedIds.add(e),this.selectedId=e):(this.selectedIds.clear(),this.selectedId=null),this.updateSelectionUI()}getSelectedIds(){return Array.from(this.selectedIds)}updateSelectionUI(){var a,s,o,l,c;if(!this.listContainer)return;Array.from(this.listContainer.querySelectorAll("[data-object-id]")).forEach(d=>{let p=d.dataset.objectId,u=p?this.selectedIds.has(p):!1,g=p===this.selectedId;d.classList.toggle("selected",u),d.classList.toggle("active",g);let h=d.closest(".scene-object-item-wrapper"),f=h==null?void 0:h.querySelector(".scene-object-checkbox");f&&(f.checked=u)});let t=(a=this.root)==null?void 0:a.querySelector("[data-breadcrumbs]"),i=(s=this.root)==null?void 0:s.querySelector("[data-breadcrumb-screen]"),n=(o=this.root)==null?void 0:o.querySelector("[data-breadcrumb-object]");if(t&&i&&n){let d=this.selectedIds.size===1?this.selectedId:null;if(d){let p=window.getEditableObjectConfig,u=typeof p=="function"?p(d):null;if(!u){let b=window.__editableObjectConfigs;b&&typeof b.get=="function"&&(u=(l=b.get(d))!=null?l:null)}let g=this.inferScreen(d,u),h={loading:"Loading",start:"Start",gameplay:"Gameplay",tutorial:"Tutorial",endgame:"Endgame"},f=(((c=u==null?void 0:u.identity)==null?void 0:c.id)||d).toString(),m=this.formatDisplayName(f);i.textContent=h[g]||g,n.textContent=m,t.style.display="flex"}else t.style.display="none"}}refreshObjects(){var u;if(!this.listContainer)return;let e=window.getEditableObjectList,t=window.getEditableObjectListAll,i=window.refreshEditableConfigIndex;if(typeof i=="function"&&i(),typeof e!="function"&&typeof t!="function"){this.scheduleRetry();return}let n=typeof t=="function"?t():e();if(!Array.isArray(n)||n.length===0){let g=window.__editableObjectConfigs;g&&typeof g.keys=="function"&&(n=Array.from(g.keys()))}if(!Array.isArray(n)||n.length===0){this.scheduleRetry();return}let a=(((u=this.searchInput)==null?void 0:u.value)||"").trim().toLowerCase(),s=["loading","start","gameplay","tutorial","endgame"],o={loading:{templates:[],systems:[],objects:[],bundles:new Map},start:{templates:[],systems:[],objects:[],bundles:new Map},gameplay:{templates:[],systems:[],objects:[],bundles:new Map},tutorial:{templates:[],systems:[],objects:[],bundles:new Map},endgame:{templates:[],systems:[],objects:[],bundles:new Map}};this.systemBundles=new Map;let l=g=>{var m,b,y,v,w;let h=(v=(y=(b=(m=window.__editableConfig)==null?void 0:m.objects)==null?void 0:b.get)==null?void 0:y.call(b,g))!=null?v:null;if(h)return h;let f=window.__editableObjectConfigs;return f&&typeof f.get=="function"&&(w=f.get(g))!=null?w:null};n.forEach(g=>{var A,E,C,O,k,R,z;let h=l(g),f=(((A=h==null?void 0:h.identity)==null?void 0:A.category)||"scene").toString(),m=(((E=h==null?void 0:h.identity)==null?void 0:E.id)||g).toString(),b=f.toLowerCase(),y=m.toLowerCase(),v=b.includes("ui")||y.startsWith("ui")||y.includes("label"),w=b==="system",T=((C=h==null?void 0:h.identity)==null?void 0:C.is_template)===!0||y.includes(".template")||g.toLowerCase().includes(".template"),I=typeof((O=h==null?void 0:h.identity)==null?void 0:O.system_group)=="string"?h.identity.system_group:null,M=typeof((k=h==null?void 0:h.identity)==null?void 0:k.system_label)=="string"?h.identity.system_label:I?this.formatDisplayName(I):null,L=this.formatDisplayName(m||g),j=((R=h==null?void 0:h.render)==null?void 0:R.visible)===!1||(h==null?void 0:h.enabled)===!1,_=this.getObjectType(h),P={id:g,label:L,category:f,isUi:v,isTemplate:T,isUnused:j,objectType:_,systemGroupId:I,systemLabel:M},x=this.inferScreen(P.id,h);if(!(this.screenFilter!=="all"&&x!==this.screenFilter||!(!a||P.id.toLowerCase().includes(a)||P.label.toLowerCase().includes(a)))){if(I){let D=this.getSystemBundleKey(x,I),U=M!=null?M:I,F=o[x],G=F.bundles.get(D);G?(G.entries.push(P),G.objectIds.push(g)):F.bundles.set(D,{key:D,label:U,objectIds:[g],entries:[P]});let B=(z=this.systemBundles.get(D))!=null?z:{label:U,objectIds:[]};B.label=U,B.objectIds.push(g),this.systemBundles.set(D,B);return}if(T){o[x].templates.push(P);return}w?o[x].systems.push(P):o[x].objects.push(P)}});let c={loading:"Loading Screen",start:"Start Screen",gameplay:"Gameplay",tutorial:"Tutorial",endgame:"Endgame"},d=this.screenFilter==="all"?s:[this.screenFilter],p=d.map(g=>this.renderScreenGroup(g,c[g],o[g])).join("");this.listContainer.innerHTML=p,this.objectEntries=[];for(let g of d){let h=o[g];this.objectEntries.push(...h.templates),h.bundles.forEach(f=>this.objectEntries.push(...f.entries)),this.objectEntries.push(...h.systems),this.objectEntries.push(...h.objects)}for(let g of d){let h=o[g];if(!h.systems.length)continue;let f=this.listContainer.querySelector(`[data-delete-system-group="${g}"]`);f==null||f.addEventListener("click",m=>{m.stopPropagation(),this.deleteSystemGroup(h.systems)})}this.updateSelectionUI()}renderSystemBundle(e,t,i,n){let a=this.isBundleAllHidden(i),s=a?"Show all objects in this system":"Hide all objects in this system",o=a?"is-hidden":"",l=n.map(g=>this.renderEntryItem(g)).join(""),c=this.escapeHtml(e),d=this.getCollapseKey(`system:${e}`),p=this.isCollapsed(d);return`
|
|
651
653
|
<div class="scene-object-group scene-object-group-bundle" data-system-bundle="${c}">
|
|
652
654
|
<div class="scene-object-group-title">
|
|
653
655
|
<button class="scene-object-group-toggle" type="button" data-collapse-key="${d}">${p?"\u25B8":"\u25BE"}</button>
|
|
654
656
|
<span>${this.escapeHtml(t)} <span class="scene-object-count">${i.length}</span></span>
|
|
655
657
|
<div class="scene-object-group-actions">
|
|
656
|
-
<button class="scene-object-group-action scene-object-group-visibility ${o}" data-system-bundle-action="toggle-visibility" data-system-bundle-id="${c}" type="button" title="${
|
|
658
|
+
<button class="scene-object-group-action scene-object-group-visibility ${o}" data-system-bundle-action="toggle-visibility" data-system-bundle-id="${c}" type="button" title="${s}">\u{1F441}\uFE0F</button>
|
|
657
659
|
<button class="scene-object-group-delete" data-system-bundle-action="delete" data-system-bundle-id="${c}" type="button" title="Delete this system">\u{1F5D1}\uFE0F</button>
|
|
658
660
|
</div>
|
|
659
661
|
</div>
|
|
@@ -661,10 +663,10 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
|
|
|
661
663
|
${l}
|
|
662
664
|
</div>
|
|
663
665
|
</div>
|
|
664
|
-
`}renderEntryItem(e){var l,c,d;let t=window.getEditableObjectConfig,i=typeof t=="function"?t(e.id):null;if(!i){let p=window.__editableObjectConfigs;p&&typeof p.get=="function"&&(i=(l=p.get(e.id))!=null?l:null)}let n=(c=i==null?void 0:i.ui)!=null&&c.text?`"${i.ui.text.substring(0,12)}${i.ui.text.length>12?"...":""}"`:"",a=e.isTemplate?'<span class="scene-object-badge template">template</span>':"",
|
|
666
|
+
`}renderEntryItem(e){var l,c,d;let t=window.getEditableObjectConfig,i=typeof t=="function"?t(e.id):null;if(!i){let p=window.__editableObjectConfigs;p&&typeof p.get=="function"&&(i=(l=p.get(e.id))!=null?l:null)}let n=(c=i==null?void 0:i.ui)!=null&&c.text?`"${i.ui.text.substring(0,12)}${i.ui.text.length>12?"...":""}"`:"",a=e.isTemplate?'<span class="scene-object-badge template">template</span>':"",s=((d=i==null?void 0:i.render)==null?void 0:d.visible)===!1;return`
|
|
665
667
|
<div class="scene-object-item-wrapper">
|
|
666
668
|
<input type="checkbox" class="scene-object-checkbox" ${this.selectedIds.has(e.id)?"checked":""} data-object-id="${e.id}">
|
|
667
|
-
${this.renderVisibilityButton(e.id,
|
|
669
|
+
${this.renderVisibilityButton(e.id,s)}
|
|
668
670
|
<button class="scene-object-item ${e.isUnused?"unused":""}" data-object-id="${e.id}">
|
|
669
671
|
<span class="scene-object-label">${e.label}</span>
|
|
670
672
|
${n?`<span class="scene-object-text-preview">${n}</span>`:""}
|
|
@@ -672,7 +674,7 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
|
|
|
672
674
|
<span class="scene-object-badge ${e.isUi?"ui":"scene"}">${e.category}</span>
|
|
673
675
|
</button>
|
|
674
676
|
</div>
|
|
675
|
-
`}escapeHtml(e){return String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}toggleObjectVisibility(e){var a;let t=(a=window.__editableConfig)==null?void 0:a.objects;if(!t||typeof t.get!="function")return;let i=t.get(e);if(!i)return;i.render||(i.render={});let n=i.render.visible!==!1;i.render.visible=!n;try{window.dispatchEvent(new CustomEvent("config:changed",{detail:{objectId:e,action:"update"}}))}catch{}this.refreshObjects()}renderVisibilityButton(e,t){let i=t?"Show object":"Hide object";return`<button class="${t?"scene-object-eye is-hidden":"scene-object-eye"}" type="button" data-object-visibility-toggle="true" data-object-id="${this.escapeHtml(e)}" title="${i}">\u{1F441}\uFE0F</button>`}isBundleAllHidden(e){var i;if(!e.length)return!1;let t=(i=window.__editableConfig)==null?void 0:i.objects;return e.every(n=>{var
|
|
677
|
+
`}escapeHtml(e){return String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}toggleObjectVisibility(e){var a;let t=(a=window.__editableConfig)==null?void 0:a.objects;if(!t||typeof t.get!="function")return;let i=t.get(e);if(!i)return;i.render||(i.render={});let n=i.render.visible!==!1;i.render.visible=!n;try{window.dispatchEvent(new CustomEvent("config:changed",{detail:{objectId:e,action:"update"}}))}catch{}this.refreshObjects()}renderVisibilityButton(e,t){let i=t?"Show object":"Hide object";return`<button class="${t?"scene-object-eye is-hidden":"scene-object-eye"}" type="button" data-object-visibility-toggle="true" data-object-id="${this.escapeHtml(e)}" title="${i}">\u{1F441}\uFE0F</button>`}isBundleAllHidden(e){var i;if(!e.length)return!1;let t=(i=window.__editableConfig)==null?void 0:i.objects;return e.every(n=>{var s,o,l;let a=(o=(s=t==null?void 0:t.get)==null?void 0:s.call(t,n))!=null?o:null;return((l=a==null?void 0:a.render)==null?void 0:l.visible)===!1})}toggleSystemBundleVisibility(e){var o;let t=this.systemBundles.get(e);if(!t)return;let i=t.objectIds||[];if(!i.length)return;let n=(o=window.__editableConfig)==null?void 0:o.objects;if(!n||typeof n.get!="function")return;let s=this.isBundleAllHidden(i);i.forEach(l=>{let c=n.get(l);c&&(c.render||(c.render={}),c.render.visible=s)});try{window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"batch"}}))}catch{}this.refreshObjects()}async deleteSystemBundle(e){let t=this.systemBundles.get(e);if(!t)return;let i=t.label||e,n=Array.from(new Set(t.objectIds||[]));!n.length||!window.confirm(`Delete system "${i}" (${n.length} object${n.length!==1?"s":""})? This removes them from the screen configuration.`)||await this.deleteMultipleObjects(n)}formatDisplayName(e){let t=e.replace(/^json\./,"").replace(/^ui\./,"").replace(/_\d+$/,"").replace(/\./g," ").replace(/_/g," ");return t=t.split(" ").map(i=>i.charAt(0).toUpperCase()+i.slice(1).toLowerCase()).join(" "),t}inferScreen(e,t){var o,l;let i=window.__HANDLER_SCREEN_INDEX,n=(o=i==null?void 0:i.instanceToScreen)==null?void 0:o[e];if(n==="loading"||n==="start"||n==="gameplay"||n==="tutorial"||n==="endgame")return n;let a=(((l=t==null?void 0:t.identity)==null?void 0:l.id)||"").toString(),s=`${e} ${a}`.toLowerCase();return s.includes("loading")?"loading":s.includes("start")?"start":s.includes("tutorial")?"tutorial":s.includes("endgame")||s.includes("end_card")||s.includes("endcard")?"endgame":"gameplay"}getObjectType(e){var t,i,n,a,s,o,l,c,d,p;return e?(t=e.ui)!=null&&t.text?"text":(a=(n=(i=e.render)==null?void 0:i.asset)==null?void 0:n.path)!=null&&a.endsWith(".json")?"animation":((o=(s=e.render)==null?void 0:s.asset)==null?void 0:o.type)==="image"||(l=e.render)!=null&&l.texture?"sprite":(d=(c=e.gameplay)==null?void 0:c.tuning)!=null&&d.panel_width||(p=e.effects)!=null&&p.width?"graphics":"container":"container"}renderEntriesList(e){return e.length?e.map(t=>this.renderEntryItem(t)).join(""):""}renderCollapsibleGroup(e){var a;let t=this.isCollapsed(e.key),i=t?"\u25B8":"\u25BE",n=e.actionsHtml?`<div class="scene-object-group-actions">${e.actionsHtml}</div>`:"";return`
|
|
676
678
|
<div class="scene-object-group ${(a=e.className)!=null?a:""}">
|
|
677
679
|
<div class="scene-object-group-title">
|
|
678
680
|
<button class="scene-object-group-toggle" type="button" data-collapse-key="${e.key}">${i}</button>
|
|
@@ -683,17 +685,17 @@ OK = Share, Cancel = Snapshot`);try{let c=await fetch("/api/objects/duplicate",{
|
|
|
683
685
|
${e.content}
|
|
684
686
|
</div>
|
|
685
687
|
</div>
|
|
686
|
-
`}renderScreenGroup(e,t,i){let n=this.getCollapseKey(`screen:${e}`),a=[];if(i.templates.length){let o=this.getCollapseKey(`screen:${e}:templates`);a.push(this.renderCollapsibleGroup({key:o,title:"Templates",count:i.templates.length,content:this.renderEntriesList(i.templates),className:"scene-object-group-sub"}))}if(i.bundles.size||i.systems.length){let o=this.getCollapseKey(`screen:${e}:systems`),l=Array.from(i.bundles.values()).sort((p,u)=>p.label.localeCompare(u.label)).map(p=>this.renderSystemBundle(p.key,p.label,p.objectIds,p.entries)).join(""),c=i.systems.length?this.renderEntriesList(i.systems):"",d=i.systems.length?`<button class="scene-object-group-delete" data-delete-system-group="${e}" type="button" title="Delete all system objects">\u{1F5D1}\uFE0F</button>`:"";a.push(this.renderCollapsibleGroup({key:o,title:"Systems",count:i.bundles.size+i.systems.length,content:`${l}${c}`,className:"scene-object-group-system",actionsHtml:d}))}if(i.objects.length){let o=this.getCollapseKey(`screen:${e}:objects`);a.push(this.renderCollapsibleGroup({key:o,title:"Objects",count:i.objects.length,content:this.renderEntriesList(i.objects),className:"scene-object-group"}))}let
|
|
688
|
+
`}renderScreenGroup(e,t,i){let n=this.getCollapseKey(`screen:${e}`),a=[];if(i.templates.length){let o=this.getCollapseKey(`screen:${e}:templates`);a.push(this.renderCollapsibleGroup({key:o,title:"Templates",count:i.templates.length,content:this.renderEntriesList(i.templates),className:"scene-object-group-sub"}))}if(i.bundles.size||i.systems.length){let o=this.getCollapseKey(`screen:${e}:systems`),l=Array.from(i.bundles.values()).sort((p,u)=>p.label.localeCompare(u.label)).map(p=>this.renderSystemBundle(p.key,p.label,p.objectIds,p.entries)).join(""),c=i.systems.length?this.renderEntriesList(i.systems):"",d=i.systems.length?`<button class="scene-object-group-delete" data-delete-system-group="${e}" type="button" title="Delete all system objects">\u{1F5D1}\uFE0F</button>`:"";a.push(this.renderCollapsibleGroup({key:o,title:"Systems",count:i.bundles.size+i.systems.length,content:`${l}${c}`,className:"scene-object-group-system",actionsHtml:d}))}if(i.objects.length){let o=this.getCollapseKey(`screen:${e}:objects`);a.push(this.renderCollapsibleGroup({key:o,title:"Objects",count:i.objects.length,content:this.renderEntriesList(i.objects),className:"scene-object-group"}))}let s=a.join("");return s?this.renderCollapsibleGroup({key:n,title:t,count:i.templates.length+i.systems.length+i.objects.length+i.bundles.size,content:s,className:"scene-object-group-screen"}):""}scheduleRetry(){this.retryTimer||(this.retryTimer=window.setTimeout(()=>{this.retryTimer=null,this.refreshObjects()},400))}select(e){var t,i,n;this.selectedId=e,this.selectedIds.has(e)||this.selectedIds.add(e),this.updateLastSelectedIndex(e),this.updateSelectionUI(),(t=this.options)==null||t.onSelect(e),(n=(i=this.options)==null?void 0:i.onMultiSelect)==null||n.call(i,Array.from(this.selectedIds))}toggleBatchSelect(e){var t,i;this.selectedIds.has(e)?this.selectedIds.delete(e):this.selectedIds.add(e),this.updateSelectionUI(),(i=(t=this.options)==null?void 0:t.onMultiSelect)==null||i.call(t,Array.from(this.selectedIds))}toggleSelect(e){this.toggleBatchSelect(e)}selectRange(e,t){var s,o,l;let i=this.objectEntries.findIndex(c=>c.id===t);if(i===-1)return;let n=Math.min(e,i),a=Math.max(e,i);for(let c=n;c<=a;c++)c>=0&&c<this.objectEntries.length&&this.selectedIds.add(this.objectEntries[c].id);this.selectedId=t,this.updateLastSelectedIndex(t),this.updateSelectionUI(),(s=this.options)==null||s.onSelect(this.selectedId),(l=(o=this.options)==null?void 0:o.onMultiSelect)==null||l.call(o,Array.from(this.selectedIds))}updateLastSelectedIndex(e){this.lastSelectedIndex=this.objectEntries.findIndex(t=>t.id===e)}getDefaultScreenForCreate(){if(this.screenFilter!=="all")return this.screenFilter;let e=window.__HANDLER_ACTIVE_SCREEN;return e==="loading"||e==="start"||e==="gameplay"||e==="tutorial"||e==="endgame"?e:"gameplay"}async openAddObjectMenu(e){try{await new ji({onRefresh:()=>this.refreshObjects(),onClose:()=>{}}).open(e)}catch(t){console.warn("[SceneObjectsPanel] Failed to open AddObjectMenu:",t)}}async openAddObjectWizard(e){try{new Pi().open({screenId:e})}catch(t){console.warn("[SceneObjectsPanel] Failed to open AddObjectWizard:",t)}}async showContextMenu(e,t,i,n){if(!this.isContextMenuOpen){this.isContextMenuOpen=!0,this.selectedIds.has(e)||this.select(e);try{new gt({objectId:e,screenId:t,onSelect:s=>{s&&this.select(s)},onRefresh:()=>this.refreshObjects(),onClose:()=>{this.isContextMenuOpen=!1},onDeleteRequest:s=>this.deleteObject(s),onMoveRequest:(s,o)=>this.moveObject(s,o)}).open({x:i,y:n})}catch(a){this.isContextMenuOpen=!1,console.warn("[SceneObjectsPanel] Failed to open context menu:",a)}}}async deleteObject(e){var a;let t=this.getSelectedIds(),i=t.length>1&&t.includes(e),n=this.getActiveScreenForSync();if(i){if(!window.confirm(`Delete ${t.length} selected object${t.length!==1?"s":""}? This removes them from the screen configuration.`))return;await this.deleteMultipleObjects(t)}else{if(!window.confirm(`Delete "${e}"? This removes it from the screen configuration.`))return;try{let o=await fetch("/api/objects/delete",{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:e,screenId:n,forceSync:!0})}),l=await o.json().catch(()=>null);if(!o.ok||(l==null?void 0:l.success)===!1){let c=((a=l==null?void 0:l.errors)==null?void 0:a.join(`
|
|
687
689
|
`))||(l==null?void 0:l.error)||"Delete failed.";alert(c);return}l!=null&&l.failedDeletions&&l.failedDeletions.length>0&&alert(`Warning: Some files could not be deleted:
|
|
688
690
|
${l.failedDeletions.join(`
|
|
689
|
-
`)}`),l!=null&&l.deletedFiles&&l.deletedFiles.length>0&&console.log(`[SceneObjectsPanel] Successfully deleted files: ${l.deletedFiles.join(", ")}`),await this.syncScreens(),this.selectedIds.delete(e),this.selectedId===e&&(this.selectedId=null),this.refreshObjects()}catch(o){alert(`Delete failed: ${o instanceof Error?o.message:String(o)}`)}}}async deleteMultipleObjects(e){var
|
|
691
|
+
`)}`),l!=null&&l.deletedFiles&&l.deletedFiles.length>0&&console.log(`[SceneObjectsPanel] Successfully deleted files: ${l.deletedFiles.join(", ")}`),await this.syncScreens(),this.selectedIds.delete(e),this.selectedId===e&&(this.selectedId=null),this.refreshObjects()}catch(o){alert(`Delete failed: ${o instanceof Error?o.message:String(o)}`)}}}async deleteMultipleObjects(e){var s;let t=0,i=0,n=[],a=this.getActiveScreenForSync();for(let o of e)try{let l=await fetch("/api/objects/delete",{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:o,skipSync:!0,screenId:a,forceSync:!0})}),c=await l.json().catch(()=>null);if(l.ok&&(c==null?void 0:c.success)!==!1)t++,this.selectedIds.delete(o);else{i++;let d=((s=c==null?void 0:c.errors)==null?void 0:s.join(`
|
|
690
692
|
`))||(c==null?void 0:c.error)||"Delete failed.";n.push(`${o}: ${d}`)}}catch(l){i++,n.push(`${o}: ${l instanceof Error?l.message:String(l)}`)}if(i>0){let o=n.length>0?n.join(`
|
|
691
693
|
`):`${i} object(s) failed to delete.`;alert(`Deleted ${t} object(s). Errors:
|
|
692
|
-
${o}`)}t===e.length&&console.log(`[SceneObjectsPanel] Successfully deleted ${t} object(s)`),this.selectedId=this.selectedIds.size>0?Array.from(this.selectedIds)[0]:null,await this.syncScreens(),this.refreshObjects()}async deleteSystemGroup(e){var c;let t=e.length;if(!window.confirm(`Delete all ${t} system object${t!==1?"s":""}? This will remove them from all screens.`))return;let n=e.map(d=>d.id),a=0,
|
|
693
|
-
`))||(u==null?void 0:u.error)||"Delete failed.";o.push(`${d}: ${g}`)}}catch(p){
|
|
694
|
-
`):`${
|
|
695
|
-
${d}`)}await this.syncScreens(),this.refreshObjects()}async moveObject(e,t){var a;let i=this.getSelectedIds();if(i.length>1&&i.includes(e))await this.moveMultipleObjects(i,t);else{let
|
|
696
|
-
`))||(l==null?void 0:l.error)||"Move failed.";alert(c);return}this.refreshObjects()}catch(o){alert(`Move failed: ${o instanceof Error?o.message:String(o)}`)}}}async moveMultipleObjects(e,t){var
|
|
694
|
+
${o}`)}t===e.length&&console.log(`[SceneObjectsPanel] Successfully deleted ${t} object(s)`),this.selectedId=this.selectedIds.size>0?Array.from(this.selectedIds)[0]:null,await this.syncScreens(),this.refreshObjects()}async deleteSystemGroup(e){var c;let t=e.length;if(!window.confirm(`Delete all ${t} system object${t!==1?"s":""}? This will remove them from all screens.`))return;let n=e.map(d=>d.id),a=0,s=0,o=[],l=this.getActiveScreenForSync();for(let d of n)try{let p=await fetch("/api/objects/delete",{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:d,screenId:l,forceSync:!0})}),u=await p.json().catch(()=>null);if(p.ok&&(u==null?void 0:u.success)!==!1)a++;else{s++;let g=((c=u==null?void 0:u.errors)==null?void 0:c.join(`
|
|
695
|
+
`))||(u==null?void 0:u.error)||"Delete failed.";o.push(`${d}: ${g}`)}}catch(p){s++,o.push(`${d}: ${p instanceof Error?p.message:String(p)}`)}if(s>0){let d=o.length>0?o.join(`
|
|
696
|
+
`):`${s} object(s) failed to delete.`;alert(`Deleted ${a} object(s). Errors:
|
|
697
|
+
${d}`)}await this.syncScreens(),this.refreshObjects()}async moveObject(e,t){var a;let i=this.getSelectedIds();if(i.length>1&&i.includes(e))await this.moveMultipleObjects(i,t);else{let s=this.inferScreen(e,null);if(t===s)return;try{let o=await fetch("/api/objects/move",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:e,fromScreenId:s,toScreenId:t})}),l=await o.json().catch(()=>({}));if(!o.ok||(l==null?void 0:l.success)===!1){let c=((a=l==null?void 0:l.errors)==null?void 0:a.join(`
|
|
698
|
+
`))||(l==null?void 0:l.error)||"Move failed.";alert(c);return}this.refreshObjects()}catch(o){alert(`Move failed: ${o instanceof Error?o.message:String(o)}`)}}}async moveMultipleObjects(e,t){var s;let i=0,n=0,a=[];for(let o of e){let l=this.inferScreen(o,null);if(t===l){i++;continue}try{let c=await fetch("/api/objects/move",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({objectId:o,fromScreenId:l,toScreenId:t})}),d=await c.json().catch(()=>({}));if(c.ok&&(d==null?void 0:d.success)!==!1)i++;else{n++;let p=((s=d==null?void 0:d.errors)==null?void 0:s.join(`
|
|
697
699
|
`))||(d==null?void 0:d.error)||"Move failed.";a.push(`${o}: ${p}`)}}catch(c){n++,a.push(`${o}: ${c instanceof Error?c.message:String(c)}`)}}if(n>0){let o=a.length>0?a.join(`
|
|
698
700
|
`):`${n} object(s) failed to move.`;alert(`Moved ${i} object(s). Errors:
|
|
699
701
|
${o}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenForSync();await fetch("/api/sync-screens",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({force:!0,screenId:e})})}catch(e){console.warn("[SceneObjectsPanel] Failed to sync screens:",e)}}getActiveScreenForSync(){let e=window.__HANDLER_ACTIVE_SCREEN;return e==="loading"||e==="start"||e==="gameplay"||e==="tutorial"||e==="endgame"?e:this.screenFilter!=="all"?this.screenFilter:"gameplay"}};var Oi=class{constructor(){this.root=null;this.options=null;this.isCollapsed=!1}getSceneStorageKey(e){let t=typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default";return`handler_preview_scene_${e}::${t}`}render(){return`
|
|
@@ -779,7 +781,7 @@ ${o}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
|
|
|
779
781
|
</div>
|
|
780
782
|
</div>
|
|
781
783
|
</div>
|
|
782
|
-
`}initialize(e,t){if(this.options=t,this.root=e.querySelector('[data-panel="scene-tools-corner"]'),!this.root)return;let i=localStorage.getItem("scene-tools-collapsed");i!==null&&(this.isCollapsed=i==="true",this.root.classList.toggle("collapsed",this.isCollapsed));let n=this.root.querySelector("[data-tools-collapse]");n==null||n.addEventListener("click",()=>{var x;this.isCollapsed=!this.isCollapsed,(x=this.root)==null||x.classList.toggle("collapsed",this.isCollapsed),localStorage.setItem("scene-tools-collapsed",String(this.isCollapsed))});let a=(x,S)=>{var E;let A=(E=this.root)==null?void 0:E.querySelector(`[data-status="${x}"]`);A&&A.classList.toggle("active",S)},
|
|
784
|
+
`}initialize(e,t){if(this.options=t,this.root=e.querySelector('[data-panel="scene-tools-corner"]'),!this.root)return;let i=localStorage.getItem("scene-tools-collapsed");i!==null&&(this.isCollapsed=i==="true",this.root.classList.toggle("collapsed",this.isCollapsed));let n=this.root.querySelector("[data-tools-collapse]");n==null||n.addEventListener("click",()=>{var x;this.isCollapsed=!this.isCollapsed,(x=this.root)==null||x.classList.toggle("collapsed",this.isCollapsed),localStorage.setItem("scene-tools-collapsed",String(this.isCollapsed))});let a=(x,S)=>{var E;let A=(E=this.root)==null?void 0:E.querySelector(`[data-status="${x}"]`);A&&A.classList.toggle("active",S)},s=this.root.querySelector("#debug-highlight-object");s==null||s.addEventListener("change",()=>{var x;(x=this.options)==null||x.onHighlightObject(!!s.checked),a("bounds",s.checked)});let o=this.root.querySelector("#debug-highlight-anchor");o==null||o.addEventListener("change",()=>{var x;(x=this.options)==null||x.onHighlightAnchor(!!o.checked),a("anchor",o.checked),window.dispatchEvent(new CustomEvent("scene-editor:highlight-anchor",{detail:{enabled:o.checked}}));try{localStorage.setItem(this.getSceneStorageKey("highlight_anchor"),o.checked?"true":"false")}catch{}});let l=this.root.querySelector("#debug-nudge-enabled");l==null||l.addEventListener("change",()=>{a("nudge",l.checked)});let c=this.root.querySelector("#scene-grid-enabled"),d=this.root.querySelector("#scene-grid-gap"),p=this.root.querySelector("#scene-grid-alpha"),u=this.root.querySelector("#scene-grid-alpha-value"),g=this.root.querySelector("#scene-play-mode"),h=this.root.querySelector("#scene-background-cover"),f=this.root.querySelector("#scene-background-lock"),m=this.root.querySelector("[data-grid-toggle-btn]"),b=this.root.querySelector("[data-play-toggle-btn]"),y=()=>{if(!p)return .25;let x=Number(p.value),S=Number.isFinite(x)?Math.min(1,Math.max(0,x)):.25;return p.value=String(S),u&&(u.textContent=`${Math.round(S*100)}%`),S},v=(x,S,A)=>{var C,O;let E=A!==void 0?A:y();(O=(C=this.options)==null?void 0:C.onGridToggle)==null||O.call(C,x,S,E),window.dispatchEvent(new CustomEvent("scene-editor:grid",{detail:{enabled:x,gap:S,alpha:E}}))},w=x=>{var A,E;let S=y();(E=(A=this.options)==null?void 0:A.onGridGapChange)==null||E.call(A,x),window.dispatchEvent(new CustomEvent("scene-editor:grid",{detail:{enabled:!!(c!=null&&c.checked),gap:x,alpha:S}}))},T=x=>{var S,A;(A=(S=this.options)==null?void 0:S.onGridAlphaChange)==null||A.call(S,x),window.dispatchEvent(new CustomEvent("scene-editor:grid",{detail:{enabled:!!(c!=null&&c.checked),gap:j(),alpha:x}}))},I=x=>{var S,A;(A=(S=this.options)==null?void 0:S.onPlayModeChange)==null||A.call(S,x),window.dispatchEvent(new CustomEvent("scene-editor:play-mode",{detail:{enabled:x}}))},M=x=>{var S,A;(A=(S=this.options)==null?void 0:S.onBackgroundCoverChange)==null||A.call(S,x),window.dispatchEvent(new CustomEvent("scene-editor:background-cover",{detail:{enabled:x}}))},L=x=>{var S,A;(A=(S=this.options)==null?void 0:S.onBackgroundLockChange)==null||A.call(S,x),window.dispatchEvent(new CustomEvent("scene-editor:background-lock",{detail:{enabled:x}}))},j=()=>{if(!d)return 50;let x=Number(d.value),S=Number.isFinite(x)?Math.min(200,Math.max(4,x)):50;return d.value=String(S),S},_=x=>{c&&(c.checked=x),d&&(d.disabled=!x),p&&(p.disabled=!x),m==null||m.classList.toggle("active",x)},P=x=>{g&&(g.checked=x),b==null||b.classList.toggle("active",x)};try{let x=localStorage.getItem(this.getSceneStorageKey("grid_enabled")),S=localStorage.getItem(this.getSceneStorageKey("grid_gap")),A=localStorage.getItem(this.getSceneStorageKey("grid_alpha")),E=localStorage.getItem(this.getSceneStorageKey("highlight_anchor")),C=localStorage.getItem(this.getSceneStorageKey("background_cover")),O=localStorage.getItem(this.getSceneStorageKey("background_lock")),k=x?x==="true":!1;_(k),d&&(d.value=S||"50",d.disabled=!k),p&&(p.value=A||"0.25",p.disabled=!k,y()),o&&(o.checked=E==="true",a("anchor",o.checked));let R=!0;P(R),g&&(g.disabled=!0),b&&(b.disabled=!0);try{localStorage.setItem(this.getSceneStorageKey("play_mode"),R?"true":"false")}catch{}v(k,j(),y()),I(R);let z=C?C==="true":!0,D=O?O==="true":!0;h&&(h.checked=z),f&&(f.checked=D),M(z),L(D),o&&window.dispatchEvent(new CustomEvent("scene-editor:highlight-anchor",{detail:{enabled:o.checked}}))}catch{}c==null||c.addEventListener("change",()=>{let x=j(),S=y();d&&(d.disabled=!c.checked),p&&(p.disabled=!c.checked),m==null||m.classList.toggle("active",c.checked);try{localStorage.setItem(this.getSceneStorageKey("grid_enabled"),c.checked?"true":"false"),localStorage.setItem(this.getSceneStorageKey("grid_gap"),String(x)),localStorage.setItem(this.getSceneStorageKey("grid_alpha"),String(S))}catch{}v(c.checked,x,S)}),d==null||d.addEventListener("input",()=>{let x=j(),S=y();try{localStorage.setItem(this.getSceneStorageKey("grid_gap"),String(x)),localStorage.setItem(this.getSceneStorageKey("grid_alpha"),String(S))}catch{}w(x)}),p==null||p.addEventListener("input",()=>{let x=y(),S=j();try{localStorage.setItem(this.getSceneStorageKey("grid_alpha"),String(x)),localStorage.setItem(this.getSceneStorageKey("grid_gap"),String(S))}catch{}T(x)}),g==null||g.addEventListener("change",()=>{try{localStorage.setItem(this.getSceneStorageKey("play_mode"),g.checked?"true":"false")}catch{}b==null||b.classList.toggle("active",g.checked),I(g.checked)}),h==null||h.addEventListener("change",()=>{try{localStorage.setItem(this.getSceneStorageKey("background_cover"),h.checked?"true":"false")}catch{}M(h.checked)}),f==null||f.addEventListener("change",()=>{try{localStorage.setItem(this.getSceneStorageKey("background_lock"),f.checked?"true":"false")}catch{}L(f.checked)}),m==null||m.addEventListener("click",()=>{c&&(c.checked=!c.checked,c.dispatchEvent(new Event("change")))}),b==null||b.addEventListener("click",()=>{g&&(g.checked=!g.checked,g.dispatchEvent(new Event("change")))})}updateInfo(e){}};var Ri=class{constructor(){this.root=null;this.options=null}render(){return`
|
|
783
785
|
<div class="nudge-panel hidden" data-panel="nudge-panel">
|
|
784
786
|
<div class="nudge-panel-header" data-panel-handle>
|
|
785
787
|
<span class="nudge-panel-title">Nudge Controls</span>
|
|
@@ -836,7 +838,7 @@ ${o}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
|
|
|
836
838
|
</div>
|
|
837
839
|
</div>
|
|
838
840
|
</div>
|
|
839
|
-
`}initialize(e,t){if(this.options=t,this.root=e.querySelector('[data-panel="nudge-panel"]'),!this.root)return;Array.from(this.root.querySelectorAll(".nudge-arrow-btn")).forEach(a=>{a.addEventListener("click",()=>{var l,c,d,p;let
|
|
841
|
+
`}initialize(e,t){if(this.options=t,this.root=e.querySelector('[data-panel="nudge-panel"]'),!this.root)return;Array.from(this.root.querySelectorAll(".nudge-arrow-btn")).forEach(a=>{a.addEventListener("click",()=>{var l,c,d,p;let s=a.dataset.nudge,o=this.getNudgeStep();switch(s){case"up":(l=this.options)==null||l.onNudge(0,-o);break;case"down":(c=this.options)==null||c.onNudge(0,o);break;case"left":(d=this.options)==null||d.onNudge(-o,0);break;case"right":(p=this.options)==null||p.onNudge(o,0);break}})}),Array.from(this.root.querySelectorAll(".nudge-scale-btn")).forEach(a=>{a.addEventListener("click",()=>{var l;let o=a.dataset.scale==="up"?.1:-.1;(l=this.options)==null||l.onScale(o)})})}show(){var e;(e=this.root)==null||e.classList.remove("hidden")}hide(){var e;(e=this.root)==null||e.classList.add("hidden")}getNudgeStep(){var i,n;let e=(i=this.root)==null?void 0:i.querySelector("#nudge-step-input"),t=Number((n=e==null?void 0:e.value)!=null?n:10);return Number.isFinite(t)&&t>0?t:10}};var Bt=class{constructor(){this.root=null;this.slotsContainer=null;this.assetsContainer=null;this.assetSearchInput=null;this.slotSearchInput=null;this.options=null;this.registry=null;this.selectedSlotId=null;this.cachedAssets={};this.pendingAssetFetches={};this.cacheBust=0;this.missingPreviewPaths=new Set;this.slotSearchDebounce=null;this.assetSearchDebounce=null}mergeRegistries(e,t){let i=e||{},n=t||{},a={slots:Array.isArray(n.slots)?[...n.slots]:[],libraryAssets:typeof n.libraryAssets=="object"&&n.libraryAssets?{...n.libraryAssets}:{},categories:Array.isArray(n.categories)?[...n.categories]:[]},s=Array.isArray(i.slots)?i.slots:[];if(s.length>0&&a.slots.length>0)for(let c of a.slots){let d=s.find(p=>(p==null?void 0:p.slotId)&&p.slotId===(c==null?void 0:c.slotId));d!=null&&d.currentAsset&&d.currentAsset!==(c==null?void 0:c.currentAsset)&&(c.currentAsset=d.currentAsset)}let o=i.libraryAssets||{};for(let[c,d]of Object.entries(o)){if(!Array.isArray(d))continue;a.libraryAssets[c]||(a.libraryAssets[c]=[]);let p=new Set((a.libraryAssets[c]||[]).map(u=>u==null?void 0:u.filename));for(let u of d){let g=u==null?void 0:u.filename;!g||p.has(g)||(a.libraryAssets[c].unshift(u),p.add(g))}}let l=new Set(a.categories||[]);for(let c of i.categories||[])typeof c=="string"&&l.add(c);return a.categories=Array.from(l),a}render(){return`
|
|
840
842
|
<div class="scene-panel library-panel panel-accent-purple" data-panel="library">
|
|
841
843
|
<div class="scene-panel-header" data-panel-handle>
|
|
842
844
|
<div class="panel-title">
|
|
@@ -864,7 +866,7 @@ ${o}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
|
|
|
864
866
|
</div>
|
|
865
867
|
<div class="panel-resize-handle" data-panel-resize></div>
|
|
866
868
|
</div>
|
|
867
|
-
`}initialize(e,t){var a,r,o,l,c,d,p,u;this.options=t,this.root=e.querySelector('[data-panel="library"]'),this.slotsContainer=(a=this.root)==null?void 0:a.querySelector("[data-library-slots]"),this.assetsContainer=(r=this.root)==null?void 0:r.querySelector("[data-library-assets]"),this.assetSearchInput=(o=this.root)==null?void 0:o.querySelector("[data-library-asset-search]"),this.slotSearchInput=(l=this.root)==null?void 0:l.querySelector("[data-library-slot-search]");let i=(c=this.root)==null?void 0:c.querySelector("[data-create-ai]");i==null||i.addEventListener("click",()=>{this.handleCreateWithAI()});let n=(d=this.root)==null?void 0:d.querySelector("[data-refresh-library]");n==null||n.addEventListener("click",()=>{n.classList.add("pulse-anim"),this.refresh(),setTimeout(()=>n.classList.remove("pulse-anim"),500)}),(p=this.assetSearchInput)==null||p.addEventListener("input",()=>this.scheduleRenderAssets()),(u=this.slotSearchInput)==null||u.addEventListener("input",()=>this.scheduleRenderSlots()),window.addEventListener("preview:select",g=>{var f;let h=(f=g.detail)==null?void 0:f.objectId;h&&this.highlightCurrentObject(h)}),this.loadAssetRegistry()}highlightCurrentObject(e){if(!this.registry)return;let t=this.registry.slots.find(i=>i.objectId===e);t&&(this.selectedSlotId=t.slotId,this.scheduleRenderSlots(),setTimeout(()=>{var n;let i=(n=this.slotsContainer)==null?void 0:n.querySelector(`[data-slot-id="${t.slotId}"]`);i&&i.scrollIntoView({behavior:"smooth",block:"center"})},100))}reRender(){console.log("[LIBRARY] Re-rendering slots..."),this.loadAssetRegistry()}async refresh(){console.log("[LIBRARY] Force refreshing asset registry...");try{let e=window.getEditableAssets,t=typeof e=="function"?e():null,i=await fetch(`/raw/assetRegistry.json?t=${Date.now()}`);if(i.ok){let n=await i.json(),a=this.mergeRegistries(t,n);window.getEditableAssets=()=>a,console.log("[LIBRARY] \u2705 Registry re-fetched successfully")}}catch(e){console.warn("[LIBRARY] Failed to re-fetch registry:",e)}this.loadAssetRegistry()}resetSearch(){this.assetSearchInput&&(this.assetSearchInput.value=""),this.slotSearchInput&&(this.slotSearchInput.value=""),this.scheduleRenderAssets(),this.scheduleRenderSlots()}loadAssetRegistry(e=0){var i,n,a,r;let t=window.getEditableAssets;if(typeof t=="function"){let o=t();if(o!=null&&o.slots&&Array.isArray(o.slots)&&o.slots.length>0){if(this.registry=o,console.log("[LIBRARY] Loaded slot-based registry:",this.registry.slots.length,"slots"),this.cacheBust=Date.now(),this.cachedAssets={},this.pendingAssetFetches={},this.missingPreviewPaths.clear(),!(this.selectedSlotId&&this.registry.slots.some(c=>c.slotId===this.selectedSlotId))){let c=window.__getSelectedObjectId,d=typeof c=="function"?c():null;if(d){let p=this.registry.slots.find(u=>u.objectId===d);p?this.selectedSlotId=p.slotId:this.selectedSlotId=(n=(i=this.registry.slots[0])==null?void 0:i.slotId)!=null?n:null}else this.selectedSlotId=(r=(a=this.registry.slots[0])==null?void 0:a.slotId)!=null?r:null}this.renderSlots(),this.renderAssets();return}}e<15?(console.log(`[LIBRARY] Waiting for asset registry... (attempt ${e+1}/15)`),setTimeout(()=>this.loadAssetRegistry(e+1),200)):(console.warn("[LIBRARY] Failed to load asset registry"),this.slotsContainer&&(this.slotsContainer.innerHTML='<div class="library-info">No editable assets available</div>'))}renderSlots(){var n;if(!this.slotsContainer||!this.registry)return;let e={};for(let a of this.registry.slots)e[a.category]||(e[a.category]=[]),e[a.category].push(a);let t=this.cacheBust||Date.now(),i=(((n=this.slotSearchInput)==null?void 0:n.value)||"").trim().toLowerCase();this.slotsContainer.innerHTML="";for(let a of this.getCategories()){let r=(e[a]||[]).filter(d=>i?`${d.displayName} ${d.slotId} ${d.objectId} ${d.currentAsset}`.toLowerCase().includes(i):!0);if(r.length===0)continue;let o=document.createElement("div");o.className="library-category";let l=document.createElement("div");l.className="library-category-header",l.textContent=this.formatCategoryName(a),o.appendChild(l);let c=document.createElement("div");c.className="library-category-slots";for(let d of r){let p=this.createSlotElement(d,t);c.appendChild(p)}o.appendChild(c),this.slotsContainer.appendChild(o)}if(!this.slotsContainer.hasChildNodes()){let a=document.createElement("div");a.className="library-info",a.textContent=i?"No slots match your search":"No editable slots available",this.slotsContainer.appendChild(a)}}createSlotElement(e,t){var y,v;let i=this.selectedSlotId===e.slotId,n=window.__getSelectedObjectId,r=(typeof n=="function"?n():null)===e.objectId,o=document.createElement("div");o.className=`library-slot ${i?"expanded":""} ${r?"current-object":""}`,o.dataset.slotId=e.slotId,o.dataset.objectId=e.objectId;let l=document.createElement("div");l.className="slot-header";let c=document.createElement("div");if(c.className="slot-current",(y=e.currentAsset)==null?void 0:y.toLowerCase().endsWith(".json")){let w=document.createElement("div");w.className="slot-thumbnail slot-thumbnail-json",w.textContent="\u{1F3AC}",w.title="Lottie/JSON Animation",c.appendChild(w)}else{let w=document.createElement("img"),T=this.resolveSlotPreviewPaths(e),I=T.primary,M=(v=T.fallback)!=null?v:null;if(!I)w.style.display="none";else if(this.missingPreviewPaths.has(I.key)&&(!M||this.missingPreviewPaths.has(M.key)))w.style.display="none";else{w.src=I.src(t),w.alt=e.displayName,w.className="slot-thumbnail",w.loading="lazy";let L=!1;w.onerror=()=>{if(L){w.onerror=null,w.style.display="none";return}if(this.missingPreviewPaths.add(I.key),M&&!this.missingPreviewPaths.has(M.key)){L=!0,w.src=M.src(t);return}M&&this.missingPreviewPaths.add(M.key),w.style.display="none"}}c.appendChild(w)}l.appendChild(c);let p=document.createElement("div");p.className="slot-info";let u=document.createElement("div");u.className="slot-name",u.textContent=e.displayName;let g=document.createElement("div");g.className="slot-asset",g.textContent=e.currentAsset,p.appendChild(u),p.appendChild(g),l.appendChild(p);let h=document.createElement("div");h.className="slot-actions";let f=document.createElement("button");f.className="slot-ai-edit",f.title="Edit with AI",f.textContent="\u2728 AI",f.addEventListener("click",async w=>{w.stopPropagation(),await this.handleAIEdit(e)}),h.appendChild(f);let m=document.createElement("button");m.className="slot-upload",m.title="Upload new asset",m.textContent="\u{1F4E4}",m.addEventListener("click",async w=>{w.stopPropagation(),await this.handleUpload(e)}),h.appendChild(m);let b=document.createElement("button");return b.className="slot-reset",b.title="Reset to default",b.textContent="\u21BA",b.addEventListener("click",async w=>{w.stopPropagation(),await this.handleReset(e)}),h.appendChild(b),l.appendChild(h),l.addEventListener("click",()=>{this.selectedSlotId=e.slotId,this.renderSlots(),this.renderAssets()}),o.appendChild(l),o}renderAssets(){var l;if(!this.assetsContainer||!this.registry)return;let e=this.cacheBust||Date.now(),t=(((l=this.assetSearchInput)==null?void 0:l.value)||"").trim().toLowerCase(),i=this.getSelectedSlot();this.assetsContainer.innerHTML="";let n=document.createElement("div");n.className="library-selected",n.textContent=i?`Selected slot: ${i.displayName} (${i.currentAsset||"no asset"})`:"Select a slot to apply assets",n.style.gridColumn="1 / -1",this.assetsContainer.appendChild(n);let a=this.getCategories(),r=!1,o=!1;for(let c of a){let d=this.getCategoryAssets(c,e);if(!d){let f=document.createElement("div");f.className="library-empty",f.textContent=`Loading ${this.formatCategoryName(c)} assets...`,this.assetsContainer.appendChild(f),o=!0;continue}let p=d.filter(f=>t?`${f.displayName} ${f.filename} ${c}`.toLowerCase().includes(t):!0);if(p.length===0)continue;let u=document.createElement("div");u.className="library-category";let g=document.createElement("div");g.className="library-category-header",g.textContent=this.formatCategoryName(c),u.appendChild(g);let h=document.createElement("div");h.className="slot-library",h.style.borderTop="none",h.style.padding="10px";for(let f of p){let m=document.createElement("div");m.className="library-item",i&&i.currentAsset===f.filename&&i.libraryFolder===c&&m.classList.add("selected");let b=document.createElement("img"),y=this.resolveLibraryAssetPath(c,f.filename);this.missingPreviewPaths.has(y.key)?b.style.display="none":b.src=y.src(e),b.alt=f.displayName,b.className="library-thumbnail",b.loading="lazy",b.onerror=()=>{this.missingPreviewPaths.add(y.key),b.style.opacity="0.3"},m.appendChild(b);let v=document.createElement("div");v.className="library-label",v.textContent=f.displayName,m.appendChild(v),m.addEventListener("click",async()=>{if(!i){alert("Select a slot first to apply an asset.");return}await this.handleApply(i,f.filename,c)}),h.appendChild(m),r=!0}u.appendChild(h),this.assetsContainer.appendChild(u)}if(!r&&!o){let c=document.createElement("div");c.className="library-empty",c.textContent=t?"No assets match your search":"No assets available",this.assetsContainer.appendChild(c)}}getCategoryAssets(e,t){var i;if(this.cachedAssets[e])return this.cachedAssets[e];if(!this.pendingAssetFetches[e]){let n=((i=this.registry)==null?void 0:i.libraryAssets[e])||[];this.pendingAssetFetches[e]=this.fetchFolderAssets(e,t).then(a=>{let r=new Map;for(let o of n)r.set(o.filename,o);for(let o of a)r.has(o.filename)||r.set(o.filename,o);return this.cachedAssets[e]=Array.from(r.values()),delete this.pendingAssetFetches[e],this.renderAssets(),this.cachedAssets[e]}).catch(()=>(this.cachedAssets[e]=n,delete this.pendingAssetFetches[e],this.renderAssets(),this.cachedAssets[e]))}return null}async fetchFolderAssets(e,t){try{let i=await fetch(`/raw/library/${e}/?t=${t}`);if(!i.ok)return[];let n=await i.text(),a=[],r=/href="([^"]+\.(png|jpg|jpeg))"/gi,o;for(;(o=r.exec(n))!==null;){let l=o[1];if(!l.startsWith("/")&&!l.startsWith("..")){let c=l.replace(/\.(png|jpg|jpeg)$/i,"").replace(/_/g," ");a.push({filename:l,displayName:c})}}return a}catch{return console.log("[LIBRARY] Could not fetch folder listing, using registry only"),[]}}async handleApply(e,t,i){var n;console.log("[LIBRARY] Applying asset:",t,"to slot:",e.slotId);try{let a=window.__wizardAssetPicker;if(a!=null&&a.onPick){let l=`raw/library/${i||e.libraryFolder||e.category}/${t}`;a.onPick(l),window.__wizardAssetPicker=null;return}let r=i||e.libraryFolder||e.category;await((n=this.options)==null?void 0:n.onApply(e.objectId,t,r)),e.currentAsset=t,e.libraryFolder=r,this.renderSlots(),this.renderAssets()}catch(a){console.error("[LIBRARY] Failed to apply asset:",a)}}async handleReset(e){var t;console.log("[LIBRARY] Resetting slot:",e.slotId,"to default:",e.defaultAsset);try{await((t=this.options)==null?void 0:t.onReset(e.objectId,e.defaultAsset,e.category)),e.currentAsset=e.defaultAsset,this.renderSlots(),this.renderAssets()}catch(i){console.error("[LIBRARY] Failed to reset slot:",i)}}formatCategoryName(e){return e.replace(/_/g," ").split(" ").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}getCategories(){if(!this.registry)return[];let e=new Set;if(Array.isArray(this.registry.categories))for(let t of this.registry.categories)t&&e.add(t);for(let t of Object.keys(this.registry.libraryAssets||{}))t&&e.add(t);for(let t of this.registry.slots||[])t!=null&&t.category&&e.add(t.category);return Array.from(e)}getSelectedSlot(){return!this.registry||!this.selectedSlotId?null:this.registry.slots.find(e=>e.slotId===this.selectedSlotId)||null}scheduleRenderSlots(){this.slotSearchDebounce&&window.clearTimeout(this.slotSearchDebounce),this.slotSearchDebounce=window.setTimeout(()=>{this.slotSearchDebounce=null,this.renderSlots()},150)}scheduleRenderAssets(){this.assetSearchDebounce&&window.clearTimeout(this.assetSearchDebounce),this.assetSearchDebounce=window.setTimeout(()=>{this.assetSearchDebounce=null,this.renderAssets()},150)}resolveSlotPreviewPaths(e){let t=(e.currentAsset||"").trim();if(!t)return{primary:null,fallback:null};let i=t.replace(/^\/+/,""),n=null,a=null;return i.startsWith("raw/")?n=i:i.startsWith("library/")?n=`raw/${i}`:i.includes("/")?n=i:e.libraryFolder?(n=`raw/library/${e.libraryFolder}/${i}`,a=`raw/${i}`):n=`raw/${i}`,{primary:n?{key:n,src:l=>`/${n}?t=${l}`}:null,fallback:a?{key:a,src:l=>`/${a}?t=${l}`}:null}}resolveLibraryAssetPath(e,t){let i=t.replace(/^\/+/,""),n="";return i.startsWith("raw/")?n=i:i.startsWith("library/")?n=`raw/${i}`:i.includes("/")?n=i:n=`raw/library/${e}/${i}`,{key:n,src:a=>`/${n}?t=${a}`}}async handleAIEdit(e){console.log("[Library] Opening AI Edit for slot:",e);let t=window.__openAiEditor;if(typeof t=="function"){let i=e.slotId||e.objectId,n="render.texture";e.category==="ui"&&(n="ui.image"),e.category==="audio"&&(n="audio.src"),t(i,`Edit ${e.displayName} with AI`,e.currentAsset,{objectId:e.objectId,path:n})}else console.warn("[Library] AI Editor not available"),alert("AI Editor is not available. Please ensure the Settings panel is loaded.")}async handleUpload(e){console.log("[Library] Opening file upload for slot:",e);let t=document.createElement("input");t.type="file",t.accept="image/*",t.style.display="none",t.addEventListener("change",async()=>{var n;let i=(n=t.files)==null?void 0:n[0];if(i){console.log("[Library] File selected:",i.name);try{let a=await this.fileToDataUrl(i);if(!a){alert("Failed to read file");return}let o=`${e.displayName.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"")}_uploaded`,l=e.category;console.log("[Library] Saving uploaded file:",o,"to category:",l);let d=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:l,filename:`${o}.png`,data:a,overwrite:!0})})).json();if(d.success){console.log("[Library] \u2705 Upload saved:",d.path);let p=window.addAssetToRegistry;typeof p=="function"&&p(l,`${o}.png`);try{await fetch("/api/setup-library",{method:"POST",headers:{"Content-Type":"application/json"}})}catch(u){console.warn("[Library] Setup-library not available:",u)}await this.handleApply(e,`${o}.png`,e.category),e.currentAsset=`${o}.png`,await this.refresh(),setTimeout(()=>{this.highlightSlot(e.objectId,l)},500),console.log("[Library] \u2705 Upload complete and applied")}else console.error("[Library] \u274C Upload failed:",d.error),alert(`Upload failed: ${d.error}`)}catch(a){console.error("[Library] \u274C Upload error:",a),alert("Upload failed. Check console for details.")}finally{t.remove()}}}),document.body.appendChild(t),t.click()}fileToDataUrl(e){return new Promise(t=>{let i=new FileReader;i.onload=()=>t(i.result),i.onerror=()=>t(null),i.readAsDataURL(e)})}handleCreateWithAI(){console.log("[Library] Opening AI Create modal");let e=window.__openAiEditor;typeof e=="function"?e("new_asset","Create new asset with AI"):(console.warn("[Library] AI Editor not available"),alert("AI Editor is not available. Please ensure the Settings panel is loaded."))}highlightSlot(e,t){if(!this.registry||!this.slotsContainer)return;let i=e.startsWith("json.")?e.replace("json.",""):e,n=this.registry.slots.find(a=>(a.objectId===i||a.slotId===i)&&(!t||a.category===t));n?(console.log("[LIBRARY] Highlighting slot:",n.slotId),this.selectedSlotId=n.slotId,this.renderSlots(),this.renderAssets(),setTimeout(()=>{var r;let a=(r=this.slotsContainer)==null?void 0:r.querySelector(`[data-slot-id="${n.slotId}"]`);a&&(a.scrollIntoView({behavior:"smooth",block:"center"}),a.classList.add("highlight-pulse"),setTimeout(()=>a.classList.remove("highlight-pulse"),3e3))},100)):console.warn("[LIBRARY] No slot found for highlight:",e,t)}};var zi=class{detectType(e,t,i){let n=e.toLowerCase();return n==="logic_id"||n==="logicid"?"select":typeof t=="string"&&t.match(/\.(png|jpg|jpeg|gif|webp)$/i)?"image":n.includes("color")||n.includes("tint")?"color":typeof t=="boolean"?"boolean":typeof t=="number"?"number":Array.isArray(t)?"array":typeof t=="object"&&t!==null?"object":"text"}isHexColor(e){return/^#[0-9a-fA-F]{6}$/i.test(e)}isImagePath(e){return/\.(png|jpg|jpeg|gif|svg)$/i.test(e)}};var $i=class{render(e,t,i,n){let a=this.formatLabel(t),r=i?this.getThumbnailUrl(i):"";return`
|
|
869
|
+
`}initialize(e,t){var a,s,o,l,c,d,p,u;this.options=t,this.root=e.querySelector('[data-panel="library"]'),this.slotsContainer=(a=this.root)==null?void 0:a.querySelector("[data-library-slots]"),this.assetsContainer=(s=this.root)==null?void 0:s.querySelector("[data-library-assets]"),this.assetSearchInput=(o=this.root)==null?void 0:o.querySelector("[data-library-asset-search]"),this.slotSearchInput=(l=this.root)==null?void 0:l.querySelector("[data-library-slot-search]");let i=(c=this.root)==null?void 0:c.querySelector("[data-create-ai]");i==null||i.addEventListener("click",()=>{this.handleCreateWithAI()});let n=(d=this.root)==null?void 0:d.querySelector("[data-refresh-library]");n==null||n.addEventListener("click",()=>{n.classList.add("pulse-anim"),this.refresh(),setTimeout(()=>n.classList.remove("pulse-anim"),500)}),(p=this.assetSearchInput)==null||p.addEventListener("input",()=>this.scheduleRenderAssets()),(u=this.slotSearchInput)==null||u.addEventListener("input",()=>this.scheduleRenderSlots()),window.addEventListener("preview:select",g=>{var f;let h=(f=g.detail)==null?void 0:f.objectId;h&&this.highlightCurrentObject(h)}),this.loadAssetRegistry()}highlightCurrentObject(e){if(!this.registry)return;let t=this.registry.slots.find(i=>i.objectId===e);t&&(this.selectedSlotId=t.slotId,this.scheduleRenderSlots(),setTimeout(()=>{var n;let i=(n=this.slotsContainer)==null?void 0:n.querySelector(`[data-slot-id="${t.slotId}"]`);i&&i.scrollIntoView({behavior:"smooth",block:"center"})},100))}reRender(){console.log("[LIBRARY] Re-rendering slots..."),this.loadAssetRegistry()}async refresh(){console.log("[LIBRARY] Force refreshing asset registry...");try{let e=window.getEditableAssets,t=typeof e=="function"?e():null,i=await fetch(`/raw/assetRegistry.json?t=${Date.now()}`);if(i.ok){let n=await i.json(),a=this.mergeRegistries(t,n);window.getEditableAssets=()=>a,console.log("[LIBRARY] \u2705 Registry re-fetched successfully")}}catch(e){console.warn("[LIBRARY] Failed to re-fetch registry:",e)}this.loadAssetRegistry()}resetSearch(){this.assetSearchInput&&(this.assetSearchInput.value=""),this.slotSearchInput&&(this.slotSearchInput.value=""),this.scheduleRenderAssets(),this.scheduleRenderSlots()}loadAssetRegistry(e=0){var i,n,a,s;let t=window.getEditableAssets;if(typeof t=="function"){let o=t();if(o!=null&&o.slots&&Array.isArray(o.slots)&&o.slots.length>0){if(this.registry=o,console.log("[LIBRARY] Loaded slot-based registry:",this.registry.slots.length,"slots"),this.cacheBust=Date.now(),this.cachedAssets={},this.pendingAssetFetches={},this.missingPreviewPaths.clear(),!(this.selectedSlotId&&this.registry.slots.some(c=>c.slotId===this.selectedSlotId))){let c=window.__getSelectedObjectId,d=typeof c=="function"?c():null;if(d){let p=this.registry.slots.find(u=>u.objectId===d);p?this.selectedSlotId=p.slotId:this.selectedSlotId=(n=(i=this.registry.slots[0])==null?void 0:i.slotId)!=null?n:null}else this.selectedSlotId=(s=(a=this.registry.slots[0])==null?void 0:a.slotId)!=null?s:null}this.renderSlots(),this.renderAssets();return}}e<15?(console.log(`[LIBRARY] Waiting for asset registry... (attempt ${e+1}/15)`),setTimeout(()=>this.loadAssetRegistry(e+1),200)):(console.warn("[LIBRARY] Failed to load asset registry"),this.slotsContainer&&(this.slotsContainer.innerHTML='<div class="library-info">No editable assets available</div>'))}renderSlots(){var n;if(!this.slotsContainer||!this.registry)return;let e={};for(let a of this.registry.slots)e[a.category]||(e[a.category]=[]),e[a.category].push(a);let t=this.cacheBust||Date.now(),i=(((n=this.slotSearchInput)==null?void 0:n.value)||"").trim().toLowerCase();this.slotsContainer.innerHTML="";for(let a of this.getCategories()){let s=(e[a]||[]).filter(d=>i?`${d.displayName} ${d.slotId} ${d.objectId} ${d.currentAsset}`.toLowerCase().includes(i):!0);if(s.length===0)continue;let o=document.createElement("div");o.className="library-category";let l=document.createElement("div");l.className="library-category-header",l.textContent=this.formatCategoryName(a),o.appendChild(l);let c=document.createElement("div");c.className="library-category-slots";for(let d of s){let p=this.createSlotElement(d,t);c.appendChild(p)}o.appendChild(c),this.slotsContainer.appendChild(o)}if(!this.slotsContainer.hasChildNodes()){let a=document.createElement("div");a.className="library-info",a.textContent=i?"No slots match your search":"No editable slots available",this.slotsContainer.appendChild(a)}}createSlotElement(e,t){var y,v;let i=this.selectedSlotId===e.slotId,n=window.__getSelectedObjectId,s=(typeof n=="function"?n():null)===e.objectId,o=document.createElement("div");o.className=`library-slot ${i?"expanded":""} ${s?"current-object":""}`,o.dataset.slotId=e.slotId,o.dataset.objectId=e.objectId;let l=document.createElement("div");l.className="slot-header";let c=document.createElement("div");if(c.className="slot-current",(y=e.currentAsset)==null?void 0:y.toLowerCase().endsWith(".json")){let w=document.createElement("div");w.className="slot-thumbnail slot-thumbnail-json",w.textContent="\u{1F3AC}",w.title="Lottie/JSON Animation",c.appendChild(w)}else{let w=document.createElement("img"),T=this.resolveSlotPreviewPaths(e),I=T.primary,M=(v=T.fallback)!=null?v:null;if(!I)w.style.display="none";else if(this.missingPreviewPaths.has(I.key)&&(!M||this.missingPreviewPaths.has(M.key)))w.style.display="none";else{w.src=I.src(t),w.alt=e.displayName,w.className="slot-thumbnail",w.loading="lazy";let L=!1;w.onerror=()=>{if(L){w.onerror=null,w.style.display="none";return}if(this.missingPreviewPaths.add(I.key),M&&!this.missingPreviewPaths.has(M.key)){L=!0,w.src=M.src(t);return}M&&this.missingPreviewPaths.add(M.key),w.style.display="none"}}c.appendChild(w)}l.appendChild(c);let p=document.createElement("div");p.className="slot-info";let u=document.createElement("div");u.className="slot-name",u.textContent=e.displayName;let g=document.createElement("div");g.className="slot-asset",g.textContent=e.currentAsset,p.appendChild(u),p.appendChild(g),l.appendChild(p);let h=document.createElement("div");h.className="slot-actions";let f=document.createElement("button");f.className="slot-ai-edit",f.title="Edit with AI",f.textContent="\u2728 AI",f.addEventListener("click",async w=>{w.stopPropagation(),await this.handleAIEdit(e)}),h.appendChild(f);let m=document.createElement("button");m.className="slot-upload",m.title="Upload new asset",m.textContent="\u{1F4E4}",m.addEventListener("click",async w=>{w.stopPropagation(),await this.handleUpload(e)}),h.appendChild(m);let b=document.createElement("button");return b.className="slot-reset",b.title="Reset to default",b.textContent="\u21BA",b.addEventListener("click",async w=>{w.stopPropagation(),await this.handleReset(e)}),h.appendChild(b),l.appendChild(h),l.addEventListener("click",()=>{this.selectedSlotId=e.slotId,this.renderSlots(),this.renderAssets()}),o.appendChild(l),o}renderAssets(){var l;if(!this.assetsContainer||!this.registry)return;let e=this.cacheBust||Date.now(),t=(((l=this.assetSearchInput)==null?void 0:l.value)||"").trim().toLowerCase(),i=this.getSelectedSlot();this.assetsContainer.innerHTML="";let n=document.createElement("div");n.className="library-selected",n.textContent=i?`Selected slot: ${i.displayName} (${i.currentAsset||"no asset"})`:"Select a slot to apply assets",n.style.gridColumn="1 / -1",this.assetsContainer.appendChild(n);let a=this.getCategories(),s=!1,o=!1;for(let c of a){let d=this.getCategoryAssets(c,e);if(!d){let f=document.createElement("div");f.className="library-empty",f.textContent=`Loading ${this.formatCategoryName(c)} assets...`,this.assetsContainer.appendChild(f),o=!0;continue}let p=d.filter(f=>t?`${f.displayName} ${f.filename} ${c}`.toLowerCase().includes(t):!0);if(p.length===0)continue;let u=document.createElement("div");u.className="library-category";let g=document.createElement("div");g.className="library-category-header",g.textContent=this.formatCategoryName(c),u.appendChild(g);let h=document.createElement("div");h.className="slot-library",h.style.borderTop="none",h.style.padding="10px";for(let f of p){let m=document.createElement("div");m.className="library-item",i&&i.currentAsset===f.filename&&i.libraryFolder===c&&m.classList.add("selected");let b=document.createElement("img"),y=this.resolveLibraryAssetPath(c,f.filename);this.missingPreviewPaths.has(y.key)?b.style.display="none":b.src=y.src(e),b.alt=f.displayName,b.className="library-thumbnail",b.loading="lazy",b.onerror=()=>{this.missingPreviewPaths.add(y.key),b.style.opacity="0.3"},m.appendChild(b);let v=document.createElement("div");v.className="library-label",v.textContent=f.displayName,m.appendChild(v),m.addEventListener("click",async()=>{if(!i){alert("Select a slot first to apply an asset.");return}await this.handleApply(i,f.filename,c)}),h.appendChild(m),s=!0}u.appendChild(h),this.assetsContainer.appendChild(u)}if(!s&&!o){let c=document.createElement("div");c.className="library-empty",c.textContent=t?"No assets match your search":"No assets available",this.assetsContainer.appendChild(c)}}getCategoryAssets(e,t){var i;if(this.cachedAssets[e])return this.cachedAssets[e];if(!this.pendingAssetFetches[e]){let n=((i=this.registry)==null?void 0:i.libraryAssets[e])||[];this.pendingAssetFetches[e]=this.fetchFolderAssets(e,t).then(a=>{let s=new Map;for(let o of n)s.set(o.filename,o);for(let o of a)s.has(o.filename)||s.set(o.filename,o);return this.cachedAssets[e]=Array.from(s.values()),delete this.pendingAssetFetches[e],this.renderAssets(),this.cachedAssets[e]}).catch(()=>(this.cachedAssets[e]=n,delete this.pendingAssetFetches[e],this.renderAssets(),this.cachedAssets[e]))}return null}async fetchFolderAssets(e,t){try{let i=await fetch(`/raw/library/${e}/?t=${t}`);if(!i.ok)return[];let n=await i.text(),a=[],s=/href="([^"]+\.(png|jpg|jpeg))"/gi,o;for(;(o=s.exec(n))!==null;){let l=o[1];if(!l.startsWith("/")&&!l.startsWith("..")){let c=l.replace(/\.(png|jpg|jpeg)$/i,"").replace(/_/g," ");a.push({filename:l,displayName:c})}}return a}catch{return console.log("[LIBRARY] Could not fetch folder listing, using registry only"),[]}}async handleApply(e,t,i){var n;console.log("[LIBRARY] Applying asset:",t,"to slot:",e.slotId);try{let a=window.__wizardAssetPicker;if(a!=null&&a.onPick){let l=`raw/library/${i||e.libraryFolder||e.category}/${t}`;a.onPick(l),window.__wizardAssetPicker=null;return}let s=i||e.libraryFolder||e.category;await((n=this.options)==null?void 0:n.onApply(e.objectId,t,s)),e.currentAsset=t,e.libraryFolder=s,this.renderSlots(),this.renderAssets()}catch(a){console.error("[LIBRARY] Failed to apply asset:",a)}}async handleReset(e){var t;console.log("[LIBRARY] Resetting slot:",e.slotId,"to default:",e.defaultAsset);try{await((t=this.options)==null?void 0:t.onReset(e.objectId,e.defaultAsset,e.category)),e.currentAsset=e.defaultAsset,this.renderSlots(),this.renderAssets()}catch(i){console.error("[LIBRARY] Failed to reset slot:",i)}}formatCategoryName(e){return e.replace(/_/g," ").split(" ").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}getCategories(){if(!this.registry)return[];let e=new Set;if(Array.isArray(this.registry.categories))for(let t of this.registry.categories)t&&e.add(t);for(let t of Object.keys(this.registry.libraryAssets||{}))t&&e.add(t);for(let t of this.registry.slots||[])t!=null&&t.category&&e.add(t.category);return Array.from(e)}getSelectedSlot(){return!this.registry||!this.selectedSlotId?null:this.registry.slots.find(e=>e.slotId===this.selectedSlotId)||null}scheduleRenderSlots(){this.slotSearchDebounce&&window.clearTimeout(this.slotSearchDebounce),this.slotSearchDebounce=window.setTimeout(()=>{this.slotSearchDebounce=null,this.renderSlots()},150)}scheduleRenderAssets(){this.assetSearchDebounce&&window.clearTimeout(this.assetSearchDebounce),this.assetSearchDebounce=window.setTimeout(()=>{this.assetSearchDebounce=null,this.renderAssets()},150)}resolveSlotPreviewPaths(e){let t=(e.currentAsset||"").trim();if(!t)return{primary:null,fallback:null};let i=t.replace(/^\/+/,""),n=null,a=null;return i.startsWith("raw/")?n=i:i.startsWith("library/")?n=`raw/${i}`:i.includes("/")?n=i:e.libraryFolder?(n=`raw/library/${e.libraryFolder}/${i}`,a=`raw/${i}`):n=`raw/${i}`,{primary:n?{key:n,src:l=>`/${n}?t=${l}`}:null,fallback:a?{key:a,src:l=>`/${a}?t=${l}`}:null}}resolveLibraryAssetPath(e,t){let i=t.replace(/^\/+/,""),n="";return i.startsWith("raw/")?n=i:i.startsWith("library/")?n=`raw/${i}`:i.includes("/")?n=i:n=`raw/library/${e}/${i}`,{key:n,src:a=>`/${n}?t=${a}`}}async handleAIEdit(e){console.log("[Library] Opening AI Edit for slot:",e);let t=window.__openAiEditor;if(typeof t=="function"){let i=e.slotId||e.objectId,n="render.texture";e.category==="ui"&&(n="ui.image"),e.category==="audio"&&(n="audio.src"),t(i,`Edit ${e.displayName} with AI`,e.currentAsset,{objectId:e.objectId,path:n})}else console.warn("[Library] AI Editor not available"),alert("AI Editor is not available. Please ensure the Settings panel is loaded.")}async handleUpload(e){console.log("[Library] Opening file upload for slot:",e);let t=document.createElement("input");t.type="file",t.accept="image/*",t.style.display="none",t.addEventListener("change",async()=>{var n;let i=(n=t.files)==null?void 0:n[0];if(i){console.log("[Library] File selected:",i.name);try{let a=await this.fileToDataUrl(i);if(!a){alert("Failed to read file");return}let o=`${e.displayName.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"")}_uploaded`,l=e.category;console.log("[Library] Saving uploaded file:",o,"to category:",l);let d=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:l,filename:`${o}.png`,data:a,overwrite:!0})})).json();if(d.success){console.log("[Library] \u2705 Upload saved:",d.path);let p=window.addAssetToRegistry;typeof p=="function"&&p(l,`${o}.png`);try{await fetch("/api/setup-library",{method:"POST",headers:{"Content-Type":"application/json"}})}catch(u){console.warn("[Library] Setup-library not available:",u)}await this.handleApply(e,`${o}.png`,e.category),e.currentAsset=`${o}.png`,await this.refresh(),setTimeout(()=>{this.highlightSlot(e.objectId,l)},500),console.log("[Library] \u2705 Upload complete and applied")}else console.error("[Library] \u274C Upload failed:",d.error),alert(`Upload failed: ${d.error}`)}catch(a){console.error("[Library] \u274C Upload error:",a),alert("Upload failed. Check console for details.")}finally{t.remove()}}}),document.body.appendChild(t),t.click()}fileToDataUrl(e){return new Promise(t=>{let i=new FileReader;i.onload=()=>t(i.result),i.onerror=()=>t(null),i.readAsDataURL(e)})}handleCreateWithAI(){console.log("[Library] Opening AI Create modal");let e=window.__openAiEditor;typeof e=="function"?e("new_asset","Create new asset with AI"):(console.warn("[Library] AI Editor not available"),alert("AI Editor is not available. Please ensure the Settings panel is loaded."))}highlightSlot(e,t){if(!this.registry||!this.slotsContainer)return;let i=e.startsWith("json.")?e.replace("json.",""):e,n=this.registry.slots.find(a=>(a.objectId===i||a.slotId===i)&&(!t||a.category===t));n?(console.log("[LIBRARY] Highlighting slot:",n.slotId),this.selectedSlotId=n.slotId,this.renderSlots(),this.renderAssets(),setTimeout(()=>{var s;let a=(s=this.slotsContainer)==null?void 0:s.querySelector(`[data-slot-id="${n.slotId}"]`);a&&(a.scrollIntoView({behavior:"smooth",block:"center"}),a.classList.add("highlight-pulse"),setTimeout(()=>a.classList.remove("highlight-pulse"),3e3))},100)):console.warn("[LIBRARY] No slot found for highlight:",e,t)}};var zi=class{detectType(e,t,i){let n=e.toLowerCase();return n==="logic_id"||n==="logicid"?"select":typeof t=="string"&&t.match(/\.(png|jpg|jpeg|gif|webp)$/i)?"image":n.includes("color")||n.includes("tint")?"color":typeof t=="boolean"?"boolean":typeof t=="number"?"number":Array.isArray(t)?"array":typeof t=="object"&&t!==null?"object":"text"}isHexColor(e){return/^#[0-9a-fA-F]{6}$/i.test(e)}isImagePath(e){return/\.(png|jpg|jpeg|gif|svg)$/i.test(e)}};var $i=class{render(e,t,i,n){let a=this.formatLabel(t),s=i?this.getThumbnailUrl(i):"";return`
|
|
868
870
|
<div class="inspector-property" data-property-type="image">
|
|
869
871
|
<div class="inspector-property-header">
|
|
870
872
|
<label class="inspector-label">${a}</label>
|
|
@@ -875,9 +877,9 @@ ${o}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
|
|
|
875
877
|
<button class="debug-btn debug-btn-sm" data-action="reset" data-path="${n}" data-object="${e}" title="Reset">\u21BA</button>
|
|
876
878
|
</div>
|
|
877
879
|
</div>
|
|
878
|
-
${
|
|
880
|
+
${s?`
|
|
879
881
|
<div class="inspector-image-preview">
|
|
880
|
-
<img src="${
|
|
882
|
+
<img src="${s}" alt="${a}" class="inspector-thumbnail" />
|
|
881
883
|
</div>
|
|
882
884
|
`:`
|
|
883
885
|
<div class="inspector-image-preview inspector-image-empty">
|
|
@@ -934,7 +936,7 @@ ${o}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
|
|
|
934
936
|
<span>${this.formatLabel(t)}</span>
|
|
935
937
|
</label>
|
|
936
938
|
</div>
|
|
937
|
-
`}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Bi=class{constructor(e){this.registry=e}render(e,t,i,n){if(t==="logic"&&this.registry){let
|
|
939
|
+
`}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Bi=class{constructor(e){this.registry=e}render(e,t,i,n){if(t==="logic"&&this.registry){let s=this.registry,o=Array.isArray(i)?i:[],l=o.map((d,p)=>{let u=`${n}.${p}`,g=`
|
|
938
940
|
<button class="inspector-button inspector-button-small"
|
|
939
941
|
data-logic-remove="true"
|
|
940
942
|
data-object-id="${e}"
|
|
@@ -942,7 +944,7 @@ ${o}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
|
|
|
942
944
|
data-index="${p}">
|
|
943
945
|
Remove
|
|
944
946
|
</button>
|
|
945
|
-
`;if(d&&typeof d=="object"&&!Array.isArray(d)){let f=
|
|
947
|
+
`;if(d&&typeof d=="object"&&!Array.isArray(d)){let f=s.renderProperty(e,"logic",d,u);return`
|
|
946
948
|
<div class="inspector-array-item inspector-logic-item">
|
|
947
949
|
<div class="inspector-array-item-header">
|
|
948
950
|
<span>Logic ${p+1}</span>
|
|
@@ -991,7 +993,7 @@ ${o}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
|
|
|
991
993
|
<label class="inspector-property-label">${this.formatLabel(t)}</label>
|
|
992
994
|
<div class="inspector-array-empty">Empty array</div>
|
|
993
995
|
</div>
|
|
994
|
-
`;let a=i.map((
|
|
996
|
+
`;let a=i.map((s,o)=>typeof s=="string"?`<div class="inspector-array-item">\u2022 ${s}</div>`:typeof s=="object"?`<div class="inspector-array-item">\u2022 ${JSON.stringify(s)}</div>`:`<div class="inspector-array-item">\u2022 ${String(s)}</div>`).join("");return`
|
|
995
997
|
<div class="inspector-property inspector-property-array">
|
|
996
998
|
<label class="inspector-property-label">${this.formatLabel(t)} (${i.length} items)</label>
|
|
997
999
|
<div class="inspector-array-list">
|
|
@@ -1012,7 +1014,7 @@ ${o}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
|
|
|
1012
1014
|
${a.join("")}
|
|
1013
1015
|
</div>
|
|
1014
1016
|
</div>
|
|
1015
|
-
`}renderLogic(e,t,i,n){let a=[],
|
|
1017
|
+
`}renderLogic(e,t,i,n){let a=[],s=typeof(i==null?void 0:i.id)=="string"?i.id:"",o={zone:["bottom-left","bottom-center","bottom-right","top-left","top-center","top-right"],directionMode:["dominantAxis","free"],axis:["both","x","y"],ease:["power2.out","linear","sine.inOut","back.out(1.8)"],direction:["any","horizontal","vertical"],spawnPattern:["continuous","onClick","wave","burst"],positionSource:["spawner","target","custom","random","points"],spawnPointMode:["cycle","random"],movementMode:["none","velocity"],particleEffect:["","sparkle","gem","fire","heart","stars","smoke","magic","coin"],collectSound:["","click_4.wav","click_6.wav","success_4.wav"],hitEffect:["","sparkle","gem","fire","heart","stars","smoke","magic","coin"],destroyEffect:["","sparkle","gem","fire","heart","stars","smoke","magic","coin"],destroySound:["","click_4.wav","click_6.wav","success_4.wav"]},l=(()=>{let u=window,g=Array.isArray(u==null?void 0:u.__HANDLER_LOGIC_OPTIONS)?u.__HANDLER_LOGIC_OPTIONS:[],f=[...["DragToWin","SwerveMove","DragSnap","JoystickMove"],...g].map(m=>String(m)).filter(m=>m.trim().length>0);return Array.from(new Set(f)).sort((m,b)=>m.localeCompare(b))})(),c=s&&!l.includes(s)?[s,...l]:l;a.push(`
|
|
1016
1018
|
<div class="inspector-property inspector-property-text">
|
|
1017
1019
|
<label class="inspector-property-label">Id</label>
|
|
1018
1020
|
<div class="inspector-input-group">
|
|
@@ -1020,8 +1022,8 @@ ${o}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
|
|
|
1020
1022
|
data-property-path="${n}.id"
|
|
1021
1023
|
data-object-id="${e}"
|
|
1022
1024
|
data-logic-id-selector="true">
|
|
1023
|
-
<option value="" ${
|
|
1024
|
-
${c.map(u=>`<option value="${u}" ${u===
|
|
1025
|
+
<option value="" ${s?"":"selected"}>None</option>
|
|
1026
|
+
${c.map(u=>`<option value="${u}" ${u===s?"selected":""}>${u}</option>`).join("")}
|
|
1025
1027
|
</select>
|
|
1026
1028
|
</div>
|
|
1027
1029
|
</div>
|
|
@@ -1073,14 +1075,14 @@ ${o}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
|
|
|
1073
1075
|
${p}
|
|
1074
1076
|
</div>
|
|
1075
1077
|
</div>
|
|
1076
|
-
`}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Ui=class{render(e,t,i,n,a){let
|
|
1078
|
+
`}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Ui=class{render(e,t,i,n,a){let s=i==null?"":String(i),o=Array.from(new Set(a.map(c=>String(c)))),l=s&&!o.includes(s)?[s,...o]:o;return`
|
|
1077
1079
|
<div class="inspector-property inspector-property-text">
|
|
1078
1080
|
<label class="inspector-property-label">${this.formatLabel(t)}</label>
|
|
1079
1081
|
<div class="inspector-input-group">
|
|
1080
1082
|
<select class="inspector-component-select inspector-input"
|
|
1081
1083
|
data-property-path="${n}"
|
|
1082
1084
|
data-object-id="${e}">
|
|
1083
|
-
${l.map(c=>`<option value="${c}" ${c===
|
|
1085
|
+
${l.map(c=>`<option value="${c}" ${c===s?"selected":""}>${c}</option>`).join("")}
|
|
1084
1086
|
</select>
|
|
1085
1087
|
</div>
|
|
1086
1088
|
</div>
|
|
@@ -1095,7 +1097,7 @@ ${o}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
|
|
|
1095
1097
|
rows="6">${a}</textarea>
|
|
1096
1098
|
</div>
|
|
1097
1099
|
</div>
|
|
1098
|
-
`}safeStringify(e){try{return JSON.stringify(e!=null?e:[],null,2)}catch{return"[]"}}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Vi=class{render(e,t,i,n){let
|
|
1100
|
+
`}safeStringify(e){try{return JSON.stringify(e!=null?e:[],null,2)}catch{return"[]"}}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Vi=class{render(e,t,i,n){let s=(Array.isArray(i)?i:[]).map((o,l)=>{let c=typeof(o==null?void 0:o.x)=="number"?o.x:0,d=typeof(o==null?void 0:o.y)=="number"?o.y:0;return`
|
|
1099
1101
|
<div class="inspector-row" style="gap:8px; align-items:center;">
|
|
1100
1102
|
<input type="number"
|
|
1101
1103
|
class="inspector-input"
|
|
@@ -1118,7 +1120,7 @@ ${o}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
|
|
|
1118
1120
|
<div class="inspector-property inspector-property-object">
|
|
1119
1121
|
<div class="inspector-object-header">${this.formatLabel(t)}</div>
|
|
1120
1122
|
<div class="inspector-object-body">
|
|
1121
|
-
${
|
|
1123
|
+
${s||'<div class="inspector-text-sm" style="opacity:0.7;">No spawn points.</div>'}
|
|
1122
1124
|
<div class="inspector-row" style="margin-top:8px;">
|
|
1123
1125
|
<button type="button"
|
|
1124
1126
|
class="inspector-btn inspector-btn-sm primary"
|
|
@@ -1163,7 +1165,7 @@ ${o}`)}this.refreshObjects()}async syncScreens(){try{let e=this.getActiveScreenF
|
|
|
1163
1165
|
</div>
|
|
1164
1166
|
</div>
|
|
1165
1167
|
</div>
|
|
1166
|
-
`}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Wi=class{constructor(){this.typeDetector=new zi,this.imageRenderer=new $i,this.colorRenderer=new Di,this.numberRenderer=new Ni,this.textRenderer=new Hi,this.booleanRenderer=new Fi,this.arrayRenderer=new Bi(this),this.objectRenderer=new Gi(this),this.selectRenderer=new Ui,this.jsonRenderer=new qi,this.spawnPointsRenderer=new Vi,this.spawnTemplatesRenderer=new Yi(this)}getObjectIds(){try{let e=window,t=e==null?void 0:e.__editableConfig;if(!(t!=null&&t.objects))return[];let i=[];if(t.objects instanceof Map)for(let n of t.objects.keys())i.push(n);else typeof t.objects=="object"&&i.push(...Object.keys(t.objects));return i.sort()}catch{return[]}}getEnumOptionsFromSchemas(e){var t;try{let i=window,n=i==null?void 0:i.__editableConfig,a=n==null?void 0:n.schemas;if(!a)return null;let
|
|
1168
|
+
`}formatLabel(e){return e.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}};var Wi=class{constructor(){this.typeDetector=new zi,this.imageRenderer=new $i,this.colorRenderer=new Di,this.numberRenderer=new Ni,this.textRenderer=new Hi,this.booleanRenderer=new Fi,this.arrayRenderer=new Bi(this),this.objectRenderer=new Gi(this),this.selectRenderer=new Ui,this.jsonRenderer=new qi,this.spawnPointsRenderer=new Vi,this.spawnTemplatesRenderer=new Yi(this)}getObjectIds(){try{let e=window,t=e==null?void 0:e.__editableConfig;if(!(t!=null&&t.objects))return[];let i=[];if(t.objects instanceof Map)for(let n of t.objects.keys())i.push(n);else typeof t.objects=="object"&&i.push(...Object.keys(t.objects));return i.sort()}catch{return[]}}getEnumOptionsFromSchemas(e){var t;try{let i=window,n=i==null?void 0:i.__editableConfig,a=n==null?void 0:n.schemas;if(!a)return null;let s=String(e||"").split(".").filter(Boolean);if(s.length<2)return null;let o=s[0],l=s.slice(1).join("."),c=a instanceof Map?a.get(o):a==null?void 0:a[o];if(!c)return null;let d=(t=c==null?void 0:c.types)==null?void 0:t[l];if(typeof d!="string"||!d.startsWith("enum:"))return null;let u=d.slice(5).split("|").map(g=>g.trim()).filter(Boolean);return u.length?u:null}catch{return null}}getLogicOptions(){try{let e=window,t=Array.isArray(e==null?void 0:e.__HANDLER_LOGIC_OPTIONS)?e.__HANDLER_LOGIC_OPTIONS:[],n=[...["DragToWin","SwerveMove","DragSnap","JoystickMove"],...t].map(a=>String(a)).filter(a=>a.trim().length>0);return Array.from(new Set(n)).sort((a,s)=>a.localeCompare(s))}catch{return[]}}renderProperty(e,t,i,n){let a=t.toLowerCase(),s=a==="logic"||a==="logic_id"||a==="logicid",o=a==="id"&&n.toLowerCase().includes("logic");if((s||o)&&typeof i=="string"){let h=this.getLogicOptions(),f=this.selectRenderer.render(e,t,i,n,h);return s?`
|
|
1167
1169
|
${f}
|
|
1168
1170
|
<div class="inspector-array-actions">
|
|
1169
1171
|
<button class="inspector-button"
|
|
@@ -1173,7 +1175,7 @@ ${f}
|
|
|
1173
1175
|
Add Logic
|
|
1174
1176
|
</button>
|
|
1175
1177
|
</div>
|
|
1176
|
-
`:f}let l={zone:["bottom-left","bottom-center","bottom-right","top-left","top-center","top-right"],directionMode:["dominantAxis","free"],axis:["both","x","y"],ease:["power2.out","linear","sine.inOut","back.out(1.8)"],direction:["any","horizontal","vertical"],spawnPattern:["continuous","onClick","wave","burst"],positionSource:["spawner","target","custom","random","points"],spawnPointMode:["cycle","random"],movementMode:["none","velocity"],particleEffect:["","sparkle","gem","fire","heart","stars","smoke","magic","coin"],collectSound:["","click_4.wav","click_6.wav","success_4.wav"],hitEffect:["","sparkle","gem","fire","heart","stars","smoke","magic","coin"],destroyEffect:["","sparkle","gem","fire","heart","stars","smoke","magic","coin"],destroySound:["","click_4.wav","click_6.wav","success_4.wav"]},c={anchor:["center","top-left","top-center","top-right","left-center","right-center","bottom-left","bottom-center","bottom-right"]},d=l[t];if(d&&n.includes("logic.props"))return this.selectRenderer.render(e,t,i,n,d);let p=c[t];if(p&&(n.includes("transform")||n.includes("render"))){let h;if(typeof i=="string")h=i;else if(i==null)h="center";else{let m=Ke(i);h=p.find(y=>{let v=Ke(y);return Math.abs(v.x-m.x)<.001&&Math.abs(v.y-m.y)<.001})||"custom"}let f=[...p];return h==="custom"&&!f.includes("custom")&&f.push("custom"),this.selectRenderer.render(e,t,h,n,f)}if(t==="spawnPoints"&&n.includes("logic.props"))return this.spawnPointsRenderer.render(e,t,i,n);if(t==="spawnTemplates"&&n.includes("logic.props"))return this.spawnTemplatesRenderer.render(e,t,i,n);if((t==="targetId"||t==="inputId"||t==="hitTemplateId"||t==="hpLabelId"||t==="hitPopupTemplateId")&&(i==null||typeof i=="string")){let h=this.getObjectIds(),f=this.selectRenderer.render(e,t,i!=null?i:"",n,["",...h]);return t==="hitTemplateId"&&n.includes("logic.props")?f+'<div class="inspector-text-sm" style="opacity:0.7; margin-top:4px;">Use template id (e.g. bullet_template), not spawner.</div>':f}if(n.includes("motion.")){if(t==="enabled")return this.booleanRenderer.render(e,t,!!i,n);if(t==="direction"&&(n.includes("continuousMove")||n.includes("continuousRotate")||n.includes("orbit"))){let f=["1","-1"],m=i==null?"1":String(i);return this.selectRenderer.render(e,t,m,n,f)}if(["speed","amplitude","intensity","minScale","maxScale","radius","lifetime","pivotOffsetX","pivotOffsetY","duration","delay","startScale","startAlpha","startYOffset","startXOffset"].includes(t)){let f=typeof i=="number"&&!Number.isNaN(i)?i:0;return this.numberRenderer.render(e,t,f,n)}}let u=this.getEnumOptionsFromSchemas(n);if(u)return this.selectRenderer.render(e,t,i,n,u);switch(this.typeDetector.detectType(t,i)){case"image":return this.imageRenderer.render(e,t,i,n);case"color":return this.colorRenderer.render(e,t,i,n);case"number":return this.numberRenderer.render(e,t,i,n);case"boolean":return this.booleanRenderer.render(e,t,i,n);case"array":return this.arrayRenderer.render(e,t,i,n);case"object":return this.objectRenderer.render(e,t,i,n);case"select":return this.selectRenderer.render(e,t,i,n,[]);default:return this.textRenderer.render(e,t,i,n)}}getTypeDetector(){return this.typeDetector}};function sl(
|
|
1178
|
+
`:f}let l={zone:["bottom-left","bottom-center","bottom-right","top-left","top-center","top-right"],directionMode:["dominantAxis","free"],axis:["both","x","y"],ease:["power2.out","linear","sine.inOut","back.out(1.8)"],direction:["any","horizontal","vertical"],spawnPattern:["continuous","onClick","wave","burst"],positionSource:["spawner","target","custom","random","points"],spawnPointMode:["cycle","random"],movementMode:["none","velocity"],particleEffect:["","sparkle","gem","fire","heart","stars","smoke","magic","coin"],collectSound:["","click_4.wav","click_6.wav","success_4.wav"],hitEffect:["","sparkle","gem","fire","heart","stars","smoke","magic","coin"],destroyEffect:["","sparkle","gem","fire","heart","stars","smoke","magic","coin"],destroySound:["","click_4.wav","click_6.wav","success_4.wav"]},c={anchor:["center","top-left","top-center","top-right","left-center","right-center","bottom-left","bottom-center","bottom-right"]},d=l[t];if(d&&n.includes("logic.props"))return this.selectRenderer.render(e,t,i,n,d);let p=c[t];if(p&&(n.includes("transform")||n.includes("render"))){let h;if(typeof i=="string")h=i;else if(i==null)h="center";else{let m=Ke(i);h=p.find(y=>{let v=Ke(y);return Math.abs(v.x-m.x)<.001&&Math.abs(v.y-m.y)<.001})||"custom"}let f=[...p];return h==="custom"&&!f.includes("custom")&&f.push("custom"),this.selectRenderer.render(e,t,h,n,f)}if(t==="spawnPoints"&&n.includes("logic.props"))return this.spawnPointsRenderer.render(e,t,i,n);if(t==="spawnTemplates"&&n.includes("logic.props"))return this.spawnTemplatesRenderer.render(e,t,i,n);if((t==="targetId"||t==="inputId"||t==="hitTemplateId"||t==="hpLabelId"||t==="hitPopupTemplateId")&&(i==null||typeof i=="string")){let h=this.getObjectIds(),f=this.selectRenderer.render(e,t,i!=null?i:"",n,["",...h]);return t==="hitTemplateId"&&n.includes("logic.props")?f+'<div class="inspector-text-sm" style="opacity:0.7; margin-top:4px;">Use template id (e.g. bullet_template), not spawner.</div>':f}if(n.includes("motion.")){if(t==="enabled")return this.booleanRenderer.render(e,t,!!i,n);if(t==="direction"&&(n.includes("continuousMove")||n.includes("continuousRotate")||n.includes("orbit"))){let f=["1","-1"],m=i==null?"1":String(i);return this.selectRenderer.render(e,t,m,n,f)}if(["speed","amplitude","intensity","minScale","maxScale","radius","lifetime","pivotOffsetX","pivotOffsetY","duration","delay","startScale","startAlpha","startYOffset","startXOffset"].includes(t)){let f=typeof i=="number"&&!Number.isNaN(i)?i:0;return this.numberRenderer.render(e,t,f,n)}}let u=this.getEnumOptionsFromSchemas(n);if(u)return this.selectRenderer.render(e,t,i,n,u);switch(this.typeDetector.detectType(t,i)){case"image":return this.imageRenderer.render(e,t,i,n);case"color":return this.colorRenderer.render(e,t,i,n);case"number":return this.numberRenderer.render(e,t,i,n);case"boolean":return this.booleanRenderer.render(e,t,i,n);case"array":return this.arrayRenderer.render(e,t,i,n);case"object":return this.objectRenderer.render(e,t,i,n);case"select":return this.selectRenderer.render(e,t,i,n,[]);default:return this.textRenderer.render(e,t,i,n)}}getTypeDetector(){return this.typeDetector}};function sl(r,e){let t;return function(...n){let a=()=>{clearTimeout(t),r(...n)};clearTimeout(t),t=setTimeout(a,e)}}var Ki=class{constructor(){this.root=null;this.contentContainer=null;this.selectedObjectId=null;this.options=null;this.showAdvanced=!1;this.motionSimpleMode=!0;this.expandMotionOnNextRender=!1;this.rendererRegistry=new Wi,this.updateManager=new xe,this.quickActions=new Ii;try{let e=localStorage.getItem("inspector:motionSimple");e!==null&&(this.motionSimpleMode=e==="true")}catch{}window.addEventListener("inspector:refresh",()=>{this.selectedObjectId&&this.loadObject(this.selectedObjectId)}),window.addEventListener("config:changed",()=>{})}render(){return`
|
|
1177
1179
|
<div class="scene-panel inspector-panel panel-accent-violet" data-panel="inspector">
|
|
1178
1180
|
<div class="scene-panel-header" data-panel-handle>
|
|
1179
1181
|
<div class="panel-title">
|
|
@@ -1194,22 +1196,22 @@ ${f}
|
|
|
1194
1196
|
</div>
|
|
1195
1197
|
</div>
|
|
1196
1198
|
</div>
|
|
1197
|
-
`}initialize(e,t){var i;this.options=t,this.root=e.querySelector('[data-panel="inspector"]'),this.contentContainer=(i=this.root)==null?void 0:i.querySelector("[data-inspector-content]")}loadObject(e){this.selectedObjectId=e;let t=window.getEditableObjectConfig;if(typeof t!="function"){this.showError("Config system not ready");return}let i=t(e);if(!i){console.error("[InspectorPanel] Object not found in config system:",e),this.showError(`Object not found: ${e}`);return}this.renderProperties(e,i)}renderProperties(e,t){if(!this.contentContainer)return;let i=[],n=t.identity||{},a=n.id||e,
|
|
1199
|
+
`}initialize(e,t){var i;this.options=t,this.root=e.querySelector('[data-panel="inspector"]'),this.contentContainer=(i=this.root)==null?void 0:i.querySelector("[data-inspector-content]")}loadObject(e){this.selectedObjectId=e;let t=window.getEditableObjectConfig;if(typeof t!="function"){this.showError("Config system not ready");return}let i=t(e);if(!i){console.error("[InspectorPanel] Object not found in config system:",e),this.showError(`Object not found: ${e}`);return}this.renderProperties(e,i)}renderProperties(e,t){if(!this.contentContainer)return;let i=[],n=t.identity||{},a=n.id||e,s=n.category||"unknown";i.push(`
|
|
1198
1200
|
<div class="inspector-header">
|
|
1199
1201
|
<div class="inspector-header-info">
|
|
1200
1202
|
<div class="inspector-object-name">${a}</div>
|
|
1201
|
-
<div class="inspector-object-category">${
|
|
1203
|
+
<div class="inspector-object-category">${s}</div>
|
|
1202
1204
|
</div>
|
|
1203
1205
|
${this.renderConversionButtons(e,t)}
|
|
1204
1206
|
</div>
|
|
1205
|
-
`);let o=["transform","ui","render","gameplay","interaction","audio","effects","physics","motion","identity"];for(let l of o){let c=t[l];if(c){if(!this.showAdvanced&&!this.isSectionMeaningful(l,c,t))continue;i.push(this.renderSection(e,l,c,l))}}for(let l in t)if(!o.includes(l)&&typeof t[l]=="object"&&t[l]!==null){if(!this.showAdvanced&&!this.isSectionMeaningful(l,t[l],t))continue;i.push(this.renderSection(e,l,t[l],l))}this.contentContainer.innerHTML=i.join("")+this.renderFooter(t),this.attachEventListeners(),this.expandMotionOnNextRender=!1}renderConversionButtons(e,t){var o,l,c,d;let i=!!t.ui,n=((o=t.ui)==null?void 0:o.renderMode)==="png"||((c=(l=t.render)==null?void 0:l.asset)==null?void 0:c.type)==="image";if(!(i||e.includes("ui_endgame")||e.includes("splash")||e.includes("button")||e.includes("label"))||n)return"";let
|
|
1207
|
+
`);let o=["transform","ui","render","gameplay","interaction","audio","effects","physics","motion","identity"];for(let l of o){let c=t[l];if(c){if(!this.showAdvanced&&!this.isSectionMeaningful(l,c,t))continue;i.push(this.renderSection(e,l,c,l))}}for(let l in t)if(!o.includes(l)&&typeof t[l]=="object"&&t[l]!==null){if(!this.showAdvanced&&!this.isSectionMeaningful(l,t[l],t))continue;i.push(this.renderSection(e,l,t[l],l))}this.contentContainer.innerHTML=i.join("")+this.renderFooter(t),this.attachEventListeners(),this.expandMotionOnNextRender=!1}renderConversionButtons(e,t){var o,l,c,d;let i=!!t.ui,n=((o=t.ui)==null?void 0:o.renderMode)==="png"||((c=(l=t.render)==null?void 0:l.asset)==null?void 0:c.type)==="image";if(!(i||e.includes("ui_endgame")||e.includes("splash")||e.includes("button")||e.includes("label"))||n)return"";let s=(d=t.ui)!=null&&d.text?"ui.text":"render.asset.path";return`
|
|
1206
1208
|
<div class="inspector-quick-actions">
|
|
1207
1209
|
<button class="debug-btn debug-btn-sm success ai-simple-btn" type="button" data-convert-toggle>
|
|
1208
1210
|
\u2728 Convert to PNG
|
|
1209
1211
|
</button>
|
|
1210
1212
|
<div class="inspector-convert-menu hidden" data-convert-menu>
|
|
1211
1213
|
<button class="debug-btn debug-btn-sm" data-action="library" data-path="render.asset.path" data-object="${e}">\u{1F3A8} Library</button>
|
|
1212
|
-
<button class="debug-btn debug-btn-sm" data-action="ai-convert" data-path="${
|
|
1214
|
+
<button class="debug-btn debug-btn-sm" data-action="ai-convert" data-path="${s}" data-object="${e}">\u2728 AI</button>
|
|
1213
1215
|
<button class="debug-btn debug-btn-sm" data-action="upload" data-path="render.asset.path" data-object="${e}">\u{1F4E4} Upload</button>
|
|
1214
1216
|
</div>
|
|
1215
1217
|
</div>
|
|
@@ -1223,7 +1225,7 @@ ${f}
|
|
|
1223
1225
|
<button class="debug-btn debug-btn-sm primary" data-inspector-add-component-btn>Add</button>
|
|
1224
1226
|
</div>
|
|
1225
1227
|
</div>
|
|
1226
|
-
`}renderSection(e,t,i,n){if(t==="motion")return this.renderMotionSection(e,i,n);if(t==="logic")return this.renderLogicSection(e,i,n);let a=[],
|
|
1228
|
+
`}renderSection(e,t,i,n){if(t==="motion")return this.renderMotionSection(e,i,n);if(t==="logic")return this.renderLogicSection(e,i,n);let a=[],s=["kind","renderMode","position_ratio","position_mode","responsive","slot_id","asset_type"];for(let c in i){if(!this.showAdvanced&&s.includes(c))continue;let d=i[c],p=`${n}.${c}`,u=this.rendererRegistry.renderProperty(e,c,d,p);u&&a.push(u)}return a.length===0?"":`
|
|
1227
1229
|
<div class="inspector-section ${t==="transform"?"":"collapsed"}" data-section="${t}">
|
|
1228
1230
|
<div class="inspector-section-header" data-section-toggle="${t}">
|
|
1229
1231
|
<span class="inspector-section-arrow">\u25BC</span>
|
|
@@ -1245,7 +1247,7 @@ ${f}
|
|
|
1245
1247
|
${n}
|
|
1246
1248
|
</div>
|
|
1247
1249
|
</div>
|
|
1248
|
-
`:""}applyMotionDefaults(e,t){if(!t||typeof t!="object")return e!=null?e:{};let i={...e!=null?e:{}};for(let n of Object.keys(t)){let a=t[n],
|
|
1250
|
+
`:""}applyMotionDefaults(e,t){if(!t||typeof t!="object")return e!=null?e:{};let i={...e!=null?e:{}};for(let n of Object.keys(t)){let a=t[n],s=i[n];a!=null&&typeof a=="object"&&!Array.isArray(a)?i[n]=this.applyMotionDefaults(s,a):s===void 0&&(i[n]=a)}return i}renderMotionSection(e,t,i){var h;let n=[],a=this.getMotionDefaults(),s=this.applyMotionDefaults(t!=null?t:{},a!=null?a:{}),o=(h=s.intro)!=null?h:{},l=o.enabled===!0&&(typeof o.duration!="number"||o.duration<=0)?'<div class="inspector-warning">\u26A0\uFE0F Duration must be > 0 to play.</div>':"",c=`
|
|
1249
1251
|
<div class="inspector-motion-presets">
|
|
1250
1252
|
<span class="inspector-subsection-title">Intro Motions</span>
|
|
1251
1253
|
<div class="inspector-motion-buttons">
|
|
@@ -1262,7 +1264,7 @@ ${f}
|
|
|
1262
1264
|
<button class="debug-btn debug-btn-sm ${this.motionSimpleMode?"primary":""}" data-motion-simple-toggle>
|
|
1263
1265
|
${this.motionSimpleMode?"Simple":"Advanced"}
|
|
1264
1266
|
</button>
|
|
1265
|
-
`,p='<button class="debug-btn debug-btn-sm success" data-motion-preview>Preview Intro</button>',u=f=>{let m=f.split(".").filter(Boolean),b=
|
|
1267
|
+
`,p='<button class="debug-btn debug-btn-sm success" data-motion-preview>Preview Intro</button>',u=f=>{let m=f.split(".").filter(Boolean),b=s;for(let w of m)b=b==null?void 0:b[w];let y=m[m.length-1],v=`${i}.${f}`;return this.rendererRegistry.renderProperty(e,y,b,v)};if(this.motionSimpleMode){let f=u("enabled");f&&n.push(f);let m=[],b=u("intro.enabled"),y=u("intro.type"),v=u("intro.duration"),w=u("intro.easing");b&&m.push(b),y&&m.push(y),v&&m.push(v),w&&m.push(w),m.length&&n.push(`
|
|
1266
1268
|
<div class="inspector-subsection">
|
|
1267
1269
|
<div class="inspector-subsection-title">Intro</div>
|
|
1268
1270
|
<div class="inspector-subsection-content">
|
|
@@ -1282,7 +1284,7 @@ ${f}
|
|
|
1282
1284
|
${x}
|
|
1283
1285
|
</div>
|
|
1284
1286
|
</div>
|
|
1285
|
-
`)}}else for(let f in
|
|
1287
|
+
`)}}else for(let f in s){let m=s[f],b=`${i}.${f}`,y=this.rendererRegistry.renderProperty(e,f,m,b);y&&n.push(y)}return n.length===0?"":`
|
|
1286
1288
|
<div class="inspector-section ${this.expandMotionOnNextRender?"":"collapsed"}" data-section="motion">
|
|
1287
1289
|
<div class="inspector-section-header" data-section-toggle="motion">
|
|
1288
1290
|
<span class="inspector-section-arrow">\u25BC</span>
|
|
@@ -1295,7 +1297,7 @@ ${f}
|
|
|
1295
1297
|
${n.join("")}
|
|
1296
1298
|
</div>
|
|
1297
1299
|
</div>
|
|
1298
|
-
`}attachEventListeners(){var w,T,I,M;if(!this.contentContainer)return;let e=this.contentContainer.querySelectorAll("[data-property-path]"),t=sl((L,j,_)=>{var P,x;this.updateManager.updateProperty(L,j,_),(x=(P=this.options)==null?void 0:P.onPropertyChange)==null||x.call(P,L,j,_)},300),i=L=>L?/(^|\.)logic(\.\d+)?\.id$/.test(L):!1;e.forEach(L=>{let j=x=>{var C,O;let S=x.target,A=S.dataset.propertyPath,E=S.dataset.objectId;if(A&&E){let k=S.value;if(S.type==="checkbox")k=S.checked;else if(S.type==="number"){if(k=parseFloat(S.value),isNaN(k))return}else if(S.dataset.json==="true")try{k=JSON.parse(S.value)}catch{return}S.type==="text"||S.type==="range"||S.tagName==="TEXTAREA"?t(E,A,k):(this.updateManager.updateProperty(E,A,k),(O=(C=this.options)==null?void 0:C.onPropertyChange)==null||O.call(C,E,A,k))}},_=L.dataset.propertyPath;_&&(_.includes("transform.anchor")||_.includes("render.anchor"))&&L.tagName==="SELECT"?L.addEventListener("change",async x=>{var O,k,R,z,D;let S=x.target,A=S.dataset.propertyPath,E=S.dataset.objectId,C=S.value;if(!(!A||!E)&&C!=="custom")if(A.includes("transform.anchor")){let U=window.getEditableObjectConfig,F=typeof U=="function"?U(E):null,G=(O=F==null?void 0:F.transform)==null?void 0:O.anchor,B=G!=null&&G!==""?G:"top-left",q=C;await this.updateManager.updateProperty(E,A,C),(R=(k=this.options)==null?void 0:k.onPropertyChange)==null||R.call(k,E,A,C),B!==q&&window.dispatchEvent(new CustomEvent("scene-editor:anchor-changed",{detail:{objectId:E,previousAnchor:B,nextAnchor:q}}))}else await this.updateManager.updateProperty(E,A,C),(D=(z=this.options)==null?void 0:z.onPropertyChange)==null||D.call(z,E,A,C)}):i(_)?(console.log("[Inspector v1.0.0] PATH-BASED DETECTION ACTIVE - logic ID found at:",_),L.addEventListener("change",async x=>{var D;let S=x.target,A=S.dataset.propertyPath,E=S.dataset.objectId,C=S.value;if(console.log("[Inspector v1.0.0] Logic ID changed to:",C),!A||!E)return;await this.updateManager.updateProperty(E,A,C),console.log("[Inspector v1.0.0] Logic ID updated");let O=window,k=(D=O==null?void 0:O.__HANDLER_LOGIC_META)==null?void 0:D[C],R=this.getDefaultPropsForLogic(C,k);console.log("[Inspector v1.0.0] New logic default props:",R);let z=A.replace(/\.id$/,".props");await this.updateManager.updateProperty(E,z,R),console.log("[Inspector v1.0.0] Logic props updated to:",R),console.log("[Inspector v1.0.0] Reloading inspector with updated config"),this.loadObject(E)})):(L.addEventListener("change",j),(L.tagName==="INPUT"||L.tagName==="TEXTAREA")&&L.addEventListener("input",j))}),this.contentContainer.querySelectorAll("[data-action]").forEach(L=>{L.addEventListener("click",j=>{let _=j.target,P=_.dataset.action,x=_.dataset.path,S=_.dataset.object;P&&x&&S&&this.quickActions.handleAction(P,S,x)})}),this.contentContainer.querySelectorAll("[data-section-toggle]").forEach(L=>{L.addEventListener("click",j=>{var x,S;let _=j.target,P=_.dataset.sectionToggle||((x=_.closest("[data-section-toggle]"))==null?void 0:x.getAttribute("data-section-toggle"));if(P){let A=(S=this.contentContainer)==null?void 0:S.querySelector(`[data-section="${P}"]`);A==null||A.classList.toggle("collapsed")}})}),this.contentContainer.querySelectorAll("[data-motion-preset]").forEach(L=>{L.addEventListener("click",async j=>{let P=j.currentTarget.dataset.motionPreset;!P||!this.selectedObjectId||await this.applyMotionPreset(this.selectedObjectId,P)})}),this.contentContainer.querySelectorAll("[data-motion-preview]").forEach(L=>{L.addEventListener("click",async()=>{this.selectedObjectId&&await this.previewMotionIntro(this.selectedObjectId)})});let l=this.contentContainer.querySelector("[data-motion-simple-toggle]");l==null||l.addEventListener("click",()=>{this.motionSimpleMode=!this.motionSimpleMode;try{localStorage.setItem("inspector:motionSimple",String(this.motionSimpleMode))}catch{}this.selectedObjectId&&this.loadObject(this.selectedObjectId)}),this.contentContainer.querySelectorAll("[data-spawnpoints-add]").forEach(L=>{L.addEventListener("click",async j=>{let _=j.target,P=_.dataset.objectId,x=_.dataset.propertyPath;if(!P||!x)return;let S=window.getEditableObjectConfig,A=S==null?void 0:S(P);if(!A)return;let E=this.updateManager.getNestedProperty(A,x),C=Array.isArray(E)?[...E]:[];C.push({x:0,y:0}),await this.updateManager.updateProperty(P,x,C),this.loadObject(P)})}),this.contentContainer.querySelectorAll("[data-spawnpoints-remove]").forEach(L=>{L.addEventListener("click",async j=>{let _=j.target,P=_.dataset.objectId,x=_.dataset.propertyPath,S=Number(_.dataset.index||"-1");if(!P||!x||S<0)return;let A=window.getEditableObjectConfig,E=A==null?void 0:A(P);if(!E)return;let C=this.updateManager.getNestedProperty(E,x);if(!Array.isArray(C))return;let O=C.filter((k,R)=>R!==S);await this.updateManager.updateProperty(P,x,O),this.loadObject(P)})}),this.contentContainer.querySelectorAll("[data-spawntemplates-add]").forEach(L=>{L.addEventListener("click",async j=>{let _=j.target,P=_.dataset.objectId,x=_.dataset.propertyPath;if(!P||!x)return;let S=window.getEditableObjectConfig,A=S==null?void 0:S(P);if(!A)return;let E=this.updateManager.getNestedProperty(A,x),C=Array.isArray(E)?[...E]:[];C.push({templateId:"",weight:1}),await this.updateManager.updateProperty(P,x,C),this.loadObject(P)})}),this.contentContainer.querySelectorAll("[data-spawntemplates-remove]").forEach(L=>{L.addEventListener("click",async j=>{var k;let _=j.target,P=_.dataset.objectId,x=_.dataset.propertyPath,S=Number((k=_.dataset.index)!=null?k:-1);if(!P||!x||S<0)return;let A=window.getEditableObjectConfig,E=A==null?void 0:A(P);if(!E)return;let C=this.updateManager.getNestedProperty(E,x);if(!Array.isArray(C))return;let O=C.filter((R,z)=>z!==S);await this.updateManager.updateProperty(P,x,O),this.loadObject(P)})}),this.contentContainer.querySelectorAll("[data-logic-add]").forEach(L=>{L.addEventListener("click",async j=>{var D;let _=j.target,P=_.dataset.objectId,x=_.dataset.propertyPath;if(!P||!x)return;let S=window.getEditableObjectConfig,A=S==null?void 0:S(P);if(!A)return;let E=this.updateManager.getNestedProperty(A,x),C;Array.isArray(E)?C=[...E]:E!=null?typeof E=="string"?C=[{id:E,props:{}}]:typeof E=="object"?C=[E]:C=[]:C=[];let O=this.getDefaultLogicId(),k=window,R=(D=k==null?void 0:k.__HANDLER_LOGIC_META)==null?void 0:D[O],z=this.getDefaultPropsForLogic(O,R);C.push({id:O,props:z}),console.log("[InspectorPanel] Adding logic to array:",{objectId:P,path:x,current:E,next:C}),await this.updateManager.updateProperty(P,x,C),this.loadObject(P)})}),this.contentContainer.querySelectorAll("[data-logic-remove]").forEach(L=>{L.addEventListener("click",async j=>{var k;let _=j.target,P=_.dataset.objectId,x=_.dataset.propertyPath,S=Number((k=_.dataset.index)!=null?k:-1);if(!P||!x||S<0)return;let A=window.getEditableObjectConfig,E=A==null?void 0:A(P);if(!E)return;let C=this.updateManager.getNestedProperty(E,x);if(!Array.isArray(C))return;let O=C.filter((R,z)=>z!==S);await this.updateManager.updateProperty(P,x,O),this.loadObject(P)})}),this.contentContainer.querySelectorAll("[data-logic-convert]").forEach(L=>{L.addEventListener("click",async j=>{var U,F;let _=j.target,P=_.dataset.objectId,x=_.dataset.propertyPath,S=Number((U=_.dataset.index)!=null?U:-1);if(!P||!x||S<0)return;let A=window.getEditableObjectConfig,E=A==null?void 0:A(P);if(!E)return;let C=this.updateManager.getNestedProperty(E,x);if(!Array.isArray(C))return;let O=C[S];if(typeof O!="string")return;let k=window,R=(F=k==null?void 0:k.__HANDLER_LOGIC_META)==null?void 0:F[O],z=this.getDefaultPropsForLogic(O,R),D=[...C];D[S]={id:O,props:z},await this.updateManager.updateProperty(P,x,D),this.loadObject(P)})});let m=(w=this.root)==null?void 0:w.querySelector("[data-inspector-advanced]");m==null||m.addEventListener("click",()=>{this.showAdvanced=!this.showAdvanced,this.selectedObjectId&&this.loadObject(this.selectedObjectId)});let b=(T=this.root)==null?void 0:T.querySelector("[data-convert-toggle]");b==null||b.addEventListener("click",()=>{var j;let L=(j=this.root)==null?void 0:j.querySelector("[data-convert-menu]");L==null||L.classList.toggle("hidden")});let y=(I=this.contentContainer)==null?void 0:I.querySelector("[data-inspector-add-component-btn]"),v=(M=this.contentContainer)==null?void 0:M.querySelector("[data-inspector-component-select]");y==null||y.addEventListener("click",async()=>{let L=v.value;L&&this.selectedObjectId&&await this.addComponent(this.selectedObjectId,L)})}getMotionDefaults(){var i,n,a,r;let e=window.__editableConfig,t=e==null?void 0:e.schemas;return t instanceof Map?(n=(i=t.get("motion"))==null?void 0:i.defaults)!=null?n:{enabled:!0}:t&&typeof t=="object"?(r=(a=t.motion)==null?void 0:a.defaults)!=null?r:{enabled:!0}:{enabled:!0}}async applyMotionPreset(e,t){var l,c;let i=window.getEditableObjectConfig,n=i==null?void 0:i(e);if(!n)return;let a=this.getMotionDefaults(),r={...(l=n.motion)!=null?l:a},o={...(c=r.intro)!=null?c:{}};r.enabled=!0,o.enabled=!0,o.type=t,o.duration=typeof o.duration=="number"&&o.duration>0?o.duration:500,o.delay=typeof o.delay=="number"?o.delay:0,o.easing=typeof o.easing=="string"?o.easing:"easeOut",r.intro=o,await this.updateManager.updateProperty(e,"motion",r),this.expandMotionOnNextRender=!0,this.loadObject(e)}async previewMotionIntro(e){var o,l;let t=window.getEditableObjectConfig,i=t==null?void 0:t(e);if(!i)return;let n=this.getMotionDefaults(),a={...(o=i.motion)!=null?o:n},r={...(l=a.intro)!=null?l:{}};a.enabled=!0,r.enabled=!0,a.intro=r,await this.updateManager.updateProperty(e,"motion",{...a,intro:{...r,enabled:!1}}),await this.updateManager.updateProperty(e,"motion",{...a,intro:{...r,enabled:!0}}),this.loadObject(e)}async addComponent(e,t){console.log("[InspectorPanel] Adding component:",t,"to:",e);let i=window.getEditableObjectConfig,n=i==null?void 0:i(e);if(!n){console.error("[InspectorPanel] Failed to get config for:",e);return}if(t==="logic"){let c={id:"SwerveMove",props:this.getDefaultPropsForLogic("SwerveMove",null)};n[t]=c,await this.updateManager.updateProperty(e,t,c),this.loadObject(e),console.log("[InspectorPanel] Logic component added with default SwerveMove");return}t==="motion"&&(this.expandMotionOnNextRender=!0);let a=window.__editableConfig,r=a==null?void 0:a.schemas,o=null;r instanceof Map?o=r.get(t):r&&typeof r=="object"&&(o=r[t]),o||console.warn("[InspectorPanel] Schema not found for component:",t);let l=(o==null?void 0:o.defaults)||{enabled:!0};n[t]={...l},await this.updateManager.updateProperty(e,t,n[t]),this.loadObject(e),console.log("[InspectorPanel] Component added successfully")}isSectionMeaningful(e,t,i){var a,r;if(["identity","transform","render"].includes(e))return!0;if(!t||typeof t!="object"||e==="ui"&&((r=(a=i.render)==null?void 0:a.asset)==null?void 0:r.type)==="image")return!1;if(e==="interaction")return t.clickable===!0||t.draggable===!0;if(t.enabled===!0||t.active===!0||t.visible===!0)return!0;if(e==="ui")return!!(t.text||t.font||t.fontSize);let n=Object.keys(t);return n.length===0||n.length===1&&n[0]==="enabled"&&t.enabled===!1?!1:["audio","effects","physics","motion","gameplay"].includes(e)?t.enabled===!0:!0}showError(e){this.contentContainer&&(this.contentContainer.innerHTML=`
|
|
1300
|
+
`}attachEventListeners(){var w,T,I,M;if(!this.contentContainer)return;let e=this.contentContainer.querySelectorAll("[data-property-path]"),t=sl((L,j,_)=>{var P,x;this.updateManager.updateProperty(L,j,_),(x=(P=this.options)==null?void 0:P.onPropertyChange)==null||x.call(P,L,j,_)},300),i=L=>L?/(^|\.)logic(\.\d+)?\.id$/.test(L):!1;e.forEach(L=>{let j=x=>{var C,O;let S=x.target,A=S.dataset.propertyPath,E=S.dataset.objectId;if(A&&E){let k=S.value;if(S.type==="checkbox")k=S.checked;else if(S.type==="number"){if(k=parseFloat(S.value),isNaN(k))return}else if(S.dataset.json==="true")try{k=JSON.parse(S.value)}catch{return}S.type==="text"||S.type==="range"||S.tagName==="TEXTAREA"?t(E,A,k):(this.updateManager.updateProperty(E,A,k),(O=(C=this.options)==null?void 0:C.onPropertyChange)==null||O.call(C,E,A,k))}},_=L.dataset.propertyPath;_&&(_.includes("transform.anchor")||_.includes("render.anchor"))&&L.tagName==="SELECT"?L.addEventListener("change",async x=>{var O,k,R,z,D;let S=x.target,A=S.dataset.propertyPath,E=S.dataset.objectId,C=S.value;if(!(!A||!E)&&C!=="custom")if(A.includes("transform.anchor")){let U=window.getEditableObjectConfig,F=typeof U=="function"?U(E):null,G=(O=F==null?void 0:F.transform)==null?void 0:O.anchor,B=G!=null&&G!==""?G:"top-left",q=C;await this.updateManager.updateProperty(E,A,C),(R=(k=this.options)==null?void 0:k.onPropertyChange)==null||R.call(k,E,A,C),B!==q&&window.dispatchEvent(new CustomEvent("scene-editor:anchor-changed",{detail:{objectId:E,previousAnchor:B,nextAnchor:q}}))}else await this.updateManager.updateProperty(E,A,C),(D=(z=this.options)==null?void 0:z.onPropertyChange)==null||D.call(z,E,A,C)}):i(_)?(console.log("[Inspector v1.0.0] PATH-BASED DETECTION ACTIVE - logic ID found at:",_),L.addEventListener("change",async x=>{var D;let S=x.target,A=S.dataset.propertyPath,E=S.dataset.objectId,C=S.value;if(console.log("[Inspector v1.0.0] Logic ID changed to:",C),!A||!E)return;await this.updateManager.updateProperty(E,A,C),console.log("[Inspector v1.0.0] Logic ID updated");let O=window,k=(D=O==null?void 0:O.__HANDLER_LOGIC_META)==null?void 0:D[C],R=this.getDefaultPropsForLogic(C,k);console.log("[Inspector v1.0.0] New logic default props:",R);let z=A.replace(/\.id$/,".props");await this.updateManager.updateProperty(E,z,R),console.log("[Inspector v1.0.0] Logic props updated to:",R),console.log("[Inspector v1.0.0] Reloading inspector with updated config"),this.loadObject(E)})):(L.addEventListener("change",j),(L.tagName==="INPUT"||L.tagName==="TEXTAREA")&&L.addEventListener("input",j))}),this.contentContainer.querySelectorAll("[data-action]").forEach(L=>{L.addEventListener("click",j=>{let _=j.target,P=_.dataset.action,x=_.dataset.path,S=_.dataset.object;P&&x&&S&&this.quickActions.handleAction(P,S,x)})}),this.contentContainer.querySelectorAll("[data-section-toggle]").forEach(L=>{L.addEventListener("click",j=>{var x,S;let _=j.target,P=_.dataset.sectionToggle||((x=_.closest("[data-section-toggle]"))==null?void 0:x.getAttribute("data-section-toggle"));if(P){let A=(S=this.contentContainer)==null?void 0:S.querySelector(`[data-section="${P}"]`);A==null||A.classList.toggle("collapsed")}})}),this.contentContainer.querySelectorAll("[data-motion-preset]").forEach(L=>{L.addEventListener("click",async j=>{let P=j.currentTarget.dataset.motionPreset;!P||!this.selectedObjectId||await this.applyMotionPreset(this.selectedObjectId,P)})}),this.contentContainer.querySelectorAll("[data-motion-preview]").forEach(L=>{L.addEventListener("click",async()=>{this.selectedObjectId&&await this.previewMotionIntro(this.selectedObjectId)})});let l=this.contentContainer.querySelector("[data-motion-simple-toggle]");l==null||l.addEventListener("click",()=>{this.motionSimpleMode=!this.motionSimpleMode;try{localStorage.setItem("inspector:motionSimple",String(this.motionSimpleMode))}catch{}this.selectedObjectId&&this.loadObject(this.selectedObjectId)}),this.contentContainer.querySelectorAll("[data-spawnpoints-add]").forEach(L=>{L.addEventListener("click",async j=>{let _=j.target,P=_.dataset.objectId,x=_.dataset.propertyPath;if(!P||!x)return;let S=window.getEditableObjectConfig,A=S==null?void 0:S(P);if(!A)return;let E=this.updateManager.getNestedProperty(A,x),C=Array.isArray(E)?[...E]:[];C.push({x:0,y:0}),await this.updateManager.updateProperty(P,x,C),this.loadObject(P)})}),this.contentContainer.querySelectorAll("[data-spawnpoints-remove]").forEach(L=>{L.addEventListener("click",async j=>{let _=j.target,P=_.dataset.objectId,x=_.dataset.propertyPath,S=Number(_.dataset.index||"-1");if(!P||!x||S<0)return;let A=window.getEditableObjectConfig,E=A==null?void 0:A(P);if(!E)return;let C=this.updateManager.getNestedProperty(E,x);if(!Array.isArray(C))return;let O=C.filter((k,R)=>R!==S);await this.updateManager.updateProperty(P,x,O),this.loadObject(P)})}),this.contentContainer.querySelectorAll("[data-spawntemplates-add]").forEach(L=>{L.addEventListener("click",async j=>{let _=j.target,P=_.dataset.objectId,x=_.dataset.propertyPath;if(!P||!x)return;let S=window.getEditableObjectConfig,A=S==null?void 0:S(P);if(!A)return;let E=this.updateManager.getNestedProperty(A,x),C=Array.isArray(E)?[...E]:[];C.push({templateId:"",weight:1}),await this.updateManager.updateProperty(P,x,C),this.loadObject(P)})}),this.contentContainer.querySelectorAll("[data-spawntemplates-remove]").forEach(L=>{L.addEventListener("click",async j=>{var k;let _=j.target,P=_.dataset.objectId,x=_.dataset.propertyPath,S=Number((k=_.dataset.index)!=null?k:-1);if(!P||!x||S<0)return;let A=window.getEditableObjectConfig,E=A==null?void 0:A(P);if(!E)return;let C=this.updateManager.getNestedProperty(E,x);if(!Array.isArray(C))return;let O=C.filter((R,z)=>z!==S);await this.updateManager.updateProperty(P,x,O),this.loadObject(P)})}),this.contentContainer.querySelectorAll("[data-logic-add]").forEach(L=>{L.addEventListener("click",async j=>{var D;let _=j.target,P=_.dataset.objectId,x=_.dataset.propertyPath;if(!P||!x)return;let S=window.getEditableObjectConfig,A=S==null?void 0:S(P);if(!A)return;let E=this.updateManager.getNestedProperty(A,x),C;Array.isArray(E)?C=[...E]:E!=null?typeof E=="string"?C=[{id:E,props:{}}]:typeof E=="object"?C=[E]:C=[]:C=[];let O=this.getDefaultLogicId(),k=window,R=(D=k==null?void 0:k.__HANDLER_LOGIC_META)==null?void 0:D[O],z=this.getDefaultPropsForLogic(O,R);C.push({id:O,props:z}),console.log("[InspectorPanel] Adding logic to array:",{objectId:P,path:x,current:E,next:C}),await this.updateManager.updateProperty(P,x,C),this.loadObject(P)})}),this.contentContainer.querySelectorAll("[data-logic-remove]").forEach(L=>{L.addEventListener("click",async j=>{var k;let _=j.target,P=_.dataset.objectId,x=_.dataset.propertyPath,S=Number((k=_.dataset.index)!=null?k:-1);if(!P||!x||S<0)return;let A=window.getEditableObjectConfig,E=A==null?void 0:A(P);if(!E)return;let C=this.updateManager.getNestedProperty(E,x);if(!Array.isArray(C))return;let O=C.filter((R,z)=>z!==S);await this.updateManager.updateProperty(P,x,O),this.loadObject(P)})}),this.contentContainer.querySelectorAll("[data-logic-convert]").forEach(L=>{L.addEventListener("click",async j=>{var U,F;let _=j.target,P=_.dataset.objectId,x=_.dataset.propertyPath,S=Number((U=_.dataset.index)!=null?U:-1);if(!P||!x||S<0)return;let A=window.getEditableObjectConfig,E=A==null?void 0:A(P);if(!E)return;let C=this.updateManager.getNestedProperty(E,x);if(!Array.isArray(C))return;let O=C[S];if(typeof O!="string")return;let k=window,R=(F=k==null?void 0:k.__HANDLER_LOGIC_META)==null?void 0:F[O],z=this.getDefaultPropsForLogic(O,R),D=[...C];D[S]={id:O,props:z},await this.updateManager.updateProperty(P,x,D),this.loadObject(P)})});let m=(w=this.root)==null?void 0:w.querySelector("[data-inspector-advanced]");m==null||m.addEventListener("click",()=>{this.showAdvanced=!this.showAdvanced,this.selectedObjectId&&this.loadObject(this.selectedObjectId)});let b=(T=this.root)==null?void 0:T.querySelector("[data-convert-toggle]");b==null||b.addEventListener("click",()=>{var j;let L=(j=this.root)==null?void 0:j.querySelector("[data-convert-menu]");L==null||L.classList.toggle("hidden")});let y=(I=this.contentContainer)==null?void 0:I.querySelector("[data-inspector-add-component-btn]"),v=(M=this.contentContainer)==null?void 0:M.querySelector("[data-inspector-component-select]");y==null||y.addEventListener("click",async()=>{let L=v.value;L&&this.selectedObjectId&&await this.addComponent(this.selectedObjectId,L)})}getMotionDefaults(){var i,n,a,s;let e=window.__editableConfig,t=e==null?void 0:e.schemas;return t instanceof Map?(n=(i=t.get("motion"))==null?void 0:i.defaults)!=null?n:{enabled:!0}:t&&typeof t=="object"?(s=(a=t.motion)==null?void 0:a.defaults)!=null?s:{enabled:!0}:{enabled:!0}}async applyMotionPreset(e,t){var l,c;let i=window.getEditableObjectConfig,n=i==null?void 0:i(e);if(!n)return;let a=this.getMotionDefaults(),s={...(l=n.motion)!=null?l:a},o={...(c=s.intro)!=null?c:{}};s.enabled=!0,o.enabled=!0,o.type=t,o.duration=typeof o.duration=="number"&&o.duration>0?o.duration:500,o.delay=typeof o.delay=="number"?o.delay:0,o.easing=typeof o.easing=="string"?o.easing:"easeOut",s.intro=o,await this.updateManager.updateProperty(e,"motion",s),this.expandMotionOnNextRender=!0,this.loadObject(e)}async previewMotionIntro(e){var o,l;let t=window.getEditableObjectConfig,i=t==null?void 0:t(e);if(!i)return;let n=this.getMotionDefaults(),a={...(o=i.motion)!=null?o:n},s={...(l=a.intro)!=null?l:{}};a.enabled=!0,s.enabled=!0,a.intro=s,await this.updateManager.updateProperty(e,"motion",{...a,intro:{...s,enabled:!1}}),await this.updateManager.updateProperty(e,"motion",{...a,intro:{...s,enabled:!0}}),this.loadObject(e)}async addComponent(e,t){console.log("[InspectorPanel] Adding component:",t,"to:",e);let i=window.getEditableObjectConfig,n=i==null?void 0:i(e);if(!n){console.error("[InspectorPanel] Failed to get config for:",e);return}if(t==="logic"){let c={id:"SwerveMove",props:this.getDefaultPropsForLogic("SwerveMove",null)};n[t]=c,await this.updateManager.updateProperty(e,t,c),this.loadObject(e),console.log("[InspectorPanel] Logic component added with default SwerveMove");return}t==="motion"&&(this.expandMotionOnNextRender=!0);let a=window.__editableConfig,s=a==null?void 0:a.schemas,o=null;s instanceof Map?o=s.get(t):s&&typeof s=="object"&&(o=s[t]),o||console.warn("[InspectorPanel] Schema not found for component:",t);let l=(o==null?void 0:o.defaults)||{enabled:!0};n[t]={...l},await this.updateManager.updateProperty(e,t,n[t]),this.loadObject(e),console.log("[InspectorPanel] Component added successfully")}isSectionMeaningful(e,t,i){var a,s;if(["identity","transform","render"].includes(e))return!0;if(!t||typeof t!="object"||e==="ui"&&((s=(a=i.render)==null?void 0:a.asset)==null?void 0:s.type)==="image")return!1;if(e==="interaction")return t.clickable===!0||t.draggable===!0;if(t.enabled===!0||t.active===!0||t.visible===!0)return!0;if(e==="ui")return!!(t.text||t.font||t.fontSize);let n=Object.keys(t);return n.length===0||n.length===1&&n[0]==="enabled"&&t.enabled===!1?!1:["audio","effects","physics","motion","gameplay"].includes(e)?t.enabled===!0:!0}showError(e){this.contentContainer&&(this.contentContainer.innerHTML=`
|
|
1299
1301
|
<div class="inspector-empty">
|
|
1300
1302
|
<span class="inspector-empty-icon">\u26A0\uFE0F</span>
|
|
1301
1303
|
<span class="inspector-empty-text">${e}</span>
|
|
@@ -1305,17 +1307,17 @@ ${f}
|
|
|
1305
1307
|
<span class="inspector-empty-icon">\u{1F3AF}</span>
|
|
1306
1308
|
<span class="inspector-empty-text">Select an object to inspect</span>
|
|
1307
1309
|
</div>
|
|
1308
|
-
`)}};function la(
|
|
1309
|
-
`)||"None",t=
|
|
1310
|
-
`),n="";if(
|
|
1310
|
+
`)}};function la(r){return new Promise((e,t)=>{let i=new FileReader;i.onerror=()=>t(new Error("FileReader failed")),i.onload=()=>e(String(i.result||"")),i.readAsDataURL(r)})}function Ks(r){var n;let[e,t]=r.split(","),i=e==null?void 0:e.match(/data:(.*?);base64/);return{base64:t!=null?t:"",mimeType:(n=i==null?void 0:i[1])!=null?n:"image/png"}}async function Xs(r){return await new Promise(e=>{let t=new Image;t.onload=()=>e({width:t.naturalWidth||t.width,height:t.naturalHeight||t.height}),t.onerror=()=>e(null),t.src=r})}async function Xi(r){var e,t;try{console.log("[ImageUtils] Fetching image data from URL:",r);let i=await fetch(r);if(!i.ok)return console.warn("[ImageUtils] Fetch failed with status:",i.status,r),null;let n=await i.blob();console.log("[ImageUtils] Blob received, size:",n.size,"type:",n.type);let a=await la(n),s=await Xs(a),o=Ks(a);return console.log("[ImageUtils] Success resolution:",s==null?void 0:s.width,"x",s==null?void 0:s.height,"mime:",o.mimeType),{base64:o.base64,mimeType:o.mimeType,dataUrl:a,width:(e=s==null?void 0:s.width)!=null?e:0,height:(t=s==null?void 0:s.height)!=null?t:0}}catch(i){return console.error("[ImageUtils] Error fetching image data:",i),null}}async function Fe(r){var e,t;try{let i=await la(r),n=await Xs(i),a=Ks(i);return{base64:a.base64,mimeType:a.mimeType,dataUrl:i,width:(e=n==null?void 0:n.width)!=null?e:0,height:(t=n==null?void 0:n.height)!=null?t:0}}catch{return null}}function ca(r){return la(r).then(e=>e).catch(()=>null)}function da(r,e){var t;try{let[i,n]=r.split(","),a=i.match(/data:(.*?);base64/),s=(t=a==null?void 0:a[1])!=null?t:"image/png",o=atob(n),l=new Uint8Array(o.length);for(let c=0;c<o.length;c++)l[c]=o.charCodeAt(c);return new File([l],e,{type:s})}catch{return null}}async function ht(r,e=30){try{console.log("[ImageUtils] Removing background color...");let t=await new Promise((p,u)=>{let g=new Image;g.onload=()=>p(g),g.onerror=()=>u(new Error("Failed to load image")),g.src=r}),i=document.createElement("canvas");i.width=t.width,i.height=t.height;let n=i.getContext("2d");if(!n)return console.error("[ImageUtils] Failed to get canvas context"),r;n.drawImage(t,0,0);let a=n.getImageData(0,0,i.width,i.height),s=a.data,l=[{name:"top-left",offset:0},{name:"top-right",offset:(i.width-1)*4},{name:"bottom-left",offset:(i.height-1)*i.width*4},{name:"bottom-right",offset:((i.height-1)*i.width+(i.width-1))*4}].map(p=>({r:s[p.offset],g:s[p.offset+1],b:s[p.offset+2]})),c=0;for(let p=0;p<s.length;p+=4){let u=s[p],g=s[p+1],h=s[p+2],f=!1;for(let m of l)if(Math.sqrt(Math.pow(u-m.r,2)+Math.pow(g-m.g,2)+Math.pow(h-m.b,2))<e){f=!0;break}f&&(s[p+3]=0,c++)}return console.log(`[ImageUtils] Removed background from ${c} pixels (4-corner sampling, tolerance: ${e})`),n.putImageData(a,0,0),i.toDataURL("image/png")}catch(t){return console.error("[ImageUtils] Error removing background:",t),r}}function pa(r,e){if(!r||!e)return"1:1";let t=r/e;return t>1.3?"16:9":t<.77?"9:16":"1:1"}function Pe(r){return typeof r=="object"&&r!==null&&!Array.isArray(r)}function ne(r){return typeof r=="string"?r:void 0}function Js(r){return r.toLowerCase().endsWith(".png")?r.slice(0,-4):r}function rl(r){var i,n,a;let e=(i=ne(r.id))!=null?i:ne(r.name);if(e)return e;let t=(n=ne(r.file))!=null?n:ne(r.asset);return t?Js((a=t.split("/").pop())!=null?a:t):void 0}function ol(r,e,t){var i,n,a;if(typeof e=="string")return{id:r,file:e,role:t};if(Pe(e)){let s=(i=ne(e.file))!=null?i:ne(e.asset);return s?{id:(n=ne(e.id))!=null?n:r,file:s,role:(a=ne(e.role))!=null?a:t,dataUrl:ne(e.dataUrl),layout:e.layout}:null}return null}function ua(r,e){var t,i,n;if(!r)return[];if(Array.isArray(r)){let a=[];for(let s of r){if(typeof s=="string"){let o=Js((t=s.split("/").pop())!=null?t:s);a.push({id:o,file:s,role:e});continue}if(Pe(s)){let o=rl(s),l=(i=ne(s.file))!=null?i:ne(s.asset);if(!o||!l)continue;a.push({id:o,file:l,role:(n=ne(s.role))!=null?n:e,dataUrl:ne(s.dataUrl),layout:s.layout})}}return a}if(Pe(r)){let a=[];for(let[s,o]of Object.entries(r)){let l=ol(s,o,e);l&&a.push(l)}return a}return[]}function ll(r){var e,t;return(t=(e=ne(r.brand_name))!=null?e:ne(r.brandName))!=null?t:ne(r.name)}function cl(r){if(Pe(r.brand_dna)&&Pe(r.brand_dna.colors))return r.brand_dna;if(Pe(r.colors)){let e={colors:r.colors};return typeof r.style=="string"&&(e.style=r.style),Pe(r.fonts)&&(e.fonts=r.fonts),e}}function dl(r){var t;let e=new Map;for(let i of r){let n=e.get(i.id);if(!n){e.set(i.id,i);continue}e.set(i.id,{...n,...i,file:i.file||n.file,role:i.role||n.role,dataUrl:i.dataUrl||n.dataUrl,layout:(t=i.layout)!=null?t:n.layout})}return Array.from(e.values())}function Zs(r,e={}){var s,o,l;let t=r.filter(Pe),i=(o=(s=t.map(ll).find(Boolean))!=null?s:e.defaultBrandName)!=null?o:"Imported Brand",n=(l=t.map(cl).find(Boolean))!=null?l:{colors:{}},a=[];for(let c of t)"layers"in c&&a.push(...ua(c.layers,"visual element")),"assets"in c&&a.push(...ua(c.assets,"visual element")),Pe(c.endgame)&&"assets"in c.endgame&&a.push(...ua(c.endgame.assets,"endgame"));return{version:"1.0",brand_name:i,brand_dna:n,assets:dl(a)}}var Qs=require("@google/genai");async function Ji(r,e,t=[],i={}){var n,a,s,o,l,c,d;try{if(!(r!=null&&r.trim()))throw new Error("Gemini API key is required");if(!(e!=null&&e.trim()))throw new Error("Prompt is required");for(let b=0;b<t.length;b++){let y=t[b];if(!y.base64||!y.mimeType)throw new Error(`Image ${b+1} is missing required data`);if(y.base64.length<1e3&&console.warn(`Image ${b+1} data appears very small, may be corrupted`),!y.mimeType.startsWith("image/"))throw new Error(`Image ${b+1} has invalid MIME type: ${y.mimeType}`)}let p=new Qs.GoogleGenAI({apiKey:r}),u="gemini-2.5-flash",g=[e];t.length>0&&t.forEach((b,y)=>{g.push({inlineData:{data:b.base64,mimeType:b.mimeType}}),console.log(`[Gemini] Added image ${y+1}: ${b.mimeType}, size: ${Math.round(b.base64.length/1024)}KB`)}),console.log(`[Gemini] Making request with ${t.length} images and prompt length: ${e.length}`);let h=await p.models.generateContent({model:u,contents:g}),f="",m=(s=(a=(n=h.candidates)==null?void 0:n[0])==null?void 0:a.content)==null?void 0:s.parts;if(m)for(let b of m)b.text&&(f+=b.text);if(!f.trim())throw new Error("Empty response from Gemini API");return console.log(`[Gemini] Response received, length: ${f.length}`),f}catch(p){throw console.error("[Gemini] API error:",p),(o=p.message)!=null&&o.includes("Unable to process input image")?new Error("Unable to process the uploaded image. Please ensure it's a valid PNG, JPG, or JPEG file under 10MB and not corrupted."):(l=p.message)!=null&&l.includes("API_KEY_INVALID")?new Error("Invalid Gemini API key. Please check your API key configuration."):(c=p.message)!=null&&c.includes("QUOTA_EXCEEDED")?new Error("Gemini API quota exceeded. Please try again later or check your billing."):(d=p.message)!=null&&d.includes("SAFETY")?new Error("Content was flagged by Gemini safety filters. Please try with different images."):p}}var er=require("@google/genai");async function ft(r,e,t=[],i={}){try{console.info("[GEMINI-REAL-SDK] Initializing GoogleGenAI...");let n=new er.GoogleGenAI({apiKey:r}),a=[{text:e}];t.length>0&&t.forEach((o,l)=>{console.info(`[GEMINI-REAL-SDK] Adding image part ${l}`),a.push({inlineData:{mimeType:o.mimeType,data:o.base64}})}),console.info("[GEMINI-REAL-SDK] Calling generateContent with model: gemini-2.5-flash-image");let s=await n.models.generateContent({model:"gemini-2.5-flash-image",contents:a});if(console.info("[GEMINI-REAL-SDK] Received response from model"),!s.candidates||!s.candidates[0]||!s.candidates[0].content||!s.candidates[0].content.parts)throw new Error("Gemini 2.5 Flash Image returned invalid response structure.");for(let o of s.candidates[0].content.parts)if(o.text)console.log(o.text);else if(o.inlineData){let l=o.inlineData.data,c=o.inlineData.mimeType||"image/png";return console.info("[GEMINI-REAL-SDK] Found inline image data in response"),`data:${c};base64,${l}`}throw new Error("Gemini 2.5 Flash Image returned no image data.")}catch(n){throw console.error("[GEMINI-REAL-SDK] Error in generateImageWithGemini25Flash:",JSON.stringify(n,Object.getOwnPropertyNames(n),2)),n}}function tr(r){let e=r.brandAssets.map(a=>{let s=`- ${a.id}: ${a.role}`;return a.layout&&(s+=` [pos: ${a.layout.x.toFixed(0)},${a.layout.y.toFixed(0)}, size: ${a.layout.w.toFixed(0)}x${a.layout.h.toFixed(0)}, z: ${a.layout.z}, opacity: ${a.layout.opacity}]`),s}).join(`
|
|
1311
|
+
`)||"None",t=r.brandDna?`Colors: ${JSON.stringify(r.brandDna.colors)}, Style: ${r.brandDna.style||"not specified"}`:"Not provided",i=r.gameObjects.map(a=>typeof a=="string"?`- id: ${a}`:`- id: ${a.id}${a.category?`, category: ${a.category}`:""}${a.type?`, type: ${a.type}`:""}`).join(`
|
|
1312
|
+
`),n="";if(r.brandConfig){let a=r.brandConfig,s=[];a.splash&&s.push(`SPLASH: title="${a.splash.title||""}", subtitle="${a.splash.subtitle||""}", button="${a.splash.button_label||""}"`),a.endgame&&s.push(`ENDGAME: title="${a.endgame.title||""}", subtitle="${a.endgame.subtitle||""}", cta="${a.endgame.cta_label||""}"`),a.tutorial&&s.push(`TUTORIAL: text="${a.tutorial.label_text||""}", helper="${a.tutorial.helper_text||""}"`),s.length>0&&(n=`
|
|
1311
1313
|
BRAND CONTENT:
|
|
1312
|
-
${
|
|
1314
|
+
${s.join(`
|
|
1313
1315
|
`)}
|
|
1314
1316
|
`)}return`
|
|
1315
1317
|
You are analyzing a brand's visual design for use in a playable ad game.
|
|
1316
1318
|
|
|
1317
1319
|
GAME CONTEXT:
|
|
1318
|
-
${
|
|
1320
|
+
${r.gamePrompt||"Simple game"}
|
|
1319
1321
|
|
|
1320
1322
|
GAME OBJECTS (need assets):
|
|
1321
1323
|
${i}
|
|
@@ -1369,28 +1371,28 @@ OUTPUT ONLY VALID JSON (no markdown, no explanation):
|
|
|
1369
1371
|
}
|
|
1370
1372
|
]
|
|
1371
1373
|
}
|
|
1372
|
-
`.trim()}function ir(
|
|
1373
|
-
TASK: ${
|
|
1374
|
+
`.trim()}function ir(r){var n,a;let e=(n=r.brandDna)!=null&&n.colors?`Primary: ${r.brandDna.colors.primary}, Secondary: ${r.brandDna.colors.secondary||"N/A"}, Accent: ${r.brandDna.colors.accent||"N/A"}`:"Use provided reference colors",t=((a=r.brandDna)==null?void 0:a.style)||"modern gaming style",i=r.needsTransparency?"BACKGROUND: REQUIRED solid magenta #FF00FF (for transparency removal)":"BACKGROUND: Use brand colors naturally, fill the entire frame";return`
|
|
1375
|
+
TASK: ${r.prompt}
|
|
1374
1376
|
|
|
1375
1377
|
BRAND STYLE:
|
|
1376
1378
|
- Colors: ${e}
|
|
1377
1379
|
- Style: ${t}
|
|
1378
1380
|
|
|
1379
1381
|
CHANGE_STRENGTH: 8/10
|
|
1380
|
-
REFERENCE: ${
|
|
1382
|
+
REFERENCE: ${r.hasReference?"provided (use as style guide for colors and aesthetics)":"none"}
|
|
1381
1383
|
${i}
|
|
1382
1384
|
|
|
1383
1385
|
OUTPUT CONSTRAINTS (MUST FOLLOW):
|
|
1384
1386
|
- Do NOT add extra text unless specifically requested
|
|
1385
|
-
- Preserve aspect ratio${
|
|
1387
|
+
- Preserve aspect ratio${r.aspectRatio?` (target: ${r.aspectRatio})`:""}
|
|
1386
1388
|
- Keep padding under 5% of asset size
|
|
1387
1389
|
- No drop shadows unless explicitly requested
|
|
1388
|
-
- No gradients on the background (solid ${
|
|
1390
|
+
- No gradients on the background (solid ${r.needsTransparency?"magenta":"colors"} only)
|
|
1389
1391
|
- Center the subject in frame
|
|
1390
1392
|
|
|
1391
1393
|
OUTPUT:
|
|
1392
|
-
Generate the requested asset matching the brand style.${
|
|
1393
|
-
`.trim()}function nr(s){return s.map(e=>{if(typeof e=="string"){let t=e,i,n;return t.includes("background")?(i="background",n="background"):t.includes("button")||t.includes("cta")?(i="ui",n="button"):t.includes("logo")?(i="ui",n="logo"):t.includes("title")||t.includes("subtitle")||t.includes("text")?(i="text",n="text"):t.includes("effect")||t.includes("confetti")||t.includes("particle")?(i="effects",n="effect"):t.includes("ui.")||t.includes("splash")||t.includes("endgame")?(i="ui",n="image"):(i="environment",n="interactive"),{id:t,category:i,type:n}}return e})}function ar(s,e){return!(s.includes("background")&&(s.includes("_1")||s.includes("splash")||s.includes("endgame")||s.includes("main"))||e==="text"||e==="effects"&&s.includes("particle"))}async function sr(s){var r,o;let e=nr(s.gameObjects),t={gamePrompt:s.gamePrompt,gameObjects:e,brandAssets:s.manifest.assets,brandDna:s.manifest.brand_dna,brandName:s.manifest.brand_name},i=tr(t),n=[];if(s.flatDesignDataUrl)try{let l=rr(s.flatDesignDataUrl);l&&l.base64&&l.mimeType?l.base64.length<100?console.warn("[Pipeline] Flat design data URL appears invalid (too short)"):(n.push(l),console.log("[Pipeline] Added flat design to analysis, size:",l.base64.length)):console.warn("[Pipeline] Failed to parse flat design data URL")}catch(l){console.warn("[Pipeline] Error processing flat design:",l)}console.log("[Pipeline] Running analysis chain with",n.length,"images...");let a;try{a=await Ji(s.apiKey,i,n,{model:"gemini-2.5-flash"}),console.log("[Pipeline] Analysis response received")}catch(l){throw console.error("[Pipeline] Gemini API error:",l),(r=l.message)!=null&&r.includes("Unable to process input image")?new Error("Gemini API unable to process the uploaded images. Please try with different images or ensure they are valid PNG/JPG files under 10MB."):(o=l.message)!=null&&o.includes("image")?new Error("Image processing failed. Please ensure your images are valid and not corrupted."):l}return pl(a,s.gameObjects)}function pl(s,e){try{let t=s,i=s.match(/```(?:json)?\s*([\s\S]*?)```/);if(i)t=i[1].trim();else{let a=s.match(/\{[\s\S]*\}/);a&&(t=a[0])}let n=JSON.parse(t);return n.mappings&&Array.isArray(n.mappings)?{mappingResult:n,rawResponse:s,parsed:!0}:{mappingResult:{mappings:e.map(a=>({game_object:a,action:"KEEP",status:"Analysis response missing mappings[]"}))},rawResponse:s,parsed:!1,parseError:"Missing mappings[] array"}}catch(t){return{mappingResult:{mappings:e.map(i=>({game_object:i,action:"KEEP",status:"Analysis response was not valid JSON"}))},rawResponse:s,parsed:!1,parseError:t!=null&&t.message?String(t.message):"JSON parse failed"}}}async function ga(s,e,t={}){var n;let i=e.mappings.filter(a=>a.action==="GENERATE");if(i.length===0){console.log("[Pipeline] No assets to generate");return}console.log(`[Pipeline] Generating ${i.length} assets...`);for(let a=0;a<i.length;a++){let r=i[a];(n=t.onProgress)==null||n.call(t,a+1,i.length,r.game_object);try{let o=await ul(s,r);r.output_dataUrl=o,r.status="Generated \u2713"}catch(o){console.error(`[Pipeline] Failed to generate ${r.game_object}:`,o),r.status="Failed \u2717"}}console.log("[Pipeline] Generation chain complete")}async function ul(s,e){if(!e.generation_prompt)throw new Error("No generation prompt provided");let t=[];if(e.reference_asset&&s.manifest){let o=s.manifest.assets.find(l=>l.id===e.reference_asset);if(o){let l=s.assetFiles.get(o.file);if(l){let c=await Fe(l);c&&t.push({base64:c.base64,mimeType:c.mimeType})}}}if(s.flatDesignDataUrl){let o=rr(s.flatDesignDataUrl);o&&t.push(o)}let i=ar(e.game_object),n={prompt:e.generation_prompt,hasReference:t.length>0,brandDna:s.manifest.brand_dna,needsTransparency:i},a=ir(n);console.log(`[Pipeline] Generating asset for ${e.game_object}... (transparency: ${i})`);let r=await ft(s.apiKey,a,t,{aspectRatio:"1:1",model:"gemini-2.5-flash-image"});return i&&await ht(r)||r}function rr(s){let[e,t]=s.split(","),i=e==null?void 0:e.match(/data:(.*?);base64/);return t&&i?{base64:t,mimeType:i[1]}:null}async function or(s,e){let t=s.assets,i=[];Array.isArray(t)?i=t:t&&typeof t=="object"?i=Object.entries(t).map(([n,a])=>({id:n,file:String(a),role:"visual element"})):i=[],s.assets=i;for(let n of i){let a=e.get(n.file);if(a){let r=await Fe(a);r&&(n.dataUrl=r.dataUrl)}}}function lr(s){var t,i;let e=new Map;if(!s)return console.warn("[CanvaZip] No position data provided"),e;if(typeof s=="string")try{s=JSON.parse(s)}catch(n){return console.error("[CanvaZip] Failed to parse position data JSON:",n),e}if(s!=null&&s.layers&&Array.isArray(s.layers)){console.log(`[CanvaZip] Parsing ${s.layers.length} layers from position data`);for(let n of s.layers){let a=n.asset;if(!a||!n.layout){console.warn("[CanvaZip] Skipping layer without asset or layout:",n);continue}let r=n.layout,o={x:typeof r.x=="number"?r.x:0,y:typeof r.y=="number"?r.y:0},l=typeof r.scaleX=="number"?r.scaleX:1,c=typeof r.scaleY=="number"?r.scaleY:1,d=(l+c)/2;d>1&&(d=d/13.33);let p=typeof r.rotation=="number"?r.rotation:0;e.set(a,{position:o,scale:d,rotation:p}),console.log(`[CanvaZip] Parsed position for ${a}:`,{position:o,scale:d,rotation:p})}console.log(`[CanvaZip] Successfully parsed ${e.size} assets from position data`)}else console.warn("[CanvaZip] Position data does not have layers array:",s);if(e.size===0&&typeof s=="object"&&!Array.isArray(s)){for(let[n,a]of Object.entries(s))if(a&&typeof a=="object"&&"layout"in a){let r=a.layout,o={x:0,y:0},l=1,c=0;if(r.position&&typeof r.position=="object"?o={x:r.position.x||0,y:r.position.y||0}:(typeof r.x=="number"||typeof r.y=="number")&&(o={x:r.x||0,y:r.y||0}),typeof r.scale=="number")l=r.scale;else if(typeof r.scaleX=="number"||typeof r.scaleY=="number"){let d=(t=r.scaleX)!=null?t:1,p=(i=r.scaleY)!=null?i:1;l=(d+p)/2}typeof r.rotation=="number"&&(c=r.rotation),e.set(n,{position:o,scale:l,rotation:c})}}return e}function cr(s,e){if(!s)return console.warn("[CanvaZip] No filename provided for matching"),null;if(e.size===0)return console.warn("[CanvaZip] Position map is empty, cannot match:",s),null;if(e.has(s))return console.log(`[CanvaZip] Exact match found for ${s}`),e.get(s);let t=s.replace(/\.png$/i,"").replace(/\.jpg$/i,"").replace(/\.jpeg$/i,"");if(e.has(t))return console.log(`[CanvaZip] Match found (without extension) for ${s} -> ${t}`),e.get(t);let i=t.toLowerCase();for(let[n,a]of e.entries()){let r=n.toLowerCase();if(r===i||r.includes(i)||i.includes(r))return console.log(`[CanvaZip] Partial match found for ${s} -> ${n}`),a}return console.warn(`[CanvaZip] No match found for ${s}. Available keys:`,Array.from(e.keys()).slice(0,5)),null}function gl(s){return s.replace(/^json\./,"").replace(/_/g," ").replace(/\b\w/g,e=>e.toUpperCase())}function dr(){let s=window.getEditableAssets;if(typeof s!="function")return console.warn("[CanvaZip] getEditableAssets not available"),[];let e=s();if(!(e!=null&&e.slots)||!Array.isArray(e.slots))return console.warn("[CanvaZip] No slots found in registry"),[];let t=[];for(let i of e.slots)i.assetType==="image"&&i.objectId&&t.push({id:i.objectId,name:i.displayName||gl(i.slotId||i.objectId),type:"sprite"});return t.sort((i,n)=>i.name.localeCompare(n.name))}var mt=require("pixi.js");ct();oi();ee();async function ur(s,e,t){var i,n;console.log("[LIBRARY] applyAssetChange called with:",e,t);try{let a=Date.now(),o=`/${`raw/library/${e}/${t}`}?t=${a}`;console.log("[LIBRARY] Loading texture from:",o);let l=await mt.Assets.load(o);if(!l){console.error("[LIBRARY] Failed to load texture:",o);return}let c=window.CustomAssets,d=Object.keys(c||{}).filter(u=>{let g=e.replace(/s$/,"");return u.startsWith(g)||u.includes(g)});for(let u of d)we[u]=l,console.log("[LIBRARY] \u2705 Updated AssetTextures."+u),(i=c[u])!=null&&i.texture&&(c[u].texture=l,console.log("[LIBRARY] \u2705 Updated CustomAssets."+u+".texture"));let p=window.gameObjectManager;if(p)for(let u of d){let g=p.get(u);if(g){let h=((n=g.getDisplayObject)==null?void 0:n.call(g))||g.pixiObject||g;h!=null&&h.texture&&(h.texture=l,console.log("[LIBRARY] \u2705 Applied to display object:",u))}}}catch(a){console.error("[LIBRARY] Error applying asset change:",a)}}async function gr(s,e){var t,i,n;console.log("[LIBRARY] resetAsset called for:",e);try{let a=window.getEditableAssets,r=typeof a=="function"?a():null,o=(t=r==null?void 0:r.slots)==null?void 0:t.find(m=>m.category===e),l=o==null?void 0:o.defaultAsset;if(!l){console.warn("[LIBRARY] Could not find default asset for:",e);return}let c=Date.now(),d=`/raw/${l}?t=${c}`;console.log("[LIBRARY] Loading default texture from:",d);let p=await mt.Assets.load(d);if(!p){console.error("[LIBRARY] Failed to load default texture:",d);return}let u=window.CustomAssets,g=e.replace(/s$/,""),h=Object.keys(u||{}).filter(m=>m.startsWith(g)||m.includes(g));for(let m of h)we[m]=p,console.log("[LIBRARY] \u2705 Reset AssetTextures."+m),(i=u[m])!=null&&i.texture&&(u[m].texture=p,console.log("[LIBRARY] \u2705 Reset CustomAssets."+m+" to default"));let f=window.gameObjectManager;if(f)for(let m of h){let b=f.get(m);if(b){let y=((n=b.getDisplayObject)==null?void 0:n.call(b))||b.pixiObject||b;y!=null&&y.texture&&(y.texture=p,console.log("[LIBRARY] \u2705 Reset display object:",m))}}}catch(a){console.error("[LIBRARY] Error resetting asset:",a)}}async function Zi(s,e,t,i){var n,a,r,o,l,c,d,p,u,g,h,f,m,b,y;console.log("[LIBRARY] applySlotAsset:",{objectId:e,assetFilename:t,category:i});try{let v=e.startsWith("json.")?e.replace("json.",""):e;console.log("[LIBRARY] Asset key:",v);let w=fr(v),T=Date.now(),I=`/raw/library/${i}/${t}?t=${T}`;console.log("[LIBRARY] Loading texture from:",I);let M=await mt.Assets.load(I);if(!M){console.error("[LIBRARY] Failed to load texture:",I);return}console.log("[LIBRARY] \u2705 Texture loaded"),we[v]=M,console.log("[LIBRARY] \u2705 Updated AssetTextures."+v);let L=window.CustomAssets;L!=null&&L[v]&&(L[v].texture=M,console.log("[LIBRARY] \u2705 Updated legacy CustomAssets."+v));let j=window.gameObjectManager;if(console.log("[LIBRARY] gameObjectManager exists?",!!j),j){let P=Array.from(((n=j.keys)==null?void 0:n.call(j))||[]).slice(0,10);console.log("[LIBRARY] Available gameObject keys (first 10):",P);let x=j.get(v);if(console.log("[LIBRARY] gameObject for "+v+"?",!!x),x){let S=((a=x.getDisplayObject)==null?void 0:a.call(x))||x.pixiObject||x.pixi||x,A=(r=S==null?void 0:S.constructor)==null?void 0:r.name;if(console.log("[LIBRARY] displayObject:",S),console.log("[LIBRARY] displayObject type:",A),console.log("[LIBRARY] has texture?",!!(S!=null&&S.texture)),S!=null&&S.texture)S.texture=M,console.log("[LIBRARY] \u2705 Applied to display object:",v);else if(A==="Text"){console.log("[LIBRARY] \u{1F504} Converting Text to Sprite...");let{Sprite:E}=await import("pixi.js"),C=S.parent,O=(l=(o=C==null?void 0:C.getChildIndex)==null?void 0:o.call(C,S))!=null?l:0,k={x:S.x,y:S.y},R={x:(d=(c=S.anchor)==null?void 0:c.x)!=null?d:.5,y:(u=(p=S.anchor)==null?void 0:p.y)!=null?u:.5},z={x:(h=(g=S.scale)==null?void 0:g.x)!=null?h:1,y:(m=(f=S.scale)==null?void 0:f.y)!=null?m:1},D=(b=S.alpha)!=null?b:1,U=(y=S.visible)!=null?y:!0,F=new E(M);F.anchor.set(R.x,R.y),F.position.set(k.x,k.y),F.scale.set(z.x,z.y),F.alpha=D,F.visible=U,C&&(C.removeChild(S),C.addChildAt(F,O),console.log("[LIBRARY] \u2705 Replaced Text with Sprite in parent")),x.pixiObject&&(x.pixiObject=F),x.pixi&&(x.pixi=F),console.log("[LIBRARY] \u2705 Text \u2192 Sprite conversion complete")}else if(S!=null&&S.children){let E=S.children.find(C=>C.texture);E?(E.texture=M,console.log("[LIBRARY] \u2705 Applied to child sprite")):console.warn("[LIBRARY] \u26A0\uFE0F No texture found in displayObject or children")}}}let _=`raw/library/${i}/${t}`;mr(v,_,M,w),window.dispatchEvent(new CustomEvent("scene-editor:asset-updated",{detail:{objectId:v,texture:M,assetPath:_}})),re({objectId:v,path:"render.asset.path",value:_}),console.log("[LIBRARY] \u2705 Staged config override for:",v,"path:",_)}catch(v){console.error("[LIBRARY] Error applying slot asset:",v)}}async function hr(s,e,t,i){var n;console.log("[LIBRARY] resetSlotAsset:",{objectId:e,defaultAsset:t,category:i});try{let a=e.startsWith("json.")?e.replace("json.",""):e,r=fr(a),o=Date.now(),l=`/raw/${t}?t=${o}`;console.log("[LIBRARY] Loading default texture from:",l);let c=await mt.Assets.load(l);if(!c){console.error("[LIBRARY] Failed to load default texture:",l);return}we[a]=c,console.log("[LIBRARY] \u2705 Reset AssetTextures."+a);let d=window.CustomAssets;d!=null&&d[a]&&(d[a].texture=c,console.log("[LIBRARY] \u2705 Reset CustomAssets."+a+" to default"));let p=window.gameObjectManager;if(p){let u=p.get(a);if(u){let g=((n=u.getDisplayObject)==null?void 0:n.call(u))||u.pixiObject||u;g!=null&&g.texture&&(g.texture=c,console.log("[LIBRARY] \u2705 Reset display object:",a))}}mr(a,t,c,r),window.dispatchEvent(new CustomEvent("scene-editor:asset-updated",{detail:{objectId:a,texture:c,assetPath:t}})),re({objectId:a,path:"render.asset.path",value:t}),console.log("[LIBRARY] \u2705 Reset config override for:",a)}catch(a){console.error("[LIBRARY] Error resetting slot asset:",a)}}function fr(s){var e,t,i;try{let n=window.getEditableObjectConfig,a=typeof n=="function"?n(s):null;return(i=(t=(e=a==null?void 0:a.render)==null?void 0:e.asset)==null?void 0:t.path)!=null?i:null}catch{return null}}function mr(s,e,t,i){if(e){try{let n=`${s}:${e}`;ce.set(n,t)}catch{}if(i&&i!==e)try{let n=ce.store;n!=null&&n.delete&&n.delete(`${s}:${i}`)}catch{}pr(e,t),i&&i!==e&&pr(i,null)}}function pr(s,e){if(!s)return;let t=mt.Assets.cache;if(!t)return;let i=s.replace(/^\.?\//,""),n=[i,`/${i}`];for(let a of n)typeof t.remove=="function"?t.remove(a):typeof t.delete=="function"&&t.delete(a),e&&typeof t.set=="function"&&t.set(a,e)}var Qi=class{constructor(){this.root=null;this.assets=[];this.positionMap=new Map;this.replaceableObjects=[];this.options=null;this.processedCount=0}render(){let e=this.assets.length,t=this.processedCount;return`
|
|
1394
|
+
Generate the requested asset matching the brand style.${r.needsTransparency?" Background MUST be solid magenta (#FF00FF).":""}
|
|
1395
|
+
`.trim()}function nr(r){return r.map(e=>{if(typeof e=="string"){let t=e,i,n;return t.includes("background")?(i="background",n="background"):t.includes("button")||t.includes("cta")?(i="ui",n="button"):t.includes("logo")?(i="ui",n="logo"):t.includes("title")||t.includes("subtitle")||t.includes("text")?(i="text",n="text"):t.includes("effect")||t.includes("confetti")||t.includes("particle")?(i="effects",n="effect"):t.includes("ui.")||t.includes("splash")||t.includes("endgame")?(i="ui",n="image"):(i="environment",n="interactive"),{id:t,category:i,type:n}}return e})}function ar(r,e){return!(r.includes("background")&&(r.includes("_1")||r.includes("splash")||r.includes("endgame")||r.includes("main"))||e==="text"||e==="effects"&&r.includes("particle"))}async function sr(r){var s,o;let e=nr(r.gameObjects),t={gamePrompt:r.gamePrompt,gameObjects:e,brandAssets:r.manifest.assets,brandDna:r.manifest.brand_dna,brandName:r.manifest.brand_name},i=tr(t),n=[];if(r.flatDesignDataUrl)try{let l=rr(r.flatDesignDataUrl);l&&l.base64&&l.mimeType?l.base64.length<100?console.warn("[Pipeline] Flat design data URL appears invalid (too short)"):(n.push(l),console.log("[Pipeline] Added flat design to analysis, size:",l.base64.length)):console.warn("[Pipeline] Failed to parse flat design data URL")}catch(l){console.warn("[Pipeline] Error processing flat design:",l)}console.log("[Pipeline] Running analysis chain with",n.length,"images...");let a;try{a=await Ji(r.apiKey,i,n,{model:"gemini-2.5-flash"}),console.log("[Pipeline] Analysis response received")}catch(l){throw console.error("[Pipeline] Gemini API error:",l),(s=l.message)!=null&&s.includes("Unable to process input image")?new Error("Gemini API unable to process the uploaded images. Please try with different images or ensure they are valid PNG/JPG files under 10MB."):(o=l.message)!=null&&o.includes("image")?new Error("Image processing failed. Please ensure your images are valid and not corrupted."):l}return pl(a,r.gameObjects)}function pl(r,e){try{let t=r,i=r.match(/```(?:json)?\s*([\s\S]*?)```/);if(i)t=i[1].trim();else{let a=r.match(/\{[\s\S]*\}/);a&&(t=a[0])}let n=JSON.parse(t);return n.mappings&&Array.isArray(n.mappings)?{mappingResult:n,rawResponse:r,parsed:!0}:{mappingResult:{mappings:e.map(a=>({game_object:a,action:"KEEP",status:"Analysis response missing mappings[]"}))},rawResponse:r,parsed:!1,parseError:"Missing mappings[] array"}}catch(t){return{mappingResult:{mappings:e.map(i=>({game_object:i,action:"KEEP",status:"Analysis response was not valid JSON"}))},rawResponse:r,parsed:!1,parseError:t!=null&&t.message?String(t.message):"JSON parse failed"}}}async function ga(r,e,t={}){var n;let i=e.mappings.filter(a=>a.action==="GENERATE");if(i.length===0){console.log("[Pipeline] No assets to generate");return}console.log(`[Pipeline] Generating ${i.length} assets...`);for(let a=0;a<i.length;a++){let s=i[a];(n=t.onProgress)==null||n.call(t,a+1,i.length,s.game_object);try{let o=await ul(r,s);s.output_dataUrl=o,s.status="Generated \u2713"}catch(o){console.error(`[Pipeline] Failed to generate ${s.game_object}:`,o),s.status="Failed \u2717"}}console.log("[Pipeline] Generation chain complete")}async function ul(r,e){if(!e.generation_prompt)throw new Error("No generation prompt provided");let t=[];if(e.reference_asset&&r.manifest){let o=r.manifest.assets.find(l=>l.id===e.reference_asset);if(o){let l=r.assetFiles.get(o.file);if(l){let c=await Fe(l);c&&t.push({base64:c.base64,mimeType:c.mimeType})}}}if(r.flatDesignDataUrl){let o=rr(r.flatDesignDataUrl);o&&t.push(o)}let i=ar(e.game_object),n={prompt:e.generation_prompt,hasReference:t.length>0,brandDna:r.manifest.brand_dna,needsTransparency:i},a=ir(n);console.log(`[Pipeline] Generating asset for ${e.game_object}... (transparency: ${i})`);let s=await ft(r.apiKey,a,t,{aspectRatio:"1:1",model:"gemini-2.5-flash-image"});return i&&await ht(s)||s}function rr(r){let[e,t]=r.split(","),i=e==null?void 0:e.match(/data:(.*?);base64/);return t&&i?{base64:t,mimeType:i[1]}:null}async function or(r,e){let t=r.assets,i=[];Array.isArray(t)?i=t:t&&typeof t=="object"?i=Object.entries(t).map(([n,a])=>({id:n,file:String(a),role:"visual element"})):i=[],r.assets=i;for(let n of i){let a=e.get(n.file);if(a){let s=await Fe(a);s&&(n.dataUrl=s.dataUrl)}}}function lr(r){var t,i;let e=new Map;if(!r)return console.warn("[CanvaZip] No position data provided"),e;if(typeof r=="string")try{r=JSON.parse(r)}catch(n){return console.error("[CanvaZip] Failed to parse position data JSON:",n),e}if(r!=null&&r.layers&&Array.isArray(r.layers)){console.log(`[CanvaZip] Parsing ${r.layers.length} layers from position data`);for(let n of r.layers){let a=n.asset;if(!a||!n.layout){console.warn("[CanvaZip] Skipping layer without asset or layout:",n);continue}let s=n.layout,o={x:typeof s.x=="number"?s.x:0,y:typeof s.y=="number"?s.y:0},l=typeof s.scaleX=="number"?s.scaleX:1,c=typeof s.scaleY=="number"?s.scaleY:1,d=(l+c)/2;d>1&&(d=d/13.33);let p=typeof s.rotation=="number"?s.rotation:0;e.set(a,{position:o,scale:d,rotation:p}),console.log(`[CanvaZip] Parsed position for ${a}:`,{position:o,scale:d,rotation:p})}console.log(`[CanvaZip] Successfully parsed ${e.size} assets from position data`)}else console.warn("[CanvaZip] Position data does not have layers array:",r);if(e.size===0&&typeof r=="object"&&!Array.isArray(r)){for(let[n,a]of Object.entries(r))if(a&&typeof a=="object"&&"layout"in a){let s=a.layout,o={x:0,y:0},l=1,c=0;if(s.position&&typeof s.position=="object"?o={x:s.position.x||0,y:s.position.y||0}:(typeof s.x=="number"||typeof s.y=="number")&&(o={x:s.x||0,y:s.y||0}),typeof s.scale=="number")l=s.scale;else if(typeof s.scaleX=="number"||typeof s.scaleY=="number"){let d=(t=s.scaleX)!=null?t:1,p=(i=s.scaleY)!=null?i:1;l=(d+p)/2}typeof s.rotation=="number"&&(c=s.rotation),e.set(n,{position:o,scale:l,rotation:c})}}return e}function cr(r,e){if(!r)return console.warn("[CanvaZip] No filename provided for matching"),null;if(e.size===0)return console.warn("[CanvaZip] Position map is empty, cannot match:",r),null;if(e.has(r))return console.log(`[CanvaZip] Exact match found for ${r}`),e.get(r);let t=r.replace(/\.png$/i,"").replace(/\.jpg$/i,"").replace(/\.jpeg$/i,"");if(e.has(t))return console.log(`[CanvaZip] Match found (without extension) for ${r} -> ${t}`),e.get(t);let i=t.toLowerCase();for(let[n,a]of e.entries()){let s=n.toLowerCase();if(s===i||s.includes(i)||i.includes(s))return console.log(`[CanvaZip] Partial match found for ${r} -> ${n}`),a}return console.warn(`[CanvaZip] No match found for ${r}. Available keys:`,Array.from(e.keys()).slice(0,5)),null}function gl(r){return r.replace(/^json\./,"").replace(/_/g," ").replace(/\b\w/g,e=>e.toUpperCase())}function dr(){let r=window.getEditableAssets;if(typeof r!="function")return console.warn("[CanvaZip] getEditableAssets not available"),[];let e=r();if(!(e!=null&&e.slots)||!Array.isArray(e.slots))return console.warn("[CanvaZip] No slots found in registry"),[];let t=[];for(let i of e.slots)i.assetType==="image"&&i.objectId&&t.push({id:i.objectId,name:i.displayName||gl(i.slotId||i.objectId),type:"sprite"});return t.sort((i,n)=>i.name.localeCompare(n.name))}var mt=require("pixi.js");ct();oi();ee();async function ur(r,e,t){var i,n;console.log("[LIBRARY] applyAssetChange called with:",e,t);try{let a=Date.now(),o=`/${`raw/library/${e}/${t}`}?t=${a}`;console.log("[LIBRARY] Loading texture from:",o);let l=await mt.Assets.load(o);if(!l){console.error("[LIBRARY] Failed to load texture:",o);return}let c=window.CustomAssets,d=Object.keys(c||{}).filter(u=>{let g=e.replace(/s$/,"");return u.startsWith(g)||u.includes(g)});for(let u of d)we[u]=l,console.log("[LIBRARY] \u2705 Updated AssetTextures."+u),(i=c[u])!=null&&i.texture&&(c[u].texture=l,console.log("[LIBRARY] \u2705 Updated CustomAssets."+u+".texture"));let p=window.gameObjectManager;if(p)for(let u of d){let g=p.get(u);if(g){let h=((n=g.getDisplayObject)==null?void 0:n.call(g))||g.pixiObject||g;h!=null&&h.texture&&(h.texture=l,console.log("[LIBRARY] \u2705 Applied to display object:",u))}}}catch(a){console.error("[LIBRARY] Error applying asset change:",a)}}async function gr(r,e){var t,i,n;console.log("[LIBRARY] resetAsset called for:",e);try{let a=window.getEditableAssets,s=typeof a=="function"?a():null,o=(t=s==null?void 0:s.slots)==null?void 0:t.find(m=>m.category===e),l=o==null?void 0:o.defaultAsset;if(!l){console.warn("[LIBRARY] Could not find default asset for:",e);return}let c=Date.now(),d=`/raw/${l}?t=${c}`;console.log("[LIBRARY] Loading default texture from:",d);let p=await mt.Assets.load(d);if(!p){console.error("[LIBRARY] Failed to load default texture:",d);return}let u=window.CustomAssets,g=e.replace(/s$/,""),h=Object.keys(u||{}).filter(m=>m.startsWith(g)||m.includes(g));for(let m of h)we[m]=p,console.log("[LIBRARY] \u2705 Reset AssetTextures."+m),(i=u[m])!=null&&i.texture&&(u[m].texture=p,console.log("[LIBRARY] \u2705 Reset CustomAssets."+m+" to default"));let f=window.gameObjectManager;if(f)for(let m of h){let b=f.get(m);if(b){let y=((n=b.getDisplayObject)==null?void 0:n.call(b))||b.pixiObject||b;y!=null&&y.texture&&(y.texture=p,console.log("[LIBRARY] \u2705 Reset display object:",m))}}}catch(a){console.error("[LIBRARY] Error resetting asset:",a)}}async function Zi(r,e,t,i){var n,a,s,o,l,c,d,p,u,g,h,f,m,b,y;console.log("[LIBRARY] applySlotAsset:",{objectId:e,assetFilename:t,category:i});try{let v=e.startsWith("json.")?e.replace("json.",""):e;console.log("[LIBRARY] Asset key:",v);let w=fr(v),T=Date.now(),I=`/raw/library/${i}/${t}?t=${T}`;console.log("[LIBRARY] Loading texture from:",I);let M=await mt.Assets.load(I);if(!M){console.error("[LIBRARY] Failed to load texture:",I);return}console.log("[LIBRARY] \u2705 Texture loaded"),we[v]=M,console.log("[LIBRARY] \u2705 Updated AssetTextures."+v);let L=window.CustomAssets;L!=null&&L[v]&&(L[v].texture=M,console.log("[LIBRARY] \u2705 Updated legacy CustomAssets."+v));let j=window.gameObjectManager;if(console.log("[LIBRARY] gameObjectManager exists?",!!j),j){let P=Array.from(((n=j.keys)==null?void 0:n.call(j))||[]).slice(0,10);console.log("[LIBRARY] Available gameObject keys (first 10):",P);let x=j.get(v);if(console.log("[LIBRARY] gameObject for "+v+"?",!!x),x){let S=((a=x.getDisplayObject)==null?void 0:a.call(x))||x.pixiObject||x.pixi||x,A=(s=S==null?void 0:S.constructor)==null?void 0:s.name;if(console.log("[LIBRARY] displayObject:",S),console.log("[LIBRARY] displayObject type:",A),console.log("[LIBRARY] has texture?",!!(S!=null&&S.texture)),S!=null&&S.texture)S.texture=M,console.log("[LIBRARY] \u2705 Applied to display object:",v);else if(A==="Text"){console.log("[LIBRARY] \u{1F504} Converting Text to Sprite...");let{Sprite:E}=await import("pixi.js"),C=S.parent,O=(l=(o=C==null?void 0:C.getChildIndex)==null?void 0:o.call(C,S))!=null?l:0,k={x:S.x,y:S.y},R={x:(d=(c=S.anchor)==null?void 0:c.x)!=null?d:.5,y:(u=(p=S.anchor)==null?void 0:p.y)!=null?u:.5},z={x:(h=(g=S.scale)==null?void 0:g.x)!=null?h:1,y:(m=(f=S.scale)==null?void 0:f.y)!=null?m:1},D=(b=S.alpha)!=null?b:1,U=(y=S.visible)!=null?y:!0,F=new E(M);F.anchor.set(R.x,R.y),F.position.set(k.x,k.y),F.scale.set(z.x,z.y),F.alpha=D,F.visible=U,C&&(C.removeChild(S),C.addChildAt(F,O),console.log("[LIBRARY] \u2705 Replaced Text with Sprite in parent")),x.pixiObject&&(x.pixiObject=F),x.pixi&&(x.pixi=F),console.log("[LIBRARY] \u2705 Text \u2192 Sprite conversion complete")}else if(S!=null&&S.children){let E=S.children.find(C=>C.texture);E?(E.texture=M,console.log("[LIBRARY] \u2705 Applied to child sprite")):console.warn("[LIBRARY] \u26A0\uFE0F No texture found in displayObject or children")}}}let _=`raw/library/${i}/${t}`;mr(v,_,M,w),window.dispatchEvent(new CustomEvent("scene-editor:asset-updated",{detail:{objectId:v,texture:M,assetPath:_}})),re({objectId:v,path:"render.asset.path",value:_}),console.log("[LIBRARY] \u2705 Staged config override for:",v,"path:",_)}catch(v){console.error("[LIBRARY] Error applying slot asset:",v)}}async function hr(r,e,t,i){var n;console.log("[LIBRARY] resetSlotAsset:",{objectId:e,defaultAsset:t,category:i});try{let a=e.startsWith("json.")?e.replace("json.",""):e,s=fr(a),o=Date.now(),l=`/raw/${t}?t=${o}`;console.log("[LIBRARY] Loading default texture from:",l);let c=await mt.Assets.load(l);if(!c){console.error("[LIBRARY] Failed to load default texture:",l);return}we[a]=c,console.log("[LIBRARY] \u2705 Reset AssetTextures."+a);let d=window.CustomAssets;d!=null&&d[a]&&(d[a].texture=c,console.log("[LIBRARY] \u2705 Reset CustomAssets."+a+" to default"));let p=window.gameObjectManager;if(p){let u=p.get(a);if(u){let g=((n=u.getDisplayObject)==null?void 0:n.call(u))||u.pixiObject||u;g!=null&&g.texture&&(g.texture=c,console.log("[LIBRARY] \u2705 Reset display object:",a))}}mr(a,t,c,s),window.dispatchEvent(new CustomEvent("scene-editor:asset-updated",{detail:{objectId:a,texture:c,assetPath:t}})),re({objectId:a,path:"render.asset.path",value:t}),console.log("[LIBRARY] \u2705 Reset config override for:",a)}catch(a){console.error("[LIBRARY] Error resetting slot asset:",a)}}function fr(r){var e,t,i;try{let n=window.getEditableObjectConfig,a=typeof n=="function"?n(r):null;return(i=(t=(e=a==null?void 0:a.render)==null?void 0:e.asset)==null?void 0:t.path)!=null?i:null}catch{return null}}function mr(r,e,t,i){if(e){try{let n=`${r}:${e}`;ce.set(n,t)}catch{}if(i&&i!==e)try{let n=ce.store;n!=null&&n.delete&&n.delete(`${r}:${i}`)}catch{}pr(e,t),i&&i!==e&&pr(i,null)}}function pr(r,e){if(!r)return;let t=mt.Assets.cache;if(!t)return;let i=r.replace(/^\.?\//,""),n=[i,`/${i}`];for(let a of n)typeof t.remove=="function"?t.remove(a):typeof t.delete=="function"&&t.delete(a),e&&typeof t.set=="function"&&t.set(a,e)}var Qi=class{constructor(){this.root=null;this.assets=[];this.positionMap=new Map;this.replaceableObjects=[];this.options=null;this.processedCount=0}render(){let e=this.assets.length,t=this.processedCount;return`
|
|
1394
1396
|
<div class="canva-wizard-overlay" data-canva-wizard>
|
|
1395
1397
|
<div class="canva-wizard-modal">
|
|
1396
1398
|
<div class="canva-wizard-header">
|
|
@@ -1428,7 +1430,7 @@ Generate the requested asset matching the brand style.${s.needsTransparency?" Ba
|
|
|
1428
1430
|
</div>
|
|
1429
1431
|
</div>
|
|
1430
1432
|
</div>
|
|
1431
|
-
`}renderAssetCard(e,t){let n=e.position&&e.scale?`x: ${e.position.x.toFixed(0)}, y: ${e.position.y.toFixed(0)}, scale: ${e.scale.toFixed(2)}`:"No position data",a=e.action==="add"||e.action==="replace"?"active":"",
|
|
1433
|
+
`}renderAssetCard(e,t){let n=e.position&&e.scale?`x: ${e.position.x.toFixed(0)}, y: ${e.position.y.toFixed(0)}, scale: ${e.scale.toFixed(2)}`:"No position data",a=e.action==="add"||e.action==="replace"?"active":"",s=e.action==="replace"?this.renderReplaceDropdown(e,t):"",o=e.action==="add"?this.renderAddToSceneFields(e,t):"";return`
|
|
1432
1434
|
<div class="canva-asset-card ${a}" data-asset-index="${t}">
|
|
1433
1435
|
<div class="canva-asset-preview">
|
|
1434
1436
|
<img src="${e.dataUrl}" alt="${e.filename}" />
|
|
@@ -1466,7 +1468,7 @@ Generate the requested asset matching the brand style.${s.needsTransparency?" Ba
|
|
|
1466
1468
|
</button>
|
|
1467
1469
|
</div>
|
|
1468
1470
|
${o}
|
|
1469
|
-
${
|
|
1471
|
+
${s}
|
|
1470
1472
|
</div>
|
|
1471
1473
|
`}renderAddToSceneFields(e,t){return`
|
|
1472
1474
|
<div class="canva-asset-add-scene" data-asset-add-scene="${t}">
|
|
@@ -1496,8 +1498,8 @@ Generate the requested asset matching the brand style.${s.needsTransparency?" Ba
|
|
|
1496
1498
|
${this.replaceableObjects.map(i=>`<option value="${i.id}" ${e.targetObjectId===i.id?"selected":""}>${i.name}</option>`).join("")}
|
|
1497
1499
|
</select>
|
|
1498
1500
|
</div>
|
|
1499
|
-
`}initialize(e,t,i,n){this.options=n,this.positionMap=lr(i),this.replaceableObjects=dr(),this.assets=t.map(a=>{let
|
|
1500
|
-
`))||(n==null?void 0:n.error)||"Batch create failed.";throw new Error(
|
|
1501
|
+
`}initialize(e,t,i,n){this.options=n,this.positionMap=lr(i),this.replaceableObjects=dr(),this.assets=t.map(a=>{let s=cr(a.filename,this.positionMap);return{filename:a.filename,dataUrl:a.dataUrl,category:this.inferCategory(a.filename),position:s==null?void 0:s.position,scale:s==null?void 0:s.scale,rotation:s==null?void 0:s.rotation,action:void 0,targetObjectId:void 0}}),e.innerHTML=this.render(),this.root=e.querySelector("[data-canva-wizard]"),this.attachEventListeners()}attachEventListeners(){var e,t,i;this.root&&((e=this.root.querySelector("[data-canva-wizard-close]"))==null||e.addEventListener("click",()=>{this.close()}),(t=this.root.querySelector("[data-canva-wizard-cancel]"))==null||t.addEventListener("click",()=>{this.close()}),(i=this.root.querySelector("[data-canva-wizard-apply-all]"))==null||i.addEventListener("click",()=>{this.applyAll()}),this.root.querySelectorAll("[data-asset-action]").forEach(n=>{n.addEventListener("click",a=>{let s=a.target,o=parseInt(s.getAttribute("data-asset-action")||"0"),l=s.getAttribute("data-action");this.handleAction(o,l)})}),this.root.querySelectorAll("[data-asset-category]").forEach(n=>{n.addEventListener("change",a=>{let s=a.target,o=parseInt(s.getAttribute("data-asset-category")||"0"),l=s.value;this.assets[o]&&(this.assets[o].category=l)})}),this.root.querySelectorAll("[data-asset-target]").forEach(n=>{n.addEventListener("change",a=>{let s=a.target,o=parseInt(s.getAttribute("data-asset-target")||"0"),l=s.value;this.assets[o]&&(this.assets[o].targetObjectId=l)})}),this.root.querySelectorAll("[data-asset-screen]").forEach(n=>{n.addEventListener("change",a=>{let s=a.target,o=parseInt(s.getAttribute("data-asset-screen")||"0"),l=s.value;this.assets[o]&&(this.assets[o].screen=l)})}),this.root.querySelectorAll("[data-asset-type]").forEach(n=>{n.addEventListener("change",a=>{let s=a.target,o=parseInt(s.getAttribute("data-asset-type")||"0"),l=s.value;this.assets[o]&&(this.assets[o].objectType=l)})}),this.root.addEventListener("click",n=>{n.target===this.root&&this.close()}))}handleAction(e,t){this.assets[e]&&(this.assets[e].action=t,t==="add"&&(this.assets[e].screen||(this.assets[e].screen="gameplay"),this.assets[e].objectType||(this.assets[e].objectType="sprite")),t==="replace"?this.updateAssetCard(e):(this.assets[e].targetObjectId=void 0,this.updateAssetCard(e)))}updateAssetCard(e){var i,n,a,s;if(!this.root)return;let t=this.root.querySelector(`[data-asset-index="${e}"]`);if(t&&this.assets[e]){let o=this.assets[e],l=this.renderAssetCard(o,e);t.outerHTML=l;let c=this.root.querySelector(`[data-asset-index="${e}"]`);c&&(c.querySelectorAll("[data-asset-action]").forEach(d=>{d.addEventListener("click",p=>{let u=p.target,g=parseInt(u.getAttribute("data-asset-action")||"0"),h=u.getAttribute("data-action");this.handleAction(g,h)})}),(i=c.querySelector("[data-asset-category]"))==null||i.addEventListener("change",d=>{let u=d.target.value;this.assets[e]&&(this.assets[e].category=u)}),(n=c.querySelector("[data-asset-target]"))==null||n.addEventListener("change",d=>{let u=d.target.value;this.assets[e]&&(this.assets[e].targetObjectId=u)}),(a=c.querySelector("[data-asset-screen]"))==null||a.addEventListener("change",d=>{let u=d.target.value;this.assets[e]&&(this.assets[e].screen=u)}),(s=c.querySelector("[data-asset-type]"))==null||s.addEventListener("change",d=>{let u=d.target.value;this.assets[e]&&(this.assets[e].objectType=u)}))}}async applyAll(){if(!this.options)return;for(let i of this.assets)i.action||(i.action="skip");this.processedCount=0,this.updateProgress();let e=[],t=[];for(let i=0;i<this.assets.length;i++){let n=this.assets[i];try{let a=await this.saveAssetToLibrary(n);n.libraryPath=a,n.action==="add"?e.push(n):n.action==="replace"&&n.targetObjectId&&t.push({asset:n,targetId:n.targetObjectId}),this.processedCount++,this.updateProgress()}catch(a){console.error(`[CanvaZip] Failed to save ${n.filename} to library:`,a)}}if(e.length>0)try{await this.batchAddToScene(e)}catch(i){console.error("[CanvaZip] Batch add to scene failed:",i)}if(t.length>0)for(let{asset:i,targetId:n}of t)try{await this.replaceObject(i,n)}catch(a){console.error(`[CanvaZip] Replace failed for ${n}:`,a)}await this.syncScreens(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"batch"}})),this.options.onComplete&&this.options.onComplete(this.assets),this.close()}async batchAddToScene(e){var a;let t=e.map(s=>{let o=s.filename.replace(/\.(png|jpg|jpeg)$/i,"").replace(/[^a-zA-Z0-9._-]/g,"_").toLowerCase(),l=`json.${o}`,c={identity:{id:l,category:s.category||"environment"},transform:{position:s.position||{x:0,y:0},offset:{x:0,y:0},scale:.3,rotation:s.rotation||0,anchor:{x:.5,y:.5},position_ratio:null,position_mode:"static"},render:{alpha:1,visible:!0,tint:null,z_index:0,asset:{type:"image",path:s.libraryPath}},instance_id:o,object_config:l};return{screenId:s.screen,instanceId:o,objectConfigId:l,layer:s.objectType==="ui-image"?"ui":"world",config:c}}),i=await fetch("/api/objects/batch-create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({objects:t})}),n=await i.json().catch(()=>({}));if(!i.ok||(n==null?void 0:n.success)===!1){let s=((a=n==null?void 0:n.errors)==null?void 0:a.join(`
|
|
1502
|
+
`))||(n==null?void 0:n.error)||"Batch create failed.";throw new Error(s)}try{let{trackObjectCreation:s}=await Promise.resolve().then(()=>(ee(),Ne));for(let o of t)s(o.instanceId,o.screenId,o.config)}catch(s){console.warn("[CanvaZip] Failed to track batch creation in history:",s)}console.log(`[CanvaZip] \u2705 Batch added ${e.length} objects to scene`)}async saveAssetToLibrary(e){try{let i=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:e.category,filename:e.filename,data:e.dataUrl,overwrite:!0})})).json();if(i.success&&i.path)return console.log(`[CanvaZip] \u2705 Saved ${e.filename} to library: ${i.path}`),i.path;throw new Error(i.error||"Failed to save to library")}catch(t){throw console.error(`[CanvaZip] Failed to save ${e.filename} to library:`,t),t}}async syncScreens(){try{let e=window.__HANDLER_ACTIVE_SCREEN,t=await fetch("/api/sync-screens",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({force:!0,screenId:e})});if(!t.ok){let i=await t.json().catch(()=>({}));throw new Error((i==null?void 0:i.error)||"Failed to sync screens")}}catch(e){console.warn("[CanvaZip] Screen sync failed:",e)}}async replaceObject(e,t){let i=window.__debugContext;if(!i){console.warn("[CanvaZip] No debug context available for replace");return}try{await Zi(i,t,e.filename,e.category),console.log(`[CanvaZip] \u2705 Replaced ${t} with ${e.filename}`)}catch(n){throw console.error(`[CanvaZip] Failed to replace ${t}:`,n),n}}updateProgress(){if(!this.root)return;let e=this.root.querySelector(".canva-wizard-progress-fill"),t=this.root.querySelector(".canva-wizard-progress-text");if(e){let i=this.processedCount/this.assets.length*100;e.style.width=`${i}%`}t&&(t.textContent=`${this.processedCount} of ${this.assets.length} assets processed`)}inferCategory(e){let t=e.toLowerCase();return t.includes("background")||t.includes("bg")?"backgrounds":t.includes("ui")||t.includes("button")||t.includes("cta")||t.includes("logo")||t.includes("text")?"ui":t.includes("sparkle")||t.includes("effect")||t.includes("particle")?"effects":t.includes("bottle")||t.includes("product")||t.includes("item")?"products":"environment"}close(){var e;(e=this.options)!=null&&e.onCancel&&this.options.onCancel(),this.root&&this.root.remove()}};var en=class{constructor(){this.root=null;this.currentTab="upload";this.uploadMethod="individual";this.uploadedJsons=new Map;this.normalizedManifest=null;this.flatDesignDataUrl=null;this.assetFiles=new Map;this.zipFile=null;this.wizardProcessedAssets=new Set;this.mappingResult=null;this.analysisRawResponse=null;this.analysisParsedOk=null;this.analysisParseError=null;this.isAnalyzing=!1;this.isGenerating=!1}get manifest(){return this.normalizedManifest}render(){return`
|
|
1501
1503
|
<div class="scene-panel brand-vision-panel panel-accent-violet" data-panel="brand-vision">
|
|
1502
1504
|
<div class="scene-panel-header" data-panel-handle>
|
|
1503
1505
|
<div class="panel-title">
|
|
@@ -1627,15 +1629,15 @@ Generate the requested asset matching the brand style.${s.needsTransparency?" Ba
|
|
|
1627
1629
|
</div>
|
|
1628
1630
|
<div class="panel-resize-handle" data-panel-resize></div>
|
|
1629
1631
|
</div>
|
|
1630
|
-
`}initialize(e,t){this.root=e.querySelector('[data-panel="brand-vision"]'),this.onClose=t,this.root&&(this.attachEventListeners(),this.setupResizeHandle())}attachEventListeners(){var t,i,n,a,r,o,l,c,d,p,u,g,h,f;if(!this.root)return;(t=this.root.querySelector("[data-panel-close]"))==null||t.addEventListener("click",()=>{if(this.onClose)this.onClose();else{let m="/dashboard";window.location.pathname!==m&&(window.location.href=m)}}),this.root.querySelectorAll("[data-vision-tab]").forEach(m=>{m.addEventListener("click",()=>{let b=m.dataset.visionTab;this.switchTab(b)})}),(i=this.root.querySelector("[data-vision-upload-method]"))==null||i.addEventListener("change",m=>{let b=m.target.value;this.switchUploadMethod(b)}),(n=this.root.querySelector("[data-vision-upload-manifest]"))==null||n.addEventListener("click",()=>{var m,b;(b=(m=this.root)==null?void 0:m.querySelector("[data-vision-manifest-input]"))==null||b.click()}),(a=this.root.querySelector("[data-vision-upload-batch-png]"))==null||a.addEventListener("click",()=>{var m,b;(b=(m=this.root)==null?void 0:m.querySelector("[data-vision-batch-png-input]"))==null||b.click()}),(r=this.root.querySelector("[data-vision-batch-png-input]"))==null||r.addEventListener("change",m=>{this.handleBatchPNGUpload(m)}),(o=this.root.querySelector("[data-vision-upload-zip]"))==null||o.addEventListener("click",()=>{var m,b;(b=(m=this.root)==null?void 0:m.querySelector("[data-vision-zip-input]"))==null||b.click()}),(l=this.root.querySelector("[data-vision-zip-input]"))==null||l.addEventListener("change",m=>{this.handleZipUpload(m)}),(c=this.root.querySelector("[data-vision-manifest-input]"))==null||c.addEventListener("change",m=>{this.handleManifestUpload(m)}),(d=this.root.querySelector("[data-vision-upload-assets]"))==null||d.addEventListener("click",()=>{var m,b;(b=(m=this.root)==null?void 0:m.querySelector("[data-vision-assets-input]"))==null||b.click()}),(p=this.root.querySelector("[data-vision-assets-input]"))==null||p.addEventListener("change",m=>{this.handleAssetsUpload(m)}),(u=this.root.querySelector("[data-vision-upload-flat]"))==null||u.addEventListener("click",()=>{var m,b;(b=(m=this.root)==null?void 0:m.querySelector("[data-vision-flat-input]"))==null||b.click()}),(g=this.root.querySelector("[data-vision-flat-input]"))==null||g.addEventListener("change",m=>{this.handleFlatDesignUpload(m)}),(h=this.root.querySelector("[data-vision-generate-all]"))==null||h.addEventListener("click",()=>{this.generateAllMissing()}),(f=this.root.querySelector("[data-vision-apply-all]"))==null||f.addEventListener("click",()=>{this.applyAll()});let e=this.root.querySelector("[data-vision-mappings]");e==null||e.addEventListener("click",m=>{let b=m.target;if(!b)return;let y=b.closest("[data-mapping-item]"),v=y==null?void 0:y.dataset.mappingItem;v&&(b.closest("[data-mapping-apply-one]")&&this.applyOne(v),b.closest("[data-mapping-save-one]")&&this.saveAndApplyOne(v),b.closest("[data-mapping-edit-one]")&&this.openEditorForOne(v),b.closest("[data-mapping-generate-one]")&&this.generateOne(v),b.closest("[data-mapping-copy-raw]")&&this.copyRawAnalysis())}),e==null||e.addEventListener("change",m=>{let b=m.target;if(!b||!this.mappingResult)return;let y=b.closest("[data-mapping-item]"),v=y==null?void 0:y.dataset.mappingItem;if(!v)return;let w=this.mappingResult.mappings.find(T=>T.game_object===v);w&&(b.matches("[data-mapping-action]")&&(w.action=String(b.value||"KEEP"),w.status="Edited",this.renderMappings()),b.matches("[data-mapping-brand-asset]")&&(w.brand_asset=String(b.value||""),w.status="Edited",this.renderMappings()))}),e==null||e.addEventListener("input",m=>{let b=m.target;if(!b||!this.mappingResult||!b.matches("[data-mapping-prompt]"))return;let y=b.closest("[data-mapping-item]"),v=y==null?void 0:y.dataset.mappingItem;if(!v)return;let w=this.mappingResult.mappings.find(T=>T.game_object===v);w&&(w.generation_prompt=String(b.value||""),w.status="Edited")})}switchTab(e){var t,i;this.root&&(this.currentTab=e,this.root.querySelectorAll("[data-vision-tab]").forEach(n=>n.classList.remove("active")),this.root.querySelectorAll("[data-vision-content]").forEach(n=>n.classList.remove("active")),(t=this.root.querySelector(`[data-vision-tab="${e}"]`))==null||t.classList.add("active"),(i=this.root.querySelector(`[data-vision-content="${e}"]`))==null||i.classList.add("active"))}switchUploadMethod(e){var t;this.root&&(this.uploadMethod=e,this.root.querySelectorAll("[data-vision-upload-section]").forEach(i=>{i.classList.remove("active")}),(t=this.root.querySelector(`[data-vision-upload-section="${e}"]`))==null||t.classList.add("active"))}async handleBatchPNGUpload(e){var r;let t=e.target,i=Array.from(t.files||[]);if(i.length===0)return;let n=i.filter(o=>o.type.startsWith("image/"));if(n.length===0){this.setStatus("upload","\u26A0\uFE0F No image files selected");return}let a=(r=this.root)==null?void 0:r.querySelector("[data-vision-batch-png-status]");a&&(a.textContent=`Processing ${n.length} PNG${n.length>1?"s":""}...`);try{let o=window.__HANDLER_ACTIVE_SCREEN,l=o==="loading"||o==="start"||o==="gameplay"||o==="tutorial"||o==="endgame"?o:"gameplay",c=[];for(let g=0;g<n.length;g++){let h=n[g];try{let f=await this.fileToDataUrl(h);if(!f){c.push({success:!1,filename:h.name,error:"Failed to read file"});continue}let m=h.name.replace(/\.[^/.]+$/,""),b=this.inferCategoryFromFilename(m),y=m.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"").toLowerCase(),v=`${y}_${Date.now()}${g>0?`_${g}`:""}`,w=`json.${v}`,T=`${y}.png`,M=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:b,filename:T,data:f,overwrite:!1})})).json();if(!M.success){c.push({success:!1,filename:h.name,error:M.error});continue}let L={identity:{id:w,category:b},transform:{anchor:"center",position:{x:0,y:0},scale:1,rotation:0},render:{z_index:0,alpha:1,visible:!0,anchor:{x:.5,y:.5},asset:{type:"image",path:M.path||`raw/library/${b}/${T}`}}},j=await fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:l,instanceId:v,objectConfigId:w,config:L,layer:b==="ui"?"ui":"world"})}),_=await j.json();j.ok&&_.success?c.push({success:!0,filename:h.name}):c.push({success:!1,filename:h.name,error:_.error})}catch(f){c.push({success:!1,filename:h.name,error:f instanceof Error?f.message:String(f)})}}let d=c.filter(g=>g.success).length,p=c.length-d;a&&(p===0?a.textContent=`\u2705 Added ${d} PNG${d>1?"s":""} to scene`:a.textContent=`\u26A0\uFE0F Added ${d}, failed ${p}`),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh"));let u=window.refreshAssetLibrary;typeof u=="function"&&u(),t.value=""}catch(o){a&&(a.textContent=`\u274C Error: ${o instanceof Error?o.message:String(o)}`),console.error("[BrandVision] Batch PNG upload failed:",o)}}inferCategoryFromFilename(e){let t=e.toLowerCase();return t.startsWith("ui_")||t.includes("button")||t.includes("label")?"ui":t.startsWith("bg_")||t.includes("background")?"backgrounds":t.includes("character")||t.includes("player")?"character":"environment"}fileToDataUrl(e){return new Promise(t=>{let i=new FileReader;i.onload=()=>t(i.result),i.onerror=()=>t(null),i.readAsDataURL(e)})}async handleZipUpload(e){var n;let i=(n=e.target.files)==null?void 0:n[0];if(i){this.zipFile=i,this.setStatus("zip",`Selected: ${i.name} (${(i.size/1024/1024).toFixed(2)} MB)`);try{await this.processZipFile(i)}catch(a){console.error("[BrandVision] ZIP processing failed:",a),this.setStatus("zip",`Error: ${a instanceof Error?a.message:"Unknown error"}`)}}}async processZipFile(e){var l;let t=null;if(typeof window!="undefined"&&window.JSZip)t=window.JSZip,console.log("[BrandVision] \u2705 Found window.JSZip");else try{let c=await import("jszip");t=c.default||c,console.log("[BrandVision] \u2705 Loaded JSZip via dynamic import")}catch(c){throw new Error(`JSZip is not properly imported. Make sure jszip is loaded globally (window.JSZip) or available as a module: ${(c==null?void 0:c.message)||"Unknown error"}`)}if(!t||typeof t.loadAsync!="function")throw new Error("JSZip is not properly imported - loadAsync method not found");let i=await t.loadAsync(e),n=[],a=[];i.forEach((c,d)=>{let p=c.toLowerCase();p.endsWith(".json")?n.push({name:c,content:null}):p.startsWith("assets/")&&p.endsWith(".png")&&a.push({name:c,file:d})});for(let c of n)try{let d=await((l=i.file(c.name))==null?void 0:l.async("text"));d&&(c.content=JSON.parse(d))}catch(d){console.warn(`Failed to parse ${c.name}:`,d)}let r=[];for(let c of a)try{let d=await c.file.async("uint8array"),p=new Blob([d],{type:"image/png"}),u=c.name.split("/").pop()||c.name;console.log(`Processing ${u}, uint8array length: ${d.length}, blob size: ${p.size}`);let g;try{g=await this.blobToDataUrl(p)}catch(h){console.warn(`FileReader failed for ${u}, using fallback:`,h),g=`data:image/png;base64,${btoa(String.fromCharCode.apply(null,Array.from(d)))}`}if(!g.startsWith("data:image/png;base64,")){console.warn(`Invalid data URL format for ${u}:`,g.substring(0,100));continue}r.push({filename:u,dataUrl:g})}catch(d){console.warn(`Failed to extract ${c.name}:`,d)}let o=null;for(let c of n){let d=c.name.toLowerCase();if(d.includes("positionnormalizedpack")||d.includes("positionnormalized")){o=c.content,console.log(`[BrandVision] Found position data file: ${c.name}`,{hasContent:!!o,isString:typeof o=="string",isObject:typeof o=="object",hasLayers:o!=null&&o.layers?o.layers.length:0});break}}if(o||console.warn("[BrandVision] No positionnormalizedpack.json found in ZIP. Available JSON files:",n.map(c=>c.name)),r.length>0){await this.showCanvaZipWizard(r,o),this.setStatus("zip",`\u2705 Wizard completed - ${r.length} assets processed`);return}else{this.setStatus("zip","\u26A0\uFE0F No PNG files found in ZIP");return}}async showCanvaZipWizard(e,t){return new Promise(i=>{let n=e.filter(o=>!this.wizardProcessedAssets.has(o.filename));if(n.length===0){console.log("[BrandVision] All assets already processed by wizard"),i();return}let a=document.createElement("div");document.body.appendChild(a),new Qi().initialize(a,n,t,{onComplete:o=>{console.log("[BrandVision] Wizard completed, processed assets:",o),o.forEach(l=>{this.wizardProcessedAssets.add(l.filename)}),a.remove(),i()},onCancel:()=>{console.log("[BrandVision] Wizard cancelled"),a.remove(),i()}})})}async blobToDataUrl(e){return new Promise((t,i)=>{let n=new FileReader;n.onload=()=>{let a=n.result;console.log("FileReader result type:",typeof a,"length:",a.length),console.log("Data URL prefix:",a.substring(0,30)),t(a)},n.onerror=a=>{console.error("FileReader error:",a),i(a)},n.readAsDataURL(e)})}inferAssetCategory(e){let t=e.toLowerCase();return t.includes("background")||t.includes("bg")?"backgrounds":t.includes("ui")||t.includes("button")||t.includes("cta")||t.includes("logo")||t.includes("text")?"ui":t.includes("sparkle")||t.includes("effect")||t.includes("particle")?"effects":t.includes("bottle")||t.includes("product")||t.includes("item")?"products":"misc"}addAssetsToRegistry(e){let t=window.getEditableAssets;if(typeof t!="function")return;let i=t();if(!(i!=null&&i.libraryAssets))return;let n={};for(let a of e){let r=a.category||"misc";n[r]||(n[r]=[]),i.libraryAssets[r]||(i.libraryAssets[r]=[]),i.libraryAssets[r].some(l=>l.filename===a.filename)||(i.libraryAssets[r].unshift({filename:a.filename,displayName:a.id.replace(/_/g," ").replace(/\b\w/g,l=>l.toUpperCase())}),console.log(`[BrandVision] Added ${a.filename} to registry category ${r}`))}}refreshLibrary(){let e=window.refreshAssetLibrary;typeof e=="function"&&e();let t=window.reRenderAssetLibrary;typeof t=="function"&&t()}async handleManifestUpload(e){var r;let t=e.target,i=t.files;if(!i||i.length===0)return;this.uploadedJsons.clear(),this.normalizedManifest=null,this.mappingResult=null;let n="";for(let o of Array.from(i))try{let l=await o.text(),c=JSON.parse(l);this.uploadedJsons.set(o.name,c),c.layers?n+=`\u2705 Layers: ${o.name}
|
|
1632
|
+
`}initialize(e,t){this.root=e.querySelector('[data-panel="brand-vision"]'),this.onClose=t,this.root&&(this.attachEventListeners(),this.setupResizeHandle())}attachEventListeners(){var t,i,n,a,s,o,l,c,d,p,u,g,h,f;if(!this.root)return;(t=this.root.querySelector("[data-panel-close]"))==null||t.addEventListener("click",()=>{if(this.onClose)this.onClose();else{let m="/dashboard";window.location.pathname!==m&&(window.location.href=m)}}),this.root.querySelectorAll("[data-vision-tab]").forEach(m=>{m.addEventListener("click",()=>{let b=m.dataset.visionTab;this.switchTab(b)})}),(i=this.root.querySelector("[data-vision-upload-method]"))==null||i.addEventListener("change",m=>{let b=m.target.value;this.switchUploadMethod(b)}),(n=this.root.querySelector("[data-vision-upload-manifest]"))==null||n.addEventListener("click",()=>{var m,b;(b=(m=this.root)==null?void 0:m.querySelector("[data-vision-manifest-input]"))==null||b.click()}),(a=this.root.querySelector("[data-vision-upload-batch-png]"))==null||a.addEventListener("click",()=>{var m,b;(b=(m=this.root)==null?void 0:m.querySelector("[data-vision-batch-png-input]"))==null||b.click()}),(s=this.root.querySelector("[data-vision-batch-png-input]"))==null||s.addEventListener("change",m=>{this.handleBatchPNGUpload(m)}),(o=this.root.querySelector("[data-vision-upload-zip]"))==null||o.addEventListener("click",()=>{var m,b;(b=(m=this.root)==null?void 0:m.querySelector("[data-vision-zip-input]"))==null||b.click()}),(l=this.root.querySelector("[data-vision-zip-input]"))==null||l.addEventListener("change",m=>{this.handleZipUpload(m)}),(c=this.root.querySelector("[data-vision-manifest-input]"))==null||c.addEventListener("change",m=>{this.handleManifestUpload(m)}),(d=this.root.querySelector("[data-vision-upload-assets]"))==null||d.addEventListener("click",()=>{var m,b;(b=(m=this.root)==null?void 0:m.querySelector("[data-vision-assets-input]"))==null||b.click()}),(p=this.root.querySelector("[data-vision-assets-input]"))==null||p.addEventListener("change",m=>{this.handleAssetsUpload(m)}),(u=this.root.querySelector("[data-vision-upload-flat]"))==null||u.addEventListener("click",()=>{var m,b;(b=(m=this.root)==null?void 0:m.querySelector("[data-vision-flat-input]"))==null||b.click()}),(g=this.root.querySelector("[data-vision-flat-input]"))==null||g.addEventListener("change",m=>{this.handleFlatDesignUpload(m)}),(h=this.root.querySelector("[data-vision-generate-all]"))==null||h.addEventListener("click",()=>{this.generateAllMissing()}),(f=this.root.querySelector("[data-vision-apply-all]"))==null||f.addEventListener("click",()=>{this.applyAll()});let e=this.root.querySelector("[data-vision-mappings]");e==null||e.addEventListener("click",m=>{let b=m.target;if(!b)return;let y=b.closest("[data-mapping-item]"),v=y==null?void 0:y.dataset.mappingItem;v&&(b.closest("[data-mapping-apply-one]")&&this.applyOne(v),b.closest("[data-mapping-save-one]")&&this.saveAndApplyOne(v),b.closest("[data-mapping-edit-one]")&&this.openEditorForOne(v),b.closest("[data-mapping-generate-one]")&&this.generateOne(v),b.closest("[data-mapping-copy-raw]")&&this.copyRawAnalysis())}),e==null||e.addEventListener("change",m=>{let b=m.target;if(!b||!this.mappingResult)return;let y=b.closest("[data-mapping-item]"),v=y==null?void 0:y.dataset.mappingItem;if(!v)return;let w=this.mappingResult.mappings.find(T=>T.game_object===v);w&&(b.matches("[data-mapping-action]")&&(w.action=String(b.value||"KEEP"),w.status="Edited",this.renderMappings()),b.matches("[data-mapping-brand-asset]")&&(w.brand_asset=String(b.value||""),w.status="Edited",this.renderMappings()))}),e==null||e.addEventListener("input",m=>{let b=m.target;if(!b||!this.mappingResult||!b.matches("[data-mapping-prompt]"))return;let y=b.closest("[data-mapping-item]"),v=y==null?void 0:y.dataset.mappingItem;if(!v)return;let w=this.mappingResult.mappings.find(T=>T.game_object===v);w&&(w.generation_prompt=String(b.value||""),w.status="Edited")})}switchTab(e){var t,i;this.root&&(this.currentTab=e,this.root.querySelectorAll("[data-vision-tab]").forEach(n=>n.classList.remove("active")),this.root.querySelectorAll("[data-vision-content]").forEach(n=>n.classList.remove("active")),(t=this.root.querySelector(`[data-vision-tab="${e}"]`))==null||t.classList.add("active"),(i=this.root.querySelector(`[data-vision-content="${e}"]`))==null||i.classList.add("active"))}switchUploadMethod(e){var t;this.root&&(this.uploadMethod=e,this.root.querySelectorAll("[data-vision-upload-section]").forEach(i=>{i.classList.remove("active")}),(t=this.root.querySelector(`[data-vision-upload-section="${e}"]`))==null||t.classList.add("active"))}async handleBatchPNGUpload(e){var s;let t=e.target,i=Array.from(t.files||[]);if(i.length===0)return;let n=i.filter(o=>o.type.startsWith("image/"));if(n.length===0){this.setStatus("upload","\u26A0\uFE0F No image files selected");return}let a=(s=this.root)==null?void 0:s.querySelector("[data-vision-batch-png-status]");a&&(a.textContent=`Processing ${n.length} PNG${n.length>1?"s":""}...`);try{let o=window.__HANDLER_ACTIVE_SCREEN,l=o==="loading"||o==="start"||o==="gameplay"||o==="tutorial"||o==="endgame"?o:"gameplay",c=[];for(let g=0;g<n.length;g++){let h=n[g];try{let f=await this.fileToDataUrl(h);if(!f){c.push({success:!1,filename:h.name,error:"Failed to read file"});continue}let m=h.name.replace(/\.[^/.]+$/,""),b=this.inferCategoryFromFilename(m),y=m.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"").toLowerCase(),v=`${y}_${Date.now()}${g>0?`_${g}`:""}`,w=`json.${v}`,T=`${y}.png`,M=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:b,filename:T,data:f,overwrite:!1})})).json();if(!M.success){c.push({success:!1,filename:h.name,error:M.error});continue}let L={identity:{id:w,category:b},transform:{anchor:"center",position:{x:0,y:0},scale:1,rotation:0},render:{z_index:0,alpha:1,visible:!0,anchor:{x:.5,y:.5},asset:{type:"image",path:M.path||`raw/library/${b}/${T}`}}},j=await fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:l,instanceId:v,objectConfigId:w,config:L,layer:b==="ui"?"ui":"world"})}),_=await j.json();j.ok&&_.success?c.push({success:!0,filename:h.name}):c.push({success:!1,filename:h.name,error:_.error})}catch(f){c.push({success:!1,filename:h.name,error:f instanceof Error?f.message:String(f)})}}let d=c.filter(g=>g.success).length,p=c.length-d;a&&(p===0?a.textContent=`\u2705 Added ${d} PNG${d>1?"s":""} to scene`:a.textContent=`\u26A0\uFE0F Added ${d}, failed ${p}`),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh"));let u=window.refreshAssetLibrary;typeof u=="function"&&u(),t.value=""}catch(o){a&&(a.textContent=`\u274C Error: ${o instanceof Error?o.message:String(o)}`),console.error("[BrandVision] Batch PNG upload failed:",o)}}inferCategoryFromFilename(e){let t=e.toLowerCase();return t.startsWith("ui_")||t.includes("button")||t.includes("label")?"ui":t.startsWith("bg_")||t.includes("background")?"backgrounds":t.includes("character")||t.includes("player")?"character":"environment"}fileToDataUrl(e){return new Promise(t=>{let i=new FileReader;i.onload=()=>t(i.result),i.onerror=()=>t(null),i.readAsDataURL(e)})}async handleZipUpload(e){var n;let i=(n=e.target.files)==null?void 0:n[0];if(i){this.zipFile=i,this.setStatus("zip",`Selected: ${i.name} (${(i.size/1024/1024).toFixed(2)} MB)`);try{await this.processZipFile(i)}catch(a){console.error("[BrandVision] ZIP processing failed:",a),this.setStatus("zip",`Error: ${a instanceof Error?a.message:"Unknown error"}`)}}}async processZipFile(e){var l;let t=null;if(typeof window!="undefined"&&window.JSZip)t=window.JSZip,console.log("[BrandVision] \u2705 Found window.JSZip");else try{let c=await import("jszip");t=c.default||c,console.log("[BrandVision] \u2705 Loaded JSZip via dynamic import")}catch(c){throw new Error(`JSZip is not properly imported. Make sure jszip is loaded globally (window.JSZip) or available as a module: ${(c==null?void 0:c.message)||"Unknown error"}`)}if(!t||typeof t.loadAsync!="function")throw new Error("JSZip is not properly imported - loadAsync method not found");let i=await t.loadAsync(e),n=[],a=[];i.forEach((c,d)=>{let p=c.toLowerCase();p.endsWith(".json")?n.push({name:c,content:null}):p.startsWith("assets/")&&p.endsWith(".png")&&a.push({name:c,file:d})});for(let c of n)try{let d=await((l=i.file(c.name))==null?void 0:l.async("text"));d&&(c.content=JSON.parse(d))}catch(d){console.warn(`Failed to parse ${c.name}:`,d)}let s=[];for(let c of a)try{let d=await c.file.async("uint8array"),p=new Blob([d],{type:"image/png"}),u=c.name.split("/").pop()||c.name;console.log(`Processing ${u}, uint8array length: ${d.length}, blob size: ${p.size}`);let g;try{g=await this.blobToDataUrl(p)}catch(h){console.warn(`FileReader failed for ${u}, using fallback:`,h),g=`data:image/png;base64,${btoa(String.fromCharCode.apply(null,Array.from(d)))}`}if(!g.startsWith("data:image/png;base64,")){console.warn(`Invalid data URL format for ${u}:`,g.substring(0,100));continue}s.push({filename:u,dataUrl:g})}catch(d){console.warn(`Failed to extract ${c.name}:`,d)}let o=null;for(let c of n){let d=c.name.toLowerCase();if(d.includes("positionnormalizedpack")||d.includes("positionnormalized")){o=c.content,console.log(`[BrandVision] Found position data file: ${c.name}`,{hasContent:!!o,isString:typeof o=="string",isObject:typeof o=="object",hasLayers:o!=null&&o.layers?o.layers.length:0});break}}if(o||console.warn("[BrandVision] No positionnormalizedpack.json found in ZIP. Available JSON files:",n.map(c=>c.name)),s.length>0){await this.showCanvaZipWizard(s,o),this.setStatus("zip",`\u2705 Wizard completed - ${s.length} assets processed`);return}else{this.setStatus("zip","\u26A0\uFE0F No PNG files found in ZIP");return}}async showCanvaZipWizard(e,t){return new Promise(i=>{let n=e.filter(o=>!this.wizardProcessedAssets.has(o.filename));if(n.length===0){console.log("[BrandVision] All assets already processed by wizard"),i();return}let a=document.createElement("div");document.body.appendChild(a),new Qi().initialize(a,n,t,{onComplete:o=>{console.log("[BrandVision] Wizard completed, processed assets:",o),o.forEach(l=>{this.wizardProcessedAssets.add(l.filename)}),a.remove(),i()},onCancel:()=>{console.log("[BrandVision] Wizard cancelled"),a.remove(),i()}})})}async blobToDataUrl(e){return new Promise((t,i)=>{let n=new FileReader;n.onload=()=>{let a=n.result;console.log("FileReader result type:",typeof a,"length:",a.length),console.log("Data URL prefix:",a.substring(0,30)),t(a)},n.onerror=a=>{console.error("FileReader error:",a),i(a)},n.readAsDataURL(e)})}inferAssetCategory(e){let t=e.toLowerCase();return t.includes("background")||t.includes("bg")?"backgrounds":t.includes("ui")||t.includes("button")||t.includes("cta")||t.includes("logo")||t.includes("text")?"ui":t.includes("sparkle")||t.includes("effect")||t.includes("particle")?"effects":t.includes("bottle")||t.includes("product")||t.includes("item")?"products":"misc"}addAssetsToRegistry(e){let t=window.getEditableAssets;if(typeof t!="function")return;let i=t();if(!(i!=null&&i.libraryAssets))return;let n={};for(let a of e){let s=a.category||"misc";n[s]||(n[s]=[]),i.libraryAssets[s]||(i.libraryAssets[s]=[]),i.libraryAssets[s].some(l=>l.filename===a.filename)||(i.libraryAssets[s].unshift({filename:a.filename,displayName:a.id.replace(/_/g," ").replace(/\b\w/g,l=>l.toUpperCase())}),console.log(`[BrandVision] Added ${a.filename} to registry category ${s}`))}}refreshLibrary(){let e=window.refreshAssetLibrary;typeof e=="function"&&e();let t=window.reRenderAssetLibrary;typeof t=="function"&&t()}async handleManifestUpload(e){var s;let t=e.target,i=t.files;if(!i||i.length===0)return;this.uploadedJsons.clear(),this.normalizedManifest=null,this.mappingResult=null;let n="";for(let o of Array.from(i))try{let l=await o.text(),c=JSON.parse(l);this.uploadedJsons.set(o.name,c),c.layers?n+=`\u2705 Layers: ${o.name}
|
|
1631
1633
|
`:c.brand_dna||c.colors?n+=`\u2705 Brand: ${o.name}
|
|
1632
1634
|
`:n+=`\u2705 Loaded: ${o.name}
|
|
1633
1635
|
`}catch{n+=`\u274C Error in ${o.name}
|
|
1634
|
-
`}try{this.normalizedManifest=Zs(Array.from(this.uploadedJsons.values()),{defaultBrandName:"Imported Brand"});let o=Array.isArray((
|
|
1636
|
+
`}try{this.normalizedManifest=Zs(Array.from(this.uploadedJsons.values()),{defaultBrandName:"Imported Brand"});let o=Array.isArray((s=this.normalizedManifest)==null?void 0:s.assets)?this.normalizedManifest.assets.length:0;n+=`
|
|
1635
1637
|
\u{1F4E6} Normalized manifest: ${o} assets`,n+=`
|
|
1636
1638
|
\u{1F3F7}\uFE0F Brand: ${this.normalizedManifest.brand_name||"Imported Brand"}`,console.info("[BrandVision] Normalized manifest",{jsonFiles:Array.from(this.uploadedJsons.keys()),assetsType:typeof this.normalizedManifest.assets,assetsCount:o,brandName:this.normalizedManifest.brand_name})}catch(o){console.error("[BrandVision] Failed to normalize manifest:",o),this.normalizedManifest=null,n+=`
|
|
1637
1639
|
\u274C Failed to normalize manifest`}t.value="";let a=n.trim();this.uploadedJsons.size>0?this.setStatus("manifest",`${a}
|
|
1638
|
-
\u2705 JSONs ready - now upload PNGs to open wizard`):this.setStatus("manifest",a)}async handleAssetsUpload(e){console.log("[BrandVision] handleAssetsUpload called",e);let t=e.target,i=t.files;if(console.log("[BrandVision] Files object:",i),!i||i.length===0){console.log("[BrandVision] No files selected");return}console.log(`[BrandVision] handleAssetsUpload: ${i.length} files selected`);for(let o=0;o<i.length;o++)console.log(`[BrandVision] File ${o}: ${i[o].name}, type: ${i[o].type}, size: ${i[o].size}`);let n=[];for(let o of Array.from(i)){if(console.log(`[BrandVision] Processing file: ${o.name}, type: ${o.type}`),!o.type.startsWith("image/")){console.log(`[BrandVision] Skipping non-image file: ${o.name}`),this.assetFiles.set(o.name,o);continue}try{let l=await this.fileToDataUrl(o);l?(n.push({filename:o.name,dataUrl:l}),console.log(`[BrandVision] \u2705 Converted ${o.name} to data URL (length: ${l.length})`)):(console.error(`[BrandVision] Failed to convert ${o.name} to data URL`),this.assetFiles.set(o.name,o))}catch(l){console.error(`[BrandVision] Failed to process ${o.name}:`,l),this.assetFiles.set(o.name,o)}}console.log(`[BrandVision] Extracted ${n.length} image assets`);let a=this.uploadedJsons.size>0,
|
|
1640
|
+
\u2705 JSONs ready - now upload PNGs to open wizard`):this.setStatus("manifest",a)}async handleAssetsUpload(e){console.log("[BrandVision] handleAssetsUpload called",e);let t=e.target,i=t.files;if(console.log("[BrandVision] Files object:",i),!i||i.length===0){console.log("[BrandVision] No files selected");return}console.log(`[BrandVision] handleAssetsUpload: ${i.length} files selected`);for(let o=0;o<i.length;o++)console.log(`[BrandVision] File ${o}: ${i[o].name}, type: ${i[o].type}, size: ${i[o].size}`);let n=[];for(let o of Array.from(i)){if(console.log(`[BrandVision] Processing file: ${o.name}, type: ${o.type}`),!o.type.startsWith("image/")){console.log(`[BrandVision] Skipping non-image file: ${o.name}`),this.assetFiles.set(o.name,o);continue}try{let l=await this.fileToDataUrl(o);l?(n.push({filename:o.name,dataUrl:l}),console.log(`[BrandVision] \u2705 Converted ${o.name} to data URL (length: ${l.length})`)):(console.error(`[BrandVision] Failed to convert ${o.name} to data URL`),this.assetFiles.set(o.name,o))}catch(l){console.error(`[BrandVision] Failed to process ${o.name}:`,l),this.assetFiles.set(o.name,o)}}console.log(`[BrandVision] Extracted ${n.length} image assets`);let a=this.uploadedJsons.size>0,s=n.length>0;if(console.log(`[BrandVision] Individual upload check: JSONs=${a}, Images=${s}`),a&&s){console.log("[BrandVision] Both JSONs and images present - showing wizard"),this.setStatus("assets",`Processing ${n.length} images...`);let o=null;console.log("[BrandVision] Checking uploaded JSONs for position data:",Array.from(this.uploadedJsons.keys()));for(let[l,c]of this.uploadedJsons.entries()){let d=l.toLowerCase();if(console.log(`[BrandVision] Checking JSON: ${l} (lowercase: ${d})`),d.includes("positionnormalizedpack")||d.includes("positionnormalized")){o=c,console.log("[BrandVision] \u2705 Found position data in:",l,{hasContent:!!o,isString:typeof o=="string",isObject:typeof o=="object",hasLayers:o!=null&&o.layers?o.layers.length:0,contentPreview:typeof o=="object"?JSON.stringify(o).substring(0,200):String(o).substring(0,200)});break}}o||console.warn("[BrandVision] \u26A0\uFE0F No position data found. Uploaded JSON files:",Array.from(this.uploadedJsons.keys())),console.log("[BrandVision] Opening wizard with assets:",n.map(l=>l.filename)),await this.showCanvaZipWizard(n,o),console.log("[BrandVision] Wizard completed successfully"),this.setStatus("assets",`\u2705 Wizard completed - ${n.length} assets processed`)}else console.log("[BrandVision] Waiting for both JSONs and images. Current state:",{jsons:this.uploadedJsons.size,images:n.length}),a?this.setStatus("assets",`Uploaded ${n.length} images. JSONs ready - wizard should open now.`):this.setStatus("assets","\u26A0\uFE0F Upload JSONs first, then PNGs to open wizard");t.value=""}async handleFlatDesignUpload(e){var a,s;let i=(a=e.target.files)==null?void 0:a[0];if(!i)return;let n=await Fe(i);if(n){this.flatDesignDataUrl=n.dataUrl,this.setStatus("flat",`\u{1F3A8} ${i.name}`);let o=(s=this.root)==null?void 0:s.querySelector("[data-vision-flat-preview]");o&&(o.innerHTML=`<img src="${n.dataUrl}" style="max-width:100%;max-height:100px;border-radius:4px;">`)}}async runAnalysis(){var i,n,a,s,o,l,c;if(this.isAnalyzing)return;let e=(a=(n=(i=this.root)==null?void 0:i.querySelector("[data-vision-api-key]"))==null?void 0:n.value)==null?void 0:a.trim();if(!e){this.setStatus("upload","Missing API key");return}let t=this.manifest;if(!t){this.setStatus("upload","Upload manifest first");return}Array.isArray(t.assets)||console.warn("[BrandVision] Manifest assets not array at analysis time; continuing with normalization fallback.",{assets:t.assets}),this.isAnalyzing=!0,this.setStatus("upload","Analyzing...");try{await or(t,this.assetFiles);let d={apiKey:e,manifest:t,flatDesignDataUrl:this.flatDesignDataUrl,assetFiles:this.assetFiles,gameObjects:this.getGameObjects(),gamePrompt:await this.getGamePrompt()},p=await sr(d);this.mappingResult=p.mappingResult,this.analysisRawResponse=p.rawResponse,this.analysisParsedOk=p.parsed,this.analysisParseError=(s=p.parseError)!=null?s:null,this.renderMappings(),p.parsed?(this.setStatus("upload","Analysis complete"),this.setStatus("mapping",`${(c=(l=(o=this.mappingResult)==null?void 0:o.mappings)==null?void 0:l.length)!=null?c:0} objects mapped`)):(this.setStatus("upload","Analysis response was not JSON"),this.setStatus("mapping",`Parse failed: ${p.parseError||"Unknown error"}`)),this.switchTab("mapping")}catch(d){console.error("[BrandVision] Analysis failed:",d),this.setStatus("upload","Analysis failed")}finally{this.isAnalyzing=!1}}async generateAllMissing(){var t,i,n;if(this.isGenerating||!this.mappingResult||!this.manifest)return;let e=(n=(i=(t=this.root)==null?void 0:t.querySelector("[data-vision-api-key]"))==null?void 0:i.value)==null?void 0:n.trim();if(!e){this.setStatus("apply","Missing API key");return}this.isGenerating=!0;try{let a={apiKey:e,manifest:this.manifest,flatDesignDataUrl:this.flatDesignDataUrl,assetFiles:this.assetFiles,gameObjects:this.getGameObjects(),gamePrompt:await this.getGamePrompt()};await ga(a,this.mappingResult,{onProgress:(s,o,l)=>{this.setStatus("apply",`Generating ${s}/${o}: ${l}`),this.renderMappings()}}),this.setStatus("apply","Generation complete"),this.renderMappings()}catch(a){console.error("[BrandVision] Generation failed:",a),this.setStatus("apply","Generation failed")}finally{this.isGenerating=!1}}renderMappings(){var o;let e=(o=this.root)==null?void 0:o.querySelector("[data-vision-mappings]");if(!e||!this.mappingResult)return;let t=this.manifest,i=this.getEngineAssets(),n=!!this.analysisRawResponse&&this.analysisParsedOk===!1,a=((t==null?void 0:t.assets)||[]).map(l=>`<option value="${l.id}">${l.id}</option>`).join(""),s=n?`
|
|
1639
1641
|
<div class="vision-raw-block">
|
|
1640
1642
|
<div class="inspector-text-sm" style="white-space: pre-wrap;">
|
|
1641
1643
|
\u26A0\uFE0F AI response was not valid JSON (${this.analysisParseError||"unknown error"}).
|
|
@@ -1644,7 +1646,7 @@ Generate the requested asset matching the brand style.${s.needsTransparency?" Ba
|
|
|
1644
1646
|
<textarea class="inspector-input vision-raw-textarea" readonly>${this.analysisRawResponse||""}</textarea>
|
|
1645
1647
|
</div>
|
|
1646
1648
|
`:"";e.innerHTML=`
|
|
1647
|
-
${
|
|
1649
|
+
${s}
|
|
1648
1650
|
${this.mappingResult.mappings.map(l=>{var b;let c=i[l.game_object]||"",d=l.brand_asset||"",p=(b=t==null?void 0:t.assets)==null?void 0:b.find(y=>y.id===d),u=(p==null?void 0:p.dataUrl)||"",g=l.output_dataUrl||"",h=l.action==="GENERATE"?g:l.action==="APPLY"?u:"",f=!!h,m=`
|
|
1649
1651
|
<select class="inspector-input" data-mapping-brand-asset style="flex:1; padding:6px 8px;">
|
|
1650
1652
|
<option value="">Select brand asset\u2026</option>
|
|
@@ -1697,7 +1699,7 @@ Generate the requested asset matching the brand style.${s.needsTransparency?" Ba
|
|
|
1697
1699
|
</div>
|
|
1698
1700
|
</div>
|
|
1699
1701
|
`}).join("")}
|
|
1700
|
-
`}async applyAll(){let e=await this.stageOverridesFromMappings({saveToLibrary:!1});this.setStatus("apply",e>0?`Staged ${e} asset overrides`:"No assets to stage")}getEngineAssets(){let e=window.getEditableEngineConfig;if(typeof e!="function")return{};let t=e();return t!=null&&t.assets&&typeof t.assets=="object"?t.assets:{}}getPreviewValueForMapping(e){if(!this.mappingResult||!this.manifest)return{value:null,source:"none"};let t=this.mappingResult.mappings.find(i=>i.game_object===e);if(!t)return{value:null,source:"none"};if(t.action==="GENERATE"&&t.output_dataUrl)return{value:t.output_dataUrl,source:"generated"};if(t.action==="APPLY"&&t.brand_asset){let i=this.manifest.assets.find(n=>n.id===t.brand_asset);if(i!=null&&i.dataUrl)return{value:i.dataUrl,source:"brand"}}return{value:null,source:"none"}}async stageOverridesFromMappings(e){if(!this.mappingResult)return 0;let t=0;for(let i of this.mappingResult.mappings){if(i.action==="KEEP"||i.action==="APPLY"&&!i.brand_asset||i.action==="GENERATE"&&!i.output_dataUrl)continue;let n=i.game_object,a=this.getPreviewValueForMapping(n);if(!a.value)continue;let
|
|
1702
|
+
`}async applyAll(){let e=await this.stageOverridesFromMappings({saveToLibrary:!1});this.setStatus("apply",e>0?`Staged ${e} asset overrides`:"No assets to stage")}getEngineAssets(){let e=window.getEditableEngineConfig;if(typeof e!="function")return{};let t=e();return t!=null&&t.assets&&typeof t.assets=="object"?t.assets:{}}getPreviewValueForMapping(e){if(!this.mappingResult||!this.manifest)return{value:null,source:"none"};let t=this.mappingResult.mappings.find(i=>i.game_object===e);if(!t)return{value:null,source:"none"};if(t.action==="GENERATE"&&t.output_dataUrl)return{value:t.output_dataUrl,source:"generated"};if(t.action==="APPLY"&&t.brand_asset){let i=this.manifest.assets.find(n=>n.id===t.brand_asset);if(i!=null&&i.dataUrl)return{value:i.dataUrl,source:"brand"}}return{value:null,source:"none"}}async stageOverridesFromMappings(e){if(!this.mappingResult)return 0;let t=0;for(let i of this.mappingResult.mappings){if(i.action==="KEEP"||i.action==="APPLY"&&!i.brand_asset||i.action==="GENERATE"&&!i.output_dataUrl)continue;let n=i.game_object,a=this.getPreviewValueForMapping(n);if(!a.value)continue;let s=e.saveToLibrary?await this.saveToLibraryAndReturnPath(n,a.value):a.value;s&&(await this.stageEngineAssetOverride(n,s),i.status=e.saveToLibrary?"Saved + staged \u2713":"Staged \u2713",t++)}return this.renderMappings(),t}async applyOne(e){var n;let t=this.getPreviewValueForMapping(e);if(!t.value){this.setStatus("apply",`No output to apply for ${e}`);return}await this.stageEngineAssetOverride(e,t.value);let i=(n=this.mappingResult)==null?void 0:n.mappings.find(a=>a.game_object===e);i&&(i.status="Staged \u2713"),this.renderMappings(),this.setStatus("apply",`Staged override for ${e}`)}async saveAndApplyOne(e){var a;let t=this.getPreviewValueForMapping(e);if(!t.value){this.setStatus("apply",`No output to save for ${e}`);return}let i=await this.saveToLibraryAndReturnPath(e,t.value);if(!i){this.setStatus("apply",`Save failed for ${e}`);return}await this.stageEngineAssetOverride(e,i);let n=(a=this.mappingResult)==null?void 0:a.mappings.find(s=>s.game_object===e);n&&(n.status="Saved + staged \u2713"),this.renderMappings(),this.setStatus("apply",`Saved + staged ${e}`)}openEditorForOne(e){if(!this.mappingResult)return;let t=this.mappingResult.mappings.find(s=>s.game_object===e);if(!t)return;let i=this.getPreviewValueForMapping(e),n=window.__openAiEditor;if(typeof n!="function"){this.setStatus("apply","AI editor not available");return}let a=t.action==="GENERATE"?t.generation_prompt:void 0;n(e,a,i.value||void 0,{path:`assets.${e}`})}async generateOne(e){var n,a,s;if(!this.mappingResult||this.isGenerating)return;let t=this.mappingResult.mappings.find(o=>o.game_object===e);if(!t)return;if(t.action="GENERATE",!t.generation_prompt){t.status="Missing prompt",this.renderMappings();return}let i=(s=(a=(n=this.root)==null?void 0:n.querySelector("[data-vision-api-key]"))==null?void 0:a.value)==null?void 0:s.trim();if(!i||!this.manifest){this.setStatus("apply","Missing API key or manifest");return}this.isGenerating=!0,t.status="Generating\u2026",this.renderMappings();try{let o={apiKey:i,manifest:this.manifest,flatDesignDataUrl:this.flatDesignDataUrl,assetFiles:this.assetFiles,gameObjects:this.getGameObjects(),gamePrompt:await this.getGamePrompt()};await ga(o,{mappings:[t]}),t.status=t.output_dataUrl?"Generated \u2713":t.status||"Done"}catch(o){console.error("[BrandVision] generateOne failed:",o),t.status="Failed \u2717"}finally{this.isGenerating=!1,this.renderMappings()}}async stageEngineAssetOverride(e,t){let{applyConfigOverride:i}=await Promise.resolve().then(()=>(ee(),Ne));i({path:`assets.${e}`,value:t},{silent:!0});let n=window.applyEditableEngineConfig;typeof n=="function"&&n({assets:{[e]:t}})}async saveToLibraryAndReturnPath(e,t){if(!/^(data:|blob:)/.test(t))return t;let i=this.inferCategoryFromAssetKey(e),n=`${e.replace(/[^a-zA-Z0-9_-]/g,"_")}_vision_${Date.now()}.png`;try{let s=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:i,filename:n,data:t,overwrite:!0})})).json();if(!(s!=null&&s.success)||!(s!=null&&s.path))return console.error("[BrandVision] Save to library failed:",(s==null?void 0:s.error)||s),null;let o=window.addAssetToRegistry;typeof o=="function"&&o(i,n);let l=window.refreshAssetLibrary;return typeof l=="function"&&l(),String(s.path)}catch(a){return console.error("[BrandVision] Save to library error:",a),null}}inferCategoryFromAssetKey(e){let t=window.getEditableAssets;if(typeof t=="function"){let n=t();if(n!=null&&n.slots&&Array.isArray(n.slots)){let s=n.slots.find(o=>o.slotId===e||o.currentAsset===e);if(s!=null&&s.category)return String(s.category)}let a=n==null?void 0:n.categories;if(Array.isArray(a)&&a.length>0){let s=e.toLowerCase(),o=l=>a.find(c=>c.toLowerCase().includes(l));return s.includes("bg")||s.includes("background")?o("background")||a[0]:(s.includes("cta")||s.includes("button")||s.includes("ui")||s.includes("logo"))&&o("ui")||a[0]}}let i=e.toLowerCase();return i.includes("bg")||i.includes("background")?"backgrounds":i.includes("cta")||i.includes("button")||i.includes("ui")||i.includes("logo")?"ui":"misc"}async copyRawAnalysis(){if(this.analysisRawResponse)try{await navigator.clipboard.writeText(this.analysisRawResponse),this.setStatus("mapping","Copied raw analysis to clipboard")}catch{this.setStatus("mapping","Clipboard not available")}}setStatus(e,t){var a;let i={manifest:"[data-vision-manifest-status]",assets:"[data-vision-assets-status]",flat:"[data-vision-flat-status]",zip:"[data-vision-zip-status]",upload:"[data-vision-upload-status]",mapping:"[data-vision-mapping-status]",apply:"[data-vision-apply-status]"},n=(a=this.root)==null?void 0:a.querySelector(i[e]);n&&(n.textContent=t)}getGameObjects(){let e=window.getEditableObjectList;return typeof e=="function"?e():[]}async getGamePrompt(){try{let e=await fetch("./configs/engine/game.prompt.json");if(e.ok)return(await e.json()).game_prompt||""}catch{}return""}setupResizeHandle(){if(!this.root)return;let e=this.root.querySelector("[data-panel-resize]");e&&e.addEventListener("pointerdown",t=>{let i=t.clientX,n=this.root.getBoundingClientRect().width,a=o=>{let l=Math.max(300,n+(o.clientX-i));this.root.style.width=`${l}px`},s=()=>{window.removeEventListener("pointermove",a),window.removeEventListener("pointerup",s)};window.addEventListener("pointermove",a),window.addEventListener("pointerup",s)})}refresh(){}};function br(r,e={}){let{includeReference:t=!1,includeMagenta:i=!0,changeLevel:n=5}=e;return[`TASK: ${r}`,`CHANGE_STRENGTH: ${n}/10`,t?"REFERENCE: provided":"REFERENCE: none",i?"BACKGROUND: solid magenta #FF00FF (if possible)":""].filter(Boolean).join(`
|
|
1701
1703
|
`)}var hl=["background_color","text_color","cta_background","cta_text","warning_text_color","endgame_title_color","endgame_subtitle_color","endgame_cta_text_color","endgame_cta_hint_color","endgame_footer_color"],fl=["cta_hint","cta_label_end"],yr=[{key:"warning_text",objectId:"label.warning",property:"ui.text"},{key:"endgame_title",objectId:"ui.endgame.title",property:"ui.text"},{key:"endgame_subtitle",objectId:"ui.endgame.subtitle",property:"ui.text"},{key:"endgame_cta_text",objectId:"ui.endgame.cta",property:"ui.text"},{key:"endgame_cta_hint_text",objectId:"ui.endgame.cta.hint",property:"ui.text"},{key:"endgame_footer_text",objectId:"ui.endgame.footer",property:"ui.text"}],ml=["brand.primary","brand.heading","brand.body","brand.warning"],tn=class{constructor(){this.root=null;this.assetsContainer=null;this.colorsContainer=null;this.fontsContainer=null;this.textsContainer=null;this.audioContainer=null;this.options=null;this.previewModal=null;this.autoApplyTimer=null;this.activePreviewKey=null;this.activePreviewValue=null;this.activePreviewFileInput=null;this.retryTimer=null;this.aiModal=null;this.aiTargetKey=null;this.aiKeyInput=null;this.aiPromptInput=null;this.aiStrengthInput=null;this.aiStrengthValue=null;this.aiModelSelect=null;this.aiModalSubtitle=null;this.aiGalleryToggle=null;this.aiGalleryEl=null;this.aiGalleryGrid=null;this.aiReferenceInput=null;this.aiReferenceName=null;this.aiReferenceFile=null;this.aiRemoveBgToggle=null;this.aiUseOutputToggle=null;this.aiGenerateBtn=null;this.aiApplyBtn=null;this.aiSaveLibraryBtn=null;this.aiCropBtn=null;this.aiDownloadBtn=null;this.aiPreviewImg=null;this.aiStatusEl=null;this.aiOutputDataUrl=null;this.aiBaseDataUrl=null;this.aiBaseValue=null;this.aiOutputKey=null;this.aiContext=null;this.aiBgToleranceInput=null;this.aiBgToleranceValue=null;this.aiRawOutputDataUrl=null;this.aiLoadingEl=null}render(){return`
|
|
1702
1704
|
<div class="scene-panel customize-panel panel-accent-blue" data-panel="customize-settings">
|
|
1703
1705
|
<div class="scene-panel-header" data-panel-handle>
|
|
@@ -1756,7 +1758,7 @@ Generate the requested asset matching the brand style.${s.needsTransparency?" Ba
|
|
|
1756
1758
|
</div>
|
|
1757
1759
|
<div class="panel-resize-handle" data-panel-resize></div>
|
|
1758
1760
|
</div>
|
|
1759
|
-
`}initialize(e,t){var n,a,
|
|
1761
|
+
`}initialize(e,t){var n,a,s,o,l,c;this.options=t,this.root=e.querySelector('[data-panel="customize-settings"]'),this.assetsContainer=(n=this.root)==null?void 0:n.querySelector("[data-customize-assets]"),this.colorsContainer=(a=this.root)==null?void 0:a.querySelector("[data-customize-colors]"),this.fontsContainer=(s=this.root)==null?void 0:s.querySelector("[data-customize-fonts]"),this.textsContainer=(o=this.root)==null?void 0:o.querySelector("[data-customize-texts]"),this.audioContainer=(l=this.root)==null?void 0:l.querySelector("[data-customize-audio]");let i=(c=this.root)==null?void 0:c.querySelector("[data-customize-apply]");i==null||i.addEventListener("click",()=>this.handleApply()),this.setupRenderModeHandlers(),this.setupResizeHandle(),this.refresh()}setupRenderModeHandlers(){var i,n;let e=(i=this.root)==null?void 0:i.querySelector('[data-render-mode="endgame-png"]'),t=(n=this.root)==null?void 0:n.querySelector('[data-render-mode="splash-png"]');e==null||e.addEventListener("change",()=>{this.applyEndgamePngMode(e.checked)}),t==null||t.addEventListener("change",()=>{this.applySplashPngMode(t.checked)})}applyEndgamePngMode(e){let t=window.getEditableObjectConfig,i=window.applyEditableObjectConfig;if(typeof t!="function"||typeof i!="function")return;let n=["ui_endgame_title_1","ui_endgame_subtitle_1","ui_endgame_logo_1","ui_endgame_cta_1"];for(let a of n){let s=t(a);s&&(s.ui||(s.ui={}),s.ui.renderMode=e?"png":"text",e&&(s.render||(s.render={}),s.render.asset||(s.render.asset={type:"image",path:""}),s.render.asset.type="image"),i(a,s))}console.log("[CustomizePanel] EndGame PNG mode:",e?"enabled":"disabled")}applySplashPngMode(e){let t=window.applyEditableEngineConfig;typeof t=="function"&&(t({splash:{type:e?"image":"text",image_path:e?"library/splash/splash.png":""}}),console.log("[CustomizePanel] Splash PNG mode:",e?"enabled":"disabled"))}openAiEditor(e,t,i,n){this.openAiModal(e,i,n),t&&this.aiPromptInput&&(this.aiPromptInput.value=t,this.setAiStatus("Prompt loaded."))}refresh(){var t,i,n,a,s,o,l,c;let e=this.getEngineSnapshot();if(!e){this.scheduleRetry();return}console.log("[CustomizePanel] Snapshot assets count:",Object.keys(e.assets||{}).length),this.renderAssets(e.assets),this.renderColors((i=(t=e.runtime)==null?void 0:t.theme)!=null?i:{}),this.renderFonts((a=(n=e.runtime)==null?void 0:n.fonts)!=null?a:{}),this.renderTexts((o=(s=e.runtime)==null?void 0:s.ui)!=null?o:{}),this.renderAudio((c=(l=e.runtime)==null?void 0:l.audio)!=null?c:{})}getEngineSnapshot(){let e=window.getEditableEngineConfig;return typeof e!="function"?null:e()}renderAssets(e){if(!this.assetsContainer)return;this.assetsContainer.innerHTML="";let t=Object.entries(e!=null?e:{});if(!t.length){this.assetsContainer.innerHTML='<div class="customize-empty">No assets found.</div>',this.scheduleRetry();return}this.clearRetry(),t.forEach(([i,n])=>{var u;let a=document.createElement("div");a.className="customize-row";let s=document.createElement("span");s.className="customize-key",s.textContent=i;let o=document.createElement("input");o.type="text",o.value=n!=null?n:"",o.className="customize-input",o.dataset.assetKey=i,o.addEventListener("input",()=>{this.handleAssetValueChange(i,o)});let l=document.createElement("div");l.className="customize-actions";let c=document.createElement("button");c.type="button",c.className="customize-icon-btn",c.title="Preview asset",c.innerHTML=`
|
|
1760
1762
|
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
1761
1763
|
<path d="M12 5c5.2 0 9.2 3.7 10 6.8-.8 3.1-4.8 6.8-10 6.8S2.8 14.9 2 11.8C2.8 8.7 6.8 5 12 5z" />
|
|
1762
1764
|
<circle cx="12" cy="12" r="3.2" />
|
|
@@ -1766,7 +1768,7 @@ Generate the requested asset matching the brand style.${s.needsTransparency?" Ba
|
|
|
1766
1768
|
<path d="M12 3l4 4h-3v6h-2V7H8l4-4z" />
|
|
1767
1769
|
<path d="M5 14v4h14v-4h2v6H3v-6h2z" />
|
|
1768
1770
|
</svg>
|
|
1769
|
-
`;let p=document.createElement("input");p.type="file",p.accept="image/*,audio/*,application/json",p.className="customize-file",p.addEventListener("change",()=>{var h;let g=(h=p.files)==null?void 0:h[0];g&&this.handleAssetUpload(g,o,i)}),d.addEventListener("click",()=>p.click()),l.appendChild(c),l.appendChild(d),l.appendChild(p),a.appendChild(
|
|
1771
|
+
`;let p=document.createElement("input");p.type="file",p.accept="image/*,audio/*,application/json",p.className="customize-file",p.addEventListener("change",()=>{var h;let g=(h=p.files)==null?void 0:h[0];g&&this.handleAssetUpload(g,o,i)}),d.addEventListener("click",()=>p.click()),l.appendChild(c),l.appendChild(d),l.appendChild(p),a.appendChild(s),a.appendChild(o),a.appendChild(l),(u=this.assetsContainer)==null||u.appendChild(a)})}renderColors(e){this.colorsContainer&&(this.colorsContainer.innerHTML="",hl.forEach(t=>{var l,c,d;let i=(l=e==null?void 0:e[t])!=null?l:"#ffffff";if(t.includes("_text_color")||t.includes("_color")){let u={warning_text_color:{objectId:"label.warning",property:"render.tint"},endgame_title_color:{objectId:"ui.endgame.title",property:"render.tint"},endgame_subtitle_color:{objectId:"ui.endgame.subtitle",property:"render.tint"},endgame_cta_text_color:{objectId:"ui.endgame.cta",property:"render.tint"},endgame_cta_hint_color:{objectId:"ui.endgame.cta.hint",property:"render.tint"},endgame_footer_color:{objectId:"ui.endgame.footer",property:"render.tint"}}[t];u&&(i=(c=this.getObjectPropertyValue(u.objectId,u.property))!=null?c:"#ffffff")}let n=document.createElement("label");n.className="customize-color-field";let a=document.createElement("span");a.textContent=t.replace(/_/g," ");let s=document.createElement("input");s.type="color",s.value=i,s.dataset.colorKey=t;let o=document.createElement("input");o.type="text",o.value=i,o.className="customize-color-text",o.dataset.colorTextKey=t,s.addEventListener("input",()=>{o.value=s.value}),o.addEventListener("input",()=>{/^#([0-9a-fA-F]{6})$/.test(o.value)&&(s.value=o.value)}),n.appendChild(a),n.appendChild(s),n.appendChild(o),(d=this.colorsContainer)==null||d.appendChild(n)}))}renderFonts(e){this.fontsContainer&&(this.fontsContainer.innerHTML="",ml.forEach(t=>{var s,o;let i=document.createElement("div");i.className="customize-row";let n=document.createElement("span");n.className="customize-key",n.textContent=t;let a=document.createElement("input");a.type="text",a.value=(s=e==null?void 0:e[t])!=null?s:t,a.className="customize-input",a.dataset.fontKey=t,i.appendChild(n),i.appendChild(a),(o=this.fontsContainer)==null||o.appendChild(i)}))}renderTexts(e){this.textsContainer&&(this.textsContainer.innerHTML="",fl.forEach(t=>{var s,o;let i=document.createElement("div");i.className="customize-row";let n=document.createElement("span");n.className="customize-key",n.textContent=t;let a=document.createElement("input");a.type="text",a.value=(s=this.readUiValue(e,t))!=null?s:"",a.className="customize-input",a.dataset.textKey=t,i.appendChild(n),i.appendChild(a),(o=this.textsContainer)==null||o.appendChild(i)}),yr.forEach(({key:t,objectId:i})=>{var o,l;let n=document.createElement("div");n.className="customize-row";let a=document.createElement("span");a.className="customize-key",a.textContent=t;let s=document.createElement("input");s.type="text",s.value=(o=this.getObjectTextValue(i))!=null?o:"",s.className="customize-input",s.dataset.objectTextKey=t,n.appendChild(a),n.appendChild(s),(l=this.textsContainer)==null||l.appendChild(n)}))}renderAudio(e){if(!this.audioContainer)return;this.audioContainer.innerHTML="",["background_file","background_volume","click_file","click_volume","success_file","success_volume","complete_file","complete_volume"].forEach(i=>{var o,l;let n=document.createElement("div");n.className="customize-row";let a=document.createElement("span");a.className="customize-key",a.textContent=i.replace("_"," ");let s=document.createElement("input");s.type=i.includes("volume")?"number":"text",s.min="0",s.max="1",s.step="0.1",s.value=String((o=e==null?void 0:e[i])!=null?o:""),s.className="customize-input",s.dataset.audioKey=i,i.includes("file")&&(s.placeholder="audio file path"),n.appendChild(a),n.appendChild(s),(l=this.audioContainer)==null||l.appendChild(n)})}readUiValue(e,t){if(t.includes(".")){let n=t.split("."),a=e;for(let s of n){if(a==null)return null;a=a[s]}return typeof a=="string"?a:null}let i=e==null?void 0:e[t];return typeof i=="string"?i:null}getObjectTextValue(e){var n,a;let t=window.getEditableObjectConfig;if(typeof t!="function")return null;let i=t(e);return(a=(n=i==null?void 0:i.ui)==null?void 0:n.text)!=null?a:null}getObjectPropertyValue(e,t){let i=window.getEditableObjectConfig;if(typeof i!="function")return null;let n=i(e);if(!n)return null;let a=t.split("."),s=n;for(let o of a){if(s==null)return null;s=s[o]}return typeof s=="string"?s:null}handleApply(){this.handleApplyWithSource("manual")}handleApplyWithSource(e){if(console.log(`[CustomizePanel] handleApplyWithSource called with source: ${e}`),!this.root||!this.options)return;let t={};this.root.querySelectorAll("[data-asset-key]").forEach(o=>{let l=o;l.dataset.assetKey&&(t[l.dataset.assetKey]=l.value)}),console.log("[CustomizePanel] Assets being applied:",Object.keys(t).length,"total"),console.log("[CustomizePanel] Asset values:",t);let i={};this.root.querySelectorAll("[data-color-text-key]").forEach(o=>{let l=o,c=l.dataset.colorTextKey;c&&(c.includes("_text_color")||c.includes("_color")?this.applyTextColorToObject(c,l.value):i[c]=l.value)});let n={};this.root.querySelectorAll("[data-font-key]").forEach(o=>{let l=o,c=l.dataset.fontKey;c&&(n[c]=l.value)});let a={};this.root.querySelectorAll("[data-text-key]").forEach(o=>{let l=o,c=l.dataset.textKey;c&&(a[c]=l.value)});let s={};this.root.querySelectorAll("[data-audio-key]").forEach(o=>{let l=o,c=l.dataset.audioKey;if(c)if(c.includes("volume")){let d=parseFloat(l.value);s[c]=isNaN(d)?0:d}else s[c]=l.value}),this.root.querySelectorAll("[data-object-text-key]").forEach(o=>{let l=o,c=l.dataset.objectTextKey;if(!c)return;let d=yr.find(p=>p.key===c);d&&this.applyObjectPropertyValue(d.objectId,d.property,l.value)}),console.log("[CustomizePanel] Calling onApply callback to restart game with source:",e),this.options.onApply({assets:t,runtime:{theme:i,ui:a,fonts:n,audio:s}},{source:e})}setupAiPanel(){}setAiStatus(e){this.aiStatusEl&&(this.aiStatusEl.textContent=e)}getSelectedAssetKey(){return this.aiTargetKey}getSelectedAssetInput(){let e=this.getSelectedAssetKey();return!this.root||!e?null:this.root.querySelector(`input[data-asset-key="${e}"]`)}async getImageDataFromAsset(e){let t=this.resolveAssetUrls(e);console.log("[CustomizePanel] Resolving asset urls for AI:",e,t);for(let i of t)try{let n=await Xi(i);if(n)return console.log("[CustomizePanel] Successfully fetched image data for AI"),{input:{base64:n.base64,mimeType:n.mimeType},dataUrl:n.dataUrl,width:n.width,height:n.height}}catch(n){console.warn("[CustomizePanel] Failed to fetch image data from:",i,n)}return console.error("[CustomizePanel] Could not load image data for AI from any URL"),null}async updateAiBasePreview(e){var n,a,s;let t=(e==null?void 0:e.trim())||"";if(!t){let o=this.getSelectedAssetInput();t=(a=(n=o==null?void 0:o.value)==null?void 0:n.trim())!=null?a:""}if(console.log("[CustomizePanel] updateAiBasePreview using value:",t),!t){this.aiBaseDataUrl=null,this.updateAiPreview();return}let i=await this.getImageDataFromAsset(t);this.aiBaseDataUrl=(s=i==null?void 0:i.dataUrl)!=null?s:null,this.updateAiPreview()}updateAiPreview(){if(!this.aiPreviewImg)return;let e=this.aiOutputDataUrl||this.aiBaseDataUrl||"";if(!e){this.aiPreviewImg.removeAttribute("src");return}this.aiPreviewImg.src=e}updateAiModalPreview(e,t){if(!e)return;let i=t!=null?t:this.activePreviewKey;if(!i||!this.aiOutputDataUrl||this.aiOutputKey!==i){e.classList.add("hidden");return}let n=e.querySelector(".asset-preview-ai-image");n&&(n.src=this.aiOutputDataUrl),e.classList.remove("hidden")}setAiLoading(e){this.aiLoadingEl&&this.aiLoadingEl.classList.toggle("active",e),this.aiGenerateBtn&&(this.aiGenerateBtn.disabled=e)}toggleAiGallery(){if(!this.aiGalleryEl||!this.aiGalleryToggle)return;let e=this.aiGalleryEl.classList.toggle("hidden");this.aiGalleryToggle.textContent=e?"Gallery":"Hide Gallery",e||this.renderAiGallery()}renderAiGallery(){if(!this.aiGalleryGrid)return;let e=this.getAiGalleryEntries();if(!e.length){this.aiGalleryGrid.innerHTML='<div class="ai-gallery-empty">No image assets found.</div>';return}this.aiGalleryGrid.innerHTML="",e.forEach(({key:t,value:i})=>{var l;let n=document.createElement("button");n.type="button",n.className="ai-gallery-item",t===this.aiTargetKey&&n.classList.add("active");let a=document.createElement("img");a.className="ai-gallery-thumb",a.alt=t;let s=this.resolveAssetUrls(i);s[0]&&(a.src=s[0]);let o=document.createElement("span");o.className="ai-gallery-label",o.textContent=t,n.appendChild(a),n.appendChild(o),n.addEventListener("click",()=>this.selectAiGalleryAsset(t)),(l=this.aiGalleryGrid)==null||l.appendChild(n)})}getAiGalleryEntries(){if(!this.root)return[];let e=[];return this.root.querySelectorAll("[data-asset-key]").forEach(t=>{var s,o;let i=t,n=i.dataset.assetKey,a=(o=(s=i.value)==null?void 0:s.trim())!=null?o:"";!n||!a||this.isAiGalleryImage(a)&&e.push({key:n,value:a})}),e}isAiGalleryImage(e){let t=e.trim();if(!t)return!1;if(/^(data:image|blob:)/.test(t))return!0;let i=t.split("?")[0].toLowerCase();return![".mp3",".wav",".ogg",".json"].some(n=>i.endsWith(n))}selectAiGalleryAsset(e){this.aiTargetKey!==e&&(this.aiTargetKey=e,this.aiOutputDataUrl=null,this.aiOutputKey=null,this.aiReferenceFile=null,this.aiBaseDataUrl=null,this.aiReferenceInput&&(this.aiReferenceInput.value=""),this.aiReferenceName&&(this.aiReferenceName.textContent="Optional"),this.aiModalSubtitle&&(this.aiModalSubtitle.textContent=e),this.setAiOutputButtonsEnabled(!1),this.updateAiBasePreview(),this.updateAiPreview(),this.renderAiGallery())}openAiModal(e,t,i){var o,l,c,d,p,u,g,h,f,m;this.closeAiModal(),this.aiTargetKey=e,this.aiBaseValue=t||null,this.aiContext=i||null,this.aiOutputDataUrl=null,this.aiOutputKey=null,this.aiReferenceFile=null,this.aiBaseDataUrl=null;let n=document.createElement("div");n.className="ai-modal",n.innerHTML=`
|
|
1770
1772
|
<div class="ai-modal-card">
|
|
1771
1773
|
<div class="ai-modal-header">
|
|
1772
1774
|
<div>
|
|
@@ -1837,7 +1839,7 @@ Generate the requested asset matching the brand style.${s.needsTransparency?" Ba
|
|
|
1837
1839
|
</div>
|
|
1838
1840
|
</div>
|
|
1839
1841
|
</div>
|
|
1840
|
-
`;let a=n.querySelector(".ai-modal-close");a==null||a.addEventListener("click",()=>this.closeAiModal()),n.addEventListener("click",b=>{b.target===n&&this.closeAiModal()}),this.aiModal=n,this.aiKeyInput=n.querySelector("[data-ai-key]"),this.aiModelSelect=n.querySelector("[data-ai-model]"),this.aiPromptInput=n.querySelector("[data-ai-prompt]"),this.aiStrengthInput=n.querySelector("[data-ai-strength]"),this.aiStrengthValue=n.querySelector("[data-ai-strength-value]"),this.aiModalSubtitle=n.querySelector(".ai-modal-subtitle"),this.aiGalleryToggle=n.querySelector("[data-ai-gallery-toggle]"),this.aiGalleryEl=n.querySelector("[data-ai-gallery]"),this.aiGalleryGrid=n.querySelector("[data-ai-gallery-grid]"),this.aiReferenceInput=n.querySelector("[data-ai-ref-input]"),this.aiReferenceName=n.querySelector("[data-ai-ref-name]"),this.aiRemoveBgToggle=n.querySelector("[data-ai-remove-bg]"),this.aiUseOutputToggle=n.querySelector("[data-ai-use-output]"),this.aiGenerateBtn=n.querySelector("[data-ai-generate]"),this.aiApplyBtn=n.querySelector("[data-ai-apply]"),this.aiSaveLibraryBtn=n.querySelector("[data-ai-save-library]"),this.aiCropBtn=n.querySelector("[data-ai-crop]"),this.aiDownloadBtn=n.querySelector("[data-ai-download]"),this.aiPreviewImg=n.querySelector("[data-ai-preview]"),this.aiStatusEl=n.querySelector("[data-ai-status]"),this.aiLoadingEl=n.querySelector("[data-ai-loading]"),this.aiBgToleranceInput=n.querySelector("[data-ai-bg-tolerance]"),this.aiBgToleranceValue=n.querySelector("[data-ai-bg-tolerance-value]"),(o=this.aiRemoveBgToggle)==null||o.addEventListener("change",()=>{this.refreshAiOutputFromRaw()});let r=n.querySelector("[data-ai-ref-button]");r==null||r.addEventListener("click",()=>{var b;return(b=this.aiReferenceInput)==null?void 0:b.click()}),(l=this.aiGalleryToggle)==null||l.addEventListener("click",()=>this.toggleAiGallery()),(c=this.aiStrengthInput)==null||c.addEventListener("input",()=>{var y,v;let b=(v=(y=this.aiStrengthInput)==null?void 0:y.value)!=null?v:"5";this.aiStrengthValue&&(this.aiStrengthValue.textContent=b)}),(d=this.aiBgToleranceInput)==null||d.addEventListener("input",()=>{var y,v;let b=(v=(y=this.aiBgToleranceInput)==null?void 0:y.value)!=null?v:"30";this.aiBgToleranceValue&&(this.aiBgToleranceValue.textContent=b),this.refreshAiOutputFromRaw()}),(p=this.aiReferenceInput)==null||p.addEventListener("change",()=>{var y,v,w;let b=(w=(v=(y=this.aiReferenceInput)==null?void 0:y.files)==null?void 0:v[0])!=null?w:null;this.aiReferenceFile=b,this.aiReferenceName&&(this.aiReferenceName.textContent=b?`${b.name} (loaded)`:"Optional"),b&&this.setAiStatus(`Reference attached: ${b.name}`)}),(u=this.aiGenerateBtn)==null||u.addEventListener("click",()=>{this.handleAiGenerate()}),(g=this.aiApplyBtn)==null||g.addEventListener("click",()=>this.handleAiApply()),(h=this.aiSaveLibraryBtn)==null||h.addEventListener("click",()=>{this.handleAiSaveToLibrary()}),(f=this.aiCropBtn)==null||f.addEventListener("click",()=>{this.handleAiCrop()}),(m=this.aiDownloadBtn)==null||m.addEventListener("click",()=>this.handleAiDownload()),document.body.appendChild(n),this.setAiOutputButtonsEnabled(!1),this.setAiStatus("Ready."),this.updateAiBasePreview(t),this.updateAiPreview(),this.renderAiGallery()}closeAiModal(){this.aiModal&&(this.aiModal.remove(),this.aiModal=null),this.aiTargetKey=null,this.aiBaseValue=null,this.aiContext=null,this.aiKeyInput=null,this.aiModelSelect=null,this.aiPromptInput=null,this.aiStrengthInput=null,this.aiStrengthValue=null,this.aiModalSubtitle=null,this.aiGalleryToggle=null,this.aiGalleryEl=null,this.aiGalleryGrid=null,this.aiReferenceInput=null,this.aiReferenceName=null,this.aiReferenceFile=null,this.aiRemoveBgToggle=null,this.aiUseOutputToggle=null,this.aiGenerateBtn=null,this.aiApplyBtn=null,this.aiCropBtn=null,this.aiDownloadBtn=null,this.aiPreviewImg=null,this.aiStatusEl=null,this.aiLoadingEl=null,this.aiBgToleranceInput=null,this.aiBgToleranceValue=null}async handleAiGenerate(){var d,p,u,g,h,f,m,b,y,v,w,T,I,M,L,j,_,P,x,S;if(console.log("[CustomizePanel] handleAiGenerate clicked"),!this.aiGenerateBtn)return;let e=(u=(p=(d=this.aiKeyInput)==null?void 0:d.value)==null?void 0:p.trim())!=null?u:"",t=(h=(g=this.aiModelSelect)==null?void 0:g.value)!=null?h:"gemini-2.5-flash-image",i=(b=(m=(f=this.aiPromptInput)==null?void 0:f.value)==null?void 0:m.trim())!=null?b:"",n=(v=(y=this.aiRemoveBgToggle)==null?void 0:y.checked)!=null?v:!1,a=n,r=n,o=Number((T=(w=this.aiStrengthInput)==null?void 0:w.value)!=null?T:"5");if(!e){this.setAiStatus("Missing API key.");return}if(!i){this.setAiStatus("Add a prompt.");return}let l=this.getSelectedAssetInput(),c=((I=l==null?void 0:l.value)==null?void 0:I.trim())||((M=this.aiBaseValue)==null?void 0:M.trim())||"";this.setAiLoading(!0),this.setAiStatus(c?"Generating...":"Generating from scratch...");try{let A=null,E=null,C=(L=this.getSelectedAssetKey())!=null?L:"unknown",O=(j=this.aiUseOutputToggle)!=null&&j.checked&&this.aiOutputDataUrl?"ai-output":"asset-value";if((_=this.aiUseOutputToggle)!=null&&_.checked&&this.aiOutputDataUrl){let G=da(this.aiOutputDataUrl,"ai-output.png");if(G){let B=await Fe(G);B&&(A={input:{base64:B.base64,mimeType:B.mimeType},dataUrl:B.dataUrl,width:B.width,height:B.height})}}!A&&c&&(A=await this.getImageDataFromAsset(c));let k=[];A&&k.push(A.input);let R=!1;if(this.aiReferenceFile){let G=await Fe(this.aiReferenceFile);G?(E={input:{base64:G.base64,mimeType:G.mimeType},dataUrl:G.dataUrl,width:G.width,height:G.height},k.push(E.input),R=!0,this.setAiStatus(`Generating with reference: ${this.aiReferenceFile.name}`)):this.setAiStatus("Reference image failed to load, generating without reference.")}let z=br(i,{includeReference:R,includeMagenta:a,changeLevel:o}),D=(x=(P=this.aiReferenceFile)==null?void 0:P.name)!=null?x:"none";console.info("[AI] Final prompt:",z),console.info("[AI] Image sources:",{assetKey:C,base:O,reference:D});let U=A?pa(A.width,A.height):E?pa(E.width,E.height):"1:1";console.info("[AI] CRITICAL: Calling generateImageWithGemini25Flash NOW...");let F=await ft(e,z,k,{aspectRatio:U,model:t});console.info("[AI] CRITICAL: generateImageWithGemini25Flash returned! Length:",F==null?void 0:F.length),this.aiRawOutputDataUrl=F,await this.refreshAiOutputFromRaw()}catch(A){console.error("[CustomizePanel] AI Generate Error:",A),this.setAiStatus("Generation failed. Check console.")}finally{this.setAiLoading(!1),((S=this.aiStatusEl)==null?void 0:S.textContent)==="Generating..."&&this.setAiStatus("Ready.")}}async refreshAiOutputFromRaw(){var n,a,r,o;if(!this.aiRawOutputDataUrl)return;let e=(a=(n=this.aiRemoveBgToggle)==null?void 0:n.checked)!=null?a:!1,t=Number((o=(r=this.aiBgToleranceInput)==null?void 0:r.value)!=null?o:"30"),i=this.aiRawOutputDataUrl;if(e){let l=await ht(this.aiRawOutputDataUrl,t);l&&(i=l)}this.setAiOutput(i),this.setAiStatus("Ready.")}setAiOutput(e){var i,n;this.aiOutputDataUrl=e,this.aiOutputKey=this.getSelectedAssetKey(),this.updateAiPreview(),this.setAiOutputButtonsEnabled(!0);let t=(i=this.previewModal)==null?void 0:i.querySelector("[data-asset-ai-preview]");this.updateAiModalPreview(t,(n=this.activePreviewKey)!=null?n:void 0)}setAiOutputButtonsEnabled(e){this.aiApplyBtn&&(this.aiApplyBtn.disabled=!e),this.aiSaveLibraryBtn&&(this.aiSaveLibraryBtn.disabled=!e),this.aiCropBtn&&(this.aiCropBtn.disabled=!e),this.aiDownloadBtn&&(this.aiDownloadBtn.disabled=!e)}handleAiApply(){var t,i,n;let e=this.getSelectedAssetInput();if(!this.aiOutputDataUrl){this.setAiStatus("Generate output first.");return}if(e)console.log("[CustomizePanel] Applying AI output to brand asset:",e.dataset.assetKey),e.value=this.aiOutputDataUrl,this.handleAssetValueChange((t=e.dataset.assetKey)!=null?t:"",e),this.setAiStatus("Applied. Restarting game...");else{let a=((i=this.aiContext)==null?void 0:i.objectId)||this.inferObjectIdFromAssetKey(this.aiTargetKey||""),r=((n=this.aiContext)==null?void 0:n.path)||this.inferPathFromAssetKey(this.aiTargetKey||"");if(a&&r)console.log("[CustomizePanel] Applying AI output directly to object:",a,r),this.applyObjectPropertyValue(a,r,this.aiOutputDataUrl),this.setAiStatus("Applied directly. Restarting game..."),window.dispatchEvent(new CustomEvent("inspector:refresh"));else{this.setAiStatus("No target input found to apply.");return}}setTimeout(()=>{this.closeAiModal()},500)}async handleAiSaveToLibrary(){var a,r,o;if(!this.aiOutputDataUrl){this.setAiStatus("Generate output first.");return}if(!this.getSelectedAssetKey()){this.setAiStatus("No asset selected.");return}let i=`${(this.aiTargetKey||"asset").replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"")}_ai_generated`,n=this.inferCategoryFromAssetKey(this.aiTargetKey||"");this.setAiStatus("Saving to library...");try{let c=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:n,filename:`${i}.png`,data:this.aiOutputDataUrl,overwrite:!0})})).json();if(c.success){console.log("[CustomizePanel] \u2705 Saved to library:",c.path),this.setAiStatus(`Saved as ${i}.png. Refreshing library...`);let d=window.addAssetToRegistry;typeof d=="function"&&(console.log("[CustomizePanel] Adding to registry category:",n),d(n,`${i}.png`));try{console.log("[CustomizePanel] Triggering setup-library..."),(await fetch("/api/setup-library",{method:"POST",headers:{"Content-Type":"application/json"}})).ok?console.log("[CustomizePanel] \u2705 Library setup completed"):console.warn("[CustomizePanel] Setup-library returned non-OK status")}catch(b){console.warn("[CustomizePanel] Setup-library endpoint not available:",b)}let p=window.refreshAssetLibrary;typeof p=="function"&&(console.log("[CustomizePanel] Refreshing library panel..."),await p());let u=window.__wizardAssetPicker;if(u!=null&&u.onPick){u.onPick(c.path),window.__wizardAssetPicker=null,this.setAiStatus("Saved to library and applied to wizard.");return}let g=((a=this.aiContext)==null?void 0:a.objectId)||this.inferObjectIdFromAssetKey(this.aiTargetKey||""),h=((r=this.aiContext)==null?void 0:r.path)||this.inferPathFromAssetKey(this.aiTargetKey||""),f=this.getSelectedAssetInput();if(f&&(f.value=c.path,this.handleAssetValueChange((o=f.dataset.assetKey)!=null?o:"",f)),g&&h){console.log("[CustomizePanel] Applying saved asset to object:",g,h);let b=window.applyAssetToSlot,y=/texture|image|sprite|asset\\.path/i.test(h)||/\\.(png|jpg|jpeg)$/i.test(String(c.path||""));if(typeof b=="function"&&y){let v=this.getFilenameFromPath(c.path);await b(g,v,n)}else this.applyObjectPropertyValue(g,h,c.path);window.dispatchEvent(new CustomEvent("inspector:refresh"))}let m=window.__highlightLibrarySlot;typeof m=="function"&&g&&(console.log("[CustomizePanel] Highlighting slot in library:",g,n),setTimeout(()=>{m(g,n)},500)),this.setAiStatus(`\u2705 Saved and applied ${i}.png`),setTimeout(()=>{this.closeAiModal()},1500)}else console.error("[CustomizePanel] \u274C Save failed:",c.error),this.setAiStatus(`Save failed: ${c.error}`)}catch(l){console.error("[CustomizePanel] \u274C Save error:",l),this.setAiStatus("Save failed. Check console.")}}inferCategoryFromAssetKey(e){var r;let t=(r=this.aiContext)==null?void 0:r.objectId,i=e||this.aiTargetKey||"",n=window.getEditableAssets;if(typeof n=="function"){let o=n();if(o!=null&&o.slots){let l=o.slots.find(c=>t&&c.objectId===t||c.currentAsset===i||c.slotId===i||c.currentAsset&&c.currentAsset.includes(i)||i.includes(c.slotId));if(l){let c=l.libraryFolder||l.category;if(c)return c}}}let a=i.toLowerCase();return a.includes("background")?"backgrounds":a.includes("character")?"characters":a.includes("key")?"collectedkeys":a.includes("draggable")?"draggables":a.includes("environment")||a.includes("env")||a.includes("hand")||a.includes("prop")||a.includes("item")||a.includes("decor")||a.includes("object")?"environment":a.includes("machine")?"machines":a.includes("tutorial")?"tutorial":a.includes("ui")||a.includes("button")||a.includes("label")||a.includes("icon")||a.includes("logo")||a.includes("cta")||a.includes("menu")||a.includes("overlay")?"ui":a.includes("effect")||a.includes("confetti")||a.includes("particle")?"effects":"ui"}inferObjectIdFromAssetKey(e){let t=window.getEditableAssets;if(typeof t!="function")return null;let i=t();if(!(i!=null&&i.slots))return null;let n=i.slots.find(a=>a.currentAsset===e||a.slotId===e);return(n==null?void 0:n.objectId)||null}inferPathFromAssetKey(e){let t=window.getEditableAssets;if(typeof t!="function")return null;let i=t();if(!(i!=null&&i.slots))return null;let n=i.slots.find(r=>r.currentAsset===e||r.slotId===e);if(!n)return null;let a=n.category;return a==="render"||a==="backgrounds"||a==="characters"?"render.texture":a==="ui"?"ui.image":a==="audio"?"audio.src":"render.texture"}getFilenameFromPath(e){if(!e)return"";let t=e.split("/");return t[t.length-1]}async handleAiCrop(){var o;if(!this.aiOutputDataUrl){this.setAiStatus("Generate output first.");return}let e=this.getSelectedAssetInput(),t=(o=e==null?void 0:e.value)!=null?o:"",i=await this.getImageDimensions(t);if(!i){this.setAiStatus("Unable to read target dimensions.");return}let n=da(this.aiOutputDataUrl,"ai-output.png");if(!n)return;let a=await this.showManualCropModal(n,i,t);if(!a)return;let r=await ca(a);r&&this.setAiOutput(r)}handleAiDownload(){var i;if(!this.aiOutputDataUrl)return;let e=(i=this.getSelectedAssetKey())!=null?i:"ai-image",t=document.createElement("a");t.href=this.aiOutputDataUrl,t.download=`${e}-ai.png`,t.click()}handleAssetValueChange(e,t){this.previewModal&&this.closePreviewModal(),this.scheduleAutoApply(),this.updatePreviewIfOpen(e,t.value,t.dataset.assetType)}async handleAssetUpload(e,t,i){console.log("[CustomizePanel] Handling asset upload for:",i);let n=t.value,a=e;if(e.type.startsWith("image/")){let d=await this.getImageDimensions(n);if(d){let p=await this.showManualCropModal(e,d,n);if(!p)return;a=p}}let r=await ca(a);if(!r){console.error("[CustomizePanel] Failed to convert file to data URL");return}let l=`${i.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"")}_uploaded`,c=this.inferCategoryFromAssetKey(i);console.log("[CustomizePanel] Saving uploaded file to library:",l,"category:",c);try{let p=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:c,filename:`${l}.png`,data:r,overwrite:!0})})).json();if(p.success){console.log("[CustomizePanel] \u2705 Uploaded file saved to library:",p.path);let u=window.addAssetToRegistry;typeof u=="function"&&u(c,`${l}.png`);try{await fetch("/api/setup-library",{method:"POST",headers:{"Content-Type":"application/json"}})}catch(b){console.warn("[CustomizePanel] Setup-library not available:",b)}let g=window.refreshAssetLibrary;typeof g=="function"&&await g(),t.value=p.path,this.handleAssetValueChange(i,t);let h=this.inferObjectIdFromAssetKey(i),f=this.inferPathFromAssetKey(i);if(h&&f){let b=window.applyAssetToSlot,y=/texture|image|sprite|asset\\.path/i.test(f)||/\\.(png|jpg|jpeg)$/i.test(String(p.path||""));if(typeof b=="function"&&y){let v=this.getFilenameFromPath(p.path);await b(h,v,c)}else this.applyObjectPropertyValue(h,f,p.path);window.dispatchEvent(new CustomEvent("inspector:refresh"))}let m=window.__highlightLibrarySlot;typeof m=="function"&&h&&setTimeout(()=>{m(h,c)},500),console.log("[CustomizePanel] \u2705 Upload complete:",l)}else console.error("[CustomizePanel] \u274C Upload save failed:",p.error),alert(`Failed to save uploaded file: ${p.error}`)}catch(d){console.error("[CustomizePanel] \u274C Upload error:",d),alert("Failed to save uploaded file. Check console for details.")}}scheduleAutoApply(){this.options&&(this.autoApplyTimer&&window.clearTimeout(this.autoApplyTimer),console.log("[CustomizePanel] Scheduling auto-apply in 250ms"),this.autoApplyTimer=window.setTimeout(()=>{this.autoApplyTimer=null,console.log("[CustomizePanel] Executing auto-apply now"),this.handleApplyWithSource("auto")},250))}previewAsset(e,t,i,n){if(!t)return;let a=this.resolveAssetUrls(t);if(a.length===0)return;let r=i||this.guessMimeType(t);this.activePreviewKey=e,this.activePreviewValue=t,this.activePreviewFileInput=n!=null?n:null,this.openPreviewModal(e,t,a,r)}resolveAssetUrls(e){let t=e.trim();if(!t)return[];if(console.log("[CustomizePanel] Resolving asset urls for:",t),/^(blob:|data:|https?:|\/)/.test(t))return console.log("[CustomizePanel] Path is absolute or data/blob, using as is"),[t];let i=t.replace(/^\.?\//,""),n=[];return i.startsWith("raw/")?n=[`/${i}`,`/assets/${i}`]:i.startsWith("assets/")?n=[`/${i}`]:n=[`/raw/${i}`,`/assets/raw/${i}`,`/assets/${i}`,`/${i}`],console.log("[CustomizePanel] Resolved to possible paths:",n),n}guessMimeType(e){let t=e.toLowerCase();return t.endsWith(".png")||t.endsWith(".jpg")||t.endsWith(".jpeg")||t.endsWith(".gif")||t.endsWith(".webp")||t.endsWith(".svg")?"image":t.endsWith(".mp3")||t.endsWith(".wav")||t.endsWith(".ogg")?"audio":t.endsWith(".json")?"json":"file"}openPreviewModal(e,t,i,n){this.closePreviewModal(!0);let a=document.createElement("div");a.className="asset-preview-modal",a.innerHTML=`
|
|
1842
|
+
`;let a=n.querySelector(".ai-modal-close");a==null||a.addEventListener("click",()=>this.closeAiModal()),n.addEventListener("click",b=>{b.target===n&&this.closeAiModal()}),this.aiModal=n,this.aiKeyInput=n.querySelector("[data-ai-key]"),this.aiModelSelect=n.querySelector("[data-ai-model]"),this.aiPromptInput=n.querySelector("[data-ai-prompt]"),this.aiStrengthInput=n.querySelector("[data-ai-strength]"),this.aiStrengthValue=n.querySelector("[data-ai-strength-value]"),this.aiModalSubtitle=n.querySelector(".ai-modal-subtitle"),this.aiGalleryToggle=n.querySelector("[data-ai-gallery-toggle]"),this.aiGalleryEl=n.querySelector("[data-ai-gallery]"),this.aiGalleryGrid=n.querySelector("[data-ai-gallery-grid]"),this.aiReferenceInput=n.querySelector("[data-ai-ref-input]"),this.aiReferenceName=n.querySelector("[data-ai-ref-name]"),this.aiRemoveBgToggle=n.querySelector("[data-ai-remove-bg]"),this.aiUseOutputToggle=n.querySelector("[data-ai-use-output]"),this.aiGenerateBtn=n.querySelector("[data-ai-generate]"),this.aiApplyBtn=n.querySelector("[data-ai-apply]"),this.aiSaveLibraryBtn=n.querySelector("[data-ai-save-library]"),this.aiCropBtn=n.querySelector("[data-ai-crop]"),this.aiDownloadBtn=n.querySelector("[data-ai-download]"),this.aiPreviewImg=n.querySelector("[data-ai-preview]"),this.aiStatusEl=n.querySelector("[data-ai-status]"),this.aiLoadingEl=n.querySelector("[data-ai-loading]"),this.aiBgToleranceInput=n.querySelector("[data-ai-bg-tolerance]"),this.aiBgToleranceValue=n.querySelector("[data-ai-bg-tolerance-value]"),(o=this.aiRemoveBgToggle)==null||o.addEventListener("change",()=>{this.refreshAiOutputFromRaw()});let s=n.querySelector("[data-ai-ref-button]");s==null||s.addEventListener("click",()=>{var b;return(b=this.aiReferenceInput)==null?void 0:b.click()}),(l=this.aiGalleryToggle)==null||l.addEventListener("click",()=>this.toggleAiGallery()),(c=this.aiStrengthInput)==null||c.addEventListener("input",()=>{var y,v;let b=(v=(y=this.aiStrengthInput)==null?void 0:y.value)!=null?v:"5";this.aiStrengthValue&&(this.aiStrengthValue.textContent=b)}),(d=this.aiBgToleranceInput)==null||d.addEventListener("input",()=>{var y,v;let b=(v=(y=this.aiBgToleranceInput)==null?void 0:y.value)!=null?v:"30";this.aiBgToleranceValue&&(this.aiBgToleranceValue.textContent=b),this.refreshAiOutputFromRaw()}),(p=this.aiReferenceInput)==null||p.addEventListener("change",()=>{var y,v,w;let b=(w=(v=(y=this.aiReferenceInput)==null?void 0:y.files)==null?void 0:v[0])!=null?w:null;this.aiReferenceFile=b,this.aiReferenceName&&(this.aiReferenceName.textContent=b?`${b.name} (loaded)`:"Optional"),b&&this.setAiStatus(`Reference attached: ${b.name}`)}),(u=this.aiGenerateBtn)==null||u.addEventListener("click",()=>{this.handleAiGenerate()}),(g=this.aiApplyBtn)==null||g.addEventListener("click",()=>this.handleAiApply()),(h=this.aiSaveLibraryBtn)==null||h.addEventListener("click",()=>{this.handleAiSaveToLibrary()}),(f=this.aiCropBtn)==null||f.addEventListener("click",()=>{this.handleAiCrop()}),(m=this.aiDownloadBtn)==null||m.addEventListener("click",()=>this.handleAiDownload()),document.body.appendChild(n),this.setAiOutputButtonsEnabled(!1),this.setAiStatus("Ready."),this.updateAiBasePreview(t),this.updateAiPreview(),this.renderAiGallery()}closeAiModal(){this.aiModal&&(this.aiModal.remove(),this.aiModal=null),this.aiTargetKey=null,this.aiBaseValue=null,this.aiContext=null,this.aiKeyInput=null,this.aiModelSelect=null,this.aiPromptInput=null,this.aiStrengthInput=null,this.aiStrengthValue=null,this.aiModalSubtitle=null,this.aiGalleryToggle=null,this.aiGalleryEl=null,this.aiGalleryGrid=null,this.aiReferenceInput=null,this.aiReferenceName=null,this.aiReferenceFile=null,this.aiRemoveBgToggle=null,this.aiUseOutputToggle=null,this.aiGenerateBtn=null,this.aiApplyBtn=null,this.aiCropBtn=null,this.aiDownloadBtn=null,this.aiPreviewImg=null,this.aiStatusEl=null,this.aiLoadingEl=null,this.aiBgToleranceInput=null,this.aiBgToleranceValue=null}async handleAiGenerate(){var d,p,u,g,h,f,m,b,y,v,w,T,I,M,L,j,_,P,x,S;if(console.log("[CustomizePanel] handleAiGenerate clicked"),!this.aiGenerateBtn)return;let e=(u=(p=(d=this.aiKeyInput)==null?void 0:d.value)==null?void 0:p.trim())!=null?u:"",t=(h=(g=this.aiModelSelect)==null?void 0:g.value)!=null?h:"gemini-2.5-flash-image",i=(b=(m=(f=this.aiPromptInput)==null?void 0:f.value)==null?void 0:m.trim())!=null?b:"",n=(v=(y=this.aiRemoveBgToggle)==null?void 0:y.checked)!=null?v:!1,a=n,s=n,o=Number((T=(w=this.aiStrengthInput)==null?void 0:w.value)!=null?T:"5");if(!e){this.setAiStatus("Missing API key.");return}if(!i){this.setAiStatus("Add a prompt.");return}let l=this.getSelectedAssetInput(),c=((I=l==null?void 0:l.value)==null?void 0:I.trim())||((M=this.aiBaseValue)==null?void 0:M.trim())||"";this.setAiLoading(!0),this.setAiStatus(c?"Generating...":"Generating from scratch...");try{let A=null,E=null,C=(L=this.getSelectedAssetKey())!=null?L:"unknown",O=(j=this.aiUseOutputToggle)!=null&&j.checked&&this.aiOutputDataUrl?"ai-output":"asset-value";if((_=this.aiUseOutputToggle)!=null&&_.checked&&this.aiOutputDataUrl){let G=da(this.aiOutputDataUrl,"ai-output.png");if(G){let B=await Fe(G);B&&(A={input:{base64:B.base64,mimeType:B.mimeType},dataUrl:B.dataUrl,width:B.width,height:B.height})}}!A&&c&&(A=await this.getImageDataFromAsset(c));let k=[];A&&k.push(A.input);let R=!1;if(this.aiReferenceFile){let G=await Fe(this.aiReferenceFile);G?(E={input:{base64:G.base64,mimeType:G.mimeType},dataUrl:G.dataUrl,width:G.width,height:G.height},k.push(E.input),R=!0,this.setAiStatus(`Generating with reference: ${this.aiReferenceFile.name}`)):this.setAiStatus("Reference image failed to load, generating without reference.")}let z=br(i,{includeReference:R,includeMagenta:a,changeLevel:o}),D=(x=(P=this.aiReferenceFile)==null?void 0:P.name)!=null?x:"none";console.info("[AI] Final prompt:",z),console.info("[AI] Image sources:",{assetKey:C,base:O,reference:D});let U=A?pa(A.width,A.height):E?pa(E.width,E.height):"1:1";console.info("[AI] CRITICAL: Calling generateImageWithGemini25Flash NOW...");let F=await ft(e,z,k,{aspectRatio:U,model:t});console.info("[AI] CRITICAL: generateImageWithGemini25Flash returned! Length:",F==null?void 0:F.length),this.aiRawOutputDataUrl=F,await this.refreshAiOutputFromRaw()}catch(A){console.error("[CustomizePanel] AI Generate Error:",A),this.setAiStatus("Generation failed. Check console.")}finally{this.setAiLoading(!1),((S=this.aiStatusEl)==null?void 0:S.textContent)==="Generating..."&&this.setAiStatus("Ready.")}}async refreshAiOutputFromRaw(){var n,a,s,o;if(!this.aiRawOutputDataUrl)return;let e=(a=(n=this.aiRemoveBgToggle)==null?void 0:n.checked)!=null?a:!1,t=Number((o=(s=this.aiBgToleranceInput)==null?void 0:s.value)!=null?o:"30"),i=this.aiRawOutputDataUrl;if(e){let l=await ht(this.aiRawOutputDataUrl,t);l&&(i=l)}this.setAiOutput(i),this.setAiStatus("Ready.")}setAiOutput(e){var i,n;this.aiOutputDataUrl=e,this.aiOutputKey=this.getSelectedAssetKey(),this.updateAiPreview(),this.setAiOutputButtonsEnabled(!0);let t=(i=this.previewModal)==null?void 0:i.querySelector("[data-asset-ai-preview]");this.updateAiModalPreview(t,(n=this.activePreviewKey)!=null?n:void 0)}setAiOutputButtonsEnabled(e){this.aiApplyBtn&&(this.aiApplyBtn.disabled=!e),this.aiSaveLibraryBtn&&(this.aiSaveLibraryBtn.disabled=!e),this.aiCropBtn&&(this.aiCropBtn.disabled=!e),this.aiDownloadBtn&&(this.aiDownloadBtn.disabled=!e)}handleAiApply(){var t,i,n;let e=this.getSelectedAssetInput();if(!this.aiOutputDataUrl){this.setAiStatus("Generate output first.");return}if(e)console.log("[CustomizePanel] Applying AI output to brand asset:",e.dataset.assetKey),e.value=this.aiOutputDataUrl,this.handleAssetValueChange((t=e.dataset.assetKey)!=null?t:"",e),this.setAiStatus("Applied. Restarting game...");else{let a=((i=this.aiContext)==null?void 0:i.objectId)||this.inferObjectIdFromAssetKey(this.aiTargetKey||""),s=((n=this.aiContext)==null?void 0:n.path)||this.inferPathFromAssetKey(this.aiTargetKey||"");if(a&&s)console.log("[CustomizePanel] Applying AI output directly to object:",a,s),this.applyObjectPropertyValue(a,s,this.aiOutputDataUrl),this.setAiStatus("Applied directly. Restarting game..."),window.dispatchEvent(new CustomEvent("inspector:refresh"));else{this.setAiStatus("No target input found to apply.");return}}setTimeout(()=>{this.closeAiModal()},500)}async handleAiSaveToLibrary(){var a,s,o;if(!this.aiOutputDataUrl){this.setAiStatus("Generate output first.");return}if(!this.getSelectedAssetKey()){this.setAiStatus("No asset selected.");return}let i=`${(this.aiTargetKey||"asset").replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"")}_ai_generated`,n=this.inferCategoryFromAssetKey(this.aiTargetKey||"");this.setAiStatus("Saving to library...");try{let c=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:n,filename:`${i}.png`,data:this.aiOutputDataUrl,overwrite:!0})})).json();if(c.success){console.log("[CustomizePanel] \u2705 Saved to library:",c.path),this.setAiStatus(`Saved as ${i}.png. Refreshing library...`);let d=window.addAssetToRegistry;typeof d=="function"&&(console.log("[CustomizePanel] Adding to registry category:",n),d(n,`${i}.png`));try{console.log("[CustomizePanel] Triggering setup-library..."),(await fetch("/api/setup-library",{method:"POST",headers:{"Content-Type":"application/json"}})).ok?console.log("[CustomizePanel] \u2705 Library setup completed"):console.warn("[CustomizePanel] Setup-library returned non-OK status")}catch(b){console.warn("[CustomizePanel] Setup-library endpoint not available:",b)}let p=window.refreshAssetLibrary;typeof p=="function"&&(console.log("[CustomizePanel] Refreshing library panel..."),await p());let u=window.__wizardAssetPicker;if(u!=null&&u.onPick){u.onPick(c.path),window.__wizardAssetPicker=null,this.setAiStatus("Saved to library and applied to wizard.");return}let g=((a=this.aiContext)==null?void 0:a.objectId)||this.inferObjectIdFromAssetKey(this.aiTargetKey||""),h=((s=this.aiContext)==null?void 0:s.path)||this.inferPathFromAssetKey(this.aiTargetKey||""),f=this.getSelectedAssetInput();if(f&&(f.value=c.path,this.handleAssetValueChange((o=f.dataset.assetKey)!=null?o:"",f)),g&&h){console.log("[CustomizePanel] Applying saved asset to object:",g,h);let b=window.applyAssetToSlot,y=/texture|image|sprite|asset\\.path/i.test(h)||/\\.(png|jpg|jpeg)$/i.test(String(c.path||""));if(typeof b=="function"&&y){let v=this.getFilenameFromPath(c.path);await b(g,v,n)}else this.applyObjectPropertyValue(g,h,c.path);window.dispatchEvent(new CustomEvent("inspector:refresh"))}let m=window.__highlightLibrarySlot;typeof m=="function"&&g&&(console.log("[CustomizePanel] Highlighting slot in library:",g,n),setTimeout(()=>{m(g,n)},500)),this.setAiStatus(`\u2705 Saved and applied ${i}.png`),setTimeout(()=>{this.closeAiModal()},1500)}else console.error("[CustomizePanel] \u274C Save failed:",c.error),this.setAiStatus(`Save failed: ${c.error}`)}catch(l){console.error("[CustomizePanel] \u274C Save error:",l),this.setAiStatus("Save failed. Check console.")}}inferCategoryFromAssetKey(e){var s;let t=(s=this.aiContext)==null?void 0:s.objectId,i=e||this.aiTargetKey||"",n=window.getEditableAssets;if(typeof n=="function"){let o=n();if(o!=null&&o.slots){let l=o.slots.find(c=>t&&c.objectId===t||c.currentAsset===i||c.slotId===i||c.currentAsset&&c.currentAsset.includes(i)||i.includes(c.slotId));if(l){let c=l.libraryFolder||l.category;if(c)return c}}}let a=i.toLowerCase();return a.includes("background")?"backgrounds":a.includes("character")?"characters":a.includes("key")?"collectedkeys":a.includes("draggable")?"draggables":a.includes("environment")||a.includes("env")||a.includes("hand")||a.includes("prop")||a.includes("item")||a.includes("decor")||a.includes("object")?"environment":a.includes("machine")?"machines":a.includes("tutorial")?"tutorial":a.includes("ui")||a.includes("button")||a.includes("label")||a.includes("icon")||a.includes("logo")||a.includes("cta")||a.includes("menu")||a.includes("overlay")?"ui":a.includes("effect")||a.includes("confetti")||a.includes("particle")?"effects":"ui"}inferObjectIdFromAssetKey(e){let t=window.getEditableAssets;if(typeof t!="function")return null;let i=t();if(!(i!=null&&i.slots))return null;let n=i.slots.find(a=>a.currentAsset===e||a.slotId===e);return(n==null?void 0:n.objectId)||null}inferPathFromAssetKey(e){let t=window.getEditableAssets;if(typeof t!="function")return null;let i=t();if(!(i!=null&&i.slots))return null;let n=i.slots.find(s=>s.currentAsset===e||s.slotId===e);if(!n)return null;let a=n.category;return a==="render"||a==="backgrounds"||a==="characters"?"render.texture":a==="ui"?"ui.image":a==="audio"?"audio.src":"render.texture"}getFilenameFromPath(e){if(!e)return"";let t=e.split("/");return t[t.length-1]}async handleAiCrop(){var o;if(!this.aiOutputDataUrl){this.setAiStatus("Generate output first.");return}let e=this.getSelectedAssetInput(),t=(o=e==null?void 0:e.value)!=null?o:"",i=await this.getImageDimensions(t);if(!i){this.setAiStatus("Unable to read target dimensions.");return}let n=da(this.aiOutputDataUrl,"ai-output.png");if(!n)return;let a=await this.showManualCropModal(n,i,t);if(!a)return;let s=await ca(a);s&&this.setAiOutput(s)}handleAiDownload(){var i;if(!this.aiOutputDataUrl)return;let e=(i=this.getSelectedAssetKey())!=null?i:"ai-image",t=document.createElement("a");t.href=this.aiOutputDataUrl,t.download=`${e}-ai.png`,t.click()}handleAssetValueChange(e,t){this.previewModal&&this.closePreviewModal(),this.scheduleAutoApply(),this.updatePreviewIfOpen(e,t.value,t.dataset.assetType)}async handleAssetUpload(e,t,i){console.log("[CustomizePanel] Handling asset upload for:",i);let n=t.value,a=e;if(e.type.startsWith("image/")){let d=await this.getImageDimensions(n);if(d){let p=await this.showManualCropModal(e,d,n);if(!p)return;a=p}}let s=await ca(a);if(!s){console.error("[CustomizePanel] Failed to convert file to data URL");return}let l=`${i.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"")}_uploaded`,c=this.inferCategoryFromAssetKey(i);console.log("[CustomizePanel] Saving uploaded file to library:",l,"category:",c);try{let p=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:c,filename:`${l}.png`,data:s,overwrite:!0})})).json();if(p.success){console.log("[CustomizePanel] \u2705 Uploaded file saved to library:",p.path);let u=window.addAssetToRegistry;typeof u=="function"&&u(c,`${l}.png`);try{await fetch("/api/setup-library",{method:"POST",headers:{"Content-Type":"application/json"}})}catch(b){console.warn("[CustomizePanel] Setup-library not available:",b)}let g=window.refreshAssetLibrary;typeof g=="function"&&await g(),t.value=p.path,this.handleAssetValueChange(i,t);let h=this.inferObjectIdFromAssetKey(i),f=this.inferPathFromAssetKey(i);if(h&&f){let b=window.applyAssetToSlot,y=/texture|image|sprite|asset\\.path/i.test(f)||/\\.(png|jpg|jpeg)$/i.test(String(p.path||""));if(typeof b=="function"&&y){let v=this.getFilenameFromPath(p.path);await b(h,v,c)}else this.applyObjectPropertyValue(h,f,p.path);window.dispatchEvent(new CustomEvent("inspector:refresh"))}let m=window.__highlightLibrarySlot;typeof m=="function"&&h&&setTimeout(()=>{m(h,c)},500),console.log("[CustomizePanel] \u2705 Upload complete:",l)}else console.error("[CustomizePanel] \u274C Upload save failed:",p.error),alert(`Failed to save uploaded file: ${p.error}`)}catch(d){console.error("[CustomizePanel] \u274C Upload error:",d),alert("Failed to save uploaded file. Check console for details.")}}scheduleAutoApply(){this.options&&(this.autoApplyTimer&&window.clearTimeout(this.autoApplyTimer),console.log("[CustomizePanel] Scheduling auto-apply in 250ms"),this.autoApplyTimer=window.setTimeout(()=>{this.autoApplyTimer=null,console.log("[CustomizePanel] Executing auto-apply now"),this.handleApplyWithSource("auto")},250))}previewAsset(e,t,i,n){if(!t)return;let a=this.resolveAssetUrls(t);if(a.length===0)return;let s=i||this.guessMimeType(t);this.activePreviewKey=e,this.activePreviewValue=t,this.activePreviewFileInput=n!=null?n:null,this.openPreviewModal(e,t,a,s)}resolveAssetUrls(e){let t=e.trim();if(!t)return[];if(console.log("[CustomizePanel] Resolving asset urls for:",t),/^(blob:|data:|https?:|\/)/.test(t))return console.log("[CustomizePanel] Path is absolute or data/blob, using as is"),[t];let i=t.replace(/^\.?\//,""),n=[];return i.startsWith("raw/")?n=[`/${i}`,`/assets/${i}`]:i.startsWith("assets/")?n=[`/${i}`]:n=[`/raw/${i}`,`/assets/raw/${i}`,`/assets/${i}`,`/${i}`],console.log("[CustomizePanel] Resolved to possible paths:",n),n}guessMimeType(e){let t=e.toLowerCase();return t.endsWith(".png")||t.endsWith(".jpg")||t.endsWith(".jpeg")||t.endsWith(".gif")||t.endsWith(".webp")||t.endsWith(".svg")?"image":t.endsWith(".mp3")||t.endsWith(".wav")||t.endsWith(".ogg")?"audio":t.endsWith(".json")?"json":"file"}openPreviewModal(e,t,i,n){this.closePreviewModal(!0);let a=document.createElement("div");a.className="asset-preview-modal",a.innerHTML=`
|
|
1841
1843
|
<div class="asset-preview-card">
|
|
1842
1844
|
<div class="asset-preview-header">
|
|
1843
1845
|
<div class="asset-preview-title">${e}</div>
|
|
@@ -1853,7 +1855,7 @@ Generate the requested asset matching the brand style.${s.needsTransparency?" Ba
|
|
|
1853
1855
|
<img class="asset-preview-ai-image" alt="AI output preview">
|
|
1854
1856
|
</div>
|
|
1855
1857
|
</div>
|
|
1856
|
-
`;let
|
|
1858
|
+
`;let s=a.querySelector(".asset-preview-body"),o=a.querySelector(".asset-preview-close"),l=a.querySelector(".asset-preview-change"),c=a.querySelector(".asset-preview-ai"),d=a.querySelector("[data-asset-ai-preview]");if(o==null||o.addEventListener("click",()=>this.closePreviewModal()),c==null||c.addEventListener("click",()=>{console.log("[CustomizePanel] AI Edit clicked for:",e),this.openAiModal(e,t)}),l==null||l.addEventListener("click",()=>{console.log("[CustomizePanel] Change clicked for:",e),this.activePreviewFileInput&&this.activePreviewFileInput.click()}),a.addEventListener("click",p=>{p.target===a&&this.closePreviewModal()}),s)if(n==="image"){let p=document.createElement("img");this.loadWithFallback(p,i),s.appendChild(p)}else if(n==="audio"){let p=document.createElement("audio");p.controls=!0,this.loadWithFallback(p,i),s.appendChild(p)}else if(n==="json"){let p=document.createElement("pre");this.fetchWithFallback(i).then(u=>{p.textContent=u!=null?u:"Unable to load JSON."}),s.appendChild(p)}else{let p=document.createElement("a");p.href=i[0],p.target="_blank",p.rel="noreferrer",p.textContent="Open asset",s.appendChild(p)}document.body.appendChild(a),this.previewModal=a,this.updateAiModalPreview(d,e)}loadWithFallback(e,t){if(t.length===0)return;let i=0,n=()=>{i>=t.length||(e.src=t[i],i+=1)};e.addEventListener("error",n),n()}async fetchWithFallback(e){for(let t of e)try{let i=await fetch(t);if(!i.ok)continue;return await i.text()}catch{}return null}applyObjectPropertyValue(e,t,i){let n=window.getEditableObjectConfig,a=window.applyEditableObjectConfig;if(typeof n!="function"||typeof a!="function")return;let s=n(e);if(!s)return;let o=JSON.parse(JSON.stringify(s)),l=t.split("."),c=o;for(let d=0;d<l.length-1;d++){let p=l[d];c[p]=c[p]||{},c=c[p]}c[l[l.length-1]]=i,a(e,o)}applyTextColorToObject(e,t){let n={warning_text_color:{objectId:"label.warning",property:"render.tint"},endgame_title_color:{objectId:"ui.endgame.title",property:"render.tint"},endgame_subtitle_color:{objectId:"ui.endgame.subtitle",property:"render.tint"},endgame_cta_text_color:{objectId:"ui.endgame.cta",property:"render.tint"},endgame_cta_hint_color:{objectId:"ui.endgame.cta.hint",property:"render.tint"},endgame_footer_color:{objectId:"ui.endgame.footer",property:"render.tint"}}[e];n&&this.applyObjectPropertyValue(n.objectId,n.property,t)}closePreviewModal(e){this.previewModal&&(this.previewModal.remove(),this.previewModal=null),e||(this.activePreviewKey=null,this.activePreviewValue=null,this.activePreviewFileInput=null)}updatePreviewIfOpen(e,t,i){var a;if(!this.previewModal||this.activePreviewKey!==e)return;let n=t!=null?t:"";this.activePreviewValue!==n&&this.previewAsset(e,n,i,(a=this.activePreviewFileInput)!=null?a:void 0)}scheduleRetry(){this.retryTimer||(this.retryTimer=window.setTimeout(()=>{this.retryTimer=null,this.refresh()},350))}clearRetry(){this.retryTimer&&(window.clearTimeout(this.retryTimer),this.retryTimer=null)}setupResizeHandle(){if(!this.root)return;let e=this.root.querySelector("[data-panel-resize]");if(!e)return;let t=window.localStorage.getItem("customizePanelWidth"),i=t?Number(t):NaN;Number.isFinite(i)&&i>0&&(this.root.style.width=`${i}px`);let n=a=>{var u,g;a.preventDefault();let s=a.clientX,o=(g=(u=this.root)==null?void 0:u.getBoundingClientRect().width)!=null?g:0,l=260,c=620,d=h=>{let f=h.clientX-s,m=Math.min(c,Math.max(l,o+f));this.root&&(this.root.style.width=`${m}px`)},p=()=>{var f,m;window.removeEventListener("pointermove",d),window.removeEventListener("pointerup",p);let h=(m=(f=this.root)==null?void 0:f.getBoundingClientRect().width)!=null?m:0;h>0&&window.localStorage.setItem("customizePanelWidth",String(Math.round(h)))};window.addEventListener("pointermove",d),window.addEventListener("pointerup",p)};e.addEventListener("pointerdown",n)}async getImageDimensions(e){let t=this.resolveAssetUrls(e);if(t.length===0)return null;for(let i of t){let n=await this.loadImage(i);if(n!=null&&n.naturalWidth&&(n!=null&&n.naturalHeight))return{width:n.naturalWidth,height:n.naturalHeight}}return null}async loadImage(e){return await new Promise(t=>{let i=new Image;i.onload=()=>t(i),i.onerror=()=>t(null),i.src=e})}async showManualCropModal(e,t,i){let n=t.width/t.height,a=URL.createObjectURL(e),s=await this.loadImage(a);try{URL.revokeObjectURL(a)}catch{}if(!(s!=null&&s.naturalWidth)||!(s!=null&&s.naturalHeight))return null;let o=await this.loadImageForValue(i);return await new Promise(l=>{let c=document.createElement("div");c.className="asset-crop-modal";let d=Math.min(860,window.innerWidth-60),h=Math.max(220,Math.floor((d-32-16)/2)),f=Math.min(520,window.innerHeight-240),m=h,b=m/n;b>f&&(b=f,m=b*n),c.innerHTML=`
|
|
1857
1859
|
<div class="asset-crop-card" style="width:${d}px;">
|
|
1858
1860
|
<div class="asset-crop-header">
|
|
1859
1861
|
<div>
|
|
@@ -1883,7 +1885,7 @@ Generate the requested asset matching the brand style.${s.needsTransparency?" Ba
|
|
|
1883
1885
|
<button class="asset-crop-apply" type="button">Apply Crop</button>
|
|
1884
1886
|
</div>
|
|
1885
1887
|
</div>
|
|
1886
|
-
`;let y=c.querySelector(".asset-crop-canvas"),v=c.querySelector(".asset-crop-preview"),w=c.querySelector(".asset-crop-zoom"),T=c.querySelector(".asset-crop-zoom-value"),I=c.querySelector(".asset-crop-close"),M=c.querySelector(".asset-crop-cancel"),L=c.querySelector(".asset-crop-apply"),j=c.querySelector(".asset-crop-reset");if(!y||!v||!w||!T){l(null);return}let _=y.getContext("2d"),P=v.getContext("2d");if(!_||!P){l(null);return}let x=
|
|
1888
|
+
`;let y=c.querySelector(".asset-crop-canvas"),v=c.querySelector(".asset-crop-preview"),w=c.querySelector(".asset-crop-zoom"),T=c.querySelector(".asset-crop-zoom-value"),I=c.querySelector(".asset-crop-close"),M=c.querySelector(".asset-crop-cancel"),L=c.querySelector(".asset-crop-apply"),j=c.querySelector(".asset-crop-reset");if(!y||!v||!w||!T){l(null);return}let _=y.getContext("2d"),P=v.getContext("2d");if(!_||!P){l(null);return}let x=s.naturalWidth,S=s.naturalHeight,A=Math.max(y.width/x,y.height/S),E=1,C=0,O=0,k=!1,R=0,z=0,D=0,U=0,F=()=>{let H=A*E,ae=Math.max(0,(x*H-y.width)/2),te=Math.max(0,(S*H-y.height)/2);C=Math.min(ae,Math.max(-ae,C)),O=Math.min(te,Math.max(-te,O))},G=()=>{let H=A*E;_.clearRect(0,0,y.width,y.height);let ae=y.width/2-x*H/2+C,te=y.height/2-S*H/2+O;if(_.drawImage(s,ae,te,x*H,S*H),P.clearRect(0,0,v.width,v.height),o!=null&&o.naturalWidth&&(o!=null&&o.naturalHeight)){let nt=Math.max(v.width/o.naturalWidth,v.height/o.naturalHeight),Cn=v.width/2-o.naturalWidth*nt/2,kt=v.height/2-o.naturalHeight*nt/2;P.drawImage(o,Cn,kt,o.naturalWidth*nt,o.naturalHeight*nt)}else P.fillStyle="rgba(255, 255, 255, 0.04)",P.fillRect(0,0,v.width,v.height),P.strokeStyle="rgba(255, 255, 255, 0.08)",P.strokeRect(4,4,v.width-8,v.height-8);let ie=v.width/y.width*(A*E),_e=C*(v.width/y.width),ge=O*(v.height/y.height),Sn=v.width/2-x*ie/2+_e,En=v.height/2-S*ie/2+ge;P.save(),P.globalAlpha=.7,P.drawImage(s,Sn,En,x*ie,S*ie),P.restore()},B=()=>{C=0,O=0,F(),G()};w.addEventListener("input",()=>{E=Number(w.value),T.textContent=`${E.toFixed(2)}\xD7`,F(),G()}),y.addEventListener("pointerdown",H=>{k=!0,R=H.clientX,z=H.clientY,D=C,U=O,y.setPointerCapture(H.pointerId)}),y.addEventListener("pointermove",H=>{k&&(C=D+(H.clientX-R),O=U+(H.clientY-z),F(),G())}),y.addEventListener("pointerup",H=>{k=!1,y.releasePointerCapture(H.pointerId)}),y.addEventListener("pointerleave",()=>{k=!1});let q=()=>{c.remove()},J=()=>{q(),l(null)},Z=async()=>{let H=document.createElement("canvas");H.width=t.width,H.height=t.height;let ae=H.getContext("2d");if(!ae){q(),l(null);return}let te=E,_e=Math.max(H.width/x,H.height/S)*te,ge=H.width/y.width,Sn=C*ge,En=O*ge,nt=H.width/2-x*_e/2+Sn,Cn=H.height/2-S*_e/2+En;ae.drawImage(s,nt,Cn,x*_e,S*_e);let kt=await new Promise(to=>{H.toBlob(io=>to(io),e.type||"image/png")});if(q(),!kt){l(null);return}l(new File([kt],e.name,{type:kt.type}))};I==null||I.addEventListener("click",J),M==null||M.addEventListener("click",J),j==null||j.addEventListener("click",B),L==null||L.addEventListener("click",()=>{Z()}),c.addEventListener("click",H=>{H.target===c&&J()}),document.body.appendChild(c),B()})}async loadImageForValue(e){let t=this.resolveAssetUrls(e);if(!t.length)return null;for(let i of t){let n=await this.loadImage(i);if(n)return n}return null}};var nn=class{constructor(){this.root=null;this.options=null}render(){return`
|
|
1887
1889
|
<div class="scene-panel loading-screen-panel panel-accent-purple" data-panel="loading-screen">
|
|
1888
1890
|
<div class="scene-panel-header" data-panel-handle>
|
|
1889
1891
|
<div class="panel-title">
|
|
@@ -1949,10 +1951,10 @@ Generate the requested asset matching the brand style.${s.needsTransparency?" Ba
|
|
|
1949
1951
|
</div>
|
|
1950
1952
|
</div>
|
|
1951
1953
|
</div>
|
|
1952
|
-
`}initialize(e,t){var y,v,w,T,I,M,L,j,_,P,x,S,A,E,C,O;this.options=t,this.root=e.querySelector('[data-panel="loading-screen"]');let n=(()=>{var R;let k=window.getEditableEngineConfig;if(typeof k=="function"){let z=k();return(R=z==null?void 0:z.loading)!=null?R:{}}return{}})(),a=(y=this.root)==null?void 0:y.querySelector("#loading-screen-type");a&&(a.value=n.type==="image"?"image":"color",a.addEventListener("change",()=>{var k,R;(R=(k=this.options)==null?void 0:k.onUpdateLoading)==null||R.call(k,{type:a.value}),this.updateFieldVisibility(a.value)}));let r=(v=this.root)==null?void 0:v.querySelector("#loading-background-color");r&&(r.value=n.background_color||"#160a17",r.addEventListener("input",()=>{var k,R;(R=(k=this.options)==null?void 0:k.onUpdateLoading)==null||R.call(k,{background_color:r.value})}));let o=(w=this.root)==null?void 0:w.querySelector("#loading-overlay-alpha"),l=(T=this.root)==null?void 0:T.querySelector("#loading-overlay-alpha-value");o&&(o.value=String((I=n.overlay_alpha)!=null?I:1),l&&(l.textContent=Number(o.value).toFixed(2)),o.addEventListener("input",()=>{var R,z;let k=Number(o.value);l&&(l.textContent=k.toFixed(2)),(z=(R=this.options)==null?void 0:R.onUpdateLoading)==null||z.call(R,{overlay_alpha:k})}));let c=(M=this.root)==null?void 0:M.querySelector("#loading-text");c&&(c.value=n.text||"",c.addEventListener("input",()=>{var k,R;(R=(k=this.options)==null?void 0:k.onUpdateLoading)==null||R.call(k,{text:c.value})}));let d=(L=this.root)==null?void 0:L.querySelector("#loading-text-scale"),p=(j=this.root)==null?void 0:j.querySelector("#loading-text-scale-value");d&&(d.value=String((_=n.text_scale)!=null?_:.6),p&&(p.textContent=Number(d.value).toFixed(2)),d.addEventListener("input",()=>{var R,z;let k=Number(d.value);p&&(p.textContent=k.toFixed(2)),(z=(R=this.options)==null?void 0:R.onUpdateLoading)==null||z.call(R,{text_scale:k})}));let u=(P=this.root)==null?void 0:P.querySelector("#loading-enabled");u&&(u.checked=n.enabled!==!1,u.addEventListener("change",()=>{var k,R;(R=(k=this.options)==null?void 0:k.onUpdateLoading)==null||R.call(k,{enabled:u.checked})}));let g=(x=this.root)==null?void 0:x.querySelector("#loading-blur-enabled");g&&(g.checked=n.blur_enabled!==!1,g.addEventListener("change",()=>{var k,R;(R=(k=this.options)==null?void 0:k.onUpdateLoading)==null||R.call(k,{blur_enabled:g.checked})}));let h=(S=this.root)==null?void 0:S.querySelector("#loading-blur-strength"),f=(A=this.root)==null?void 0:A.querySelector("#loading-blur-strength-value");h&&(h.value=String((E=n.blur_strength)!=null?E:8),f&&(f.textContent=h.value),h.addEventListener("input",()=>{var k,R;f&&(f.textContent=h.value),(R=(k=this.options)==null?void 0:k.onUpdateLoading)==null||R.call(k,{blur_strength:Number(h.value)})}));let m=(C=this.root)==null?void 0:C.querySelector("#loading-show-btn"),b=(O=this.root)==null?void 0:O.querySelector("#loading-hide-btn");m==null||m.addEventListener("click",()=>{var k,R;(R=(k=this.options)==null?void 0:k.onShowLoadingScreen)==null||R.call(k)}),b==null||b.addEventListener("click",()=>{var k,R;(R=(k=this.options)==null?void 0:k.onHideLoadingScreen)==null||R.call(k)}),this.updateFieldVisibility(n.type==="image"?"image":"color")}updateFieldVisibility(e){var n,a;let t=(n=this.root)==null?void 0:n.querySelector("#loading-color-field"),i=(a=this.root)==null?void 0:a.querySelector("#loading-alpha-field");e==="image"?(t&&(t.style.display="none"),i&&(i.style.display="none")):(t&&(t.style.display=""),i&&(i.style.display=""))}refresh(){}};var qt=require("pixi.js");var ha=require("pixi.js"),Be=()=>window.debugConfig||{},vr=()=>window.resolveAnchorVec2||(s=>({x:.5,y:.5})),wr=()=>window.resolveScreenAnchorPoint||(()=>new ha.Point),xr=()=>window.resolveScreenRatioPoint||(()=>new ha.Point);function Sr(s){an(s)&&(s.objectDebugRaf||(s.objectDebugRaf=window.requestAnimationFrame(()=>sn(s))))}function Er(s){s.objectDebugRaf&&(window.cancelAnimationFrame(s.objectDebugRaf),s.objectDebugRaf=null),Ut(s)}function an(s){return s.isDebugOpen}function sn(s){var a,r,o;if(!an(s)){s.objectDebugRaf=null;return}s.objectDebugRaf=window.requestAnimationFrame(()=>sn(s));let e=fa(s);if(!e){Gt(s,null),Ut(s);return}let t=ma(s,e);if(!t){Gt(s,null),Ut(s);return}let i=new qt.Point;(a=t.getGlobalPosition)==null||a.call(t,i);let n=ba(s,t);Gt(s,{instanceId:e,worldX:i.x,worldY:i.y,configX:(r=n==null?void 0:n.x)!=null?r:null,configY:(o=n==null?void 0:n.y)!=null?o:null}),s.highlightObject?xa(s,t):Ea(s),s.highlightAnchor&&n?Sa(s,n):Ca(s)}function fa(s){var n;let e=s.selectedObjectId;if(!e)return null;let t=window.__editableObjectInstances,i=(n=t==null?void 0:t.get)==null?void 0:n.call(t,e);return Array.isArray(i)&&i.length>0?i[0]:e}function ma(s,e){var n,a;let t=window.gameObjectManager,i=(n=t==null?void 0:t.get)==null?void 0:n.call(t,e);return i?((a=i.getDisplayObject)==null?void 0:a.call(i))||i.pixiObject||i:null}function Vt(s){let e=s.selectedObjectId;if(!e)return null;let t=window.getEditableObjectConfig;return typeof t!="function"?null:t(e)}function ba(s,e){var r,o;let t=Vt(s);if(!t)return null;let i=(r=t.transform)!=null?r:{},n=ya(s);if(!n)return null;if(i.position_ratio!=null)return xr()(n.width,n.height,i.position_ratio);let a=(o=i.anchor)!=null?o:"bottom-center";return a==="bottom-center"&&i.anchor==null&&console.log("[DEBUG FALLBACK] objectVisuals transform.anchor \u2192 bottom-center"),wr()(n.width,n.height,a)}function ya(s){var a;let e=(a=s.container)==null?void 0:a.querySelector(".game-container"),t=Number(e==null?void 0:e.dataset.screenWidth),i=Number(e==null?void 0:e.dataset.screenHeight);if(Number.isFinite(t)&&t>0&&Number.isFinite(i)&&i>0)return{width:t,height:i};let n=window.gameApp;return n!=null&&n.renderer?{width:n.renderer.width,height:n.renderer.height}:null}function va(s){let e=window.gameApp;return e!=null&&e.stage?(s.objectBoundsGfx&&s.objectBoundsGfx.parent!==e.stage&&(s.objectBoundsGfx.destroy(),s.objectBoundsGfx=null),s.objectBoundsGfx||(s.objectBoundsGfx=new qt.Graphics,s.objectBoundsGfx.zIndex=999999,e.stage.addChild(s.objectBoundsGfx)),s.objectBoundsGfx):null}function wa(s){let e=window.gameApp;return e!=null&&e.stage?(s.objectAnchorGfx&&s.objectAnchorGfx.parent!==e.stage&&(s.objectAnchorGfx.destroy(),s.objectAnchorGfx=null),s.objectAnchorGfx||(s.objectAnchorGfx=new qt.Graphics,s.objectAnchorGfx.zIndex=1e6,e.stage.addChild(s.objectAnchorGfx)),s.objectAnchorGfx):null}function xa(s,e){var n;let t=va(s);if(!t)return;let i=(n=e.getBounds)==null?void 0:n.call(e);i&&(t.clear(),t.rect(i.x,i.y,i.width,i.height).stroke({width:2,color:16726832,alpha:.9}))}function Sa(s,e){let t=wa(s);if(!t)return;let i=6;t.clear(),t.moveTo(e.x-i,e.y),t.lineTo(e.x+i,e.y),t.moveTo(e.x,e.y-i),t.lineTo(e.x,e.y+i),t.stroke({width:2,color:3066993,alpha:.9})}function Ea(s){s.objectBoundsGfx&&s.objectBoundsGfx.clear()}function Ca(s){s.objectAnchorGfx&&s.objectAnchorGfx.clear()}function Ut(s){s.objectBoundsGfx&&(s.objectBoundsGfx.destroy(),s.objectBoundsGfx=null),s.objectAnchorGfx&&(s.objectAnchorGfx.destroy(),s.objectAnchorGfx=null)}function Gt(s,e){s.sceneToolsPanel.updateInfo(e?{instanceId:e.instanceId,worldX:e.worldX,worldY:e.worldY,anchorX:e.configX,anchorY:e.configY}:null)}function Cr(s,e){return e.split(".").reduce((t,i)=>t?t[i]:void 0,s)}function Ar(s,e,t){var r;let i=e.split("."),n=i.pop(),a=s;for(let o of i)a[o]=(r=a[o])!=null?r:{},a=a[o];a[n]=t}function Aa(s){var i,n,a,r,o;if(!s)return!1;if((i=s.transform)!=null&&i.offset)return!0;let e=((a=(n=s.identity)==null?void 0:n.category)!=null?a:"").toString().toLowerCase(),t=((o=(r=s.identity)==null?void 0:r.id)!=null?o:"").toString().toLowerCase();return e.includes("ui")||t.startsWith("ui")||t.includes("label")}function on(s){let e=Be();e.layout&&(e.layout.scale_multiplier=1,e.layout.position_offset={x:0,y:0},e.layout.debug_rect_visible=!0,e.layout.debug_rect_color=16711680,e.layout.debug_rect_thickness=4),e.engine&&(e.engine.scale=1,e.engine.background_scale=1.05,e.engine.label_pulse_speed=3,e.engine.label_pulse_intensity=.03),e.physics&&(e.physics.rope_length=420),window.location.reload()}function Lr(s){window.location.reload()}function ln(s){let e=JSON.stringify(Be(),null,2);navigator.clipboard.writeText(e).then(()=>{alert("Debug config copied to clipboard!")}).catch(()=>{console.log(e),alert("Config logged to console (clipboard not available)")})}async function Tr(s,e){var t,i,n;if(!(!s.configViewer||!s.container))try{let a=window.getEditableObjectConfig,r=typeof a=="function"?a(e):null;if(!r){let{loadObjectCentricConfig:o,loadObjectConfig:l}=await Promise.resolve().then(()=>(Ti(),Vs)),p=(((t=(await o("scene.main")).scene)==null?void 0:t.objects)||[]).find(g=>g.object_config===e||g.instance_id===e);if(!p)return;let u=await l(p.object_config);console.log("[PREVIEW] Loaded object config (fallback)",e,u),rn(s,u),(i=s.configViewer)==null||i.style.setProperty("display","block");return}console.log("[PREVIEW] Loaded object config",e,r),rn(s,r),(n=s.configViewer)==null||n.style.setProperty("display","block");return}catch(a){console.error("[DEBUG] Failed to load object config:",a)}}function rn(s,e){var u,g,h,f,m,b,y,v,w,T;if(!s.container)return;let t=s.container.querySelector("#config-pos-x"),i=s.container.querySelector("#config-pos-y"),n=s.container.querySelector("#config-scale"),a=s.container.querySelector("#config-anchor-preset"),r=s.container.querySelector("#config-anchor-x"),o=s.container.querySelector("#config-anchor-y"),c=Aa(e)?(u=e.transform)==null?void 0:u.offset:(g=e.transform)==null?void 0:g.position;t&&(t.value=String((h=c==null?void 0:c.x)!=null?h:0)),i&&(i.value=String((f=c==null?void 0:c.y)!=null?f:0)),n&&(n.value=String((b=(m=e.transform)==null?void 0:m.scale)!=null?b:1));let d=(T=(w=(y=e.transform)==null?void 0:y.anchor)!=null?w:(v=e.render)==null?void 0:v.anchor)!=null?T:"center";if(a){typeof d=="string"?a.value=d:a.value="custom";let I=s.container.querySelectorAll(".anchor-custom-field"),M=a.value==="custom";I.forEach(L=>L.style.display=M?"block":"none")}let p=vr()(d);r&&(r.value=String(p.x)),o&&(o.value=String(p.y))}function kr(s){var l,c,d,p,u,g,h,f,m,b;let e=s.selectedObjectId;if(!e||!s.container)return;let t=(c=(l=s.container.querySelector("#config-pos-x"))==null?void 0:l.value)!=null?c:"0",i=(p=(d=s.container.querySelector("#config-pos-y"))==null?void 0:d.value)!=null?p:"0",n=(g=(u=s.container.querySelector("#config-scale"))==null?void 0:u.value)!=null?g:"1",a=(f=(h=s.container.querySelector("#config-anchor-x"))==null?void 0:h.value)!=null?f:"0.5",r=(b=(m=s.container.querySelector("#config-anchor-y"))==null?void 0:m.value)!=null?b:"0.5",o=`${e}:
|
|
1954
|
+
`}initialize(e,t){var y,v,w,T,I,M,L,j,_,P,x,S,A,E,C,O;this.options=t,this.root=e.querySelector('[data-panel="loading-screen"]');let n=(()=>{var R;let k=window.getEditableEngineConfig;if(typeof k=="function"){let z=k();return(R=z==null?void 0:z.loading)!=null?R:{}}return{}})(),a=(y=this.root)==null?void 0:y.querySelector("#loading-screen-type");a&&(a.value=n.type==="image"?"image":"color",a.addEventListener("change",()=>{var k,R;(R=(k=this.options)==null?void 0:k.onUpdateLoading)==null||R.call(k,{type:a.value}),this.updateFieldVisibility(a.value)}));let s=(v=this.root)==null?void 0:v.querySelector("#loading-background-color");s&&(s.value=n.background_color||"#160a17",s.addEventListener("input",()=>{var k,R;(R=(k=this.options)==null?void 0:k.onUpdateLoading)==null||R.call(k,{background_color:s.value})}));let o=(w=this.root)==null?void 0:w.querySelector("#loading-overlay-alpha"),l=(T=this.root)==null?void 0:T.querySelector("#loading-overlay-alpha-value");o&&(o.value=String((I=n.overlay_alpha)!=null?I:1),l&&(l.textContent=Number(o.value).toFixed(2)),o.addEventListener("input",()=>{var R,z;let k=Number(o.value);l&&(l.textContent=k.toFixed(2)),(z=(R=this.options)==null?void 0:R.onUpdateLoading)==null||z.call(R,{overlay_alpha:k})}));let c=(M=this.root)==null?void 0:M.querySelector("#loading-text");c&&(c.value=n.text||"",c.addEventListener("input",()=>{var k,R;(R=(k=this.options)==null?void 0:k.onUpdateLoading)==null||R.call(k,{text:c.value})}));let d=(L=this.root)==null?void 0:L.querySelector("#loading-text-scale"),p=(j=this.root)==null?void 0:j.querySelector("#loading-text-scale-value");d&&(d.value=String((_=n.text_scale)!=null?_:.6),p&&(p.textContent=Number(d.value).toFixed(2)),d.addEventListener("input",()=>{var R,z;let k=Number(d.value);p&&(p.textContent=k.toFixed(2)),(z=(R=this.options)==null?void 0:R.onUpdateLoading)==null||z.call(R,{text_scale:k})}));let u=(P=this.root)==null?void 0:P.querySelector("#loading-enabled");u&&(u.checked=n.enabled!==!1,u.addEventListener("change",()=>{var k,R;(R=(k=this.options)==null?void 0:k.onUpdateLoading)==null||R.call(k,{enabled:u.checked})}));let g=(x=this.root)==null?void 0:x.querySelector("#loading-blur-enabled");g&&(g.checked=n.blur_enabled!==!1,g.addEventListener("change",()=>{var k,R;(R=(k=this.options)==null?void 0:k.onUpdateLoading)==null||R.call(k,{blur_enabled:g.checked})}));let h=(S=this.root)==null?void 0:S.querySelector("#loading-blur-strength"),f=(A=this.root)==null?void 0:A.querySelector("#loading-blur-strength-value");h&&(h.value=String((E=n.blur_strength)!=null?E:8),f&&(f.textContent=h.value),h.addEventListener("input",()=>{var k,R;f&&(f.textContent=h.value),(R=(k=this.options)==null?void 0:k.onUpdateLoading)==null||R.call(k,{blur_strength:Number(h.value)})}));let m=(C=this.root)==null?void 0:C.querySelector("#loading-show-btn"),b=(O=this.root)==null?void 0:O.querySelector("#loading-hide-btn");m==null||m.addEventListener("click",()=>{var k,R;(R=(k=this.options)==null?void 0:k.onShowLoadingScreen)==null||R.call(k)}),b==null||b.addEventListener("click",()=>{var k,R;(R=(k=this.options)==null?void 0:k.onHideLoadingScreen)==null||R.call(k)}),this.updateFieldVisibility(n.type==="image"?"image":"color")}updateFieldVisibility(e){var n,a;let t=(n=this.root)==null?void 0:n.querySelector("#loading-color-field"),i=(a=this.root)==null?void 0:a.querySelector("#loading-alpha-field");e==="image"?(t&&(t.style.display="none"),i&&(i.style.display="none")):(t&&(t.style.display=""),i&&(i.style.display=""))}refresh(){}};var qt=require("pixi.js");var ha=require("pixi.js"),Be=()=>window.debugConfig||{},vr=()=>window.resolveAnchorVec2||(r=>({x:.5,y:.5})),wr=()=>window.resolveScreenAnchorPoint||(()=>new ha.Point),xr=()=>window.resolveScreenRatioPoint||(()=>new ha.Point);function Sr(r){an(r)&&(r.objectDebugRaf||(r.objectDebugRaf=window.requestAnimationFrame(()=>sn(r))))}function Er(r){r.objectDebugRaf&&(window.cancelAnimationFrame(r.objectDebugRaf),r.objectDebugRaf=null),Ut(r)}function an(r){return r.isDebugOpen}function sn(r){var a,s,o;if(!an(r)){r.objectDebugRaf=null;return}r.objectDebugRaf=window.requestAnimationFrame(()=>sn(r));let e=fa(r);if(!e){Gt(r,null),Ut(r);return}let t=ma(r,e);if(!t){Gt(r,null),Ut(r);return}let i=new qt.Point;(a=t.getGlobalPosition)==null||a.call(t,i);let n=ba(r,t);Gt(r,{instanceId:e,worldX:i.x,worldY:i.y,configX:(s=n==null?void 0:n.x)!=null?s:null,configY:(o=n==null?void 0:n.y)!=null?o:null}),r.highlightObject?xa(r,t):Ea(r),r.highlightAnchor&&n?Sa(r,n):Ca(r)}function fa(r){var n;let e=r.selectedObjectId;if(!e)return null;let t=window.__editableObjectInstances,i=(n=t==null?void 0:t.get)==null?void 0:n.call(t,e);return Array.isArray(i)&&i.length>0?i[0]:e}function ma(r,e){var n,a;let t=window.gameObjectManager,i=(n=t==null?void 0:t.get)==null?void 0:n.call(t,e);return i?((a=i.getDisplayObject)==null?void 0:a.call(i))||i.pixiObject||i:null}function Vt(r){let e=r.selectedObjectId;if(!e)return null;let t=window.getEditableObjectConfig;return typeof t!="function"?null:t(e)}function ba(r,e){var s,o;let t=Vt(r);if(!t)return null;let i=(s=t.transform)!=null?s:{},n=ya(r);if(!n)return null;if(i.position_ratio!=null)return xr()(n.width,n.height,i.position_ratio);let a=(o=i.anchor)!=null?o:"bottom-center";return a==="bottom-center"&&i.anchor==null&&console.log("[DEBUG FALLBACK] objectVisuals transform.anchor \u2192 bottom-center"),wr()(n.width,n.height,a)}function ya(r){var a;let e=(a=r.container)==null?void 0:a.querySelector(".game-container"),t=Number(e==null?void 0:e.dataset.screenWidth),i=Number(e==null?void 0:e.dataset.screenHeight);if(Number.isFinite(t)&&t>0&&Number.isFinite(i)&&i>0)return{width:t,height:i};let n=window.gameApp;return n!=null&&n.renderer?{width:n.renderer.width,height:n.renderer.height}:null}function va(r){let e=window.gameApp;return e!=null&&e.stage?(r.objectBoundsGfx&&r.objectBoundsGfx.parent!==e.stage&&(r.objectBoundsGfx.destroy(),r.objectBoundsGfx=null),r.objectBoundsGfx||(r.objectBoundsGfx=new qt.Graphics,r.objectBoundsGfx.zIndex=999999,e.stage.addChild(r.objectBoundsGfx)),r.objectBoundsGfx):null}function wa(r){let e=window.gameApp;return e!=null&&e.stage?(r.objectAnchorGfx&&r.objectAnchorGfx.parent!==e.stage&&(r.objectAnchorGfx.destroy(),r.objectAnchorGfx=null),r.objectAnchorGfx||(r.objectAnchorGfx=new qt.Graphics,r.objectAnchorGfx.zIndex=1e6,e.stage.addChild(r.objectAnchorGfx)),r.objectAnchorGfx):null}function xa(r,e){var n;let t=va(r);if(!t)return;let i=(n=e.getBounds)==null?void 0:n.call(e);i&&(t.clear(),t.rect(i.x,i.y,i.width,i.height).stroke({width:2,color:16726832,alpha:.9}))}function Sa(r,e){let t=wa(r);if(!t)return;let i=6;t.clear(),t.moveTo(e.x-i,e.y),t.lineTo(e.x+i,e.y),t.moveTo(e.x,e.y-i),t.lineTo(e.x,e.y+i),t.stroke({width:2,color:3066993,alpha:.9})}function Ea(r){r.objectBoundsGfx&&r.objectBoundsGfx.clear()}function Ca(r){r.objectAnchorGfx&&r.objectAnchorGfx.clear()}function Ut(r){r.objectBoundsGfx&&(r.objectBoundsGfx.destroy(),r.objectBoundsGfx=null),r.objectAnchorGfx&&(r.objectAnchorGfx.destroy(),r.objectAnchorGfx=null)}function Gt(r,e){r.sceneToolsPanel.updateInfo(e?{instanceId:e.instanceId,worldX:e.worldX,worldY:e.worldY,anchorX:e.configX,anchorY:e.configY}:null)}function Cr(r,e){return e.split(".").reduce((t,i)=>t?t[i]:void 0,r)}function Ar(r,e,t){var s;let i=e.split("."),n=i.pop(),a=r;for(let o of i)a[o]=(s=a[o])!=null?s:{},a=a[o];a[n]=t}function Aa(r){var i,n,a,s,o;if(!r)return!1;if((i=r.transform)!=null&&i.offset)return!0;let e=((a=(n=r.identity)==null?void 0:n.category)!=null?a:"").toString().toLowerCase(),t=((o=(s=r.identity)==null?void 0:s.id)!=null?o:"").toString().toLowerCase();return e.includes("ui")||t.startsWith("ui")||t.includes("label")}function on(r){let e=Be();e.layout&&(e.layout.scale_multiplier=1,e.layout.position_offset={x:0,y:0},e.layout.debug_rect_visible=!0,e.layout.debug_rect_color=16711680,e.layout.debug_rect_thickness=4),e.engine&&(e.engine.scale=1,e.engine.background_scale=1.05,e.engine.label_pulse_speed=3,e.engine.label_pulse_intensity=.03),e.physics&&(e.physics.rope_length=420),window.location.reload()}function Lr(r){window.location.reload()}function ln(r){let e=JSON.stringify(Be(),null,2);navigator.clipboard.writeText(e).then(()=>{alert("Debug config copied to clipboard!")}).catch(()=>{console.log(e),alert("Config logged to console (clipboard not available)")})}async function Tr(r,e){var t,i,n;if(!(!r.configViewer||!r.container))try{let a=window.getEditableObjectConfig,s=typeof a=="function"?a(e):null;if(!s){let{loadObjectCentricConfig:o,loadObjectConfig:l}=await Promise.resolve().then(()=>(Ti(),Vs)),p=(((t=(await o("scene.main")).scene)==null?void 0:t.objects)||[]).find(g=>g.object_config===e||g.instance_id===e);if(!p)return;let u=await l(p.object_config);console.log("[PREVIEW] Loaded object config (fallback)",e,u),rn(r,u),(i=r.configViewer)==null||i.style.setProperty("display","block");return}console.log("[PREVIEW] Loaded object config",e,s),rn(r,s),(n=r.configViewer)==null||n.style.setProperty("display","block");return}catch(a){console.error("[DEBUG] Failed to load object config:",a)}}function rn(r,e){var u,g,h,f,m,b,y,v,w,T;if(!r.container)return;let t=r.container.querySelector("#config-pos-x"),i=r.container.querySelector("#config-pos-y"),n=r.container.querySelector("#config-scale"),a=r.container.querySelector("#config-anchor-preset"),s=r.container.querySelector("#config-anchor-x"),o=r.container.querySelector("#config-anchor-y"),c=Aa(e)?(u=e.transform)==null?void 0:u.offset:(g=e.transform)==null?void 0:g.position;t&&(t.value=String((h=c==null?void 0:c.x)!=null?h:0)),i&&(i.value=String((f=c==null?void 0:c.y)!=null?f:0)),n&&(n.value=String((b=(m=e.transform)==null?void 0:m.scale)!=null?b:1));let d=(T=(w=(y=e.transform)==null?void 0:y.anchor)!=null?w:(v=e.render)==null?void 0:v.anchor)!=null?T:"center";if(a){typeof d=="string"?a.value=d:a.value="custom";let I=r.container.querySelectorAll(".anchor-custom-field"),M=a.value==="custom";I.forEach(L=>L.style.display=M?"block":"none")}let p=vr()(d);s&&(s.value=String(p.x)),o&&(o.value=String(p.y))}function kr(r){var l,c,d,p,u,g,h,f,m,b;let e=r.selectedObjectId;if(!e||!r.container)return;let t=(c=(l=r.container.querySelector("#config-pos-x"))==null?void 0:l.value)!=null?c:"0",i=(p=(d=r.container.querySelector("#config-pos-y"))==null?void 0:d.value)!=null?p:"0",n=(g=(u=r.container.querySelector("#config-scale"))==null?void 0:u.value)!=null?g:"1",a=(f=(h=r.container.querySelector("#config-anchor-x"))==null?void 0:h.value)!=null?f:"0.5",s=(b=(m=r.container.querySelector("#config-anchor-y"))==null?void 0:m.value)!=null?b:"0.5",o=`${e}:
|
|
1953
1955
|
position: (${t}, ${i})
|
|
1954
1956
|
scale: ${n}
|
|
1955
|
-
anchor: (${a}, ${r})`;navigator.clipboard.writeText(o).then(()=>console.log("[DEBUG] Config values copied to clipboard")).catch(y=>console.error("[DEBUG] Failed to copy config values:",y))}async function La(s,e){var u,g,h,f,m,b,y,v,w,T,I,M;if(console.log("[INSPECTOR] \u{1F527} applyObjectConfig called"),!s.container)return;let t=s.selectedObjectId;if(!t){console.warn("[PREVIEW] Apply object config clicked with no selection");return}let i=Number((g=(u=s.container.querySelector("#config-pos-x"))==null?void 0:u.value)!=null?g:0),n=Number((f=(h=s.container.querySelector("#config-pos-y"))==null?void 0:h.value)!=null?f:0),a=Number((b=(m=s.container.querySelector("#config-scale"))==null?void 0:m.value)!=null?b:1),r=(v=(y=s.container.querySelector("#config-anchor-preset"))==null?void 0:y.value)!=null?v:"center",o=Number((T=(w=s.container.querySelector("#config-anchor-x"))==null?void 0:w.value)!=null?T:.5),l=Number((M=(I=s.container.querySelector("#config-anchor-y"))==null?void 0:I.value)!=null?M:.5),c=r==="custom"?{x:o,y:l}:r;console.log("[INSPECTOR] Applying config for:",t,{posX:i,posY:n,scale:a,anchor:c});let{applyConfigOverride:d}=await Promise.resolve().then(()=>(ee(),Ne));d({objectId:t,path:"transform.position",value:{x:i,y:n}},{silent:e==null?void 0:e.silent}),d({objectId:t,path:"transform.scale",value:a},{silent:e==null?void 0:e.silent}),d({objectId:t,path:"transform.anchor",value:c},{silent:e==null?void 0:e.silent});let p=Vt(s);Aa(p)&&d({objectId:t,path:"transform.offset",value:{x:i,y:n}},{silent:!0})}async function Ir(s,e,t){let{applyConfigOverride:i}=await Promise.resolve().then(()=>(ee(),Ne));Object.entries(e.assets).forEach(([l,c])=>{i({path:`assets.${l}`,value:c},{silent:!0})}),Object.entries(e.runtime.theme).forEach(([l,c])=>{i({path:`runtime.theme.${l}`,value:c},{silent:!0})}),Object.entries(e.runtime.ui).forEach(([l,c])=>{i({path:`runtime.ui.${l}`,value:c},{silent:!0})}),Object.entries(e.runtime.fonts).forEach(([l,c])=>{i({path:`runtime.fonts.${l}`,value:c},{silent:!0})}),Object.entries(e.runtime.audio).forEach(([l,c])=>{i({path:`runtime.audio.${l}`,value:c},{silent:!0})});let n=window.applyEditableEngineConfig;if(typeof n=="function"){let l={theme:e.runtime.theme,fonts:e.runtime.fonts,audio:e.runtime.audio},c={};Object.entries(e.runtime.ui).forEach(([d,p])=>{var u;if(d)if(d.includes(".")){let g=d.split("."),h=c;for(let f=0;f<g.length-1;f++){let m=g[f];h[m]=(u=h[m])!=null?u:{},h=h[m]}h[g[g.length-1]]=p}else c[d]=p}),l.ui=c,n({runtime:l,assets:e.assets})}let a=Object.values(e.assets).some(l=>/^(blob:|data:)/.test(l)),r=(t==null?void 0:t.source)!=="auto"&&!a,o=window.__previewShell;r&&(o!=null&&o.refresh)&&o.refresh()}function Pr(s){s.selectedObjectId&&(s.objectAutoApplyTimer&&window.clearTimeout(s.objectAutoApplyTimer),s.objectAutoApplyTimer=window.setTimeout(()=>{s.objectAutoApplyTimer=null,La(s,{silent:!0})},150))}var bl=3e3;function et(s,e,t){let i=t!=null?t:s.offsetParent;if(!i)return;e.style.cursor="move";let n=!1,a=0,r=0,o=0,l=0,c=0,d=0,p=g=>{if(!n)return;let h=i.getBoundingClientRect();s.style.left=`${g.clientX-h.left-c}px`,s.style.top=`${g.clientY-h.top-d}px`},u=()=>{n&&(n=!1,s.classList.remove("dragging"),window.removeEventListener("pointermove",p),window.removeEventListener("pointerup",u))};e.addEventListener("pointerdown",g=>{if(g.button!==0)return;let h=g.target;if(h!=null&&h.closest("button, input, select, textarea"))return;g.preventDefault();let f=s.getBoundingClientRect(),m=i.getBoundingClientRect();console.log("[DRAG] Panel:",s.className),console.log("[DRAG] Container:",i.className),console.log("[DRAG] panelRect:",{left:f.left,top:f.top,width:f.width,height:f.height}),console.log("[DRAG] containerRect:",{left:m.left,top:m.top,width:m.width,height:m.height}),console.log("[DRAG] mouse:",{x:g.clientX,y:g.clientY}),c=g.clientX-f.left,d=g.clientY-f.top,console.log("[DRAG] offset:",{x:c,y:d});let b=f.left-m.left,y=f.top-m.top;console.log("[DRAG] targetPosition:",{left:b,top:y}),s.style.left=`${b}px`,s.style.top=`${y}px`,s.style.right="auto",s.style.bottom="auto",s.style.zIndex=String(++bl),n=!0,s.classList.add("dragging"),window.addEventListener("pointermove",p),window.addEventListener("pointerup",u)})}function cn(s,e,t,i=280,n=200){e.style.cursor="nwse-resize";let a=0,r=0,o=0,l=0,c=!1,d=u=>{var y;if(!c)return;let g=u.clientX-o,h=u.clientY-l,f=Math.max(i,a+g),m=Math.max(n,r+h);s.style.width=`${f}px`,(y=s.closest(".preview-shell"))!=null&&y.classList.contains("layout-fixed")||(s.style.height=`${m}px`),t==null||t(f,m)},p=()=>{c&&(c=!1,window.removeEventListener("pointermove",d),window.removeEventListener("pointerup",p))};e.addEventListener("pointerdown",u=>{if(u.button!==0)return;u.preventDefault(),u.stopPropagation();let g=s.getBoundingClientRect();a=g.width,r=g.height,o=u.clientX,l=u.clientY,c=!0,window.addEventListener("pointermove",d),window.addEventListener("pointerup",p)})}function Ta(s,e){var f,m,b,y;let t=(b=(m=(f=s.container)==null?void 0:f.querySelector("#debug-overlay"))!=null?m:s.debugOverlay)!=null?b:e.offsetParent;if(!t||(y=s.container)!=null&&y.classList.contains("layout-fixed"))return;let i=t.getBoundingClientRect(),n=e.getBoundingClientRect(),a=12,r=Math.max(250,Math.floor(i.width-a*2)),o=Math.max(200,Math.floor(i.height-a*2));n.width>r&&(e.style.width=`${r}px`),n.height>o&&(e.style.height=`${o}px`);let l=e.getBoundingClientRect(),c=l.left-i.left,d=l.top-i.top,p=Math.max(a,i.width-l.width-a),u=Math.max(a,i.height-l.height-a),g=Math.min(Math.max(c,a),p),h=Math.min(Math.max(d,a),u);e.style.left=`${Math.round(g)}px`,e.style.top=`${Math.round(h)}px`,e.style.right="auto",e.style.bottom="auto"}function bt(s){var i,n;if(!s.container)return;let e=s.container.querySelector("#debug-workbench");if(!e)return;if(Ta(s,e),(i=s.container)!=null&&i.classList.contains("layout-fixed")){let a=localStorage.getItem("preview_workbench_state"),r={activeTab:s.activeTab};if(a)try{r={...JSON.parse(a),activeTab:s.activeTab}}catch{}localStorage.setItem("preview_workbench_state",JSON.stringify(r));return}let t={activeTab:s.activeTab,width:e.style.width,height:(n=s.container)!=null&&n.classList.contains("layout-fixed")?"":e.style.height,left:e.style.left,top:e.style.top};localStorage.setItem("preview_workbench_state",JSON.stringify(t))}function dn(s){try{let e=localStorage.getItem("preview_workbench_state");if(!e)return;let t=JSON.parse(e);t.activeTab&&(s.activeTab=t.activeTab),window.requestAnimationFrame(()=>{var n,a;let i=(n=s.container)==null?void 0:n.querySelector("#debug-workbench");if(i){let r=(a=s.container)==null?void 0:a.classList.contains("layout-fixed");t.width&&(i.style.width=t.width),t.height&&!r?i.style.height=t.height:r&&(i.style.height=""),t.left&&(i.style.left=t.left,i.style.right="auto"),t.top&&(i.style.top=t.top,i.style.bottom="auto"),Ta(s,i)}})}catch(e){console.warn("[PREVIEW] Failed to load workbench state",e)}}function ka(s,e){let t=e.getBoundingClientRect();(t.left<0||t.top<0||t.right>window.innerWidth||t.bottom>window.innerHeight)&&(console.warn("[Workbench] Workbench positioned outside viewport, repositioning..."),e.style.left="16px",e.style.top="72px",e.style.right="auto",e.style.bottom="auto",Ta(s,e),bt(s))}function Mr(s){var n,a,r;if(!s.container)return;let e=s.container,t=e.querySelector("#debug-toggle");t||console.warn("[PREVIEW] Debug toggle not found in DOM"),t==null||t.addEventListener("click",()=>{var o;console.log("[PREVIEW] Debug toggle clicked"),(o=s.toggleDebug)==null||o.call(s)}),(n=e.querySelector("#debug-close"))==null||n.addEventListener("click",()=>{var o;return(o=s.toggleDebug)==null?void 0:o.call(s,!1)}),(a=e.querySelector("#debug-reset"))==null||a.addEventListener("click",()=>on(s)),(r=e.querySelector("#debug-export"))==null||r.addEventListener("click",()=>ln(s)),e.querySelectorAll(".workbench-tab").forEach(o=>{o.addEventListener("click",()=>{let l=o.dataset.tab;s.activeTab=l,Ia(s),bt(s)})}),Ma(s,e),Pa(s,e)}function Ia(s){var n,a;if(!s.container)return;let e=s.container;e.querySelectorAll(".workbench-tab").forEach(r=>{let o=r.dataset.tab;r.classList.toggle("active",o===s.activeTab)}),e.querySelectorAll(".workbench-tab-panel").forEach(r=>{let o=r.dataset.tabPanel;r.classList.toggle("active",o===s.activeTab)}),s.activeTab==="library"&&s.libraryPanel&&((a=(n=s.libraryPanel).resetSearch)==null||a.call(n))}function Pa(s,e){fe(s,e,"debug-layout-scale","layout.scale_multiplier","#debug-layout-scale-value"),fe(s,e,"debug-layout-offset-x","layout.position_offset.x","#debug-layout-offset-x-value"),fe(s,e,"debug-layout-offset-y","layout.position_offset.y","#debug-layout-offset-y-value"),fe(s,e,"debug-rect-thickness","layout.debug_rect_thickness","#debug-rect-thickness-value"),fe(s,e,"debug-engine-scale","engine.scale","#debug-engine-scale-value"),fe(s,e,"debug-background-scale","engine.background_scale","#debug-background-scale-value"),fe(s,e,"debug-label-pulse-speed","engine.label_pulse_speed","#debug-label-pulse-speed-value"),fe(s,e,"debug-label-pulse-intensity","engine.label_pulse_intensity","#debug-label-pulse-intensity-value"),fe(s,e,"debug-rope-length","physics.rope_length","#debug-rope-length-value");let t=e.querySelector("#debug-rect-visible");t==null||t.addEventListener("change",()=>{let n=Be();n.layout&&(n.layout.debug_rect_visible=!!t.checked)});let i=e.querySelector("#debug-rect-color");i==null||i.addEventListener("input",()=>{let n=i.value.replace("#",""),a=parseInt(n,16),r=Be();r.layout&&(r.layout.debug_rect_color=Number.isFinite(a)?a:16711680)})}function jr(s){if(!s.container||!s.debugOverlay)return;let e=s.container.querySelector("#debug-workbench"),t=s.container.querySelector("#workbench-handle");e&&t&&(!e.style.left&&!e.style.right&&!e.style.top&&!e.style.bottom&&(e.style.right="16px",e.style.top="72px"),et(e,t,s.debugOverlay),t.addEventListener("pointerup",()=>{setTimeout(()=>{bt(s),ka(s,e)},10)}));let i=s.container.querySelector('[data-panel="scene-objects"]'),n=i==null?void 0:i.querySelector("[data-panel-handle]"),a=i==null?void 0:i.querySelector("[data-panel-resize-v]");i&&n&&(!i.style.left&&!i.style.right&&!i.style.top&&!i.style.bottom&&(i.style.left="16px",i.style.top="72px"),et(i,n,s.debugOverlay),n.addEventListener("pointerup",()=>{setTimeout(()=>{ka(s,i)},10)})),i&&a&&cn(i,a);let r=s.container.querySelector('[data-panel="scene-tools-corner"]'),o=r==null?void 0:r.querySelector("[data-panel-handle]");r&&o&&et(r,o,s.debugOverlay);let l=s.container.querySelector('[data-panel="nudge-panel"]'),c=l==null?void 0:l.querySelector("[data-panel-handle]");l&&c&&et(l,c,s.debugOverlay),dn(s)}function Ma(s,e){Array.from(e.querySelectorAll("[data-panel-toggle]")).forEach(i=>{i.addEventListener("click",()=>{let n=i.closest(".scene-panel");n&&n.classList.toggle("collapsed")})})}function fe(s,e,t,i,n){let a=e.querySelector(`#${t}`),r=e.querySelector(n);if(!a||!r)return;let o=Cr(Be(),i);typeof o=="number"&&(a.value=String(o),r.textContent=String(o)),a.addEventListener("input",()=>{let l=Number(a.value);r.textContent=String(l),Ar(Be(),i,l)})}ee();var pn=class{constructor(){this.container=null;this.currentVersion=null;this.availableVersions=[];this.isDevelopmentMode=!1}async forceResyncAfterApply(){var e;try{let t=window.__HANDLER_ACTIVE_SCREEN;await fetch("/api/sync-screens",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({force:!0,screenId:t})})}catch(t){console.warn("[ConfigPersistence] sync-screens failed:",t)}try{let t=window.__HANDLER_REFRESH_SCREEN_INDEX;typeof t=="function"?await t():window.dispatchEvent(new CustomEvent("handler:screen-index-loaded"))}catch{}try{(e=window.refreshEditableConfigIndex)==null||e.call(window)}catch{}try{window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"batch"}}))}catch{}}async initialize(e){this.container=e,this.isDevelopmentMode=typeof window!="undefined"&&document.querySelector('script[type="module"][src*="/@vite/"]')!==null,await this.loadVersionsList(),window.addEventListener("config:changed",()=>{this.refreshPanel()}),this.refreshPanel()}render(){let e=De(),{hasChanges:t,overrideCount:i,overrides:n}=e,a={};for(let d of n){let p=d.objectId||"Engine";a[p]||(a[p]=[]),a[p].push(d)}let r=localStorage.getItem("handler_last_applied"),o=r?new Date(parseInt(r)).toLocaleString():"Never",l=this.currentVersion?`Version: ${this.currentVersion} (Active)`:"Original",c=this.currentVersion?`Versioned (${this.currentVersion})`:"Global";return`
|
|
1957
|
+
anchor: (${a}, ${s})`;navigator.clipboard.writeText(o).then(()=>console.log("[DEBUG] Config values copied to clipboard")).catch(y=>console.error("[DEBUG] Failed to copy config values:",y))}async function La(r,e){var u,g,h,f,m,b,y,v,w,T,I,M;if(console.log("[INSPECTOR] \u{1F527} applyObjectConfig called"),!r.container)return;let t=r.selectedObjectId;if(!t){console.warn("[PREVIEW] Apply object config clicked with no selection");return}let i=Number((g=(u=r.container.querySelector("#config-pos-x"))==null?void 0:u.value)!=null?g:0),n=Number((f=(h=r.container.querySelector("#config-pos-y"))==null?void 0:h.value)!=null?f:0),a=Number((b=(m=r.container.querySelector("#config-scale"))==null?void 0:m.value)!=null?b:1),s=(v=(y=r.container.querySelector("#config-anchor-preset"))==null?void 0:y.value)!=null?v:"center",o=Number((T=(w=r.container.querySelector("#config-anchor-x"))==null?void 0:w.value)!=null?T:.5),l=Number((M=(I=r.container.querySelector("#config-anchor-y"))==null?void 0:I.value)!=null?M:.5),c=s==="custom"?{x:o,y:l}:s;console.log("[INSPECTOR] Applying config for:",t,{posX:i,posY:n,scale:a,anchor:c});let{applyConfigOverride:d}=await Promise.resolve().then(()=>(ee(),Ne));d({objectId:t,path:"transform.position",value:{x:i,y:n}},{silent:e==null?void 0:e.silent}),d({objectId:t,path:"transform.scale",value:a},{silent:e==null?void 0:e.silent}),d({objectId:t,path:"transform.anchor",value:c},{silent:e==null?void 0:e.silent});let p=Vt(r);Aa(p)&&d({objectId:t,path:"transform.offset",value:{x:i,y:n}},{silent:!0})}async function Ir(r,e,t){let{applyConfigOverride:i}=await Promise.resolve().then(()=>(ee(),Ne));Object.entries(e.assets).forEach(([l,c])=>{i({path:`assets.${l}`,value:c},{silent:!0})}),Object.entries(e.runtime.theme).forEach(([l,c])=>{i({path:`runtime.theme.${l}`,value:c},{silent:!0})}),Object.entries(e.runtime.ui).forEach(([l,c])=>{i({path:`runtime.ui.${l}`,value:c},{silent:!0})}),Object.entries(e.runtime.fonts).forEach(([l,c])=>{i({path:`runtime.fonts.${l}`,value:c},{silent:!0})}),Object.entries(e.runtime.audio).forEach(([l,c])=>{i({path:`runtime.audio.${l}`,value:c},{silent:!0})});let n=window.applyEditableEngineConfig;if(typeof n=="function"){let l={theme:e.runtime.theme,fonts:e.runtime.fonts,audio:e.runtime.audio},c={};Object.entries(e.runtime.ui).forEach(([d,p])=>{var u;if(d)if(d.includes(".")){let g=d.split("."),h=c;for(let f=0;f<g.length-1;f++){let m=g[f];h[m]=(u=h[m])!=null?u:{},h=h[m]}h[g[g.length-1]]=p}else c[d]=p}),l.ui=c,n({runtime:l,assets:e.assets})}let a=Object.values(e.assets).some(l=>/^(blob:|data:)/.test(l)),s=(t==null?void 0:t.source)!=="auto"&&!a,o=window.__previewShell;s&&(o!=null&&o.refresh)&&o.refresh()}function Pr(r){r.selectedObjectId&&(r.objectAutoApplyTimer&&window.clearTimeout(r.objectAutoApplyTimer),r.objectAutoApplyTimer=window.setTimeout(()=>{r.objectAutoApplyTimer=null,La(r,{silent:!0})},150))}var bl=3e3;function et(r,e,t){let i=t!=null?t:r.offsetParent;if(!i)return;e.style.cursor="move";let n=!1,a=0,s=0,o=0,l=0,c=0,d=0,p=g=>{if(!n)return;let h=i.getBoundingClientRect();r.style.left=`${g.clientX-h.left-c}px`,r.style.top=`${g.clientY-h.top-d}px`},u=()=>{n&&(n=!1,r.classList.remove("dragging"),window.removeEventListener("pointermove",p),window.removeEventListener("pointerup",u))};e.addEventListener("pointerdown",g=>{if(g.button!==0)return;let h=g.target;if(h!=null&&h.closest("button, input, select, textarea"))return;g.preventDefault();let f=r.getBoundingClientRect(),m=i.getBoundingClientRect();console.log("[DRAG] Panel:",r.className),console.log("[DRAG] Container:",i.className),console.log("[DRAG] panelRect:",{left:f.left,top:f.top,width:f.width,height:f.height}),console.log("[DRAG] containerRect:",{left:m.left,top:m.top,width:m.width,height:m.height}),console.log("[DRAG] mouse:",{x:g.clientX,y:g.clientY}),c=g.clientX-f.left,d=g.clientY-f.top,console.log("[DRAG] offset:",{x:c,y:d});let b=f.left-m.left,y=f.top-m.top;console.log("[DRAG] targetPosition:",{left:b,top:y}),r.style.left=`${b}px`,r.style.top=`${y}px`,r.style.right="auto",r.style.bottom="auto",r.style.zIndex=String(++bl),n=!0,r.classList.add("dragging"),window.addEventListener("pointermove",p),window.addEventListener("pointerup",u)})}function cn(r,e,t,i=280,n=200){e.style.cursor="nwse-resize";let a=0,s=0,o=0,l=0,c=!1,d=u=>{var y;if(!c)return;let g=u.clientX-o,h=u.clientY-l,f=Math.max(i,a+g),m=Math.max(n,s+h);r.style.width=`${f}px`,(y=r.closest(".preview-shell"))!=null&&y.classList.contains("layout-fixed")||(r.style.height=`${m}px`),t==null||t(f,m)},p=()=>{c&&(c=!1,window.removeEventListener("pointermove",d),window.removeEventListener("pointerup",p))};e.addEventListener("pointerdown",u=>{if(u.button!==0)return;u.preventDefault(),u.stopPropagation();let g=r.getBoundingClientRect();a=g.width,s=g.height,o=u.clientX,l=u.clientY,c=!0,window.addEventListener("pointermove",d),window.addEventListener("pointerup",p)})}function Ta(r,e){var f,m,b,y;let t=(b=(m=(f=r.container)==null?void 0:f.querySelector("#debug-overlay"))!=null?m:r.debugOverlay)!=null?b:e.offsetParent;if(!t||(y=r.container)!=null&&y.classList.contains("layout-fixed"))return;let i=t.getBoundingClientRect(),n=e.getBoundingClientRect(),a=12,s=Math.max(250,Math.floor(i.width-a*2)),o=Math.max(200,Math.floor(i.height-a*2));n.width>s&&(e.style.width=`${s}px`),n.height>o&&(e.style.height=`${o}px`);let l=e.getBoundingClientRect(),c=l.left-i.left,d=l.top-i.top,p=Math.max(a,i.width-l.width-a),u=Math.max(a,i.height-l.height-a),g=Math.min(Math.max(c,a),p),h=Math.min(Math.max(d,a),u);e.style.left=`${Math.round(g)}px`,e.style.top=`${Math.round(h)}px`,e.style.right="auto",e.style.bottom="auto"}function bt(r){var i,n;if(!r.container)return;let e=r.container.querySelector("#debug-workbench");if(!e)return;if(Ta(r,e),(i=r.container)!=null&&i.classList.contains("layout-fixed")){let a=localStorage.getItem("preview_workbench_state"),s={activeTab:r.activeTab};if(a)try{s={...JSON.parse(a),activeTab:r.activeTab}}catch{}localStorage.setItem("preview_workbench_state",JSON.stringify(s));return}let t={activeTab:r.activeTab,width:e.style.width,height:(n=r.container)!=null&&n.classList.contains("layout-fixed")?"":e.style.height,left:e.style.left,top:e.style.top};localStorage.setItem("preview_workbench_state",JSON.stringify(t))}function dn(r){try{let e=localStorage.getItem("preview_workbench_state");if(!e)return;let t=JSON.parse(e);t.activeTab&&(r.activeTab=t.activeTab),window.requestAnimationFrame(()=>{var n,a;let i=(n=r.container)==null?void 0:n.querySelector("#debug-workbench");if(i){let s=(a=r.container)==null?void 0:a.classList.contains("layout-fixed");t.width&&(i.style.width=t.width),t.height&&!s?i.style.height=t.height:s&&(i.style.height=""),t.left&&(i.style.left=t.left,i.style.right="auto"),t.top&&(i.style.top=t.top,i.style.bottom="auto"),Ta(r,i)}})}catch(e){console.warn("[PREVIEW] Failed to load workbench state",e)}}function ka(r,e){let t=e.getBoundingClientRect();(t.left<0||t.top<0||t.right>window.innerWidth||t.bottom>window.innerHeight)&&(console.warn("[Workbench] Workbench positioned outside viewport, repositioning..."),e.style.left="16px",e.style.top="72px",e.style.right="auto",e.style.bottom="auto",Ta(r,e),bt(r))}function Mr(r){var n,a,s;if(!r.container)return;let e=r.container,t=e.querySelector("#debug-toggle");t||console.warn("[PREVIEW] Debug toggle not found in DOM"),t==null||t.addEventListener("click",()=>{var o;console.log("[PREVIEW] Debug toggle clicked"),(o=r.toggleDebug)==null||o.call(r)}),(n=e.querySelector("#debug-close"))==null||n.addEventListener("click",()=>{var o;return(o=r.toggleDebug)==null?void 0:o.call(r,!1)}),(a=e.querySelector("#debug-reset"))==null||a.addEventListener("click",()=>on(r)),(s=e.querySelector("#debug-export"))==null||s.addEventListener("click",()=>ln(r)),e.querySelectorAll(".workbench-tab").forEach(o=>{o.addEventListener("click",()=>{let l=o.dataset.tab;r.activeTab=l,Ia(r),bt(r)})}),Ma(r,e),Pa(r,e)}function Ia(r){var n,a;if(!r.container)return;let e=r.container;e.querySelectorAll(".workbench-tab").forEach(s=>{let o=s.dataset.tab;s.classList.toggle("active",o===r.activeTab)}),e.querySelectorAll(".workbench-tab-panel").forEach(s=>{let o=s.dataset.tabPanel;s.classList.toggle("active",o===r.activeTab)}),r.activeTab==="library"&&r.libraryPanel&&((a=(n=r.libraryPanel).resetSearch)==null||a.call(n))}function Pa(r,e){fe(r,e,"debug-layout-scale","layout.scale_multiplier","#debug-layout-scale-value"),fe(r,e,"debug-layout-offset-x","layout.position_offset.x","#debug-layout-offset-x-value"),fe(r,e,"debug-layout-offset-y","layout.position_offset.y","#debug-layout-offset-y-value"),fe(r,e,"debug-rect-thickness","layout.debug_rect_thickness","#debug-rect-thickness-value"),fe(r,e,"debug-engine-scale","engine.scale","#debug-engine-scale-value"),fe(r,e,"debug-background-scale","engine.background_scale","#debug-background-scale-value"),fe(r,e,"debug-label-pulse-speed","engine.label_pulse_speed","#debug-label-pulse-speed-value"),fe(r,e,"debug-label-pulse-intensity","engine.label_pulse_intensity","#debug-label-pulse-intensity-value"),fe(r,e,"debug-rope-length","physics.rope_length","#debug-rope-length-value");let t=e.querySelector("#debug-rect-visible");t==null||t.addEventListener("change",()=>{let n=Be();n.layout&&(n.layout.debug_rect_visible=!!t.checked)});let i=e.querySelector("#debug-rect-color");i==null||i.addEventListener("input",()=>{let n=i.value.replace("#",""),a=parseInt(n,16),s=Be();s.layout&&(s.layout.debug_rect_color=Number.isFinite(a)?a:16711680)})}function jr(r){if(!r.container||!r.debugOverlay)return;let e=r.container.querySelector("#debug-workbench"),t=r.container.querySelector("#workbench-handle");e&&t&&(!e.style.left&&!e.style.right&&!e.style.top&&!e.style.bottom&&(e.style.right="16px",e.style.top="72px"),et(e,t,r.debugOverlay),t.addEventListener("pointerup",()=>{setTimeout(()=>{bt(r),ka(r,e)},10)}));let i=r.container.querySelector('[data-panel="scene-objects"]'),n=i==null?void 0:i.querySelector("[data-panel-handle]"),a=i==null?void 0:i.querySelector("[data-panel-resize-v]");i&&n&&(!i.style.left&&!i.style.right&&!i.style.top&&!i.style.bottom&&(i.style.left="16px",i.style.top="72px"),et(i,n,r.debugOverlay),n.addEventListener("pointerup",()=>{setTimeout(()=>{ka(r,i)},10)})),i&&a&&cn(i,a);let s=r.container.querySelector('[data-panel="scene-tools-corner"]'),o=s==null?void 0:s.querySelector("[data-panel-handle]");s&&o&&et(s,o,r.debugOverlay);let l=r.container.querySelector('[data-panel="nudge-panel"]'),c=l==null?void 0:l.querySelector("[data-panel-handle]");l&&c&&et(l,c,r.debugOverlay),dn(r)}function Ma(r,e){Array.from(e.querySelectorAll("[data-panel-toggle]")).forEach(i=>{i.addEventListener("click",()=>{let n=i.closest(".scene-panel");n&&n.classList.toggle("collapsed")})})}function fe(r,e,t,i,n){let a=e.querySelector(`#${t}`),s=e.querySelector(n);if(!a||!s)return;let o=Cr(Be(),i);typeof o=="number"&&(a.value=String(o),s.textContent=String(o)),a.addEventListener("input",()=>{let l=Number(a.value);s.textContent=String(l),Ar(Be(),i,l)})}ee();var pn=class{constructor(){this.container=null;this.currentVersion=null;this.availableVersions=[];this.isDevelopmentMode=!1}async forceResyncAfterApply(){var e;try{let t=window.__HANDLER_ACTIVE_SCREEN;await fetch("/api/sync-screens",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({force:!0,screenId:t})})}catch(t){console.warn("[ConfigPersistence] sync-screens failed:",t)}try{let t=window.__HANDLER_REFRESH_SCREEN_INDEX;typeof t=="function"?await t():window.dispatchEvent(new CustomEvent("handler:screen-index-loaded"))}catch{}try{(e=window.refreshEditableConfigIndex)==null||e.call(window)}catch{}try{window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),window.dispatchEvent(new CustomEvent("inspector:refresh")),window.dispatchEvent(new CustomEvent("config:changed",{detail:{action:"batch"}}))}catch{}}async initialize(e){this.container=e,this.isDevelopmentMode=typeof window!="undefined"&&document.querySelector('script[type="module"][src*="/@vite/"]')!==null,await this.loadVersionsList(),window.addEventListener("config:changed",()=>{this.refreshPanel()}),this.refreshPanel()}render(){let e=De(),{hasChanges:t,overrideCount:i,overrides:n}=e,a={};for(let d of n){let p=d.objectId||"Engine";a[p]||(a[p]=[]),a[p].push(d)}let s=localStorage.getItem("handler_last_applied"),o=s?new Date(parseInt(s)).toLocaleString():"Never",l=this.currentVersion?`Version: ${this.currentVersion} (Active)`:"Original",c=this.currentVersion?`Versioned (${this.currentVersion})`:"Global";return`
|
|
1956
1958
|
<div class="config-persistence-panel">
|
|
1957
1959
|
<!-- Status Footer (Always Visible) -->
|
|
1958
1960
|
<div class="persistence-status-footer">
|
|
@@ -2142,19 +2144,19 @@ Continue?`))try{n.textContent="\u23F3 Writing to base...",n.setAttribute("disabl
|
|
|
2142
2144
|
<strong>${i}</strong>
|
|
2143
2145
|
<span>Project files updated.</span>
|
|
2144
2146
|
</div>
|
|
2145
|
-
`,document.body.appendChild(t),setTimeout(()=>{t.classList.add("out"),setTimeout(()=>t.remove(),500)},3e3)}refreshPanel(){if(!this.container)return;let e=this.container.querySelector(".config-persistence-panel");e?e.outerHTML=this.render():this.container.innerHTML=this.render(),this.setupEventListeners()}async loadVersionsList(){try{let e=await fetch("/api/versions");if(!e.ok)throw new Error("Failed to fetch versions");let t=await e.json();this.availableVersions=t.versions||[],this.currentVersion=t.current||null}catch(e){console.error("[ConfigPersistence] Failed to load versions:",e),this.availableVersions=[],this.currentVersion=null}}async switchVersion(e){var n,a,
|
|
2147
|
+
`,document.body.appendChild(t),setTimeout(()=>{t.classList.add("out"),setTimeout(()=>t.remove(),500)},3e3)}refreshPanel(){if(!this.container)return;let e=this.container.querySelector(".config-persistence-panel");e?e.outerHTML=this.render():this.container.innerHTML=this.render(),this.setupEventListeners()}async loadVersionsList(){try{let e=await fetch("/api/versions");if(!e.ok)throw new Error("Failed to fetch versions");let t=await e.json();this.availableVersions=t.versions||[],this.currentVersion=t.current||null}catch(e){console.error("[ConfigPersistence] Failed to load versions:",e),this.availableVersions=[],this.currentVersion=null}}async switchVersion(e){var n,a,s;let t=De();if(t.hasChanges){if(!confirm(`Switch to version "${e||"original"}"?
|
|
2146
2148
|
|
|
2147
2149
|
You have ${t.overrideCount} staged changes that will be discarded.
|
|
2148
2150
|
|
|
2149
2151
|
Options:
|
|
2150
2152
|
OK = Discard staged overrides and switch
|
|
2151
|
-
Cancel = Stay on current version`)){let l=(n=this.container)==null?void 0:n.querySelector("#version-selector");l&&(l.value=this.currentVersion||"");return}}else if(!confirm(`Switch to version "${e||"original"}"?`)){let l=(a=this.container)==null?void 0:a.querySelector("#version-selector");l&&(l.value=this.currentVersion||"");return}try{let o=await fetch("/api/switch-version",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({versionName:e||null})});if(!o.ok){let l=await o.json();throw new Error(l.error||"Failed to switch version")}pe(),localStorage.removeItem("handler_config_overrides"),localStorage.setItem("handler_preview_override_mode","false"),window.location.reload()}catch(o){alert(`\u274C Failed to switch version: ${o.message}`);let l=(
|
|
2153
|
+
Cancel = Stay on current version`)){let l=(n=this.container)==null?void 0:n.querySelector("#version-selector");l&&(l.value=this.currentVersion||"");return}}else if(!confirm(`Switch to version "${e||"original"}"?`)){let l=(a=this.container)==null?void 0:a.querySelector("#version-selector");l&&(l.value=this.currentVersion||"");return}try{let o=await fetch("/api/switch-version",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({versionName:e||null})});if(!o.ok){let l=await o.json();throw new Error(l.error||"Failed to switch version")}pe(),localStorage.removeItem("handler_config_overrides"),localStorage.setItem("handler_preview_override_mode","false"),window.location.reload()}catch(o){alert(`\u274C Failed to switch version: ${o.message}`);let l=(s=this.container)==null?void 0:s.querySelector("#version-selector");l&&(l.value=this.currentVersion||"")}}async directApply(){if(!this.isDevelopmentMode){alert("Direct Apply is only available in development mode.");return}if(confirm(`\u26A0\uFE0F WARNING: Direct Apply
|
|
2152
2154
|
|
|
2153
2155
|
This will DIRECTLY MODIFY your base configuration files WITHOUT creating a snapshot.
|
|
2154
2156
|
|
|
2155
2157
|
This cannot be undone unless you have git commits or backups.
|
|
2156
2158
|
|
|
2157
|
-
Are you absolutely sure?`))try{let t=Xe(),i={};for(let[a,
|
|
2159
|
+
Are you absolutely sure?`))try{let t=Xe(),i={};for(let[a,s]of Object.entries(t.objects)){let o=s,l=a;/^(json\.|ui\.|effects\.|engine\.)/.test(l)||(l=`json.${a}`),o&&typeof o=="object"&&(o.identity||(o.identity={}),o.identity.id=l),i[`objects/${l}.json`]=o}t.engine&&(t.engine.runtime&&(i["engine/engine.runtime.json"]=t.engine.runtime),t.engine.assets&&(i["engine/engine.assets.json"]=t.engine.assets),t.engine.splash&&(i["engine/engine.splash.json"]=t.engine.splash),t.engine.loading&&(i["engine/engine.loading.json"]=t.engine.loading),t.engine.start&&(i["engine/engine.start.json"]=t.engine.start),t.engine.tutorial&&(i["engine/engine.tutorial.json"]=t.engine.tutorial),t.engine.endgame&&(i["engine/engine.endgame.json"]=t.engine.endgame),!t.engine.runtime&&!t.engine.assets&&(i["engine/engine.json"]=t.engine));for(let[a,s]of Object.entries(t.scenes)){let o=a.startsWith("scene.")?a:`scene.${a}`;i[`scenes/${o}.json`]=s}let n=await fetch("/api/apply-direct",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({configs:i,assets:{}})});if(!n.ok){let a=await n.json();throw new Error(a.error||"Direct apply failed")}pe(),this.showSuccessNotification(),this.refreshPanel()}catch(t){console.error("[ConfigPersistence] Direct apply failed:",t),alert(`\u274C Direct apply failed: ${t.message}`)}}};var Yt=class{constructor(){this.debugOverlay=null;this.isDebugOpen=!1;this.selectedObjectId=null;this.configViewer=null;this.container=null;this.objectAutoApplyTimer=null;this.objectDebugRaf=null;this.objectBoundsGfx=null;this.objectAnchorGfx=null;this.highlightObject=!1;this.highlightAnchor=!1;this.activeTab="hierarchy";this.sceneObjectsPanel=new _i;this.sceneToolsPanel=new Oi;this.nudgePanel=new Ri;this.inspectorPanel=new Ki;this.libraryPanel=new Bt;this.libraryPanelDocked=new Bt;this.brandVisionPanel=new en;this.customizeSettingsPanel=new tn;this.configPersistencePanel=new pn;this.loadingScreenPanel=new nn}applyAssetChange(e,t){return ur(this,e,t)}resetAsset(e){return gr(this,e)}applySlotAsset(e,t,i){return Zi(this,e,t,i)}resetSlotAsset(e,t,i){return hr(this,e,t,i)}startObjectVisuals(){return Sr(this)}stopObjectVisuals(){return Er(this)}shouldRunObjectVisuals(){return an(this)}updateObjectVisuals(){return sn(this)}getSelectedInstanceId(){return fa(this)}getDisplayObjectById(e){return ma(this,e)}getSelectedObjectConfig(){return Vt(this)}getConfigAnchorWorldPoint(e){return ba(this,e)}getScreenSize(){return ya(this)}ensureBoundsGfx(){return va(this)}ensureAnchorGfx(){return wa(this)}drawBounds(e){return xa(this,e)}drawAnchor(e){return Sa(this,e)}clearBounds(){return Ea(this)}clearAnchor(){return Ca(this)}clearObjectVisuals(){return Ut(this)}updateObjectInfo(e){return Gt(this,e)}resetDebugConfig(){return on(this)}applyDebugConfig(){return Lr(this)}exportDebugConfig(){return ln(this)}loadObjectConfig(e){return Tr(this,e)}fillConfigViewer(e){return rn(this,e)}copyConfigValues(){return kr(this)}applyObjectConfig(e){return La(this,e)}applyCustomizeSettings(e,t){return Ir(this,e,t)}scheduleObjectAutoApply(){return Pr(this)}setupDebugEventListeners(){return Mr(this)}setupDebugInputListeners(e){return Pa(this,e)}setupPanelLayout(){return jr(this)}setupCollapsiblePanels(e){return Ma(this,e)}setupRangeInput(e,t,i,n){return fe(this,e,t,i,n)}updateWorkbenchTabs(){return Ia(this)}saveWorkbenchState(){return bt(this)}loadWorkbenchState(){return dn(this)}initialize(e){var n;this.container=e,this.debugOverlay=e.querySelector(".debug-overlay"),this.configViewer=e.querySelector("#config-viewer");try{let a=localStorage.getItem("preview_workbench_state");if(a){let s=JSON.parse(a);s.activeTab&&(this.activeTab=s.activeTab)}}catch(a){console.warn("[PREVIEW] Failed to load workbench tab state",a)}this.sceneObjectsPanel.initialize(e,{onSelect:a=>this.handleObjectSelect(a)}),this.libraryPanel.initialize(e,{onApply:(a,s,o)=>this.applySlotAsset(a,s,o),onReset:(a,s,o)=>this.resetSlotAsset(a,s,o)});let t=e.querySelector("#dock-library-content");t&&(t.innerHTML=this.libraryPanelDocked.render(),this.libraryPanelDocked.initialize(t,{onApply:(a,s,o)=>this.applySlotAsset(a,s,o),onReset:(a,s,o)=>this.resetSlotAsset(a,s,o)})),this.inspectorPanel.initialize(e,{onPropertyChange:(a,s,o)=>{console.log("[Inspector] Property changed:",a,s,o)}}),this.brandVisionPanel.initialize(e,()=>{this.toggleDebug(!1);let a="/dashboard";window.location.pathname!==a&&(window.location.href=a)}),this.customizeSettingsPanel.initialize(e,{onApply:(a,s)=>this.applyCustomizeSettings(a,s)}),this.sceneToolsPanel.initialize(e,{onHighlightObject:a=>{this.highlightObject=a,a?this.selectedObjectId&&this.startObjectVisuals():this.stopObjectVisuals()},onHighlightAnchor:a=>{this.highlightAnchor=a,a?this.selectedObjectId&&this.startObjectVisuals():this.stopObjectVisuals()},onNudge:(a,s)=>this.nudgeSelectedObject(a,s),onShowSplash:()=>{let a=window;typeof a.__previewShowSplash=="function"&&a.__previewShowSplash()},onUpdateSplash:a=>{let s=window;typeof s.applyEditableEngineConfig=="function"&&s.applyEditableEngineConfig({splash:a})}}),this.nudgePanel.initialize(e,{onNudge:async(a,s)=>{var u,g,h;if(!this.selectedObjectId)return;let o=this.getSelectedObjectConfig();if(!o)return;let l=(u=o.transform)==null?void 0:u.position,c=((g=l==null?void 0:l.x)!=null?g:0)+a,d=((h=l==null?void 0:l.y)!=null?h:0)+s,{applyConfigOverride:p}=await Promise.resolve().then(()=>(ee(),Ne));p({objectId:this.selectedObjectId,path:"transform.position",value:{x:c,y:d}},{silent:!0,emitEvent:!0}),window.dispatchEvent(new CustomEvent("inspector:refresh"))},onScale:async a=>{var d,p;if(!this.selectedObjectId)return;let s=this.getSelectedObjectConfig();if(!s)return;let o=(p=(d=s.transform)==null?void 0:d.scale)!=null?p:1,l=Math.max(.1,o+a),{applyConfigOverride:c}=await Promise.resolve().then(()=>(ee(),Ne));c({objectId:this.selectedObjectId,path:"transform.scale",value:l},{silent:!0,emitEvent:!0}),window.dispatchEvent(new CustomEvent("inspector:refresh"))}});let i=e.querySelector("#debug-nudge-enabled");i==null||i.addEventListener("change",()=>{i.checked?this.nudgePanel.show():this.nudgePanel.hide()}),this.configPersistencePanel.initialize(e),this.loadingScreenPanel.initialize(e,{onShowLoadingScreen:()=>{let a=window;typeof a.__previewShowLoading=="function"?a.__previewShowLoading():console.warn("[DEBUG] __previewShowLoading not available")},onHideLoadingScreen:()=>{let a=window;typeof a.__previewHideLoading=="function"?a.__previewHideLoading():console.warn("[DEBUG] __previewHideLoading not available")},onUpdateLoading:a=>{let s=window;typeof s.applyEditableEngineConfig=="function"&&s.applyEditableEngineConfig({loading:a}),typeof s.__previewUpdateLoading=="function"?s.__previewUpdateLoading(a):console.warn("[DEBUG] __previewUpdateLoading not available")}}),window.__openAiEditor=(a,s,o,l)=>{this.customizeSettingsPanel.openAiEditor(a,s,o,l)},this.setupPanelLayout(),this.updateWorkbenchTabs(),window.__debugContext=this,window.__updateWorkbenchTabs=()=>this.updateWorkbenchTabs(),this.isDebugOpen=!0,(n=this.debugOverlay)==null||n.classList.remove("hidden"),this.updateDebugBadge(),this.sceneObjectsPanel.refreshObjects(),window.__previewSelectObject=a=>this.selectObject(a),window.__getSelectedObjectId=()=>this.selectedObjectId,window.addEventListener("config:changed",a=>{var s,o;((s=a.detail)==null?void 0:s.action)!=="remove"&&((o=a.detail)==null?void 0:o.action)!=="clear_object"&&this.highlightChangesTab()}),window.applyAssetToSlot=(a,s,o)=>this.applySlotAsset(a,s,o),window.refreshAssetLibrary=()=>Promise.all([this.libraryPanel.refresh(),this.libraryPanelDocked.refresh()]),window.reRenderAssetLibrary=()=>{this.libraryPanel.reRender(),this.libraryPanelDocked.reRender()},window.getEngineSplashConfig=()=>{var s;let a=window.getActiveConfig;if(typeof a=="function"){let o=a();return((s=o==null?void 0:o.engine)==null?void 0:s.splash)||null}return null},window.addAssetToRegistry=(a,s)=>{let o=window.getEditableAssets;if(typeof o=="function"){let l=o();if(l!=null&&l.libraryAssets&&(l.libraryAssets[a]||(l.libraryAssets[a]=[]),!l.libraryAssets[a].some(d=>d.filename===s))){let d=s.replace(/\.(png|jpg|jpeg)$/i,"").replace(/_/g," ");l.libraryAssets[a].unshift({filename:s,displayName:d}),console.log(`[DEBUG] Added ${s} to registry category ${a}`)}}},window.__highlightLibrarySlot=(a,s)=>{this.libraryPanel.highlightSlot(a,s),this.libraryPanelDocked.highlightSlot(a,s)}}selectObject(e){this.handleObjectSelect(e),this.activeTab!=="inspector"&&this.activeTab!=="ai"&&this.setActiveTab("inspector")}setActiveTab(e){this.activeTab=e,this.updateWorkbenchTabs(),this.saveWorkbenchState()}highlightChangesTab(){var t;let e=(t=this.container)==null?void 0:t.querySelector('[data-tab="changes"]');e&&e.classList.add("has-pending-changes")}getDebugOverlayHTML(){return`
|
|
2158
2160
|
<div class="debug-overlay hidden" id="debug-overlay">
|
|
2159
2161
|
<div class="debug-workbench" id="debug-workbench">
|
|
2160
2162
|
<div class="workbench-header" id="workbench-handle">
|
|
@@ -2201,7 +2203,7 @@ Are you absolutely sure?`))try{let t=Xe(),i={};for(let[a,r]of Object.entries(t.o
|
|
|
2201
2203
|
${this.sceneToolsPanel.render()}
|
|
2202
2204
|
${this.nudgePanel.render()}
|
|
2203
2205
|
</div>
|
|
2204
|
-
`}refresh(){this.isDebugOpen&&(this.sceneObjectsPanel.refreshObjects(),this.libraryPanel.refresh(),this.libraryPanelDocked.refresh(),this.brandVisionPanel.refresh(),this.selectedObjectId&&this.handleObjectSelect(this.selectedObjectId))}toggleDebug(e){var t;this.isDebugOpen=e!=null?e:!this.isDebugOpen,(t=this.debugOverlay)==null||t.classList.toggle("hidden",!this.isDebugOpen),this.updateDebugBadge(),this.isDebugOpen?this.refresh():this.stopObjectVisuals()}updateDebugBadge(){if(!this.container)return;let e=this.container.querySelector("#debug-badge");e&&e.classList.toggle("active",this.isDebugOpen)}handleObjectSelect(e){this.selectedObjectId=e,this.sceneObjectsPanel.setSelected(e),this.inspectorPanel.loadObject(e),this.loadObjectConfig(e),this.startObjectVisuals(),window.dispatchEvent(new CustomEvent("preview:select",{detail:{objectId:e}}))}async nudgeSelectedObject(e,t){var o,l,c,d;let i=this.sceneObjectsPanel.getSelectedIds();if(i.length===0)return;let n=this.nudgePanel.getNudgeStep();if(i.length===1&&this.container){let p=this.container.querySelector("#config-pos-x"),u=this.container.querySelector("#config-pos-y");if(p&&u){let g=Number((o=p.value)!=null?o:0),h=Number((l=u.value)!=null?l:0),f=g+e*n,m=h+t*n;p.value=String(f),u.value=String(m),(c=this.configViewer)==null||c.style.setProperty("display","block"),this.scheduleObjectAutoApply();return}}let a=window.getEditableObjectConfig;if(typeof a!="function")return;let
|
|
2206
|
+
`}refresh(){this.isDebugOpen&&(this.sceneObjectsPanel.refreshObjects(),this.libraryPanel.refresh(),this.libraryPanelDocked.refresh(),this.brandVisionPanel.refresh(),this.selectedObjectId&&this.handleObjectSelect(this.selectedObjectId))}toggleDebug(e){var t;this.isDebugOpen=e!=null?e:!this.isDebugOpen,(t=this.debugOverlay)==null||t.classList.toggle("hidden",!this.isDebugOpen),this.updateDebugBadge(),this.isDebugOpen?this.refresh():this.stopObjectVisuals()}updateDebugBadge(){if(!this.container)return;let e=this.container.querySelector("#debug-badge");e&&e.classList.toggle("active",this.isDebugOpen)}handleObjectSelect(e){this.selectedObjectId=e,this.sceneObjectsPanel.setSelected(e),this.inspectorPanel.loadObject(e),this.loadObjectConfig(e),this.startObjectVisuals(),window.dispatchEvent(new CustomEvent("preview:select",{detail:{objectId:e}}))}async nudgeSelectedObject(e,t){var o,l,c,d;let i=this.sceneObjectsPanel.getSelectedIds();if(i.length===0)return;let n=this.nudgePanel.getNudgeStep();if(i.length===1&&this.container){let p=this.container.querySelector("#config-pos-x"),u=this.container.querySelector("#config-pos-y");if(p&&u){let g=Number((o=p.value)!=null?o:0),h=Number((l=u.value)!=null?l:0),f=g+e*n,m=h+t*n;p.value=String(f),u.value=String(m),(c=this.configViewer)==null||c.style.setProperty("display","block"),this.scheduleObjectAutoApply();return}}let a=window.getEditableObjectConfig;if(typeof a!="function")return;let s=new xe;for(let p of i){let u=a(p);if(!u)continue;let g=((d=u.transform)==null?void 0:d.position)||[0,0],h=Array.isArray(g)?g[0]:g.x||0,f=Array.isArray(g)?g[1]:g.y||0,m=h+e*n,b=f+t*n;await s.updateProperty(p,"transform.position",[m,b])}i.length===1&&this.selectedObjectId===i[0]&&window.dispatchEvent(new CustomEvent("inspector:refresh"))}};function yl(r){return new Promise((e,t)=>{let i=new FileReader;i.onerror=()=>t(new Error("FileReader failed")),i.onload=()=>e(String(i.result||"")),i.readAsDataURL(r)})}function vl(r){var n;let[e,t]=r.split(","),i=e==null?void 0:e.match(/data:(.*?);base64/);return{base64:t!=null?t:"",mimeType:(n=i==null?void 0:i[1])!=null?n:"image/png"}}function wl(r){return`
|
|
2205
2207
|
Analyze these screenshots of a brand or game and extract its "Brand DNA".
|
|
2206
2208
|
|
|
2207
2209
|
Provide a concise summary (2-3 sentences) covering:
|
|
@@ -2215,12 +2217,27 @@ FORMAT:
|
|
|
2215
2217
|
Summary: [Your summary here]
|
|
2216
2218
|
Palette: [#RRGGBB, #RRGGBB, ...]
|
|
2217
2219
|
|
|
2218
|
-
${
|
|
2220
|
+
${r?`
|
|
2219
2221
|
ADDITIONAL RULES/NOTES:
|
|
2220
|
-
${
|
|
2221
|
-
`.trim()}function _r(){let
|
|
2222
|
+
${r}`:""}
|
|
2223
|
+
`.trim()}function _r(){let r=[],e="",t=null;return{async addSources(i){let n=[];for(let a of i){let s=await yl(a),o=vl(s),l={id:`${Date.now()}-${Math.random().toString(16).slice(2)}`,name:a.name,base64:o.base64,mimeType:o.mimeType,dataUrl:s};r.push(l),n.push(l)}return n},getSources(){return r.slice()},async analyze(i,n,a){if(r.length===0)throw new Error("No screenshots to analyze.");let s=wl(n),o=r.map(u=>({base64:u.base64,mimeType:u.mimeType})),l=await Ji(i,s,o,{model:a}),c=e,d=[],p=l.split(`
|
|
2222
2224
|
`);for(let u of p)if(u.toLowerCase().startsWith("summary:"))c=u.slice(8).trim();else if(u.toLowerCase().includes("palette:")){let g=u.match(/#[0-9A-Fa-f]{6}/g);g&&g.forEach(h=>{d.includes(h.toUpperCase())||d.push(h.toUpperCase())})}return(!c||c===e)&&(c=l.split(`
|
|
2223
|
-
Palette:`)[0].replace(/^Summary:\s*/i,"").trim()),t={summary:c,palette:d.slice(0,10)},t},setSummary(i){e=i,t&&(t={...t,summary:i})},getResult(){return t}}}var tt="handler_api_key_";var yt=class{static setKey(e,t,i){try{let n={key:this.encryptKey(t),created:Date.now(),lastUsed:Date.now(),label:i||e},a=`${tt}${e}`;localStorage.setItem(a,JSON.stringify(n))}catch(n){console.error("[ApiKeyStorage] Failed to store API key:",n)}}static getKey(e){try{let t=`${tt}${e}`,i=localStorage.getItem(t);if(!i)return null;let n=JSON.parse(i);return n.lastUsed=Date.now(),localStorage.setItem(t,JSON.stringify(n)),this.decryptKey(n.key)}catch(t){return console.error("[ApiKeyStorage] Failed to retrieve API key:",t),null}}static hasKey(e){let t=`${tt}${e}`;return localStorage.getItem(t)!==null}static removeKey(e){try{let t=`${tt}${e}`;localStorage.removeItem(t)}catch(t){console.error("[ApiKeyStorage] Failed to remove API key:",t)}}static getStoredServices(){let e=[];try{for(let t=0;t<localStorage.length;t++){let i=localStorage.key(t);if(i&&i.startsWith(tt)){let n=i.substring(tt.length),a=localStorage.getItem(i);if(a){let
|
|
2225
|
+
Palette:`)[0].replace(/^Summary:\s*/i,"").trim()),t={summary:c,palette:d.slice(0,10)},t},setSummary(i){e=i,t&&(t={...t,summary:i})},getResult(){return t}}}var tt="handler_api_key_";var yt=class{static setKey(e,t,i){try{let n={key:this.encryptKey(t),created:Date.now(),lastUsed:Date.now(),label:i||e},a=`${tt}${e}`;localStorage.setItem(a,JSON.stringify(n))}catch(n){console.error("[ApiKeyStorage] Failed to store API key:",n)}}static getKey(e){try{let t=`${tt}${e}`,i=localStorage.getItem(t);if(!i)return null;let n=JSON.parse(i);return n.lastUsed=Date.now(),localStorage.setItem(t,JSON.stringify(n)),this.decryptKey(n.key)}catch(t){return console.error("[ApiKeyStorage] Failed to retrieve API key:",t),null}}static hasKey(e){let t=`${tt}${e}`;return localStorage.getItem(t)!==null}static removeKey(e){try{let t=`${tt}${e}`;localStorage.removeItem(t)}catch(t){console.error("[ApiKeyStorage] Failed to remove API key:",t)}}static getStoredServices(){let e=[];try{for(let t=0;t<localStorage.length;t++){let i=localStorage.key(t);if(i&&i.startsWith(tt)){let n=i.substring(tt.length),a=localStorage.getItem(i);if(a){let s=JSON.parse(a);e.push({service:n,label:s.label,created:s.created,lastUsed:s.lastUsed})}}}}catch(t){console.error("[ApiKeyStorage] Failed to get stored services:",t)}return e.sort((t,i)=>i.lastUsed-t.lastUsed)}static clearAll(){try{let e=[];for(let t=0;t<localStorage.length;t++){let i=localStorage.key(t);i&&i.startsWith(tt)&&e.push(i)}e.forEach(t=>localStorage.removeItem(t))}catch(e){console.error("[ApiKeyStorage] Failed to clear API keys:",e)}}static encryptKey(e){try{let i="handler_preview_salt_2024"+e;return btoa(i)}catch(t){return console.warn("[ApiKeyStorage] Encryption failed, storing as-is:",t),e}}static decryptKey(e){try{let t=atob(e),i="handler_preview_salt_2024";return t.startsWith(i)?t.substring(i.length):t}catch(t){return console.warn("[ApiKeyStorage] Decryption failed, returning as-is:",t),e}}},ja=()=>yt.getKey("gemini"),_a=(r,e)=>yt.setKey("gemini",r,e),xl=()=>yt.hasKey("gemini");window.ApiKeyStorage=yt;window.getGeminiApiKey=ja;window.setGeminiApiKey=_a;window.hasGeminiApiKey=xl;var Ra=class{constructor(){this.modal=null;this.options=null;this.analyzer=_r();this.currentPrompt="";this.isGenerating=!1;this.generatedImages=[];this.selectedImageIndex=-1;this.savedLibraryPaths=new Map;this.promptInput=null;this.generateBtn=null;this.saveLibraryBtn=null;this.loadingEl=null;this.galleryEl=null;this.previewEl=null;this.statusEl=null}open(e){this.options=e,this.currentPrompt=e.initialPrompt||"",this.generatedImages=[],this.selectedImageIndex=-1,this.isGenerating=!1,this.savedLibraryPaths.clear(),this.createModal(),document.body.appendChild(this.modal),setTimeout(()=>{var t,i;(t=this.promptInput)==null||t.focus(),(i=this.promptInput)==null||i.select()},100)}createModal(){var t;let e=document.createElement("div");e.className="ai-modal",e.innerHTML=`
|
|
2226
|
+
<style>
|
|
2227
|
+
.ai-gallery-item {
|
|
2228
|
+
position: relative;
|
|
2229
|
+
}
|
|
2230
|
+
.ai-gallery-saved {
|
|
2231
|
+
position: absolute;
|
|
2232
|
+
top: 4px;
|
|
2233
|
+
right: 4px;
|
|
2234
|
+
font-size: 14px;
|
|
2235
|
+
background: rgba(0, 0, 0, 0.6);
|
|
2236
|
+
border-radius: 4px;
|
|
2237
|
+
padding: 2px 4px;
|
|
2238
|
+
pointer-events: none;
|
|
2239
|
+
}
|
|
2240
|
+
</style>
|
|
2224
2241
|
<div class="ai-modal-card">
|
|
2225
2242
|
<div class="ai-modal-header">
|
|
2226
2243
|
<div class="ai-modal-actions">
|
|
@@ -2292,21 +2309,26 @@ Palette:`)[0].replace(/^Summary:\s*/i,"").trim()),t={summary:c,palette:d.slice(0
|
|
|
2292
2309
|
</div>
|
|
2293
2310
|
</div>
|
|
2294
2311
|
|
|
2312
|
+
<!-- STATUS MESSAGE -->
|
|
2313
|
+
<div class="ai-status" data-status style="padding: 8px 16px; font-size: 12px; color: #888; text-align: center;"></div>
|
|
2314
|
+
|
|
2295
2315
|
<!-- ACTION BUTTONS -->
|
|
2296
2316
|
<div class="ai-modal-actions">
|
|
2297
2317
|
<button class="ai-btn" data-action="cancel">Cancel</button>
|
|
2298
2318
|
<button class="ai-btn" data-action="generate" disabled>Generate</button>
|
|
2319
|
+
<button class="ai-btn success" data-action="save-library" disabled>\u{1F4BE} Save to Library</button>
|
|
2299
2320
|
<button class="ai-btn primary" data-action="apply" disabled>Apply</button>
|
|
2300
2321
|
</div>
|
|
2301
2322
|
</div>
|
|
2302
|
-
`,this.modal=e,this.attachEventListeners(),this.updatePromptFromDna()}attachEventListeners(){var i;if(!this.modal)return;this.promptInput=this.modal.querySelector(".ai-textarea"),this.generateBtn=this.modal.querySelector('[data-action="generate"]'),this.loadingEl=this.modal.querySelector("[data-loading]"),this.galleryEl=this.modal.querySelector("[data-gallery]"),this.previewEl=this.modal.querySelector("[data-preview]"),(i=this.promptInput)==null||i.addEventListener("input",()=>{var n;this.currentPrompt=((n=this.promptInput)==null?void 0:n.value)||"",this.updateGenerateButton()});let e=this.modal.querySelector('[data-strength="creativity"]'),t=this.modal.querySelector(".ai-strength-value");e==null||e.addEventListener("input",()=>{t.textContent=e.value}),this.modal.addEventListener("click",n=>{var o;let a=n.target;switch(a.dataset.action||((o=a.closest("[data-action]"))==null?void 0:o.getAttribute("data-action"))){case"generate":this.generateImage();break;case"apply":this.applySelectedImage();break;case"gallery":this.toggleGallery();break;case"close":case"cancel":this.close();break}}),this.modal.addEventListener("click",n=>{let a=n.target;if(a.classList.contains("ai-gallery-item")||a.closest(".ai-gallery-item")){let
|
|
2323
|
+
`,this.modal=e,this.attachEventListeners(),this.updatePromptFromDna()}attachEventListeners(){var i;if(!this.modal)return;this.promptInput=this.modal.querySelector(".ai-textarea"),this.generateBtn=this.modal.querySelector('[data-action="generate"]'),this.saveLibraryBtn=this.modal.querySelector('[data-action="save-library"]'),this.loadingEl=this.modal.querySelector("[data-loading]"),this.galleryEl=this.modal.querySelector("[data-gallery]"),this.previewEl=this.modal.querySelector("[data-preview]"),this.statusEl=this.modal.querySelector("[data-status]"),(i=this.promptInput)==null||i.addEventListener("input",()=>{var n;this.currentPrompt=((n=this.promptInput)==null?void 0:n.value)||"",this.updateGenerateButton()});let e=this.modal.querySelector('[data-strength="creativity"]'),t=this.modal.querySelector(".ai-strength-value");e==null||e.addEventListener("input",()=>{t.textContent=e.value}),this.modal.addEventListener("click",n=>{var o;let a=n.target;switch(a.dataset.action||((o=a.closest("[data-action]"))==null?void 0:o.getAttribute("data-action"))){case"generate":this.generateImage();break;case"save-library":this.saveSelectedImageToLibrary();break;case"apply":this.applySelectedImage();break;case"gallery":this.toggleGallery();break;case"close":case"cancel":this.close();break}}),this.modal.addEventListener("click",n=>{let a=n.target;if(a.classList.contains("ai-gallery-item")||a.closest(".ai-gallery-item")){let s=a.closest(".ai-gallery-item"),o=parseInt(s.dataset.index||"-1");o>=0&&this.selectImage(o)}}),this.updateGenerateButton(),this.setStatus("Ready. Generate an image to get started.")}updateGenerateButton(){if(!this.generateBtn)return;let e=this.currentPrompt.trim().length>0;this.generateBtn.disabled=!e||this.isGenerating}async updatePromptFromDna(){var t;let e=(t=this.modal)==null?void 0:t.querySelector("#ai-use-dna");if(e!=null&&e.checked)try{let i=this.analyzer.getResult();if(i!=null&&i.summary&&this.promptInput){let n=`${this.currentPrompt}
|
|
2303
2324
|
|
|
2304
|
-
Style guidelines: ${i.summary}`;this.promptInput.value=n,this.currentPrompt=n}}catch(i){console.warn("[AiEditorModal] Failed to apply brand DNA:",i)}}async generateImage(){var e,t,i,n;if(!(!this.options||this.isGenerating)){this.isGenerating=!0,this.updateGenerateButton(),(e=this.loadingEl)==null||e.classList.remove("hidden"),(t=this.previewEl)==null||t.classList.add("hidden");try{let a=this.getApiKey();if(!a){alert("Please set your Gemini API key first. You can do this in the AI Creative Suite panel.");return}let
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2325
|
+
Style guidelines: ${i.summary}`;this.promptInput.value=n,this.currentPrompt=n}}catch(i){console.warn("[AiEditorModal] Failed to apply brand DNA:",i)}}async generateImage(){var e,t,i,n;if(!(!this.options||this.isGenerating)){this.isGenerating=!0,this.updateGenerateButton(),(e=this.loadingEl)==null||e.classList.remove("hidden"),(t=this.previewEl)==null||t.classList.add("hidden");try{let a=this.getApiKey();if(!a){alert("Please set your Gemini API key first. You can do this in the AI Creative Suite panel.");return}let s=[];if(this.options.currentValue&&this.options.currentValue.startsWith("data:"))try{let c=await Xi(this.options.currentValue);c&&(s=[{base64:c.base64,mimeType:c.mimeType}])}catch(c){console.warn("[AiEditorModal] Failed to load current image:",c)}let o=await ft(a,this.currentPrompt,s,{aspectRatio:"1:1"}),l=await ht(o);this.generatedImages.push(l||o),this.selectedImageIndex=this.generatedImages.length-1,this.updateGallery(),this.updatePreview(),this.updateApplyButton()}catch(a){console.error("[AiEditorModal] Generation failed:",a),alert(`Generation failed: ${a instanceof Error?a.message:"Unknown error"}`)}finally{this.isGenerating=!1,(i=this.loadingEl)==null||i.classList.add("hidden"),(n=this.previewEl)==null||n.classList.remove("hidden"),this.updateGenerateButton()}}}updateGallery(){if(!this.galleryEl)return;let e=this.galleryEl.querySelector("[data-gallery-grid]");e&&(e.innerHTML=this.generatedImages.map((t,i)=>{let n=this.savedLibraryPaths.has(i),a=n?this.savedLibraryPaths.get(i):null,s=a?a.split("/").pop():"";return`
|
|
2326
|
+
<div class="ai-gallery-item ${i===this.selectedImageIndex?"active":""}" data-index="${i}">
|
|
2327
|
+
<img class="ai-gallery-thumb" src="${t}" alt="Generated ${i+1}" />
|
|
2328
|
+
<div class="ai-gallery-label">#${i+1}${n?" \u2713":""}</div>
|
|
2329
|
+
${n?`<div class="ai-gallery-saved" title="Saved: ${s}">\u{1F4BE}</div>`:""}
|
|
2330
|
+
</div>
|
|
2331
|
+
`}).join(""))}updatePreview(){if(!this.previewEl||this.selectedImageIndex<0)return;let e=this.generatedImages[this.selectedImageIndex];this.previewEl.innerHTML=`<img src="${e}" alt="Selected image" />`}selectImage(e){e<0||e>=this.generatedImages.length||(this.selectedImageIndex=e,this.updateGallery(),this.updatePreview(),this.updateApplyButton())}toggleGallery(){this.galleryEl&&this.galleryEl.classList.toggle("hidden")}updateApplyButton(){var i,n;let e=(i=this.modal)==null?void 0:i.querySelector('[data-action="apply"]'),t=(n=this.modal)==null?void 0:n.querySelector('[data-action="save-library"]');e&&(e.disabled=this.selectedImageIndex<0),t&&(t.disabled=this.selectedImageIndex<0)}setStatus(e,t=!1){this.statusEl&&(this.statusEl.textContent=e,this.statusEl.style.color=t?"#ff4444":"#888")}async saveSelectedImageToLibrary(){var s;if(this.selectedImageIndex<0){this.setStatus("No image selected.",!0);return}let e=this.generatedImages[this.selectedImageIndex];if(!e){this.setStatus("Invalid image data.",!0);return}if(this.savedLibraryPaths.has(this.selectedImageIndex)){let o=this.savedLibraryPaths.get(this.selectedImageIndex);this.setStatus(`Already saved: ${o}`);return}let t=((s=this.options)==null?void 0:s.objectId)||"asset",n=`${t.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"")}_ai_${Date.now()}.png`,a=this.inferCategoryFromObjectId(t);this.setStatus("Saving to library...");try{let l=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:a,filename:n,data:e,overwrite:!0})})).json();if(l.success){console.log("[AiEditorModal] \u2705 Saved to library:",l.path),this.savedLibraryPaths.set(this.selectedImageIndex,l.path),this.setStatus(`\u2705 Saved: ${n}`);let c=window.addAssetToRegistry;typeof c=="function"&&c(a,n);let d=window.getEditableAssets;if(typeof d=="function"){let u=d();u&&!u.categories&&(u.categories=[]),u!=null&&u.categories&&!u.categories.includes(a)&&(u.categories.push(a),console.log(`[AiEditorModal] Added category ${a} to registry`))}try{(await fetch("/api/setup-library",{method:"POST",headers:{"Content-Type":"application/json"}})).ok?console.log("[AiEditorModal] \u2705 Registry rebuilt from disk"):console.warn("[AiEditorModal] Setup-library returned non-OK status")}catch(u){console.warn("[AiEditorModal] Setup-library not available:",u)}let p=window.refreshAssetLibrary;typeof p=="function"&&(console.log("[AiEditorModal] Refreshing library panel..."),await p()),this.updateGallery()}else console.error("[AiEditorModal] \u274C Save failed:",l.error),this.setStatus(`Save failed: ${l.error}`,!0)}catch(o){console.error("[AiEditorModal] \u274C Save error:",o),this.setStatus("Save failed. Check console.",!0)}}inferCategoryFromObjectId(e){let t=e.toLowerCase();return t.includes("background")?"backgrounds":t.includes("character")?"characters":t.includes("key")?"collectedkeys":t.includes("draggable")?"draggables":t.includes("environment")||t.includes("env")||t.includes("hand")||t.includes("prop")||t.includes("item")?"environment":t.includes("machine")?"machines":t.includes("tutorial")?"tutorial":t.includes("ui")||t.includes("button")||t.includes("label")||t.includes("icon")||t.includes("logo")?"ui":t.includes("effect")||t.includes("confetti")||t.includes("particle")?"effects":"ui"}async applySelectedImage(){var i;if(this.selectedImageIndex<0||!((i=this.options)!=null&&i.onApply))return;let t=this.generatedImages[this.selectedImageIndex];this.savedLibraryPaths.has(this.selectedImageIndex)?(t=this.savedLibraryPaths.get(this.selectedImageIndex),this.setStatus("Applying saved image...")):(this.setStatus("Saving to library before applying..."),await this.saveSelectedImageToLibrary(),this.savedLibraryPaths.has(this.selectedImageIndex)?(t=this.savedLibraryPaths.get(this.selectedImageIndex),this.setStatus("\u2705 Saved and applying...")):this.setStatus("Failed to save. Applying data URL instead.",!0)),this.options.onApply(t),setTimeout(()=>{this.close()},500)}getApiKey(){let e=ja();if(e)return e;try{let t=this.analyzer.getResult();if(t&&t.apiKey)return _a(t.apiKey,"From Brand DNA"),t.apiKey}catch(t){console.warn("[AiEditorModal] Failed to get API key from brand DNA:",t)}return null}close(){this.modal&&this.modal.parentNode&&this.modal.parentNode.removeChild(this.modal),this.modal=null,this.options=null}},Oa=null;window.__openAiEditor=function(r,e,t,i){Oa||(Oa=new Ra),Oa.open({objectId:r,initialPrompt:e,currentValue:t,path:i==null?void 0:i.path,onApply:n=>{if(i!=null&&i.path){let a=window.updateManager;if(a)a.updateProperty(r,i.path,n);else{let s=window.getEditableObjectConfig,o=s==null?void 0:s(r);if(o){let l=i.path.split("."),c=o;for(let d=0;d<l.length-1;d++)c[l[d]]||(c[l[d]]={}),c=c[l[d]];c[l[l.length-1]]=n}}}window.dispatchEvent(new CustomEvent("inspector:refresh"))}})};ut();var za=class{constructor(){this.modal=null;this.options=null}open(e){this.options=e,this.createModal(),document.body.appendChild(this.modal)}createModal(){if(!this.options)return;let{assetPath:e,assetType:t,objectId:i}=this.options,n=i||"Asset Preview",a=document.createElement("div");a.className="asset-preview-modal",a.innerHTML=`
|
|
2310
2332
|
<div class="asset-preview-card">
|
|
2311
2333
|
<div class="asset-preview-header">
|
|
2312
2334
|
<div class="asset-preview-title">${n}</div>
|
|
@@ -2333,7 +2355,7 @@ Style guidelines: ${i.summary}`;this.promptInput.value=n,this.currentPrompt=n}}c
|
|
|
2333
2355
|
<source src="${n}" type="audio/wav">
|
|
2334
2356
|
Your browser does not support the audio element.
|
|
2335
2357
|
</audio>
|
|
2336
|
-
`;case"text":return`<pre style="background: rgba(0,0,0,0.2); padding: 16px; border-radius: 8px; max-height: 300px; overflow-y: auto; white-space: pre-wrap;">${e}</pre>`;default:return`<div class="asset-preview-placeholder">Cannot preview ${t} assets</div>`}}resolveAssetUrl(e){return e.startsWith("data:")||e.startsWith("blob:")||e.startsWith("/")?e:`/raw/${e}`}attachEventListeners(){if(!this.modal)return;this.modal.addEventListener("click",i=>{let n=i.target;(n.dataset.action==="close"||n===this.modal)&&this.close()});let e=this.modal.querySelector('[data-action="change"]');e&&e.addEventListener("click",()=>{this.openAssetEditor()});let t=this.modal.querySelector('[data-action="edit"]');t&&t.addEventListener("click",()=>{this.openAiEditor(),this.close()})}openAssetEditor(){this.options&&Promise.resolve().then(()=>(ut(),Ht)).then(({AssetEditorModal:e})=>{new e().show(this.options.objectId||"unknown",this.options.propertyPath||"",this.options.assetPath,i=>{var n;(n=this.options)!=null&&n.onChange&&this.options.onChange(i),this.close()})})}openAiEditor(){if(!this.options||this.options.assetType!=="image")return;let e=window.__openAiEditor;typeof e=="function"&&e(this.options.objectId||"asset","Edit this image asset",this.options.assetPath,{path:this.options.propertyPath,onApply:t=>{var i;(i=this.options)!=null&&i.onChange&&this.options.onChange(t)}})}close(){this.modal&&this.modal.parentNode&&this.modal.parentNode.removeChild(this.modal),this.modal=null,this.options=null}};window.openAssetPreview=function(s){new za().open(s)};oa();ee();var $=require("pixi.js");ee();var un=class{constructor(e){this.app=null;this.camera=new $.Container;this.bgContainer=new $.Container;this.mainContainer=new $.Container;this.uiContainer=new $.Container;this.gizmoLayer=new $.Container;this.screenFrame=new $.Graphics;this.gameFrame=new $.Graphics;this.gridLayer=new $.Graphics;this.spawnPointLayer=new $.Container;this.objectMap=new Map;this.selectedId=null;this.selectedIds=new Set;this.dragMode=null;this.selectionBox=null;this.selectionBoxStart=null;this.isSelectionBoxActive=!1;this.dragStartPointer=null;this.dragStartPos=null;this.dragStartScale=1;this.dragStartRotation=0;this.dragStartAngle=0;this.dragStartDistance=1;this.dragAnchorLocal=null;this.dragStartValue=null;this.dragContainer=null;this.dragLastPointer=null;this.dragPointerOffset=null;this.dragSyncHoldUntil=0;this.dragLogged=!1;this.spawnPointDrag=null;this.lastGameFrameSize=null;this.cameraScale=1;this.isPanning=!1;this.panStart=null;this.panStartCamera=null;this.hasUserCamera=!1;this.resizeObserver=null;this.screenSyncRaf=null;this.gizmoOutline=new $.Graphics;this.anchorVisualizationLayer=new $.Graphics;this.moveHandle=new $.Graphics;this.scaleHandle=new $.Graphics;this.rotateHandle=new $.Graphics;this.isVisible=!0;this.applyQueued=!1;this.applyQueuedId=null;this.gridEnabled=!1;this.gridGap=50;this.gridAlpha=.25;this.snapToGrid=!1;this.alignmentGuidesEnabled=!0;this.alignmentGuideLayer=new $.Graphics;this.lastPickPoint=null;this.lastPickIds=[];this.lastPickIndex=0;this.lastPickTime=0;this.playModeEnabled=!0;this.playModeInitialized=!1;this.layoutScale=1;this.updateManager=new xe;this.backgroundCoverEnabled=!0;this.backgroundLocked=!0;this.dropZoneActive=!1;this.dropZoneOverlay=null;this.handleScreenChange=e=>{if(!(e!=null&&e.detail))return;let{width:t,height:i}=e.detail;!t||!i||(this.hasUserCamera=!1,this.updateLayout({width:t,height:i}),this.hasUserCamera||this.centerCamera(),this.updateGizmos(),this.updateGrid(),this.playModeEnabled?this.schedulePostScreenSync({width:t,height:i}):this.syncFromConfig())};this.handleAnchorChanged=e=>{let t=e==null?void 0:e.detail,i=t==null?void 0:t.objectId;if(!i)return;let n=t==null?void 0:t.previousAnchor,a=t==null?void 0:t.nextAnchor;this.adjustPositionForAnchorChange(i,n,a)};this.handleActiveScreenChanged=()=>{this.isVisible&&this.syncFromConfig()};this.handleConfigChanged=e=>{if(!this.isVisible)return;this.updateLayout(),this.updateGrid();let t=e==null?void 0:e.detail;if(!t){this.syncFromConfig();return}let i=t.path,n=t.objectId;if(i==="transform.anchor"&&n){let r=t.value,o=t.oldValue;o!=null&&this.adjustPositionForAnchorChange(n,o,r)}let a=t.objectIds;if(n){this.syncFromConfig([n]);return}if(Array.isArray(a)&&a.length>0){this.syncFromConfig(a);return}this.syncFromConfig()};this.handleSceneRefresh=()=>{this.isVisible&&this.syncFromConfig()};this.handleAssetUpdated=e=>{var l;let t=(l=e==null?void 0:e.detail)!=null?l:{},i=t.objectId,n=t.texture;if(!i||!n)return;let a=this.objectMap.get(i);if(!a)return;let r=a.displayObject;if(r!=null&&r.texture)r.texture=n;else if(r!=null&&r.children){let c=r.children.find(d=>d==null?void 0:d.texture);c&&(c.texture=n)}let o=this.getEditableObjectConfig(i);o&&(a.assetKey=this.getAssetKey(o))};this.handleLayoutApplied=e=>{var r;if(!this.isVisible)return;let t=(r=e==null?void 0:e.detail)!=null?r:{},i=Number(t.width),n=Number(t.height),a=Number.isFinite(i)&&i>0&&Number.isFinite(n)&&n>0?{width:i,height:n}:this.getScreen();this.updateLayout(a),this.hasUserCamera||this.centerCamera(),this.syncFromConfig().then(()=>{this.playModeEnabled&&this.syncFromGameObjectsInternal(),this.updateGizmos(),this.updateGrid()})};this.handlePreviewSelect=e=>{var i,n;let t=(n=(i=e==null?void 0:e.detail)==null?void 0:i.objectId)!=null?n:null;this.setSelected(t,{silent:!0})};this.onStagePointerDown=e=>{if(!this.app||!this.isVisible)return;let t=this.getPointerButton(e);if(t===2){if(this.isGizmoTarget(e==null?void 0:e.target))return;let h=this.getEventGlobalPoint(e);if(!h)return;let f=new $.Point(h.x,h.y),m=this.getPickCandidates(f);if(m.length>0){let b=m[0];this.selectedIds.has(b)||(this.selectedIds.clear(),this.selectedIds.add(b),this.setSelected(b),this.updateGizmos()),this.showContextMenu(b,h.x,h.y)}return}if(t!==0||this.isGizmoTarget(e==null?void 0:e.target))return;let i=this.getEventGlobalPoint(e);if(!i)return;let n=new $.Point(i.x,i.y),a=this.getPickCandidates(n),o=navigator.platform.toUpperCase().indexOf("MAC")>=0?e.metaKey:e.ctrlKey;if(a.length===0){o||(this.setSelected(null),this.selectedIds.clear()),this.selectionBoxStart=n,this.isSelectionBoxActive=!0,this.lastPickIds=[],this.lastPickIndex=0,this.lastPickPoint=n,this.lastPickTime=performance.now();return}let l=performance.now(),c=this.areSameIds(a,this.lastPickIds),d=this.lastPickPoint&&this.distance(n,this.lastPickPoint)<=6,p=l-this.lastPickTime<1200,u=c&&d&&p?(this.lastPickIndex+1)%a.length:0,g=a[u];this.lastPickIds=a,this.lastPickIndex=u,this.lastPickPoint=n,this.lastPickTime=l,o?this.selectedIds.has(g)?(this.selectedIds.delete(g),this.selectedId===g&&(this.selectedId=this.selectedIds.size>0?Array.from(this.selectedIds)[0]:null)):(this.selectedIds.add(g),this.selectedId=g):(this.selectedIds.clear(),this.selectedIds.add(g),this.setSelected(g)),this.updateGizmos()};this.handleGridSettings=e=>{var a,r,o;let t=(a=e==null?void 0:e.detail)==null?void 0:a.enabled,i=(r=e==null?void 0:e.detail)==null?void 0:r.gap,n=(o=e==null?void 0:e.detail)==null?void 0:o.alpha;typeof t=="boolean"&&(this.gridEnabled=t),typeof i=="number"&&Number.isFinite(i)&&i>2&&(this.gridGap=i),typeof n=="number"&&Number.isFinite(n)&&n>=0&&n<=1&&(this.gridAlpha=n),this.updateGrid()};this.handleBackgroundCover=e=>{var i;let t=(i=e==null?void 0:e.detail)==null?void 0:i.enabled;typeof t=="boolean"&&(this.backgroundCoverEnabled=t,this.syncFromConfig(),this.updateGizmos())};this.handleBackgroundLock=e=>{var i;let t=(i=e==null?void 0:e.detail)==null?void 0:i.enabled;if(typeof t=="boolean"&&(this.backgroundLocked=t,t&&this.selectedId)){let n=this.getEditableObjectConfig(this.selectedId),a=this.objectMap.get(this.selectedId);this.isBackgroundObject(this.selectedId,n,a==null?void 0:a.displayObject)&&this.setSelected(null)}};this.handlePlayModeChange=e=>{var i;let t=(i=e==null?void 0:e.detail)==null?void 0:i.enabled;typeof t=="boolean"&&(!this.playModeInitialized&&(this.playModeInitialized=!0,!t)||t&&this.applyPlayModeState(!0))};this.syncFromGameObjects=()=>{this.syncFromGameObjectsInternal()};this.onSpawnPointDragMove=e=>{if(!this.spawnPointDrag)return;let t=this.getPointerInContainer(e.clientX,e.clientY,this.mainContainer);if(!t)return;let i=t.x+this.spawnPointDrag.offset.x,n=t.y+this.spawnPointDrag.offset.y;this.updateLiveSpawnPoint(this.spawnPointDrag.objectId,this.spawnPointDrag.index,i,n)};this.onSpawnPointDragEnd=()=>{if(!this.spawnPointDrag)return;let{objectId:e,startPoints:t}=this.spawnPointDrag,i=this.getEditableObjectConfig(e),n=i?this.getSpawnPoints(i):null;i&&n&&(this.setNestedValue(i,"logic.props.spawnPoints",t),re({objectId:e,path:"logic.props.spawnPoints",value:n},{persist:!0,emitEvent:!0,trackHistory:!0}),this.queueLiveApply(e)),this.spawnPointDrag=null,window.dispatchEvent(new CustomEvent("inspector:refresh")),window.removeEventListener("pointermove",this.onSpawnPointDragMove),window.removeEventListener("pointerup",this.onSpawnPointDragEnd)};this.onDragMove=e=>{var n;if(!this.dragMode||!this.selectedId||!this.dragContainer||!this.dragStartPointer||!this.dragStartPos)return;let t=this.objectMap.get(this.selectedId);if(!(t!=null&&t.displayObject))return;let i=this.getPointerInContainer(e.clientX,e.clientY,this.dragContainer);if(i){if(this.dragMode==="move"){let a=this.dragPointerOffset;if(!a)return;let r=i.x+a.x,o=i.y+a.y;if(this.snapToGrid){let d=this.snapToGridPosition(r,o);r=d.x,o=d.y}let l=r-this.dragStartPos.x,c=o-this.dragStartPos.y;if(t.displayObject.position.set(r,o),this.updateAlignmentGuides(this.selectedId,new $.Point(r,o)),this.updateLiveConfigPosition(r,o),this.selectedIds.size>1){let d=new Map;if(!this.multiDragStartPositions){this.multiDragStartPositions=new Map;for(let p of this.selectedIds){if(p===this.selectedId)continue;let u=this.objectMap.get(p);u!=null&&u.displayObject&&this.multiDragStartPositions.set(p,new $.Point(u.displayObject.position.x,u.displayObject.position.y))}}for(let p of this.selectedIds){if(p===this.selectedId)continue;let u=this.objectMap.get(p);if(!(u!=null&&u.displayObject))continue;let g=this.multiDragStartPositions.get(p);if(g){let h=g.x+l,f=g.y+c;if(this.snapToGrid){let m=this.snapToGridPosition(h,f);h=m.x,f=m.y}u.displayObject.position.set(h,f),this.updateLiveConfigPositionForObject(p,h,f)}}}this.dragLastPointer=new $.Point(i.x,i.y),this.dragLogged||(this.dragLogged=!0,console.log("[SceneEditor][DragMove]",{objectId:this.selectedId,selectedCount:this.selectedIds.size,pointer:{x:i.x,y:i.y},nextPos:{x:r,y:o}}))}if(this.dragMode==="scale"&&this.dragAnchorLocal){let r=Math.max(1,this.distance(i,this.dragAnchorLocal))/Math.max(1,this.dragStartDistance),o=Math.max(.01,this.dragStartScale*r);(n=t.displayObject.scale)!=null&&n.set?t.displayObject.scale.set(o,o):t.displayObject.scale&&(t.displayObject.scale.x=o,t.displayObject.scale.y=o),this.updateLiveConfigScale(o)}if(this.dragMode==="rotate"&&this.dragAnchorLocal){let a=Math.atan2(i.y-this.dragAnchorLocal.y,i.x-this.dragAnchorLocal.x),r=this.dragStartRotation+(a-this.dragStartAngle);t.displayObject.rotation=r,this.updateLiveConfigRotation(r)}this.updateGizmos()}};this.onDragEnd=()=>{if(this.dragMode){if(this.alignmentGuideLayer&&this.alignmentGuideLayer.clear(),this.selectedIds.size>0){let e=Array.from(this.selectedIds);window.dispatchEvent(new CustomEvent("config:changed",{detail:{objectIds:e}})),this.dragSyncHoldUntil=performance.now()+200}this.dragMode=null,this.dragStartPointer=null,this.dragStartPos=null,this.dragAnchorLocal=null,this.dragStartValue=null,this.dragContainer=null,this.dragLastPointer=null,this.dragPointerOffset=null,this.multiDragStartPositions=null,window.removeEventListener("pointermove",this.onDragMove),window.removeEventListener("pointerup",this.onDragEnd)}};this.onWheel=e=>{if(!this.app||!this.isVisible)return;e.preventDefault();let i=Math.sign(e.deltaY)<0?1.1:.9,n=Math.min(6,Math.max(.1,this.cameraScale*i)),a=new $.Point(this.app.renderer.width/2,this.app.renderer.height/2),r=this.camera.toLocal(a);this.cameraScale=n,this.camera.scale.set(n);let o=this.camera.toGlobal(r);this.camera.position.set(this.camera.position.x+(a.x-o.x),this.camera.position.y+(a.y-o.y)),this.hasUserCamera=!0,this.updateGizmos(),this.updateGrid()};this.onPanStart=e=>{e.button===2&&(this.isPanning=!0,this.panStart={x:e.clientX,y:e.clientY},this.panStartCamera={x:this.camera.position.x,y:this.camera.position.y},this.hasUserCamera=!0)};this.onPanMove=e=>{if(this.isPanning&&this.panStart&&this.panStartCamera){let t=e.clientX-this.panStart.x,i=e.clientY-this.panStart.y;this.camera.position.set(this.panStartCamera.x+t,this.panStartCamera.y+i),this.updateGrid()}if(this.isSelectionBoxActive&&this.selectionBoxStart&&this.app){let t=this.getEventGlobalPoint(e);if(!t)return;let i=new $.Point(t.x,t.y);this.drawSelectionBox(this.selectionBoxStart,i)}};this.onPanEnd=e=>{if(this.isPanning&&(this.isPanning=!1,this.panStart=null,this.panStartCamera=null),this.isSelectionBoxActive&&this.selectionBoxStart&&this.app){let t=this.getEventGlobalPoint(e);if(t){let i=new $.Point(t.x,t.y);this.finalizeSelectionBox(this.selectionBoxStart,i)}this.isSelectionBoxActive=!1,this.selectionBoxStart=null,this.selectionBox&&this.selectionBox.clear()}this.multiDragStartPositions=null};this.root=e.root,this.getScreen=e.getScreen}async mount(){this.app||(this.app=new $.Application,await this.app.init({resizeTo:this.root,autoDensity:!0,resolution:window.devicePixelRatio||1,antialias:!0,backgroundAlpha:0}),this.root.innerHTML="",this.root.appendChild(this.app.canvas),this.root.style.position="relative",this.root.style.overflow="hidden",this.app.stage.sortableChildren=!0,this.app.stage.eventMode="static",this.camera.sortableChildren=!0,this.bgContainer.sortableChildren=!0,this.mainContainer.sortableChildren=!0,this.uiContainer.sortableChildren=!0,this.spawnPointLayer.sortableChildren=!0,this.gizmoLayer.sortableChildren=!0,this.app.stage.addChild(this.camera),this.camera.addChild(this.screenFrame),this.camera.addChild(this.bgContainer),this.camera.addChild(this.mainContainer),this.camera.addChild(this.gridLayer),this.camera.addChild(this.uiContainer),this.camera.addChild(this.spawnPointLayer),this.camera.addChild(this.gameFrame),this.camera.addChild(this.gizmoLayer),this.screenFrame.zIndex=-1,this.screenFrame.eventMode="none",this.bgContainer.zIndex=-5e3,this.bgContainer.eventMode="none",this.mainContainer.zIndex=0,this.gridLayer.zIndex=2e4,this.gridLayer.eventMode="none",this.gridLayer.visible=!0,this.uiContainer.zIndex=5e4,this.spawnPointLayer.zIndex=8e4,this.spawnPointLayer.eventMode="passive",this.gameFrame.zIndex=85e3,this.gameFrame.eventMode="none",this.gizmoLayer.zIndex=1e5,this.gizmoLayer.addChild(this.gizmoOutline),this.gizmoLayer.addChild(this.anchorVisualizationLayer),this.gizmoLayer.addChild(this.moveHandle),this.gizmoLayer.addChild(this.scaleHandle),this.gizmoLayer.addChild(this.rotateHandle),this.selectionBox=new $.Graphics,this.selectionBox.zIndex=99999,this.selectionBox.eventMode="none",this.gizmoLayer.addChild(this.selectionBox),this.dropZoneOverlay=new $.Graphics,this.dropZoneOverlay.zIndex=99998,this.dropZoneOverlay.eventMode="none",this.gizmoLayer.addChild(this.dropZoneOverlay),this.alignmentGuideLayer=new $.Graphics,this.alignmentGuideLayer.zIndex=99997,this.alignmentGuideLayer.eventMode="none",this.gizmoLayer.addChild(this.alignmentGuideLayer),this.gizmoOutline.eventMode="none",this.anchorVisualizationLayer.eventMode="none",this.setupInteractions(),this.setupObservers(),this.updateLayout(),this.hasUserCamera||this.centerCamera(),this.restoreScenePreferences(),this.refresh(),this.applyPlayModeState(!0),!this.isVisible&&this.app.ticker&&this.app.ticker.stop())}destroy(){var e;this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null),this.screenSyncRaf&&(cancelAnimationFrame(this.screenSyncRaf),this.screenSyncRaf=null),window.removeEventListener("handler-preview:screen",this.handleScreenChange),window.removeEventListener("handler:active-screen-changed",this.handleActiveScreenChanged),window.removeEventListener("config:changed",this.handleConfigChanged),window.removeEventListener("handler:scene-objects-refresh",this.handleSceneRefresh),window.removeEventListener("handler:layout-applied",this.handleLayoutApplied),window.removeEventListener("preview:select",this.handlePreviewSelect),window.removeEventListener("scene-editor:grid",this.handleGridSettings),window.removeEventListener("scene-editor:background-cover",this.handleBackgroundCover),window.removeEventListener("scene-editor:background-lock",this.handleBackgroundLock),window.removeEventListener("scene-editor:asset-updated",this.handleAssetUpdated),window.removeEventListener("scene-editor:play-mode",this.handlePlayModeChange),window.removeEventListener("scene-editor:anchor-changed",this.handleAnchorChanged),window.removeEventListener("pointermove",this.onSpawnPointDragMove),window.removeEventListener("pointerup",this.onSpawnPointDragEnd),this.app&&((e=this.app.ticker)==null||e.remove(this.syncFromGameObjects),this.app.stage.off("pointerdown",this.onStagePointerDown),this.app.destroy(!0),this.app=null)}setVisible(e){this.isVisible=e,!(!this.app||!this.app.ticker)&&(e?(this.app.ticker.start(),this.refresh(),this.updateGrid()):this.app.ticker.stop())}refresh(){this.syncFromConfig()}setupObservers(){window.addEventListener("handler-preview:screen",this.handleScreenChange),window.addEventListener("handler:active-screen-changed",this.handleActiveScreenChanged),window.addEventListener("config:changed",this.handleConfigChanged),window.addEventListener("handler:scene-objects-refresh",this.handleSceneRefresh),window.addEventListener("handler:layout-applied",this.handleLayoutApplied),window.addEventListener("preview:select",this.handlePreviewSelect),window.addEventListener("scene-editor:grid",this.handleGridSettings),window.addEventListener("scene-editor:background-cover",this.handleBackgroundCover),window.addEventListener("scene-editor:background-lock",this.handleBackgroundLock),window.addEventListener("scene-editor:asset-updated",this.handleAssetUpdated),window.addEventListener("scene-editor:play-mode",this.handlePlayModeChange),window.addEventListener("scene-editor:anchor-changed",this.handleAnchorChanged),this.resizeObserver=new ResizeObserver(()=>{this.handleResize()}),this.resizeObserver.observe(this.root)}setupInteractions(){if(!this.app)return;let e=this.app.canvas;e.addEventListener("contextmenu",t=>t.preventDefault()),e.addEventListener("wheel",this.onWheel,{passive:!1}),e.addEventListener("pointerdown",this.onPanStart),window.addEventListener("pointermove",this.onPanMove),window.addEventListener("pointerup",this.onPanEnd),this.app.stage.on("pointerdown",this.onStagePointerDown),this.moveHandle.on("pointerdown",t=>this.startDrag("move",t)),this.scaleHandle.on("pointerdown",t=>this.startDrag("scale",t)),this.rotateHandle.on("pointerdown",t=>this.startDrag("rotate",t)),this.applyEditControls(),this.setupKeyboardShortcuts(),this.setupDragAndDrop()}setupKeyboardShortcuts(){window.addEventListener("keydown",e=>{if(!this.isVisible)return;let i=navigator.platform.toUpperCase().indexOf("MAC")>=0?e.metaKey:e.ctrlKey,n=e.target;n.tagName==="INPUT"||n.tagName==="TEXTAREA"||n.isContentEditable||(i&&e.key==="a"?(e.preventDefault(),this.selectAll()):i&&e.key==="d"?(e.preventDefault(),this.duplicateSelected()):i&&e.key==="c"?(e.preventDefault(),this.copySelected()):i&&e.key==="v"?(e.preventDefault(),this.pasteObjects()):e.key==="Escape"?(this.setSelected(null),this.selectedIds.clear(),this.updateGizmos()):(e.key==="Delete"||e.key==="Backspace")&&this.selectedIds.size>0?(e.preventDefault(),this.deleteSelectedObjects()):e.key==="g"||e.key==="G"?(e.preventDefault(),this.toggleGrid()):e.shiftKey&&(e.key==="g"||e.key==="G")&&(e.preventDefault(),this.toggleSnapToGrid()))})}async duplicateSelected(){if(this.selectedIds.size===0)return;let e=window.__HANDLER_ACTIVE_SCREEN,t=e==="loading"||e==="start"||e==="gameplay"||e==="tutorial"||e==="endgame"?e:"gameplay",i=Array.from(this.selectedIds),n=[];for(let a of i)try{let r=`${a}_copy_${Date.now()}`,o=await fetch("/api/objects/duplicate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sourceId:a,newInstanceId:r,shareConfig:!1,screenId:t})}),l=await o.json();o.ok&&l.success&&n.push(l.newObjectId)}catch(r){console.error(`[SceneEditor] Failed to duplicate ${a}:`,r)}n.length>0&&(this.selectedIds=new Set(n),this.selectedId=n[0],this.updateGizmos(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")))}copySelected(){if(this.selectedIds.size===0)return;let e=[];for(let t of this.selectedIds){let i=this.getEditableObjectConfig(t);i&&e.push({id:t,config:i})}window.__sceneEditorClipboard={configs:e,timestamp:Date.now()},this.showToast(`\u{1F4CB} Copied ${e.length} object${e.length>1?"s":""}`,1500)}async pasteObjects(){var a,r;let e=window.__sceneEditorClipboard;if(!e||!e.configs||e.configs.length===0)return;let t=window.__HANDLER_ACTIVE_SCREEN,i=t==="loading"||t==="start"||t==="gameplay"||t==="tutorial"||t==="endgame"?t:"gameplay",n=[];for(let{id:o,config:l}of e.configs)try{let c=`${o}_paste_${Date.now()}_${Math.random().toString(36).substr(2,5)}`,d=`json.${c}`,p=JSON.parse(JSON.stringify(l));if(p.identity.id=d,p.instance_id=c,p.object_config=d,(a=p.transform)!=null&&a.position){let h=p.transform.position,f=Array.isArray(h)?h[0]:h.x||0,m=Array.isArray(h)?h[1]:h.y||0;Array.isArray(h)?p.transform.position=[f+20,m+20]:p.transform.position={x:f+20,y:m+20}}let u=await fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i,instanceId:c,objectConfigId:d,config:p,layer:((r=p.identity)==null?void 0:r.category)==="ui"?"ui":"world"})}),g=await u.json();u.ok&&g.success&&n.push(c)}catch(c){console.error(`[SceneEditor] Failed to paste ${o}:`,c)}n.length>0&&(this.selectedIds=new Set(n),this.selectedId=n[0],this.updateGizmos(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),this.showToast(`\u{1F4CB} Pasted ${n.length} object${n.length>1?"s":""}`,1500))}toggleGrid(){this.gridEnabled=!this.gridEnabled,this.updateGrid();try{window.localStorage.setItem(this.getSceneStorageKey("grid_enabled"),String(this.gridEnabled))}catch{}this.showToast(this.gridEnabled?"\u{1F4D0} Grid enabled":"\u{1F4D0} Grid disabled",1e3)}toggleSnapToGrid(){this.snapToGrid=!this.snapToGrid;try{window.localStorage.setItem(this.getSceneStorageKey("snap_to_grid"),String(this.snapToGrid))}catch{}this.showToast(this.snapToGrid?"\u{1F532} Snap to grid enabled":"\u{1F532} Snap to grid disabled",1e3)}snapToGridPosition(e,t){if(!this.snapToGrid)return{x:e,y:t};let i=this.gridGap;return{x:Math.round(e/i)*i,y:Math.round(t/i)*i}}updateAlignmentGuides(e,t){var d,p,u,g;if(!this.alignmentGuidesEnabled||!e||!this.alignmentGuideLayer){this.alignmentGuideLayer&&this.alignmentGuideLayer.clear();return}let i=this.objectMap.get(e);if(!(i!=null&&i.displayObject)){this.alignmentGuideLayer.clear();return}let n=(p=(d=i.displayObject).getBounds)==null?void 0:p.call(d);if(!n){this.alignmentGuideLayer.clear();return}this.alignmentGuideLayer.clear();let a=this.camera.toLocal(new $.Point(n.x,n.y)),r=this.camera.toLocal(new $.Point(n.x+n.width,n.y+n.height)),o=(a.x+r.x)/2,l=(a.y+r.y)/2,c=5;for(let[h,f]of this.objectMap.entries()){if(h===e||!(f!=null&&f.displayObject)||f.displayObject.visible===!1)continue;let m=(g=(u=f.displayObject).getBounds)==null?void 0:g.call(u);if(!m)continue;let b=this.camera.toLocal(new $.Point(m.x,m.y)),y=this.camera.toLocal(new $.Point(m.x+m.width,m.y+m.height)),v=(b.x+y.x)/2,w=(b.y+y.y)/2;if(Math.abs(o-v)<c){let S=Math.min(a.y,b.y),A=Math.max(r.y,y.y);this.alignmentGuideLayer.moveTo(v,S),this.alignmentGuideLayer.lineTo(v,A),this.alignmentGuideLayer.stroke({width:1,color:3900150,alpha:.6})}if(Math.abs(l-w)<c){let S=Math.min(a.x,b.x),A=Math.max(r.x,y.x);this.alignmentGuideLayer.moveTo(S,w),this.alignmentGuideLayer.lineTo(A,w),this.alignmentGuideLayer.stroke({width:1,color:3900150,alpha:.6})}let T=a.x,I=r.x,M=a.y,L=r.y,j=b.x,_=y.x,P=b.y,x=y.y;if(Math.abs(T-j)<c||Math.abs(T-_)<c||Math.abs(I-j)<c||Math.abs(I-_)<c){let S=Math.abs(T-j)<c?j:Math.abs(T-_)<c?_:Math.abs(I-j)<c?j:_,A=Math.min(M,P),E=Math.max(L,x);this.alignmentGuideLayer.moveTo(S,A),this.alignmentGuideLayer.lineTo(S,E),this.alignmentGuideLayer.stroke({width:1,color:1096065,alpha:.5})}if(Math.abs(M-P)<c||Math.abs(M-x)<c||Math.abs(L-P)<c||Math.abs(L-x)<c){let S=Math.abs(M-P)<c?P:Math.abs(M-x)<c?x:Math.abs(L-P)<c?P:x,A=Math.min(T,j),E=Math.max(I,_);this.alignmentGuideLayer.moveTo(A,S),this.alignmentGuideLayer.lineTo(E,S),this.alignmentGuideLayer.stroke({width:1,color:1096065,alpha:.5})}}}selectAll(){let e=Array.from(this.objectMap.keys()).filter(t=>{let i=this.getEditableObjectConfig(t),n=this.objectMap.get(t);return!(!(n!=null&&n.displayObject)||n.displayObject.visible===!1||this.backgroundLocked&&this.isBackgroundObject(t,i,n.displayObject))});this.selectedIds=new Set(e),e.length>0&&(this.selectedId=e[0],this.updateGizmos())}deleteSelectedObjects(){let e=Array.from(this.selectedIds);for(let t of e){let i=window.__deleteObjectRequest;typeof i=="function"&&i(t)}this.selectedIds.clear(),this.selectedId=null,this.updateGizmos()}handleResize(){this.app&&(this.updateLayout(),this.hasUserCamera||this.centerCamera(),this.updateGizmos(),this.updateGrid())}adjustPositionForAnchorChange(e,t,i){var _,P,x,S,A,E;if(t==null||i==null||t===i)return;let n=this.getEditableObjectConfig(e);if(!n)return;let a=(_=n.transform)!=null?_:{};if(a.position_ratio!=null)return;let r=(P=this.getRuntimeScreenSize())!=null?P:this.getScreen();if(!(r!=null&&r.width)||!(r!=null&&r.height))return;let o=this.objectMap.get(e);if(!(o!=null&&o.displayObject))return;let l=this.isBackgroundObject(e,n,o.displayObject),c=this.getRuntimeScale(),d=o.displayObject.position.x,p=o.displayObject.position.y,u=ze(r.width,r.height,t),g=ze(r.width,r.height,i),h=u.x,f=u.y,m=g.x,b=g.y;l||(h=(u.x-r.width/2)/c,f=(u.y-r.height/2)/c,m=(g.x-r.width/2)/c,b=(g.y-r.height/2)/c);let y={x:d-h,y:p-f},v={x:d-m,y:p-b},w=a.offset,T=Array.isArray(w)?Number((x=w[0])!=null?x:0):Number((S=w==null?void 0:w.x)!=null?S:0),I=Array.isArray(w)?Number((A=w[1])!=null?A:0):Number((E=w==null?void 0:w.y)!=null?E:0),M=v.x-T,L=v.y-I,j=this.buildPositionValue(a,{x:M,y:L});this.updateManager.updateProperty(e,"transform.position",j,{refreshInspector:!0})}getPickCandidates(e){var i;let t=[];for(let[n,a]of this.objectMap.entries()){let r=a.displayObject;if(!r||r.visible===!1||this.backgroundLocked&&this.isBackgroundObject(n,this.getEditableObjectConfig(n),r))continue;let o=(i=r.getBounds)==null?void 0:i.call(r);if(!o||o.width<=0||o.height<=0||e.x<o.x||e.x>o.x+o.width||e.y<o.y||e.y>o.y+o.height)continue;let l=r.parent,c=typeof(l==null?void 0:l.zIndex)=="number"?l.zIndex:0,d=typeof r.zIndex=="number"?r.zIndex:0,p=typeof(l==null?void 0:l.getChildIndex)=="function"?l.getChildIndex(r):0,u=c*1e6+d*1e3+p;t.push({id:n,order:u})}return t.sort((n,a)=>a.order-n.order),t.map(n=>n.id)}areSameIds(e,t){if(e.length!==t.length)return!1;for(let i=0;i<e.length;i+=1)if(e[i]!==t[i])return!1;return!0}isGizmoTarget(e){return e&&this.spawnPointLayer.children.indexOf(e)!==-1?!0:e===this.moveHandle||e===this.scaleHandle||e===this.rotateHandle||e===this.gizmoOutline}restoreScenePreferences(){if(typeof window!="undefined"){try{let e=window.localStorage.getItem(this.getSceneStorageKey("grid_enabled")),t=window.localStorage.getItem(this.getSceneStorageKey("grid_gap")),i=window.localStorage.getItem(this.getSceneStorageKey("grid_alpha")),n=window.localStorage.getItem(this.getSceneStorageKey("snap_to_grid")),a=window.localStorage.getItem(this.getSceneStorageKey("background_cover")),r=window.localStorage.getItem(this.getSceneStorageKey("background_lock"));if(e!==null&&(this.gridEnabled=e==="true"),t!==null){let o=Number(t);Number.isFinite(o)&&o>2&&(this.gridGap=o)}if(i!==null){let o=Number(i);Number.isFinite(o)&&o>=0&&o<=1&&(this.gridAlpha=o)}n!==null&&(this.snapToGrid=n==="true"),a!==null&&(this.backgroundCoverEnabled=a==="true"),r!==null&&(this.backgroundLocked=r==="true")}catch{}this.updateGrid()}}getSceneStorageKey(e){let t=typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default";return`handler_preview_scene_${e}::${t}`}applyPlayModeState(e){var t;this.playModeEnabled=e,(t=this.app)!=null&&t.ticker&&(this.app.ticker.remove(this.syncFromGameObjects),e&&this.app.ticker.add(this.syncFromGameObjects)),this.applyEditControls(),this.updateLayout(),this.hasUserCamera||this.centerCamera(),this.syncFromConfig().then(()=>{this.playModeEnabled&&this.syncFromGameObjectsInternal(),this.updateGizmos(),this.updateGrid()})}applyEditControls(){this.moveHandle.eventMode="static",this.scaleHandle.eventMode="static",this.rotateHandle.eventMode="static"}schedulePostScreenSync(e){this.screenSyncRaf&&cancelAnimationFrame(this.screenSyncRaf),this.screenSyncRaf=requestAnimationFrame(()=>{this.runPostScreenSync(e)})}async runPostScreenSync(e){this.screenSyncRaf=null,this.isVisible&&this.playModeEnabled&&(this.updateLayout(e),this.hasUserCamera||this.centerCamera(),await this.syncFromConfig(),this.syncFromGameObjectsInternal(),this.updateGizmos(),this.updateGrid())}getRuntimeScreenSize(){var a,r,o,l,c,d,p;let e=window.gameApp;if(e!=null&&e.renderer){let u=e.renderer.screen,g=Number((a=u==null?void 0:u.width)!=null?a:0),h=Number((r=u==null?void 0:u.height)!=null?r:0);if(Number.isFinite(g)&&g>0&&Number.isFinite(h)&&h>0)return{width:g,height:h};let f=Number((o=e.renderer.resolution)!=null?o:1)||1,m=Number((l=e.renderer.width)!=null?l:0)/f,b=Number((c=e.renderer.height)!=null?c:0)/f;if(Number.isFinite(m)&&m>0&&Number.isFinite(b)&&b>0)return{width:m,height:b}}let t=document.querySelector(".game-container"),i=Number((d=t==null?void 0:t.dataset)==null?void 0:d.screenWidth),n=Number((p=t==null?void 0:t.dataset)==null?void 0:p.screenHeight);return Number.isFinite(i)&&i>0&&Number.isFinite(n)&&n>0?{width:i,height:n}:null}getRuntimeLayoutReference(){var a,r,o,l,c,d,p,u,g,h,f,m,b,y,v,w,T,I,M,L,j,_,P,x,S,A,E,C,O,k,R,z,D,U;let e=window.__screenManager;if(e){let F=["gameplay","start","tutorial","endgame","loading"];for(let G of F){let B=(a=e.get)==null?void 0:a.call(e,G);if(B!=null&&B.visible){let q=(r=B.getContentLayer)==null?void 0:r.call(B);if(q){let J=(o=B.x)!=null?o:0,Z=(l=B.y)!=null?l:0,H=(c=q.x)!=null?c:0,ae=(d=q.y)!=null?d:0,te=(u=(p=q.scale)==null?void 0:p.x)!=null?u:1,ie=(h=(g=q.scale)==null?void 0:g.y)!=null?h:te;return console.log("[SceneEditor] getRuntimeLayoutReference: using visible screen contentLayer",{screenId:G,contentLayerScale:{x:te,y:ie},position:{x:J+H,y:Z+ae}}),{scale:{x:te,y:ie},position:{x:J+H,y:Z+ae},pivot:q.pivot?{x:q.pivot.x,y:q.pivot.y}:void 0}}}}for(let G of F){let B=(f=e.get)==null?void 0:f.call(e,G);if(B){if(!B.visible&&typeof B.updateLayout=="function"){let J=window.gameApp;if((m=J==null?void 0:J.renderer)!=null&&m.screen){let Z=J.renderer.screen.width,H=J.renderer.screen.height;Z>0&&H>0&&B.updateLayout(Z,H)}}let q=(b=B.getContentLayer)==null?void 0:b.call(B);if(q){let J=(y=B.x)!=null?y:0,Z=(v=B.y)!=null?v:0,H=(w=q.x)!=null?w:0,ae=(T=q.y)!=null?T:0,te=(M=(I=q.scale)==null?void 0:I.x)!=null?M:1,ie=(j=(L=q.scale)==null?void 0:L.y)!=null?j:te;return console.log("[SceneEditor] getRuntimeLayoutReference: using any screen contentLayer",{screenId:G,visible:B.visible,contentLayerScale:{x:te,y:ie},position:{x:J+H,y:Z+ae}}),{scale:{x:te,y:ie},position:{x:J+H,y:Z+ae},pivot:q.pivot?{x:q.pivot.x,y:q.pivot.y}:void 0}}}}}let t=window.__mainContainer;if(t){let F=(P=(_=t.scale)==null?void 0:_.x)!=null?P:1,G=(S=(x=t.scale)==null?void 0:x.y)!=null?S:F;return console.log("[SceneEditor] getRuntimeLayoutReference: using __mainContainer",{scale:{x:F,y:G},position:{x:(A=t.position)==null?void 0:A.x,y:(E=t.position)==null?void 0:E.y}}),t}let i=window.gameApp,n=(C=i==null?void 0:i.stage)!=null?C:null;if(n){let F=(k=(O=n.scale)==null?void 0:O.x)!=null?k:1,G=(z=(R=n.scale)==null?void 0:R.y)!=null?z:F;console.log("[SceneEditor] getRuntimeLayoutReference: using gameApp.stage (fallback)",{scale:{x:F,y:G},position:{x:(D=n.position)==null?void 0:D.x,y:(U=n.position)==null?void 0:U.y}})}else console.log("[SceneEditor] getRuntimeLayoutReference: no reference found");return n}getRuntimeScale(){var i,n;let e=this.getRuntimeLayoutReference(),t=Number((n=(i=e==null?void 0:e.scale)==null?void 0:i.x)!=null?n:1);return Number.isFinite(t)&&t>0?t:Number.isFinite(this.layoutScale)&&this.layoutScale>0?this.layoutScale:1}getRuntimeParentContainer(e){var c,d,p,u,g;let t=window.gameObjectManager;if(!(t!=null&&t.get))return null;let i=t.get(e),n=((c=i==null?void 0:i.getDisplayObject)==null?void 0:c.call(i))||(i==null?void 0:i.pixiObject)||i,a=n==null?void 0:n.parent;if(!a)return null;let r=window.__screenManager;if(r){let h=["gameplay","start","tutorial","endgame","loading"];for(let f of h){let m=(d=r.get)==null?void 0:d.call(r,f);if(!m)continue;let b=(u=(p=m.getBgLayer)==null?void 0:p.call(m))!=null?u:m.bgLayer;if(b&&(a===b||typeof b.contains=="function"&&b.contains(a)))return this.bgContainer}}let o=this.getRuntimeLayoutReference(),l=(g=window.gameApp)==null?void 0:g.stage;return o&&l&&o===l?this.mainContainer:o&&typeof o.contains=="function"&&o.contains(a)?this.mainContainer:a===o||a===l?this.mainContainer:this.uiContainer}applyRuntimeTransform(e){var r,o,l,c,d,p,u,g,h,f;if(!e)return console.log("[SceneEditor] applyRuntimeTransform: no reference"),!1;let t=1,i=1,n=Number((o=(r=e.position)==null?void 0:r.x)!=null?o:0),a=Number((c=(l=e.position)==null?void 0:l.y)!=null?c:0);if(!Number.isFinite(n)||!Number.isFinite(a))return console.log("[SceneEditor] applyRuntimeTransform: invalid position",{posX:n,posY:a}),!1;if(console.log("[SceneEditor] applyRuntimeTransform: applying (scale always 1)",{scale:{x:t,y:i},position:{x:n,y:a}}),this.mainContainer.scale.set(1,1),this.uiContainer.scale.set(1,1),this.mainContainer.position.set(n,a),this.uiContainer.position.set(n,a),e.pivot&&((d=this.mainContainer.pivot)!=null&&d.set)&&((p=this.uiContainer.pivot)!=null&&p.set)){let m=Number((g=(u=e.pivot)==null?void 0:u.x)!=null?g:0),b=Number((f=(h=e.pivot)==null?void 0:h.y)!=null?f:0);Number.isFinite(m)&&Number.isFinite(b)&&(this.mainContainer.pivot.set(m,b),this.uiContainer.pivot.set(m,b))}return typeof e.rotation=="number"&&(this.mainContainer.rotation=e.rotation,this.uiContainer.rotation=e.rotation),!0}getEditableConfig(){return window.__editableConfig||null}getEditableObjectConfig(e){var n,a;let t=window.getEditableObjectConfig;if(typeof t=="function")return t(e);let i=this.getEditableConfig();return i!=null&&i.objects?typeof i.objects.get=="function"?(n=i.objects.get(e))!=null?n:null:(a=i.objects[e])!=null?a:null:null}getEditableObjectIds(){let e=window.getEditableObjectList;if(typeof e=="function"){let i=e();if(Array.isArray(i))return i}let t=this.getEditableConfig();return t!=null&&t.objects?typeof t.objects.keys=="function"?Array.from(t.objects.keys()):Object.keys(t.objects):[]}async syncFromConfig(e){if(!this.app)return;let t=this.getEditableConfig();if(!(t!=null&&t.objects))return;let i=e!=null&&e.length?e:this.getEditableObjectIds(),n=new Set(i);if(!e)for(let a of Array.from(this.objectMap.keys()))n.has(a)||this.removeObject(a);for(let a of i){let r=this.getEditableObjectConfig(a);if(!r){this.removeObject(a);continue}await this.upsertObject(a,r)}this.updateGizmos(),this.updateSpawnPointHandles(),this.updateGameFrame(this.getScreen())}removeObject(e){var i,n;let t=this.objectMap.get(e);if(t){try{(n=(i=t.displayObject)==null?void 0:i.destroy)==null||n.call(i)}catch{}this.objectMap.delete(e),this.selectedId===e&&this.setSelected(null,{silent:!0})}}async upsertObject(e,t){let i=this.getAssetKey(t),n=this.objectMap.get(e),a=this.isUiConfig(e,t),r=this.playModeEnabled?this.getRuntimeParentContainer(e):null,l=this.isBackgroundObject(e,t)?this.bgContainer:a?this.uiContainer:this.mainContainer,c=r!=null?r:l;if(!n||n.assetKey!==i||n.isUi!==a){n&&this.removeObject(e);let p=await this.createDisplayObject(e,t);if(!p)return;c.addChild(p),this.objectMap.set(e,{id:e,displayObject:p,assetKey:i,isUi:a}),this.attachObjectInteraction(p,e)}let d=this.objectMap.get(e);d&&(d.displayObject.parent!==c&&c.addChild(d.displayObject),this.applyVisualConfig(d.displayObject,t),this.playModeEnabled||this.applyTransformFromConfig(e,d.displayObject,t))}async createDisplayObject(e,t){var o,l,c,d,p,u,g,h,f,m,b,y,v,w,T;if((o=t==null?void 0:t.render)!=null&&o.asset)try{if(((c=(l=t==null?void 0:t.render)==null?void 0:l.asset)==null?void 0:c.type)!=="json"){let M=await ve.create(e,t,this.app);if(M instanceof $.Container)return M}}catch(I){console.warn("[SceneEditor] ObjectFactory failed for",e,I)}let i=t==null?void 0:t.ui,n=(d=t==null?void 0:t.render)!=null?d:{},a=(i==null?void 0:i.text)||(i==null?void 0:i.kind)==="text";if(!!n.background_color){let I=this.getScreen(),M=(p=I==null?void 0:I.width)!=null?p:0,L=(u=I==null?void 0:I.height)!=null?u:0,j=new $.Graphics,_=this.parseColor(n.background_color,0),P=typeof n.background_alpha=="number"?n.background_alpha:1;M>0&&L>0&&j.rect(0,0,M,L).fill({color:_,alpha:P});let x=new $.Container;return x.addChild(j),x}if(a){let I=(h=(g=i==null?void 0:i.color)!=null?g:n==null?void 0:n.tint)!=null?h:"#ffffff",M=new $.TextStyle({fontFamily:"Arial, sans-serif",fontSize:(f=i==null?void 0:i.fontSize)!=null?f:16,fill:I,align:(m=i==null?void 0:i.align)!=null?m:"center",letterSpacing:(b=i==null?void 0:i.letterSpacing)!=null?b:0});return new $.Text({text:(y=i==null?void 0:i.text)!=null?y:"",style:M})}if((v=t==null?void 0:t.effects)!=null&&v.width||(w=t==null?void 0:t.effects)!=null&&w.height){let I=new $.Graphics,M=typeof t.effects.width=="number"?t.effects.width:100,L=typeof t.effects.height=="number"?t.effects.height:100,j=(T=t.effects.fill_color)!=null?T:"#ffffff",_=typeof t.effects.fill_alpha=="number"?t.effects.fill_alpha:1,P=Number.parseInt(String(j).replace("#",""),16);return I.rect(0,0,M,L).fill({color:Number.isFinite(P)?P:16777215,alpha:_}),I}return new $.Container}attachObjectInteraction(e,t){if(e&&(e.eventMode="static",e.cursor="pointer",!e.hitArea&&typeof e.getLocalBounds=="function")){let i=e.getLocalBounds();i&&i.width>0&&i.height>0&&(e.hitArea=new $.Rectangle(i.x,i.y,i.width,i.height))}}getAssetKey(e){var i;let t=(i=e==null?void 0:e.render)==null?void 0:i.asset;return t?`${t.type||"asset"}::${t.path||""}`:null}isUiConfig(e,t){var a,r;let i=(((a=t==null?void 0:t.identity)==null?void 0:a.category)||"").toString().toLowerCase(),n=(((r=t==null?void 0:t.identity)==null?void 0:r.id)||e||"").toString().toLowerCase();return i.includes("ui")||n.startsWith("ui")||n.includes("label")}isBackgroundObject(e,t,i){var r,o;if((i==null?void 0:i.parent)===this.bgContainer)return!0;let n=(((r=t==null?void 0:t.identity)==null?void 0:r.category)||"").toString().toLowerCase(),a=(((o=t==null?void 0:t.identity)==null?void 0:o.id)||e||"").toString().toLowerCase();return!!(n.includes("bg")||n.includes("background")||a.startsWith("background_")||a.includes("background"))}applyVisualConfig(e,t){var a,r,o;if(!e)return;let i=(a=t==null?void 0:t.render)!=null?a:{};typeof i.alpha=="number"&&(e.alpha=i.alpha),e.visible=i.visible!==!1,e.zIndex=typeof i.z_index=="number"?i.z_index:0;let n={x:.5,y:.5};if((r=e.anchor)!=null&&r.set)e.anchor.set(n.x,n.y);else if(e.pivot){let l=(o=e.getLocalBounds)==null?void 0:o.call(e);l&&e.pivot.set(l.width*n.x,l.height*n.y)}}applyTransformFromConfig(e,t,i){var M,L,j,_,P,x,S,A,E,C,O,k,R,z,D,U,F,G,B,q,J;if(!t)return;let n=this.getScreen();if(!(n!=null&&n.width)||!(n!=null&&n.height))return;let a=(M=i==null?void 0:i.transform)!=null?M:{},r=this.getPositioningAnchor(e,a),o=a==null?void 0:a.position_ratio,l=a==null?void 0:a.position,c=a==null?void 0:a.offset,d=Array.isArray(l)?Number((L=l[0])!=null?L:0):Number((j=l==null?void 0:l.x)!=null?j:0),p=Array.isArray(l)?Number((_=l[1])!=null?_:0):Number((P=l==null?void 0:l.y)!=null?P:0),u=Array.isArray(c)?Number((x=c[0])!=null?x:0):Number((S=c==null?void 0:c.x)!=null?S:0),g=Array.isArray(c)?Number((A=c[1])!=null?A:0):Number((E=c==null?void 0:c.y)!=null?E:0),h=(Number.isFinite(d)?d:0)+(Number.isFinite(u)?u:0),f=(Number.isFinite(p)?p:0)+(Number.isFinite(g)?g:0);if(this.backgroundCoverEnabled&&this.isBackgroundObject(e,i,t)){let Z=Number((O=(C=t==null?void 0:t.texture)==null?void 0:C.width)!=null?O:0),H=Number((R=(k=t==null?void 0:t.texture)==null?void 0:k.height)!=null?R:0);if(!Number.isFinite(Z)||Z<=0||!Number.isFinite(H)||H<=0){let ge=(z=t==null?void 0:t.getLocalBounds)==null?void 0:z.call(t);Z=Number((D=ge==null?void 0:ge.width)!=null?D:0),H=Number((U=ge==null?void 0:ge.height)!=null?U:0)}if(!Number.isFinite(Z)||Z<=0||!Number.isFinite(H)||H<=0)return;(F=t.anchor)!=null&&F.set&&t.anchor.set(.5,.5),(G=t.position)!=null&&G.set?t.position.set(n.width/2,n.height/2):t.position&&(t.position.x=n.width/2,t.position.y=n.height/2);let ae=n.width/Z,te=n.height/H,ie=Math.max(ae,te);(B=t.scale)!=null&&B.set?t.scale.set(ie,ie):t.scale&&(t.scale.x=ie,t.scale.y=ie);let _e=typeof(a==null?void 0:a.rotation)=="number"?a.rotation:0;t.rotation=this.toRadians(_e);return}let m=o!=null?dt(n.width,n.height,o):ze(n.width,n.height,r),b=this.getRuntimeScale(),y=(m.x-n.width/2)/b+h,v=(m.y-n.height/2)/b+f;(q=t.position)!=null&&q.set?t.position.set(y,v):t.position&&(t.position.x=y,t.position.y=v);let T=(typeof(a==null?void 0:a.scale)=="number"?a.scale:1)*this.getRuntimeScale();(J=t.scale)!=null&&J.set?t.scale.set(T,T):t.scale&&(t.scale.x=T,t.scale.y=T);let I=typeof(a==null?void 0:a.rotation)=="number"?a.rotation:0;t.rotation=this.toRadians(I)}getAnchorLocalPoint(e,t=this.mainContainer){var d;let i=(d=this.getRuntimeScreenSize())!=null?d:this.getScreen();if(!(i!=null&&i.width)||!(i!=null&&i.height))return null;let n="top-right",a=this.getPositioningAnchor(this.selectedId,e!=null?e:{}),r=(e==null?void 0:e.position_ratio)!=null?dt(i.width,i.height,e.position_ratio):ze(i.width,i.height,a!=null?a:n);if(t===this.bgContainer)return new $.Point(r.x,r.y);let o=this.getRuntimeScale(),l=(r.x-i.width/2)/o,c=(r.y-i.height/2)/o;return new $.Point(l,c)}getPositioningAnchor(e,t){var i,n,a,r,o,l,c,d,p,u;if((t==null?void 0:t.anchor)!=null&&t.anchor!=="")return t.anchor;if(typeof window!="undefined"&&e){let g=window,h=g.__editableConfig,f=(n=(i=h==null?void 0:h.objects)==null?void 0:i.get)==null?void 0:n.call(i,e),m=(o=(a=f==null?void 0:f.transform)==null?void 0:a.anchor)!=null?o:(r=f==null?void 0:f.render)==null?void 0:r.anchor;if(m!=null&&m!=="")return m;let b=g.__editableConfigBaseline,y=(c=(l=b==null?void 0:b.objects)==null?void 0:l.get)==null?void 0:c.call(l,e),v=(u=(d=y==null?void 0:y.transform)==null?void 0:d.anchor)!=null?u:(p=y==null?void 0:y.render)==null?void 0:p.anchor;if(v!=null&&v!=="")return v}return"top-left"}getActiveScreenSize(e){var t,i;return this.playModeEnabled?(i=(t=this.getRuntimeScreenSize())!=null?t:e)!=null?i:this.getScreen():e!=null?e:this.getScreen()}updateLayout(e){var i,n,a,r,o,l,c,d,p;let t=this.getActiveScreenSize(e);if(!(!(t!=null&&t.width)||!(t!=null&&t.height))){if(console.log("[SceneEditor] updateLayout: called",{screen:{width:t.width,height:t.height},currentScale:{x:this.mainContainer.scale.x,y:this.mainContainer.scale.y}}),this.playModeEnabled){let u=this.getRuntimeLayoutReference();if(u){let g=Number((n=(i=u.position)==null?void 0:i.x)!=null?n:t.width/2),h=Number((r=(a=u.position)==null?void 0:a.y)!=null?r:t.height/2);this.mainContainer.position.set(g,h),this.uiContainer.position.set(g,h);let f=Number((l=(o=u.scale)==null?void 0:o.x)!=null?l:1);Number.isFinite(f)&&f>0&&(this.layoutScale=f)}this.bgContainer.position.set(0,0),this.bgContainer.scale.set(1,1),this.mainContainer.scale.set(1,1),this.uiContainer.scale.set(1,1)}else this.bgContainer.position.set(0,0),this.bgContainer.scale.set(1,1),this.mainContainer.position.set(t.width/2,t.height/2),this.uiContainer.position.set(t.width/2,t.height/2),this.mainContainer.scale.set(1,1),this.uiContainer.scale.set(1,1),this.mainContainer.rotation=0,this.uiContainer.rotation=0,(c=this.mainContainer.pivot)!=null&&c.set&&this.mainContainer.pivot.set(0,0),(d=this.uiContainer.pivot)!=null&&d.set&&this.uiContainer.pivot.set(0,0);console.log("[SceneEditor] updateLayout: result",{finalScale:{x:this.mainContainer.scale.x,y:this.mainContainer.scale.y},position:{x:this.mainContainer.position.x,y:this.mainContainer.position.y}}),this.screenFrame.clear(),this.screenFrame.rect(0,0,t.width,t.height),this.screenFrame.stroke({width:2,color:2894892,alpha:.5}),this.updateGameFrame(t),(p=this.app)!=null&&p.stage&&(this.app.stage.hitArea=new $.Rectangle(0,0,this.app.renderer.width,this.app.renderer.height)),this.updateSpawnPointHandles()}}updateGrid(){if(!this.app)return;if(!this.gridEnabled){this.gridLayer.clear(),this.gridLayer.visible=!0;return}let e=Math.max(4,this.gridGap),t=this.app.renderer,i=this.camera.toLocal(new $.Point(0,0)),n=this.camera.toLocal(new $.Point(t.width,t.height)),a=Math.min(i.x,n.x),r=Math.max(i.x,n.x),o=Math.min(i.y,n.y),l=Math.max(i.y,n.y),c=400,d=Math.ceil((r-a)/e),p=Math.ceil((l-o)/e),u=e*Math.max(1,Math.ceil(d/c)),g=e*Math.max(1,Math.ceil(p/c)),h=Math.floor(a/u)*u,f=Math.floor(o/g)*g;this.gridLayer.clear(),this.gridLayer.visible=!0;for(let m=h;m<=r;m+=u)this.gridLayer.moveTo(m,o),this.gridLayer.lineTo(m,l);for(let m=f;m<=l;m+=g)this.gridLayer.moveTo(a,m),this.gridLayer.lineTo(r,m);this.gridLayer.stroke({width:1,color:16777215,alpha:this.gridAlpha})}updateGameFrame(e){let t=this.getActiveScreenSize(e);if(!(t!=null&&t.width)||!(t!=null&&t.height))return;let i=t.width,n=t.height,a=0,r=0;this.lastGameFrameSize&&this.lastGameFrameSize.width===t.width&&this.lastGameFrameSize.height===t.height||(this.lastGameFrameSize={width:t.width,height:t.height},this.gameFrame.clear(),this.gameFrame.rect(a,r,i,n),this.gameFrame.stroke({width:2,color:6333946,alpha:.35}))}syncFromGameObjectsInternal(){var i,n,a,r,o,l,c,d,p;if(!this.app||!this.isVisible)return;let e=window.gameObjectManager;if(!(e!=null&&e.get))return;let t=this.dragMode||this.selectedId&&performance.now()<this.dragSyncHoldUntil?this.selectedId:null;for(let[u,g]of this.objectMap.entries()){if(t&&u===t)continue;let h=e.get(u),f=((i=h==null?void 0:h.getDisplayObject)==null?void 0:i.call(h))||(h==null?void 0:h.pixiObject)||h;if(!f)continue;let m=(a=(n=g.displayObject)==null?void 0:n.parent)!=null?a:this.mainContainer,b=new $.Point;if(typeof f.getGlobalPosition=="function"){f.getGlobalPosition(b);let I=m.toLocal(b,this.camera);g.displayObject.position.set(I.x,I.y)}else if(f.worldTransform){b.set(f.worldTransform.tx,f.worldTransform.ty);let I=m.toLocal(b,this.camera);g.displayObject.position.set(I.x,I.y)}let y=this.getWorldScale(f);if(y){let I=Number((o=(r=m.scale)==null?void 0:r.x)!=null?o:1)||1,M=Number((c=(l=m.scale)==null?void 0:l.y)!=null?c:1)||1,L=y.x/I,j=y.y/M;(d=g.displayObject.scale)!=null&&d.set?g.displayObject.scale.set(L,j):g.displayObject.scale&&(g.displayObject.scale.x=L,g.displayObject.scale.y=j)}let v=this.getWorldRotation(f);if(typeof v=="number"){let I=m?m.rotation:0,M=v-I;g.displayObject.rotation=M;let L=this.getEditableObjectConfig(u);if(L){let j=(p=L.transform)!=null?p:{};L.transform||(L.transform=j);let _=this.toDegrees(M),P=typeof j.rotation=="number"?j.rotation:0;if(Math.abs(_-P)>.01){let x=Math.round(_*100)/100;j.rotation=x}}}let w=f.parent,T=typeof(w==null?void 0:w.getChildIndex)=="function"?w.getChildIndex(f):0;typeof f.zIndex=="number"?g.displayObject.zIndex=f.zIndex:Number.isFinite(T)&&(g.displayObject.zIndex=T)}this.updateGizmos()}getWorldScale(e){var a,r;let t=(r=e==null?void 0:e.worldTransform)!=null?r:(a=e==null?void 0:e.transform)==null?void 0:a.worldTransform;if(!t)return null;let i=Math.sqrt(t.a*t.a+t.b*t.b),n=Math.sqrt(t.c*t.c+t.d*t.d);return!Number.isFinite(i)||!Number.isFinite(n)?null:{x:i,y:n}}getWorldRotation(e){var i,n;let t=(n=e==null?void 0:e.worldTransform)!=null?n:(i=e==null?void 0:e.transform)==null?void 0:i.worldTransform;if(t){let a=Math.atan2(t.b,t.a);return Number.isFinite(a)?a:null}return typeof(e==null?void 0:e.rotation)=="number"?e.rotation:null}centerCamera(){if(!this.app)return;let e=this.getActiveScreenSize();if(!(e!=null&&e.width)||!(e!=null&&e.height))return;let t=this.app.renderer.width,i=this.app.renderer.height,n=Math.max(.01,Math.min(t/e.width,i/e.height));this.cameraScale=n,this.camera.scale.set(n),this.camera.position.set((t-e.width*n)/2,(i-e.height*n)/2)}updateGizmos(){var f,m,b,y,v,w;if(!this.selectedId&&this.selectedIds.size===0||!this.isVisible){this.clearGizmos();return}if(this.selectedIds.size>1){let T=1/0,I=1/0,M=-1/0,L=-1/0,j=!1;for(let _ of this.selectedIds){let P=this.objectMap.get(_);if(!(P!=null&&P.displayObject))continue;let x=(m=(f=P.displayObject).getBounds)==null?void 0:m.call(f);if(!x||x.width<=0||x.height<=0)continue;let S=this.camera.toLocal(new $.Point(x.x,x.y)),A=this.camera.toLocal(new $.Point(x.x+x.width,x.y+x.height));T=Math.min(T,S.x,A.x),I=Math.min(I,S.y,A.y),M=Math.max(M,S.x,A.x),L=Math.max(L,S.y,A.y),j=!0}if(j){let _=M-T,P=L-I,x=T+_/2,S=I+P/2;this.gizmoOutline.clear(),this.gizmoOutline.rect(T,I,_,P),this.gizmoOutline.stroke({width:2,color:16752394,alpha:.9});for(let C of this.selectedIds){let O=this.objectMap.get(C);if(!(O!=null&&O.displayObject))continue;let k=(y=(b=O.displayObject).getBounds)==null?void 0:y.call(b);if(!k||k.width<=0||k.height<=0)continue;let R=this.camera.toLocal(new $.Point(k.x,k.y)),z=this.camera.toLocal(new $.Point(k.x+k.width,k.y+k.height)),D=z.x-R.x,U=z.y-R.y;this.gizmoOutline.rect(R.x,R.y,D,U),this.gizmoOutline.stroke({width:1,color:16752394,alpha:.5})}let A=7,E={width:2,color:988970,alpha:.6};this.moveHandle.clear(),this.moveHandle.circle(x,S,A).fill({color:2278750,alpha:.95}),this.moveHandle.stroke(E),this.moveHandle.cursor="move",this.scaleHandle.clear(),this.rotateHandle.clear()}else this.clearGizmos();return}if(!this.selectedId){this.clearGizmos();return}let e=this.objectMap.get(this.selectedId);if(!(e!=null&&e.displayObject)){this.clearGizmos();return}let t=(w=(v=e.displayObject).getBounds)==null?void 0:w.call(v);if(!t||t.width<=0||t.height<=0){this.clearGizmos();return}let i=this.camera.toLocal(new $.Point(t.x,t.y)),n=this.camera.toLocal(new $.Point(t.x+t.width,t.y+t.height)),a=n.x-i.x,r=n.y-i.y,o=i.x+a/2,l=i.y+r/2;this.gizmoOutline.clear(),this.gizmoOutline.rect(i.x,i.y,a,r),this.gizmoOutline.stroke({width:2,color:16752394,alpha:.9});let c=7,d={width:2,color:988970,alpha:.6};this.moveHandle.clear(),this.moveHandle.circle(o,l,c).fill({color:2278750,alpha:.95}),this.moveHandle.stroke(d),this.moveHandle.cursor="move";let p=i.x+a,u=i.y+r;this.scaleHandle.clear(),this.scaleHandle.rect(p-c,u-c,c*2,c*2).fill({color:3718648,alpha:.95}),this.scaleHandle.stroke(d),this.scaleHandle.cursor="nwse-resize";let g=o,h=i.y-c*2;this.rotateHandle.clear(),this.rotateHandle.circle(g,h,c).fill({color:16347926,alpha:.95}),this.rotateHandle.stroke(d),this.rotateHandle.cursor="crosshair"}clearGizmos(){this.gizmoOutline.clear(),this.moveHandle.clear(),this.scaleHandle.clear(),this.rotateHandle.clear()}updateSpawnPointHandles(){if(this.clearSpawnPointHandles(),!this.selectedId)return;let e=this.getEditableObjectConfig(this.selectedId);if(!e||!this.isSpawnerConfig(e))return;let t=this.getSpawnPoints(e);!t||t.length===0||t.forEach((i,n)=>{let a=new $.Graphics;a.circle(0,0,5).fill({color:16096779,alpha:.9}),a.circle(0,0,9).stroke({width:1,color:16096779,alpha:.45});let r=this.toCameraFromMain(i);a.position.set(r.x,r.y),a.cursor="move",a.eventMode="static",a.on("pointerdown",o=>this.startSpawnPointDrag(n,o)),this.spawnPointLayer.addChild(a)})}clearSpawnPointHandles(){this.spawnPointLayer.removeChildren().forEach(t=>{var i;(i=t.destroy)==null||i.call(t)})}isSpawnerConfig(e){var i,n;return((i=e==null?void 0:e.logic)==null?void 0:i.id)==="Spawner"?!0:String(((n=e==null?void 0:e.identity)==null?void 0:n.system_role)||"").toLowerCase().includes("spawner")}getSpawnPoints(e){var i,n;let t=(n=(i=e==null?void 0:e.logic)==null?void 0:i.props)==null?void 0:n.spawnPoints;return Array.isArray(t)?t.map(a=>{var r,o;return{x:Number((r=a==null?void 0:a.x)!=null?r:0),y:Number((o=a==null?void 0:a.y)!=null?o:0)}}):null}toCameraFromMain(e){let t=this.mainContainer.toGlobal(new $.Point(e.x,e.y)),i=new $.Point;return this.camera.toLocal(t,void 0,i),i}startSpawnPointDrag(e,t){var o,l;if(!this.selectedId)return;let i=this.getEditableObjectConfig(this.selectedId);if(!i)return;let n=this.getSpawnPoints(i);if(!n||!n[e])return;(o=t==null?void 0:t.stopPropagation)==null||o.call(t),(l=t==null?void 0:t.stopImmediatePropagation)==null||l.call(t);let a=this.getEventLocalPoint(t,this.mainContainer);if(!a)return;let r=n[e];this.spawnPointDrag={objectId:this.selectedId,index:e,offset:new $.Point(r.x-a.x,r.y-a.y),startPoints:n.map(c=>({x:c.x,y:c.y}))},window.addEventListener("pointermove",this.onSpawnPointDragMove),window.addEventListener("pointerup",this.onSpawnPointDragEnd)}updateLiveSpawnPoint(e,t,i,n){let a=this.getEditableObjectConfig(e);if(!a)return;let r=this.getSpawnPoints(a);if(!r||!r[t])return;let o=r.map((l,c)=>c===t?{x:i,y:n}:{x:l.x,y:l.y});this.setNestedValue(a,"logic.props.spawnPoints",o),this.queueLiveApply(e),this.updateSpawnPointHandles()}setSelected(e,t={}){if(!(this.selectedId===e&&this.selectedIds.size===1&&this.selectedIds.has(e||""))&&(this.selectedId=e,e?(this.selectedIds.clear(),this.selectedIds.add(e)):this.selectedIds.clear(),this.updateGizmos(),this.updateSpawnPointHandles(),!t.silent&&e)){let i=window.__previewSelectObject;typeof i=="function"&&i(e)}}startDrag(e,t){var d,p,u,g,h,f,m;if(!this.selectedId)return;let i=this.objectMap.get(this.selectedId);if(!(i!=null&&i.displayObject))return;let n=this.getEditableObjectConfig(this.selectedId);if(!n||this.backgroundLocked&&this.isBackgroundObject(this.selectedId,n,i.displayObject))return;let a=(d=n.transform)!=null?d:{},r=(p=i.displayObject.parent)!=null?p:this.mainContainer,o=this.getEventLocalPoint(t,r);if(!o)return;(u=t==null?void 0:t.stopPropagation)==null||u.call(t),(g=t==null?void 0:t.stopImmediatePropagation)==null||g.call(t);let l=this.getPositioningAnchor(this.selectedId,a);(a.anchor==null||a.anchor==="")&&this.updateManager.updateProperty(this.selectedId,"transform.anchor",l),(((h=n==null?void 0:n.render)==null?void 0:h.anchor)==null||n.render.anchor==="")&&this.updateManager.updateProperty(this.selectedId,"render.anchor",l),this.dragMode=e,this.dragContainer=r,this.dragStartPointer=new $.Point(o.x,o.y),this.dragStartPos=new $.Point(i.displayObject.position.x,i.displayObject.position.y),this.dragLastPointer=new $.Point(o.x,o.y),this.dragPointerOffset=new $.Point(i.displayObject.position.x-o.x,i.displayObject.position.y-o.y),this.dragLogged=!1;let c=(f=this.getRuntimeScreenSize())!=null?f:this.getScreen();console.log("[SceneEditor][DragStart]",{objectId:this.selectedId,mode:e,isBackground:this.isBackgroundObject(this.selectedId,n,i.displayObject),screen:c,runtimeScale:this.getRuntimeScale(),pointer:{x:o.x,y:o.y},objectPos:{x:i.displayObject.position.x,y:i.displayObject.position.y},container:r===this.bgContainer?"bg":r===this.uiContainer?"ui":"main"}),this.dragStartScale=typeof((m=i.displayObject.scale)==null?void 0:m.x)=="number"?i.displayObject.scale.x:1,this.dragStartRotation=typeof i.displayObject.rotation=="number"?i.displayObject.rotation:0,this.dragAnchorLocal=this.getAnchorLocalPoint(a,r),this.dragStartValue=this.getDragStartValue(e,a),this.dragAnchorLocal&&(this.dragStartAngle=Math.atan2(o.y-this.dragAnchorLocal.y,o.x-this.dragAnchorLocal.x),this.dragStartDistance=Math.max(1,this.distance(o,this.dragAnchorLocal))),window.addEventListener("pointermove",this.onDragMove),window.addEventListener("pointerup",this.onDragEnd)}getDragStartValue(e,t){var i,n,a;return e==="move"?(i=t==null?void 0:t.position)!=null?i:{x:0,y:0}:e==="scale"?(n=t==null?void 0:t.scale)!=null?n:1:e==="rotate"?(a=t==null?void 0:t.rotation)!=null?a:0:null}updateLiveConfigPositionForObject(e,t,i){var T,I,M,L,j,_,P,x;let n=this.getEditableObjectConfig(e);if(!n)return;let a=(T=n.transform)!=null?T:{};n.transform||(n.transform=a);let r=(I=this.getRuntimeScreenSize())!=null?I:this.getScreen();if(!(r!=null&&r.width)||!(r!=null&&r.height))return;let o=this.objectMap.get(e),l=((M=o==null?void 0:o.displayObject)==null?void 0:M.parent)===this.bgContainer,c=this.getPositioningAnchor(e,a),d=(a==null?void 0:a.position_ratio)!=null?dt(r.width,r.height,a.position_ratio):ze(r.width,r.height,c),p=d.x,u=d.y,g=t,h=i;if(!l){let S=this.getRuntimeScale();p=(d.x-r.width/2)/S,u=(d.y-r.height/2)/S,g=t/S,h=i/S}let f=g-p,m=h-u,b=(L=a.offset)!=null?L:{x:0,y:0},y=Array.isArray(b)?Number((j=b[0])!=null?j:0):Number((_=b==null?void 0:b.x)!=null?_:0),v=Array.isArray(b)?Number((P=b[1])!=null?P:0):Number((x=b==null?void 0:b.y)!=null?x:0),w=this.buildPositionValue(a,{x:f-y,y:m-v});this.updateManager.updateProperty(e,"transform.position",w,{refreshInspector:!0})}updateLiveConfigPosition(e,t){this.selectedId&&this.updateLiveConfigPositionForObject(this.selectedId,e,t)}updateLiveConfigScale(e){var a;if(!this.selectedId)return;let t=this.getEditableObjectConfig(this.selectedId);if(!t)return;let i=(a=t.transform)!=null?a:{};t.transform||(t.transform=i);let n=Math.round(e*100)/100;this.updateManager.updateProperty(this.selectedId,"transform.scale",n,{refreshInspector:!0})}updateLiveConfigRotation(e){var r;if(!this.selectedId)return;let t=this.getEditableObjectConfig(this.selectedId);if(!t)return;let i=(r=t.transform)!=null?r:{};t.transform||(t.transform=i);let n=this.toDegrees(e),a=typeof i.rotation=="number"?i.rotation:0;if(Math.abs(n-a)>.01){let o=Math.round(n*100)/100;this.updateManager.updateProperty(this.selectedId,"transform.rotation",o,{refreshInspector:!0})}}applyFinalOverride(e,t,i,n){let a=this.getEditableObjectConfig(e);a!=null&&a.transform&&this.setNestedValue(a.transform,t.replace("transform.",""),n),re({objectId:e,path:t,value:i},{persist:!0,emitEvent:!0,trackHistory:!0})}queueLiveApply(e){this.applyQueuedId=e,!this.applyQueued&&(this.applyQueued=!0,requestAnimationFrame(()=>{this.applyQueued=!1;let t=this.applyQueuedId;if(!t)return;let i=this.getEditableObjectConfig(t),n=window.applyEditableObjectConfig;typeof n=="function"&&i&&(n(t,i),window.dispatchEvent(new CustomEvent("inspector:refresh")))}))}setNestedValue(e,t,i){let n=t.split("."),a=e;for(let r=0;r<n.length-1;r+=1){let o=n[r];(!a[o]||typeof a[o]!="object")&&(a[o]={}),a=a[o]}a[n[n.length-1]]=i}buildPositionValue(e,t){let i=e==null?void 0:e.position,n=Math.round(t.x*100)/100,a=Math.round(t.y*100)/100;return Array.isArray(i)?[n,a]:{x:n,y:a}}toRadians(e){return e*Math.PI/180}toDegrees(e){return e*180/Math.PI}distance(e,t){let i=e.x-t.x,n=e.y-t.y;return Math.sqrt(i*i+n*n)}getPointerButton(e){var t,i,n;return typeof(e==null?void 0:e.button)=="number"?e.button:typeof((t=e==null?void 0:e.data)==null?void 0:t.button)=="number"?e.data.button:typeof((n=(i=e==null?void 0:e.data)==null?void 0:i.originalEvent)==null?void 0:n.button)=="number"?e.data.originalEvent.button:0}getEventGlobalPoint(e){var l,c;let t=(c=e==null?void 0:e.global)!=null?c:(l=e==null?void 0:e.data)==null?void 0:l.global;if(t)return new $.Point(t.x,t.y);if(!this.app)return null;let i=e==null?void 0:e.clientX,n=e==null?void 0:e.clientY;if(typeof i!="number"||typeof n!="number")return null;let a=this.app.canvas.getBoundingClientRect(),r=(i-a.left)*(this.app.renderer.width/a.width),o=(n-a.top)*(this.app.renderer.height/a.height);return new $.Point(r,o)}getEventLocalPoint(e,t=this.mainContainer){var a,r;if(!this.app)return null;if(typeof(e==null?void 0:e.getLocalPosition)=="function"){let o=e.getLocalPosition(t);return new $.Point(o.x,o.y)}let i=(r=e==null?void 0:e.global)!=null?r:(a=e==null?void 0:e.data)==null?void 0:a.global;if(!i)return null;let n=new $.Point;return t.toLocal(new $.Point(i.x,i.y),void 0,n),n}getPointerInContainer(e,t,i){if(!this.app)return null;let n=this.app.canvas.getBoundingClientRect(),a=(e-n.left)*(this.app.renderer.width/n.width),r=(t-n.top)*(this.app.renderer.height/n.height),o=new $.Point;return i.toLocal(new $.Point(a,r),void 0,o),o}parseColor(e,t){if(typeof e=="number"&&Number.isFinite(e))return e;if(typeof e=="string"){let i=e.trim().replace("#",""),n=Number.parseInt(i,16);if(Number.isFinite(n))return n}return t}drawSelectionBox(e,t){if(!this.selectionBox)return;this.selectionBox.clear();let i=Math.min(e.x,t.x),n=Math.max(e.x,t.x),a=Math.min(e.y,t.y),r=Math.max(e.y,t.y),o=n-i,l=r-a;this.selectionBox.rect(i,a,o,l),this.selectionBox.stroke({width:2,color:3900150,alpha:.8}),this.selectionBox.rect(i,a,o,l),this.selectionBox.fill({color:3900150,alpha:.1})}finalizeSelectionBox(e,t){var l;let i=Math.min(e.x,t.x),n=Math.max(e.x,t.x),a=Math.min(e.y,t.y),r=Math.max(e.y,t.y),o=[];for(let[c,d]of this.objectMap.entries()){let p=d.displayObject;if(!p||p.visible===!1||this.backgroundLocked&&this.isBackgroundObject(c,this.getEditableObjectConfig(c),p))continue;let u=(l=p.getBounds)==null?void 0:l.call(p);if(!u||u.width<=0||u.height<=0)continue;let g=u.x+u.width/2,h=u.y+u.height/2;g>=i&&g<=n&&h>=a&&h<=r&&o.push(c)}o.length>0&&(this.selectedIds=new Set(o),this.selectedId=o[0],this.updateGizmos())}setupDragAndDrop(){if(!this.app)return;let e=this.app.canvas;e.addEventListener("dragover",t=>{t.preventDefault(),t.stopPropagation(),this.dropZoneActive||(this.dropZoneActive=!0,this.showDropZone())}),e.addEventListener("dragleave",t=>{e.contains(t.relatedTarget)||(this.dropZoneActive=!1,this.hideDropZone())}),e.addEventListener("drop",async t=>{var d;t.preventDefault(),t.stopPropagation(),this.dropZoneActive=!1,this.hideDropZone();let n=Array.from(((d=t.dataTransfer)==null?void 0:d.files)||[]).filter(p=>p.type.startsWith("image/"));if(n.length===0)return;let a=e.getBoundingClientRect(),r=t.clientX-a.left,o=t.clientY-a.top,l=new $.Point(r/a.width*this.app.renderer.width,o/a.height*this.app.renderer.height),c=this.camera.toLocal(l);await this.handleDroppedPNGs(n,c)})}showDropZone(){if(!this.dropZoneOverlay||!this.app)return;let e=this.camera.toLocal(new $.Point(0,0)),t=this.camera.toLocal(new $.Point(this.app.renderer.width,this.app.renderer.height)),i=t.x-e.x,n=t.y-e.y;this.dropZoneOverlay.clear(),this.dropZoneOverlay.rect(e.x,e.y,i,n),this.dropZoneOverlay.fill({color:3900150,alpha:.1}),this.dropZoneOverlay.rect(e.x,e.y,i,n),this.dropZoneOverlay.stroke({width:3,color:3900150,alpha:.6}),this.dropZoneOverlay.visible=!0}hideDropZone(){this.dropZoneOverlay&&(this.dropZoneOverlay.clear(),this.dropZoneOverlay.visible=!1)}async handleDroppedPNGs(e,t){let i=window.__HANDLER_ACTIVE_SCREEN,n=i==="loading"||i==="start"||i==="gameplay"||i==="tutorial"||i==="endgame"?i:"gameplay",a=this.showToast(`Processing ${e.length} PNG${e.length>1?"s":""}...`);try{for(let r=0;r<e.length;r++){let o=e[r];await this.processDroppedPNG(o,t,n,r)}this.hideToast(a),this.showToast(`\u2705 Added ${e.length} PNG${e.length>1?"s":""} to scene`,2e3),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh"))}catch(r){this.hideToast(a),this.showToast(`\u274C Error: ${r instanceof Error?r.message:String(r)}`,3e3),console.error("[SceneEditor] Failed to process dropped PNGs:",r)}}async processDroppedPNG(e,t,i,n){let a=await this.fileToDataUrl(e);if(!a)throw new Error(`Failed to read ${e.name}`);let r=e.name.replace(/\.[^/.]+$/,""),o=this.inferCategoryFromFilename(r),l=r.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"").toLowerCase(),c=`${l}_${Date.now()}${n>0?`_${n}`:""}`,d=`json.${c}`,p=`${l}.png`,g=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:o,filename:p,data:a,overwrite:!1})})).json();if(!g.success)throw new Error(`Failed to save ${e.name} to library: ${g.error}`);let h=this.getScreen(),f=this.getRuntimeScale(),m=(t.x-h.width/2)/f,b=(t.y-h.height/2)/f,y={identity:{id:d,category:o},transform:{anchor:"center",position:{x:m,y:b},scale:1,rotation:0},render:{z_index:0,alpha:1,visible:!0,anchor:{x:.5,y:.5},asset:{type:"image",path:g.path||`raw/library/${o}/${p}`}}},v=await fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i,instanceId:c,objectConfigId:d,config:y,layer:o==="ui"?"ui":"world"})}),w=await v.json();if(!v.ok||!w.success)throw new Error(`Failed to create object: ${w.error||"Unknown error"}`)}inferCategoryFromFilename(e){let t=e.toLowerCase();return t.startsWith("ui_")||t.includes("button")||t.includes("label")?"ui":t.startsWith("bg_")||t.includes("background")?"backgrounds":t.includes("character")||t.includes("player")?"character":"environment"}fileToDataUrl(e){return new Promise(t=>{let i=new FileReader;i.onload=()=>t(i.result),i.onerror=()=>t(null),i.readAsDataURL(e)})}showToast(e,t=3e3){let i=document.createElement("div");return i.style.cssText=`
|
|
2358
|
+
`;case"text":return`<pre style="background: rgba(0,0,0,0.2); padding: 16px; border-radius: 8px; max-height: 300px; overflow-y: auto; white-space: pre-wrap;">${e}</pre>`;default:return`<div class="asset-preview-placeholder">Cannot preview ${t} assets</div>`}}resolveAssetUrl(e){return e.startsWith("data:")||e.startsWith("blob:")||e.startsWith("/")?e:`/raw/${e}`}attachEventListeners(){if(!this.modal)return;this.modal.addEventListener("click",i=>{let n=i.target;(n.dataset.action==="close"||n===this.modal)&&this.close()});let e=this.modal.querySelector('[data-action="change"]');e&&e.addEventListener("click",()=>{this.openAssetEditor()});let t=this.modal.querySelector('[data-action="edit"]');t&&t.addEventListener("click",()=>{this.openAiEditor(),this.close()})}openAssetEditor(){this.options&&Promise.resolve().then(()=>(ut(),Ht)).then(({AssetEditorModal:e})=>{new e().show(this.options.objectId||"unknown",this.options.propertyPath||"",this.options.assetPath,i=>{var n;(n=this.options)!=null&&n.onChange&&this.options.onChange(i),this.close()})})}openAiEditor(){if(!this.options||this.options.assetType!=="image")return;let e=window.__openAiEditor;typeof e=="function"&&e(this.options.objectId||"asset","Edit this image asset",this.options.assetPath,{path:this.options.propertyPath,onApply:t=>{var i;(i=this.options)!=null&&i.onChange&&this.options.onChange(t)}})}close(){this.modal&&this.modal.parentNode&&this.modal.parentNode.removeChild(this.modal),this.modal=null,this.options=null}};window.openAssetPreview=function(r){new za().open(r)};oa();ee();var $=require("pixi.js");ee();var un=class{constructor(e){this.app=null;this.camera=new $.Container;this.bgContainer=new $.Container;this.mainContainer=new $.Container;this.uiContainer=new $.Container;this.gizmoLayer=new $.Container;this.screenFrame=new $.Graphics;this.gameFrame=new $.Graphics;this.gridLayer=new $.Graphics;this.spawnPointLayer=new $.Container;this.objectMap=new Map;this.selectedId=null;this.selectedIds=new Set;this.dragMode=null;this.selectionBox=null;this.selectionBoxStart=null;this.isSelectionBoxActive=!1;this.dragStartPointer=null;this.dragStartPos=null;this.dragStartScale=1;this.dragStartRotation=0;this.dragStartAngle=0;this.dragStartDistance=1;this.dragAnchorLocal=null;this.dragStartValue=null;this.dragContainer=null;this.dragLastPointer=null;this.dragPointerOffset=null;this.dragSyncHoldUntil=0;this.dragLogged=!1;this.spawnPointDrag=null;this.lastGameFrameSize=null;this.cameraScale=1;this.isPanning=!1;this.panStart=null;this.panStartCamera=null;this.hasUserCamera=!1;this.resizeObserver=null;this.screenSyncRaf=null;this.gizmoOutline=new $.Graphics;this.anchorVisualizationLayer=new $.Graphics;this.moveHandle=new $.Graphics;this.scaleHandle=new $.Graphics;this.rotateHandle=new $.Graphics;this.isVisible=!0;this.applyQueued=!1;this.applyQueuedId=null;this.gridEnabled=!1;this.gridGap=50;this.gridAlpha=.25;this.snapToGrid=!1;this.alignmentGuidesEnabled=!0;this.alignmentGuideLayer=new $.Graphics;this.lastPickPoint=null;this.lastPickIds=[];this.lastPickIndex=0;this.lastPickTime=0;this.playModeEnabled=!0;this.playModeInitialized=!1;this.layoutScale=1;this.updateManager=new xe;this.backgroundCoverEnabled=!0;this.backgroundLocked=!0;this.dropZoneActive=!1;this.dropZoneOverlay=null;this.handleScreenChange=e=>{if(!(e!=null&&e.detail))return;let{width:t,height:i}=e.detail;!t||!i||(this.hasUserCamera=!1,this.updateLayout({width:t,height:i}),this.hasUserCamera||this.centerCamera(),this.updateGizmos(),this.updateGrid(),this.playModeEnabled?this.schedulePostScreenSync({width:t,height:i}):this.syncFromConfig())};this.handleAnchorChanged=e=>{let t=e==null?void 0:e.detail,i=t==null?void 0:t.objectId;if(!i)return;let n=t==null?void 0:t.previousAnchor,a=t==null?void 0:t.nextAnchor;this.adjustPositionForAnchorChange(i,n,a)};this.handleActiveScreenChanged=()=>{this.isVisible&&this.syncFromConfig()};this.handleConfigChanged=e=>{if(!this.isVisible)return;this.updateLayout(),this.updateGrid();let t=e==null?void 0:e.detail;if(!t){this.syncFromConfig();return}let i=t.path,n=t.objectId;if(i==="transform.anchor"&&n){let s=t.value,o=t.oldValue;o!=null&&this.adjustPositionForAnchorChange(n,o,s)}let a=t.objectIds;if(n){this.syncFromConfig([n]);return}if(Array.isArray(a)&&a.length>0){this.syncFromConfig(a);return}this.syncFromConfig()};this.handleSceneRefresh=()=>{this.isVisible&&this.syncFromConfig()};this.handleAssetUpdated=e=>{var l;let t=(l=e==null?void 0:e.detail)!=null?l:{},i=t.objectId,n=t.texture;if(!i||!n)return;let a=this.objectMap.get(i);if(!a)return;let s=a.displayObject;if(s!=null&&s.texture)s.texture=n;else if(s!=null&&s.children){let c=s.children.find(d=>d==null?void 0:d.texture);c&&(c.texture=n)}let o=this.getEditableObjectConfig(i);o&&(a.assetKey=this.getAssetKey(o))};this.handleLayoutApplied=e=>{var s;if(!this.isVisible)return;let t=(s=e==null?void 0:e.detail)!=null?s:{},i=Number(t.width),n=Number(t.height),a=Number.isFinite(i)&&i>0&&Number.isFinite(n)&&n>0?{width:i,height:n}:this.getScreen();this.updateLayout(a),this.hasUserCamera||this.centerCamera(),this.syncFromConfig().then(()=>{this.playModeEnabled&&this.syncFromGameObjectsInternal(),this.updateGizmos(),this.updateGrid()})};this.handlePreviewSelect=e=>{var i,n;let t=(n=(i=e==null?void 0:e.detail)==null?void 0:i.objectId)!=null?n:null;this.setSelected(t,{silent:!0})};this.onStagePointerDown=e=>{if(!this.app||!this.isVisible)return;let t=this.getPointerButton(e);if(t===2){if(this.isGizmoTarget(e==null?void 0:e.target))return;let h=this.getEventGlobalPoint(e);if(!h)return;let f=new $.Point(h.x,h.y),m=this.getPickCandidates(f);if(m.length>0){let b=m[0];this.selectedIds.has(b)||(this.selectedIds.clear(),this.selectedIds.add(b),this.setSelected(b),this.updateGizmos()),this.showContextMenu(b,h.x,h.y)}return}if(t!==0||this.isGizmoTarget(e==null?void 0:e.target))return;let i=this.getEventGlobalPoint(e);if(!i)return;let n=new $.Point(i.x,i.y),a=this.getPickCandidates(n),o=navigator.platform.toUpperCase().indexOf("MAC")>=0?e.metaKey:e.ctrlKey;if(a.length===0){o||(this.setSelected(null),this.selectedIds.clear()),this.selectionBoxStart=n,this.isSelectionBoxActive=!0,this.lastPickIds=[],this.lastPickIndex=0,this.lastPickPoint=n,this.lastPickTime=performance.now();return}let l=performance.now(),c=this.areSameIds(a,this.lastPickIds),d=this.lastPickPoint&&this.distance(n,this.lastPickPoint)<=6,p=l-this.lastPickTime<1200,u=c&&d&&p?(this.lastPickIndex+1)%a.length:0,g=a[u];this.lastPickIds=a,this.lastPickIndex=u,this.lastPickPoint=n,this.lastPickTime=l,o?this.selectedIds.has(g)?(this.selectedIds.delete(g),this.selectedId===g&&(this.selectedId=this.selectedIds.size>0?Array.from(this.selectedIds)[0]:null)):(this.selectedIds.add(g),this.selectedId=g):(this.selectedIds.clear(),this.selectedIds.add(g),this.setSelected(g)),this.updateGizmos()};this.handleGridSettings=e=>{var a,s,o;let t=(a=e==null?void 0:e.detail)==null?void 0:a.enabled,i=(s=e==null?void 0:e.detail)==null?void 0:s.gap,n=(o=e==null?void 0:e.detail)==null?void 0:o.alpha;typeof t=="boolean"&&(this.gridEnabled=t),typeof i=="number"&&Number.isFinite(i)&&i>2&&(this.gridGap=i),typeof n=="number"&&Number.isFinite(n)&&n>=0&&n<=1&&(this.gridAlpha=n),this.updateGrid()};this.handleBackgroundCover=e=>{var i;let t=(i=e==null?void 0:e.detail)==null?void 0:i.enabled;typeof t=="boolean"&&(this.backgroundCoverEnabled=t,this.syncFromConfig(),this.updateGizmos())};this.handleBackgroundLock=e=>{var i;let t=(i=e==null?void 0:e.detail)==null?void 0:i.enabled;if(typeof t=="boolean"&&(this.backgroundLocked=t,t&&this.selectedId)){let n=this.getEditableObjectConfig(this.selectedId),a=this.objectMap.get(this.selectedId);this.isBackgroundObject(this.selectedId,n,a==null?void 0:a.displayObject)&&this.setSelected(null)}};this.handlePlayModeChange=e=>{var i;let t=(i=e==null?void 0:e.detail)==null?void 0:i.enabled;typeof t=="boolean"&&(!this.playModeInitialized&&(this.playModeInitialized=!0,!t)||t&&this.applyPlayModeState(!0))};this.syncFromGameObjects=()=>{this.syncFromGameObjectsInternal()};this.onSpawnPointDragMove=e=>{if(!this.spawnPointDrag)return;let t=this.getPointerInContainer(e.clientX,e.clientY,this.mainContainer);if(!t)return;let i=t.x+this.spawnPointDrag.offset.x,n=t.y+this.spawnPointDrag.offset.y;this.updateLiveSpawnPoint(this.spawnPointDrag.objectId,this.spawnPointDrag.index,i,n)};this.onSpawnPointDragEnd=()=>{if(!this.spawnPointDrag)return;let{objectId:e,startPoints:t}=this.spawnPointDrag,i=this.getEditableObjectConfig(e),n=i?this.getSpawnPoints(i):null;i&&n&&(this.setNestedValue(i,"logic.props.spawnPoints",t),re({objectId:e,path:"logic.props.spawnPoints",value:n},{persist:!0,emitEvent:!0,trackHistory:!0}),this.queueLiveApply(e)),this.spawnPointDrag=null,window.dispatchEvent(new CustomEvent("inspector:refresh")),window.removeEventListener("pointermove",this.onSpawnPointDragMove),window.removeEventListener("pointerup",this.onSpawnPointDragEnd)};this.onDragMove=e=>{var n;if(!this.dragMode||!this.selectedId||!this.dragContainer||!this.dragStartPointer||!this.dragStartPos)return;let t=this.objectMap.get(this.selectedId);if(!(t!=null&&t.displayObject))return;let i=this.getPointerInContainer(e.clientX,e.clientY,this.dragContainer);if(i){if(this.dragMode==="move"){let a=this.dragPointerOffset;if(!a)return;let s=i.x+a.x,o=i.y+a.y;if(this.snapToGrid){let d=this.snapToGridPosition(s,o);s=d.x,o=d.y}let l=s-this.dragStartPos.x,c=o-this.dragStartPos.y;if(t.displayObject.position.set(s,o),this.updateAlignmentGuides(this.selectedId,new $.Point(s,o)),this.updateLiveConfigPosition(s,o),this.selectedIds.size>1){let d=new Map;if(!this.multiDragStartPositions){this.multiDragStartPositions=new Map;for(let p of this.selectedIds){if(p===this.selectedId)continue;let u=this.objectMap.get(p);u!=null&&u.displayObject&&this.multiDragStartPositions.set(p,new $.Point(u.displayObject.position.x,u.displayObject.position.y))}}for(let p of this.selectedIds){if(p===this.selectedId)continue;let u=this.objectMap.get(p);if(!(u!=null&&u.displayObject))continue;let g=this.multiDragStartPositions.get(p);if(g){let h=g.x+l,f=g.y+c;if(this.snapToGrid){let m=this.snapToGridPosition(h,f);h=m.x,f=m.y}u.displayObject.position.set(h,f),this.updateLiveConfigPositionForObject(p,h,f)}}}this.dragLastPointer=new $.Point(i.x,i.y),this.dragLogged||(this.dragLogged=!0,console.log("[SceneEditor][DragMove]",{objectId:this.selectedId,selectedCount:this.selectedIds.size,pointer:{x:i.x,y:i.y},nextPos:{x:s,y:o}}))}if(this.dragMode==="scale"&&this.dragAnchorLocal){let s=Math.max(1,this.distance(i,this.dragAnchorLocal))/Math.max(1,this.dragStartDistance),o=Math.max(.01,this.dragStartScale*s);(n=t.displayObject.scale)!=null&&n.set?t.displayObject.scale.set(o,o):t.displayObject.scale&&(t.displayObject.scale.x=o,t.displayObject.scale.y=o),this.updateLiveConfigScale(o)}if(this.dragMode==="rotate"&&this.dragAnchorLocal){let a=Math.atan2(i.y-this.dragAnchorLocal.y,i.x-this.dragAnchorLocal.x),s=this.dragStartRotation+(a-this.dragStartAngle);t.displayObject.rotation=s,this.updateLiveConfigRotation(s)}this.updateGizmos()}};this.onDragEnd=()=>{if(this.dragMode){if(this.alignmentGuideLayer&&this.alignmentGuideLayer.clear(),this.selectedIds.size>0){let e=Array.from(this.selectedIds);window.dispatchEvent(new CustomEvent("config:changed",{detail:{objectIds:e}})),this.dragSyncHoldUntil=performance.now()+200}this.dragMode=null,this.dragStartPointer=null,this.dragStartPos=null,this.dragAnchorLocal=null,this.dragStartValue=null,this.dragContainer=null,this.dragLastPointer=null,this.dragPointerOffset=null,this.multiDragStartPositions=null,window.removeEventListener("pointermove",this.onDragMove),window.removeEventListener("pointerup",this.onDragEnd)}};this.onWheel=e=>{if(!this.app||!this.isVisible)return;e.preventDefault();let i=Math.sign(e.deltaY)<0?1.1:.9,n=Math.min(6,Math.max(.1,this.cameraScale*i)),a=new $.Point(this.app.renderer.width/2,this.app.renderer.height/2),s=this.camera.toLocal(a);this.cameraScale=n,this.camera.scale.set(n);let o=this.camera.toGlobal(s);this.camera.position.set(this.camera.position.x+(a.x-o.x),this.camera.position.y+(a.y-o.y)),this.hasUserCamera=!0,this.updateGizmos(),this.updateGrid()};this.onPanStart=e=>{e.button===2&&(this.isPanning=!0,this.panStart={x:e.clientX,y:e.clientY},this.panStartCamera={x:this.camera.position.x,y:this.camera.position.y},this.hasUserCamera=!0)};this.onPanMove=e=>{if(this.isPanning&&this.panStart&&this.panStartCamera){let t=e.clientX-this.panStart.x,i=e.clientY-this.panStart.y;this.camera.position.set(this.panStartCamera.x+t,this.panStartCamera.y+i),this.updateGrid()}if(this.isSelectionBoxActive&&this.selectionBoxStart&&this.app){let t=this.getEventGlobalPoint(e);if(!t)return;let i=new $.Point(t.x,t.y);this.drawSelectionBox(this.selectionBoxStart,i)}};this.onPanEnd=e=>{if(this.isPanning&&(this.isPanning=!1,this.panStart=null,this.panStartCamera=null),this.isSelectionBoxActive&&this.selectionBoxStart&&this.app){let t=this.getEventGlobalPoint(e);if(t){let i=new $.Point(t.x,t.y);this.finalizeSelectionBox(this.selectionBoxStart,i)}this.isSelectionBoxActive=!1,this.selectionBoxStart=null,this.selectionBox&&this.selectionBox.clear()}this.multiDragStartPositions=null};this.root=e.root,this.getScreen=e.getScreen}async mount(){this.app||(this.app=new $.Application,await this.app.init({resizeTo:this.root,autoDensity:!0,resolution:window.devicePixelRatio||1,antialias:!0,backgroundAlpha:0}),this.root.innerHTML="",this.root.appendChild(this.app.canvas),this.root.style.position="relative",this.root.style.overflow="hidden",this.app.stage.sortableChildren=!0,this.app.stage.eventMode="static",this.camera.sortableChildren=!0,this.bgContainer.sortableChildren=!0,this.mainContainer.sortableChildren=!0,this.uiContainer.sortableChildren=!0,this.spawnPointLayer.sortableChildren=!0,this.gizmoLayer.sortableChildren=!0,this.app.stage.addChild(this.camera),this.camera.addChild(this.screenFrame),this.camera.addChild(this.bgContainer),this.camera.addChild(this.mainContainer),this.camera.addChild(this.gridLayer),this.camera.addChild(this.uiContainer),this.camera.addChild(this.spawnPointLayer),this.camera.addChild(this.gameFrame),this.camera.addChild(this.gizmoLayer),this.screenFrame.zIndex=-1,this.screenFrame.eventMode="none",this.bgContainer.zIndex=-5e3,this.bgContainer.eventMode="none",this.mainContainer.zIndex=0,this.gridLayer.zIndex=2e4,this.gridLayer.eventMode="none",this.gridLayer.visible=!0,this.uiContainer.zIndex=5e4,this.spawnPointLayer.zIndex=8e4,this.spawnPointLayer.eventMode="passive",this.gameFrame.zIndex=85e3,this.gameFrame.eventMode="none",this.gizmoLayer.zIndex=1e5,this.gizmoLayer.addChild(this.gizmoOutline),this.gizmoLayer.addChild(this.anchorVisualizationLayer),this.gizmoLayer.addChild(this.moveHandle),this.gizmoLayer.addChild(this.scaleHandle),this.gizmoLayer.addChild(this.rotateHandle),this.selectionBox=new $.Graphics,this.selectionBox.zIndex=99999,this.selectionBox.eventMode="none",this.gizmoLayer.addChild(this.selectionBox),this.dropZoneOverlay=new $.Graphics,this.dropZoneOverlay.zIndex=99998,this.dropZoneOverlay.eventMode="none",this.gizmoLayer.addChild(this.dropZoneOverlay),this.alignmentGuideLayer=new $.Graphics,this.alignmentGuideLayer.zIndex=99997,this.alignmentGuideLayer.eventMode="none",this.gizmoLayer.addChild(this.alignmentGuideLayer),this.gizmoOutline.eventMode="none",this.anchorVisualizationLayer.eventMode="none",this.setupInteractions(),this.setupObservers(),this.updateLayout(),this.hasUserCamera||this.centerCamera(),this.restoreScenePreferences(),this.refresh(),this.applyPlayModeState(!0),!this.isVisible&&this.app.ticker&&this.app.ticker.stop())}destroy(){var e;this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null),this.screenSyncRaf&&(cancelAnimationFrame(this.screenSyncRaf),this.screenSyncRaf=null),window.removeEventListener("handler-preview:screen",this.handleScreenChange),window.removeEventListener("handler:active-screen-changed",this.handleActiveScreenChanged),window.removeEventListener("config:changed",this.handleConfigChanged),window.removeEventListener("handler:scene-objects-refresh",this.handleSceneRefresh),window.removeEventListener("handler:layout-applied",this.handleLayoutApplied),window.removeEventListener("preview:select",this.handlePreviewSelect),window.removeEventListener("scene-editor:grid",this.handleGridSettings),window.removeEventListener("scene-editor:background-cover",this.handleBackgroundCover),window.removeEventListener("scene-editor:background-lock",this.handleBackgroundLock),window.removeEventListener("scene-editor:asset-updated",this.handleAssetUpdated),window.removeEventListener("scene-editor:play-mode",this.handlePlayModeChange),window.removeEventListener("scene-editor:anchor-changed",this.handleAnchorChanged),window.removeEventListener("pointermove",this.onSpawnPointDragMove),window.removeEventListener("pointerup",this.onSpawnPointDragEnd),this.app&&((e=this.app.ticker)==null||e.remove(this.syncFromGameObjects),this.app.stage.off("pointerdown",this.onStagePointerDown),this.app.destroy(!0),this.app=null)}setVisible(e){this.isVisible=e,!(!this.app||!this.app.ticker)&&(e?(this.app.ticker.start(),this.refresh(),this.updateGrid()):this.app.ticker.stop())}refresh(){this.syncFromConfig()}setupObservers(){window.addEventListener("handler-preview:screen",this.handleScreenChange),window.addEventListener("handler:active-screen-changed",this.handleActiveScreenChanged),window.addEventListener("config:changed",this.handleConfigChanged),window.addEventListener("handler:scene-objects-refresh",this.handleSceneRefresh),window.addEventListener("handler:layout-applied",this.handleLayoutApplied),window.addEventListener("preview:select",this.handlePreviewSelect),window.addEventListener("scene-editor:grid",this.handleGridSettings),window.addEventListener("scene-editor:background-cover",this.handleBackgroundCover),window.addEventListener("scene-editor:background-lock",this.handleBackgroundLock),window.addEventListener("scene-editor:asset-updated",this.handleAssetUpdated),window.addEventListener("scene-editor:play-mode",this.handlePlayModeChange),window.addEventListener("scene-editor:anchor-changed",this.handleAnchorChanged),this.resizeObserver=new ResizeObserver(()=>{this.handleResize()}),this.resizeObserver.observe(this.root)}setupInteractions(){if(!this.app)return;let e=this.app.canvas;e.addEventListener("contextmenu",t=>t.preventDefault()),e.addEventListener("wheel",this.onWheel,{passive:!1}),e.addEventListener("pointerdown",this.onPanStart),window.addEventListener("pointermove",this.onPanMove),window.addEventListener("pointerup",this.onPanEnd),this.app.stage.on("pointerdown",this.onStagePointerDown),this.moveHandle.on("pointerdown",t=>this.startDrag("move",t)),this.scaleHandle.on("pointerdown",t=>this.startDrag("scale",t)),this.rotateHandle.on("pointerdown",t=>this.startDrag("rotate",t)),this.applyEditControls(),this.setupKeyboardShortcuts(),this.setupDragAndDrop()}setupKeyboardShortcuts(){window.addEventListener("keydown",e=>{if(!this.isVisible)return;let i=navigator.platform.toUpperCase().indexOf("MAC")>=0?e.metaKey:e.ctrlKey,n=e.target;n.tagName==="INPUT"||n.tagName==="TEXTAREA"||n.isContentEditable||(i&&e.key==="a"?(e.preventDefault(),this.selectAll()):i&&e.key==="d"?(e.preventDefault(),this.duplicateSelected()):i&&e.key==="c"?(e.preventDefault(),this.copySelected()):i&&e.key==="v"?(e.preventDefault(),this.pasteObjects()):e.key==="Escape"?(this.setSelected(null),this.selectedIds.clear(),this.updateGizmos()):(e.key==="Delete"||e.key==="Backspace")&&this.selectedIds.size>0?(e.preventDefault(),this.deleteSelectedObjects()):e.key==="g"||e.key==="G"?(e.preventDefault(),this.toggleGrid()):e.shiftKey&&(e.key==="g"||e.key==="G")&&(e.preventDefault(),this.toggleSnapToGrid()))})}async duplicateSelected(){if(this.selectedIds.size===0)return;let e=window.__HANDLER_ACTIVE_SCREEN,t=e==="loading"||e==="start"||e==="gameplay"||e==="tutorial"||e==="endgame"?e:"gameplay",i=Array.from(this.selectedIds),n=[];for(let a of i)try{let s=`${a}_copy_${Date.now()}`,o=await fetch("/api/objects/duplicate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sourceId:a,newInstanceId:s,shareConfig:!1,screenId:t})}),l=await o.json();o.ok&&l.success&&n.push(l.newObjectId)}catch(s){console.error(`[SceneEditor] Failed to duplicate ${a}:`,s)}n.length>0&&(this.selectedIds=new Set(n),this.selectedId=n[0],this.updateGizmos(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")))}copySelected(){if(this.selectedIds.size===0)return;let e=[];for(let t of this.selectedIds){let i=this.getEditableObjectConfig(t);i&&e.push({id:t,config:i})}window.__sceneEditorClipboard={configs:e,timestamp:Date.now()},this.showToast(`\u{1F4CB} Copied ${e.length} object${e.length>1?"s":""}`,1500)}async pasteObjects(){var a,s;let e=window.__sceneEditorClipboard;if(!e||!e.configs||e.configs.length===0)return;let t=window.__HANDLER_ACTIVE_SCREEN,i=t==="loading"||t==="start"||t==="gameplay"||t==="tutorial"||t==="endgame"?t:"gameplay",n=[];for(let{id:o,config:l}of e.configs)try{let c=`${o}_paste_${Date.now()}_${Math.random().toString(36).substr(2,5)}`,d=`json.${c}`,p=JSON.parse(JSON.stringify(l));if(p.identity.id=d,p.instance_id=c,p.object_config=d,(a=p.transform)!=null&&a.position){let h=p.transform.position,f=Array.isArray(h)?h[0]:h.x||0,m=Array.isArray(h)?h[1]:h.y||0;Array.isArray(h)?p.transform.position=[f+20,m+20]:p.transform.position={x:f+20,y:m+20}}let u=await fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i,instanceId:c,objectConfigId:d,config:p,layer:((s=p.identity)==null?void 0:s.category)==="ui"?"ui":"world"})}),g=await u.json();u.ok&&g.success&&n.push(c)}catch(c){console.error(`[SceneEditor] Failed to paste ${o}:`,c)}n.length>0&&(this.selectedIds=new Set(n),this.selectedId=n[0],this.updateGizmos(),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh")),this.showToast(`\u{1F4CB} Pasted ${n.length} object${n.length>1?"s":""}`,1500))}toggleGrid(){this.gridEnabled=!this.gridEnabled,this.updateGrid();try{window.localStorage.setItem(this.getSceneStorageKey("grid_enabled"),String(this.gridEnabled))}catch{}this.showToast(this.gridEnabled?"\u{1F4D0} Grid enabled":"\u{1F4D0} Grid disabled",1e3)}toggleSnapToGrid(){this.snapToGrid=!this.snapToGrid;try{window.localStorage.setItem(this.getSceneStorageKey("snap_to_grid"),String(this.snapToGrid))}catch{}this.showToast(this.snapToGrid?"\u{1F532} Snap to grid enabled":"\u{1F532} Snap to grid disabled",1e3)}snapToGridPosition(e,t){if(!this.snapToGrid)return{x:e,y:t};let i=this.gridGap;return{x:Math.round(e/i)*i,y:Math.round(t/i)*i}}updateAlignmentGuides(e,t){var d,p,u,g;if(!this.alignmentGuidesEnabled||!e||!this.alignmentGuideLayer){this.alignmentGuideLayer&&this.alignmentGuideLayer.clear();return}let i=this.objectMap.get(e);if(!(i!=null&&i.displayObject)){this.alignmentGuideLayer.clear();return}let n=(p=(d=i.displayObject).getBounds)==null?void 0:p.call(d);if(!n){this.alignmentGuideLayer.clear();return}this.alignmentGuideLayer.clear();let a=this.camera.toLocal(new $.Point(n.x,n.y)),s=this.camera.toLocal(new $.Point(n.x+n.width,n.y+n.height)),o=(a.x+s.x)/2,l=(a.y+s.y)/2,c=5;for(let[h,f]of this.objectMap.entries()){if(h===e||!(f!=null&&f.displayObject)||f.displayObject.visible===!1)continue;let m=(g=(u=f.displayObject).getBounds)==null?void 0:g.call(u);if(!m)continue;let b=this.camera.toLocal(new $.Point(m.x,m.y)),y=this.camera.toLocal(new $.Point(m.x+m.width,m.y+m.height)),v=(b.x+y.x)/2,w=(b.y+y.y)/2;if(Math.abs(o-v)<c){let S=Math.min(a.y,b.y),A=Math.max(s.y,y.y);this.alignmentGuideLayer.moveTo(v,S),this.alignmentGuideLayer.lineTo(v,A),this.alignmentGuideLayer.stroke({width:1,color:3900150,alpha:.6})}if(Math.abs(l-w)<c){let S=Math.min(a.x,b.x),A=Math.max(s.x,y.x);this.alignmentGuideLayer.moveTo(S,w),this.alignmentGuideLayer.lineTo(A,w),this.alignmentGuideLayer.stroke({width:1,color:3900150,alpha:.6})}let T=a.x,I=s.x,M=a.y,L=s.y,j=b.x,_=y.x,P=b.y,x=y.y;if(Math.abs(T-j)<c||Math.abs(T-_)<c||Math.abs(I-j)<c||Math.abs(I-_)<c){let S=Math.abs(T-j)<c?j:Math.abs(T-_)<c?_:Math.abs(I-j)<c?j:_,A=Math.min(M,P),E=Math.max(L,x);this.alignmentGuideLayer.moveTo(S,A),this.alignmentGuideLayer.lineTo(S,E),this.alignmentGuideLayer.stroke({width:1,color:1096065,alpha:.5})}if(Math.abs(M-P)<c||Math.abs(M-x)<c||Math.abs(L-P)<c||Math.abs(L-x)<c){let S=Math.abs(M-P)<c?P:Math.abs(M-x)<c?x:Math.abs(L-P)<c?P:x,A=Math.min(T,j),E=Math.max(I,_);this.alignmentGuideLayer.moveTo(A,S),this.alignmentGuideLayer.lineTo(E,S),this.alignmentGuideLayer.stroke({width:1,color:1096065,alpha:.5})}}}selectAll(){let e=Array.from(this.objectMap.keys()).filter(t=>{let i=this.getEditableObjectConfig(t),n=this.objectMap.get(t);return!(!(n!=null&&n.displayObject)||n.displayObject.visible===!1||this.backgroundLocked&&this.isBackgroundObject(t,i,n.displayObject))});this.selectedIds=new Set(e),e.length>0&&(this.selectedId=e[0],this.updateGizmos())}deleteSelectedObjects(){let e=Array.from(this.selectedIds);for(let t of e){let i=window.__deleteObjectRequest;typeof i=="function"&&i(t)}this.selectedIds.clear(),this.selectedId=null,this.updateGizmos()}handleResize(){this.app&&(this.updateLayout(),this.hasUserCamera||this.centerCamera(),this.updateGizmos(),this.updateGrid())}adjustPositionForAnchorChange(e,t,i){var _,P,x,S,A,E;if(t==null||i==null||t===i)return;let n=this.getEditableObjectConfig(e);if(!n)return;let a=(_=n.transform)!=null?_:{};if(a.position_ratio!=null)return;let s=(P=this.getRuntimeScreenSize())!=null?P:this.getScreen();if(!(s!=null&&s.width)||!(s!=null&&s.height))return;let o=this.objectMap.get(e);if(!(o!=null&&o.displayObject))return;let l=this.isBackgroundObject(e,n,o.displayObject),c=this.getRuntimeScale(),d=o.displayObject.position.x,p=o.displayObject.position.y,u=ze(s.width,s.height,t),g=ze(s.width,s.height,i),h=u.x,f=u.y,m=g.x,b=g.y;l||(h=(u.x-s.width/2)/c,f=(u.y-s.height/2)/c,m=(g.x-s.width/2)/c,b=(g.y-s.height/2)/c);let y={x:d-h,y:p-f},v={x:d-m,y:p-b},w=a.offset,T=Array.isArray(w)?Number((x=w[0])!=null?x:0):Number((S=w==null?void 0:w.x)!=null?S:0),I=Array.isArray(w)?Number((A=w[1])!=null?A:0):Number((E=w==null?void 0:w.y)!=null?E:0),M=v.x-T,L=v.y-I,j=this.buildPositionValue(a,{x:M,y:L});this.updateManager.updateProperty(e,"transform.position",j,{refreshInspector:!0})}getPickCandidates(e){var i;let t=[];for(let[n,a]of this.objectMap.entries()){let s=a.displayObject;if(!s||s.visible===!1||this.backgroundLocked&&this.isBackgroundObject(n,this.getEditableObjectConfig(n),s))continue;let o=(i=s.getBounds)==null?void 0:i.call(s);if(!o||o.width<=0||o.height<=0||e.x<o.x||e.x>o.x+o.width||e.y<o.y||e.y>o.y+o.height)continue;let l=s.parent,c=typeof(l==null?void 0:l.zIndex)=="number"?l.zIndex:0,d=typeof s.zIndex=="number"?s.zIndex:0,p=typeof(l==null?void 0:l.getChildIndex)=="function"?l.getChildIndex(s):0,u=c*1e6+d*1e3+p;t.push({id:n,order:u})}return t.sort((n,a)=>a.order-n.order),t.map(n=>n.id)}areSameIds(e,t){if(e.length!==t.length)return!1;for(let i=0;i<e.length;i+=1)if(e[i]!==t[i])return!1;return!0}isGizmoTarget(e){return e&&this.spawnPointLayer.children.indexOf(e)!==-1?!0:e===this.moveHandle||e===this.scaleHandle||e===this.rotateHandle||e===this.gizmoOutline}restoreScenePreferences(){if(typeof window!="undefined"){try{let e=window.localStorage.getItem(this.getSceneStorageKey("grid_enabled")),t=window.localStorage.getItem(this.getSceneStorageKey("grid_gap")),i=window.localStorage.getItem(this.getSceneStorageKey("grid_alpha")),n=window.localStorage.getItem(this.getSceneStorageKey("snap_to_grid")),a=window.localStorage.getItem(this.getSceneStorageKey("background_cover")),s=window.localStorage.getItem(this.getSceneStorageKey("background_lock"));if(e!==null&&(this.gridEnabled=e==="true"),t!==null){let o=Number(t);Number.isFinite(o)&&o>2&&(this.gridGap=o)}if(i!==null){let o=Number(i);Number.isFinite(o)&&o>=0&&o<=1&&(this.gridAlpha=o)}n!==null&&(this.snapToGrid=n==="true"),a!==null&&(this.backgroundCoverEnabled=a==="true"),s!==null&&(this.backgroundLocked=s==="true")}catch{}this.updateGrid()}}getSceneStorageKey(e){let t=typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default";return`handler_preview_scene_${e}::${t}`}applyPlayModeState(e){var t;this.playModeEnabled=e,(t=this.app)!=null&&t.ticker&&(this.app.ticker.remove(this.syncFromGameObjects),e&&this.app.ticker.add(this.syncFromGameObjects)),this.applyEditControls(),this.updateLayout(),this.hasUserCamera||this.centerCamera(),this.syncFromConfig().then(()=>{this.playModeEnabled&&this.syncFromGameObjectsInternal(),this.updateGizmos(),this.updateGrid()})}applyEditControls(){this.moveHandle.eventMode="static",this.scaleHandle.eventMode="static",this.rotateHandle.eventMode="static"}schedulePostScreenSync(e){this.screenSyncRaf&&cancelAnimationFrame(this.screenSyncRaf),this.screenSyncRaf=requestAnimationFrame(()=>{this.runPostScreenSync(e)})}async runPostScreenSync(e){this.screenSyncRaf=null,this.isVisible&&this.playModeEnabled&&(this.updateLayout(e),this.hasUserCamera||this.centerCamera(),await this.syncFromConfig(),this.syncFromGameObjectsInternal(),this.updateGizmos(),this.updateGrid())}getRuntimeScreenSize(){var a,s,o,l,c,d,p;let e=window.gameApp;if(e!=null&&e.renderer){let u=e.renderer.screen,g=Number((a=u==null?void 0:u.width)!=null?a:0),h=Number((s=u==null?void 0:u.height)!=null?s:0);if(Number.isFinite(g)&&g>0&&Number.isFinite(h)&&h>0)return{width:g,height:h};let f=Number((o=e.renderer.resolution)!=null?o:1)||1,m=Number((l=e.renderer.width)!=null?l:0)/f,b=Number((c=e.renderer.height)!=null?c:0)/f;if(Number.isFinite(m)&&m>0&&Number.isFinite(b)&&b>0)return{width:m,height:b}}let t=document.querySelector(".game-container"),i=Number((d=t==null?void 0:t.dataset)==null?void 0:d.screenWidth),n=Number((p=t==null?void 0:t.dataset)==null?void 0:p.screenHeight);return Number.isFinite(i)&&i>0&&Number.isFinite(n)&&n>0?{width:i,height:n}:null}getRuntimeLayoutReference(){var a,s,o,l,c,d,p,u,g,h,f,m,b,y,v,w,T,I,M,L,j,_,P,x,S,A,E,C,O,k,R,z,D,U;let e=window.__screenManager;if(e){let F=["gameplay","start","tutorial","endgame","loading"];for(let G of F){let B=(a=e.get)==null?void 0:a.call(e,G);if(B!=null&&B.visible){let q=(s=B.getContentLayer)==null?void 0:s.call(B);if(q){let J=(o=B.x)!=null?o:0,Z=(l=B.y)!=null?l:0,H=(c=q.x)!=null?c:0,ae=(d=q.y)!=null?d:0,te=(u=(p=q.scale)==null?void 0:p.x)!=null?u:1,ie=(h=(g=q.scale)==null?void 0:g.y)!=null?h:te;return console.log("[SceneEditor] getRuntimeLayoutReference: using visible screen contentLayer",{screenId:G,contentLayerScale:{x:te,y:ie},position:{x:J+H,y:Z+ae}}),{scale:{x:te,y:ie},position:{x:J+H,y:Z+ae},pivot:q.pivot?{x:q.pivot.x,y:q.pivot.y}:void 0}}}}for(let G of F){let B=(f=e.get)==null?void 0:f.call(e,G);if(B){if(!B.visible&&typeof B.updateLayout=="function"){let J=window.gameApp;if((m=J==null?void 0:J.renderer)!=null&&m.screen){let Z=J.renderer.screen.width,H=J.renderer.screen.height;Z>0&&H>0&&B.updateLayout(Z,H)}}let q=(b=B.getContentLayer)==null?void 0:b.call(B);if(q){let J=(y=B.x)!=null?y:0,Z=(v=B.y)!=null?v:0,H=(w=q.x)!=null?w:0,ae=(T=q.y)!=null?T:0,te=(M=(I=q.scale)==null?void 0:I.x)!=null?M:1,ie=(j=(L=q.scale)==null?void 0:L.y)!=null?j:te;return console.log("[SceneEditor] getRuntimeLayoutReference: using any screen contentLayer",{screenId:G,visible:B.visible,contentLayerScale:{x:te,y:ie},position:{x:J+H,y:Z+ae}}),{scale:{x:te,y:ie},position:{x:J+H,y:Z+ae},pivot:q.pivot?{x:q.pivot.x,y:q.pivot.y}:void 0}}}}}let t=window.__mainContainer;if(t){let F=(P=(_=t.scale)==null?void 0:_.x)!=null?P:1,G=(S=(x=t.scale)==null?void 0:x.y)!=null?S:F;return console.log("[SceneEditor] getRuntimeLayoutReference: using __mainContainer",{scale:{x:F,y:G},position:{x:(A=t.position)==null?void 0:A.x,y:(E=t.position)==null?void 0:E.y}}),t}let i=window.gameApp,n=(C=i==null?void 0:i.stage)!=null?C:null;if(n){let F=(k=(O=n.scale)==null?void 0:O.x)!=null?k:1,G=(z=(R=n.scale)==null?void 0:R.y)!=null?z:F;console.log("[SceneEditor] getRuntimeLayoutReference: using gameApp.stage (fallback)",{scale:{x:F,y:G},position:{x:(D=n.position)==null?void 0:D.x,y:(U=n.position)==null?void 0:U.y}})}else console.log("[SceneEditor] getRuntimeLayoutReference: no reference found");return n}getRuntimeScale(){var i,n;let e=this.getRuntimeLayoutReference(),t=Number((n=(i=e==null?void 0:e.scale)==null?void 0:i.x)!=null?n:1);return Number.isFinite(t)&&t>0?t:Number.isFinite(this.layoutScale)&&this.layoutScale>0?this.layoutScale:1}getRuntimeParentContainer(e){var c,d,p,u,g;let t=window.gameObjectManager;if(!(t!=null&&t.get))return null;let i=t.get(e),n=((c=i==null?void 0:i.getDisplayObject)==null?void 0:c.call(i))||(i==null?void 0:i.pixiObject)||i,a=n==null?void 0:n.parent;if(!a)return null;let s=window.__screenManager;if(s){let h=["gameplay","start","tutorial","endgame","loading"];for(let f of h){let m=(d=s.get)==null?void 0:d.call(s,f);if(!m)continue;let b=(u=(p=m.getBgLayer)==null?void 0:p.call(m))!=null?u:m.bgLayer;if(b&&(a===b||typeof b.contains=="function"&&b.contains(a)))return this.bgContainer}}let o=this.getRuntimeLayoutReference(),l=(g=window.gameApp)==null?void 0:g.stage;return o&&l&&o===l?this.mainContainer:o&&typeof o.contains=="function"&&o.contains(a)?this.mainContainer:a===o||a===l?this.mainContainer:this.uiContainer}applyRuntimeTransform(e){var s,o,l,c,d,p,u,g,h,f;if(!e)return console.log("[SceneEditor] applyRuntimeTransform: no reference"),!1;let t=1,i=1,n=Number((o=(s=e.position)==null?void 0:s.x)!=null?o:0),a=Number((c=(l=e.position)==null?void 0:l.y)!=null?c:0);if(!Number.isFinite(n)||!Number.isFinite(a))return console.log("[SceneEditor] applyRuntimeTransform: invalid position",{posX:n,posY:a}),!1;if(console.log("[SceneEditor] applyRuntimeTransform: applying (scale always 1)",{scale:{x:t,y:i},position:{x:n,y:a}}),this.mainContainer.scale.set(1,1),this.uiContainer.scale.set(1,1),this.mainContainer.position.set(n,a),this.uiContainer.position.set(n,a),e.pivot&&((d=this.mainContainer.pivot)!=null&&d.set)&&((p=this.uiContainer.pivot)!=null&&p.set)){let m=Number((g=(u=e.pivot)==null?void 0:u.x)!=null?g:0),b=Number((f=(h=e.pivot)==null?void 0:h.y)!=null?f:0);Number.isFinite(m)&&Number.isFinite(b)&&(this.mainContainer.pivot.set(m,b),this.uiContainer.pivot.set(m,b))}return typeof e.rotation=="number"&&(this.mainContainer.rotation=e.rotation,this.uiContainer.rotation=e.rotation),!0}getEditableConfig(){return window.__editableConfig||null}getEditableObjectConfig(e){var n,a;let t=window.getEditableObjectConfig;if(typeof t=="function")return t(e);let i=this.getEditableConfig();return i!=null&&i.objects?typeof i.objects.get=="function"?(n=i.objects.get(e))!=null?n:null:(a=i.objects[e])!=null?a:null:null}getEditableObjectIds(){let e=window.getEditableObjectList;if(typeof e=="function"){let i=e();if(Array.isArray(i))return i}let t=this.getEditableConfig();return t!=null&&t.objects?typeof t.objects.keys=="function"?Array.from(t.objects.keys()):Object.keys(t.objects):[]}async syncFromConfig(e){if(!this.app)return;let t=this.getEditableConfig();if(!(t!=null&&t.objects))return;let i=e!=null&&e.length?e:this.getEditableObjectIds(),n=new Set(i);if(!e)for(let a of Array.from(this.objectMap.keys()))n.has(a)||this.removeObject(a);for(let a of i){let s=this.getEditableObjectConfig(a);if(!s){this.removeObject(a);continue}await this.upsertObject(a,s)}this.updateGizmos(),this.updateSpawnPointHandles(),this.updateGameFrame(this.getScreen())}removeObject(e){var i,n;let t=this.objectMap.get(e);if(t){try{(n=(i=t.displayObject)==null?void 0:i.destroy)==null||n.call(i)}catch{}this.objectMap.delete(e),this.selectedId===e&&this.setSelected(null,{silent:!0})}}async upsertObject(e,t){let i=this.getAssetKey(t),n=this.objectMap.get(e),a=this.isUiConfig(e,t),s=this.playModeEnabled?this.getRuntimeParentContainer(e):null,l=this.isBackgroundObject(e,t)?this.bgContainer:a?this.uiContainer:this.mainContainer,c=s!=null?s:l;if(!n||n.assetKey!==i||n.isUi!==a){n&&this.removeObject(e);let p=await this.createDisplayObject(e,t);if(!p)return;c.addChild(p),this.objectMap.set(e,{id:e,displayObject:p,assetKey:i,isUi:a}),this.attachObjectInteraction(p,e)}let d=this.objectMap.get(e);d&&(d.displayObject.parent!==c&&c.addChild(d.displayObject),this.applyVisualConfig(d.displayObject,t),this.playModeEnabled||this.applyTransformFromConfig(e,d.displayObject,t))}async createDisplayObject(e,t){var o,l,c,d,p,u,g,h,f,m,b,y,v,w,T;if((o=t==null?void 0:t.render)!=null&&o.asset)try{if(((c=(l=t==null?void 0:t.render)==null?void 0:l.asset)==null?void 0:c.type)!=="json"){let M=await ve.create(e,t,this.app);if(M instanceof $.Container)return M}}catch(I){console.warn("[SceneEditor] ObjectFactory failed for",e,I)}let i=t==null?void 0:t.ui,n=(d=t==null?void 0:t.render)!=null?d:{},a=(i==null?void 0:i.text)||(i==null?void 0:i.kind)==="text";if(!!n.background_color){let I=this.getScreen(),M=(p=I==null?void 0:I.width)!=null?p:0,L=(u=I==null?void 0:I.height)!=null?u:0,j=new $.Graphics,_=this.parseColor(n.background_color,0),P=typeof n.background_alpha=="number"?n.background_alpha:1;M>0&&L>0&&j.rect(0,0,M,L).fill({color:_,alpha:P});let x=new $.Container;return x.addChild(j),x}if(a){let I=(h=(g=i==null?void 0:i.color)!=null?g:n==null?void 0:n.tint)!=null?h:"#ffffff",M=new $.TextStyle({fontFamily:"Arial, sans-serif",fontSize:(f=i==null?void 0:i.fontSize)!=null?f:16,fill:I,align:(m=i==null?void 0:i.align)!=null?m:"center",letterSpacing:(b=i==null?void 0:i.letterSpacing)!=null?b:0});return new $.Text({text:(y=i==null?void 0:i.text)!=null?y:"",style:M})}if((v=t==null?void 0:t.effects)!=null&&v.width||(w=t==null?void 0:t.effects)!=null&&w.height){let I=new $.Graphics,M=typeof t.effects.width=="number"?t.effects.width:100,L=typeof t.effects.height=="number"?t.effects.height:100,j=(T=t.effects.fill_color)!=null?T:"#ffffff",_=typeof t.effects.fill_alpha=="number"?t.effects.fill_alpha:1,P=Number.parseInt(String(j).replace("#",""),16);return I.rect(0,0,M,L).fill({color:Number.isFinite(P)?P:16777215,alpha:_}),I}return new $.Container}attachObjectInteraction(e,t){if(e&&(e.eventMode="static",e.cursor="pointer",!e.hitArea&&typeof e.getLocalBounds=="function")){let i=e.getLocalBounds();i&&i.width>0&&i.height>0&&(e.hitArea=new $.Rectangle(i.x,i.y,i.width,i.height))}}getAssetKey(e){var i;let t=(i=e==null?void 0:e.render)==null?void 0:i.asset;return t?`${t.type||"asset"}::${t.path||""}`:null}isUiConfig(e,t){var a,s;let i=(((a=t==null?void 0:t.identity)==null?void 0:a.category)||"").toString().toLowerCase(),n=(((s=t==null?void 0:t.identity)==null?void 0:s.id)||e||"").toString().toLowerCase();return i.includes("ui")||n.startsWith("ui")||n.includes("label")}isBackgroundObject(e,t,i){var s,o;if((i==null?void 0:i.parent)===this.bgContainer)return!0;let n=(((s=t==null?void 0:t.identity)==null?void 0:s.category)||"").toString().toLowerCase(),a=(((o=t==null?void 0:t.identity)==null?void 0:o.id)||e||"").toString().toLowerCase();return!!(n.includes("bg")||n.includes("background")||a.startsWith("background_")||a.includes("background"))}applyVisualConfig(e,t){var a,s,o;if(!e)return;let i=(a=t==null?void 0:t.render)!=null?a:{};typeof i.alpha=="number"&&(e.alpha=i.alpha),e.visible=i.visible!==!1,e.zIndex=typeof i.z_index=="number"?i.z_index:0;let n={x:.5,y:.5};if((s=e.anchor)!=null&&s.set)e.anchor.set(n.x,n.y);else if(e.pivot){let l=(o=e.getLocalBounds)==null?void 0:o.call(e);l&&e.pivot.set(l.width*n.x,l.height*n.y)}}applyTransformFromConfig(e,t,i){var M,L,j,_,P,x,S,A,E,C,O,k,R,z,D,U,F,G,B,q,J;if(!t)return;let n=this.getScreen();if(!(n!=null&&n.width)||!(n!=null&&n.height))return;let a=(M=i==null?void 0:i.transform)!=null?M:{},s=this.getPositioningAnchor(e,a),o=a==null?void 0:a.position_ratio,l=a==null?void 0:a.position,c=a==null?void 0:a.offset,d=Array.isArray(l)?Number((L=l[0])!=null?L:0):Number((j=l==null?void 0:l.x)!=null?j:0),p=Array.isArray(l)?Number((_=l[1])!=null?_:0):Number((P=l==null?void 0:l.y)!=null?P:0),u=Array.isArray(c)?Number((x=c[0])!=null?x:0):Number((S=c==null?void 0:c.x)!=null?S:0),g=Array.isArray(c)?Number((A=c[1])!=null?A:0):Number((E=c==null?void 0:c.y)!=null?E:0),h=(Number.isFinite(d)?d:0)+(Number.isFinite(u)?u:0),f=(Number.isFinite(p)?p:0)+(Number.isFinite(g)?g:0);if(this.backgroundCoverEnabled&&this.isBackgroundObject(e,i,t)){let Z=Number((O=(C=t==null?void 0:t.texture)==null?void 0:C.width)!=null?O:0),H=Number((R=(k=t==null?void 0:t.texture)==null?void 0:k.height)!=null?R:0);if(!Number.isFinite(Z)||Z<=0||!Number.isFinite(H)||H<=0){let ge=(z=t==null?void 0:t.getLocalBounds)==null?void 0:z.call(t);Z=Number((D=ge==null?void 0:ge.width)!=null?D:0),H=Number((U=ge==null?void 0:ge.height)!=null?U:0)}if(!Number.isFinite(Z)||Z<=0||!Number.isFinite(H)||H<=0)return;(F=t.anchor)!=null&&F.set&&t.anchor.set(.5,.5),(G=t.position)!=null&&G.set?t.position.set(n.width/2,n.height/2):t.position&&(t.position.x=n.width/2,t.position.y=n.height/2);let ae=n.width/Z,te=n.height/H,ie=Math.max(ae,te);(B=t.scale)!=null&&B.set?t.scale.set(ie,ie):t.scale&&(t.scale.x=ie,t.scale.y=ie);let _e=typeof(a==null?void 0:a.rotation)=="number"?a.rotation:0;t.rotation=this.toRadians(_e);return}let m=o!=null?dt(n.width,n.height,o):ze(n.width,n.height,s),b=this.getRuntimeScale(),y=(m.x-n.width/2)/b+h,v=(m.y-n.height/2)/b+f;(q=t.position)!=null&&q.set?t.position.set(y,v):t.position&&(t.position.x=y,t.position.y=v);let T=(typeof(a==null?void 0:a.scale)=="number"?a.scale:1)*this.getRuntimeScale();(J=t.scale)!=null&&J.set?t.scale.set(T,T):t.scale&&(t.scale.x=T,t.scale.y=T);let I=typeof(a==null?void 0:a.rotation)=="number"?a.rotation:0;t.rotation=this.toRadians(I)}getAnchorLocalPoint(e,t=this.mainContainer){var d;let i=(d=this.getRuntimeScreenSize())!=null?d:this.getScreen();if(!(i!=null&&i.width)||!(i!=null&&i.height))return null;let n="top-right",a=this.getPositioningAnchor(this.selectedId,e!=null?e:{}),s=(e==null?void 0:e.position_ratio)!=null?dt(i.width,i.height,e.position_ratio):ze(i.width,i.height,a!=null?a:n);if(t===this.bgContainer)return new $.Point(s.x,s.y);let o=this.getRuntimeScale(),l=(s.x-i.width/2)/o,c=(s.y-i.height/2)/o;return new $.Point(l,c)}getPositioningAnchor(e,t){var i,n,a,s,o,l,c,d,p,u;if((t==null?void 0:t.anchor)!=null&&t.anchor!=="")return t.anchor;if(typeof window!="undefined"&&e){let g=window,h=g.__editableConfig,f=(n=(i=h==null?void 0:h.objects)==null?void 0:i.get)==null?void 0:n.call(i,e),m=(o=(a=f==null?void 0:f.transform)==null?void 0:a.anchor)!=null?o:(s=f==null?void 0:f.render)==null?void 0:s.anchor;if(m!=null&&m!=="")return m;let b=g.__editableConfigBaseline,y=(c=(l=b==null?void 0:b.objects)==null?void 0:l.get)==null?void 0:c.call(l,e),v=(u=(d=y==null?void 0:y.transform)==null?void 0:d.anchor)!=null?u:(p=y==null?void 0:y.render)==null?void 0:p.anchor;if(v!=null&&v!=="")return v}return"top-left"}getActiveScreenSize(e){var t,i;return this.playModeEnabled?(i=(t=this.getRuntimeScreenSize())!=null?t:e)!=null?i:this.getScreen():e!=null?e:this.getScreen()}updateLayout(e){var i,n,a,s,o,l,c,d,p;let t=this.getActiveScreenSize(e);if(!(!(t!=null&&t.width)||!(t!=null&&t.height))){if(console.log("[SceneEditor] updateLayout: called",{screen:{width:t.width,height:t.height},currentScale:{x:this.mainContainer.scale.x,y:this.mainContainer.scale.y}}),this.playModeEnabled){let u=this.getRuntimeLayoutReference();if(u){let g=Number((n=(i=u.position)==null?void 0:i.x)!=null?n:t.width/2),h=Number((s=(a=u.position)==null?void 0:a.y)!=null?s:t.height/2);this.mainContainer.position.set(g,h),this.uiContainer.position.set(g,h);let f=Number((l=(o=u.scale)==null?void 0:o.x)!=null?l:1);Number.isFinite(f)&&f>0&&(this.layoutScale=f)}this.bgContainer.position.set(0,0),this.bgContainer.scale.set(1,1),this.mainContainer.scale.set(1,1),this.uiContainer.scale.set(1,1)}else this.bgContainer.position.set(0,0),this.bgContainer.scale.set(1,1),this.mainContainer.position.set(t.width/2,t.height/2),this.uiContainer.position.set(t.width/2,t.height/2),this.mainContainer.scale.set(1,1),this.uiContainer.scale.set(1,1),this.mainContainer.rotation=0,this.uiContainer.rotation=0,(c=this.mainContainer.pivot)!=null&&c.set&&this.mainContainer.pivot.set(0,0),(d=this.uiContainer.pivot)!=null&&d.set&&this.uiContainer.pivot.set(0,0);console.log("[SceneEditor] updateLayout: result",{finalScale:{x:this.mainContainer.scale.x,y:this.mainContainer.scale.y},position:{x:this.mainContainer.position.x,y:this.mainContainer.position.y}}),this.screenFrame.clear(),this.screenFrame.rect(0,0,t.width,t.height),this.screenFrame.stroke({width:2,color:2894892,alpha:.5}),this.updateGameFrame(t),(p=this.app)!=null&&p.stage&&(this.app.stage.hitArea=new $.Rectangle(0,0,this.app.renderer.width,this.app.renderer.height)),this.updateSpawnPointHandles()}}updateGrid(){if(!this.app)return;if(!this.gridEnabled){this.gridLayer.clear(),this.gridLayer.visible=!0;return}let e=Math.max(4,this.gridGap),t=this.app.renderer,i=this.camera.toLocal(new $.Point(0,0)),n=this.camera.toLocal(new $.Point(t.width,t.height)),a=Math.min(i.x,n.x),s=Math.max(i.x,n.x),o=Math.min(i.y,n.y),l=Math.max(i.y,n.y),c=400,d=Math.ceil((s-a)/e),p=Math.ceil((l-o)/e),u=e*Math.max(1,Math.ceil(d/c)),g=e*Math.max(1,Math.ceil(p/c)),h=Math.floor(a/u)*u,f=Math.floor(o/g)*g;this.gridLayer.clear(),this.gridLayer.visible=!0;for(let m=h;m<=s;m+=u)this.gridLayer.moveTo(m,o),this.gridLayer.lineTo(m,l);for(let m=f;m<=l;m+=g)this.gridLayer.moveTo(a,m),this.gridLayer.lineTo(s,m);this.gridLayer.stroke({width:1,color:16777215,alpha:this.gridAlpha})}updateGameFrame(e){let t=this.getActiveScreenSize(e);if(!(t!=null&&t.width)||!(t!=null&&t.height))return;let i=t.width,n=t.height,a=0,s=0;this.lastGameFrameSize&&this.lastGameFrameSize.width===t.width&&this.lastGameFrameSize.height===t.height||(this.lastGameFrameSize={width:t.width,height:t.height},this.gameFrame.clear(),this.gameFrame.rect(a,s,i,n),this.gameFrame.stroke({width:2,color:6333946,alpha:.35}))}syncFromGameObjectsInternal(){var i,n,a,s,o,l,c,d,p;if(!this.app||!this.isVisible)return;let e=window.gameObjectManager;if(!(e!=null&&e.get))return;let t=this.dragMode||this.selectedId&&performance.now()<this.dragSyncHoldUntil?this.selectedId:null;for(let[u,g]of this.objectMap.entries()){if(t&&u===t)continue;let h=e.get(u),f=((i=h==null?void 0:h.getDisplayObject)==null?void 0:i.call(h))||(h==null?void 0:h.pixiObject)||h;if(!f)continue;let m=(a=(n=g.displayObject)==null?void 0:n.parent)!=null?a:this.mainContainer,b=new $.Point;if(typeof f.getGlobalPosition=="function"){f.getGlobalPosition(b);let I=m.toLocal(b,this.camera);g.displayObject.position.set(I.x,I.y)}else if(f.worldTransform){b.set(f.worldTransform.tx,f.worldTransform.ty);let I=m.toLocal(b,this.camera);g.displayObject.position.set(I.x,I.y)}let y=this.getWorldScale(f);if(y){let I=Number((o=(s=m.scale)==null?void 0:s.x)!=null?o:1)||1,M=Number((c=(l=m.scale)==null?void 0:l.y)!=null?c:1)||1,L=y.x/I,j=y.y/M;(d=g.displayObject.scale)!=null&&d.set?g.displayObject.scale.set(L,j):g.displayObject.scale&&(g.displayObject.scale.x=L,g.displayObject.scale.y=j)}let v=this.getWorldRotation(f);if(typeof v=="number"){let I=m?m.rotation:0,M=v-I;g.displayObject.rotation=M;let L=this.getEditableObjectConfig(u);if(L){let j=(p=L.transform)!=null?p:{};L.transform||(L.transform=j);let _=this.toDegrees(M),P=typeof j.rotation=="number"?j.rotation:0;if(Math.abs(_-P)>.01){let x=Math.round(_*100)/100;j.rotation=x}}}let w=f.parent,T=typeof(w==null?void 0:w.getChildIndex)=="function"?w.getChildIndex(f):0;typeof f.zIndex=="number"?g.displayObject.zIndex=f.zIndex:Number.isFinite(T)&&(g.displayObject.zIndex=T)}this.updateGizmos()}getWorldScale(e){var a,s;let t=(s=e==null?void 0:e.worldTransform)!=null?s:(a=e==null?void 0:e.transform)==null?void 0:a.worldTransform;if(!t)return null;let i=Math.sqrt(t.a*t.a+t.b*t.b),n=Math.sqrt(t.c*t.c+t.d*t.d);return!Number.isFinite(i)||!Number.isFinite(n)?null:{x:i,y:n}}getWorldRotation(e){var i,n;let t=(n=e==null?void 0:e.worldTransform)!=null?n:(i=e==null?void 0:e.transform)==null?void 0:i.worldTransform;if(t){let a=Math.atan2(t.b,t.a);return Number.isFinite(a)?a:null}return typeof(e==null?void 0:e.rotation)=="number"?e.rotation:null}centerCamera(){if(!this.app)return;let e=this.getActiveScreenSize();if(!(e!=null&&e.width)||!(e!=null&&e.height))return;let t=this.app.renderer.width,i=this.app.renderer.height,n=Math.max(.01,Math.min(t/e.width,i/e.height));this.cameraScale=n,this.camera.scale.set(n),this.camera.position.set((t-e.width*n)/2,(i-e.height*n)/2)}updateGizmos(){var f,m,b,y,v,w;if(!this.selectedId&&this.selectedIds.size===0||!this.isVisible){this.clearGizmos();return}if(this.selectedIds.size>1){let T=1/0,I=1/0,M=-1/0,L=-1/0,j=!1;for(let _ of this.selectedIds){let P=this.objectMap.get(_);if(!(P!=null&&P.displayObject))continue;let x=(m=(f=P.displayObject).getBounds)==null?void 0:m.call(f);if(!x||x.width<=0||x.height<=0)continue;let S=this.camera.toLocal(new $.Point(x.x,x.y)),A=this.camera.toLocal(new $.Point(x.x+x.width,x.y+x.height));T=Math.min(T,S.x,A.x),I=Math.min(I,S.y,A.y),M=Math.max(M,S.x,A.x),L=Math.max(L,S.y,A.y),j=!0}if(j){let _=M-T,P=L-I,x=T+_/2,S=I+P/2;this.gizmoOutline.clear(),this.gizmoOutline.rect(T,I,_,P),this.gizmoOutline.stroke({width:2,color:16752394,alpha:.9});for(let C of this.selectedIds){let O=this.objectMap.get(C);if(!(O!=null&&O.displayObject))continue;let k=(y=(b=O.displayObject).getBounds)==null?void 0:y.call(b);if(!k||k.width<=0||k.height<=0)continue;let R=this.camera.toLocal(new $.Point(k.x,k.y)),z=this.camera.toLocal(new $.Point(k.x+k.width,k.y+k.height)),D=z.x-R.x,U=z.y-R.y;this.gizmoOutline.rect(R.x,R.y,D,U),this.gizmoOutline.stroke({width:1,color:16752394,alpha:.5})}let A=7,E={width:2,color:988970,alpha:.6};this.moveHandle.clear(),this.moveHandle.circle(x,S,A).fill({color:2278750,alpha:.95}),this.moveHandle.stroke(E),this.moveHandle.cursor="move",this.scaleHandle.clear(),this.rotateHandle.clear()}else this.clearGizmos();return}if(!this.selectedId){this.clearGizmos();return}let e=this.objectMap.get(this.selectedId);if(!(e!=null&&e.displayObject)){this.clearGizmos();return}let t=(w=(v=e.displayObject).getBounds)==null?void 0:w.call(v);if(!t||t.width<=0||t.height<=0){this.clearGizmos();return}let i=this.camera.toLocal(new $.Point(t.x,t.y)),n=this.camera.toLocal(new $.Point(t.x+t.width,t.y+t.height)),a=n.x-i.x,s=n.y-i.y,o=i.x+a/2,l=i.y+s/2;this.gizmoOutline.clear(),this.gizmoOutline.rect(i.x,i.y,a,s),this.gizmoOutline.stroke({width:2,color:16752394,alpha:.9});let c=7,d={width:2,color:988970,alpha:.6};this.moveHandle.clear(),this.moveHandle.circle(o,l,c).fill({color:2278750,alpha:.95}),this.moveHandle.stroke(d),this.moveHandle.cursor="move";let p=i.x+a,u=i.y+s;this.scaleHandle.clear(),this.scaleHandle.rect(p-c,u-c,c*2,c*2).fill({color:3718648,alpha:.95}),this.scaleHandle.stroke(d),this.scaleHandle.cursor="nwse-resize";let g=o,h=i.y-c*2;this.rotateHandle.clear(),this.rotateHandle.circle(g,h,c).fill({color:16347926,alpha:.95}),this.rotateHandle.stroke(d),this.rotateHandle.cursor="crosshair"}clearGizmos(){this.gizmoOutline.clear(),this.moveHandle.clear(),this.scaleHandle.clear(),this.rotateHandle.clear()}updateSpawnPointHandles(){if(this.clearSpawnPointHandles(),!this.selectedId)return;let e=this.getEditableObjectConfig(this.selectedId);if(!e||!this.isSpawnerConfig(e))return;let t=this.getSpawnPoints(e);!t||t.length===0||t.forEach((i,n)=>{let a=new $.Graphics;a.circle(0,0,5).fill({color:16096779,alpha:.9}),a.circle(0,0,9).stroke({width:1,color:16096779,alpha:.45});let s=this.toCameraFromMain(i);a.position.set(s.x,s.y),a.cursor="move",a.eventMode="static",a.on("pointerdown",o=>this.startSpawnPointDrag(n,o)),this.spawnPointLayer.addChild(a)})}clearSpawnPointHandles(){this.spawnPointLayer.removeChildren().forEach(t=>{var i;(i=t.destroy)==null||i.call(t)})}isSpawnerConfig(e){var i,n;return((i=e==null?void 0:e.logic)==null?void 0:i.id)==="Spawner"?!0:String(((n=e==null?void 0:e.identity)==null?void 0:n.system_role)||"").toLowerCase().includes("spawner")}getSpawnPoints(e){var i,n;let t=(n=(i=e==null?void 0:e.logic)==null?void 0:i.props)==null?void 0:n.spawnPoints;return Array.isArray(t)?t.map(a=>{var s,o;return{x:Number((s=a==null?void 0:a.x)!=null?s:0),y:Number((o=a==null?void 0:a.y)!=null?o:0)}}):null}toCameraFromMain(e){let t=this.mainContainer.toGlobal(new $.Point(e.x,e.y)),i=new $.Point;return this.camera.toLocal(t,void 0,i),i}startSpawnPointDrag(e,t){var o,l;if(!this.selectedId)return;let i=this.getEditableObjectConfig(this.selectedId);if(!i)return;let n=this.getSpawnPoints(i);if(!n||!n[e])return;(o=t==null?void 0:t.stopPropagation)==null||o.call(t),(l=t==null?void 0:t.stopImmediatePropagation)==null||l.call(t);let a=this.getEventLocalPoint(t,this.mainContainer);if(!a)return;let s=n[e];this.spawnPointDrag={objectId:this.selectedId,index:e,offset:new $.Point(s.x-a.x,s.y-a.y),startPoints:n.map(c=>({x:c.x,y:c.y}))},window.addEventListener("pointermove",this.onSpawnPointDragMove),window.addEventListener("pointerup",this.onSpawnPointDragEnd)}updateLiveSpawnPoint(e,t,i,n){let a=this.getEditableObjectConfig(e);if(!a)return;let s=this.getSpawnPoints(a);if(!s||!s[t])return;let o=s.map((l,c)=>c===t?{x:i,y:n}:{x:l.x,y:l.y});this.setNestedValue(a,"logic.props.spawnPoints",o),this.queueLiveApply(e),this.updateSpawnPointHandles()}setSelected(e,t={}){if(!(this.selectedId===e&&this.selectedIds.size===1&&this.selectedIds.has(e||""))&&(this.selectedId=e,e?(this.selectedIds.clear(),this.selectedIds.add(e)):this.selectedIds.clear(),this.updateGizmos(),this.updateSpawnPointHandles(),!t.silent&&e)){let i=window.__previewSelectObject;typeof i=="function"&&i(e)}}startDrag(e,t){var d,p,u,g,h,f,m;if(!this.selectedId)return;let i=this.objectMap.get(this.selectedId);if(!(i!=null&&i.displayObject))return;let n=this.getEditableObjectConfig(this.selectedId);if(!n||this.backgroundLocked&&this.isBackgroundObject(this.selectedId,n,i.displayObject))return;let a=(d=n.transform)!=null?d:{},s=(p=i.displayObject.parent)!=null?p:this.mainContainer,o=this.getEventLocalPoint(t,s);if(!o)return;(u=t==null?void 0:t.stopPropagation)==null||u.call(t),(g=t==null?void 0:t.stopImmediatePropagation)==null||g.call(t);let l=this.getPositioningAnchor(this.selectedId,a);(a.anchor==null||a.anchor==="")&&this.updateManager.updateProperty(this.selectedId,"transform.anchor",l),(((h=n==null?void 0:n.render)==null?void 0:h.anchor)==null||n.render.anchor==="")&&this.updateManager.updateProperty(this.selectedId,"render.anchor",l),this.dragMode=e,this.dragContainer=s,this.dragStartPointer=new $.Point(o.x,o.y),this.dragStartPos=new $.Point(i.displayObject.position.x,i.displayObject.position.y),this.dragLastPointer=new $.Point(o.x,o.y),this.dragPointerOffset=new $.Point(i.displayObject.position.x-o.x,i.displayObject.position.y-o.y),this.dragLogged=!1;let c=(f=this.getRuntimeScreenSize())!=null?f:this.getScreen();console.log("[SceneEditor][DragStart]",{objectId:this.selectedId,mode:e,isBackground:this.isBackgroundObject(this.selectedId,n,i.displayObject),screen:c,runtimeScale:this.getRuntimeScale(),pointer:{x:o.x,y:o.y},objectPos:{x:i.displayObject.position.x,y:i.displayObject.position.y},container:s===this.bgContainer?"bg":s===this.uiContainer?"ui":"main"}),this.dragStartScale=typeof((m=i.displayObject.scale)==null?void 0:m.x)=="number"?i.displayObject.scale.x:1,this.dragStartRotation=typeof i.displayObject.rotation=="number"?i.displayObject.rotation:0,this.dragAnchorLocal=this.getAnchorLocalPoint(a,s),this.dragStartValue=this.getDragStartValue(e,a),this.dragAnchorLocal&&(this.dragStartAngle=Math.atan2(o.y-this.dragAnchorLocal.y,o.x-this.dragAnchorLocal.x),this.dragStartDistance=Math.max(1,this.distance(o,this.dragAnchorLocal))),window.addEventListener("pointermove",this.onDragMove),window.addEventListener("pointerup",this.onDragEnd)}getDragStartValue(e,t){var i,n,a;return e==="move"?(i=t==null?void 0:t.position)!=null?i:{x:0,y:0}:e==="scale"?(n=t==null?void 0:t.scale)!=null?n:1:e==="rotate"?(a=t==null?void 0:t.rotation)!=null?a:0:null}updateLiveConfigPositionForObject(e,t,i){var T,I,M,L,j,_,P,x;let n=this.getEditableObjectConfig(e);if(!n)return;let a=(T=n.transform)!=null?T:{};n.transform||(n.transform=a);let s=(I=this.getRuntimeScreenSize())!=null?I:this.getScreen();if(!(s!=null&&s.width)||!(s!=null&&s.height))return;let o=this.objectMap.get(e),l=((M=o==null?void 0:o.displayObject)==null?void 0:M.parent)===this.bgContainer,c=this.getPositioningAnchor(e,a),d=(a==null?void 0:a.position_ratio)!=null?dt(s.width,s.height,a.position_ratio):ze(s.width,s.height,c),p=d.x,u=d.y,g=t,h=i;if(!l){let S=this.getRuntimeScale();p=(d.x-s.width/2)/S,u=(d.y-s.height/2)/S,g=t/S,h=i/S}let f=g-p,m=h-u,b=(L=a.offset)!=null?L:{x:0,y:0},y=Array.isArray(b)?Number((j=b[0])!=null?j:0):Number((_=b==null?void 0:b.x)!=null?_:0),v=Array.isArray(b)?Number((P=b[1])!=null?P:0):Number((x=b==null?void 0:b.y)!=null?x:0),w=this.buildPositionValue(a,{x:f-y,y:m-v});this.updateManager.updateProperty(e,"transform.position",w,{refreshInspector:!0})}updateLiveConfigPosition(e,t){this.selectedId&&this.updateLiveConfigPositionForObject(this.selectedId,e,t)}updateLiveConfigScale(e){var a;if(!this.selectedId)return;let t=this.getEditableObjectConfig(this.selectedId);if(!t)return;let i=(a=t.transform)!=null?a:{};t.transform||(t.transform=i);let n=Math.round(e*100)/100;this.updateManager.updateProperty(this.selectedId,"transform.scale",n,{refreshInspector:!0})}updateLiveConfigRotation(e){var s;if(!this.selectedId)return;let t=this.getEditableObjectConfig(this.selectedId);if(!t)return;let i=(s=t.transform)!=null?s:{};t.transform||(t.transform=i);let n=this.toDegrees(e),a=typeof i.rotation=="number"?i.rotation:0;if(Math.abs(n-a)>.01){let o=Math.round(n*100)/100;this.updateManager.updateProperty(this.selectedId,"transform.rotation",o,{refreshInspector:!0})}}applyFinalOverride(e,t,i,n){let a=this.getEditableObjectConfig(e);a!=null&&a.transform&&this.setNestedValue(a.transform,t.replace("transform.",""),n),re({objectId:e,path:t,value:i},{persist:!0,emitEvent:!0,trackHistory:!0})}queueLiveApply(e){this.applyQueuedId=e,!this.applyQueued&&(this.applyQueued=!0,requestAnimationFrame(()=>{this.applyQueued=!1;let t=this.applyQueuedId;if(!t)return;let i=this.getEditableObjectConfig(t),n=window.applyEditableObjectConfig;typeof n=="function"&&i&&(n(t,i),window.dispatchEvent(new CustomEvent("inspector:refresh")))}))}setNestedValue(e,t,i){let n=t.split("."),a=e;for(let s=0;s<n.length-1;s+=1){let o=n[s];(!a[o]||typeof a[o]!="object")&&(a[o]={}),a=a[o]}a[n[n.length-1]]=i}buildPositionValue(e,t){let i=e==null?void 0:e.position,n=Math.round(t.x*100)/100,a=Math.round(t.y*100)/100;return Array.isArray(i)?[n,a]:{x:n,y:a}}toRadians(e){return e*Math.PI/180}toDegrees(e){return e*180/Math.PI}distance(e,t){let i=e.x-t.x,n=e.y-t.y;return Math.sqrt(i*i+n*n)}getPointerButton(e){var t,i,n;return typeof(e==null?void 0:e.button)=="number"?e.button:typeof((t=e==null?void 0:e.data)==null?void 0:t.button)=="number"?e.data.button:typeof((n=(i=e==null?void 0:e.data)==null?void 0:i.originalEvent)==null?void 0:n.button)=="number"?e.data.originalEvent.button:0}getEventGlobalPoint(e){var l,c;let t=(c=e==null?void 0:e.global)!=null?c:(l=e==null?void 0:e.data)==null?void 0:l.global;if(t)return new $.Point(t.x,t.y);if(!this.app)return null;let i=e==null?void 0:e.clientX,n=e==null?void 0:e.clientY;if(typeof i!="number"||typeof n!="number")return null;let a=this.app.canvas.getBoundingClientRect(),s=(i-a.left)*(this.app.renderer.width/a.width),o=(n-a.top)*(this.app.renderer.height/a.height);return new $.Point(s,o)}getEventLocalPoint(e,t=this.mainContainer){var a,s;if(!this.app)return null;if(typeof(e==null?void 0:e.getLocalPosition)=="function"){let o=e.getLocalPosition(t);return new $.Point(o.x,o.y)}let i=(s=e==null?void 0:e.global)!=null?s:(a=e==null?void 0:e.data)==null?void 0:a.global;if(!i)return null;let n=new $.Point;return t.toLocal(new $.Point(i.x,i.y),void 0,n),n}getPointerInContainer(e,t,i){if(!this.app)return null;let n=this.app.canvas.getBoundingClientRect(),a=(e-n.left)*(this.app.renderer.width/n.width),s=(t-n.top)*(this.app.renderer.height/n.height),o=new $.Point;return i.toLocal(new $.Point(a,s),void 0,o),o}parseColor(e,t){if(typeof e=="number"&&Number.isFinite(e))return e;if(typeof e=="string"){let i=e.trim().replace("#",""),n=Number.parseInt(i,16);if(Number.isFinite(n))return n}return t}drawSelectionBox(e,t){if(!this.selectionBox)return;this.selectionBox.clear();let i=Math.min(e.x,t.x),n=Math.max(e.x,t.x),a=Math.min(e.y,t.y),s=Math.max(e.y,t.y),o=n-i,l=s-a;this.selectionBox.rect(i,a,o,l),this.selectionBox.stroke({width:2,color:3900150,alpha:.8}),this.selectionBox.rect(i,a,o,l),this.selectionBox.fill({color:3900150,alpha:.1})}finalizeSelectionBox(e,t){var l;let i=Math.min(e.x,t.x),n=Math.max(e.x,t.x),a=Math.min(e.y,t.y),s=Math.max(e.y,t.y),o=[];for(let[c,d]of this.objectMap.entries()){let p=d.displayObject;if(!p||p.visible===!1||this.backgroundLocked&&this.isBackgroundObject(c,this.getEditableObjectConfig(c),p))continue;let u=(l=p.getBounds)==null?void 0:l.call(p);if(!u||u.width<=0||u.height<=0)continue;let g=u.x+u.width/2,h=u.y+u.height/2;g>=i&&g<=n&&h>=a&&h<=s&&o.push(c)}o.length>0&&(this.selectedIds=new Set(o),this.selectedId=o[0],this.updateGizmos())}setupDragAndDrop(){if(!this.app)return;let e=this.app.canvas;e.addEventListener("dragover",t=>{t.preventDefault(),t.stopPropagation(),this.dropZoneActive||(this.dropZoneActive=!0,this.showDropZone())}),e.addEventListener("dragleave",t=>{e.contains(t.relatedTarget)||(this.dropZoneActive=!1,this.hideDropZone())}),e.addEventListener("drop",async t=>{var d;t.preventDefault(),t.stopPropagation(),this.dropZoneActive=!1,this.hideDropZone();let n=Array.from(((d=t.dataTransfer)==null?void 0:d.files)||[]).filter(p=>p.type.startsWith("image/"));if(n.length===0)return;let a=e.getBoundingClientRect(),s=t.clientX-a.left,o=t.clientY-a.top,l=new $.Point(s/a.width*this.app.renderer.width,o/a.height*this.app.renderer.height),c=this.camera.toLocal(l);await this.handleDroppedPNGs(n,c)})}showDropZone(){if(!this.dropZoneOverlay||!this.app)return;let e=this.camera.toLocal(new $.Point(0,0)),t=this.camera.toLocal(new $.Point(this.app.renderer.width,this.app.renderer.height)),i=t.x-e.x,n=t.y-e.y;this.dropZoneOverlay.clear(),this.dropZoneOverlay.rect(e.x,e.y,i,n),this.dropZoneOverlay.fill({color:3900150,alpha:.1}),this.dropZoneOverlay.rect(e.x,e.y,i,n),this.dropZoneOverlay.stroke({width:3,color:3900150,alpha:.6}),this.dropZoneOverlay.visible=!0}hideDropZone(){this.dropZoneOverlay&&(this.dropZoneOverlay.clear(),this.dropZoneOverlay.visible=!1)}async handleDroppedPNGs(e,t){let i=window.__HANDLER_ACTIVE_SCREEN,n=i==="loading"||i==="start"||i==="gameplay"||i==="tutorial"||i==="endgame"?i:"gameplay",a=this.showToast(`Processing ${e.length} PNG${e.length>1?"s":""}...`);try{for(let s=0;s<e.length;s++){let o=e[s];await this.processDroppedPNG(o,t,n,s)}this.hideToast(a),this.showToast(`\u2705 Added ${e.length} PNG${e.length>1?"s":""} to scene`,2e3),window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh"))}catch(s){this.hideToast(a),this.showToast(`\u274C Error: ${s instanceof Error?s.message:String(s)}`,3e3),console.error("[SceneEditor] Failed to process dropped PNGs:",s)}}async processDroppedPNG(e,t,i,n){let a=await this.fileToDataUrl(e);if(!a)throw new Error(`Failed to read ${e.name}`);let s=e.name.replace(/\.[^/.]+$/,""),o=this.inferCategoryFromFilename(s),l=s.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"").toLowerCase(),c=`${l}_${Date.now()}${n>0?`_${n}`:""}`,d=`json.${c}`,p=`${l}.png`,g=await(await fetch("/api/library/save",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({category:o,filename:p,data:a,overwrite:!1})})).json();if(!g.success)throw new Error(`Failed to save ${e.name} to library: ${g.error}`);let h=this.getScreen(),f=this.getRuntimeScale(),m=(t.x-h.width/2)/f,b=(t.y-h.height/2)/f,y={identity:{id:d,category:o},transform:{anchor:"center",position:{x:m,y:b},scale:1,rotation:0},render:{z_index:0,alpha:1,visible:!0,anchor:{x:.5,y:.5},asset:{type:"image",path:g.path||`raw/library/${o}/${p}`}}},v=await fetch("/api/objects/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screenId:i,instanceId:c,objectConfigId:d,config:y,layer:o==="ui"?"ui":"world"})}),w=await v.json();if(!v.ok||!w.success)throw new Error(`Failed to create object: ${w.error||"Unknown error"}`)}inferCategoryFromFilename(e){let t=e.toLowerCase();return t.startsWith("ui_")||t.includes("button")||t.includes("label")?"ui":t.startsWith("bg_")||t.includes("background")?"backgrounds":t.includes("character")||t.includes("player")?"character":"environment"}fileToDataUrl(e){return new Promise(t=>{let i=new FileReader;i.onload=()=>t(i.result),i.onerror=()=>t(null),i.readAsDataURL(e)})}showToast(e,t=3e3){let i=document.createElement("div");return i.style.cssText=`
|
|
2337
2359
|
position: fixed;
|
|
2338
2360
|
top: 20px;
|
|
2339
2361
|
right: 20px;
|
|
@@ -2346,7 +2368,7 @@ Style guidelines: ${i.summary}`;this.promptInput.value=n,this.currentPrompt=n}}c
|
|
|
2346
2368
|
font-family: system-ui, -apple-system, sans-serif;
|
|
2347
2369
|
font-size: 14px;
|
|
2348
2370
|
pointer-events: none;
|
|
2349
|
-
`,i.textContent=e,document.body.appendChild(i),t>0&&setTimeout(()=>this.hideToast(i),t),i}hideToast(e){e&&e.parentNode&&e.parentNode.removeChild(e)}showContextMenu(e,t,i){let n=window.__HANDLER_ACTIVE_SCREEN,a=n==="loading"||n==="start"||n==="gameplay"||n==="tutorial"||n==="endgame"?n:"gameplay";new gt({objectId:e,screenId:a,onSelect:o=>{o?(this.selectedIds.clear(),this.selectedIds.add(o),this.setSelected(o),this.updateGizmos()):(this.setSelected(null),this.selectedIds.clear(),this.updateGizmos())},onRefresh:()=>{window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh"))},onClose:()=>{},onDeleteRequest:o=>{let l=window.__deleteObjectRequest;typeof l=="function"&&l(o)},onMoveRequest:(o,l)=>{let c=window.__moveObjectRequest;typeof c=="function"&&c(o,a,l)}}).open({x:t,y:i})}};var gn=class{constructor(e={}){this.isLandscape=!1;this.autoScale=1;this.userScaleMultiplier=1;this.viewMode="single";this.layoutMode="fixed";this.comparePresets=[Qe("playable-portrait"),Qe("iphone-14"),Qe("ipad-mini")];this.activeCompareId="playable-portrait";this.compareViewports=new Map;this.resizeObserver=null;this.rafFitHandle=null;this.ignoreNextWindowResize=!1;this.frameDragOffsetX=0;this.frameDragOffsetY=0;this.frameDragActive=!1;this.frameDragStartX=0;this.frameDragStartY=0;this.frameDragOriginX=0;this.frameDragOriginY=0;this.isSpaceKeyPressed=!1;this.consolePanel=null;this.consoleMessages=[];this.isConsoleOpen=!1;this.originalConsole={log:console.log.bind(console),warn:console.warn.bind(console),error:console.error.bind(console),info:console.info.bind(console)};this.sceneEditor=null;this.sceneVisiblePreference=!0;this.sceneVisible=!0;this.hasInitialFit=!1;this.isMounted=!1;this.isInitialized=!1;this.gameReady=!1;this.resizeListenersDisabled=!1;this.compareSnapshotTimer=null;this.hasUnsavedChanges=!1;this.hasForceSynced=!1;this.onWindowResize=e=>{if(this.ignoreNextWindowResize){this.ignoreNextWindowResize=!1;return}this.resizeListenersDisabled||!this.gameReady||this.scheduleFit()};this.onFrameDragMove=e=>{if(!this.frameDragActive)return;let t=e.clientX-this.frameDragStartX,i=e.clientY-this.frameDragStartY;this.frameDragOffsetX=this.frameDragOriginX+t,this.frameDragOffsetY=this.frameDragOriginY+i,this.applyFrameDrag(),this.updateDragCursor()};this.onFrameDragEnd=()=>{this.frameDragActive&&(this.frameDragActive=!1,window.removeEventListener("pointermove",this.onFrameDragMove),window.removeEventListener("pointerup",this.onFrameDragEnd),this.updateDragCursor())};this.options=e,this.currentPreset=Qe(e.defaultDevice||ki.id),this.debugPanel=new Yt,this.container=this.createShell(),this.previewContainer=this.mustQuery(".preview-container"),this.singleStage=this.mustQuery('[data-preview-stage="single"]'),this.compareStage=this.mustQuery('[data-preview-stage="compare"]'),this.frameDragger=this.mustQuery(".frame-dragger"),this.frameWrapper=this.mustQuery(".frame-wrapper"),this.deviceFrame=this.mustQuery(".device-frame"),this.gameContainer=this.mustQuery(".game-container"),this.scenePane=this.mustQuery("[data-scene-pane]"),this.sceneRoot=this.mustQuery("#scene-editor-root"),this.sceneSplitter=this.mustQuery("[data-scene-splitter]"),this.gameViewPane=this.mustQuery("[data-game-pane]"),this.lastSinglePresetId=this.currentPreset.id,this.consolePanel=this.container.querySelector(".console-panel"),this.debugPanel.initialize(this.container),this.debugPanel.setupDebugEventListeners();try{let i=window.localStorage.getItem(this.getSceneVisibilityStorageKey());this.sceneVisiblePreference=i===null?!0:i==="true"}catch{}let t="dark";try{let i=window.localStorage.getItem(this.getThemeStorageKey());(i==="light"||i==="dark")&&(t=i)}catch{}this.setTheme(t),this.sceneEditor=new un({root:this.sceneRoot,getScreen:()=>this.getScreen()}),this.sceneEditor.mount(),this.applyDeviceFrameStyles(),this.setupCompareViewports(),this.setupConsoleInterceptor(),this.setupObserversAndListeners(),this.setupFrameDragging(),this.setupSpaceKeyListener(),this.setupShortcutListeners(),this.setupUnsavedChangesIndicator(),this.setupScenePaneInteractions(),this.updateSceneVisibility(),this.setDevice(this.currentPreset.id,{suppressCallback:!0}),this.updateDockState(),this.isInitialized=!0,this.scheduleForceSync()}getShortcutKey(){return typeof navigator!="undefined"&&navigator.platform.toUpperCase().indexOf("MAC")>=0?"CMD":"CTRL"}mount(e=document.body){e.innerHTML="",e.appendChild(this.container),this.isMounted=!0,this.scheduleFit()}scheduleForceSync(){this.hasForceSynced||(this.hasForceSynced=!0,window.setTimeout(()=>{let e=window.__HANDLER_ACTIVE_SCREEN;fetch("/api/sync-screens",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({force:!0,screenId:e==="loading"||e==="start"||e==="gameplay"||e==="tutorial"||e==="endgame"?e:"gameplay"})}).catch(i=>{console.warn("[PreviewShell] Force sync on refresh failed:",i)})},250))}destroy(){if(this.disableResizeListeners(),this.resizeObserver){try{this.resizeObserver.disconnect()}catch{}this.resizeObserver=null}window.removeEventListener("resize",this.onWindowResize),this.rafFitHandle&&(cancelAnimationFrame(this.rafFitHandle),this.rafFitHandle=null),this.compareSnapshotTimer&&(window.clearInterval(this.compareSnapshotTimer),this.compareSnapshotTimer=null),this.gameReady=!1,this.sceneEditor&&(this.sceneEditor.destroy(),this.sceneEditor=null)}getGameContainer(){return this.gameContainer}getScreen(){let e=this.getEffectivePreset();return{width:e.width,height:e.height}}getEffectivePreset(){var e;return this.isLandscape?{...this.currentPreset,width:this.currentPreset.height,height:this.currentPreset.width,ratio:((e=this.currentPreset.ratio)==null?void 0:e.split(":").reverse().join(":"))||this.currentPreset.ratio}:this.currentPreset}notifyGameLoaded(){var e;this.gameReady=!0,this.enableResizeListeners(),this.scheduleFit(),this.debugPanel.refresh(),(e=this.sceneEditor)==null||e.refresh(),requestAnimationFrame(()=>this.updatePanelPositions())}notifyGameDestroyed(){this.gameReady=!1,this.disableResizeListeners()}disableResizeListeners(){this.resizeListenersDisabled=!0,this.rafFitHandle&&(cancelAnimationFrame(this.rafFitHandle),this.rafFitHandle=null)}enableResizeListeners(){this.resizeListenersDisabled=!1}refresh(){this.options.onRefresh?this.options.onRefresh():window.location.reload()}setDevice(e,t={}){var n,a;let i=this.userScaleMultiplier;this.isLandscape=!1,this.currentPreset=Qe(e),this.viewMode==="single"&&(this.lastSinglePresetId=this.currentPreset.id),this.applyPresetDimensions(),this.fitToScreen({keepUserScaleMultiplier:i}),t.suppressCallback||(a=(n=this.options).onDeviceChange)==null||a.call(n,this.getEffectivePreset()),this.emitScreenChange()}setTheme(e){e==="dark"?this.container.classList.add("theme-dark"):this.container.classList.remove("theme-dark");try{window.localStorage.setItem(this.getThemeStorageKey(),e)}catch{}let t=this.container.querySelector("#theme-select");t&&(t.value=e),requestAnimationFrame(()=>this.updatePanelPositions())}setLayoutMode(e){if(this.layoutMode===e)return;this.layoutMode=e,this.container.classList.toggle("layout-fixed",e==="fixed"),this.container.classList.toggle("layout-draggable",e==="draggable"),Array.from(this.container.querySelectorAll("[data-layout-toggle]")).forEach(n=>n.classList.toggle("active",n.dataset.layoutToggle===e)),Array.from(this.container.querySelectorAll(".debug-workbench, .scene-panel")).forEach(n=>{n.style.left="",n.style.top="",n.style.width="",n.style.height="",n.style.zIndex=""}),this.scheduleFit(),this.updateDockState(),this.updatePanelPositions(),this.updateSceneVisibility(),window.dispatchEvent(new CustomEvent("inspector:refresh"))}updateDockState(){let e=this.container.querySelector("#bottom-dock");e==null||e.classList.remove("hidden");let t=this.container.querySelector("#console-messages"),i=this.container.querySelector("#dock-console-content");t&&i&&t.parentElement!==i&&i.appendChild(t)}makeBottomDockResizable(e,t){let i,n,a=o=>{let l=o.clientY-i,c=Math.max(100,Math.min(800,n-l));e.style.height=`${c}px`;let d=this.autoScale*this.userScaleMultiplier;this.fitToScreen({keepVisibleScale:d})},r=()=>{document.removeEventListener("pointermove",a),document.removeEventListener("pointerup",r),e.classList.remove("resizing")};t.addEventListener("pointerdown",o=>{o.preventDefault(),i=o.clientY,n=e.offsetHeight,document.addEventListener("pointermove",a),document.addEventListener("pointerup",r),e.classList.add("resizing")})}makeSidebarResizable(e,t,i){let n,a,r=()=>{let c=this.container.querySelector(".preview-main");if(!c)return 600;let p=c.getBoundingClientRect().width,u=i==="left"?this.container.querySelector(".debug-workbench"):this.container.querySelector(".scene-panel.scene-objects"),g=u?u.offsetWidth:i==="left"?350:300,f=p-g-200;return Math.max(200,f)},o=c=>{let d=i==="left"?c.clientX-n:n-c.clientX,p=r(),u=Math.max(200,Math.min(p,a+d));e.style.width=`${u}px`;let g=this.container.querySelector(".preview-main");if(g){let f=i==="left"?`${u}px`:g.style.gridTemplateColumns.split(" ")[0]||"300px",m=i==="right"?`${u}px`:g.style.gridTemplateColumns.split(" ")[2]||"350px",b=400;g.style.gridTemplateColumns=`${f} minmax(${b}px, 1fr) ${m}`}let h=this.autoScale*this.userScaleMultiplier;this.fitToScreen({keepVisibleScale:h})},l=()=>{document.removeEventListener("pointermove",o),document.removeEventListener("pointerup",l),e.classList.remove("resizing")};t.addEventListener("pointerdown",c=>{c.preventDefault(),n=c.clientX,a=e.offsetWidth,document.addEventListener("pointermove",o),document.addEventListener("pointerup",l),e.classList.add("resizing")})}getSceneVisibilityStorageKey(){return`handler_preview_scene_visible::${typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default"}`}getSceneWidthStorageKey(){return`handler_preview_scene_width::${typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default"}`}getThemeStorageKey(){return`handler_preview_theme::${typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default"}`}setupScenePaneInteractions(){let e=this.scenePane.querySelector("[data-scene-drag-handle]"),t=this.scenePane.querySelector("[data-scene-resize]"),i=this.container.querySelector("[data-preview-split]");e&&et(this.scenePane,e,i!=null?i:this.previewContainer),t&&cn(this.scenePane,t,void 0,260,200);let n=this.getStoredSceneWidth();n&&(this.scenePane.style.width=`${n}px`),this.sceneSplitter.addEventListener("pointerdown",a=>{if(this.layoutMode!=="fixed"||!this.sceneVisible)return;a.preventDefault();let r=a.clientX,o=this.scenePane.offsetWidth,l=Math.max(260,Math.min(720,this.previewContainer.clientWidth*.6)),c=p=>{let u=p.clientX-r,g=Math.max(240,Math.min(l,o+u));this.scenePane.style.width=`${g}px`;let h=this.autoScale*this.userScaleMultiplier;this.fitToScreen({keepVisibleScale:h})},d=()=>{document.removeEventListener("pointermove",c),document.removeEventListener("pointerup",d),this.storeSceneWidth(this.scenePane.offsetWidth)};document.addEventListener("pointermove",c),document.addEventListener("pointerup",d)})}storeSceneWidth(e){try{window.localStorage.setItem(this.getSceneWidthStorageKey(),String(e))}catch{}}getStoredSceneWidth(){try{let e=window.localStorage.getItem(this.getSceneWidthStorageKey()),t=e?Number(e):null;return Number.isFinite(t)&&t?t:null}catch{return null}}updateSceneVisibility(){let e=this.viewMode==="single"&&this.sceneVisiblePreference;this.setSceneVisible(e,{persist:!1});let t=this.container.querySelector("#scene-toggle");t&&(t.classList.toggle("active",this.sceneVisiblePreference),t.setAttribute("aria-pressed",String(this.sceneVisiblePreference)))}setSceneVisible(e,t={}){var i;if(this.sceneVisible=e,this.container.classList.toggle("scene-hidden",!e),(i=this.sceneEditor)==null||i.setVisible(e),t.persist!==!1){this.sceneVisiblePreference=e;try{window.localStorage.setItem(this.getSceneVisibilityStorageKey(),String(e))}catch{}}this.scheduleFit()}createShell(){var t;let e=document.createElement("div");return e.className="preview-shell layout-fixed",e.innerHTML=`
|
|
2371
|
+
`,i.textContent=e,document.body.appendChild(i),t>0&&setTimeout(()=>this.hideToast(i),t),i}hideToast(e){e&&e.parentNode&&e.parentNode.removeChild(e)}showContextMenu(e,t,i){let n=window.__HANDLER_ACTIVE_SCREEN,a=n==="loading"||n==="start"||n==="gameplay"||n==="tutorial"||n==="endgame"?n:"gameplay";new gt({objectId:e,screenId:a,onSelect:o=>{o?(this.selectedIds.clear(),this.selectedIds.add(o),this.setSelected(o),this.updateGizmos()):(this.setSelected(null),this.selectedIds.clear(),this.updateGizmos())},onRefresh:()=>{window.dispatchEvent(new CustomEvent("handler:scene-objects-refresh"))},onClose:()=>{},onDeleteRequest:o=>{let l=window.__deleteObjectRequest;typeof l=="function"&&l(o)},onMoveRequest:(o,l)=>{let c=window.__moveObjectRequest;typeof c=="function"&&c(o,a,l)}}).open({x:t,y:i})}};var gn=class{constructor(e={}){this.isLandscape=!1;this.autoScale=1;this.userScaleMultiplier=1;this.viewMode="single";this.layoutMode="fixed";this.comparePresets=[Qe("playable-portrait"),Qe("iphone-14"),Qe("ipad-mini")];this.activeCompareId="playable-portrait";this.compareViewports=new Map;this.resizeObserver=null;this.rafFitHandle=null;this.ignoreNextWindowResize=!1;this.frameDragOffsetX=0;this.frameDragOffsetY=0;this.frameDragActive=!1;this.frameDragStartX=0;this.frameDragStartY=0;this.frameDragOriginX=0;this.frameDragOriginY=0;this.isSpaceKeyPressed=!1;this.consolePanel=null;this.consoleMessages=[];this.isConsoleOpen=!1;this.originalConsole={log:console.log.bind(console),warn:console.warn.bind(console),error:console.error.bind(console),info:console.info.bind(console)};this.sceneEditor=null;this.sceneVisiblePreference=!0;this.sceneVisible=!0;this.hasInitialFit=!1;this.isMounted=!1;this.isInitialized=!1;this.gameReady=!1;this.resizeListenersDisabled=!1;this.compareSnapshotTimer=null;this.hasUnsavedChanges=!1;this.hasForceSynced=!1;this.onWindowResize=e=>{if(this.ignoreNextWindowResize){this.ignoreNextWindowResize=!1;return}this.resizeListenersDisabled||!this.gameReady||(this.scheduleFit(),this.updateBottomDockHeight())};this.onFrameDragMove=e=>{if(!this.frameDragActive)return;let t=e.clientX-this.frameDragStartX,i=e.clientY-this.frameDragStartY;this.frameDragOffsetX=this.frameDragOriginX+t,this.frameDragOffsetY=this.frameDragOriginY+i,this.applyFrameDrag(),this.updateDragCursor()};this.onFrameDragEnd=()=>{this.frameDragActive&&(this.frameDragActive=!1,window.removeEventListener("pointermove",this.onFrameDragMove),window.removeEventListener("pointerup",this.onFrameDragEnd),this.updateDragCursor())};this.options=e,this.currentPreset=Qe(e.defaultDevice||ki.id),this.debugPanel=new Yt,this.container=this.createShell(),this.previewContainer=this.mustQuery(".preview-container"),this.singleStage=this.mustQuery('[data-preview-stage="single"]'),this.compareStage=this.mustQuery('[data-preview-stage="compare"]'),this.frameDragger=this.mustQuery(".frame-dragger"),this.frameWrapper=this.mustQuery(".frame-wrapper"),this.deviceFrame=this.mustQuery(".device-frame"),this.gameContainer=this.mustQuery(".game-container"),this.scenePane=this.mustQuery("[data-scene-pane]"),this.sceneRoot=this.mustQuery("#scene-editor-root"),this.sceneSplitter=this.mustQuery("[data-scene-splitter]"),this.gameViewPane=this.mustQuery("[data-game-pane]"),this.lastSinglePresetId=this.currentPreset.id,this.consolePanel=this.container.querySelector(".console-panel"),this.debugPanel.initialize(this.container),this.debugPanel.setupDebugEventListeners();try{let i=window.localStorage.getItem(this.getSceneVisibilityStorageKey());this.sceneVisiblePreference=i===null?!0:i==="true"}catch{}let t="dark";try{let i=window.localStorage.getItem(this.getThemeStorageKey());(i==="light"||i==="dark")&&(t=i)}catch{}this.setTheme(t),this.sceneEditor=new un({root:this.sceneRoot,getScreen:()=>this.getScreen()}),this.sceneEditor.mount(),this.applyDeviceFrameStyles(),this.setupCompareViewports(),this.setupConsoleInterceptor(),this.setupObserversAndListeners(),this.setupFrameDragging(),this.setupSpaceKeyListener(),this.setupShortcutListeners(),this.setupUnsavedChangesIndicator(),this.setupScenePaneInteractions(),this.updateSceneVisibility(),this.setDevice(this.currentPreset.id,{suppressCallback:!0}),this.updateDockState(),this.updateBottomDockHeight(),this.isInitialized=!0,this.scheduleForceSync()}getShortcutKey(){return typeof navigator!="undefined"&&navigator.platform.toUpperCase().indexOf("MAC")>=0?"CMD":"CTRL"}mount(e=document.body){e.innerHTML="",e.appendChild(this.container),this.isMounted=!0,this.scheduleFit()}scheduleForceSync(){this.hasForceSynced||(this.hasForceSynced=!0,window.setTimeout(()=>{let e=window.__HANDLER_ACTIVE_SCREEN;fetch("/api/sync-screens",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({force:!0,screenId:e==="loading"||e==="start"||e==="gameplay"||e==="tutorial"||e==="endgame"?e:"gameplay"})}).catch(i=>{console.warn("[PreviewShell] Force sync on refresh failed:",i)})},250))}destroy(){if(this.disableResizeListeners(),this.resizeObserver){try{this.resizeObserver.disconnect()}catch{}this.resizeObserver=null}window.removeEventListener("resize",this.onWindowResize),this.rafFitHandle&&(cancelAnimationFrame(this.rafFitHandle),this.rafFitHandle=null),this.compareSnapshotTimer&&(window.clearInterval(this.compareSnapshotTimer),this.compareSnapshotTimer=null),this.gameReady=!1,this.sceneEditor&&(this.sceneEditor.destroy(),this.sceneEditor=null)}getGameContainer(){return this.gameContainer}getScreen(){let e=this.getEffectivePreset();return{width:e.width,height:e.height}}getEffectivePreset(){var e;return this.isLandscape?{...this.currentPreset,width:this.currentPreset.height,height:this.currentPreset.width,ratio:((e=this.currentPreset.ratio)==null?void 0:e.split(":").reverse().join(":"))||this.currentPreset.ratio}:this.currentPreset}notifyGameLoaded(){var e;this.gameReady=!0,this.enableResizeListeners(),this.scheduleFit(),this.debugPanel.refresh(),(e=this.sceneEditor)==null||e.refresh(),requestAnimationFrame(()=>this.updatePanelPositions())}notifyGameDestroyed(){this.gameReady=!1,this.disableResizeListeners()}disableResizeListeners(){this.resizeListenersDisabled=!0,this.rafFitHandle&&(cancelAnimationFrame(this.rafFitHandle),this.rafFitHandle=null)}enableResizeListeners(){this.resizeListenersDisabled=!1}refresh(){this.options.onRefresh?this.options.onRefresh():window.location.reload()}setDevice(e,t={}){var n,a;let i=this.userScaleMultiplier;this.isLandscape=!1,this.currentPreset=Qe(e),this.viewMode==="single"&&(this.lastSinglePresetId=this.currentPreset.id),this.applyPresetDimensions(),this.fitToScreen({keepUserScaleMultiplier:i}),t.suppressCallback||(a=(n=this.options).onDeviceChange)==null||a.call(n,this.getEffectivePreset()),this.emitScreenChange()}setTheme(e){e==="dark"?this.container.classList.add("theme-dark"):this.container.classList.remove("theme-dark");try{window.localStorage.setItem(this.getThemeStorageKey(),e)}catch{}let t=this.container.querySelector("#theme-select");t&&(t.value=e),requestAnimationFrame(()=>this.updatePanelPositions())}setLayoutMode(e){if(this.layoutMode===e)return;this.layoutMode=e,this.container.classList.toggle("layout-fixed",e==="fixed"),this.container.classList.toggle("layout-draggable",e==="draggable"),Array.from(this.container.querySelectorAll("[data-layout-toggle]")).forEach(n=>n.classList.toggle("active",n.dataset.layoutToggle===e)),Array.from(this.container.querySelectorAll(".debug-workbench, .scene-panel")).forEach(n=>{n.style.left="",n.style.top="",n.style.width="",n.style.height="",n.style.zIndex=""}),this.scheduleFit(),this.updateDockState(),this.updatePanelPositions(),this.updateSceneVisibility(),window.dispatchEvent(new CustomEvent("inspector:refresh"))}updateDockState(){let e=this.container.querySelector("#bottom-dock");e==null||e.classList.remove("hidden");let t=this.container.querySelector("#console-messages"),i=this.container.querySelector("#dock-console-content");t&&i&&t.parentElement!==i&&i.appendChild(t)}makeBottomDockResizable(e,t){let i,n,a=null,s=l=>{let c=l.clientY-i,d=Math.max(100,Math.min(800,n-c));e.style.height=`${d}px`;let p=window.innerHeight;a=d/p*100;try{window.localStorage.setItem("preview_bottom_dock_height_percent",String(a))}catch{}let u=this.autoScale*this.userScaleMultiplier;this.fitToScreen({keepVisibleScale:u})},o=()=>{document.removeEventListener("pointermove",s),document.removeEventListener("pointerup",o),e.classList.remove("resizing")};t.addEventListener("pointerdown",l=>{l.preventDefault(),i=l.clientY,n=e.offsetHeight,document.addEventListener("pointermove",s),document.addEventListener("pointerup",o),e.classList.add("resizing")})}updateBottomDockHeight(){let e=this.container.querySelector("#bottom-dock");if(!e||e.classList.contains("resizing"))return;try{let a=window.localStorage.getItem("preview_bottom_dock_height_percent");if(a){let s=Number(a);if(Number.isFinite(s)&&s>0){let o=window.innerHeight,l=Math.max(100,Math.min(800,s/100*o));e.style.height=`${l}px`;return}}}catch{}let t=e.offsetHeight,i=window.innerHeight,n=Math.min(800,i*.5);t>n&&(e.style.height=`${n}px`)}makeSidebarResizable(e,t,i){let n,a,s=()=>{let c=this.container.querySelector(".preview-main");if(!c)return 600;let p=c.getBoundingClientRect().width,u=i==="left"?this.container.querySelector(".debug-workbench"):this.container.querySelector(".scene-panel.scene-objects"),g=u?u.offsetWidth:i==="left"?350:300,f=p-g-200;return Math.max(200,f)},o=c=>{let d=i==="left"?c.clientX-n:n-c.clientX,p=s(),u=Math.max(200,Math.min(p,a+d));e.style.width=`${u}px`;let g=this.container.querySelector(".preview-main");if(g){let f=i==="left"?`${u}px`:g.style.gridTemplateColumns.split(" ")[0]||"300px",m=i==="right"?`${u}px`:g.style.gridTemplateColumns.split(" ")[2]||"350px",b=400;g.style.gridTemplateColumns=`${f} minmax(${b}px, 1fr) ${m}`}let h=this.autoScale*this.userScaleMultiplier;this.fitToScreen({keepVisibleScale:h})},l=()=>{document.removeEventListener("pointermove",o),document.removeEventListener("pointerup",l),e.classList.remove("resizing")};t.addEventListener("pointerdown",c=>{c.preventDefault(),n=c.clientX,a=e.offsetWidth,document.addEventListener("pointermove",o),document.addEventListener("pointerup",l),e.classList.add("resizing")})}getSceneVisibilityStorageKey(){return`handler_preview_scene_visible::${typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default"}`}getSceneWidthStorageKey(){return`handler_preview_scene_width::${typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default"}`}getThemeStorageKey(){return`handler_preview_theme::${typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default"}`}setupScenePaneInteractions(){let e=this.scenePane.querySelector("[data-scene-drag-handle]"),t=this.scenePane.querySelector("[data-scene-resize]"),i=this.container.querySelector("[data-preview-split]");e&&et(this.scenePane,e,i!=null?i:this.previewContainer),t&&cn(this.scenePane,t,void 0,260,200);let n=this.getStoredSceneWidth();n&&(this.scenePane.style.width=`${n}px`),this.sceneSplitter.addEventListener("pointerdown",a=>{if(this.layoutMode!=="fixed"||!this.sceneVisible)return;a.preventDefault();let s=a.clientX,o=this.scenePane.offsetWidth,l=Math.max(260,Math.min(720,this.previewContainer.clientWidth*.6)),c=p=>{let u=p.clientX-s,g=Math.max(240,Math.min(l,o+u));this.scenePane.style.width=`${g}px`;let h=this.autoScale*this.userScaleMultiplier;this.fitToScreen({keepVisibleScale:h})},d=()=>{document.removeEventListener("pointermove",c),document.removeEventListener("pointerup",d),this.storeSceneWidth(this.scenePane.offsetWidth)};document.addEventListener("pointermove",c),document.addEventListener("pointerup",d)})}storeSceneWidth(e){try{window.localStorage.setItem(this.getSceneWidthStorageKey(),String(e))}catch{}}getStoredSceneWidth(){try{let e=window.localStorage.getItem(this.getSceneWidthStorageKey()),t=e?Number(e):null;return Number.isFinite(t)&&t?t:null}catch{return null}}updateSceneVisibility(){let e=this.viewMode==="single"&&this.sceneVisiblePreference;this.setSceneVisible(e,{persist:!1});let t=this.container.querySelector("#scene-toggle");t&&(t.classList.toggle("active",this.sceneVisiblePreference),t.setAttribute("aria-pressed",String(this.sceneVisiblePreference)))}setSceneVisible(e,t={}){var i;if(this.sceneVisible=e,this.container.classList.toggle("scene-hidden",!e),(i=this.sceneEditor)==null||i.setVisible(e),t.persist!==!1){this.sceneVisiblePreference=e;try{window.localStorage.setItem(this.getSceneVisibilityStorageKey(),String(e))}catch{}}this.scheduleFit()}createShell(){var t;let e=document.createElement("div");return e.className="preview-shell layout-fixed",e.innerHTML=`
|
|
2350
2372
|
<div class="preview-toolbar">
|
|
2351
2373
|
<div class="preview-toolbar-left">
|
|
2352
2374
|
<span class="preview-logo">PREVIEWER</span>
|
|
@@ -2538,7 +2560,7 @@ Style guidelines: ${i.summary}`;this.promptInput.value=n,this.currentPrompt=n}}c
|
|
|
2538
2560
|
</div>
|
|
2539
2561
|
|
|
2540
2562
|
</div>
|
|
2541
|
-
`,this.setupEventListeners(e),e}setupEventListeners(e){var I,M,L,j,_,P,x,S;let t=e.querySelector("#device-select");t==null||t.addEventListener("change",A=>{if(this.viewMode==="compare")return;let E=A.target.value;this.setDevice(E)});let i=e.querySelector("#theme-select");i==null||i.addEventListener("change",A=>{let E=A.target.value;this.setTheme(E)}),Array.from(e.querySelectorAll("[data-view-toggle]")).forEach(A=>{A.addEventListener("click",()=>{let E=A.dataset.viewToggle;E&&this.setViewMode(E)})}),Array.from(e.querySelectorAll("[data-layout-toggle]")).forEach(A=>{A.addEventListener("click",()=>{let E=A.dataset.layoutToggle;E&&this.setLayoutMode(E)})});let r=e.querySelector("#scene-toggle");r==null||r.addEventListener("click",()=>{this.viewMode!=="compare"&&(this.setSceneVisible(!this.sceneVisiblePreference),this.updateSceneVisibility())});let o=e.querySelector("#scene-hide-btn");o==null||o.addEventListener("click",()=>{this.viewMode!=="compare"&&(this.setSceneVisible(!1),this.updateSceneVisibility())});let l=A=>{let E=typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default";return`handler_preview_scene_${A}::${E}`},c=e.querySelector("#scene-grid-btn"),d=e.querySelector("#scene-play-btn"),p=(A,E,C)=>{A&&(A.textContent=E?`${C} On`:`${C} Off`,A.setAttribute("aria-pressed",E?"true":"false"))},u=()=>{let A=window.localStorage.getItem(l("grid_gap")),E=Number(A!=null?A:50);return Number.isFinite(E)?E:50},g=A=>{try{window.localStorage.setItem(l("grid_enabled"),A?"true":"false")}catch{}p(c,A,"Grid");let E=u();window.dispatchEvent(new CustomEvent("scene-editor:grid",{detail:{enabled:A,gap:E}}))},h=A=>{try{window.localStorage.setItem(l("play_mode"),A?"true":"false")}catch{}p(d,A,"Play"),window.dispatchEvent(new CustomEvent("scene-editor:play-mode",{detail:{enabled:A}}))};try{let A=window.localStorage.getItem(l("grid_enabled"))==="true",E=!0;try{window.localStorage.setItem(l("play_mode"),"true")}catch{}if(p(c,A,"Grid"),p(d,E,"Play"),d&&(d.disabled=!0),c){let C=u();window.dispatchEvent(new CustomEvent("scene-editor:grid",{detail:{enabled:A,gap:C}}))}d&&window.dispatchEvent(new CustomEvent("scene-editor:play-mode",{detail:{enabled:E}}))}catch{}c==null||c.addEventListener("click",()=>{let A=c.getAttribute("aria-pressed")==="true";g(!A)}),d==null||d.addEventListener("click",()=>{let A=d.getAttribute("aria-pressed")==="true";h(!A)}),(I=e.querySelector("#rotate-btn"))==null||I.addEventListener("click",()=>this.toggleRotation()),(M=e.querySelector("#zoom-in-btn"))==null||M.addEventListener("click",()=>this.adjustUserZoom(.1)),(L=e.querySelector("#zoom-out-btn"))==null||L.addEventListener("click",()=>this.adjustUserZoom(-.1)),(j=e.querySelector("#refresh-btn"))==null||j.addEventListener("click",()=>this.refresh());let f=e.querySelector("#bottom-dock"),m=e.querySelector("#bottom-dock-resize");f&&m&&this.makeBottomDockResizable(f,m);let b=Array.from(e.querySelectorAll(".bottom-dock-tab"));b.forEach(A=>{A.addEventListener("click",()=>{let E=A.dataset.dockTab;if(!E)return;b.forEach(O=>O.classList.remove("active")),A.classList.add("active"),Array.from(e.querySelectorAll(".bottom-dock-panel")).forEach(O=>{let k=O.dataset.dockPanel;O.classList.toggle("active",k===E)})})}),(_=e.querySelector("#console-clear"))==null||_.addEventListener("click",()=>this.clearConsole()),(P=e.querySelector("#corner-zoom-in-btn"))==null||P.addEventListener("click",()=>this.adjustUserZoom(.1)),(x=e.querySelector("#corner-zoom-out-btn"))==null||x.addEventListener("click",()=>this.adjustUserZoom(-.1)),(S=e.querySelector("#corner-grab-btn"))==null||S.addEventListener("click",()=>{this.frameDragger.style.cursor="grab",setTimeout(()=>{this.isSpaceKeyPressed||(this.frameDragger.style.cursor="")},1e3)});let y=e.querySelector(".scene-panel.scene-objects"),v=y==null?void 0:y.querySelector("[data-panel-resize-v]");y&&v&&this.makeSidebarResizable(y,v,"left");let w=e.querySelector(".debug-workbench"),T=w==null?void 0:w.querySelector("#workbench-resize-v");w&&T&&this.makeSidebarResizable(w,T,"right")}applyDeviceFrameStyles(){Object.assign(this.frameDragger.style,{display:"flex",justifyContent:"center",alignItems:"center",transform:"translate(0px, 0px)",touchAction:"none"}),Object.assign(this.frameWrapper.style,{display:"flex",justifyContent:"center",alignItems:"center",transformOrigin:"center center",transition:"transform 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94)",boxShadow:"var(--ui-shadow-strong)",borderRadius:"0px",willChange:"transform"}),Object.assign(this.deviceFrame.style,{overflow:"hidden",position:"relative",borderRadius:"0px"}),Object.assign(this.gameContainer.style,{position:"relative",overflow:"hidden",minWidth:"0px",minHeight:"0px"})}setupObserversAndListeners(){this.resizeObserver=new ResizeObserver(()=>{this.resizeListenersDisabled||this.scheduleFit()}),this.resizeObserver.observe(this.previewContainer),window.addEventListener("resize",this.onWindowResize,{passive:!0})}scheduleFit(){this.rafFitHandle&&cancelAnimationFrame(this.rafFitHandle),this.rafFitHandle=requestAnimationFrame(()=>{this.rafFitHandle=null,this.fitToScreen()})}applyPresetDimensions(){let e=this.getEffectivePreset(),t=`${e.width}px`,i=`${e.height}px`;this.deviceFrame.style.width=t,this.deviceFrame.style.height=i,this.gameContainer.style.width=t,this.gameContainer.style.height=i,this.gameContainer.style.maxWidth=t,this.gameContainer.style.maxHeight=i,this.gameContainer.style.minWidth=t,this.gameContainer.style.minHeight=i,this.gameContainer.dataset.screenWidth=String(e.width),this.gameContainer.dataset.screenHeight=String(e.height),this.container.style.setProperty("--preview-screen-width",String(e.width)),this.container.style.setProperty("--preview-screen-height",String(e.height))}fitToScreen(e){if(!this.previewContainer)return;let t=this.getEffectivePreset(),i=this.getFitBounds(),n=Math.max(0,i.width),a=Math.max(0,i.height);if(n<=0||a<=0)return;this.applyPresetDimensions(),this.viewMode==="compare"&&this.applyCompareDimensions();let r=n/t.width,o=a/t.height;if(this.autoScale=Math.max(.01,Math.min(r,o)),!this.hasInitialFit){this.hasInitialFit=!0;let l=.6;this.userScaleMultiplier=l/this.autoScale}(e==null?void 0:e.keepUserScaleMultiplier)!==void 0&&e.keepUserScaleMultiplier>0?this.userScaleMultiplier=e.keepUserScaleMultiplier:e!=null&&e.keepVisibleScale&&e.keepVisibleScale>0&&(this.userScaleMultiplier=e.keepVisibleScale/this.autoScale),this.applyTransform(),this.viewMode==="compare"&&this.fitCompareGhosts(),requestAnimationFrame(()=>this.updatePanelPositions()),this.emitScreenChange()}applyTransform(){let e=this.autoScale*this.userScaleMultiplier;this.frameWrapper.style.transform=`scale(${e})`;let t=this.container.querySelector("#zoom-label");t&&(t.textContent=`${Math.round(e*100)}%`),requestAnimationFrame(()=>this.updatePanelPositions())}applyFrameDrag(){this.frameDragger.style.transform=`translate(${this.frameDragOffsetX}px, ${this.frameDragOffsetY}px)`,requestAnimationFrame(()=>this.updatePanelPositions())}updatePanelPositions(){if(!this.gameReady||this.viewMode==="compare")return;let e=this.container.querySelector('[data-panel="scene-tools-corner"]'),t=this.container.querySelector('[data-panel="nudge-panel"]');if(this.layoutMode==="fixed"){let i=this.gameViewPane||this.container.querySelector(".preview-container");i&&(e&&e.parentElement!==i&&i.appendChild(e),t&&t.parentElement!==i&&i.appendChild(t))}else{let i=this.container.querySelector(".preview-main");i&&(e&&e.parentElement!==i&&i.appendChild(e),t&&t.parentElement!==i&&i.appendChild(t))}e&&(e.style.zIndex="100"),t&&(t.style.position="absolute",t.style.left="50%",t.style.top="16px",t.style.transform="translateX(calc(-50% + 200px))",t.style.zIndex="100")}setupFrameDragging(){this.frameDragger.addEventListener("pointerdown",e=>{let t=!this.gameContainer.contains(e.target);!this.isSpaceKeyPressed&&!t||e.button===0&&(e.preventDefault(),this.frameDragActive=!0,this.frameDragStartX=e.clientX,this.frameDragStartY=e.clientY,this.frameDragOriginX=this.frameDragOffsetX,this.frameDragOriginY=this.frameDragOffsetY,window.addEventListener("pointermove",this.onFrameDragMove),window.addEventListener("pointerup",this.onFrameDragEnd))})}setupSpaceKeyListener(){window.addEventListener("keydown",e=>{e.code==="Space"&&!this.isInputFocused()&&(this.isSpaceKeyPressed||(this.isSpaceKeyPressed=!0,this.updateDragCursor(),e.preventDefault()))}),window.addEventListener("keyup",e=>{e.code==="Space"&&(this.isSpaceKeyPressed=!1,this.updateDragCursor(),this.frameDragActive&&this.onFrameDragEnd())}),window.addEventListener("blur",()=>{this.isSpaceKeyPressed=!1,this.updateDragCursor(),this.frameDragActive&&this.onFrameDragEnd()})}isInputFocused(){let e=document.activeElement;if(!e)return!1;let t=e.tagName.toLowerCase();return t==="input"||t==="textarea"||t==="select"||e.isContentEditable}setupShortcutListeners(){window.addEventListener("keydown",e=>{if(this.isInputFocused())return;let t=navigator.platform.toUpperCase().indexOf("MAC")>=0,i=e.ctrlKey||e.metaKey,n=e.shiftKey;if(i&&e.key==="s"&&!n){e.preventDefault();let a=document.querySelector("#apply-current-btn");a&&a.getAttribute("disabled")===null&&a.click();return}if(i&&e.key==="z"&&!n){e.preventDefault(),vi();return}if(i&&(e.key==="z"&&n||e.key==="y"&&!n)){e.preventDefault(),wi();return}})}setupUnsavedChangesIndicator(){let e=this.container.querySelector("#preview-save-shortcut-text");e&&(e.textContent=`(${this.getShortcutKey()} + S)`),window.addEventListener("config:changed",()=>{this.updateUnsavedChangesIndicator()}),this.updateUnsavedChangesIndicator();let t=this.container.querySelector("#preview-save-btn");t==null||t.addEventListener("click",()=>{let i=document.querySelector("#apply-current-btn");i&&i.getAttribute("disabled")===null&&i.click()})}updateUnsavedChangesIndicator(){let t=De().hasChanges;if(t!==this.hasUnsavedChanges){this.hasUnsavedChanges=t;let i=this.container.querySelector("#preview-unsaved-star"),n=this.container.querySelector("#preview-save-btn");i&&(i.style.display=t?"inline-block":"none"),n&&(n.style.display=t?"inline-flex":"none")}}updateDragCursor(){this.isSpaceKeyPressed?(this.frameDragger.style.cursor="grab",this.frameDragActive&&(this.frameDragger.style.cursor="grabbing")):this.frameDragger.style.cursor=""}adjustUserZoom(e){this.userScaleMultiplier=Math.max(.1,Math.min(6,this.userScaleMultiplier+e)),this.applyTransform(),this.emitScreenChange()}toggleRotation(){var t,i;if(this.viewMode==="compare")return;let e=this.userScaleMultiplier;this.isLandscape=!this.isLandscape,this.applyPresetDimensions(),this.fitToScreen({keepUserScaleMultiplier:e}),(i=(t=this.options).onDeviceChange)==null||i.call(t,this.getEffectivePreset()),this.emitScreenChange()}emitScreenChange(){if(!this.gameReady)return;let e=this.getEffectivePreset(),t={width:e.width,height:e.height,dpr:Math.max(1,Math.floor(window.devicePixelRatio||1)),presetId:e.id,isLandscape:this.isLandscape};if(window.dispatchEvent(new CustomEvent("handler-preview:screen",{detail:t})),this.viewMode==="compare"&&this.refreshCompareSnapshots(),this.isInitialized&&this.isMounted&&this.gameReady){let i=window.gameApp;if(!(i!=null&&i.renderer))return;this.ignoreNextWindowResize=!0,window.dispatchEvent(new Event("resize"))}}safeStringify(e){var i;let t=new WeakSet;try{return JSON.stringify(e,(n,a)=>{if(typeof a=="object"&&a!==null){if(t.has(a))return"[Circular]";t.add(a)}return a},2)}catch{try{if(e&&((i=e.constructor)!=null&&i.name))return`[object ${e.constructor.name}]`}catch{}return String(e)}}setupConsoleInterceptor(){let e=(t,...i)=>{let n=i.map(r=>typeof r=="object"?this.safeStringify(r):String(r)).join(" ");this.consoleMessages.push({type:t,message:n,timestamp:new Date}),this.appendConsoleMessage(this.consoleMessages[this.consoleMessages.length-1]);let a=this.container.querySelector("#console-badge");if(a){let r=this.consoleMessages.filter(o=>o.type==="error").length;a.textContent=r>0?`${r}!`:"0",a.classList.toggle("has-errors",r>0)}};console.log=(...t)=>{this.originalConsole.log(...t),e("log",...t)},console.warn=(...t)=>{this.originalConsole.warn(...t),e("warn",...t)},console.error=(...t)=>{this.originalConsole.error(...t),e("error",...t)},console.info=(...t)=>{this.originalConsole.info(...t),e("info",...t)}}appendConsoleMessage(e){let t=this.container.querySelector("#console-messages");if(!t)return;let i=document.createElement("div");i.className=`console-msg type-${e.type}`;let n=e.timestamp.toLocaleTimeString();i.innerHTML=`<span class="time">${this.escapeHtml(n)}</span> <pre>${this.escapeHtml(e.message)}</pre>`,t.appendChild(i),t.scrollTop=t.scrollHeight}escapeHtml(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}toggleConsole(e){var t;if(this.layoutMode==="fixed"){let i=this.container.querySelector('[data-dock-tab="console"]');if(i){i.click();let n=this.container.querySelector("#bottom-dock");n==null||n.classList.remove("hidden")}return}this.isConsoleOpen=e!=null?e:!this.isConsoleOpen,(t=this.consolePanel)==null||t.classList.toggle("closed",!this.isConsoleOpen)}clearConsole(){this.consoleMessages=[];let e=this.container.querySelector("#console-messages");e&&(e.innerHTML="");let t=this.container.querySelector("#console-badge");t&&(t.textContent="0")}setupCompareViewports(){Array.from(this.container.querySelectorAll("[data-viewport]")).forEach(t=>{let i=t.dataset.viewport;if(!i)return;let n=this.comparePresets.find(p=>p.id===i);if(!n)return;let a=t.querySelector("[data-compare-slot]"),r=t.querySelector("[data-compare-ghost]"),o=t.querySelector("[data-compare-wrapper]"),l=t.querySelector("[data-compare-frame]"),c=t.querySelector("[data-compare-snapshot]"),d=t.querySelector("[data-compare-focus]");!a||!r||!o||!l||(t.addEventListener("click",p=>{let u=p.target;if(u!=null&&u.closest("[data-compare-focus]")){p.preventDefault(),this.activateCompareViewport(i);return}t.classList.contains("is-active")||this.activateCompareViewport(i)}),this.compareViewports.set(i,{preset:n,root:t,slot:a,ghost:r,wrapper:o,frame:l,canvas:c,focus:d}))})}setViewMode(e){if(this.viewMode===e)return;this.viewMode=e,this.container.classList.toggle("compare-mode",e==="compare"),this.singleStage.classList.toggle("hidden",e!=="single"),this.compareStage.classList.toggle("hidden",e!=="compare");let t=this.container.querySelector("#device-select");t&&(t.disabled=e==="compare");let i=this.container.querySelector("#rotate-btn");i&&(i.disabled=e==="compare");let n=this.container.querySelector("#scene-toggle");if(n&&(n.disabled=e==="compare"),this.updateViewToggleUI(),e==="compare"){this.lastSinglePresetId=this.currentPreset.id,this.activateCompareViewport(this.activeCompareId),this.refreshCompareSnapshots(),this.startCompareSnapshots(),this.updateSceneVisibility();return}this.stopCompareSnapshots(),this.singleStage.appendChild(this.frameDragger),this.setDevice(this.lastSinglePresetId,{suppressCallback:!0}),this.fitToScreen(),this.updateSceneVisibility()}updateViewToggleUI(){Array.from(this.container.querySelectorAll("[data-view-toggle]")).forEach(t=>{t.classList.toggle("active",t.dataset.viewToggle===this.viewMode)})}activateCompareViewport(e){var a,r;let t=this.compareViewports.get(e);if(!t)return;let i=this.autoScale*this.userScaleMultiplier,n=this.activeCompareId;n&&n!==e&&this.captureCompareSnapshot(n),this.activeCompareId=e,this.currentPreset=t.preset,this.isLandscape=!1,t.slot.appendChild(this.frameDragger),this.frameDragOffsetX=0,this.frameDragOffsetY=0,this.applyFrameDrag(),this.compareViewports.forEach((o,l)=>{o.root.classList.toggle("is-active",l===e),o.ghost.classList.toggle("hidden",l===e),o.focus&&(o.focus.textContent=l===e?"Live":"Focus")}),this.applyPresetDimensions(),this.applyCompareDimensions(),this.fitToScreen({keepVisibleScale:i}),(r=(a=this.options).onDeviceChange)==null||r.call(a,this.getEffectivePreset())}applyCompareDimensions(){this.compareViewports.forEach(e=>{let t=e.preset,i=`${t.width}px`,n=`${t.height}px`;e.frame.style.width=i,e.frame.style.height=n,e.canvas&&(e.canvas.width=t.width,e.canvas.height=t.height)})}fitCompareGhosts(){this.compareViewports.forEach(e=>{let t=e.root.querySelector(".compare-body");if(!t)return;let i=Math.max(0,t.clientWidth-24),n=Math.max(0,t.clientHeight-24);if(i<=0||n<=0)return;let a=i/e.preset.width,r=n/e.preset.height,o=Math.max(.01,Math.min(a,r));e.wrapper.style.transform=`scale(${o})`})}captureCompareSnapshot(e){let t=this.compareViewports.get(e);if(!(t!=null&&t.canvas))return;let i=this.gameContainer.querySelector("canvas");if(!i)return;let n=t.canvas.getContext("2d");if(!n)return;let a=t.canvas.width,r=t.canvas.height,o=Math.min(a/i.width,r/i.height),l=i.width*o,c=i.height*o,d=(a-l)/2,p=(r-c)/2;n.clearRect(0,0,a,r),n.drawImage(i,d,p,l,c)}refreshCompareSnapshots(){this.compareViewports.forEach((e,t)=>{t!==this.activeCompareId&&this.captureCompareSnapshot(t)})}startCompareSnapshots(){this.compareSnapshotTimer||(this.compareSnapshotTimer=window.setInterval(()=>{this.viewMode==="compare"&&this.refreshCompareSnapshots()},500))}stopCompareSnapshots(){this.compareSnapshotTimer&&(window.clearInterval(this.compareSnapshotTimer),this.compareSnapshotTimer=null)}getFitBounds(){if(this.viewMode!=="compare"){let i=this.gameViewPane||this.previewContainer;return{width:i.clientWidth-40,height:i.clientHeight-40}}let e=this.compareViewports.get(this.activeCompareId),t=e==null?void 0:e.root.querySelector(".compare-body");return t?{width:t.clientWidth-24,height:t.clientHeight-24}:{width:this.previewContainer.clientWidth-40,height:this.previewContainer.clientHeight-40}}mustQuery(e){let t=this.container.querySelector(e);if(!t)throw new Error(`PreviewShell missing element: ${e}`);return t}};function $a(s={}){let e=new gn(s);return typeof window!="undefined"&&(window.__previewShell=e),e.mount(),e}ee();function Da(s){try{if(s&&typeof s.keys=="function")return Array.from(s.keys())}catch{}return[]}function Or(s){var e;return s?((e=s.getDisplayObject)==null?void 0:e.call(s))||s.pixiObject||s:null}function Sl(s,e){if(!s||!(e!=null&&e.interaction))return;let t=e.interaction,i=t.enabled!==!1&&(t.draggable===!0||t.clickable===!0);s.eventMode=i?"static":"none",s.interactive=i,i&&(s.cursor=t.draggable?"move":"pointer")}function Rr(s,e){var d,p,u;if(!s||!e)return;let t=e.transform||{};Sl(s,e);let i=t.position||{},n=t.offset||{},a=(typeof i.x=="number"?i.x:0)+(typeof n.x=="number"?n.x:0),r=(typeof i.y=="number"?i.y:0)+(typeof n.y=="number"?n.y:0),o=333,l=111;a+=o,r+=l,console.log("[DEBUG FALLBACK] tryApplyTransform (live-edit) position.set",a,r,"(raw + 333, +111)"),(d=s.position)!=null&&d.set?s.position.set(a,r):(typeof s.x=="number"&&(s.x=a),typeof s.y=="number"&&(s.y=r)),typeof t.scale=="number"&&((p=s.scale)!=null&&p.set?s.scale.set(t.scale):s.scale&&(s.scale.x=t.scale,s.scale.y=t.scale));let c=t.anchor;if(c&&((u=s.anchor)!=null&&u.set)){let g=null;typeof window!="undefined"&&window.resolveAnchorVec2?g=window.resolveAnchorVec2(c):typeof c=="object"&&c.x!==void 0&&c.y!==void 0?g=c:Array.isArray(c)&&c.length===2&&(g={x:c[0],y:c[1]}),g&&typeof g.x=="number"&&typeof g.y=="number"&&s.anchor.set(g.x,g.y)}}function zr(s){if(typeof window=="undefined")return;let e=s==null?void 0:s.objects,t=Da(e),i=a=>{var r;try{let o=window.__HANDLER_ACTIVE_SCREEN;if(!o||o==="all")return a;let l=window.__HANDLER_SCREEN_INDEX,c=(r=l==null?void 0:l.screenToInstances)==null?void 0:r[o];if(Array.isArray(c)&&c.length>0){let p=new Set(c);return a.filter(u=>p.has(u))}let d=l==null?void 0:l.instanceToScreen;return d?a.filter(p=>d[p]===o):a}catch{return a}};window.__editableObjectConfigs=e;let n=new Map;t.forEach(a=>n.set(a,[a])),window.__editableObjectInstances=n,window.refreshEditableConfigIndex=()=>zr(window.__editableConfig),window.getEditableObjectList=()=>{var a;return i(Da((a=window.__editableConfig)==null?void 0:a.objects))},window.getEditableObjectListAll=()=>{var a;return Da((a=window.__editableConfig)==null?void 0:a.objects)},window.getEditableObjectConfig=a=>{var p,u,g,h,f,m;let r=(h=(g=(u=(p=window.__editableConfig)==null?void 0:p.objects)==null?void 0:u.get)==null?void 0:g.call(u,a))!=null?h:null,o=window.__HANDLER_ACTIVE_SCREEN;if(!o||o==="all")return r;let l=window.__HANDLER_SCREEN_INDEX,c=(f=l==null?void 0:l.screenToInstances)==null?void 0:f[o];if(Array.isArray(c))return c.includes(a)?r:null;let d=(m=l==null?void 0:l.instanceToScreen)==null?void 0:m[a];return d&&d===o?r:null},window.getEditableEngineConfig=()=>{let a=window.__editableConfig;if(console.log("[BRIDGE] getEditableEngineConfig called, cfg present:",!!a),!a)return null;if(a.engine&&a.objects instanceof Map){console.log("[BRIDGE] Detected ObjectCentricConfig, flattening...");let r={...a.engine,objects:a.objects,scene:a.scene};return console.log("[BRIDGE] Returned assets:",Object.keys(r.assets||{})),r}return a}}function El(){if(typeof window=="undefined")return;let s=t=>{let i=String(t||"").trim();return i?/^(data:|blob:|https?:)/.test(i)||i.startsWith("/")?i:`/${i.replace(/^\.\//,"")}`:""},e=async(t,i)=>{var a,r,o;let n=s(i);if(n)try{let[{Assets:l},{AssetTextures:c}]=await Promise.all([import("pixi.js"),Promise.resolve().then(()=>(ct(),js))]),d=Date.now(),p=/^(data:|blob:)/.test(n)?n:n+(n.includes("?")?`&t=${d}`:`?t=${d}`),u=await l.load(p);if(!u)return;c[t]=u;let g=window.CustomAssets;(a=g==null?void 0:g[t])!=null&&a.texture&&(g[t].texture=u);let h=window.gameObjectManager,f=(r=h==null?void 0:h.get)==null?void 0:r.call(h,t);if(f){let m=((o=f.getDisplayObject)==null?void 0:o.call(f))||f.pixiObject||f.pixi||f;if(m!=null&&m.texture)m.texture=u;else if(m!=null&&m.children){let b=m.children.find(y=>y==null?void 0:y.texture);b!=null&&b.texture&&(b.texture=u)}}}catch(l){console.warn("[LIVE-EDIT] Failed to reload Pixi texture for",t,l)}};window.applyLiveEditOverrides=t=>{try{let i=se();Array.isArray(i)&&i.length&&(window.__editableConfig=t,$e(i,{silent:!0,persist:!1}))}catch{}},window.applyEngineOverrides=t=>{try{let i=se();Array.isArray(i)&&i.length&&(window.__editableConfig=t,$e(i,{silent:!0,persist:!1}))}catch{}},window.applyEditableEngineConfig=t=>{let i=window.__editableConfig;if(!(i!=null&&i.engine))return;let n=[];if(t.runtime)for(let[a,r]of Object.entries(t.runtime))n.push({path:`runtime.${a}`,value:r});if(t.assets)for(let[a,r]of Object.entries(t.assets))n.push({path:`assets.${a}`,value:r}),typeof r=="string"&&e(a,r);if(t.splash)for(let[a,r]of Object.entries(t.splash))n.push({path:`splash.${a}`,value:r});if(t.loading)for(let[a,r]of Object.entries(t.loading))n.push({path:`loading.${a}`,value:r});if(t.start)for(let[a,r]of Object.entries(t.start))n.push({path:`start.${a}`,value:r});n.length&&$e(n,{silent:!0,persist:!0,emitEvent:!0})}}function hn(s){let{getConfig:e,gameObjectManager:t,onObjectConfigApplied:i}=s;t&&(t.onObjectRebuildRequired=async(a,r)=>{console.log(`[LIVE-EDIT] \u{1F3D7}\uFE0F Rebuilding object ${a} due to type change...`);let o=t.get(a),l=o==null?void 0:o.pixiObject,c=l==null?void 0:l.parent,d=c==null?void 0:c.children.indexOf(l);o?t.remove(a):l&&l.destroy();let p=window.gameApp,u=await ve.create(a,r,p);c&&(d!==void 0&&d!==-1?c.addChildAt(u,d):c.addChild(u));let g=t.create(a,u);return console.log(`[LIVE-EDIT] \u2705 Rebuild complete for ${a}`),g}),typeof window!="undefined"&&(El(),window.applyEditableObjectConfig=(a,r)=>{var o,l,c;console.log("[LIVE-EDIT] \u{1F504} applyEditableObjectConfig called for:",a);try{let d=window.__editableConfig;(o=d==null?void 0:d.objects)!=null&&o.set&&(d.objects.set(a,r),console.log("[LIVE-EDIT] \u2705 Updated config in __editableConfig"));let p=(l=t==null?void 0:t.get)==null?void 0:l.call(t,a);if(console.log("[LIVE-EDIT] gameObject found?",!!p),p&&(console.log("[LIVE-EDIT] gameObject type:",(c=p.constructor)==null?void 0:c.name),console.log("[LIVE-EDIT] has updateConfig?",typeof p.updateConfig=="function"),console.log("[LIVE-EDIT] has onConfigUpdate?",typeof p.onConfigUpdate=="function")),p&&typeof p.updateConfig=="function")console.log("[LIVE-EDIT] \u2705 Calling updateConfig()"),p.updateConfig(r);else if(p&&typeof p.onConfigUpdate=="function")console.log("[LIVE-EDIT] \u2705 Calling onConfigUpdate()"),p.onConfigUpdate();else{console.log("[LIVE-EDIT] \u26A0\uFE0F No updateConfig or onConfigUpdate, applying transform directly");let u=Or(p);Rr(u,r)}}catch(d){console.error("[LIVE-EDIT] \u274C Error in applyEditableObjectConfig:",d)}});let n={async applyObjectConfig(a,r){var d,p;console.log("[BRIDGE] \u{1F504} applyObjectConfig called for:",a);let o=e();(d=o==null?void 0:o.objects)!=null&&d.set&&(o.objects.set(a,r),console.log("[BRIDGE] \u2705 Updated config"));let l=(p=t==null?void 0:t.get)==null?void 0:p.call(t,a);if(console.log("[BRIDGE] gameObject found?",!!l),l&&(console.log("[BRIDGE] has updateConfig?",typeof l.updateConfig=="function"),console.log("[BRIDGE] has onConfigUpdate?",typeof l.onConfigUpdate=="function")),l&&typeof l.updateConfig=="function")console.log("[BRIDGE] \u2705 Calling updateConfig()"),l.updateConfig(r);else if(l&&typeof l.onConfigUpdate=="function")console.log("[BRIDGE] \u2705 Calling onConfigUpdate()"),l.onConfigUpdate();else{console.log("[BRIDGE] \u26A0\uFE0F Applying transform directly");let u=Or(l);Rr(u,r)}let c=[a];i==null||i(a,r,c)},rebuildIndexes(){let a=e();typeof window!="undefined"&&(window.__editableConfig=a,zr(a))}};return n.rebuildIndexes(),n}ee();var Nr=st(require("lottie-web"),1);Mn(In);typeof window!="undefined"&&!window.lottie&&(window.lottie=Nr.default);var vt=null,Cl=async()=>{if(!vt){let s=typeof window!="undefined"?window.INLINE_ASSETS:null,e=(s==null?void 0:s["handler.config"])||(s==null?void 0:s["handler.config.json"]);if(e)try{if(e.startsWith("data:")){let i=atob(e.split(",")[1]);vt=JSON.parse(i)}else vt=JSON.parse(e);return vt}catch(i){console.warn("[CONFIG] Failed to parse inline handler.config.json:",i)}vt=await(await fetch("./handler.config.json")).json()}return vt},Fa,Xt,Hr,wt,Na,Ha;function Al(s){Fa=s.initGame,Xt=s.CustomAssets,Hr=s.updateScreenState,wt=s.globalResponsiveMultipliers,Na=s.layout,Ha=s.clearResponsiveElements}var fn="web_embed",Kt="https://example.com",$r={profile_id:fn},Ge=null,Se=null,Wt={width:0,height:0},Ll=!0,Tl=async()=>{var c,d,p,u;document.title="Handler Pixi Game";let s=await Cl();$r={...s.ids||{},profile_id:fn},Kt=s.destination_url||((d=(c=s.export_profiles)==null?void 0:c[fn])==null?void 0:d.destination_url)||Kt,qe.init({ids:$r,profile:fn,destinationUrl:Kt});let e=qe.getRoot();if(typeof __PREVIEW_SHELL__!="undefined"&&__PREVIEW_SHELL__){console.log("[BOOTSTRAP] Initializing Preview Shell..."),Se=$a({onDeviceChange:h=>{console.log(`[PREVIEW] Device switched to ${h.width}x${h.height}, restarting game...`),Dr()},onRefresh:Dr});let g=Se.getGameContainer();g&&(e=g),window.addEventListener("handler-preview:screen",h=>{var v,w,T,I,M,L,j,_,P,x,S,A,E;let f=window.gameApp,m=window.gameObjectManager,{width:b,height:y}=h.detail;if(Wt.width=b,Wt.height=y,Hr(b,y),!(!f||!f.renderer)){m&&o(f,m);try{f.renderer.resize(b,y);let C=f.view;C&&(C.style.width="100%",C.style.height="100%",C.style.display="block")}catch(C){console.warn("[SCREEN] Error resizing renderer:",C);return}if(t&&m&&Na)try{let C=(v=window.__mainContainer)!=null?v:f.stage,O=(j=(L=(I=window.__tutorialLabel)!=null?I:(T=(w=m.get("label_1"))==null?void 0:w.getDisplayObject)==null?void 0:T.call(w))!=null?L:(M=m.get("label_1"))==null?void 0:M.pixiObject)!=null?j:m.get("label_1"),k=m.get("background_1"),R=(S=(x=(P=window.__background)!=null?P:(_=k==null?void 0:k.getDisplayObject)==null?void 0:_.call(k))!=null?x:k==null?void 0:k.pixiObject)!=null?S:k;if(C){let z=C===f.stage;Na({mainContainer:C,label:O,background:R,backgroundTexture:(R==null?void 0:R.texture)||null,app:f},t,0,Wt,m,{skipMainContainerTransform:z}),window.dispatchEvent(new CustomEvent("handler:layout-applied",{detail:{width:Wt.width,height:Wt.height,presetId:(E=(A=h.detail)==null?void 0:A.presetId)!=null?E:null}}))}}catch(C){console.warn("[SCREEN] Error in layout:",C)}}})}let t=await Ie("scene.main");window.__editableConfig=t,r(),window.__editableConfigBaseline||(window.__editableConfigBaseline=Q(t),console.log("[BOOTSTRAP] Frozen config baseline for persistence")),(u=(p=t.engine.runtime)==null?void 0:p.layout)!=null&&u.design_width_portrait||(console.warn("[BOOTSTRAP] Config layout missing, retrying..."),await new Promise(g=>setTimeout(g,100)),t=await Ie("scene.main"));let i=await Fa(e,t,Kt,Se);Ge=i.app;let n=i.gameObjectManager;window.gameApp=Ge,window.gameObjectManager=n;try{window.__liveEditBridge=hn({getConfig:()=>window.__editableConfig,gameObjectManager:n,assets:Xt})}catch(g){console.warn("[BOOTSTRAP] Failed to initialize live-edit bridge",g)}Se&&Se.notifyGameLoaded();let a=window.__debugScale;a&&typeof a=="number"&&(wt.scale=a,console.log(`[DEBUG] Applied persisted debug scale: ${a}`)),o(Ge,n);async function r(){try{let g=async y=>{let v=y.startsWith("/")?y:`/${y}`,w=await fetch(v,{cache:"no-cache"});if(!w.ok)return null;let T=await w.text();try{return JSON.parse(T)}catch{return null}},h=await g("configs/flow/app.flow.json");if(!h||typeof h!="object")return;let f=h.screens;if(!f||typeof f!="object")return;let m={},b={};for(let[y,v]of Object.entries(f)){let w=v==null?void 0:v.source;if(typeof w!="string")continue;let T=await g(w),I=T==null?void 0:T.elements;if(!Array.isArray(I))continue;let M=I.map(L=>L==null?void 0:L.instance_id).filter(L=>typeof L=="string");m[y]=M;for(let L of M)b[L]||(b[L]=y)}window.__HANDLER_APP_FLOW=h,window.__HANDLER_SCREEN_INDEX={screenToInstances:m,instanceToScreen:b},window.dispatchEvent(new CustomEvent("handler:screen-index-loaded"))}catch{}}function o(g,h){if(Ll){console.log("[RESPONSIVE] Skipping global scaling; using config-driven layout");return}if(console.log("[RESPONSIVE] ===== APPLYING GLOBAL RESPONSIVE SCALING ====="),console.log(`[RESPONSIVE] Scale multiplier: ${wt.scale.toFixed(3)}`),g.stage){let m=function(b,y=0){if(!b||!b.children)return;let v=" ".repeat(y);b.children.forEach((w,T)=>{if(w&&w.zIndex===9999){console.log(`${v}[RESPONSIVE] Skipping debug border (zIndex 9999)`);return}if(w&&w.scale){let I=w.scale.x||1,M=w.scale.y||1;w.__originalScale||(w.__originalScale={x:I,y:M},console.log(`${v}[RESPONSIVE] Stored original scale for child[${T}]: ${I.toFixed(3)}, ${M.toFixed(3)}`));let L=w.__originalScale.x*wt.scale,j=w.__originalScale.y*wt.scale;typeof w.scale.set=="function"?w.scale.set(L,j):(w.scale.x=L,w.scale.y=j),console.log(`${v}[RESPONSIVE] Child[${T}] scale: ${I.toFixed(3)}\u2192${w.scale.x.toFixed(3)} (type: ${w.constructor.name})`),m(w,y+1)}else w&&console.log(`${v}[RESPONSIVE] Child[${T}] has no scale (type: ${w.constructor.name})`)})};var f=m;console.log("[RESPONSIVE] Applying scale to PIXI stage children"),m(g.stage)}else console.warn("[RESPONSIVE] No app.stage found!");console.log("[REDDEBUG] Debug border left unscaled (fixed boundaries)"),console.log("[RESPONSIVE] ===== GLOBAL RESPONSIVE SCALING COMPLETE =====")}function l(g){if(g!==void 0){wt.scale=g,console.log(`[RESPONSIVE] Updated global scale multiplier to: ${g.toFixed(3)}`);let h=window.gameApp,f=window.gameObjectManager;h&&f?(o(h,f),h.renderer&&(h.renderer.render(h.stage),console.log("[RESPONSIVE] Forced PIXI renderer update"))):console.warn(`[RESPONSIVE] No gameApp (${!!h}) or gameObjectManager (${!!f}) found in window for live update`)}}window.updateGlobalResponsiveMultipliers=l,qe.start()},Dr=async()=>{var e,t,i,n;console.log("[PREVIEW] Restarting game in 1 seconds...");let s=(e=window.gameObjectManager)==null?void 0:e.get("character_1");if(s){let a=((t=s.getDisplayObject)==null?void 0:t.call(s))||s;a&&a.scale&&console.log(`[CHARACTER] Before restart - Current scale - x: ${((i=a.scale.x)!=null?i:1).toFixed(3)}, y: ${((n=a.scale.y)!=null?n:1).toFixed(3)}`)}if(Se){Se.notifyGameDestroyed();try{Ha&&Ha()}catch(a){console.warn("Failed to clear responsive elements",a)}setTimeout(()=>{console.log("[PREVIEW] Executing restart...");let a=Se.getGameContainer(),r=window.gameObjectManager;if(r&&typeof r.clear=="function"&&(console.log("[PREVIEW] Clearing old GameObjectManager tickers..."),r.clear()),Ge){try{Ge.destroy(!0,{children:!0,texture:!1})}catch(o){console.warn("[PREVIEW] Destroy warning:",o)}Ge=null}window.gameApp=null,window.gameObjectManager=null,a&&(a.innerHTML="");try{typeof Xt.resetScene=="function"&&Xt.resetScene()}catch(o){console.warn("Asset reset failed",o)}setTimeout(()=>{Ie("scene.main").then(o=>{window.__editableConfig=o,window.__editableConfigBaseline||(window.__editableConfigBaseline=Q(o)),Fa(a,o,Kt).then(l=>{Ge=l.app,window.gameApp=Ge,window.gameObjectManager=l.gameObjectManager;try{window.__liveEditBridge=hn({getConfig:()=>window.__editableConfig,gameObjectManager:window.gameObjectManager,assets:Xt})}catch(c){console.warn("[BOOTSTRAP] Failed to re-initialize live-edit bridge",c)}Se&&Se.notifyGameLoaded(),console.log("[PREVIEW] Game restarted successfully");try{qe.start()}catch{}})})},100)},1e3)}};Ti();ee();var Ee={background:"#F6F3EF",ink:"#1E1E1E",secondaryText:"#8E8A84",primaryAccent:"#E38A5A",secondaryAccent:"#C9A28C",statusGreen:"#5F8F6B"},Fr=1.25,Br={fontFamily:"Inter, system-ui, sans-serif"};var mn=class{constructor(e={}){this.currentProgress=0;var t;this.currentProgress=(t=e.progress)!=null?t:0,this.container=this.createContainer()}createContainer(){let e=document.createElement("div");e.className="handler-loading-screen",e.style.cssText=`
|
|
2563
|
+
`,this.setupEventListeners(e),e}setupEventListeners(e){var I,M,L,j,_,P,x,S;let t=e.querySelector("#device-select");t==null||t.addEventListener("change",A=>{if(this.viewMode==="compare")return;let E=A.target.value;this.setDevice(E)});let i=e.querySelector("#theme-select");i==null||i.addEventListener("change",A=>{let E=A.target.value;this.setTheme(E)}),Array.from(e.querySelectorAll("[data-view-toggle]")).forEach(A=>{A.addEventListener("click",()=>{let E=A.dataset.viewToggle;E&&this.setViewMode(E)})}),Array.from(e.querySelectorAll("[data-layout-toggle]")).forEach(A=>{A.addEventListener("click",()=>{let E=A.dataset.layoutToggle;E&&this.setLayoutMode(E)})});let s=e.querySelector("#scene-toggle");s==null||s.addEventListener("click",()=>{this.viewMode!=="compare"&&(this.setSceneVisible(!this.sceneVisiblePreference),this.updateSceneVisibility())});let o=e.querySelector("#scene-hide-btn");o==null||o.addEventListener("click",()=>{this.viewMode!=="compare"&&(this.setSceneVisible(!1),this.updateSceneVisibility())});let l=A=>{let E=typeof window!="undefined"&&window.__HANDLER_PROJECT_ID||"default";return`handler_preview_scene_${A}::${E}`},c=e.querySelector("#scene-grid-btn"),d=e.querySelector("#scene-play-btn"),p=(A,E,C)=>{A&&(A.textContent=E?`${C} On`:`${C} Off`,A.setAttribute("aria-pressed",E?"true":"false"))},u=()=>{let A=window.localStorage.getItem(l("grid_gap")),E=Number(A!=null?A:50);return Number.isFinite(E)?E:50},g=A=>{try{window.localStorage.setItem(l("grid_enabled"),A?"true":"false")}catch{}p(c,A,"Grid");let E=u();window.dispatchEvent(new CustomEvent("scene-editor:grid",{detail:{enabled:A,gap:E}}))},h=A=>{try{window.localStorage.setItem(l("play_mode"),A?"true":"false")}catch{}p(d,A,"Play"),window.dispatchEvent(new CustomEvent("scene-editor:play-mode",{detail:{enabled:A}}))};try{let A=window.localStorage.getItem(l("grid_enabled"))==="true",E=!0;try{window.localStorage.setItem(l("play_mode"),"true")}catch{}if(p(c,A,"Grid"),p(d,E,"Play"),d&&(d.disabled=!0),c){let C=u();window.dispatchEvent(new CustomEvent("scene-editor:grid",{detail:{enabled:A,gap:C}}))}d&&window.dispatchEvent(new CustomEvent("scene-editor:play-mode",{detail:{enabled:E}}))}catch{}c==null||c.addEventListener("click",()=>{let A=c.getAttribute("aria-pressed")==="true";g(!A)}),d==null||d.addEventListener("click",()=>{let A=d.getAttribute("aria-pressed")==="true";h(!A)}),(I=e.querySelector("#rotate-btn"))==null||I.addEventListener("click",()=>this.toggleRotation()),(M=e.querySelector("#zoom-in-btn"))==null||M.addEventListener("click",()=>this.adjustUserZoom(.1)),(L=e.querySelector("#zoom-out-btn"))==null||L.addEventListener("click",()=>this.adjustUserZoom(-.1)),(j=e.querySelector("#refresh-btn"))==null||j.addEventListener("click",()=>this.refresh());let f=e.querySelector("#bottom-dock"),m=e.querySelector("#bottom-dock-resize");f&&m&&this.makeBottomDockResizable(f,m);let b=Array.from(e.querySelectorAll(".bottom-dock-tab"));b.forEach(A=>{A.addEventListener("click",()=>{let E=A.dataset.dockTab;if(!E)return;b.forEach(O=>O.classList.remove("active")),A.classList.add("active"),Array.from(e.querySelectorAll(".bottom-dock-panel")).forEach(O=>{let k=O.dataset.dockPanel;O.classList.toggle("active",k===E)})})}),(_=e.querySelector("#console-clear"))==null||_.addEventListener("click",()=>this.clearConsole()),(P=e.querySelector("#corner-zoom-in-btn"))==null||P.addEventListener("click",()=>this.adjustUserZoom(.1)),(x=e.querySelector("#corner-zoom-out-btn"))==null||x.addEventListener("click",()=>this.adjustUserZoom(-.1)),(S=e.querySelector("#corner-grab-btn"))==null||S.addEventListener("click",()=>{this.frameDragger.style.cursor="grab",setTimeout(()=>{this.isSpaceKeyPressed||(this.frameDragger.style.cursor="")},1e3)});let y=e.querySelector(".scene-panel.scene-objects"),v=y==null?void 0:y.querySelector("[data-panel-resize-v]");y&&v&&this.makeSidebarResizable(y,v,"left");let w=e.querySelector(".debug-workbench"),T=w==null?void 0:w.querySelector("#workbench-resize-v");w&&T&&this.makeSidebarResizable(w,T,"right")}applyDeviceFrameStyles(){Object.assign(this.frameDragger.style,{display:"flex",justifyContent:"center",alignItems:"center",transform:"translate(0px, 0px)",touchAction:"none"}),Object.assign(this.frameWrapper.style,{display:"flex",justifyContent:"center",alignItems:"center",transformOrigin:"center center",transition:"transform 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94)",boxShadow:"var(--ui-shadow-strong)",borderRadius:"0px",willChange:"transform"}),Object.assign(this.deviceFrame.style,{overflow:"hidden",position:"relative",borderRadius:"0px"}),Object.assign(this.gameContainer.style,{position:"relative",overflow:"hidden",minWidth:"0px",minHeight:"0px"})}setupObserversAndListeners(){this.resizeObserver=new ResizeObserver(()=>{this.resizeListenersDisabled||this.scheduleFit()}),this.resizeObserver.observe(this.previewContainer),window.addEventListener("resize",this.onWindowResize,{passive:!0})}scheduleFit(){this.rafFitHandle&&cancelAnimationFrame(this.rafFitHandle),this.rafFitHandle=requestAnimationFrame(()=>{this.rafFitHandle=null,this.fitToScreen()})}applyPresetDimensions(){let e=this.getEffectivePreset(),t=`${e.width}px`,i=`${e.height}px`;this.deviceFrame.style.width=t,this.deviceFrame.style.height=i,this.gameContainer.style.width=t,this.gameContainer.style.height=i,this.gameContainer.style.maxWidth=t,this.gameContainer.style.maxHeight=i,this.gameContainer.style.minWidth=t,this.gameContainer.style.minHeight=i,this.gameContainer.dataset.screenWidth=String(e.width),this.gameContainer.dataset.screenHeight=String(e.height),this.container.style.setProperty("--preview-screen-width",String(e.width)),this.container.style.setProperty("--preview-screen-height",String(e.height))}fitToScreen(e){if(!this.previewContainer)return;let t=this.getEffectivePreset(),i=this.getFitBounds(),n=Math.max(0,i.width),a=Math.max(0,i.height);if(n<=0||a<=0)return;this.applyPresetDimensions(),this.viewMode==="compare"&&this.applyCompareDimensions();let s=n/t.width,o=a/t.height;if(this.autoScale=Math.max(.01,Math.min(s,o)),!this.hasInitialFit){this.hasInitialFit=!0;let l=.6;this.userScaleMultiplier=l/this.autoScale}(e==null?void 0:e.keepUserScaleMultiplier)!==void 0&&e.keepUserScaleMultiplier>0?this.userScaleMultiplier=e.keepUserScaleMultiplier:e!=null&&e.keepVisibleScale&&e.keepVisibleScale>0&&(this.userScaleMultiplier=e.keepVisibleScale/this.autoScale),this.applyTransform(),this.viewMode==="compare"&&this.fitCompareGhosts(),requestAnimationFrame(()=>this.updatePanelPositions()),this.emitScreenChange()}applyTransform(){let e=this.autoScale*this.userScaleMultiplier;this.frameWrapper.style.transform=`scale(${e})`;let t=this.container.querySelector("#zoom-label");t&&(t.textContent=`${Math.round(e*100)}%`),requestAnimationFrame(()=>this.updatePanelPositions())}applyFrameDrag(){this.frameDragger.style.transform=`translate(${this.frameDragOffsetX}px, ${this.frameDragOffsetY}px)`,requestAnimationFrame(()=>this.updatePanelPositions())}updatePanelPositions(){if(!this.gameReady||this.viewMode==="compare")return;let e=this.container.querySelector('[data-panel="scene-tools-corner"]'),t=this.container.querySelector('[data-panel="nudge-panel"]');if(this.layoutMode==="fixed"){let i=this.gameViewPane||this.container.querySelector(".preview-container");i&&(e&&e.parentElement!==i&&i.appendChild(e),t&&t.parentElement!==i&&i.appendChild(t))}else{let i=this.container.querySelector(".preview-main");i&&(e&&e.parentElement!==i&&i.appendChild(e),t&&t.parentElement!==i&&i.appendChild(t))}e&&(e.style.zIndex="100"),t&&(t.style.position="absolute",t.style.left="50%",t.style.top="16px",t.style.transform="translateX(calc(-50% + 200px))",t.style.zIndex="100")}setupFrameDragging(){this.frameDragger.addEventListener("pointerdown",e=>{let t=!this.gameContainer.contains(e.target);!this.isSpaceKeyPressed&&!t||e.button===0&&(e.preventDefault(),this.frameDragActive=!0,this.frameDragStartX=e.clientX,this.frameDragStartY=e.clientY,this.frameDragOriginX=this.frameDragOffsetX,this.frameDragOriginY=this.frameDragOffsetY,window.addEventListener("pointermove",this.onFrameDragMove),window.addEventListener("pointerup",this.onFrameDragEnd))})}setupSpaceKeyListener(){window.addEventListener("keydown",e=>{e.code==="Space"&&!this.isInputFocused()&&(this.isSpaceKeyPressed||(this.isSpaceKeyPressed=!0,this.updateDragCursor(),e.preventDefault()))}),window.addEventListener("keyup",e=>{e.code==="Space"&&(this.isSpaceKeyPressed=!1,this.updateDragCursor(),this.frameDragActive&&this.onFrameDragEnd())}),window.addEventListener("blur",()=>{this.isSpaceKeyPressed=!1,this.updateDragCursor(),this.frameDragActive&&this.onFrameDragEnd()})}isInputFocused(){let e=document.activeElement;if(!e)return!1;let t=e.tagName.toLowerCase();return t==="input"||t==="textarea"||t==="select"||e.isContentEditable}setupShortcutListeners(){window.addEventListener("keydown",e=>{if(this.isInputFocused())return;let t=navigator.platform.toUpperCase().indexOf("MAC")>=0,i=e.ctrlKey||e.metaKey,n=e.shiftKey;if(i&&e.key==="s"&&!n){e.preventDefault();let a=document.querySelector("#apply-current-btn");a&&a.getAttribute("disabled")===null&&a.click();return}if(i&&e.key==="z"&&!n){e.preventDefault(),vi();return}if(i&&(e.key==="z"&&n||e.key==="y"&&!n)){e.preventDefault(),wi();return}})}setupUnsavedChangesIndicator(){let e=this.container.querySelector("#preview-save-shortcut-text");e&&(e.textContent=`(${this.getShortcutKey()} + S)`),window.addEventListener("config:changed",()=>{this.updateUnsavedChangesIndicator()}),this.updateUnsavedChangesIndicator();let t=this.container.querySelector("#preview-save-btn");t==null||t.addEventListener("click",()=>{let i=document.querySelector("#apply-current-btn");i&&i.getAttribute("disabled")===null&&i.click()})}updateUnsavedChangesIndicator(){let t=De().hasChanges;if(t!==this.hasUnsavedChanges){this.hasUnsavedChanges=t;let i=this.container.querySelector("#preview-unsaved-star"),n=this.container.querySelector("#preview-save-btn");i&&(i.style.display=t?"inline-block":"none"),n&&(n.style.display=t?"inline-flex":"none")}}updateDragCursor(){this.isSpaceKeyPressed?(this.frameDragger.style.cursor="grab",this.frameDragActive&&(this.frameDragger.style.cursor="grabbing")):this.frameDragger.style.cursor=""}adjustUserZoom(e){this.userScaleMultiplier=Math.max(.1,Math.min(6,this.userScaleMultiplier+e)),this.applyTransform(),this.emitScreenChange()}toggleRotation(){var t,i;if(this.viewMode==="compare")return;let e=this.userScaleMultiplier;this.isLandscape=!this.isLandscape,this.applyPresetDimensions(),this.fitToScreen({keepUserScaleMultiplier:e}),(i=(t=this.options).onDeviceChange)==null||i.call(t,this.getEffectivePreset()),this.emitScreenChange()}emitScreenChange(){if(!this.gameReady)return;let e=this.getEffectivePreset(),t={width:e.width,height:e.height,dpr:Math.max(1,Math.floor(window.devicePixelRatio||1)),presetId:e.id,isLandscape:this.isLandscape};if(window.dispatchEvent(new CustomEvent("handler-preview:screen",{detail:t})),this.viewMode==="compare"&&this.refreshCompareSnapshots(),this.isInitialized&&this.isMounted&&this.gameReady){let i=window.gameApp;if(!(i!=null&&i.renderer))return;this.ignoreNextWindowResize=!0,window.dispatchEvent(new Event("resize"))}}safeStringify(e){var i;let t=new WeakSet;try{return JSON.stringify(e,(n,a)=>{if(typeof a=="object"&&a!==null){if(t.has(a))return"[Circular]";t.add(a)}return a},2)}catch{try{if(e&&((i=e.constructor)!=null&&i.name))return`[object ${e.constructor.name}]`}catch{}return String(e)}}setupConsoleInterceptor(){let e=(t,...i)=>{let n=i.map(s=>typeof s=="object"?this.safeStringify(s):String(s)).join(" ");this.consoleMessages.push({type:t,message:n,timestamp:new Date}),this.appendConsoleMessage(this.consoleMessages[this.consoleMessages.length-1]);let a=this.container.querySelector("#console-badge");if(a){let s=this.consoleMessages.filter(o=>o.type==="error").length;a.textContent=s>0?`${s}!`:"0",a.classList.toggle("has-errors",s>0)}};console.log=(...t)=>{this.originalConsole.log(...t),e("log",...t)},console.warn=(...t)=>{this.originalConsole.warn(...t),e("warn",...t)},console.error=(...t)=>{this.originalConsole.error(...t),e("error",...t)},console.info=(...t)=>{this.originalConsole.info(...t),e("info",...t)}}appendConsoleMessage(e){let t=this.container.querySelector("#console-messages");if(!t)return;let i=document.createElement("div");i.className=`console-msg type-${e.type}`;let n=e.timestamp.toLocaleTimeString();i.innerHTML=`<span class="time">${this.escapeHtml(n)}</span> <pre>${this.escapeHtml(e.message)}</pre>`,t.appendChild(i),t.scrollTop=t.scrollHeight}escapeHtml(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}toggleConsole(e){var t;if(this.layoutMode==="fixed"){let i=this.container.querySelector('[data-dock-tab="console"]');if(i){i.click();let n=this.container.querySelector("#bottom-dock");n==null||n.classList.remove("hidden")}return}this.isConsoleOpen=e!=null?e:!this.isConsoleOpen,(t=this.consolePanel)==null||t.classList.toggle("closed",!this.isConsoleOpen)}clearConsole(){this.consoleMessages=[];let e=this.container.querySelector("#console-messages");e&&(e.innerHTML="");let t=this.container.querySelector("#console-badge");t&&(t.textContent="0")}setupCompareViewports(){Array.from(this.container.querySelectorAll("[data-viewport]")).forEach(t=>{let i=t.dataset.viewport;if(!i)return;let n=this.comparePresets.find(p=>p.id===i);if(!n)return;let a=t.querySelector("[data-compare-slot]"),s=t.querySelector("[data-compare-ghost]"),o=t.querySelector("[data-compare-wrapper]"),l=t.querySelector("[data-compare-frame]"),c=t.querySelector("[data-compare-snapshot]"),d=t.querySelector("[data-compare-focus]");!a||!s||!o||!l||(t.addEventListener("click",p=>{let u=p.target;if(u!=null&&u.closest("[data-compare-focus]")){p.preventDefault(),this.activateCompareViewport(i);return}t.classList.contains("is-active")||this.activateCompareViewport(i)}),this.compareViewports.set(i,{preset:n,root:t,slot:a,ghost:s,wrapper:o,frame:l,canvas:c,focus:d}))})}setViewMode(e){if(this.viewMode===e)return;this.viewMode=e,this.container.classList.toggle("compare-mode",e==="compare"),this.singleStage.classList.toggle("hidden",e!=="single"),this.compareStage.classList.toggle("hidden",e!=="compare");let t=this.container.querySelector("#device-select");t&&(t.disabled=e==="compare");let i=this.container.querySelector("#rotate-btn");i&&(i.disabled=e==="compare");let n=this.container.querySelector("#scene-toggle");if(n&&(n.disabled=e==="compare"),this.updateViewToggleUI(),e==="compare"){this.lastSinglePresetId=this.currentPreset.id,this.activateCompareViewport(this.activeCompareId),this.refreshCompareSnapshots(),this.startCompareSnapshots(),this.updateSceneVisibility();return}this.stopCompareSnapshots(),this.singleStage.appendChild(this.frameDragger),this.setDevice(this.lastSinglePresetId,{suppressCallback:!0}),this.fitToScreen(),this.updateSceneVisibility()}updateViewToggleUI(){Array.from(this.container.querySelectorAll("[data-view-toggle]")).forEach(t=>{t.classList.toggle("active",t.dataset.viewToggle===this.viewMode)})}activateCompareViewport(e){var a,s;let t=this.compareViewports.get(e);if(!t)return;let i=this.autoScale*this.userScaleMultiplier,n=this.activeCompareId;n&&n!==e&&this.captureCompareSnapshot(n),this.activeCompareId=e,this.currentPreset=t.preset,this.isLandscape=!1,t.slot.appendChild(this.frameDragger),this.frameDragOffsetX=0,this.frameDragOffsetY=0,this.applyFrameDrag(),this.compareViewports.forEach((o,l)=>{o.root.classList.toggle("is-active",l===e),o.ghost.classList.toggle("hidden",l===e),o.focus&&(o.focus.textContent=l===e?"Live":"Focus")}),this.applyPresetDimensions(),this.applyCompareDimensions(),this.fitToScreen({keepVisibleScale:i}),(s=(a=this.options).onDeviceChange)==null||s.call(a,this.getEffectivePreset())}applyCompareDimensions(){this.compareViewports.forEach(e=>{let t=e.preset,i=`${t.width}px`,n=`${t.height}px`;e.frame.style.width=i,e.frame.style.height=n,e.canvas&&(e.canvas.width=t.width,e.canvas.height=t.height)})}fitCompareGhosts(){this.compareViewports.forEach(e=>{let t=e.root.querySelector(".compare-body");if(!t)return;let i=Math.max(0,t.clientWidth-24),n=Math.max(0,t.clientHeight-24);if(i<=0||n<=0)return;let a=i/e.preset.width,s=n/e.preset.height,o=Math.max(.01,Math.min(a,s));e.wrapper.style.transform=`scale(${o})`})}captureCompareSnapshot(e){let t=this.compareViewports.get(e);if(!(t!=null&&t.canvas))return;let i=this.gameContainer.querySelector("canvas");if(!i)return;let n=t.canvas.getContext("2d");if(!n)return;let a=t.canvas.width,s=t.canvas.height,o=Math.min(a/i.width,s/i.height),l=i.width*o,c=i.height*o,d=(a-l)/2,p=(s-c)/2;n.clearRect(0,0,a,s),n.drawImage(i,d,p,l,c)}refreshCompareSnapshots(){this.compareViewports.forEach((e,t)=>{t!==this.activeCompareId&&this.captureCompareSnapshot(t)})}startCompareSnapshots(){this.compareSnapshotTimer||(this.compareSnapshotTimer=window.setInterval(()=>{this.viewMode==="compare"&&this.refreshCompareSnapshots()},500))}stopCompareSnapshots(){this.compareSnapshotTimer&&(window.clearInterval(this.compareSnapshotTimer),this.compareSnapshotTimer=null)}getFitBounds(){if(this.viewMode!=="compare"){let i=this.gameViewPane||this.previewContainer;return{width:i.clientWidth-40,height:i.clientHeight-40}}let e=this.compareViewports.get(this.activeCompareId),t=e==null?void 0:e.root.querySelector(".compare-body");return t?{width:t.clientWidth-24,height:t.clientHeight-24}:{width:this.previewContainer.clientWidth-40,height:this.previewContainer.clientHeight-40}}mustQuery(e){let t=this.container.querySelector(e);if(!t)throw new Error(`PreviewShell missing element: ${e}`);return t}};function $a(r={}){let e=new gn(r);return typeof window!="undefined"&&(window.__previewShell=e),e.mount(),e}ee();function Da(r){try{if(r&&typeof r.keys=="function")return Array.from(r.keys())}catch{}return[]}function Or(r){var e;return r?((e=r.getDisplayObject)==null?void 0:e.call(r))||r.pixiObject||r:null}function Sl(r,e){if(!r||!(e!=null&&e.interaction))return;let t=e.interaction,i=t.enabled!==!1&&(t.draggable===!0||t.clickable===!0);r.eventMode=i?"static":"none",r.interactive=i,i&&(r.cursor=t.draggable?"move":"pointer")}function Rr(r,e){var d,p,u;if(!r||!e)return;let t=e.transform||{};Sl(r,e);let i=t.position||{},n=t.offset||{},a=(typeof i.x=="number"?i.x:0)+(typeof n.x=="number"?n.x:0),s=(typeof i.y=="number"?i.y:0)+(typeof n.y=="number"?n.y:0),o=333,l=111;a+=o,s+=l,console.log("[DEBUG FALLBACK] tryApplyTransform (live-edit) position.set",a,s,"(raw + 333, +111)"),(d=r.position)!=null&&d.set?r.position.set(a,s):(typeof r.x=="number"&&(r.x=a),typeof r.y=="number"&&(r.y=s)),typeof t.scale=="number"&&((p=r.scale)!=null&&p.set?r.scale.set(t.scale):r.scale&&(r.scale.x=t.scale,r.scale.y=t.scale));let c=t.anchor;if(c&&((u=r.anchor)!=null&&u.set)){let g=null;typeof window!="undefined"&&window.resolveAnchorVec2?g=window.resolveAnchorVec2(c):typeof c=="object"&&c.x!==void 0&&c.y!==void 0?g=c:Array.isArray(c)&&c.length===2&&(g={x:c[0],y:c[1]}),g&&typeof g.x=="number"&&typeof g.y=="number"&&r.anchor.set(g.x,g.y)}}function zr(r){if(typeof window=="undefined")return;let e=r==null?void 0:r.objects,t=Da(e),i=a=>{var s;try{let o=window.__HANDLER_ACTIVE_SCREEN;if(!o||o==="all")return a;let l=window.__HANDLER_SCREEN_INDEX,c=(s=l==null?void 0:l.screenToInstances)==null?void 0:s[o];if(Array.isArray(c)&&c.length>0){let p=new Set(c);return a.filter(u=>p.has(u))}let d=l==null?void 0:l.instanceToScreen;return d?a.filter(p=>d[p]===o):a}catch{return a}};window.__editableObjectConfigs=e;let n=new Map;t.forEach(a=>n.set(a,[a])),window.__editableObjectInstances=n,window.refreshEditableConfigIndex=()=>zr(window.__editableConfig),window.getEditableObjectList=()=>{var a;return i(Da((a=window.__editableConfig)==null?void 0:a.objects))},window.getEditableObjectListAll=()=>{var a;return Da((a=window.__editableConfig)==null?void 0:a.objects)},window.getEditableObjectConfig=a=>{var p,u,g,h,f,m;let s=(h=(g=(u=(p=window.__editableConfig)==null?void 0:p.objects)==null?void 0:u.get)==null?void 0:g.call(u,a))!=null?h:null,o=window.__HANDLER_ACTIVE_SCREEN;if(!o||o==="all")return s;let l=window.__HANDLER_SCREEN_INDEX,c=(f=l==null?void 0:l.screenToInstances)==null?void 0:f[o];if(Array.isArray(c))return c.includes(a)?s:null;let d=(m=l==null?void 0:l.instanceToScreen)==null?void 0:m[a];return d&&d===o?s:null},window.getEditableEngineConfig=()=>{let a=window.__editableConfig;if(console.log("[BRIDGE] getEditableEngineConfig called, cfg present:",!!a),!a)return null;if(a.engine&&a.objects instanceof Map){console.log("[BRIDGE] Detected ObjectCentricConfig, flattening...");let s={...a.engine,objects:a.objects,scene:a.scene};return console.log("[BRIDGE] Returned assets:",Object.keys(s.assets||{})),s}return a}}function El(){if(typeof window=="undefined")return;let r=t=>{let i=String(t||"").trim();return i?/^(data:|blob:|https?:)/.test(i)||i.startsWith("/")?i:`/${i.replace(/^\.\//,"")}`:""},e=async(t,i)=>{var a,s,o;let n=r(i);if(n)try{let[{Assets:l},{AssetTextures:c}]=await Promise.all([import("pixi.js"),Promise.resolve().then(()=>(ct(),js))]),d=Date.now(),p=/^(data:|blob:)/.test(n)?n:n+(n.includes("?")?`&t=${d}`:`?t=${d}`),u=await l.load(p);if(!u)return;c[t]=u;let g=window.CustomAssets;(a=g==null?void 0:g[t])!=null&&a.texture&&(g[t].texture=u);let h=window.gameObjectManager,f=(s=h==null?void 0:h.get)==null?void 0:s.call(h,t);if(f){let m=((o=f.getDisplayObject)==null?void 0:o.call(f))||f.pixiObject||f.pixi||f;if(m!=null&&m.texture)m.texture=u;else if(m!=null&&m.children){let b=m.children.find(y=>y==null?void 0:y.texture);b!=null&&b.texture&&(b.texture=u)}}}catch(l){console.warn("[LIVE-EDIT] Failed to reload Pixi texture for",t,l)}};window.applyLiveEditOverrides=t=>{try{let i=se();Array.isArray(i)&&i.length&&(window.__editableConfig=t,$e(i,{silent:!0,persist:!1}))}catch{}},window.applyEngineOverrides=t=>{try{let i=se();Array.isArray(i)&&i.length&&(window.__editableConfig=t,$e(i,{silent:!0,persist:!1}))}catch{}},window.applyEditableEngineConfig=t=>{let i=window.__editableConfig;if(!(i!=null&&i.engine))return;let n=[];if(t.runtime)for(let[a,s]of Object.entries(t.runtime))n.push({path:`runtime.${a}`,value:s});if(t.assets)for(let[a,s]of Object.entries(t.assets))n.push({path:`assets.${a}`,value:s}),typeof s=="string"&&e(a,s);if(t.splash)for(let[a,s]of Object.entries(t.splash))n.push({path:`splash.${a}`,value:s});if(t.loading)for(let[a,s]of Object.entries(t.loading))n.push({path:`loading.${a}`,value:s});if(t.start)for(let[a,s]of Object.entries(t.start))n.push({path:`start.${a}`,value:s});n.length&&$e(n,{silent:!0,persist:!0,emitEvent:!0})}}function hn(r){let{getConfig:e,gameObjectManager:t,onObjectConfigApplied:i}=r;t&&(t.onObjectRebuildRequired=async(a,s)=>{console.log(`[LIVE-EDIT] \u{1F3D7}\uFE0F Rebuilding object ${a} due to type change...`);let o=t.get(a),l=o==null?void 0:o.pixiObject,c=l==null?void 0:l.parent,d=c==null?void 0:c.children.indexOf(l);o?t.remove(a):l&&l.destroy();let p=window.gameApp,u=await ve.create(a,s,p);c&&(d!==void 0&&d!==-1?c.addChildAt(u,d):c.addChild(u));let g=t.create(a,u);return console.log(`[LIVE-EDIT] \u2705 Rebuild complete for ${a}`),g}),typeof window!="undefined"&&(El(),window.applyEditableObjectConfig=(a,s)=>{var o,l,c;console.log("[LIVE-EDIT] \u{1F504} applyEditableObjectConfig called for:",a);try{let d=window.__editableConfig;(o=d==null?void 0:d.objects)!=null&&o.set&&(d.objects.set(a,s),console.log("[LIVE-EDIT] \u2705 Updated config in __editableConfig"));let p=(l=t==null?void 0:t.get)==null?void 0:l.call(t,a);if(console.log("[LIVE-EDIT] gameObject found?",!!p),p&&(console.log("[LIVE-EDIT] gameObject type:",(c=p.constructor)==null?void 0:c.name),console.log("[LIVE-EDIT] has updateConfig?",typeof p.updateConfig=="function"),console.log("[LIVE-EDIT] has onConfigUpdate?",typeof p.onConfigUpdate=="function")),p&&typeof p.updateConfig=="function")console.log("[LIVE-EDIT] \u2705 Calling updateConfig()"),p.updateConfig(s);else if(p&&typeof p.onConfigUpdate=="function")console.log("[LIVE-EDIT] \u2705 Calling onConfigUpdate()"),p.onConfigUpdate();else{console.log("[LIVE-EDIT] \u26A0\uFE0F No updateConfig or onConfigUpdate, applying transform directly");let u=Or(p);Rr(u,s)}}catch(d){console.error("[LIVE-EDIT] \u274C Error in applyEditableObjectConfig:",d)}});let n={async applyObjectConfig(a,s){var d,p;console.log("[BRIDGE] \u{1F504} applyObjectConfig called for:",a);let o=e();(d=o==null?void 0:o.objects)!=null&&d.set&&(o.objects.set(a,s),console.log("[BRIDGE] \u2705 Updated config"));let l=(p=t==null?void 0:t.get)==null?void 0:p.call(t,a);if(console.log("[BRIDGE] gameObject found?",!!l),l&&(console.log("[BRIDGE] has updateConfig?",typeof l.updateConfig=="function"),console.log("[BRIDGE] has onConfigUpdate?",typeof l.onConfigUpdate=="function")),l&&typeof l.updateConfig=="function")console.log("[BRIDGE] \u2705 Calling updateConfig()"),l.updateConfig(s);else if(l&&typeof l.onConfigUpdate=="function")console.log("[BRIDGE] \u2705 Calling onConfigUpdate()"),l.onConfigUpdate();else{console.log("[BRIDGE] \u26A0\uFE0F Applying transform directly");let u=Or(l);Rr(u,s)}let c=[a];i==null||i(a,s,c)},rebuildIndexes(){let a=e();typeof window!="undefined"&&(window.__editableConfig=a,zr(a))}};return n.rebuildIndexes(),n}ee();var Nr=st(require("lottie-web"),1);Mn(In);typeof window!="undefined"&&!window.lottie&&(window.lottie=Nr.default);var vt=null,Cl=async()=>{if(!vt){let r=typeof window!="undefined"?window.INLINE_ASSETS:null,e=(r==null?void 0:r["handler.config"])||(r==null?void 0:r["handler.config.json"]);if(e)try{if(e.startsWith("data:")){let i=atob(e.split(",")[1]);vt=JSON.parse(i)}else vt=JSON.parse(e);return vt}catch(i){console.warn("[CONFIG] Failed to parse inline handler.config.json:",i)}vt=await(await fetch("./handler.config.json")).json()}return vt},Fa,Xt,Hr,wt,Na,Ha;function Al(r){Fa=r.initGame,Xt=r.CustomAssets,Hr=r.updateScreenState,wt=r.globalResponsiveMultipliers,Na=r.layout,Ha=r.clearResponsiveElements}var fn="web_embed",Kt="https://example.com",$r={profile_id:fn},Ge=null,Se=null,Wt={width:0,height:0},Ll=!0,Tl=async()=>{var c,d,p,u;document.title="Handler Pixi Game";let r=await Cl();$r={...r.ids||{},profile_id:fn},Kt=r.destination_url||((d=(c=r.export_profiles)==null?void 0:c[fn])==null?void 0:d.destination_url)||Kt,qe.init({ids:$r,profile:fn,destinationUrl:Kt});let e=qe.getRoot();if(typeof __PREVIEW_SHELL__!="undefined"&&__PREVIEW_SHELL__){console.log("[BOOTSTRAP] Initializing Preview Shell..."),Se=$a({onDeviceChange:h=>{console.log(`[PREVIEW] Device switched to ${h.width}x${h.height}, restarting game...`),Dr()},onRefresh:Dr});let g=Se.getGameContainer();g&&(e=g),window.addEventListener("handler-preview:screen",h=>{var v,w,T,I,M,L,j,_,P,x,S,A,E;let f=window.gameApp,m=window.gameObjectManager,{width:b,height:y}=h.detail;if(Wt.width=b,Wt.height=y,Hr(b,y),!(!f||!f.renderer)){m&&o(f,m);try{f.renderer.resize(b,y);let C=f.view;C&&(C.style.width="100%",C.style.height="100%",C.style.display="block")}catch(C){console.warn("[SCREEN] Error resizing renderer:",C);return}if(t&&m&&Na)try{let C=(v=window.__mainContainer)!=null?v:f.stage,O=(j=(L=(I=window.__tutorialLabel)!=null?I:(T=(w=m.get("label_1"))==null?void 0:w.getDisplayObject)==null?void 0:T.call(w))!=null?L:(M=m.get("label_1"))==null?void 0:M.pixiObject)!=null?j:m.get("label_1"),k=m.get("background_1"),R=(S=(x=(P=window.__background)!=null?P:(_=k==null?void 0:k.getDisplayObject)==null?void 0:_.call(k))!=null?x:k==null?void 0:k.pixiObject)!=null?S:k;if(C){let z=C===f.stage;Na({mainContainer:C,label:O,background:R,backgroundTexture:(R==null?void 0:R.texture)||null,app:f},t,0,Wt,m,{skipMainContainerTransform:z}),window.dispatchEvent(new CustomEvent("handler:layout-applied",{detail:{width:Wt.width,height:Wt.height,presetId:(E=(A=h.detail)==null?void 0:A.presetId)!=null?E:null}}))}}catch(C){console.warn("[SCREEN] Error in layout:",C)}}})}let t=await Ie("scene.main");window.__editableConfig=t,s(),window.__editableConfigBaseline||(window.__editableConfigBaseline=Q(t),console.log("[BOOTSTRAP] Frozen config baseline for persistence")),(u=(p=t.engine.runtime)==null?void 0:p.layout)!=null&&u.design_width_portrait||(console.warn("[BOOTSTRAP] Config layout missing, retrying..."),await new Promise(g=>setTimeout(g,100)),t=await Ie("scene.main"));let i=await Fa(e,t,Kt,Se);Ge=i.app;let n=i.gameObjectManager;window.gameApp=Ge,window.gameObjectManager=n;try{window.__liveEditBridge=hn({getConfig:()=>window.__editableConfig,gameObjectManager:n,assets:Xt})}catch(g){console.warn("[BOOTSTRAP] Failed to initialize live-edit bridge",g)}Se&&Se.notifyGameLoaded();let a=window.__debugScale;a&&typeof a=="number"&&(wt.scale=a,console.log(`[DEBUG] Applied persisted debug scale: ${a}`)),o(Ge,n);async function s(){try{let g=async y=>{let v=y.startsWith("/")?y:`/${y}`,w=await fetch(v,{cache:"no-cache"});if(!w.ok)return null;let T=await w.text();try{return JSON.parse(T)}catch{return null}},h=await g("configs/flow/app.flow.json");if(!h||typeof h!="object")return;let f=h.screens;if(!f||typeof f!="object")return;let m={},b={};for(let[y,v]of Object.entries(f)){let w=v==null?void 0:v.source;if(typeof w!="string")continue;let T=await g(w),I=T==null?void 0:T.elements;if(!Array.isArray(I))continue;let M=I.map(L=>L==null?void 0:L.instance_id).filter(L=>typeof L=="string");m[y]=M;for(let L of M)b[L]||(b[L]=y)}window.__HANDLER_APP_FLOW=h,window.__HANDLER_SCREEN_INDEX={screenToInstances:m,instanceToScreen:b},window.dispatchEvent(new CustomEvent("handler:screen-index-loaded"))}catch{}}function o(g,h){if(Ll){console.log("[RESPONSIVE] Skipping global scaling; using config-driven layout");return}if(console.log("[RESPONSIVE] ===== APPLYING GLOBAL RESPONSIVE SCALING ====="),console.log(`[RESPONSIVE] Scale multiplier: ${wt.scale.toFixed(3)}`),g.stage){let m=function(b,y=0){if(!b||!b.children)return;let v=" ".repeat(y);b.children.forEach((w,T)=>{if(w&&w.zIndex===9999){console.log(`${v}[RESPONSIVE] Skipping debug border (zIndex 9999)`);return}if(w&&w.scale){let I=w.scale.x||1,M=w.scale.y||1;w.__originalScale||(w.__originalScale={x:I,y:M},console.log(`${v}[RESPONSIVE] Stored original scale for child[${T}]: ${I.toFixed(3)}, ${M.toFixed(3)}`));let L=w.__originalScale.x*wt.scale,j=w.__originalScale.y*wt.scale;typeof w.scale.set=="function"?w.scale.set(L,j):(w.scale.x=L,w.scale.y=j),console.log(`${v}[RESPONSIVE] Child[${T}] scale: ${I.toFixed(3)}\u2192${w.scale.x.toFixed(3)} (type: ${w.constructor.name})`),m(w,y+1)}else w&&console.log(`${v}[RESPONSIVE] Child[${T}] has no scale (type: ${w.constructor.name})`)})};var f=m;console.log("[RESPONSIVE] Applying scale to PIXI stage children"),m(g.stage)}else console.warn("[RESPONSIVE] No app.stage found!");console.log("[REDDEBUG] Debug border left unscaled (fixed boundaries)"),console.log("[RESPONSIVE] ===== GLOBAL RESPONSIVE SCALING COMPLETE =====")}function l(g){if(g!==void 0){wt.scale=g,console.log(`[RESPONSIVE] Updated global scale multiplier to: ${g.toFixed(3)}`);let h=window.gameApp,f=window.gameObjectManager;h&&f?(o(h,f),h.renderer&&(h.renderer.render(h.stage),console.log("[RESPONSIVE] Forced PIXI renderer update"))):console.warn(`[RESPONSIVE] No gameApp (${!!h}) or gameObjectManager (${!!f}) found in window for live update`)}}window.updateGlobalResponsiveMultipliers=l,qe.start()},Dr=async()=>{var e,t,i,n;console.log("[PREVIEW] Restarting game in 1 seconds...");let r=(e=window.gameObjectManager)==null?void 0:e.get("character_1");if(r){let a=((t=r.getDisplayObject)==null?void 0:t.call(r))||r;a&&a.scale&&console.log(`[CHARACTER] Before restart - Current scale - x: ${((i=a.scale.x)!=null?i:1).toFixed(3)}, y: ${((n=a.scale.y)!=null?n:1).toFixed(3)}`)}if(Se){Se.notifyGameDestroyed();try{Ha&&Ha()}catch(a){console.warn("Failed to clear responsive elements",a)}setTimeout(()=>{console.log("[PREVIEW] Executing restart...");let a=Se.getGameContainer(),s=window.gameObjectManager;if(s&&typeof s.clear=="function"&&(console.log("[PREVIEW] Clearing old GameObjectManager tickers..."),s.clear()),Ge){try{Ge.destroy(!0,{children:!0,texture:!1})}catch(o){console.warn("[PREVIEW] Destroy warning:",o)}Ge=null}window.gameApp=null,window.gameObjectManager=null,a&&(a.innerHTML="");try{typeof Xt.resetScene=="function"&&Xt.resetScene()}catch(o){console.warn("Asset reset failed",o)}setTimeout(()=>{Ie("scene.main").then(o=>{window.__editableConfig=o,window.__editableConfigBaseline||(window.__editableConfigBaseline=Q(o)),Fa(a,o,Kt).then(l=>{Ge=l.app,window.gameApp=Ge,window.gameObjectManager=l.gameObjectManager;try{window.__liveEditBridge=hn({getConfig:()=>window.__editableConfig,gameObjectManager:window.gameObjectManager,assets:Xt})}catch(c){console.warn("[BOOTSTRAP] Failed to re-initialize live-edit bridge",c)}Se&&Se.notifyGameLoaded(),console.log("[PREVIEW] Game restarted successfully");try{qe.start()}catch{}})})},100)},1e3)}};Ti();ee();var Ee={background:"#F6F3EF",ink:"#1E1E1E",secondaryText:"#8E8A84",primaryAccent:"#E38A5A",secondaryAccent:"#C9A28C",statusGreen:"#5F8F6B"},Fr=1.25,Br={fontFamily:"Inter, system-ui, sans-serif"};var mn=class{constructor(e={}){this.currentProgress=0;var t;this.currentProgress=(t=e.progress)!=null?t:0,this.container=this.createContainer()}createContainer(){let e=document.createElement("div");e.className="handler-loading-screen",e.style.cssText=`
|
|
2542
2564
|
position: fixed;
|
|
2543
2565
|
inset: 0;
|
|
2544
2566
|
display: flex;
|
|
@@ -2573,17 +2595,17 @@ Style guidelines: ${i.summary}`;this.promptInput.value=n,this.currentPrompt=n}}c
|
|
|
2573
2595
|
justify-content: space-between;
|
|
2574
2596
|
align-items: flex-end;
|
|
2575
2597
|
margin-bottom: 8px;
|
|
2576
|
-
`;let
|
|
2598
|
+
`;let s=document.createElement("span");s.style.cssText=`
|
|
2577
2599
|
font-size: 12px;
|
|
2578
2600
|
font-weight: 900;
|
|
2579
2601
|
letter-spacing: 0.15em;
|
|
2580
2602
|
color: ${Ee.ink};
|
|
2581
|
-
`,
|
|
2603
|
+
`,s.innerHTML='LOADING<span class="loading-dots" style="animation: pulse 1.5s infinite;">..</span>',this.progressText=document.createElement("span"),this.progressText.style.cssText=`
|
|
2582
2604
|
font-size: 10px;
|
|
2583
2605
|
font-family: monospace;
|
|
2584
2606
|
font-weight: bold;
|
|
2585
2607
|
color: ${Ee.primaryAccent};
|
|
2586
|
-
`,this.progressText.textContent=`${Math.floor(this.currentProgress)}%`,a.appendChild(
|
|
2608
|
+
`,this.progressText.textContent=`${Math.floor(this.currentProgress)}%`,a.appendChild(s),a.appendChild(this.progressText);let o=document.createElement("div");o.style.cssText=`
|
|
2587
2609
|
height: 4px;
|
|
2588
2610
|
width: 100%;
|
|
2589
2611
|
background-color: #E0DDD8;
|
|
@@ -2737,7 +2759,7 @@ Style guidelines: ${i.summary}`;this.promptInput.value=n,this.currentPrompt=n}}c
|
|
|
2737
2759
|
0%, 100% { opacity: 1; }
|
|
2738
2760
|
50% { opacity: 0.3; }
|
|
2739
2761
|
}
|
|
2740
|
-
`,document.head.appendChild(e)}setProgress(e){this.currentProgress=Math.max(0,Math.min(100,e)),this.progressBar.style.width=`${this.currentProgress}%`,this.progressText.textContent=`${Math.floor(this.currentProgress)}%`,this.authSeq.textContent=`Auth_Seq: 0x${Math.floor(this.currentProgress*2.55).toString(16).toUpperCase()} // System_Ready`}mount(e=document.body){e.appendChild(this.container)}unmount(){this.container.parentElement&&this.container.parentElement.removeChild(this.container)}getElement(){return this.container}};var Ba=ls.version,kl=new Set(["init","boot","view","ready","start","pause","resume","complete","error","engagement","first_interaction","retry","cta_show","cta_click","cta_dismiss","clickout","conversion","session_time","level_time","load_time","level_start","level_complete","level_fail","checkpoint","reward","tutorial_start","tutorial_complete","tutorial_skip","ab_assign","fps","memory","asset_load_start","asset_load_complete"]);os();var Kr={mechanic_id:"TODO_mechanic_id",variant_id:"TODO_variant_id",deployment_id:"TODO_deployment_id",export_id:"TODO_export_id",profile_id:"TODO_profile_id",instance_id:"default"},Xr=Math.random().toString(36).slice(2),Et=null,xt={...Kr},Jr="web_embed",Va={},Zt,Ga=!1,Jt=!1,ei=!1,Zr=!1,Xa=1,yn=0,xn=!1,Me=!1,St="",Ct=Math.floor(window.innerWidth),At=Math.floor(window.innerHeight),Ya=Ct>At,je=!1,Qt=!1,Gr=!1,Ur=!1,Ua=!1,vn=null,it=null,Wa=!1,Ka=!1,bn=new Map;function Qr(){if(!it)return null;let s=Date.now()-it;return!Number.isFinite(s)||s<0?null:s}function qa(s){if(Wa)return;let e=Qr();e!==null&&(Wa=!0,N("session_time",{duration_ms:e,reason:s}))}function qr(){if(Et)return Et;let s=document.createElement("div");return s.id="handler-root",s.setAttribute("data-handler-root","true"),document.body.appendChild(s),Et=s,s}function wn(s){switch(s){case"interaction":return"engagement";case"finish":return"complete";case"install":return"cta_click";default:return s}}function eo(s,e){return{event_name:s,ts:Date.now(),session_id:Xr,deployment_id:xt.deployment_id,variant_id:xt.variant_id,export_profile_id:xt.profile_id,instance_id:xt.instance_id||"default",env:Jr==="mraid"?"mraid":"web",attribution:Zt,payload:e}}function N(s,e){let t=wn(s),i=eo(t,e);Ln(i,!!Va.analytics),si(t,i),t!==s&&si(s,i)}function ti(){vn&&(vn(Ct,At),vn=null)}function Lt(s){Xa=s,N("volume",s)}function Tt(s){s&&(Zr=!0),!ei&&(ei=!0,N("pause"),Lt(0))}function ii(s){!s&&Zr||ei&&(ei=!1,N("resume"),Lt(Xa))}function Ue(s,e){Ct=Math.floor(s||window.innerWidth),At=Math.floor(e||window.innerHeight),Ya=Ct>At,N("resize",{width:Ct,height:At})}function Il(){if(ws())try{let s=mraid.getMaxSize();Ue(s.width,s.height);let e=()=>{mraid.isViewable()&&mraid.getState()!=="hidden"?ii():Tt()};if(mraid.addEventListener("viewableChange",e),mraid.addEventListener("stateChange",e),mraid.addEventListener("sizeChange",()=>{let t=mraid.getMaxSize();Ue(t.width,t.height)}),mraid.getAudioVolume){let t=mraid.getAudioVolume();Lt(t?1:0)}if(mraid.addEventListener("audioVolumeChange",t=>{t!==null&&Lt(t>0?1:0)}),mraid.addEventListener("error",(t,i)=>{console.warn("mraid error:",t,"action:",i)}),xn=!0,mraid.isViewable()&&mraid.getState()!=="hidden")je=!0,N("boot"),N("view"),N("ready"),Me=!0,ti();else{let t=()=>{je=!0,N("boot"),N("view"),N("ready"),Me=!0,ti()};mraid.addEventListener("ready",t)}}catch(s){console.warn("MRAID hook skipped",s)}}function Pl(){if(xs())try{let s=dapi.getScreenSize();Ue(s.width,s.height),dapi.addEventListener("viewableChange",t=>{t.isViewable?ii():Tt()}),dapi.addEventListener("adResized",t=>{let i=dapi.getScreenSize();Ue(t.width||i.width,t.height||i.height)});let e=dapi.getAudioVolume();if(Lt(e?1:0),dapi.addEventListener("audioVolumeChange",t=>Lt(t?1:0)),xn=!0,dapi.isViewable())je=!0,N("boot"),N("view"),N("ready"),Me=!0,ti();else{let t=()=>{je=!0,N("boot"),N("view"),N("ready"),Me=!0,ti()};dapi.addEventListener("ready",t)}}catch(s){console.warn("DAPI hook skipped",s)}}function Vr(){let s=()=>{je||document.visibilityState==="visible"&&(document.readyState==="complete"||document.readyState==="interactive")&&(je=!0,N("boot"),N("view"),N("ready"),Me=!0,ti(),Qt&&(Qt=!1,me.start()))};window.addEventListener("resize",()=>Ue()),document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"?(ii(),s()):Tt()}),document.readyState==="complete"||document.readyState==="interactive"?s():window.addEventListener("load",s),xn=!0}function Ml(){let s=e=>{typeof TouchEvent!="undefined"&&e instanceof TouchEvent&&(Gr=!0),!(Gr&&e instanceof MouseEvent)&&(yn+=1,Ka||(Ka=!0,N("first_interaction",{count:yn})),N("interaction",yn))};document.addEventListener("mousedown",s),document.addEventListener("touchstart",s)}function Yr(s){var i,n,a,r,o,l,c,d,p,u,g,h;let e=typeof AD_PROTOCOL!="undefined"?AD_PROTOCOL:"none";if((typeof AD_NETWORK!="undefined"?AD_NETWORK:"web_embed")==="google")try{(i=window.ExitApi)==null||i.exit();return}catch{}if(e==="mraid"&&typeof mraid!="undefined")mraid.open(s||"");else if(e==="dapi"&&typeof dapi!="undefined")dapi.openStoreUrl();else if(lt())(a=(n=window.TJ_API)==null?void 0:n.click)==null||a.call(n);else if(Ss())(o=(r=window.FbPlayableAd)==null?void 0:r.onCTAClick)==null||o.call(r);else if(Ls())(c=(l=window.ScPlayableAd)==null?void 0:l.onCTAClick)==null||c.call(l);else if(As())try{(p=(d=window.smxTracking)==null?void 0:d.redirect)==null||p.call(d)}catch(f){console.warn("Smadex redirect failed",f)}else if(Es()){let f=window.ExitApi;f&&typeof f.exit=="function"?f.exit(s||St||""):s&&window.open(s)}else ot()?(u=window.install)==null||u.call(window):Cs()?(g=window.openAppStore)==null||g.call(window):Tn()?(h=parent==null?void 0:parent.postMessage)==null||h.call(parent,"download","*"):s&&window.open(s)}function jl(){let s=typeof AD_NETWORK!="undefined"?AD_NETWORK:"web_embed",e=t=>{if(!t)return;let i=new Image;i.src=t};if(s==="bigabid"){let t=window.BIGABID_BIDTIMEMACROS;if(!t)return;oe("view",()=>e(t.mraid_viewable)),oe("start",()=>e(t.game_viewable)),oe("engagement",()=>e(t.engagement));let i=()=>e(t.complete);oe("complete",i),ai("engagement",n=>{var a;((a=n==null?void 0:n.payload)==null?void 0:a.count)>3&&i()}),oe("cta_click",()=>e(t.click))}else if(s==="inmobi"){let t=window.INMOBI_DSPMACROS;if(!t)return;oe("view",()=>e(t.Ad_Load_Start)),oe("start",()=>e(t.Ad_Viewable)),oe("engagement",()=>e(t.First_Engagement)),oe("complete",()=>e(t.Gameplay_Complete)),oe("cta_click",()=>e(t.DSP_Click)),oe("start",()=>{[5,10,15,20,25,30].forEach(i=>setTimeout(()=>e(t[`Spent_${i}_Seconds`]),i*1e3))})}}function _l(){if(!lt())return;let s=window.TJ_API;s&&s.setPlayableAPI&&s.setPlayableAPI({skipAd:()=>{try{me.finish()}catch(e){console.warn("Tapjoy skip failed",e)}}})}function Wr(){var e,t,i;let s=window.TJ_API;(e=s==null?void 0:s.objectiveComplete)==null||e.call(s),(t=s==null?void 0:s.playableFinished)==null||t.call(s),(i=s==null?void 0:s.gameplayFinished)==null||i.call(s)}function Ol(){ot()&&(window.mintGameStart=()=>{ii(!0),Ue()},window.mintGameClose=()=>{Tt(!0)})}function Rl(){if(!kn())return;let s=window.NUC;!s||!s.trigger||(me.on("cta_click",()=>{var e,t;return(t=(e=s.trigger).convert)==null?void 0:t.call(e,St)}),me.on("complete",()=>{var e,t;return(t=(e=s.trigger).tryAgain)==null?void 0:t.call(e)}))}var me={init(s={},e){var t;if(Jr=s.profile||"web_embed",Va=s.consent||{},xt={...Kr,...s.ids||{}},Et=s.rootEl||Et,Zt=void 0,es((t=s.telemetry)!=null&&t.endpoint?s.telemetry:null),it=null,Wa=!1,Ka=!1,bn.clear(),St=s.destinationUrl||(/android/i.test(navigator.userAgent)?"https://play.google.com/store":"https://www.apple.com/app-store/"),e&&(vn=e),N("init"),document.body.oncontextmenu=()=>!1,qr(),$l(Et),Ts(),Il(),Pl(),!xn){if(document.readyState==="complete")Vr();else if(!Ur){Ur=!0;let i=()=>{Vr(),window.removeEventListener("load",i),document.removeEventListener("DOMContentLoaded",i)};window.addEventListener("load",i),document.addEventListener("DOMContentLoaded",i)}}Ml(),jl(),_l(),Ol(),Rl(),console.log(`%c @handler/playable-sdk %c v${Ba} `,"background: var(--ui-console-info); color: var(--ui-white); font-size: 14px; padding: 4px 8px; border-top-left-radius: 4px; border-bottom-left-radius: 4px;","background: var(--ui-console-bg); color: var(--ui-console-text); font-size: 14px; padding: 4px 8px; border-top-right-radius: 4px; border-bottom-right-radius: 4px;"),je&&!Me&&(N("boot"),N("view"),N("ready"),Qt&&(Qt=!1,me.start()),Me=!0),Me=je},getRoot(){return qr()},get version(){return Ba},get maxWidth(){return Ct},get maxHeight(){return At},get isLandscape(){return Ya},get isReady(){return Me},get isStarted(){return Ga},get isPaused(){return ei},get isFinished(){return Jt},get volume(){return Xa},get interactions(){return yn},on(s,e){ai(wn(s),e)},off(s,e){An(wn(s),e)},start(){var s,e;if(!Ga){if(!je){Qt=!0;return}if(Ga=!0,it||(it=Date.now()),N("start"),Ue(),ot())Tt(),(s=window.gameReady)==null||s.call(window);else if(lt()){let t=window.TJ_API;(e=t==null?void 0:t.setPlayableBuild)==null||e.call(t,{orientation:Ya?"landscape":"portrait",buildID:Ba})}}},finish(){var s,e;Jt||(Jt=!0,N("complete"),qa("complete"),ot()?(s=window.gameEnd)==null||s.call(window):Tn()?(e=parent==null?void 0:parent.postMessage)==null||e.call(parent,"complete","*"):lt()&&Wr())},install(s){if(!Jt){Jt=!0,lt()?(Wr(),setTimeout(()=>me.install(s),300)):(N("complete"),setTimeout(()=>me.install(s),0));return}Ua||(Ua=!0,setTimeout(()=>Ua=!1,500),N("cta_click"),N("conversion"),qa("cta"),Yr(s||St))},emit(s,e){let t=wn(s);if(!kl.has(t)&&t!=="resize"&&t!=="volume"&&!t.startsWith("custom."))throw new Error(`Event ${s} must be canonical or namespaced as custom.<mechanic_id>.<event>`);let i=eo(t,e);Ln(i,!!Va.analytics),si(t,i)},gameStart(){me.start()},gameEnd(){me.finish()},ctaClick(s,e){N("cta_click",{url:s||St,manual:!0}),(e==null?void 0:e.open)!==!1&&Yr(s||St)},ctaShow(s){N("cta_show",s)},ctaDismiss(s){N("cta_dismiss",s)},getGameTimeMs(){return Qr()},endSession(s="manual"){qa(s)},setAttribution(s){Zt=s},abTest(s,e){if(!s)throw new Error("abTest requires experimentId");if(!Array.isArray(e)||e.length<2)throw new Error("abTest requires at least 2 variants");let t=Math.abs(zl(`${Xr}:${s}`))%e.length,i=e[t];return Zt={...Zt||{},experiment_id:s},xt.variant_id=i,N("ab_assign",{experiment_id:s,variant_id:i}),i},levelStart(s,e){it||(it=Date.now()),N("level_start",{level_id:s,...e})},levelComplete(s,e){N("level_complete",{level_id:s,...e})},levelFail(s,e){N("level_fail",{level_id:s,...e})},checkpoint(s,e){N("checkpoint",{checkpoint_id:s,...e})},reward(s,e){N("reward",{reward_id:s,...e})},tutorialStart(s,e){N("tutorial_start",{step_id:s,...e})},tutorialComplete(s,e){N("tutorial_complete",{step_id:s,...e})},tutorialSkip(s,e){N("tutorial_skip",{step_id:s,...e})},timerStart(s){s&&bn.set(s,Date.now())},timerEnd(s,e="custom",t){if(!s)return;let i=bn.get(s);if(!i)return;bn.delete(s);let n=Date.now()-i;if(!(!Number.isFinite(n)||n<0)){if(e==="custom"){N("engagement",{action:"timer",key:s,duration_ms:n,...t});return}N(e,{key:s,duration_ms:n,...t})}},fps(s,e){N("fps",{value:s,...e})},memory(s,e){N("memory",{bytes:s,...e})},assetLoadStart(s,e){N("asset_load_start",{asset_id:s,...e})},assetLoadComplete(s,e){N("asset_load_complete",{asset_id:s,...e})},reportError(s,e,t){N("error",{code:s,message:e,...t})},retry(){var s,e,t;if(ot())(s=window.gameRetry)==null||s.call(window);else if(kn()){let i=window.NUC;(t=(e=i==null?void 0:i.trigger)==null?void 0:e.tryAgain)==null||t.call(e)}N("engagement",{action:"retry"})},pause(){Tt(!0)},resume(){ii(!0)},resize(s,e){Ue(s,e)}},qe=me;function zl(s){let e=2166136261;for(let t=0;t<s.length;t++)e^=s.charCodeAt(t),e=Math.imul(e,16777619);return e|0}function $l(s){let e=document.createElement("script");e.type="text/javascript",e.textContent=`
|
|
2762
|
+
`,document.head.appendChild(e)}setProgress(e){this.currentProgress=Math.max(0,Math.min(100,e)),this.progressBar.style.width=`${this.currentProgress}%`,this.progressText.textContent=`${Math.floor(this.currentProgress)}%`,this.authSeq.textContent=`Auth_Seq: 0x${Math.floor(this.currentProgress*2.55).toString(16).toUpperCase()} // System_Ready`}mount(e=document.body){e.appendChild(this.container)}unmount(){this.container.parentElement&&this.container.parentElement.removeChild(this.container)}getElement(){return this.container}};var Ba=ls.version,kl=new Set(["init","boot","view","ready","start","pause","resume","complete","error","engagement","first_interaction","retry","cta_show","cta_click","cta_dismiss","clickout","conversion","session_time","level_time","load_time","level_start","level_complete","level_fail","checkpoint","reward","tutorial_start","tutorial_complete","tutorial_skip","ab_assign","fps","memory","asset_load_start","asset_load_complete"]);os();var Kr={mechanic_id:"TODO_mechanic_id",variant_id:"TODO_variant_id",deployment_id:"TODO_deployment_id",export_id:"TODO_export_id",profile_id:"TODO_profile_id",instance_id:"default"},Xr=Math.random().toString(36).slice(2),Et=null,xt={...Kr},Jr="web_embed",Va={},Zt,Ga=!1,Jt=!1,ei=!1,Zr=!1,Xa=1,yn=0,xn=!1,Me=!1,St="",Ct=Math.floor(window.innerWidth),At=Math.floor(window.innerHeight),Ya=Ct>At,je=!1,Qt=!1,Gr=!1,Ur=!1,Ua=!1,vn=null,it=null,Wa=!1,Ka=!1,bn=new Map;function Qr(){if(!it)return null;let r=Date.now()-it;return!Number.isFinite(r)||r<0?null:r}function qa(r){if(Wa)return;let e=Qr();e!==null&&(Wa=!0,N("session_time",{duration_ms:e,reason:r}))}function qr(){if(Et)return Et;let r=document.createElement("div");return r.id="handler-root",r.setAttribute("data-handler-root","true"),document.body.appendChild(r),Et=r,r}function wn(r){switch(r){case"interaction":return"engagement";case"finish":return"complete";case"install":return"cta_click";default:return r}}function eo(r,e){return{event_name:r,ts:Date.now(),session_id:Xr,deployment_id:xt.deployment_id,variant_id:xt.variant_id,export_profile_id:xt.profile_id,instance_id:xt.instance_id||"default",env:Jr==="mraid"?"mraid":"web",attribution:Zt,payload:e}}function N(r,e){let t=wn(r),i=eo(t,e);Ln(i,!!Va.analytics),si(t,i),t!==r&&si(r,i)}function ti(){vn&&(vn(Ct,At),vn=null)}function Lt(r){Xa=r,N("volume",r)}function Tt(r){r&&(Zr=!0),!ei&&(ei=!0,N("pause"),Lt(0))}function ii(r){!r&&Zr||ei&&(ei=!1,N("resume"),Lt(Xa))}function Ue(r,e){Ct=Math.floor(r||window.innerWidth),At=Math.floor(e||window.innerHeight),Ya=Ct>At,N("resize",{width:Ct,height:At})}function Il(){if(ws())try{let r=mraid.getMaxSize();Ue(r.width,r.height);let e=()=>{mraid.isViewable()&&mraid.getState()!=="hidden"?ii():Tt()};if(mraid.addEventListener("viewableChange",e),mraid.addEventListener("stateChange",e),mraid.addEventListener("sizeChange",()=>{let t=mraid.getMaxSize();Ue(t.width,t.height)}),mraid.getAudioVolume){let t=mraid.getAudioVolume();Lt(t?1:0)}if(mraid.addEventListener("audioVolumeChange",t=>{t!==null&&Lt(t>0?1:0)}),mraid.addEventListener("error",(t,i)=>{console.warn("mraid error:",t,"action:",i)}),xn=!0,mraid.isViewable()&&mraid.getState()!=="hidden")je=!0,N("boot"),N("view"),N("ready"),Me=!0,ti();else{let t=()=>{je=!0,N("boot"),N("view"),N("ready"),Me=!0,ti()};mraid.addEventListener("ready",t)}}catch(r){console.warn("MRAID hook skipped",r)}}function Pl(){if(xs())try{let r=dapi.getScreenSize();Ue(r.width,r.height),dapi.addEventListener("viewableChange",t=>{t.isViewable?ii():Tt()}),dapi.addEventListener("adResized",t=>{let i=dapi.getScreenSize();Ue(t.width||i.width,t.height||i.height)});let e=dapi.getAudioVolume();if(Lt(e?1:0),dapi.addEventListener("audioVolumeChange",t=>Lt(t?1:0)),xn=!0,dapi.isViewable())je=!0,N("boot"),N("view"),N("ready"),Me=!0,ti();else{let t=()=>{je=!0,N("boot"),N("view"),N("ready"),Me=!0,ti()};dapi.addEventListener("ready",t)}}catch(r){console.warn("DAPI hook skipped",r)}}function Vr(){let r=()=>{je||document.visibilityState==="visible"&&(document.readyState==="complete"||document.readyState==="interactive")&&(je=!0,N("boot"),N("view"),N("ready"),Me=!0,ti(),Qt&&(Qt=!1,me.start()))};window.addEventListener("resize",()=>Ue()),document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"?(ii(),r()):Tt()}),document.readyState==="complete"||document.readyState==="interactive"?r():window.addEventListener("load",r),xn=!0}function Ml(){let r=e=>{typeof TouchEvent!="undefined"&&e instanceof TouchEvent&&(Gr=!0),!(Gr&&e instanceof MouseEvent)&&(yn+=1,Ka||(Ka=!0,N("first_interaction",{count:yn})),N("interaction",yn))};document.addEventListener("mousedown",r),document.addEventListener("touchstart",r)}function Yr(r){var i,n,a,s,o,l,c,d,p,u,g,h;let e=typeof AD_PROTOCOL!="undefined"?AD_PROTOCOL:"none";if((typeof AD_NETWORK!="undefined"?AD_NETWORK:"web_embed")==="google")try{(i=window.ExitApi)==null||i.exit();return}catch{}if(e==="mraid"&&typeof mraid!="undefined")mraid.open(r||"");else if(e==="dapi"&&typeof dapi!="undefined")dapi.openStoreUrl();else if(lt())(a=(n=window.TJ_API)==null?void 0:n.click)==null||a.call(n);else if(Ss())(o=(s=window.FbPlayableAd)==null?void 0:s.onCTAClick)==null||o.call(s);else if(Ls())(c=(l=window.ScPlayableAd)==null?void 0:l.onCTAClick)==null||c.call(l);else if(As())try{(p=(d=window.smxTracking)==null?void 0:d.redirect)==null||p.call(d)}catch(f){console.warn("Smadex redirect failed",f)}else if(Es()){let f=window.ExitApi;f&&typeof f.exit=="function"?f.exit(r||St||""):r&&window.open(r)}else ot()?(u=window.install)==null||u.call(window):Cs()?(g=window.openAppStore)==null||g.call(window):Tn()?(h=parent==null?void 0:parent.postMessage)==null||h.call(parent,"download","*"):r&&window.open(r)}function jl(){let r=typeof AD_NETWORK!="undefined"?AD_NETWORK:"web_embed",e=t=>{if(!t)return;let i=new Image;i.src=t};if(r==="bigabid"){let t=window.BIGABID_BIDTIMEMACROS;if(!t)return;oe("view",()=>e(t.mraid_viewable)),oe("start",()=>e(t.game_viewable)),oe("engagement",()=>e(t.engagement));let i=()=>e(t.complete);oe("complete",i),ai("engagement",n=>{var a;((a=n==null?void 0:n.payload)==null?void 0:a.count)>3&&i()}),oe("cta_click",()=>e(t.click))}else if(r==="inmobi"){let t=window.INMOBI_DSPMACROS;if(!t)return;oe("view",()=>e(t.Ad_Load_Start)),oe("start",()=>e(t.Ad_Viewable)),oe("engagement",()=>e(t.First_Engagement)),oe("complete",()=>e(t.Gameplay_Complete)),oe("cta_click",()=>e(t.DSP_Click)),oe("start",()=>{[5,10,15,20,25,30].forEach(i=>setTimeout(()=>e(t[`Spent_${i}_Seconds`]),i*1e3))})}}function _l(){if(!lt())return;let r=window.TJ_API;r&&r.setPlayableAPI&&r.setPlayableAPI({skipAd:()=>{try{me.finish()}catch(e){console.warn("Tapjoy skip failed",e)}}})}function Wr(){var e,t,i;let r=window.TJ_API;(e=r==null?void 0:r.objectiveComplete)==null||e.call(r),(t=r==null?void 0:r.playableFinished)==null||t.call(r),(i=r==null?void 0:r.gameplayFinished)==null||i.call(r)}function Ol(){ot()&&(window.mintGameStart=()=>{ii(!0),Ue()},window.mintGameClose=()=>{Tt(!0)})}function Rl(){if(!kn())return;let r=window.NUC;!r||!r.trigger||(me.on("cta_click",()=>{var e,t;return(t=(e=r.trigger).convert)==null?void 0:t.call(e,St)}),me.on("complete",()=>{var e,t;return(t=(e=r.trigger).tryAgain)==null?void 0:t.call(e)}))}var me={init(r={},e){var t;if(Jr=r.profile||"web_embed",Va=r.consent||{},xt={...Kr,...r.ids||{}},Et=r.rootEl||Et,Zt=void 0,es((t=r.telemetry)!=null&&t.endpoint?r.telemetry:null),it=null,Wa=!1,Ka=!1,bn.clear(),St=r.destinationUrl||(/android/i.test(navigator.userAgent)?"https://play.google.com/store":"https://www.apple.com/app-store/"),e&&(vn=e),N("init"),document.body.oncontextmenu=()=>!1,qr(),$l(Et),Ts(),Il(),Pl(),!xn){if(document.readyState==="complete")Vr();else if(!Ur){Ur=!0;let i=()=>{Vr(),window.removeEventListener("load",i),document.removeEventListener("DOMContentLoaded",i)};window.addEventListener("load",i),document.addEventListener("DOMContentLoaded",i)}}Ml(),jl(),_l(),Ol(),Rl(),console.log(`%c @handler/playable-sdk %c v${Ba} `,"background: var(--ui-console-info); color: var(--ui-white); font-size: 14px; padding: 4px 8px; border-top-left-radius: 4px; border-bottom-left-radius: 4px;","background: var(--ui-console-bg); color: var(--ui-console-text); font-size: 14px; padding: 4px 8px; border-top-right-radius: 4px; border-bottom-right-radius: 4px;"),je&&!Me&&(N("boot"),N("view"),N("ready"),Qt&&(Qt=!1,me.start()),Me=!0),Me=je},getRoot(){return qr()},get version(){return Ba},get maxWidth(){return Ct},get maxHeight(){return At},get isLandscape(){return Ya},get isReady(){return Me},get isStarted(){return Ga},get isPaused(){return ei},get isFinished(){return Jt},get volume(){return Xa},get interactions(){return yn},on(r,e){ai(wn(r),e)},off(r,e){An(wn(r),e)},start(){var r,e;if(!Ga){if(!je){Qt=!0;return}if(Ga=!0,it||(it=Date.now()),N("start"),Ue(),ot())Tt(),(r=window.gameReady)==null||r.call(window);else if(lt()){let t=window.TJ_API;(e=t==null?void 0:t.setPlayableBuild)==null||e.call(t,{orientation:Ya?"landscape":"portrait",buildID:Ba})}}},finish(){var r,e;Jt||(Jt=!0,N("complete"),qa("complete"),ot()?(r=window.gameEnd)==null||r.call(window):Tn()?(e=parent==null?void 0:parent.postMessage)==null||e.call(parent,"complete","*"):lt()&&Wr())},install(r){if(!Jt){Jt=!0,lt()?(Wr(),setTimeout(()=>me.install(r),300)):(N("complete"),setTimeout(()=>me.install(r),0));return}Ua||(Ua=!0,setTimeout(()=>Ua=!1,500),N("cta_click"),N("conversion"),qa("cta"),Yr(r||St))},emit(r,e){let t=wn(r);if(!kl.has(t)&&t!=="resize"&&t!=="volume"&&!t.startsWith("custom."))throw new Error(`Event ${r} must be canonical or namespaced as custom.<mechanic_id>.<event>`);let i=eo(t,e);Ln(i,!!Va.analytics),si(t,i)},gameStart(){me.start()},gameEnd(){me.finish()},ctaClick(r,e){N("cta_click",{url:r||St,manual:!0}),(e==null?void 0:e.open)!==!1&&Yr(r||St)},ctaShow(r){N("cta_show",r)},ctaDismiss(r){N("cta_dismiss",r)},getGameTimeMs(){return Qr()},endSession(r="manual"){qa(r)},setAttribution(r){Zt=r},abTest(r,e){if(!r)throw new Error("abTest requires experimentId");if(!Array.isArray(e)||e.length<2)throw new Error("abTest requires at least 2 variants");let t=Math.abs(zl(`${Xr}:${r}`))%e.length,i=e[t];return Zt={...Zt||{},experiment_id:r},xt.variant_id=i,N("ab_assign",{experiment_id:r,variant_id:i}),i},levelStart(r,e){it||(it=Date.now()),N("level_start",{level_id:r,...e})},levelComplete(r,e){N("level_complete",{level_id:r,...e})},levelFail(r,e){N("level_fail",{level_id:r,...e})},checkpoint(r,e){N("checkpoint",{checkpoint_id:r,...e})},reward(r,e){N("reward",{reward_id:r,...e})},tutorialStart(r,e){N("tutorial_start",{step_id:r,...e})},tutorialComplete(r,e){N("tutorial_complete",{step_id:r,...e})},tutorialSkip(r,e){N("tutorial_skip",{step_id:r,...e})},timerStart(r){r&&bn.set(r,Date.now())},timerEnd(r,e="custom",t){if(!r)return;let i=bn.get(r);if(!i)return;bn.delete(r);let n=Date.now()-i;if(!(!Number.isFinite(n)||n<0)){if(e==="custom"){N("engagement",{action:"timer",key:r,duration_ms:n,...t});return}N(e,{key:r,duration_ms:n,...t})}},fps(r,e){N("fps",{value:r,...e})},memory(r,e){N("memory",{bytes:r,...e})},assetLoadStart(r,e){N("asset_load_start",{asset_id:r,...e})},assetLoadComplete(r,e){N("asset_load_complete",{asset_id:r,...e})},reportError(r,e,t){N("error",{code:r,message:e,...t})},retry(){var r,e,t;if(ot())(r=window.gameRetry)==null||r.call(window);else if(kn()){let i=window.NUC;(t=(e=i==null?void 0:i.trigger)==null?void 0:e.tryAgain)==null||t.call(e)}N("engagement",{action:"retry"})},pause(){Tt(!0)},resume(){ii(!0)},resize(r,e){Ue(r,e)}},qe=me;function zl(r){let e=2166136261;for(let t=0;t<r.length;t++)e^=r.charCodeAt(t),e=Math.imul(e,16777619);return e|0}function $l(r){let e=document.createElement("script");e.type="text/javascript",e.textContent=`
|
|
2741
2763
|
(function(){
|
|
2742
2764
|
var events = ['touchstart','touchend','mousedown','keydown'];
|
|
2743
2765
|
function unlock(){
|
|
@@ -2753,4 +2775,4 @@ Style guidelines: ${i.summary}`;this.promptInput.value=n,this.currentPrompt=n}}c
|
|
|
2753
2775
|
}
|
|
2754
2776
|
events.forEach(function(e){ document.addEventListener(e, unlock, false); });
|
|
2755
2777
|
})();
|
|
2756
|
-
`,
|
|
2778
|
+
`,r.appendChild(e)}0&&(module.exports={COLORS,ConfigWatcher,DebugPanel,DefaultReloadStrategy,Handler,PlayableLoadingScreen,PreviewShell,STROKE_WIDTH,THEME,applyConfigOverride,applyConfigOverrides,applyConfigsToDisk,applyDefaults,baseLottie,bootstrap,clearConfigOverrides,clearConfigOverridesForObject,configOverrideManager,createPreviewShell,deepClone,defaultPreset,deviceGroups,devicePresets,diffConfigs,exportConfigsAsJSON,getConfigOverrides,getConfigStateSummary,getOverrideMode,getPresetById,getPresetsByCategory,loadAllObjectConfigs,loadComponentSchemas,loadEngineConfig,loadGamePromptConfig,loadObjectCentricConfig,loadObjectConfig,loadSceneConfig,redoLastConfigChange,rehydrateObject,removeConfigOverride,resetToApplied,resetToOriginal,setBootstrapDependencies,setOverrideMode,setupHotReload,setupLiveEditBridge,toLegacyFormat,trackObjectCreation,trackObjectDeletion,undoLastConfigChange,validateObjectConfig});
|