@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.
144 lines (131 loc) โข 1.29 MB
JavaScript
"use strict";const c=require("./three.umd.cjs"),oe=require("./gltf-progressive-BacJPTD6.umd.cjs"),q=require("./three-examples.umd.cjs"),re=require("./vendor-BwxpsdCm.umd.cjs"),te=require("./three-mesh-ui-Chib781Y.umd.cjs"),Ux=require("./postprocessing-C_736uMz.umd.cjs");var ga=typeof document<"u"?document.currentScript:null;const _f=new Map;function pi(s=globalThis.location?.hostname){if(_f.has(s))return _f.get(s);const e=/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})|localhost/.test(s);return _f.set(s,e),e===!0}function Yb(){return window.location.hostname.includes("glitch.me")}const Vy=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 le{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&&(Vy&&console.warn("Registering context"),this.Registered.push(e),this.dispatchCallback("ContextRegistered",e))}static unregister(e){const t=this.Registered.indexOf(e);t!==-1&&(Vy&&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 Kb=()=>s=>s;function Fx(s){return Kb()(s)}function zx(){return!!x("debug")}class mi{_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 Wo=!1;const Pp=new Array;typeof window<"u"&&setTimeout(()=>{if(Wo){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 Pp){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=Wo===!0?"":` (containing "${Wo}")`;console.group("Available URL parameters:"+n);for(const o of Object.keys(s).sort())typeof Wo=="string"&&!o.toLowerCase().includes(Wo.toLowerCase())||(console.groupCollapsed(o),console.log("Reload with this flag enabled:"),console.log(s[o]),console.groupEnd());console.groupEnd()}},100);function Dc(){return new URLSearchParams(globalThis.location?.search)}function x(s){Wo&&!Pp.includes(s)&&Pp.push(s);const e=Dc();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}Wo=x("help");function Nx(s,e){const t=Dc();t.has(s)?t.set(s,e):t.append(s,e),document.location.search=t.toString()}function fc(s,e,t=!0){const i=Dc();i.has(s)?e===null?i.delete(s):i.set(s,e):e!==null&&i.append(s,e),t?Zb(s,i):Pm(s,i)}function Op(s,e,t){s.has(e)?s.set(e,t.toString()):s.append(e,t.toString())}function Zb(s,e,t){window.history.pushState(t,s,"?"+e.toString())}function Pm(s,e,t){window.history.replaceState(t,s,"?"+e.toString())}function Vx(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 $x(s,e){return Math.floor(Math.random()*(e-s+1))+s}const $y=["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"],Wy=["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 Jb(){const s=$y[Math.floor(Math.random()*$y.length)],e=Wy[Math.floor(Math.random()*Wy.length)];return s+"_"+e}function ev(s){return s=s.replace(/[^a-z0-9รกรฉรญรณรบรฑรผ \.,_-]/gim,""),s.trim()}function Oa(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=Oa(s,o,t,i);if(r)return r}if(e.children)for(const n in e.children){const o=e.children[n],r=Oa(s,o,t,i);if(r)return r}}}function Lc(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]=Lc(n,e)}return t}return s}function gs(s){return new Promise((e,t)=>{setTimeout(e,s)})}function Ic(s,e){if(s<=0)return Promise.resolve();if(e||(e=le.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 Eh=x("debugresolveurl"),tv="rel:";function Wx(s,e){return bs(s,e)}function bs(s,e){if(e===void 0)return Eh&&console.warn("getPath: uri is undefined, returning uri",e),e;if(e.startsWith("./"))return e;if(e.startsWith("http"))return Eh&&console.warn("getPath: uri is absolute, returning uri",e),e;if(s===void 0)return Eh&&console.warn("getPath: source is undefined, returning uri",e),e;e.startsWith(tv)&&(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 Eh&&console.log("source:",s,`changed uri
from`,e,`
to `,n,`
basePath: `+i),n}return e}function iv(s){if(s)return s=s.trim(),s=s.split("?")[0]?.split("#")[0],s}class Gx{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 fs{_watches=[];constructor(e,t){if(Array.isArray(t))for(const i of t)this._watches.push(new fs(e,i));else this._watches.push(new Gx(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 Jr=Symbol("needle:watches");function au(s,e){if(!s[Jr])if(s instanceof c.Vector2)s[Jr]=new fs(s,["x","y"]);else if(s instanceof c.Vector3)s[Jr]=new fs(s,["x","y","z"]);else if(s instanceof c.Vector4||s instanceof c.Quaternion)s[Jr]=new fs(s,["x","y","z","w"]);else return!1;return s[Jr].subscribeWrite(e),!0}function Om(s,e){if(!s)return;const t=s[Jr];t&&t.unsubscribeWrite(e)}exports.DeviceUtilities=void 0;(s=>{let e;function t(){if(e!==void 0)return e;const X=window.navigator.userAgent,ge=/Windows|MacOS|Mac OS/.test(X),Ht=/Windows NT/.test(X)&&/Edg/.test(X)&&!/Win64/.test(X);return e=ge&&!Ht&&!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 X=navigator.userAgent.toLowerCase();return r=/iPad/.test(navigator.userAgent)||X.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 X=navigator.userAgent.toLowerCase();return navigator.userAgentData?y=navigator.userAgentData.platform==="macOS":y=X.includes("mac os x")||X.includes("macintosh")}s.isMacOS=_;let g;function w(){return g!==void 0?g:g=a()&&"xr"in navigator&&N()}s.isVisionOS=w;let b;const v=["iPad Simulator","iPhone Simulator","iPod Simulator","iPad","iPhone","iPod"];function R(){return b!==void 0?b:b=v.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 A;function D(){return A!==void 0?A:A=navigator.userAgent.includes("OculusBrowser")}s.isQuest=D;let I;function N(){return I!==void 0||(I=document.createElement("a").relList.supports("ar")),I}s.supportsQuickLookAR=N;async function $(){try{return(await navigator.permissions.query({name:"microphone"})).state!=="denied"}catch(X){return console.error("Error querying `microphone` permissions.",X),!1}}s.microphonePermissionsGranted=$;let k;function z(){if(k!==void 0)return k;const X=navigator.userAgent.match(/iPhone OS (\d+_\d+)/);if(X&&(k=X[1].replace("_",".")),!k){const ge=navigator.userAgent.match(/(?:\(Macintosh;|iPhone;|iPad;).*Version\/(\d+\.\d+)/);ge&&(k=ge[1])}return k||(k=null),k}s.getiOSVersion=z;let V;function J(){if(V!==void 0)return V;const X=navigator.userAgent.match(/(?:CriOS|Chrome)\/(\d+\.\d+\.\d+\.\d+)/);return X?V=X[1].replace("_","."):V=null,V}s.getChromeVersion=J;let Z;function ce(){if(Z!==void 0)return Z;const X=navigator.userAgent.match(/Version\/(\d+\.\d+)/);return X&&M()?Z=X[1]:Z=null,Z}s.getSafariVersion=ce})(exports.DeviceUtilities||(exports.DeviceUtilities={}));function Hx(){return exports.DeviceUtilities.isDesktop()}function qx(){return exports.DeviceUtilities.isMobileDevice()}function Xx(){return exports.DeviceUtilities.isiPad()}function Qx(){return exports.DeviceUtilities.isiPad()}function Yx(){return exports.DeviceUtilities.isAndroidDevice()}function Kx(){return exports.DeviceUtilities.isMozillaXR()}function Zx(){return exports.DeviceUtilities.isMacOS()}function Jx(){return exports.DeviceUtilities.isiOS()}function eS(){return exports.DeviceUtilities.isSafari()}function tS(){return exports.DeviceUtilities.isQuest()}async function iS(){return exports.DeviceUtilities.microphonePermissionsGranted()}const eo=new WeakMap;function Mm(s,e,t){if(!eo.get(s)){const n=new MutationObserver(o=>{nS(s,o)});eo.set(s,{observer:n,attributeChangedListeners:new Map}),n.observe(s,{attributes:!0})}const i=eo.get(s).attributeChangedListeners;return i.has(e)||i.set(e,[]),i.get(e).push(t),()=>{km(s,e,t)}}function km(s,e,t){if(!eo.get(s))return;const i=eo.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),eo.get(s)?.observer.disconnect(),eo.delete(s)))}function nS(s,e){const t=eo.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 Mp{reason;constructor(e){this.reason=e}}async function Em(s){const e=await Promise.allSettled(s).catch(n=>[new Mp(n.message)]);let t=!1;const i=e.map(n=>"value"in n?n.value:(t=!0,new Mp(n.reason)));return{anyFailed:t,results:i}}const sS=x("debugdebug");let Rm=!1;(x("noerrors")||x("nooverlaymessages"))&&(Rm=!0);const bf="needle_engine_global_error_container";var ui=(s=>(s[s.Log=0]="Log",s[s.Warn=1]="Warn",s[s.Error=2]="Error",s))(ui||{});function nv(){return rv}const kp=new Array;function oS(s){kp.push(s)}let vf=!1;function rS(...s){if(!vf){vf=!0;try{for(let e=0;e<kp.length;e++)kp[e](...s)}catch(e){console.error(e)}vf=!1}}const sv=console.error,aS=function(...s){sv.apply(console,s),hS(s),Xo(2,s,{}),cS(...s)};function ov(s){Rm=!s,s?console.error=aS:console.error=sv}function lS(s){return ov(s)}let rv=0;function cS(...s){rv+=1,rS(...s)}function hS(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 Gy=new Set;function Xo(s,e,t={},i,n){if(Rm)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(Gy.has(a))return;Gy.add(a)}const o=le.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||dS(s,r,e,t)}}const la=new Map,Hy=.2;function dS(s,e,t,i={}){if(t==null)return;const n=pS(e);if(n.childElementCount>=20){const h=n.lastElementChild;qy(h)}t.length>400&&(t=t.substring(0,400)+"...");const o=i.key??t;if(la.has(o)){la.get(o)?.update(t,i);return}const r=mS(s,t);n.prepend(r);const a=()=>{la.delete(o),qy(r)};let l=setTimeout(a,Math.max(Hy,i.duration??10)*1e3);la.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(Hy,d.duration)*1e3))},removeFunction:a})}function uS(){sS&&console.log("Clearing messages");for(const s of la.values())s?.removeFunction.call(s);la.clear()}const fS=`
@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 pS(s){globalThis[bf]||(globalThis[bf]=new Map);const e=globalThis[bf];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=fS,t.appendChild(n),t}}const av=Symbol("logtype"),Td=new Map;function qy(s){s.remove();const e=s[av],t=Td.get(e)??[];t.push(s),Td.set(e,t)}function mS(s,e){if(Td.has(s)){const i=Td.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[av]=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}class gS{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 yS){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 yS=["x","y","z","w"],L=new gS;class Xy{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 cd{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 Xy(this.alpha(this.minCutOff)),this.dx=new Xy(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 Tm{x;y;z;constructor(e,t=1,i=0,n=1){this.x=new cd(e,t,i,n),this.y=new cd(e,t,i,n),this.z=new cd(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 hd="needle:cameraController";function lv(s){return s[hd]}function Ep(s,e,t){t?s[hd]=e:s[hd]===e&&(s[hd]=null)}const Rp="needle:autofit";function cv(s){return s[Rp]===void 0?!0:s[Rp]!==!1}function Ad(s,e){s[Rp]=e}let Ki;const _S={x:0,y:0,width:0,height:0},bS=x("debugfocusrect");function vS(s,e,t,i,n){s instanceof Element&&(bS&&s instanceof HTMLElement&&(s.style.outline="2px dashed rgba(255, 150, 0, .8)"),s=s.getBoundingClientRect()),Ki=n.domElement.getBoundingClientRect();const o=_S;o.x=s.x,o.y=s.y,o.width=s.width,o.height=s.height,o.x-=Ki.x,o.y-=Ki.y;const r=Ki.width,a=Ki.height,l=i.view,h=e.zoom;let d=l?.offsetX||0,u=l?.offsetY||0,p=Ki.width,m=Ki.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=Ki.width*.5,w=Ki.height*.5,b=y-g,v=_-w;d-=b/h,u-=v/h,e.offsetX!==void 0&&(d+=e.offsetX*(Ki.width*.5)),e.offsetY!==void 0&&(u-=e.offsetY*(Ki.height*.5));const R=l?.offsetX||d,O=l?.offsetY||u;d=L.lerp(R,d,t),u=L.lerp(O,u,t);const M=l?.width||r,A=l?.height||a;p=L.lerp(M,p,t),m=L.lerp(A,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 wS(s,e,t){const i=s.length(),n=e.length(),o=L.lerp(i,n,t);return s.lerp(e,t).normalize().multiplyScalar(o)}const wf=new c.Quaternion,hv=new c.Quaternion().setFromAxisAngle(new c.Vector3(0,1,0),Math.PI);function xS(s,e){s.lookAt(e),s.quaternion.multiply(hv)}function jc(s,e,t=!0,i=!1){if(s===e)return;wf.copy(s.quaternion);const n=Q(e),o=Q(s);if(i){if(ln(s,fe(e)),t){const r=o.y,a=o.sub(uv(s));a.y=r,s.lookAt(a),s.quaternion.multiply(hv)}Number.isNaN(s.quaternion.x)&&s.quaternion.copy(wf);return}t&&(n.y=o.y),s.lookAt(n),Number.isNaN(s.quaternion.x)&&s.quaternion.copy(wf)}function SS(s,e,t,i=1){if(t){const n=B(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 CS=new mi(()=>new c.Vector3,100);function B(s,e,t){const i=CS.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 PS=new mi(()=>new c.Color,30);function dv(s){const e=PS.get();return s?e.copy(s):e.set(0,0,0),e}const OS=new mi(()=>new c.Quaternion,100);function Kt(s,e,t,i){const n=OS.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 Am=new mi(()=>new c.Vector3,100),Qy=Symbol("lastMatrixWorldUpdateKey");function Q(s,e=null,t=!0){const i=e??Am.get();return s?s.parent?(t&&s.updateWorldMatrix(!0,!1),s.matrixWorldNeedsUpdate&&s[Qy]!==Date.now()&&(s[Qy]=Date.now(),s.updateMatrixWorld()),i.setFromMatrixPosition(s.matrixWorld),i):i.copy(s.position):i.set(0,0,0)}function ot(s,e){if(!s)return s;const t=Am.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 cr(s,e,t,i){const n=Am.get();return n.set(e,t,i),ot(s,n),s}const Dd=new mi(()=>new c.Quaternion,100),Zo=new c.Quaternion,xf=new c.Quaternion;function fe(s,e=null){if(!s)return Dd.get().identity();const t=e??Dd.get();return s.parent?(s.getWorldQuaternion(t),t):t.copy(s.quaternion)}function ln(s,e){if(!s)return;e!==Zo&&Zo.copy(e);const t=Zo;s?.parent?.getWorldQuaternion(xf),xf.invert();const n=xf.multiply(t);s.quaternion.set(n.x,n.y,n.z,n.w)}function Dm(s,e,t,i,n){Zo.set(e,t,i,n),ln(s,Zo)}const MS=new mi(()=>new c.Vector3,100),kS=new c.Vector3;function Le(s,e=null){return e||(e=MS.get()),s?s.parent?(s.getWorldScale(e),e):e.copy(s.scale):e.set(0,0,0)}function Ma(s,e){if(!s)return;if(!s.parent){s.scale.copy(e);return}const t=kS;s.parent.getWorldScale(t),s.scale.copy(e),s.scale.divide(t)}const ES=new c.Vector3,Yy=new c.Quaternion;function RS(s){return fe(s,Yy),ES.set(0,0,1).applyQuaternion(Yy)}const TS=new mi(()=>new c.Vector3,100),Ky=new c.Quaternion;function uv(s,e){return e||(e=TS.get().set(0,0,1)),fe(s,Ky),e.applyQuaternion(Ky)}const Zy=new c.Euler,Jy=new c.Euler,AS=new c.Vector3;function Lm(s){const e=Dd.get();return s.getWorldQuaternion(e),Jy.setFromQuaternion(e),Jy}function Im(s,e){const t=Dd.get();ln(s,t.setFromEuler(e))}function lu(s){const e=Lm(s),t=AS;return t.set(e.x,e.y,e.z),t.x=L.toDegrees(t.x),t.y=L.toDegrees(t.y),t.z=L.toDegrees(t.z),t}function fv(s,e){Bc(s,e.x,e.y,e.z,!0)}function Bc(s,e,t,i,n=!0){n&&(e=L.toRadians(e),t=L.toRadians(t),i=L.toRadians(i)),Zy.set(e,t,i),Zo.setFromEuler(Zy),ln(s,Zo)}function Ld(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 DS(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 pv(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 Id extends c.ShaderMaterial{static vertex=`
varying vec2 vUv;
void main(){
vUv = uv;
gl_Position = vec4(position.xy, 0., 1.0);
}`;constructor(){super({vertexShader:Id.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 lo{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 Id;static mesh=new c.Mesh(lo.planeGeometry,lo.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=Id.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.pixelRatio!==window.devicePixelRatio&&n.xr.isPresenting===!1&&n.setPixelRatio(window.devicePixelRatio),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=mv(e));const i=e.image;if(IS(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 mv(s){return lo.copyTexture(s)}function LS(s,e=!1){return lo.textureToCanvas(s,e)}function IS(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 jS(s){const e=s.type;return e==="Mesh"||e==="SkinnedMesh"}function jm(s,e){e?s["needle:rendercustomshadow"]=!0:s["needle:rendercustomshadow"]=!1}function gv(s){if(s){if(s["needle:rendercustomshadow"]===!0)return!0;if(s["needle:rendercustomshadow"]==null)return!0}return!1}function ii(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 q.GroundedSkybox&&(h=!1),l.isGizmo===!0&&(h=!1),l.material instanceof c.ShadowMaterial&&(h=!1),jS(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 yv(s,e,t){const i=ii([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&&Ma(s,Le(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),ot(s,Q(s).add(m))}return{boundsBefore:i,scale:l}}function _v(s,e){const t=ii([s]),i=new c.Vector3;t.getCenter(i),i.y=t.min.y;const n=e.clone().sub(i),o=Q(s);return ot(s,o.add(n)),{offset:n,bounds:t}}function Bm(s,e,t,i){if(Array.isArray(e)){let r=!0;for(let a=0;a<e.length;a++)Bm(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 Rh=!1;oS((...s)=>{T()&&le.Current?.isInXR&&(ya(!0),bv("error",...s))});function ya(s){if(s){if(Rh)return;Rh=!0,US()}else{if(!Rh)return;Rh=!1,FS()}}const Yl={log:void 0,warn:void 0,error:void 0};class BS{familyName="needle-xr";root=null;context=null;defaultFontSize=.06;constructor(){this.ensureFont()}onEnable(){this.context=le.Current||le.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 Tm(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),jc(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 te.__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}),te.__webpack_exports__default.update()}ensureFont(){let e=te.__webpack_exports__default.FontLibrary.getFontFamily(this.familyName);e||(e=te.__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",()=>{te.__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 te.__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&&te.__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 te.__webpack_exports__default.Block(t),this.root}}let Jo=null;function US(){Jo||(Jo=new BS),Jo.onEnable();for(const s in Yl){Yl[s]=console[s];let e=!1;console[s]=function(){if(Yl[s]?.apply(console,arguments),!e)try{e=!0,bv(s,...arguments)}finally{e=!1}}}}function FS(){Jo?.onDisable();for(const s in Yl)console[s]=Yl[s]}const yl=new Map;function bv(s,...e){try{switch(yl.clear(),s){case"log":Jo?.addLog("log",t());break;case"warn":Jo?.addLog("warn",t());break;case"error":Jo?.addLog("error",t());break}}catch(o){console.error("Error in spatial console",o)}finally{yl.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(yl.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(yl.has(p)){h+="";continue}yl.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}}const zS=x("nodevlogs");function we(s,e){Xo(e?.type??ui.Log,s,e)}function ue(s,e){we(s,{...e,type:ui.Warn})}function Uc(s,e){we(s,{...e,type:ui.Error})}let Tp,Sf;function T(){if(zS)return!1;if(Tp!==void 0)return Tp;if(Sf!==void 0)return Sf;let s=pi();return s||(s=window.location.hostname.endsWith(".local-credentialless.webcontainer.io")),Sf=s,s}function NS(s){Tp=s}let Qt,Do=null,An=null,_l=!1,e_=null;const vv="terminal",VS=x("console");VS&&Um();const $S=Symbol("consoleParent");function Um(){if(Qt){Qt.showSwitch();return}XS()}function wv(){Qt&&(Qt.hide(),Qt.hideSwitch())}function WS(){e_||(e_=setInterval(GS,500))}let t_=0;function GS(){const s=nv(),e=s!==t_;t_=s,e&&HS()}function HS(){Um(),An&&(An.setAttribute("error","true"),An.innerText="๐คฌ")}function qS(){An&&(An.removeAttribute("error"),An.innerText=vv)}function XS(s=!1){if(Qt!==void 0||_l)return;_l=!0;const e=document.createElement("script");e.onload=()=>{if(!globalThis.VConsole){console.warn("๐ต Debug console failed to load."),_l=!1,Qt=null;return}_l=!1,WS(),Qt=new VConsole({pluginOrder:["default","needle-console"]});const t=globalThis["needle:codegen_files"];if(t&&t.length>0&&Qt.addPlugin(QS()),Qt.addPlugin(JS()),Qt.addPlugin(eC()),Do=dC(),Do&&(Do[$S]=Do.parentElement,Do.style.position="absolute",Do.style.zIndex=Number.MAX_SAFE_INTEGER.toString()),Qt.setSwitchPosition(20,30),An=hC(),An){An.innerText=vv,An.addEventListener("click",qS);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;
}
`,Do?.prepend(i),s===!0&&nv()<=0&&wv(),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.":"")),_l=!1,Qt=null},e.src="https://cdn.jsdelivr.net/npm/vconsole@3.15.1/dist/vconsole.min.js",document.body.appendChild(e)}function QS(){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"),Qt?.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 Ap="padding: 10px; font-family: monospace;",i_="margin-bottom: 10px;",Lo="margin-bottom: 10px; margin-top: 15px;",YS="width: 100%; border-collapse: collapse; border: 1px solid rgba(0,0,0,0.1); table-layout: fixed;",xv="border: 1px solid rgba(0,0,0,0.1); padding: 5px;",KS=xv,ZS=xv+" word-break: break-all;";function On(s,e=!1){e&&s.sort((i,n)=>(n.value?1:0)-(i.value?1:0));let t=`<table style='${YS}'>`;t+="<tbody>";for(const i of s){const n=typeof i.value=="boolean"?i.value?"โ
":"โ":i.value;t+=`<tr><td style='${KS}'>${i.label}</td><td style='${ZS}'>${n}</td></tr>`}return t+="</tbody></table>",t}function Sv(){try{if(document.createElement("canvas").getContext("webgl2"))return"โ
"}catch{}return"โ"}function JS(){if(!globalThis.VConsole)return;const s=new VConsole.VConsolePlugin("device-utilities","๐ฑ Device Info");return s.on("renderTab",function(e){let t=`<div style='${Ap}'>`;const i=cC();t+=`<h3 style='${i_}'>Device: ${i}</h3>`,t+=On([{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+=On(n,!1)),t+="</div>",t+=`<div style='${Ap} margin-top: 20px;'>`,t+=`<h3 style='${i_}'>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:Sv()}];t+=On(l,!1),t+="</div>",e(t)}),s}function eC(){if(!globalThis.VConsole)return;const s=new VConsole.VConsolePlugin("graphics-info","๐จ Graphics Info");return s.on("renderTab",async function(e){let t=`<div style='${Ap}'>`;const i=tC();i.length>0&&(t+=`<h3 style='${Lo}'>General GPU Info</h3>`,t+=On(i,!1));const n=nC();n.length>0&&(t+=`<h3 style='${Lo}'>WebGL</h3>`,t+=On(n,!1));const o=sC();o.length>0&&(t+=`<h3 style='${Lo}'>WebGL 2 Features</h3>`,t+=On(o,!1));const r=oC();r.length>0&&(t+=`<h3 style='${Lo}'>WebGL Limits</h3>`,t+=On(r,!1));const a=rC();a.length>0&&(t+=`<h3 style='${Lo}'>Texture Formats</h3>`,t+=On(a,!1));const l=await aC();if(l.length>0&&(t+=`<h3 style='${Lo}'>WebGPU</h3>`,t+=On(l,!1)),exports.DeviceUtilities.isSafari()){const h=lC();h.length>0&&(t+=`<h3 style='${Lo}'>Safari GPU Info</h3>`,t+=On(h,!1))}t+="</div>",e(t)}),s}function tC(){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=Cv();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=iC(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 iC(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 nC(){const s=[],e=Cv();return e&&(s.push({label:"๐ WebGL Version",value:e.version}),s.push({label:"๐ฎ WebGL 2 Available",value:Sv()})),s}function sC(){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 oC(){const s=[];try{const e=document.createElement("canvas"),t=e.getContext("webgl2")||e.getContext("webgl");if(!t)return s;const i=t instanceof WebGL2Render