@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
JavaScript
"use strict";const c=require("./three.umd.cjs"),re=require("./gltf-progressive-BBIL1q1j.umd.cjs"),X=require("./three-examples.umd.cjs"),ce=require("./vendor-BLeytgEr.umd.cjs"),ie=require("./three-mesh-ui-Chib781Y.umd.cjs"),Zx=require("./postprocessing-B2wb6pzI.umd.cjs");var ga=typeof document<"u"?document.currentScript:null;const Qy=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&&(Qy&&console.warn("Registering context"),this.Registered.push(e),this.dispatchCallback("ContextRegistered",e))}static unregister(e){const t=this.Registered.indexOf(e);t!==-1&&(Qy&&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 Pf=new Map;function yi(s=globalThis.location?.hostname){if(Pf.has(s))return Pf.get(s);const e=/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})|localhost/.test(s);return Pf.set(s,e),e===!0}function dv(){return window.location.hostname.includes("glitch.me")}const uv=()=>s=>s;function Jx(s){return uv()(s)}function eS(){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 Tp=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 Tp){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 Bc(){return new URLSearchParams(globalThis.location?.search)}function x(s){Go&&!Tp.includes(s)&&Tp.push(s);const e=Bc();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 tS(s,e){const t=Bc();t.has(s)?t.set(s,e):t.append(s,e),document.location.search=t.toString()}function yc(s,e,t=!0){const i=Bc();i.has(s)?e===null?i.delete(s):i.set(s,e):e!==null&&i.append(s,e),t?fv(s,i):Am(s,i)}function Ap(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 Am(s,e,t){window.history.replaceState(t,s,"?"+e.toString())}function iS(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 nS(s,e){return Math.floor(Math.random()*(e-s+1))+s}const Yy=["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"],Ky=["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=Yy[Math.floor(Math.random()*Yy.length)],e=Ky[Math.floor(Math.random()*Ky.length)];return s+"_"+e}function mv(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 Fc(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]=Fc(n,e)}return t}return s}function _s(s){return new Promise((e,t)=>{setTimeout(e,s)})}function Uc(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 Dh=x("debugresolveurl"),gv="rel:";function sS(s,e){return ws(s,e)}function ws(s,e){if(e===void 0)return Dh&&console.warn("getPath: uri is undefined, returning uri",e),e;if(e.startsWith("./"))return e;if(e.startsWith("http"))return Dh&&console.warn("getPath: uri is absolute, returning uri",e),e;if(s===void 0)return Dh&&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 Dh&&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 oS{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 oS(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 fu(s,e){if(!s[Jr])if(s instanceof c.Vector2)s[Jr]=new ms(s,["x","y"]);else if(s instanceof c.Vector3)s[Jr]=new ms(s,["x","y","z"]);else if(s instanceof c.Vector4||s instanceof c.Quaternion)s[Jr]=new ms(s,["x","y","z","w"]);else return!1;return s[Jr].subscribeWrite(e),!0}function Dm(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 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 w(){return g!==void 0?g:g=a()&&"xr"in navigator&&V()}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 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 he(){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=he})(exports.DeviceUtilities||(exports.DeviceUtilities={}));function rS(){return exports.DeviceUtilities.isDesktop()}function aS(){return exports.DeviceUtilities.isMobileDevice()}function lS(){return exports.DeviceUtilities.isiPad()}function cS(){return exports.DeviceUtilities.isiPad()}function hS(){return exports.DeviceUtilities.isAndroidDevice()}function dS(){return exports.DeviceUtilities.isMozillaXR()}function uS(){return exports.DeviceUtilities.isMacOS()}function fS(){return exports.DeviceUtilities.isiOS()}function pS(){return exports.DeviceUtilities.isSafari()}function mS(){return exports.DeviceUtilities.isQuest()}async function gS(){return exports.DeviceUtilities.microphonePermissionsGranted()}const io=new WeakMap;function Lm(s,e,t){if(!io.get(s)){const n=new MutationObserver(o=>{yS(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),()=>{Im(s,e,t)}}function Im(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 yS(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 Dp{reason;constructor(e){this.reason=e}}async function jm(s){const e=await Promise.allSettled(s).catch(n=>[new Dp(n.message)]);let t=!1;const i=e.map(n=>"value"in n?n.value:(t=!0,new Dp(n.reason)));return{anyFailed:t,results:i}}const _S=x("debugdebug");let Bm=!1;(x("noerrors")||x("nooverlaymessages"))&&(Bm=!0);const Of="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 Lp=new Array;function bS(s){Lp.push(s)}let Mf=!1;function vS(...s){if(!Mf){Mf=!0;try{for(let e=0;e<Lp.length;e++)Lp[e](...s)}catch(e){console.error(e)}Mf=!1}}const bv=console.error,wS=function(...s){bv.apply(console,s),CS(s),Qo(2,s,{}),SS(...s)};function vv(s){Bm=!s,s?console.error=wS:console.error=bv}function xS(s){return vv(s)}let wv=0;function SS(...s){wv+=1,vS(...s)}function CS(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 Zy=new Set;function Qo(s,e,t={},i,n){if(Bm)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(Zy.has(a))return;Zy.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||PS(s,r,e,t)}}const la=new Map,Jy=.2;function PS(s,e,t,i={}){if(t==null)return;const n=kS(e);if(n.childElementCount>=20){const h=n.lastElementChild;e_(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=ES(s,t);n.prepend(r);const a=()=>{la.delete(o),e_(r)};let l=setTimeout(a,Math.max(Jy,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(Jy,d.duration)*1e3))},removeFunction:a})}function OS(){_S&&console.log("Clearing messages");for(const s of la.values())s?.removeFunction.call(s);la.clear()}const MS=`
@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 kS(s){globalThis[Of]||(globalThis[Of]=new Map);const e=globalThis[Of];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=MS,t.appendChild(n),t}}const xv=Symbol("logtype"),Fd=new Map;function e_(s){s.remove();const e=s[xv],t=Fd.get(e)??[];t.push(s),Fd.set(e,t)}function ES(s,e){if(Fd.has(s)){const i=Fd.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 RS=x("nodevlogs");let Ip,kf;function A(){if(RS)return!1;if(Ip!==void 0)return Ip;if(kf!==void 0)return kf;let s=yi();return s||(s=window.location.hostname.endsWith(".local-credentialless.webcontainer.io")),kf=s,s}function TS(s){Ip=s}class AS{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 DS){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 DS=["x","y","z","w"],I=new AS;class t_{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 pd{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 t_(this.alpha(this.minCutOff)),this.dx=new t_(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 Fm{x;y;z;constructor(e,t=1,i=0,n=1){this.x=new pd(e,t,i,n),this.y=new pd(e,t,i,n),this.z=new pd(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 md="needle:cameraController";function Sv(s){return s[md]}function jp(s,e,t){t?s[md]=e:s[md]===e&&(s[md]=null)}const Bp="needle:autofit";function Cv(s){return s[Bp]===void 0?!0:s[Bp]!==!1}function Ud(s,e){s[Bp]=e}let en;const LS={x:0,y:0,width:0,height:0},IS=x("debugfocusrect");function jS(s,e,t,i,n){s instanceof Element&&(IS&&s instanceof HTMLElement&&(s.style.outline="2px dashed rgba(255, 150, 0, .8)"),s=s.getBoundingClientRect()),en=n.domElement.getBoundingClientRect();const o=LS;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,w=en.height*.5,b=y-g,v=_-w;d-=b/h,u-=v/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 Ef=new c.Quaternion,Ov=new c.Quaternion().setFromAxisAngle(new c.Vector3(0,1,0),Math.PI);function BS(s,e){s.lookAt(e),s.quaternion.multiply(Ov)}function zc(s,e,t=!0,i=!1){if(s===e)return;Ef.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(Ef);return}t&&(n.y=o.y),s.lookAt(n),Number.isNaN(s.quaternion.x)&&s.quaternion.copy(Ef)}function FS(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 US=new _i(()=>new c.Vector3,100);function F(s,e,t){const i=US.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 zS=new _i(()=>new c.Color,30);function Mv(s){const e=zS.get();return s?e.copy(s):e.set(0,0,0),e}const NS=new _i(()=>new c.Quaternion,100);function ei(s,e,t,i){const n=NS.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 Um=new _i(()=>new c.Vector3,100),i_=Symbol("lastMatrixWorldUpdateKey");function Y(s,e=null,t=!0){const i=e??Um.get();return s?s.parent?(t&&s.updateWorldMatrix(!0,!1),s.matrixWorldNeedsUpdate&&s[i_]!==Date.now()&&(s[i_]=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=Um.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=Um.get();return n.set(e,t,i),at(s,n),s}const zd=new _i(()=>new c.Quaternion,100),Jo=new c.Quaternion,Rf=new c.Quaternion;function pe(s,e=null){if(!s)return zd.get().identity();const t=e??zd.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(Rf),Rf.invert();const n=Rf.multiply(t);s.quaternion.set(n.x,n.y,n.z,n.w)}function zm(s,e,t,i,n){Jo.set(e,t,i,n),dn(s,Jo)}const VS=new _i(()=>new c.Vector3,100),$S=new c.Vector3;function je(s,e=null){return e||(e=VS.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=$S;s.parent.getWorldScale(t),s.scale.copy(e),s.scale.divide(t)}const WS=new c.Vector3,n_=new c.Quaternion;function GS(s){return pe(s,n_),WS.set(0,0,1).applyQuaternion(n_)}const HS=new _i(()=>new c.Vector3,100),s_=new c.Quaternion;function kv(s,e){return e||(e=HS.get().set(0,0,1)),pe(s,s_),e.applyQuaternion(s_)}const o_=new c.Euler,r_=new c.Euler,qS=new c.Vector3;function Nm(s){const e=zd.get();return s.getWorldQuaternion(e),r_.setFromQuaternion(e),r_}function Vm(s,e){const t=zd.get();dn(s,t.setFromEuler(e))}function pu(s){const e=Nm(s),t=qS;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){Nc(s,e.x,e.y,e.z,!0)}function Nc(s,e,t,i,n=!0){n&&(e=I.toRadians(e),t=I.toRadians(t),i=I.toRadians(i)),o_.set(e,t,i),Jo.setFromEuler(o_),dn(s,Jo)}function Nd(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 XS(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 Vd extends c.ShaderMaterial{static vertex=`
varying vec2 vUv;
void main(){
vUv = uv;
gl_Position = vec4(position.xy, 0., 1.0);
}`;constructor(){super({vertexShader:Vd.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 Vd;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=Vd.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(YS(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 QS(s,e=!1){return co.textureToCanvas(s,e)}function YS(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 KS(s){const e=s.type;return e==="Mesh"||e==="SkinnedMesh"}function $m(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),KS(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&&Ma(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 Wm(s,e,t,i){if(Array.isArray(e)){let r=!0;for(let a=0;a<e.length;a++)Wm(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 Lh=!1;bS((...s)=>{A()&&le.Current?.isInXR&&(ya(!0),Iv("error",...s))});function ya(s){if(s){if(Lh)return;Lh=!0,JS()}else{if(!Lh)return;Lh=!1,eC()}}const Jl={log:void 0,warn:void 0,error:void 0};class ZS{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 Fm(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),zc(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 JS(){er||(er=new ZS),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 eC(){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 Vc(s,e){Se(s,{...e,type:gi.Error})}let Zt,Lo=null,In=null,vl=!1,a_=null;const jv="terminal",tC=x("console");tC&&Gm();const iC=Symbol("consoleParent");function Gm(){if(Zt){Zt.showSwitch();return}aC()}function Bv(){Zt&&(Zt.hide(),Zt.hideSwitch())}function nC(){a_||(a_=setInterval(sC,500))}let l_=0;function sC(){const s=_v(),e=s!==l_;l_=s,e&&oC()}function oC(){Gm(),In&&(In.setAttribute("error","true"),In.innerText="๐คฌ")}function rC(){In&&(In.removeAttribute("error"),In.innerText=jv)}function aC(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,nC(),Zt=new VConsole({pluginOrder:["default","needle-console"]});const t=globalThis["needle:codegen_files"];if(t&&t.length>0&&Zt.addPlugin(lC()),Zt.addPlugin(uC()),Zt.addPlugin(fC()),Lo=CC(),Lo&&(Lo[iC]=Lo.parentElement,Lo.style.position="absolute",Lo.style.zIndex=Number.MAX_SAFE_INTEGER.toString()),Zt.setSwitchPosition(20,30),In=SC(),In){In.innerText=jv,In.addEventListener("click",rC);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 lC(){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 Fp="padding: 10px; font-family: monospace;",c_="margin-bottom: 10px;",Io="margin-bottom: 10px; margin-top: 15px;",cC="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;",hC=Fv,dC=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='${cC}'>`;t+="<tbody>";for(const i of s){const n=typeof i.value=="boolean"?i.value?"โ
":"โ":i.value;t+=`<tr><td style='${hC}'>${i.label}</td><td style='${dC}'>${n}</td></tr>`}return t+="</tbody></table>",t}function Uv(){try{if(document.createElement("canvas").getContext("webgl2"))return"โ
"}catch{}return"โ"}function uC(){if(!globalThis.VConsole)return;const s=new VConsole.VConsolePlugin("device-utilities","๐ฑ Device Info");return s.on("renderTab",function(e){let t=`<div style='${Fp}'>`;const i=xC();t+=`<h3 style='${c_}'>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='${Fp} margin-top: 20px;'>`,t+=`<h3 style='${c_}'>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 fC(){if(!globalThis.VConsole)return;const s=new VConsole.VConsolePlugin("graphics-info","๐จ Graphics Info");return s.on("renderTab",async function(e){let t=`<div style='${Fp}'>`;const i=pC();i.length>0&&(t+=`<h3 style='${Io}'>General GPU Info</h3>`,t+=En(i,!1));const n=gC();n.length>0&&(t+=`<h3 style='${Io}'>WebGL</h3>`,t+=En(n,!1));const o=yC();o.length>0&&(t+=`<h3 style='${Io}'>WebGL 2 Features</h3>`,t+=En(o,!1));const r=_C();r.length>0&&(t+=`<h3 style='${Io}'>WebGL Limits</h3>`,t+=En(r,!1));const a=bC();a.length>0&&(t+=`<h3 style='${Io}'>Texture Formats</h3>`,t+=En(a,!1));const l=await vC();if(l.length>0&&(t+=`<h3 style='${Io}'>WebGPU</h3>`,t+=En(l,!1)),exports.DeviceUtilities.isSafari()){const h=wC();h.length>0&&(t+=`<h3 style='${Io}'>Safari GPU Info</h3>`,t+=En(h,!1))}t+="</div>",e(t)}),s}function pC(){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=mC(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 mC(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 gC(){const s=[],e=zv();return e&&(s.push({label:"๐ WebGL Version",value:e.version}),s.push({label:"๐ฎ WebGL 2 Available",value:Uv()})),s}function yC(){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 _C(){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