UNPKG

@needle-tools/engine

Version:

Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in.

143 lines (131 loc) โ€ข 1.29 MB
"use strict";const c=require("./three.umd.cjs"),re=require("./gltf-progressive-DJBMx-zB.umd.cjs"),X=require("./three-examples.umd.cjs"),le=require("./vendor-CntUvmJu.umd.cjs"),ie=require("./three-mesh-ui-Chib781Y.umd.cjs"),Kx=require("./postprocessing-B2wb6pzI.umd.cjs");var ya=typeof document<"u"?document.currentScript:null;const Yy=typeof window!==void 0?window.location.search.includes("debugcontext"):!1;var ae=(s=>(s.ContextRegistered="ContextRegistered",s.ContextCreationStart="ContextCreationStart",s.ContextCreated="ContextCreated",s.ContextFirstFrameRendered="ContextFirstFrameRendered",s.ContextDestroying="ContextDestroying",s.ContextDestroyed="ContextDestroyed",s.MissingCamera="MissingCamera",s.ContextClearing="ContextClearing",s.ContextCleared="ContextCleared",s))(ae||{});class ce{static get Current(){return globalThis["NeedleEngine.Context.Current"]}static set Current(e){globalThis["NeedleEngine.Context.Current"]=e}static get All(){return this.Registered}static Registered=[];static register(e){this.Registered.indexOf(e)===-1&&(Yy&&console.warn("Registering context"),this.Registered.push(e),this.dispatchCallback("ContextRegistered",e))}static unregister(e){const t=this.Registered.indexOf(e);t!==-1&&(Yy&&console.warn("Unregistering context"),this.Registered.splice(t,1))}static _callbacks={};static registerCallback(e,t){this._callbacks[e]||(this._callbacks[e]=[]),this._callbacks[e].push(t)}static unregisterCallback(e,t){if(!this._callbacks[e])return;const i=this._callbacks[e].indexOf(t);i!==-1&&this._callbacks[e].splice(i,1)}static dispatchCallback(e,t,i){if(!this._callbacks[e])return!0;const n={event:e,context:t};if(i)for(const r in i)n[r]=i[r];const o=new Array;return this._callbacks[e].forEach(r=>{const a=r(n);a instanceof Promise&&o.push(a)}),Promise.all(o)}static addContextCreatedCallback(e){this.registerCallback("ContextCreated",e)}static addContextDestroyedCallback(e){this.registerCallback("ContextDestroyed",e)}}const Of=new Map;function yi(s=globalThis.location?.hostname){if(Of.has(s))return Of.get(s);const e=/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})|localhost/.test(s);return Of.set(s,e),e===!0}function dv(){return window.location.hostname.includes("glitch.me")}const uv=()=>s=>s;function Zx(s){return uv()(s)}function Jx(){return!!x("debug")}class _i{_factory;_cache=[];_maxSize;_index=0;constructor(e,t){this._factory=e,this._maxSize=t}get(){const e=this._index%this._maxSize;return this._index++,this._cache.length<=e&&(this._cache[e]=this._factory()),this._cache[e]}}let Go=!1;const Ap=new Array;typeof window<"u"&&setTimeout(()=>{if(Go){const s={},e=new URL(window.location.href),t=new URL(e);t.searchParams.append("console","");const i=t.toString().replace(/=$|=(?=&)/g,"");for(const o of Ap){const r=new URL(e);r.searchParams.append(o,""),s[o]=r.toString().replace(/=$|=(?=&)/g,"")}console.log(`๐ŸŒต ?help: Debug Options for Needle Engine. Append any of these parameters to the URL to enable specific debug options. Example: ${i} will show an onscreen console window.`);const n=Go===!0?"":` (containing "${Go}")`;console.group("Available URL parameters:"+n);for(const o of Object.keys(s).sort())typeof Go=="string"&&!o.toLowerCase().includes(Go.toLowerCase())||(console.groupCollapsed(o),console.log("Reload with this flag enabled:"),console.log(s[o]),console.groupEnd());console.groupEnd()}},100);function Fc(){return new URLSearchParams(globalThis.location?.search)}function x(s){Go&&!Ap.includes(s)&&Ap.push(s);const e=Fc();if(e.has(s)){const t=e.get(s);if(t){const i=Number(t);return isNaN(i)?t:i}else return!0}return!1}Go=x("help");function eS(s,e){const t=Fc();t.has(s)?t.set(s,e):t.append(s,e),document.location.search=t.toString()}function yc(s,e,t=!0){const i=Fc();i.has(s)?e===null?i.delete(s):i.set(s,e):e!==null&&i.append(s,e),t?fv(s,i):Dm(s,i)}function Dp(s,e,t){s.has(e)?s.set(e,t.toString()):s.append(e,t.toString())}function fv(s,e,t){window.history.pushState(t,s,"?"+e.toString())}function Dm(s,e,t){window.history.replaceState(t,s,"?"+e.toString())}function tS(s){for(var e="",t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",i=t.length,n=0;n<s;n++)e+=t.charAt(Math.floor(Math.random()*i));return e}function iS(s,e){return Math.floor(Math.random()*(e-s+1))+s}const Ky=["smol","tiny","giant","interesting","smart","bright","dull","extreme","beautiful","pretty","dark","epic","salty","silly","funny","lame","lazy","loud","lucky","mad","mean","mighty","mysterious","nasty","odd","old","powerful","quiet","rapid","scary","shiny","shy","silly","smooth","sour","spicy","stupid","sweet","tasty","terrible","ugly","unusual","vast","wet","wild","witty","wrong","zany","zealous","zippy","zombie","zorro"],Zy=["cat","dog","mouse","pig","cow","horse","sheep","chicken","duck","goat","panda","tiger","lion","elephant","monkey","bird","fish","snake","frog","turtle","hamster","penguin","kangaroo","whale","dolphin","crocodile","snail","ant","bee","beetle","butterfly","dragon","eagle","fish","giraffe","lizard","panda","penguin","rabbit","snake","spider","tiger","zebra"];function pv(){const s=Ky[Math.floor(Math.random()*Ky.length)],e=Zy[Math.floor(Math.random()*Zy.length)];return s+"_"+e}function mv(s){return s=s.replace(/[^a-z0-9รกรฉรญรณรบรฑรผ \.,_-]/gim,""),s.trim()}function Ma(s,e,t=!0,i=!1){if(e==null)return null;if(e.userData&&e.userData.guid===s)return e;if(e.guid==s)return e;if(i&&e.userData?.components){for(const n of e.userData.components)if(n.guid===s)return n}if(t){if(e.scenes)for(const n in e.scenes){const o=e.scenes[n],r=Ma(s,o,t,i);if(r)return r}if(e.children)for(const n in e.children){const o=e.children[n],r=Ma(s,o,t,i);if(r)return r}}}function Uc(s,e){if(s!=null&&typeof s=="object"){let t;Array.isArray(s)?t=[]:(t=Object.create(s),Object.assign(t,s));for(const i of Object.keys(s)){const n=s[i];e&&!e(s,i,n)?t[i]=n:n?.clone!==void 0&&typeof n.clone=="function"?t[i]=n.clone():t[i]=Uc(n,e)}return t}return s}function _s(s){return new Promise((e,t)=>{setTimeout(e,s)})}function zc(s,e){if(s<=0)return Promise.resolve();if(e||(e=ce.Current),!e)return Promise.reject("No context");const t=e.time.frameCount+s;return new Promise((i,n)=>{if(!e)return n("No context");const o=()=>{e.time.frameCount>=t&&(e.pre_update_callbacks.splice(e.pre_update_callbacks.indexOf(o),1),i())};e.pre_update_callbacks.push(o)})}const Lh=x("debugresolveurl"),gv="rel:";function nS(s,e){return ws(s,e)}function ws(s,e){if(e===void 0)return Lh&&console.warn("getPath: uri is undefined, returning uri",e),e;if(e.startsWith("./"))return e;if(e.startsWith("http"))return Lh&&console.warn("getPath: uri is absolute, returning uri",e),e;if(s===void 0)return Lh&&console.warn("getPath: source is undefined, returning uri",e),e;e.startsWith(gv)&&(e=e.substring(4));const t=s.lastIndexOf("/");if(t>=0){const i=s.substring(0,t+1);for(;i.endsWith("/")&&e.startsWith("/");)e=e.substring(1);const n=i+e;return Lh&&console.log("source:",s,`changed uri from`,e,` to `,n,` basePath: `+i),n}return e}function yv(s){if(s)return s=s.trim(),s=s.split("?")[0]?.split("#")[0],s}class sS{subscribeWrite(e){this.writeCallbacks.push(e)}unsubscribeWrite(e){const t=this.writeCallbacks.indexOf(e);t!==-1&&this.writeCallbacks.splice(t,1)}writeCallbacks=[];constructor(e,t){this._object=e,this._prop=t,this._wrapperProp=Symbol("$"+t),this.apply()}_applied=!1;_object;_prop;_wrapperProp;apply(){if(this._applied||!this._object)return;const e=this._object,t=this._prop;if(e[t]===void 0)return;this._applied=!0,e[this._wrapperProp]!==void 0&&console.warn("Watcher is being applied to an object that already has a wrapper property. This is not (yet) supported");const i=e[t];e[this._wrapperProp]=i,Object.defineProperty(e,t,{get:()=>e[this._wrapperProp],set:r=>{e[this._wrapperProp]=r;for(const a of this.writeCallbacks)a(r,this._prop)}})}revoke(){if(!this._applied||!this._object)return;this._applied=!1;const e=this._object,t=this._prop;Reflect.deleteProperty(e,t);const i=e[this._wrapperProp];e[t]=i,Reflect.deleteProperty(e,this._wrapperProp)}dispose(){this.revoke(),this.writeCallbacks.length=0,this._object=null}}class ms{_watches=[];constructor(e,t){if(Array.isArray(t))for(const i of t)this._watches.push(new ms(e,i));else this._watches.push(new sS(e,t))}subscribeWrite(e){for(const t of this._watches)t.subscribeWrite(e)}unsubscribeWrite(e){for(const t of this._watches)t.unsubscribeWrite(e)}apply(){for(const e of this._watches)e.apply()}revoke(){for(const e of this._watches)e.revoke()}dispose(){for(const e of this._watches)e.dispose();this._watches.length=0}}const ta=Symbol("needle:watches");function pu(s,e){if(!s[ta])if(s instanceof c.Vector2)s[ta]=new ms(s,["x","y"]);else if(s instanceof c.Vector3)s[ta]=new ms(s,["x","y","z"]);else if(s instanceof c.Vector4||s instanceof c.Quaternion)s[ta]=new ms(s,["x","y","z","w"]);else return!1;return s[ta].subscribeWrite(e),!0}function Lm(s,e){if(!s)return;const t=s[ta];t&&t.unsubscribeWrite(e)}exports.DeviceUtilities=void 0;(s=>{let e;function t(){if(e!==void 0)return e;const Q=window.navigator.userAgent,_e=/Windows|MacOS|Mac OS/.test(Q),Xt=/Windows NT/.test(Q)&&/Edg/.test(Q)&&!/Win64/.test(Q);return e=_e&&!Xt&&!R()}s.isDesktop=t;let i;function n(){return i!==void 0?i:typeof window.orientation<"u"||navigator.userAgent.indexOf("IEMobile")!==-1?i=!0:i=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent)}s.isMobileDevice=n;function o(){return a()}s.isIPad=o;let r;function a(){if(r!==void 0)return r;const Q=navigator.userAgent.toLowerCase();return r=/iPad/.test(navigator.userAgent)||Q.includes("macintosh")&&"ontouchend"in document}s.isiPad=a;let l;function h(){return l!==void 0?l:l=/Android/.test(navigator.userAgent)}s.isAndroidDevice=h;let d;function u(){return d!==void 0?d:d=/WebXRViewer\//i.test(navigator.userAgent)}s.isMozillaXR=u;let p;function m(){return p!==void 0?p:p=/NeedleAppClip\//i.test(navigator.userAgent)}s.isNeedleAppClip=m;let y;function _(){if(y!==void 0)return y;if(R()||a())return y=!1;const Q=navigator.userAgent.toLowerCase();return navigator.userAgentData?y=navigator.userAgentData.platform==="macOS":y=Q.includes("mac os x")||Q.includes("macintosh")}s.isMacOS=_;let g;function v(){return g!==void 0?g:g=a()&&"xr"in navigator&&V()}s.isVisionOS=v;let b;const w=["iPad Simulator","iPhone Simulator","iPod Simulator","iPad","iPhone","iPod"];function R(){return b!==void 0?b:b=w.includes(navigator.platform)||navigator.userAgent.includes("Mac")&&"ontouchend"in document}s.isiOS=R;let O;function M(){return O!==void 0||(O=/^((?!chrome|android).)*safari/i.test(navigator.userAgent)),O}s.isSafari=M;let D;function L(){return D!==void 0?D:D=navigator.userAgent.includes("OculusBrowser")}s.isQuest=L;let j;function V(){return j!==void 0||(j=document.createElement("a").relList.supports("ar")),j}s.supportsQuickLookAR=V;async function W(){try{return(await navigator.permissions.query({name:"microphone"})).state!=="denied"}catch(Q){return console.error("Error querying `microphone` permissions.",Q),!1}}s.microphonePermissionsGranted=W;let k;function N(){if(k!==void 0)return k;const Q=navigator.userAgent.match(/iPhone OS (\d+_\d+)/);if(Q&&(k=Q[1].replace("_",".")),!k){const _e=navigator.userAgent.match(/(?:\(Macintosh;|iPhone;|iPad;).*Version\/(\d+\.\d+)/);_e&&(k=_e[1])}return k||(k=null),k}s.getiOSVersion=N;let $;function ee(){if($!==void 0)return $;const Q=navigator.userAgent.match(/(?:CriOS|Chrome)\/(\d+\.\d+\.\d+\.\d+)/);return Q?$=Q[1].replace("_","."):$=null,$}s.getChromeVersion=ee;let J;function de(){if(J!==void 0)return J;const Q=navigator.userAgent.match(/Version\/(\d+\.\d+)/);return Q&&M()?J=Q[1]:J=null,J}s.getSafariVersion=de})(exports.DeviceUtilities||(exports.DeviceUtilities={}));function oS(){return exports.DeviceUtilities.isDesktop()}function rS(){return exports.DeviceUtilities.isMobileDevice()}function aS(){return exports.DeviceUtilities.isiPad()}function lS(){return exports.DeviceUtilities.isiPad()}function cS(){return exports.DeviceUtilities.isAndroidDevice()}function hS(){return exports.DeviceUtilities.isMozillaXR()}function dS(){return exports.DeviceUtilities.isMacOS()}function uS(){return exports.DeviceUtilities.isiOS()}function fS(){return exports.DeviceUtilities.isSafari()}function pS(){return exports.DeviceUtilities.isQuest()}async function mS(){return exports.DeviceUtilities.microphonePermissionsGranted()}const io=new WeakMap;function Im(s,e,t){if(!io.get(s)){const n=new MutationObserver(o=>{gS(s,o)});io.set(s,{observer:n,attributeChangedListeners:new Map}),n.observe(s,{attributes:!0})}const i=io.get(s).attributeChangedListeners;return i.has(e)||i.set(e,[]),i.get(e).push(t),()=>{jm(s,e,t)}}function jm(s,e,t){if(!io.get(s))return;const i=io.get(s).attributeChangedListeners;if(!i.has(e))return;const n=i.get(e),o=n.indexOf(t);o!==-1&&(n.splice(o,1),n.length<=0&&(i.delete(e),io.get(s)?.observer.disconnect(),io.delete(s)))}function gS(s,e){const t=io.get(s).attributeChangedListeners;for(const i of e)if(i.type==="attributes"){const n=i.attributeName,o=s.getAttribute(n);if(t.has(n))for(const r of t.get(n))r(o)}}class Lp{reason;constructor(e){this.reason=e}}async function Bm(s){const e=await Promise.allSettled(s).catch(n=>[new Lp(n.message)]);let t=!1;const i=e.map(n=>"value"in n?n.value:(t=!0,new Lp(n.reason)));return{anyFailed:t,results:i}}const yS=x("debugdebug");let Fm=!1;(x("noerrors")||x("nooverlaymessages"))&&(Fm=!0);const Mf="needle_engine_global_error_container";var gi=(s=>(s[s.Log=0]="Log",s[s.Warn=1]="Warn",s[s.Error=2]="Error",s))(gi||{});function _v(){return wv}const Ip=new Array;function _S(s){Ip.push(s)}let kf=!1;function bS(...s){if(!kf){kf=!0;try{for(let e=0;e<Ip.length;e++)Ip[e](...s)}catch(e){console.error(e)}kf=!1}}const bv=console.error,vS=function(...s){bv.apply(console,s),SS(s),Qo(2,s,{}),xS(...s)};function vv(s){Fm=!s,s?console.error=vS:console.error=bv}function wS(s){return vv(s)}let wv=0;function xS(...s){wv+=1,bS(...s)}function SS(s){if(Array.isArray(s))for(let e=0;e<s.length;e++){const t=s[e];typeof t=="string"&&t.startsWith("THREE.PropertyBinding: Trying to update node for track:")&&(s[e]="Some animated objects couldn't be found: see console for details")}}const Jy=new Set;function Qo(s,e,t={},i,n){if(Fm)return;if(t.once===!0){let a="";if(Array.isArray(e))for(let l=0;l<e.length;l++){let h=e[l];h instanceof Error&&(h=h.message),typeof h!="object"&&(l>0&&(a+=" "),a+=h)}else typeof e=="string"&&(a=e);if(Jy.has(a))return;Jy.add(a)}const o=ce.Current;let r=o?.domElement??document.querySelector("needle-engine");if(o?.isInAR&&(r=o.arOverlayElement),!!r){if(Array.isArray(e)){let a="";for(let l=0;l<e.length;l++){let h=e[l];h instanceof Error&&(h=h.message),typeof h!="object"&&(l>0&&(a+=" "),a+=h)}e=a}!e||e.length<=0||CS(s,r,e,t)}}const ha=new Map,e_=.2;function CS(s,e,t,i={}){if(t==null)return;const n=MS(e);if(n.childElementCount>=20){const h=n.lastElementChild;t_(h)}t.length>400&&(t=t.substring(0,400)+"...");const o=i.key??t;if(ha.has(o)){ha.get(o)?.update(t,i);return}const r=kS(s,t);n.prepend(r);const a=()=>{ha.delete(o),t_(r)};let l=setTimeout(a,Math.max(e_,i.duration??10)*1e3);ha.set(o,{update:(h,d)=>{h.length>400&&(h=h.substring(0,400)+"..."),r.innerHTML=h,d.duration&&(clearTimeout(l),l=setTimeout(a,Math.max(e_,d.duration)*1e3))},removeFunction:a})}function PS(){yS&&console.log("Clearing messages");for(const s of ha.values())s?.removeFunction.call(s);ha.clear()}const OS=` @import url('https://fonts.googleapis.com/css2?family=Roboto+Flex:opsz,wght@8..144,100..1000&display=swap'); div[data-needle_engine_debug_overlay] { font-family: 'Roboto Flex', sans-serif; font-weight: 400; font-size: 16px; } div[data-needle_engine_debug_overlay] strong { font-weight: 700; } div[data-needle_engine_debug_overlay] a { color: white; text-decoration: none; border-bottom: 1px solid rgba(255, 255, 255, 0.3); } div[data-needle_engine_debug_overlay] a:hover { text-decoration: none; border: none; } div[data-needle_engine_debug_overlay] .log strong { color: rgba(200,200,200,.9); } div[data-needle_engine_debug_overlay] .warn strong { color: rgba(255,255,230, 1); } div[data-needle_engine_debug_overlay] .error strong { color: rgba(255,100,120, 1); } `;function MS(s){globalThis[Mf]||(globalThis[Mf]=new Map);const e=globalThis[Mf];if(e.has(s))return e.get(s);{const t=document.createElement("div");e.set(s,t),t.setAttribute("data-needle_engine_debug_overlay",""),t.classList.add("debug-container"),t.style.cssText=` position: absolute; top: 0; right: 5px; padding-top: env(safe-area-inset-top, 0px); max-width: 70%; max-height: calc(100% - 105px); z-index: 100000; pointer-events: scroll; display: flex; align-items: end; flex-direction: column; color: white; overflow: auto; word-break: break-word; `,exports.DeviceUtilities.isNeedleAppClip()&&(t.style.left="5px",t.style.right="unset");const i=document.querySelector('meta[name="viewport"]');i&&!i.getAttribute("content")?.includes("viewport-fit=")&&i.setAttribute("content",i.getAttribute("content")+",viewport-fit=cover"),s.shadowRoot?s.shadowRoot.appendChild(t):s.appendChild(t);const n=document.createElement("style");return n.innerHTML=OS,t.appendChild(n),t}}const xv=Symbol("logtype"),zd=new Map;function t_(s){s.remove();const e=s[xv],t=zd.get(e)??[];t.push(s),zd.set(e,t)}function kS(s,e){if(zd.has(s)){const i=zd.get(s);if(i.length>0){const n=i.pop();return n.innerHTML=e,n}}const t=document.createElement("div");switch(t.setAttribute("data-id","__needle_engine_debug_overlay"),t.style.marginRight="5px",t.style.padding=".5em",t.style.backgroundColor="rgba(0,0,0,.9)",t.style.marginTop="5px",t.style.marginBottom="3px",t.style.borderRadius="8px",t.style.pointerEvents="all",t.style.userSelect="text",t.style.maxWidth="250px",t.style.whiteSpace="pre-wrap",t.style["backdrop-filter"]="blur(10px)",t.style["-webkit-backdrop-filter"]="blur(10px)",t.style.backgroundColor="rgba(20,20,20,.8)",t.style.boxShadow="inset 0 0 80px rgba(0,0,0,.2), 0 0 5px rgba(0,0,0,.2)",t.style.border="1px solid rgba(160,160,160,.2)",t[xv]=s,s){case 0:t.classList.add("log"),t.style.color="rgba(200,200,200,.7)",t.style.backgroundColor="rgba(40,40,40,.7)";break;case 1:t.classList.add("warn"),t.style.color="rgb(255, 255, 150)",t.style.backgroundColor="rgba(50,50,20,.8)";break;case 2:t.classList.add("error"),t.style.color="rgb(255, 50, 50",t.style.backgroundColor="rgba(50,20,20,.8)";break}return t.title="Open the browser console (F12) for more information",t.innerHTML=e,t}const ES=x("nodevlogs");let jp,Ef;function A(){if(ES)return!1;if(jp!==void 0)return jp;if(Ef!==void 0)return Ef;let s=yi();return s||(s=window.location.hostname.endsWith(".local-credentialless.webcontainer.io")),Ef=s,s}function RS(s){jp=s}class TS{random(e,t){return Array.isArray(e)?e.length<=0?null:e[Math.floor(Math.random()*e.length)]:e!==void 0&&t!==void 0?Math.random()*(t-e)+e:Math.random()}randomVector3(e,t=0,i=1){e.x=this.random(t,i),e.y=this.random(t,i),e.z=this.random(t,i)}clamp(e,t,i){return e<t?t:e>i?i:e}clamp01(e){return this.clamp(e,0,1)}lerp(e,t,i){return i=i<0?0:i,i=i>1?1:i,e+(t-e)*i}inverseLerp(e,t,i){return(i-e)/(t-e)}remap(e,t,i,n,o){return n+(o-n)*(e-t)/(i-t)}moveTowards(e,t,i){return e+=i,(i<0&&e<t||i>0&&e>t)&&(e=t),e}Rad2Deg=180/Math.PI;Deg2Rad=Math.PI/180;Epsilon=1e-5;toDegrees(e){return e*180/Math.PI}toRadians(e){return e*Math.PI/180}tan(e){return Math.tan(e)}gammaToLinear(e){return Math.pow(e,2.2)}linearToGamma(e){return Math.pow(e,1/2.2)}approximately(e,t,i=Number.EPSILON){for(const n of AS){const o=e[n],r=t[n];if(o===void 0||r===void 0)break;if(Math.abs(o-r)>i)return!1}return!0}easeInOutCubic(e){return e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2}}const AS=["x","y","z","w"],I=new TS;class i_{y;s;alpha=0;constructor(e){this.setAlpha(e),this.y=null,this.s=null}setAlpha(e){if(e<=0||e>1)throw new Error;this.alpha=e}filter(e,t){t&&this.setAlpha(t);let i;return this.y?i=this.alpha*e+(1-this.alpha)*this.s:i=e,this.y=e,this.s=i,i}lastValue(){return this.y}reset(e){this.y=e,this.s=e}}class gd{freq;minCutOff;beta;dCutOff;x;dx;lasttime;constructor(e,t=1,i=0,n=1){if(e<=0||t<=0||n<=0)throw new Error;this.freq=e,this.minCutOff=t,this.beta=i,this.dCutOff=n,this.x=new i_(this.alpha(this.minCutOff)),this.dx=new i_(this.alpha(this.dCutOff)),this.lasttime=null}alpha(e){const t=1/this.freq;return 1/(1+1/(2*Math.PI*e)/t)}filter(e,t=null){this.lasttime&&t&&(this.freq=1/(t-this.lasttime)),this.lasttime=t;const i=this.x.lastValue(),n=i?(e-i)*this.freq:0,o=this.dx.filter(n,this.alpha(this.dCutOff)),r=this.minCutOff+this.beta*Math.abs(o);return this.x.filter(e,this.alpha(r))}reset(e){e!=null&&this.x.reset(e),this.x.alpha=this.alpha(this.minCutOff),this.dx.alpha=this.alpha(this.dCutOff),this.lasttime=null}}class Um{x;y;z;constructor(e,t=1,i=0,n=1){this.x=new gd(e,t,i,n),this.y=new gd(e,t,i,n),this.z=new gd(e,t,i,n)}filter(e,t,i=null){t.x=this.x.filter(e.x,i),t.y=this.y.filter(e.y,i),t.z=this.z.filter(e.z,i)}reset(e){this.x.reset(e?.x),this.y.reset(e?.y),this.z.reset(e?.z)}}const yd="needle:cameraController";function Sv(s){return s[yd]}function Bp(s,e,t){t?s[yd]=e:s[yd]===e&&(s[yd]=null)}const Fp="needle:autofit";function Cv(s){return s[Fp]===void 0?!0:s[Fp]!==!1}function Nd(s,e){s[Fp]=e}let en;const DS={x:0,y:0,width:0,height:0},LS=x("debugfocusrect");function IS(s,e,t,i,n){s instanceof Element&&(LS&&s instanceof HTMLElement&&(s.style.outline="2px dashed rgba(255, 150, 0, .8)"),s=s.getBoundingClientRect()),en=n.domElement.getBoundingClientRect();const o=DS;o.x=s.x,o.y=s.y,o.width=s.width,o.height=s.height,o.x-=en.x,o.y-=en.y;const r=en.width,a=en.height,l=i.view,h=e.zoom;let d=l?.offsetX||0,u=l?.offsetY||0,p=en.width,m=en.height;p/=h,m/=h,d=p*(h-1)*.5,u=m*(h-1)*.5;const y=o.x+o.width*.5,_=o.y+o.height*.5,g=en.width*.5,v=en.height*.5,b=y-g,w=_-v;d-=b/h,u-=w/h,e.offsetX!==void 0&&(d+=e.offsetX*(en.width*.5)),e.offsetY!==void 0&&(u-=e.offsetY*(en.height*.5));const R=l?.offsetX||d,O=l?.offsetY||u;d=I.lerp(R,d,t),u=I.lerp(O,u,t);const M=l?.width||r,D=l?.height||a;p=I.lerp(M,p,t),m=I.lerp(D,m,t),i.setViewOffset(r,a,d,u,p,m),i.updateProjectionMatrix(),e.damping>0&&(e.damping*=1-t,e.damping<.01&&(e.damping=0),e.damping=Math.max(0,e.damping))}function Pv(s,e,t){const i=s.length(),n=e.length(),o=I.lerp(i,n,t);return s.lerp(e,t).normalize().multiplyScalar(o)}const Rf=new c.Quaternion,Ov=new c.Quaternion().setFromAxisAngle(new c.Vector3(0,1,0),Math.PI);function jS(s,e){s.lookAt(e),s.quaternion.multiply(Ov)}function Nc(s,e,t=!0,i=!1){if(s===e)return;Rf.copy(s.quaternion);const n=Y(e),o=Y(s);if(i){if(dn(s,pe(e)),t){const r=o.y,a=o.sub(kv(s));a.y=r,s.lookAt(a),s.quaternion.multiply(Ov)}Number.isNaN(s.quaternion.x)&&s.quaternion.copy(Rf);return}t&&(n.y=o.y),s.lookAt(n),Number.isNaN(s.quaternion.x)&&s.quaternion.copy(Rf)}function BS(s,e,t,i=1){if(t){const n=F(0,0,0),o=e.x/window.innerWidth*2-1,r=-(e.y/window.innerHeight)*2+1;n.set(o,r,0),n.unproject(t);const a=t.worldPosition,l=s.worldPosition.distanceTo(a),h=n.sub(a);h.multiplyScalar(i*3.6*l);const d=t.worldPosition.add(h);return s.lookAt(d),d}return null}const FS=new _i(()=>new c.Vector3,100);function F(s,e,t){const i=FS.get();return i.set(0,0,0),s instanceof c.Vector3?i.copy(s):Array.isArray(s)?i.set(s[0],s[1],s[2]):s instanceof DOMPointReadOnly?i.set(s.x,s.y,s.z):typeof s=="number"?(i.x=s,i.y=e!==void 0?e:i.x,i.z=t!==void 0?t:i.x):typeof s=="object"&&(i.x=s.x,i.y=s.y,i.z=s.z),i}const US=new _i(()=>new c.Color,30);function Mv(s){const e=US.get();return s?e.copy(s):e.set(0,0,0),e}const zS=new _i(()=>new c.Quaternion,100);function ei(s,e,t,i){const n=zS.get();return n.identity(),s instanceof c.Quaternion?n.copy(s):s instanceof DOMPointReadOnly?n.set(s.x,s.y,s.z,s.w):typeof s=="number"&&e!==void 0&&t!==void 0&&i!==void 0?n.set(s,e,t,i):typeof s=="object"&&"x"in s&&"y"in s&&"z"in s&&"w"in s&&n.set(s.x,s.y,s.z,s.w),n}const zm=new _i(()=>new c.Vector3,100),n_=Symbol("lastMatrixWorldUpdateKey");function Y(s,e=null,t=!0){const i=e??zm.get();return s?s.parent?(t&&s.updateWorldMatrix(!0,!1),s.matrixWorldNeedsUpdate&&s[n_]!==Date.now()&&(s[n_]=Date.now(),s.updateMatrixWorld()),i.setFromMatrixPosition(s.matrixWorld),i):i.copy(s.position):i.set(0,0,0)}function at(s,e){if(!s)return s;const t=zm.get();return e!==t&&t.copy(e),s.parent!==null&&s.parent.worldToLocal(t),s.position.set(t.x,t.y,t.z),s}function hr(s,e,t,i){const n=zm.get();return n.set(e,t,i),at(s,n),s}const Vd=new _i(()=>new c.Quaternion,100),Jo=new c.Quaternion,Tf=new c.Quaternion;function pe(s,e=null){if(!s)return Vd.get().identity();const t=e??Vd.get();return s.parent?(s.getWorldQuaternion(t),t):t.copy(s.quaternion)}function dn(s,e){if(!s)return;e!==Jo&&Jo.copy(e);const t=Jo;s?.parent?.getWorldQuaternion(Tf),Tf.invert();const n=Tf.multiply(t);s.quaternion.set(n.x,n.y,n.z,n.w)}function Nm(s,e,t,i,n){Jo.set(e,t,i,n),dn(s,Jo)}const NS=new _i(()=>new c.Vector3,100),VS=new c.Vector3;function je(s,e=null){return e||(e=NS.get()),s?s.parent?(s.getWorldScale(e),e):e.copy(s.scale):e.set(0,0,0)}function ka(s,e){if(!s)return;if(!s.parent){s.scale.copy(e);return}const t=VS;s.parent.getWorldScale(t),s.scale.copy(e),s.scale.divide(t)}const $S=new c.Vector3,s_=new c.Quaternion;function WS(s){return pe(s,s_),$S.set(0,0,1).applyQuaternion(s_)}const GS=new _i(()=>new c.Vector3,100),o_=new c.Quaternion;function kv(s,e){return e||(e=GS.get().set(0,0,1)),pe(s,o_),e.applyQuaternion(o_)}const r_=new c.Euler,a_=new c.Euler,HS=new c.Vector3;function Vm(s){const e=Vd.get();return s.getWorldQuaternion(e),a_.setFromQuaternion(e),a_}function $m(s,e){const t=Vd.get();dn(s,t.setFromEuler(e))}function mu(s){const e=Vm(s),t=HS;return t.set(e.x,e.y,e.z),t.x=I.toDegrees(t.x),t.y=I.toDegrees(t.y),t.z=I.toDegrees(t.z),t}function Ev(s,e){Vc(s,e.x,e.y,e.z,!0)}function Vc(s,e,t,i,n=!0){n&&(e=I.toRadians(e),t=I.toRadians(t),i=I.toRadians(i)),r_.set(e,t,i),Jo.setFromEuler(r_),dn(s,Jo)}function $d(s,e=!0){s&&(e?(function t(i){console.groupCollapsed((i.name?i.name:"(no name : "+i.type+")")+" %o",i),i.children.forEach(t),console.groupEnd()})(s):s.traverse(function(t){for(var i="|___",n=t;n.parent!==null;)i=" "+i,n=n.parent;console.log(i+t.name+" <"+t.type+">")}))}function qS(s){let e=s?.name||"";if(!s)return e;let t=s.parent;for(;t;)e=t.name+"/"+e,t=t.parent;return e}function Rv(s){if(s){const e=s;return e.blendMode!==void 0&&e.clampWhenFinished!==void 0&&e.enabled!==void 0&&e.fadeIn!==void 0&&e.getClip!==void 0}return!1}class Wd extends c.ShaderMaterial{static vertex=` varying vec2 vUv; void main(){ vUv = uv; gl_Position = vec4(position.xy, 0., 1.0); }`;constructor(){super({vertexShader:Wd.vertex,uniforms:{map:new c.Uniform$1(null),flipY:new c.Uniform$1(!0),writeDepth:new c.Uniform$1(!1),depthTexture:new c.Uniform$1(null)},fragmentShader:` uniform sampler2D map; uniform bool flipY; uniform bool writeDepth; uniform sampler2D depthTexture; varying vec2 vUv; void main(){ vec2 uv = vUv; if (flipY) uv.y = 1.0 - uv.y; gl_FragColor = texture2D(map, uv); if (writeDepth) { float depth = texture2D(depthTexture, uv).r; gl_FragDepth = depth; // float linearDepth = (depth - 0.99) * 100.0; // Enhance near 1.0 values // gl_FragColor = vec4(linearDepth, linearDepth, linearDepth, 1.0); } }`})}reset(){this.uniforms.map.value=null,this.uniforms.flipY.value=!0,this.uniforms.writeDepth.value=!1,this.uniforms.depthTexture.value=null,this.needsUpdate=!0,this.uniformsNeedUpdate=!0}}class co{static planeGeometry=new c.PlaneGeometry(2,2,1,1);static renderer=new c.WebGLRenderer({antialias:!1,alpha:!0});static perspectiveCam=new c.PerspectiveCamera;static orthographicCam=new c.OrthographicCamera;static scene=new c.Scene;static blitMaterial=new Wd;static mesh=new c.Mesh(co.planeGeometry,co.blitMaterial);static copyTexture(e,t){t||(t=this.blitMaterial),this.blitMaterial.reset();const i=t||this.blitMaterial;i.uniforms.map.value=e,i.needsUpdate=!0,i.uniformsNeedUpdate=!0;const n=i.vertexShader;i.vertexShader=Wd.vertex;const o=this.mesh;o.material=i,o.frustumCulled=!1,this.scene.children.length=0,this.scene.add(o),this.renderer.setSize(e.image.width,e.image.height),this.renderer.clear(),this.renderer.render(this.scene,this.perspectiveCam);const r=new c.Texture(this.renderer.domElement);return r.name="Copy",r.needsUpdate=!0,i.vertexShader=n,r}static blit(e,t,i){const{renderer:n=this.renderer,blitMaterial:o=this.blitMaterial,flipY:r=!1,depthTexture:a=null,depthTest:l=!0,depthWrite:h=!0}=i||{};this.blitMaterial.reset(),o.uniforms.map&&(o.uniforms.map.value=e),o.uniforms.flipY&&(o.uniforms.flipY.value=r),a?(o.uniforms.writeDepth=new c.Uniform$1(!0),o.uniforms.depthTexture.value=a):(o.uniforms.writeDepth=new c.Uniform$1(!1),o.uniforms.depthTexture.value=null),o.needsUpdate=!0,o.uniformsNeedUpdate=!0;const d=this.mesh;d.material=o,d.frustumCulled=!1,this.scene.children.length=0,this.scene.add(d);const u=n.getRenderTarget(),p=n.getContext();l?p.enable(p.DEPTH_TEST):p.disable(p.DEPTH_TEST),n.state.buffers.depth.setMask(h),n.setClearColor(new c.Color(0,0,0),0),n.setRenderTarget(t),n.clear(),n.render(this.scene,this.perspectiveCam),n.setRenderTarget(u),p.enable(p.DEPTH_TEST),n.state.buffers.depth.setMask(!0)}static textureToCanvas(e,t=!1){if(!e)return null;(t===!0||e.isCompressedTexture===!0)&&(e=Tv(e));const i=e.image;if(QS(i)){const n=document.createElement("canvas");n.width=i.width,n.height=i.height;const o=n.getContext("2d");return o?(o.drawImage(i,0,0,i.width,i.height,0,0,n.width,n.height),n):(console.error("Failed getting canvas 2d context"),null)}return null}}function Tv(s){return co.copyTexture(s)}function XS(s,e=!1){return co.textureToCanvas(s,e)}function QS(s){return typeof HTMLImageElement<"u"&&s instanceof HTMLImageElement||typeof HTMLCanvasElement<"u"&&s instanceof HTMLCanvasElement||typeof OffscreenCanvas<"u"&&s instanceof OffscreenCanvas||typeof ImageBitmap<"u"&&s instanceof ImageBitmap}function YS(s){const e=s.type;return e==="Mesh"||e==="SkinnedMesh"}function Wm(s,e){e?s["needle:rendercustomshadow"]=!0:s["needle:rendercustomshadow"]=!1}function Av(s){if(s){if(s["needle:rendercustomshadow"]===!0)return!0;if(s["needle:rendercustomshadow"]==null)return!0}return!1}function ri(s,e=void 0,t=void 0,i=void 0){const n=i||new c.Box3;n.makeEmpty();const o=[];function r(l){let h=!0;if(l.visible&&Cv(l)!==!1&&!(l.type==="TransformControlsGizmo"||l.type==="TransformControlsPlane")){if(l instanceof c.Box3Helper&&(h=!1),l instanceof c.GridHelper&&(h=!1),l instanceof X.GroundedSkybox&&(h=!1),l.isGizmo===!0&&(h=!1),l.material instanceof c.ShadowMaterial&&(h=!1),YS(l)||(h=!1),t&&l.layers.test(t)===!1&&(h=!1),h){if(e&&Array.isArray(e)&&e?.includes(l))return;if(typeof e=="function"&&e(l)===!0)return}if(l.isUI!==!0){if(h){const d=l.children;l.children=o;const u=l.position,p=l.scale;if(Number.isNaN(u.x)||Number.isNaN(u.y)||Number.isNaN(u.z)){console.warn(`Object "${l.name}" has NaN values in position or scale.... will ignore it`,u,p);return}l.geometry===null&&(l.geometry=void 0),n.expandByObject(l,!0),l.children=d}for(const d of l.children)r(d)}}}let a=!1;Array.isArray(s)||(s=[s]);for(const l of s)l&&(a=!0,l.updateMatrixWorld(),r(l));return a||console.warn("No objects to fit camera to..."),n}function Dv(s,e,t){const i=ri([s],t?.ignore),n=new c.Vector3;i.getSize(n);const o=new c.Vector3;i.getCenter(o);const r=new c.Vector3;e.getSize(r);const a=new c.Vector3;e.getCenter(a);const l=new c.Vector3;l.set(r.x/n.x,r.y/n.y,r.z/n.z);const h=Math.min(l.x,l.y,l.z),d=t?.scale!==!1;if(d&&ka(s,je(s).multiplyScalar(h)),t?.position!==!1){const u=new c.Vector3;i.getCenter(u),u.y=i.min.y;const p=new c.Vector3;e.getCenter(p),p.y=e.min.y;const m=p.clone().sub(u);d&&m.multiplyScalar(h),at(s,Y(s).add(m))}return{boundsBefore:i,scale:l}}function Lv(s,e){const t=ri([s]),i=new c.Vector3;t.getCenter(i),i.y=t.min.y;const n=e.clone().sub(i),o=Y(s);return at(s,o.add(n)),{offset:n,bounds:t}}function Gm(s,e,t,i){if(Array.isArray(e)){let r=!0;for(let a=0;a<e.length;a++)Gm(s,e[a],a,e)||(r=!1);return r}if(e.type==="MeshStandardMaterial"||e.type==="MeshBasicMaterial")return!1;if(e["material:fbx"]!=null)return!0;const n=new c.MeshStandardMaterial;n["material:fbx"]=e;const o=e;return o&&(o.map?n.color.set(1,1,1):n.color.copyLinearToSRGB(o.color),n.emissive.copyLinearToSRGB(o.emissive),n.emissiveIntensity=o.emissiveIntensity,n.opacity=o.opacity,n.displacementScale=o.displacementScale,n.transparent=o.transparent,n.bumpMap=o.bumpMap,n.aoMap=o.aoMap,n.map=o.map,n.displacementMap=o.displacementMap,n.emissiveMap=o.emissiveMap,n.normalMap=o.normalMap,n.envMap=o.envMap,n.alphaMap=o.alphaMap,n.metalness=o.reflectivity,n.vertexColors=o.vertexColors,o.shininess&&(n.roughness=1-Math.sqrt(o.shininess)/10),n.needsUpdate=!0),t===void 0?s.material=n:i[t]=n,!0}let Ih=!1;_S((...s)=>{A()&&ce.Current?.isInXR&&(_a(!0),Iv("error",...s))});function _a(s){if(s){if(Ih)return;Ih=!0,ZS()}else{if(!Ih)return;Ih=!1,JS()}}const Jl={log:void 0,warn:void 0,error:void 0};class KS{familyName="needle-xr";root=null;context=null;defaultFontSize=.06;constructor(){this.ensureFont()}onEnable(){this.context=ce.Current||ce.All[0],this.context.pre_render_callbacks.push(this.onBeforeRender)}onDisable(){this.context?.pre_render_callbacks.splice(this.context?.pre_render_callbacks.indexOf(this.onBeforeRender),1),this.root?.removeFromParent()}targetObject=new c.Object3D;userForwardViewPoint=new c.Vector3;oneEuroFilter=new Um(90,.8);_lastElementRemoveTime=0;onBeforeRender=()=>{const e=this.context?.mainCamera;if(this.context&&e instanceof c.PerspectiveCamera){const t=this.getRoot();Number.isNaN(t.position.x)&&t.position.set(0,0,0),Number.isNaN(t.quaternion.x)&&t.quaternion.set(0,0,0,1),this.context.scene.add(this.targetObject);const i=this.context.xr?.rigScale??1,n=3.5*i,o=e.worldForward;o.y=0,o.normalize().multiplyScalar(n),this.userForwardViewPoint.copy(e.worldPosition).sub(o),this.targetObject.position.distanceTo(this.userForwardViewPoint)>2*i&&(this.targetObject.position.copy(this.userForwardViewPoint),Nc(this.targetObject,e,!0,!0),this.targetObject.rotateY(Math.PI)),this.oneEuroFilter.filter(this.targetObject.position,t.position,this.context.time.time);const a=this.context.time.deltaTime;if(t.quaternion.slerp(this.targetObject.quaternion,a*5),t.scale.setScalar(i),this.targetObject.removeFromParent(),this.context.scene.add(t),this.context.time.time-this._lastElementRemoveTime>.1){this._lastElementRemoveTime=this.context.time.time;const l=Date.now();for(let h=0;h<this._activeTexts.length;h++){const d=this._activeTexts[h];if(d instanceof ie.__webpack_exports__default.Text&&l-d._activatedTime>2e4){d.removeFromParent(),this._textBuffer.push(d),this._activeTexts.splice(h,1);break}}}}};addLog(e,t){const i=this.getRoot(),n=this.getText();let o=16777215,r=0;switch(e){case"log":o=16777215,r=0;break;case"warn":o=16772761,r=4465152;break;case"error":o=16755370,r=7798784;break}t.length>1e3&&(t=t.substring(0,1e3)+"...");const a=new Date().toISOString().split("T")[1].split(".")[0];n.textContent="["+a+"] "+t,n.visible=!0,n._activatedTime=Date.now(),i.add(n),this._activeTexts.push(n),this.context&&this.context.scene.add(i),n.set({backgroundColor:o,color:r}),ie.__webpack_exports__default.update()}ensureFont(){let e=ie.__webpack_exports__default.FontLibrary.getFontFamily(this.familyName);e||(e=ie.__webpack_exports__default.FontLibrary.addFontFamily(this.familyName),e.addVariant("normal","normal","https://cdn.needle.tools/static/fonts/msdf/arial/arial-msdf.json","https://cdn.needle.tools/static/fonts/msdf/arial/arial.png")?.addEventListener("ready",()=>{ie.__webpack_exports__default.update()}))}textOptions={fontSize:this.defaultFontSize,fontFamily:this.familyName,padding:.03,margin:.005,color:0,backgroundColor:16777215,backgroundOpacity:.4,borderRadius:.03,offset:.025};_textBuffer=[];_activeTexts=[];getText(){const e=this.getRoot();if(this._textBuffer.length>0){const i=this._textBuffer.pop();return i.visible=!0,setTimeout(()=>this.disableDepthTestRecursive(i),100),i}if(e.children.length>20&&this._activeTexts.length>0)return this._activeTexts.shift();const t=new ie.__webpack_exports__default.Text(this.textOptions);return setTimeout(()=>this.disableDepthTestRecursive(t),500),setTimeout(()=>this.disableDepthTestRecursive(t),1500),t}disableDepthTestRecursive(e,t=0){for(let n=0;n<e.children.length;n++){const o=e.children[n];o instanceof c.Object3D&&this.disableDepthTestRecursive(o,t+1)}e.renderOrder=10*t,e.layers.set(2);const i=e.material;i&&(i.depthWrite=!1,i.depthTest=!1,i.transparent=!0),t===0&&ie.__webpack_exports__default.update()}getRoot(){if(this.root)return this.root;const e=this.defaultFontSize,t={boxSizing:"border-box",fontFamily:this.familyName,width:"2.6",fontSize:e,color:0,lineHeight:1,backgroundColor:16777215,backgroundOpacity:0,whiteSpace:"pre-wrap",flexDirection:"column-reverse"};return this.root=new ie.__webpack_exports__default.Block(t),this.root}}let er=null;function ZS(){er||(er=new KS),er.onEnable();for(const s in Jl){Jl[s]=console[s];let e=!1;console[s]=function(){if(Jl[s]?.apply(console,arguments),!e)try{e=!0,Iv(s,...arguments)}finally{e=!1}}}}function JS(){er?.onDisable();for(const s in Jl)console[s]=Jl[s]}const bl=new Map;function Iv(s,...e){try{switch(bl.clear(),s){case"log":er?.addLog("log",t());break;case"warn":er?.addLog("warn",t());break;case"error":er?.addLog("error",t());break}}catch(o){console.error("Error in spatial console",o)}finally{bl.clear()}function t(){let o="";for(let r=0;r<e.length;r++){const a=e[r];o+=i(a),r<e.length-1&&(o+=", ")}return o}function i(o,r=0){if(typeof o=="string")return'"'+o+'"';if(typeof o=="number"){if(o%1!==0){const l=o.toFixed(5),h=l.indexOf(".");let d=l.length-1;for(;d>h&&l[d]==="0";)d--;return l.substring(0,d+1)}return o.toString()}else if(Array.isArray(o)){let a="[";for(let l=0;l<o.length;l++){const h=o[l];a+=i(h,r+1),l<o.length-1&&(a+=", ")}return a+="]",a}else{if(o===null)return"null";if(o===void 0)return"undefined";if(typeof o=="function")return o.name+"()"}if(o instanceof c.Vector2)return`(${i(o.x)}, ${i(o.y)})`;if(o instanceof c.Vector3)return`(${i(o.x)}, ${i(o.y)}, ${i(o.z)})`;if(o instanceof c.Vector4)return`(${i(o.x)}, ${i(o.y)}, ${i(o.z)}, ${i(o.w)})`;if(o instanceof c.Quaternion)return`(${i(o.x)}, ${i(o.y)}, ${i(o.z)}, ${i(o.w)})`;if(o instanceof c.Material||o instanceof c.Texture)return o.name;if(o instanceof c.Matrix3)return`[${o.elements.join(", ")}]`;if(o instanceof c.Matrix4)return`[${o.elements.join(", ")}]`;if(o instanceof c.Layers)return o.mask.toString();if(typeof o=="object"){if(bl.has(o))return"*";let a=`{ `;a+=n(r);const l=Object.keys(o);let h="";for(let d=0;d<l.length;d++){const u=l[d],p=o[u];if(bl.has(p)){h+="";continue}bl.set(p,!0),h+=u+":"+i(p,r+1),d<l.length-1&&(h+=", "),h.length>=60&&(h+=` `,h+=n(r),a+=h,h="")}return a+=h,a+=` }`,a}return o}function n(o){let r="";for(let a=0;a<o;a++)r+=" ";return r}}function Se(s,e){Qo(e?.type??gi.Log,s,e)}function fe(s,e){Se(s,{...e,type:gi.Warn})}function $c(s,e){Se(s,{...e,type:gi.Error})}let Zt,Lo=null,In=null,vl=!1,l_=null;const jv="terminal",eC=x("console");eC&&Hm();const tC=Symbol("consoleParent");function Hm(){if(Zt){Zt.showSwitch();return}rC()}function Bv(){Zt&&(Zt.hide(),Zt.hideSwitch())}function iC(){l_||(l_=setInterval(nC,500))}let c_=0;function nC(){const s=_v(),e=s!==c_;c_=s,e&&sC()}function sC(){Hm(),In&&(In.setAttribute("error","true"),In.innerText="๐Ÿคฌ")}function oC(){In&&(In.removeAttribute("error"),In.innerText=jv)}function rC(s=!1){if(Zt!==void 0||vl)return;vl=!0;const e=document.createElement("script");e.onload=()=>{if(!globalThis.VConsole){console.warn("๐ŸŒต Debug console failed to load."),vl=!1,Zt=null;return}vl=!1,iC(),Zt=new VConsole({pluginOrder:["default","needle-console"]});const t=globalThis["needle:codegen_files"];if(t&&t.length>0&&Zt.addPlugin(aC()),Zt.addPlugin(dC()),Zt.addPlugin(uC()),Lo=SC(),Lo&&(Lo[tC]=Lo.parentElement,Lo.style.position="absolute",Lo.style.zIndex=Number.MAX_SAFE_INTEGER.toString()),Zt.setSwitchPosition(20,30),In=xC(),In){In.innerText=jv,In.addEventListener("click",oC);const i=document.createElement("style"),n=40;i.innerHTML=` #__vconsole .vc-switch { border: 1px solid rgba(255, 255, 255, .1); border-radius: 50%; width: ${n}px; height: ${n}px; padding: 0; line-height: ${n}px; font-size: ${n*.4}px; text-align: center; background: #ffffff5c; backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); user-select: none; pointer-events: auto; transition: transform .2s ease-in-out; box-shadow: 0px 7px 0.5rem 0px rgb(0 0 0 / 6%), inset 0px 0px 1.3rem rgba(0,0,0,.05); font-family: 'Material Symbols Outlined'; color: black; font-size: 2.3em; font-weight: 100; } #__vconsole .vc-switch:hover { cursor: pointer; transform: scale(1.1); transition: transform .1s ease-in-out, background .1s linear; background: rgba(245, 245, 245, .8); outline: rgba(0, 0, 0, .05) 1px solid; } #__vconsole .vc-switch[error] { background: rgba(255,0,0,.2); animation: vconsole-notify 1s ease-in-out; line-height: 35px; } @keyframes vconsole-notify { from { transform: scale(1, 1); } 10% { transform: scale(1.3, 1.3); } 70% { transform: scale(1.4, 1.4); } to { transform: scale(1, 1); } } #__vconsole .vc-panel { font-family: monospace; font-size: 11px; } #__vconsole .vc-plugin-box.vc-actived { height: 100%; } #__vconsole .vc-mask { overflow: hidden; } `,Lo?.prepend(i),s===!0&&_v()<=0&&Bv(),console.log("๐ŸŒต Debug console has loaded")}},e.onerror=()=>{console.warn("๐ŸŒต Debug console failed to load."+(window.crossOriginIsolated?"This page is using cross-origin isolation, so external scripts can't be loaded.":"")),vl=!1,Zt=null},e.src="https://cdn.jsdelivr.net/npm/vconsole@3.15.1/dist/vconsole.min.js",document.body.appendChild(e)}function aC(){if(!globalThis.VConsole)return;const s=new VConsole.VConsolePlugin("needle-console","๐ŸŒต Inspect glTF"),e=()=>document.querySelector("#__vc_plug_"+s._id+" iframe");return s.on("renderTab",function(t){const i=globalThis["needle:codegen_files"];if(!i||i.length===0)return;let n=globalThis["needle:codegen_files"][0];const o=n.indexOf("?");o>-1&&(n=n.substring(0,o));const a=location.protocol+"//"+location.host+location.pathname+"/"+n,l=encodeURIComponent(a);s.fullUrl="https://viewer.needle.tools?inspect&file="+l;var h='<iframe src="" style="width: 100%; height: 99%; border: none;"></iframe>';t(h)}),s.on("show",function(){const t=e();t&&t.src!==s.fullUrl&&(t.src=s.fullUrl)}),s.on("hide",function(){const t=e();t&&(t.src="")}),s.on("addTopBar",function(t){var i=new Array;i.push({name:"Open in new window โ†—",onClick:function(n){window.open(s.fullUrl,"_blank"),Zt?.hide()}}),i.push({name:"Reload",onClick:function(n){const o=e();o&&(o.src=s.fullUrl)}}),i.push({name:"Fullscreen",onClick:function(n){const o=e();o.requestFullscreen?o.requestFullscreen():o.webkitRequestFullscreen instanceof Function&&o.webkitRequestFullscreen()}}),t(i)}),s}const Up="padding: 10px; font-family: monospace;",h_="margin-bottom: 10px;",Io="margin-bottom: 10px; margin-top: 15px;",lC="width: 100%; border-collapse: collapse; border: 1px solid rgba(0,0,0,0.1); table-layout: fixed;",Fv="border: 1px solid rgba(0,0,0,0.1); padding: 5px;",cC=Fv,hC=Fv+" word-break: break-all;";function En(s,e=!1){e&&s.sort((i,n)=>(n.value?1:0)-(i.value?1:0));let t=`<table style='${lC}'>`;t+="<tbody>";for(const i of s){const n=typeof i.value=="boolean"?i.value?"โœ…":"โŒ":i.value;t+=`<tr><td style='${cC}'>${i.label}</td><td style='${hC}'>${n}</td></tr>`}return t+="</tbody></table>",t}function Uv(){try{if(document.createElement("canvas").getContext("webgl2"))return"โœ…"}catch{}return"โŒ"}function dC(){if(!globalThis.VConsole)return;const s=new VConsole.VConsolePlugin("device-utilities","๐Ÿ“ฑ Device Info");return s.on("renderTab",function(e){let t=`<div style='${Up}'>`;const i=wC();t+=`<h3 style='${h_}'>Device: ${i}</h3>`,t+=En([{label:"๐Ÿ’ป Desktop",value:exports.DeviceUtilities.isDesktop()},{label:"๐Ÿ“ฑ Mobile Device",value:exports.DeviceUtilities.isMobileDevice()},{label:"๐ŸŽ iOS",value:exports.DeviceUtilities.isiOS()},{label:"๐Ÿ“ฑ iPad",value:exports.DeviceUtilities.isiPad()},{label:"๐Ÿค– Android",value:exports.DeviceUtilities.isAndroidDevice()},{label:"๐ŸฆŠ Mozilla XR",value:exports.DeviceUtilities.isMozillaXR()},{label:"๐ŸŒต Needle App Clip",value:exports.DeviceUtilities.isNeedleAppClip()},{label:"๐Ÿ macOS",value:exports.DeviceUtilities.isMacOS()},{label:"๐Ÿ‘“ VisionOS",value:exports.DeviceUtilities.isVisionOS()},{label:"๐Ÿงญ Safari",value:exports.DeviceUtilities.isSafari()},{label:"๐Ÿ•ถ๏ธ Meta Quest",value:exports.DeviceUtilities.isQuest()},{label:"๐Ÿ”— QuickLook AR Support",value:exports.DeviceUtilities.supportsQuickLookAR()}],!0);const n=[],o=exports.DeviceUtilities.getiOSVersion();o&&n.push({label:"๐ŸŽ iOS Version",value:o});const r=exports.DeviceUtilities.getChromeVersion();r&&n.push({label:"๐ŸŒ Chrome Version",value:r});const a=exports.DeviceUtilities.getSafariVersion();a&&n.push({label:"๐Ÿงญ Safari Version",value:a}),n.length>0&&(t+=En(n,!1)),t+="</div>",t+=`<div style='${Up} margin-top: 20px;'>`,t+=`<h3 style='${h_}'>User Agent Info</h3>`;const l=[{label:"User Agent",value:navigator.userAgent},{label:"Platform",value:navigator.platform},{label:"App Version",value:navigator.appVersion},{label:"User Agent Data",value:navigator.userAgentData?`Platform: ${navigator.userAgentData.platform}, Mobile: ${navigator.userAgentData.mobile}`:"Not supported"},{label:"WebXR",value:"xr"in navigator?"โœ…":"โŒ"},{label:"WebGPU",value:"gpu"in navigator?"โœ…":"โŒ"},{label:"WebGL 2",value:Uv()}];t+=En(l,!1),t+="</div>",e(t)}),s}function uC(){if(!globalThis.VConsole)return;const s=new VConsole.VConsolePlugin("graphics-info","๐ŸŽจ Graphics Info");return s.on("renderTab",async function(e){let t=`<div style='${Up}'>`;const i=fC();i.length>0&&(t+=`<h3 style='${Io}'>General GPU Info</h3>`,t+=En(i,!1));const n=mC();n.length>0&&(t+=`<h3 style='${Io}'>WebGL</h3>`,t+=En(n,!1));const o=gC();o.length>0&&(t+=`<h3 style='${Io}'>WebGL 2 Features</h3>`,t+=En(o,!1));const r=yC();r.length>0&&(t+=`<h3 style='${Io}'>WebGL Limits</h3>`,t+=En(r,!1));const a=_C();a.length>0&&(t+=`<h3 style='${Io}'>Texture Formats</h3>`,t+=En(a,!1));const l=await bC();if(l.length>0&&(t+=`<h3 style='${Io}'>WebGPU</h3>`,t+=En(l,!1)),exports.DeviceUtilities.isSafari()){const h=vC();h.length>0&&(t+=`<h3 style='${Io}'>Safari GPU Info</h3>`,t+=En(h,!1))}t+="</div>",e(t)}),s}function fC(){const s=[],e=window.devicePixelRatio;s.push({label:"Device Pixel Ratio",value:e.toString()}),s.push({label:"Width (px)",value:(window.innerWidth*e).toString()}),s.push({label:"Height (px)",value:(window.innerHeight*e).toString()});const i=exports.DeviceUtilities.isMobileDevice()?150:96,n=screen.width/i,o=screen.height/i,r=n*2.54,a=o*2.54;s.push({label:"Estimated Width (cm)",value:r.toFixed(1)}),s.push({label:"Estimated Height (cm)",value:a.toFixed(1)});const l=zv();if(l){s.push({label:"GPU",value:l.renderer}),s.push({label:"Driver",value:l.vendor}),s.push({label:"ANGLE",value:l.angle||"Not detected"});const h=pC(l.renderer);h&&(h.manufacturer&&s.push({label:"Manufacturer",value:h.manufacturer}),h.cardVersion&&s.push({label:"Card Version",value:h.cardVersion}),h.brand&&s.push({label:"Brand",value:h.brand}),s.push({label:"Integrated",value:h.integrated?"Yes":"No"}),h.layer&&s.push({label:"WebGL Layer",value:h.layer}))}return s}function pC(s){if(!s)return null;const e=(h,d)=>{const u=d.match(h);return u&&u[0]},t=e(/(ANGLE)/g,s)||void 0,i=e(/((NVIDIA|AMD|Intel)[^\d]*[^\s]+)/,s)||s,n=i.split(" ");n.shift();const o=e(/(NVIDIA|AMD|Intel)/g,i)||void 0,r=n.length>0?n.pop():void 0,a=n.length>0?n.join(" "):void 0;return{manufacturer:o,cardVersion:r,brand:a,integrated:o==="Intel",layer:t,card:i}}function mC(){const s=[],e=zv();return e&&(s.push({label:"๐Ÿ“Š WebGL Version",value:e.version}),s.push({label:"๐ŸŽฎ WebGL 2 Available",value:Uv()})),s}function gC(){const s=[];try{const t=document.createElement("canvas").getContext("webgl2");if(!t)return s;s.push({label:"Float Color Buffer",value:t.getExtension("EXT_color_buffer_float")?"โœ…":"โŒ"}),s.push({label:"Anisotropic Filtering",value:t.getExtension("EXT_texture_filter_anisotropic")?"โœ…":"โŒ"}),s.push({label:"Float Texture Linear",value:t.getExtension("OES_texture_float_linear")?"โœ…":"โŒ"}),s.push({label:"S3TC Compression",value:t.getExtension("WEBGL_compressed_texture_s3tc")?"โœ…":"โŒ"}),s.push({label:"ETC Compression",value:t.getExtension("WEBGL_compressed_texture_etc")?"โœ…":"โŒ"}),s.push({label:"PVRTC Compression",value:t.getExtension("WEBGL_compressed_texture_pvrtc")?"โœ…":"โŒ"}),s.push({label:"ASTC Compression",value:t.getExtension("WEBGL_compressed_texture_astc")?"โœ…":"โŒ"})}catch{}return s}function yC(){const s=[];try{const e=document.createElement("canvas"),t=e.getContext("webgl2")||e.getContext("webgl");if(!t)return s;const i=t instanceof WebGL2RenderingContext;s.push({label:"๐Ÿ“ Max Texture Size",value:t.getParameter(t.MAX_TEXTURE_SIZE).toString()}),s.p