@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.27 MB
JavaScript
import{createLoaders as km,getRaycastMesh as bb,LODsManager as _r,NEEDLE_progressive as $e,addDracoAndKTX2Loaders as QS,configureLoader as YS,setKTX2TranscoderLocation as ZS,setDracoDecoderLocation as KS}from"./gltf-progressive-CqZYu6Hx.min.js";import{Vector2 as K,Vector3 as b,Vector4 as ye,Quaternion as N,PlaneGeometry as wn,WebGLRenderer as vr,PerspectiveCamera as de,OrthographicCamera as Cd,Scene as Gi,Mesh as H,Texture as Se,Uniform$1 as qi,Color as oe,ShaderMaterial as $n,Box3 as zt,ShadowMaterial as _b,Euler as lt,MeshStandardMaterial as ft,Box3Helper as JS,GridHelper as vb,Object3D as M,Material as we,Matrix3 as wb,Matrix4 as J,Layers as ws,Ray as Po,MathUtils as Oo,AxesHelper as ki,MeshBasicMaterial as Ce,DoubleSide as Mi,BufferGeometry as xn,Group as ko,CylinderGeometry as xb,SphereGeometry as Pd,BoxGeometry as La,SpriteMaterial as eC,Sprite as tC,Shape as iC,ExtrudeGeometry as nC,Fog as Sb,DirectionalLight as Mm,PointLight as Em,TextureLoader as wr,EdgesGeometry as oC,LineSegments as Cb,LineBasicMaterial as Rm,Line as ja,BufferAttribute as yt,Raycaster as Od,Sphere as kd,ArrayCamera as sC,Plane as xr,SkinnedMesh as xs,InterleavedBufferAttribute as Pb,Skeleton as rC,Bone as aC,WebGLCubeRenderTarget as lC,CubeCamera as cC,AnimationClip as Ei,FileLoader as Tm,PropertyBinding as Da,KeyframeTrack as hC,CubeUVReflectionMapping as Mo,LinearSRGBColorSpace as Eo,ShaderChunk as Kt,DataTexture as Am,RGBAFormat as Md,EquirectangularReflectionMapping as Ro,SRGBColorSpace as To,Clock as dC,NeutralToneMapping as Ba,AgXToneMapping as Ed,ACESFilmicToneMapping as Rd,NoToneMapping as Td,PCFSoftShadowMap$1 as uC,BasicNodeLibrary as pC,WebGLRenderTarget as Hn,DepthTexture as Ob,NearestFilter as Ad,LoopRepeat as mC,LoopOnce as Im,AnimationMixer as Lm,CompressedTexture as gC,FrontSide as Ss,Camera as fC,Frustum as kb,AudioListener as yC,PositionalAudio as bC,AudioLoader as jm,EventDispatcher as Dm,BackSide as Id,MeshDepthMaterial as _C,CustomBlending as vC,MaxEquation as wC,AlwaysStencilFunc as xC,GreaterEqualStencilFunc as SC,NotEqualStencilFunc as CC,GreaterStencilFunc as PC,LessEqualStencilFunc as OC,EqualStencilFunc as kC,LessStencilFunc as MC,NeverStencilFunc as Mb,InvertStencilOp as EC,DecrementWrapStencilOp as RC,IncrementWrapStencilOp as TC,DecrementStencilOp as AC,IncrementStencilOp as IC,ReplaceStencilOp as LC,ZeroStencilOp as jC,KeepStencilOp as DC,EquirectangularRefractionMapping as Eb,CubeTexture as Rb,AmbientLight as BC,HemisphereLight as FC,Loader as UC,RawShaderMaterial as Tb,GLSL3 as zC,AlwaysDepth as NC,GreaterEqualDepth as WC,GreaterDepth as VC,LessEqualDepth as $C,LessDepth as HC,NotEqualDepth as GC,EqualDepth as qC,BatchedMesh as Ab,LinearFilter as Ld,UnsignedByteType as XC,MeshPhysicalMaterial as Ib,RingGeometry as QC,Line3 as YC,AdditiveBlending as Lb,BoxHelper as ZC,SpotLight as KC,DirectionalLightHelper as JC,CameraHelper as eP,LOD as tP,Triangle as iP,NormalBlending as nP,ReinhardToneMapping as Bm,LinearToneMapping as Fm,HalfFloatType as Um,VideoTexture as oP,CompressedCubeTexture as sP,CatmullRomCurve3 as rP,VectorKeyframeTrack as aP,QuaternionKeyframeTrack as lP,Audio as cP,ShaderLib as jd,UniformsUtils as jb,MirroredRepeatWrapping as Db,MeshNormalMaterial as hP,AudioContext as dP,PMREMGenerator$1 as uP}from"./three.min.js";import{GroundedSkybox as Fa,Font as pP,TextGeometry as mP,FontLoader as gP,GLTFLoader as Ao,TransformControlsGizmo as Bb,EXRLoader as zm,RGBELoader as Fb,Stats as fP,nodeFrame as Ub,OrbitControls as yP,PositionalAudioHelper as bP,HorizontalBlurShader as _P,VerticalBlurShader as vP,GLTFExporter as zb,strToU8 as Nb,zipSync as wP,XRControllerModelFactory as xP,XRHandMeshModel as SP,Line2 as CP,LineGeometry as PP,LineMaterial as OP,TransformControls as kP,InteractiveGroup as MP,HTMLMesh as EP,VertexNormalsHelper as RP,OBJLoader as Nm,FBXLoader as Wb,mergeVertices as TP}from"./three-examples.min.js";import{fetchProfile as AP,MotionController as IP,$70d766613f57b014$export$2e2bcd8739ae039 as Vb,ByteBuffer as LP,v5 as $b,md5 as Hb,SIZE_PREFIX_LENGTH as Gb,Builder as Wm,createNoise4D as jP,Matrix4 as Vm,BatchedParticleRenderer as DP,ParticleSystem as BP,RenderMode as Io,ConstantColor as FP,Vector4 as UP,ConstantValue as zP,TrailParticle as qb,WorkerBase as NP,MeshBVH as WP}from"./vendor-BPp9F5vR.min.js";import{__webpack_exports__default as Pe,__webpack_exports__Text as Xb,__webpack_exports__Block as Qb,__webpack_exports__update as VP,SimpleStateBehavior as $P,__webpack_exports__Inline as $m,__webpack_exports__FontLibrary as Yb,ThreeMeshUI as Zb}from"./three-mesh-ui-n3JU4M2W.min.js";import{EffectAttribute as HP}from"./postprocessing-CaEfRjRY.min.js";const Hm=new Map;function Ri(o=globalThis.location?.hostname){if(Hm.has(o))return Hm.get(o);const e=/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})|localhost/.test(o);return Hm.set(o,e),e===!0}function Kb(){return window.location.hostname.includes("glitch.me")}const Jb=typeof window!==void 0?window.location.search.includes("debugcontext"):!1;var ue=(o=>(o.ContextRegistered="ContextRegistered",o.ContextCreationStart="ContextCreationStart",o.ContextCreated="ContextCreated",o.ContextFirstFrameRendered="ContextFirstFrameRendered",o.ContextDestroying="ContextDestroying",o.ContextDestroyed="ContextDestroyed",o.MissingCamera="MissingCamera",o.ContextClearing="ContextClearing",o.ContextCleared="ContextCleared",o))(ue||{});class pe{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&&(Jb&&console.warn("Registering context"),this.Registered.push(e),this.dispatchCallback("ContextRegistered",e))}static unregister(e){const t=this.Registered.indexOf(e);t!==-1&&(Jb&&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 s=new Array;return this._callbacks[e].forEach(r=>{const a=r(n);a instanceof Promise&&s.push(a)}),Promise.all(s)}static addContextCreatedCallback(e){this.registerCallback("ContextCreated",e)}static addContextDestroyedCallback(e){this.registerCallback("ContextDestroyed",e)}}const e_=()=>o=>o;function GP(o){return e_()(o)}function qP(){return!!w("debug")}class Ti{_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 Sr=!1;const Gm=new Array;typeof window<"u"&&setTimeout(()=>{if(Sr){const o={},e=new URL(window.location.href),t=new URL(e);t.searchParams.append("console","");const i=t.toString().replace(/=$|=(?=&)/g,"");for(const s of Gm){const r=new URL(e);r.searchParams.append(s,""),o[s]=r.toString().replace(/=$|=(?=&)/g,"")}console.log(`\u{1F335} ?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=Sr===!0?"":` (containing "${Sr}")`;console.group("Available URL parameters:"+n);for(const s of Object.keys(o).sort())typeof Sr=="string"&&!s.toLowerCase().includes(Sr.toLowerCase())||(console.groupCollapsed(s),console.log("Reload with this flag enabled:"),console.log(o[s]),console.groupEnd());console.groupEnd()}},100);function uc(){return new URLSearchParams(globalThis.location?.search)}function w(o){Sr&&!Gm.includes(o)&&Gm.push(o);const e=uc();if(e.has(o)){const t=e.get(o);if(t){const i=Number(t);return isNaN(i)?t:i}else return!0}return!1}Sr=w("help");function XP(o,e){const t=uc();t.has(o)?t.set(o,e):t.append(o,e),document.location.search=t.toString()}function pc(o,e,t=!0){const i=uc();i.has(o)?e===null?i.delete(o):i.set(o,e):e!==null&&i.append(o,e),t?t_(o,i):Xm(o,i)}function qm(o,e,t){o.has(e)?o.set(e,t.toString()):o.append(e,t.toString())}function t_(o,e,t){window.history.pushState(t,o,"?"+e.toString())}function Xm(o,e,t){window.history.replaceState(t,o,"?"+e.toString())}function QP(o){for(var e="",t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",i=t.length,n=0;n<o;n++)e+=t.charAt(Math.floor(Math.random()*i));return e}function YP(o,e){return Math.floor(Math.random()*(e-o+1))+o}const i_=["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"],n_=["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 o_(){const o=i_[Math.floor(Math.random()*i_.length)],e=n_[Math.floor(Math.random()*n_.length)];return o+"_"+e}function s_(o){return o=o.replace(/[^a-z0-9áéíóúñü \.,_-]/gim,""),o.trim()}function Ua(o,e,t=!0,i=!1){if(e==null)return null;if(e.userData&&e.userData.guid===o||e.guid==o)return e;if(i&&e.userData?.components){for(const n of e.userData.components)if(n.guid===o)return n}if(t){if(e.scenes)for(const n in e.scenes){const s=e.scenes[n],r=Ua(o,s,t,i);if(r)return r}if(e.children)for(const n in e.children){const s=e.children[n],r=Ua(o,s,t,i);if(r)return r}}}function mc(o,e){if(o!=null&&typeof o=="object"){let t;Array.isArray(o)?t=[]:(t=Object.create(o),Object.assign(t,o));for(const i of Object.keys(o)){const n=o[i];e&&!e(o,i,n)?t[i]=n:n?.clone!==void 0&&typeof n.clone=="function"?t[i]=n.clone():t[i]=mc(n,e)}return t}return o}function Lo(o){return new Promise((e,t)=>{setTimeout(e,o)})}function gc(o,e){if(o<=0)return Promise.resolve();if(e||(e=pe.Current),!e)return Promise.reject("No context");const t=e.time.frameCount+o;return new Promise((i,n)=>{if(!e)return n("No context");const s=()=>{e.time.frameCount>=t&&(e.pre_update_callbacks.splice(e.pre_update_callbacks.indexOf(s),1),i())};e.pre_update_callbacks.push(s)})}const Dd=w("debugresolveurl"),r_="rel:";function ZP(o,e){return jo(o,e)}function jo(o,e){if(e===void 0)return Dd&&console.warn("getPath: uri is undefined, returning uri",e),e;if(e.startsWith("./"))return e;if(e.startsWith("http"))return Dd&&console.warn("getPath: uri is absolute, returning uri",e),e;if(o===void 0)return Dd&&console.warn("getPath: source is undefined, returning uri",e),e;e.startsWith(r_)&&(e=e.substring(4));const t=o.lastIndexOf("/");if(t>=0){const i=o.substring(0,t+1);for(;i.endsWith("/")&&e.startsWith("/");)e=e.substring(1);const n=i+e;return Dd&&console.log("source:",o,`changed uri
from`,e,`
to `,n,`
basePath: `+i),n}return e}function a_(o){if(o)return o=o.trim(),o=o.split("?")[0]?.split("#")[0],o}class KP{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:n=>{e[this._wrapperProp]=n;for(const s of this.writeCallbacks)s(n,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 gs{_watches=[];constructor(e,t){if(Array.isArray(t))for(const i of t)this._watches.push(new gs(e,i));else this._watches.push(new KP(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 za=Symbol("needle:watches");function Bd(o,e){if(!o[za])if(o instanceof K)o[za]=new gs(o,["x","y"]);else if(o instanceof b)o[za]=new gs(o,["x","y","z"]);else if(o instanceof ye||o instanceof N)o[za]=new gs(o,["x","y","z","w"]);else return!1;return o[za].subscribeWrite(e),!0}function Qm(o,e){if(!o)return;const t=o[za];t&&t.unsubscribeWrite(e)}var I;(o=>{let e;function t(){if(e!==void 0)return e;const te=window.navigator.userAgent,Ve=/Windows|MacOS|Mac OS/.test(te),hi=/Windows NT/.test(te)&&/Edg/.test(te)&&!/Win64/.test(te);return e=Ve&&!hi&&!k()}o.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)}o.isMobileDevice=n;function s(){return a()}o.isIPad=s;let r;function a(){if(r!==void 0)return r;const te=navigator.userAgent.toLowerCase();return r=/iPad/.test(navigator.userAgent)||te.includes("macintosh")&&"ontouchend"in document}o.isiPad=a;let l;function c(){return l!==void 0?l:l=/Android/.test(navigator.userAgent)}o.isAndroidDevice=c;let h;function d(){return h!==void 0?h:h=/WebXRViewer\//i.test(navigator.userAgent)}o.isMozillaXR=d;let p;function m(){return p!==void 0?p:p=/NeedleAppClip\//i.test(navigator.userAgent)}o.isNeedleAppClip=m;let f;function g(){if(f!==void 0)return f;if(k()||a())return f=!1;const te=navigator.userAgent.toLowerCase();return navigator.userAgentData?f=navigator.userAgentData.platform==="macOS":f=te.includes("mac os x")||te.includes("macintosh")}o.isMacOS=g;let y;function _(){return y!==void 0?y:y=a()&&"xr"in navigator&&G()}o.isVisionOS=_;let v;const P=["iPad Simulator","iPhone Simulator","iPod Simulator","iPad","iPhone","iPod"];function k(){return v!==void 0?v:v=P.includes(navigator.platform)||navigator.userAgent.includes("Mac")&&"ontouchend"in document}o.isiOS=k;let O;function D(){return O!==void 0||(O=/^((?!chrome|android).)*safari/i.test(navigator.userAgent)),O}o.isSafari=D;let L;function V(){return L!==void 0?L:L=navigator.userAgent.includes("OculusBrowser")}o.isQuest=V;let W;function G(){return W!==void 0||(W=document.createElement("a").relList.supports("ar")),W}o.supportsQuickLookAR=G;async function X(){try{return(await navigator.permissions.query({name:"microphone"})).state!=="denied"}catch(te){return console.error("Error querying `microphone` permissions.",te),!1}}o.microphonePermissionsGranted=X;let R;function $(){if(R!==void 0)return R;const te=navigator.userAgent.match(/iPhone OS (\d+_\d+)/);if(te&&(R=te[1].replace("_",".")),!R){const Ve=navigator.userAgent.match(/(?:\(Macintosh;|iPhone;|iPad;).*Version\/(\d+\.\d+)/);Ve&&(R=Ve[1])}return R||(R=null),R}o.getiOSVersion=$;let q;function he(){if(q!==void 0)return q;const te=navigator.userAgent.match(/(?:CriOS|Chrome)\/(\d+\.\d+\.\d+\.\d+)/);return te?q=te[1].replace("_","."):q=null,q}o.getChromeVersion=he;let re;function ge(){if(re!==void 0)return re;const te=navigator.userAgent.match(/Version\/(\d+\.\d+)/);return te&&D()?re=te[1]:re=null,re}o.getSafariVersion=ge})(I||(I={}));function JP(){return I.isDesktop()}function eO(){return I.isMobileDevice()}function tO(){return I.isiPad()}function iO(){return I.isiPad()}function nO(){return I.isAndroidDevice()}function oO(){return I.isMozillaXR()}function sO(){return I.isMacOS()}function rO(){return I.isiOS()}function aO(){return I.isSafari()}function lO(){return I.isQuest()}async function cO(){return I.microphonePermissionsGranted()}const Cs=new WeakMap;function Ym(o,e,t){if(!Cs.get(o)){const n=new MutationObserver(s=>{hO(o,s)});Cs.set(o,{observer:n,attributeChangedListeners:new Map}),n.observe(o,{attributes:!0})}const i=Cs.get(o).attributeChangedListeners;return i.has(e)||i.set(e,[]),i.get(e).push(t),()=>{Zm(o,e,t)}}function Zm(o,e,t){if(!Cs.get(o))return;const i=Cs.get(o).attributeChangedListeners;if(!i.has(e))return;const n=i.get(e),s=n.indexOf(t);s!==-1&&(n.splice(s,1),n.length<=0&&(i.delete(e),Cs.get(o)?.observer.disconnect(),Cs.delete(o)))}function hO(o,e){const t=Cs.get(o).attributeChangedListeners;for(const i of e)if(i.type==="attributes"){const n=i.attributeName,s=o.getAttribute(n);if(t.has(n))for(const r of t.get(n))r(s)}}class Km{reason;constructor(e){this.reason=e}}async function Jm(o){const e=await Promise.allSettled(o).catch(n=>[new Km(n.message)]);let t=!1;const i=e.map(n=>"value"in n?n.value:(t=!0,new Km(n.reason)));return{anyFailed:t,results:i}}const dO=w("debugdebug");let eg=!1;(w("noerrors")||w("nooverlaymessages"))&&(eg=!0);const tg="needle_engine_global_error_container";var Ai=(o=>(o[o.Log=0]="Log",o[o.Warn=1]="Warn",o[o.Error=2]="Error",o))(Ai||{});function l_(){return d_}const ig=new Array;function uO(o){ig.push(o)}let ng=!1;function pO(...o){if(!ng){ng=!0;try{for(let e=0;e<ig.length;e++)ig[e](...o)}catch(e){console.error(e)}ng=!1}}const c_=console.error,mO=function(...o){c_.apply(console,o),yO(o),Cr(2,o,{}),fO(...o)};function h_(o){eg=!o,o?console.error=mO:console.error=c_}function gO(o){return h_(o)}let d_=0;function fO(...o){d_+=1,pO(...o)}function yO(o){if(Array.isArray(o))for(let e=0;e<o.length;e++){const t=o[e];typeof t=="string"&&t.startsWith("THREE.PropertyBinding: Trying to update node for track:")&&(o[e]="Some animated objects couldn't be found: see console for details")}}const u_=new Set;function Cr(o,e,t={},i,n){if(eg)return;if(t.once===!0){let a="";if(Array.isArray(e))for(let l=0;l<e.length;l++){let c=e[l];c instanceof Error&&(c=c.message),typeof c!="object"&&(l>0&&(a+=" "),a+=c)}else typeof e=="string"&&(a=e);if(u_.has(a))return;u_.add(a)}const s=pe.Current;let r=s?.domElement??document.querySelector("needle-engine");if(s?.isInAR&&(r=s.arOverlayElement),!!r){if(Array.isArray(e)){let a="";for(let l=0;l<e.length;l++){let c=e[l];c instanceof Error&&(c=c.message),typeof c!="object"&&(l>0&&(a+=" "),a+=c)}e=a}!e||e.length<=0||bO(o,r,e,t)}}const Na=new Map,p_=.2;function bO(o,e,t,i={}){if(t==null)return;const n=wO(e);if(n.childElementCount>=20){const c=n.lastElementChild;g_(c)}t.length>400&&(t=t.substring(0,400)+"...");const s=i.key??t;if(Na.has(s)){Na.get(s)?.update(t,i);return}const r=xO(o,t);n.prepend(r);const a=()=>{Na.delete(s),g_(r)};let l=setTimeout(a,Math.max(p_,i.duration??10)*1e3);Na.set(s,{update:(c,h)=>{c.length>400&&(c=c.substring(0,400)+"..."),r.innerHTML=c,h.duration&&(clearTimeout(l),l=setTimeout(a,Math.max(p_,h.duration)*1e3))},removeFunction:a})}function _O(){dO&&console.log("Clearing messages");for(const o of Na.values())o?.removeFunction.call(o);Na.clear()}const vO=`
@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 wO(o){globalThis[tg]||(globalThis[tg]=new Map);const e=globalThis[tg];if(e.has(o))return e.get(o);{const t=document.createElement("div");e.set(o,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;
`,I.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"),o.shadowRoot?o.shadowRoot.appendChild(t):o.appendChild(t);const n=document.createElement("style");return n.innerHTML=vO,t.appendChild(n),t}}const m_=Symbol("logtype"),Fd=new Map;function g_(o){o.remove();const e=o[m_],t=Fd.get(e)??[];t.push(o),Fd.set(e,t)}function xO(o,e){if(Fd.has(o)){const i=Fd.get(o);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[m_]=o,o){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 SO{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,s){return n+(s-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 CO){const s=e[n],r=t[n];if(s===void 0||r===void 0)break;if(Math.abs(s-r)>i)return!1}return!0}easeInOutCubic(e){return e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2}}const CO=["x","y","z","w"],j=new SO;class f_{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 Ud{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 f_(this.alpha(this.minCutOff)),this.dx=new f_(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,s=this.dx.filter(n,this.alpha(this.dCutOff)),r=this.minCutOff+this.beta*Math.abs(s);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 og{x;y;z;constructor(e,t=1,i=0,n=1){this.x=new Ud(e,t,i,n),this.y=new Ud(e,t,i,n),this.z=new Ud(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 zd="needle:cameraController";function y_(o){return o[zd]}function sg(o,e,t){t?o[zd]=e:o[zd]===e&&(o[zd]=null)}const rg="needle:autofit";function b_(o){return o[rg]===void 0?!0:o[rg]!==!1}function Nd(o,e){o[rg]=e}let Sn;const PO={x:0,y:0,width:0,height:0},OO=w("debugfocusrect");function kO(o,e,t,i,n){o instanceof Element&&(OO&&o instanceof HTMLElement&&(o.style.outline="2px dashed rgba(255, 150, 0, .8)"),o=o.getBoundingClientRect()),Sn=n.domElement.getBoundingClientRect();const s=PO;s.x=o.x,s.y=o.y,s.width=o.width,s.height=o.height,s.x-=Sn.x,s.y-=Sn.y;const r=Sn.width,a=Sn.height,l=i.view,c=e.zoom;let h=l?.offsetX||0,d=l?.offsetY||0,p=Sn.width,m=Sn.height;p/=c,m/=c,h=p*(c-1)*.5,d=m*(c-1)*.5;const f=s.x+s.width*.5,g=s.y+s.height*.5,y=Sn.width*.5,_=Sn.height*.5,v=f-y,P=g-_;h-=v/c,d-=P/c,e.offsetX!==void 0&&(h+=e.offsetX*(Sn.width*.5)),e.offsetY!==void 0&&(d-=e.offsetY*(Sn.height*.5));const k=l?.offsetX||h,O=l?.offsetY||d;h=j.lerp(k,h,t),d=j.lerp(O,d,t);const D=l?.width||r,L=l?.height||a;p=j.lerp(D,p,t),m=j.lerp(L,m,t),i.setViewOffset(r,a,h,d,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 MO(o,e,t){const i=o.length(),n=e.length(),s=j.lerp(i,n,t);return o.lerp(e,t).normalize().multiplyScalar(s)}const ag=new N,__=new N().setFromAxisAngle(new b(0,1,0),Math.PI);function EO(o,e){o.lookAt(e),o.quaternion.multiply(__)}function fc(o,e,t=!0,i=!1){if(o===e)return;ag.copy(o.quaternion);const n=ee(e),s=ee(o);if(i){if(Cn(o,_e(e)),t){const r=s.y,a=s.sub(C_(o));a.y=r,o.lookAt(a),o.quaternion.multiply(__)}Number.isNaN(o.quaternion.x)&&o.quaternion.copy(ag);return}t&&(n.y=s.y),o.lookAt(n),Number.isNaN(o.quaternion.x)&&o.quaternion.copy(ag)}function RO(o,e,t,i=1){if(t){const n=F(0,0,0),s=e.x/window.innerWidth*2-1,r=-(e.y/window.innerHeight)*2+1;n.set(s,r,0),n.unproject(t);const a=t.worldPosition,l=o.worldPosition.distanceTo(a),c=n.sub(a);c.multiplyScalar(i*3.6*l);const h=t.worldPosition.add(c);return o.lookAt(h),h}return null}const TO=new Ti(()=>new b,100);function F(o,e,t){const i=TO.get();return i.set(0,0,0),o instanceof b?i.copy(o):Array.isArray(o)?i.set(o[0],o[1],o[2]):o instanceof DOMPointReadOnly?i.set(o.x,o.y,o.z):typeof o=="number"?(i.x=o,i.y=e!==void 0?e:i.x,i.z=t!==void 0?t:i.x):typeof o=="object"&&(i.x=o.x,i.y=o.y,i.z=o.z),i}const AO=new Ti(()=>new oe,30);function v_(o){const e=AO.get();return o?e.copy(o):e.set(0,0,0),e}const IO=new Ti(()=>new N,100);function di(o,e,t,i){const n=IO.get();return n.identity(),o instanceof N?n.copy(o):o instanceof DOMPointReadOnly?n.set(o.x,o.y,o.z,o.w):typeof o=="number"&&e!==void 0&&t!==void 0&&i!==void 0?n.set(o,e,t,i):typeof o=="object"&&"x"in o&&"y"in o&&"z"in o&&"w"in o&&n.set(o.x,o.y,o.z,o.w),n}const lg=new Ti(()=>new b,100),w_=Symbol("lastMatrixWorldUpdateKey");function ee(o,e=null,t=!0){const i=e??lg.get();return o?o.parent?(t&&o.updateWorldMatrix(!0,!1),o.matrixWorldNeedsUpdate&&o[w_]!==Date.now()&&(o[w_]=Date.now(),o.updateMatrixWorld()),i.setFromMatrixPosition(o.matrixWorld),i):i.copy(o.position):i.set(0,0,0)}function bt(o,e){if(!o)return o;const t=lg.get();return e!==t&&t.copy(e),o.parent!==null&&o.parent.worldToLocal(t),o.position.set(t.x,t.y,t.z),o}function Pr(o,e,t,i){const n=lg.get();return n.set(e,t,i),bt(o,n),o}const Wd=new Ti(()=>new N,100),Or=new N,cg=new N;function _e(o,e=null){if(!o)return Wd.get().identity();const t=e??Wd.get();return o.parent?(o.getWorldQuaternion(t),t):t.copy(o.quaternion)}function Cn(o,e){if(!o)return;e!==Or&&Or.copy(e);const t=Or;o?.parent?.getWorldQuaternion(cg),cg.invert();const i=cg.multiply(t);o.quaternion.set(i.x,i.y,i.z,i.w)}function hg(o,e,t,i,n){Or.set(e,t,i,n),Cn(o,Or)}const LO=new Ti(()=>new b,100),jO=new b;function He(o,e=null){return e||(e=LO.get()),o?o.parent?(o.getWorldScale(e),e):e.copy(o.scale):e.set(0,0,0)}function Wa(o,e){if(!o)return;if(!o.parent){o.scale.copy(e);return}const t=jO;o.parent.getWorldScale(t),o.scale.copy(e),o.scale.divide(t)}const DO=new b,x_=new N;function BO(o){return _e(o,x_),DO.set(0,0,1).applyQuaternion(x_)}const FO=new Ti(()=>new b,100),S_=new N;function C_(o,e){return e||(e=FO.get().set(0,0,1)),_e(o,S_),e.applyQuaternion(S_)}const P_=new lt,O_=new lt,UO=new b;function dg(o){const e=Wd.get();return o.getWorldQuaternion(e),O_.setFromQuaternion(e),O_}function ug(o,e){const t=Wd.get();Cn(o,t.setFromEuler(e))}function Vd(o){const e=dg(o),t=UO;return t.set(e.x,e.y,e.z),t.x=j.toDegrees(t.x),t.y=j.toDegrees(t.y),t.z=j.toDegrees(t.z),t}function k_(o,e){yc(o,e.x,e.y,e.z,!0)}function yc(o,e,t,i,n=!0){n&&(e=j.toRadians(e),t=j.toRadians(t),i=j.toRadians(i)),P_.set(e,t,i),Or.setFromEuler(P_),Cn(o,Or)}function $d(o,e=!0){o&&(e?function t(i){console.groupCollapsed((i.name?i.name:"(no name : "+i.type+")")+" %o",i),i.children.forEach(t),console.groupEnd()}(o):o.traverse(function(t){for(var i="|___",n=t;n.parent!==null;)i=" "+i,n=n.parent;console.log(i+t.name+" <"+t.type+">")}))}function zO(o){let e=o?.name||"";if(!o)return e;let t=o.parent;for(;t;)e=t.name+"/"+e,t=t.parent;return e}function M_(o){if(o){const e=o;return e.blendMode!==void 0&&e.clampWhenFinished!==void 0&&e.enabled!==void 0&&e.fadeIn!==void 0&&e.getClip!==void 0}return!1}class wm extends $n{static vertex=`
varying vec2 vUv;
void main(){
vUv = uv;
gl_Position = vec4(position.xy, 0., 1.0);
}`;constructor(){super({vertexShader:wm.vertex,uniforms:{map:new qi(null),flipY:new qi(!0),writeDepth:new qi(!1),depthTexture:new qi(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 gr{static planeGeometry=new wn(2,2,1,1);static renderer=new vr({antialias:!1,alpha:!0});static perspectiveCam=new de;static orthographicCam=new Cd;static scene=new Gi;static blitMaterial=new wm;static mesh=new H(gr.planeGeometry,gr.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=wm.vertex;const s=this.mesh;s.material=i,s.frustumCulled=!1,this.scene.children.length=0,this.scene.add(s),this.renderer.setSize(e.image.width,e.image.height),this.renderer.clear(),this.renderer.render(this.scene,this.perspectiveCam);const r=new Se(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:s=this.blitMaterial,flipY:r=!1,depthTexture:a=null,depthTest:l=!0,depthWrite:c=!0}=i||{};this.blitMaterial.reset(),s.uniforms.map&&(s.uniforms.map.value=e),s.uniforms.flipY&&(s.uniforms.flipY.value=r),a?(s.uniforms.writeDepth=new qi(!0),s.uniforms.depthTexture.value=a):(s.uniforms.writeDepth=new qi(!1),s.uniforms.depthTexture.value=null),s.needsUpdate=!0,s.uniformsNeedUpdate=!0;const h=this.mesh;h.material=s,h.frustumCulled=!1,this.scene.children.length=0,this.scene.add(h);const d=n.getRenderTarget(),p=n.getContext();l?p.enable(p.DEPTH_TEST):p.disable(p.DEPTH_TEST),n.state.buffers.depth.setMask(c),n.setClearColor(new oe(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(d),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=E_(e));const i=e.image;if(WO(i)){const n=document.createElement("canvas");n.width=i.width,n.height=i.height;const s=n.getContext("2d");return s?(s.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 E_(o){return gr.copyTexture(o)}function NO(o,e=!1){return gr.textureToCanvas(o,e)}function WO(o){return typeof HTMLImageElement<"u"&&o instanceof HTMLImageElement||typeof HTMLCanvasElement<"u"&&o instanceof HTMLCanvasElement||typeof OffscreenCanvas<"u"&&o instanceof OffscreenCanvas||typeof ImageBitmap<"u"&&o instanceof ImageBitmap}function VO(o){const e=o.type;return e==="Mesh"||e==="SkinnedMesh"}function pg(o,e){e?o["needle:rendercustomshadow"]=!0:o["needle:rendercustomshadow"]=!1}function R_(o){return!!(o&&(o["needle:rendercustomshadow"]===!0||o["needle:rendercustomshadow"]==null))}function ui(o,e=void 0,t=void 0,i=void 0){const n=i||new zt;n.makeEmpty();const s=[];function r(l){let c=!0;if(l.visible&&b_(l)!==!1&&!(l.type==="TransformControlsGizmo"||l.type==="TransformControlsPlane")){if(l instanceof JS&&(c=!1),l instanceof vb&&(c=!1),l instanceof Fa&&(c=!1),l.isGizmo===!0&&(c=!1),l.material instanceof _b&&(c=!1),VO(l)||(c=!1),t&&l.layers.test(t)===!1&&(c=!1),c&&(e&&Array.isArray(e)&&e?.includes(l)||typeof e=="function"&&e(l)===!0))return;if(l.isUI!==!0){if(c){const h=l.children;l.children=s;const d=l.position,p=l.scale;if(Number.isNaN(d.x)||Number.isNaN(d.y)||Number.isNaN(d.z)){console.warn(`Object "${l.name}" has NaN values in position or scale.... will ignore it`,d,p);return}l.geometry===null&&(l.geometry=void 0),n.expandByObject(l,!0),l.children=h}for(const h of l.children)r(h)}}}let a=!1;Array.isArray(o)||(o=[o]);for(const l of o)l&&(a=!0,l.updateMatrixWorld(),r(l));return a||console.warn("No objects to fit camera to..."),n}function T_(o,e,t){const i=ui([o],t?.ignore),n=new b;i.getSize(n);const s=new b;i.getCenter(s);const r=new b;e.getSize(r);const a=new b;e.getCenter(a);const l=new b;l.set(r.x/n.x,r.y/n.y,r.z/n.z);const c=Math.min(l.x,l.y,l.z),h=t?.scale!==!1;if(h&&Wa(o,He(o).multiplyScalar(c)),t?.position!==!1){const d=new b;i.getCenter(d),d.y=i.min.y;const p=new b;e.getCenter(p),p.y=e.min.y;const m=p.clone().sub(d);h&&m.multiplyScalar(c),bt(o,ee(o).add(m))}return{boundsBefore:i,scale:l}}function A_(o,e){const t=ui([o]),i=new b;t.getCenter(i),i.y=t.min.y;const n=e.clone().sub(i),s=ee(o);return bt(o,s.add(n)),{offset:n,bounds:t}}function mg(o,e,t,i){if(Array.isArray(e)){let r=!0;for(let a=0;a<e.length;a++)mg(o,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 ft;n["material:fbx"]=e;const s=e;return s&&(s.map?n.color.set(1,1,1):n.color.copyLinearToSRGB(s.color),n.emissive.copyLinearToSRGB(s.emissive),n.emissiveIntensity=s.emissiveIntensity,n.opacity=s.opacity,n.displacementScale=s.displacementScale,n.transparent=s.transparent,n.bumpMap=s.bumpMap,n.aoMap=s.aoMap,n.map=s.map,n.displacementMap=s.displacementMap,n.emissiveMap=s.emissiveMap,n.normalMap=s.normalMap,n.envMap=s.envMap,n.alphaMap=s.alphaMap,n.metalness=s.reflectivity,n.vertexColors=s.vertexColors,s.shininess&&(n.roughness=1-Math.sqrt(s.shininess)/10),n.needsUpdate=!0),t===void 0?o.material=n:i[t]=n,!0}let Hd=!1;uO((...o)=>{A()&&pe.Current?.isInXR&&(Va(!0),I_("error",...o))});function Va(o){if(o){if(Hd)return;Hd=!0,HO()}else{if(!Hd)return;Hd=!1,GO()}}const bc={log:void 0,warn:void 0,error:void 0};class $O{familyName="needle-xr";root=null;context=null;defaultFontSize=.06;constructor(){this.ensureFont()}onEnable(){this.context=pe.Current||pe.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 M;userForwardViewPoint=new b;oneEuroFilter=new og(90,.8);_lastElementRemoveTime=0;onBeforeRender=()=>{const e=this.context?.mainCamera;if(this.context&&e instanceof de){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,s=e.worldForward;s.y=0,s.normalize().multiplyScalar(n),this.userForwardViewPoint.copy(e.worldPosition).sub(s),this.targetObject.position.distanceTo(this.userForwardViewPoint)>2*i&&(this.targetObject.position.copy(this.userForwardViewPoint),fc(this.targetObject,e,!0,!0),this.targetObject.rotateY(Math.PI)),this.oneEuroFilter.filter(this.targetObject.position,t.position,this.context.time.time);const r=this.context.time.deltaTime;if(t.quaternion.slerp(this.targetObject.quaternion,r*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 a=Date.now();for(let l=0;l<this._activeTexts.length;l++){const c=this._activeTexts[l];if(c instanceof Pe.Text&&a-c._activatedTime>2e4){c.removeFromParent(),this._textBuffer.push(c),this._activeTexts.splice(l,1);break}}}}};addLog(e,t){const i=this.getRoot(),n=this.getText();let s=16777215,r=0;switch(e){case"log":s=16777215,r=0;break;case"warn":s=16772761,r=4465152;break;case"error":s=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:s,color:r}),Pe.update()}ensureFont(){let e=Pe.FontLibrary.getFontFamily(this.familyName);e||(e=Pe.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",()=>{Pe.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 Pe.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 s=e.children[n];s instanceof M&&this.disableDepthTestRecursive(s,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&&Pe.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 Pe.Block(t),this.root}}let kr=null;function HO(){kr||(kr=new $O),kr.onEnable();for(const o in bc){bc[o]=console[o];let e=!1;console[o]=function(){if(bc[o]?.apply(console,arguments),!e)try{e=!0,I_(o,...arguments)}finally{e=!1}}}}function GO(){kr?.onDisable();for(const o in bc)console[o]=bc[o]}const _c=new Map;function I_(o,...e){try{switch(_c.clear(),o){case"log":kr?.addLog("log",t());break;case"warn":kr?.addLog("warn",t());break;case"error":kr?.addLog("error",t());break}}catch(s){console.error("Error in spatial console",s)}finally{_c.clear()}function t(){let s="";for(let r=0;r<e.length;r++){const a=e[r];s+=i(a),r<e.length-1&&(s+=", ")}return s}function i(s,r=0){if(typeof s=="string")return'"'+s+'"';if(typeof s=="number"){if(s%1!==0){const a=s.toFixed(5),l=a.indexOf(".");let c=a.length-1;for(;c>l&&a[c]==="0";)c--;return a.substring(0,c+1)}return s.toString()}else if(Array.isArray(s)){let a="[";for(let l=0;l<s.length;l++){const c=s[l];a+=i(c,r+1),l<s.length-1&&(a+=", ")}return a+="]",a}else{if(s===null)return"null";if(s===void 0)return"undefined";if(typeof s=="function")return s.name+"()"}if(s instanceof K)return`(${i(s.x)}, ${i(s.y)})`;if(s instanceof b)return`(${i(s.x)}, ${i(s.y)}, ${i(s.z)})`;if(s instanceof ye)return`(${i(s.x)}, ${i(s.y)}, ${i(s.z)}, ${i(s.w)})`;if(s instanceof N)return`(${i(s.x)}, ${i(s.y)}, ${i(s.z)}, ${i(s.w)})`;if(s instanceof we||s instanceof Se)return s.name;if(s instanceof wb)return`[${s.elements.join(", ")}]`;if(s instanceof J)return`[${s.elements.join(", ")}]`;if(s instanceof ws)return s.mask.toString();if(typeof s=="object"){if(_c.has(s))return"*";let a=`{
`;a+=n(r);const l=Object.keys(s);let c="";for(let h=0;h<l.length;h++){const d=l[h],p=s[d];if(_c.has(p)){c+="";continue}_c.set(p,!0),c+=d+":"+i(p,r+1),h<l.length-1&&(c+=", "),c.length>=60&&(c+=`
`,c+=n(r),a+=c,c="")}return a+=c,a+=`
}`,a}return s}function n(s){let r="";for(let a=0;a<s;a++)r+=" ";return r}}const qO=w("nodevlogs");function ke(o,e){Cr(e?.type??Ai.Log,o,e)}function be(o,e){ke(o,{...e,type:Ai.Warn})}function vc(o,e){ke(o,{...e,type:Ai.Error})}let gg,fg;function A(){if(qO)return!1;if(gg!==void 0)return gg;if(fg!==void 0)return fg;let o=Ri();return o||(o=window.location.hostname.endsWith(".local-credentialless.webcontainer.io")),fg=o,o}function XO(o){gg=o}let pi,Mr=null,Gn=null,wc=!1,L_=null;const j_="terminal",QO=w("console");QO&&yg();const YO=Symbol("consoleParent");function yg(){if(pi){pi.showSwitch();return}tk()}function D_(){pi&&(pi.hide(),pi.hideSwitch())}function ZO(){L_||(L_=setInterval(KO,500))}let B_=0;function KO(){const o=l_(),e=o!==B_;B_=o,e&&JO()}function JO(){yg(),Gn&&(Gn.setAttribute("error","true"),Gn.innerText="\u{1F92C}")}function ek(){Gn&&(Gn.removeAttribute("error"),Gn.innerText=j_)}function tk(o=!1){if(pi!==void 0||wc)return;wc=!0;const e=document.createElement("script");e.onload=()=>{if(!globalThis.VConsole){console.warn("\u{1F335} Debug console failed to load."),wc=!1,pi=null;return}wc=!1,ZO(),pi=new VConsole({pluginOrder:["default","needle-console"]});const t=globalThis["needle:codegen_files"];if(t&&t.length>0&&pi.addPlugin(ik()),pi.addPlugin(rk()),pi.addPlugin(ak()),Mr=bk(),Mr&&(Mr[YO]=Mr.parentElement,Mr.style.position="absolute",Mr.style.zIndex=Number.MAX_SAFE_INTEGER.toString()),pi.setSwitchPosition(20,30),Gn=yk(),Gn){Gn.innerText=j_,Gn.addEventListener("click",ek);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;
}
`,Mr?.prepend(i),o===!0&&l_()<=0&&D_(),console.log("\u{1F335} Debug console has loaded")}},e.onerror=()=>{console.warn("\u{1F335} Debug console failed to load."+(window.crossOriginIsolated?"This page is using cross-origin isolation, so external scripts can't be loaded.":"")),wc=!1,pi=null},e.src="https://cdn.jsdelivr.net/npm/vconsole@3.15.1/dist/vconsole.min.js",document.body.appendChild(e)}function ik(){if(!globalThis.VConsole)return;const o=new VConsole.VConsolePlugin("needle-console","\u{1F335} Inspect glTF"),e=()=>document.querySelector("#__vc_plug_"+o._id+" iframe");return o.on("renderTab",function(t){const i=globalThis["needle:codegen_files"];if(!i||i.length===0)return;let n=globalThis["needle:codegen_files"][0];const s=n.indexOf("?");s>-1&&(n=n.substring(0,s));const r=location.protocol+"//"+location.host+location.pathname+"/"+n,a=encodeURIComponent(r);o.fullUrl="https://viewer.needle.tools?inspect&file="+a;var l='<iframe src="" style="width: 100%; height: 99%; border: none;"></iframe>';t(l)}),o.on("show",function(){const t=e();t&&t.src!==o.fullUrl&&(t.src=o.fullUrl)}),o.on("hide",function(){const t=e();t&&(t.src="")}),o.on("addTopBar",function(t){var i=new Array;i.push({name:"Open in new window \u2197",onClick:function(n){window.open(o.fullUrl,"_blank"),pi?.hide()}}),i.push({name:"Reload",onClick:function(n){const s=e();s&&(s.src=o.fullUrl)}}),i.push({name:"Fullscreen",onClick:function(n){const s=e();s.requestFullscreen?s.requestFullscreen():s.webkitRequestFullscreen instanceof Function&&s.webkitRequestFullscreen()}}),t(i)}),o}const bg="padding: 10px; font-family: monospace;",F_="margin-bottom: 10px;",Er="margin-bottom: 10px; margin-top: 15px;",nk="width: 100%; border-collapse: collapse; border: 1px solid rgba(0,0,0,0.1); table-layout: fixed;",U_="border: 1px solid rgba(0,0,0,0.1); padding: 5px;",ok=U_,sk=U_+" word-break: break-all;";function qn(o,e=!1){e&&o.sort((i,n)=>(n.value?1:0)-(i.value?1:0));let t=`<table style='${nk}'>`;t+="<tbody>";for(const i of o){const n=typeof i.value=="boolean"?i.value?"\u2705":"\u274C":i.value;t+=`<tr><td style='${ok}'>${i.label}</td><td style='${sk}'>${n}</td></tr>`}return t+="</tbody></table>",t}function z_(){try{if(document.createElement("canvas").getContext("webgl2"))return"\u2705"}catch{}return"\u274C"}function rk(){if(!globalThis.VConsole)return;const o=new VConsole.VConsolePlugin("device-utilities","\u{1F4F1} Device Info");return o.on("renderTab",function(e){let t=`<div style='${bg}'>`;const i=fk();t+=`<h3 style='${F_}'>Device: ${i}</h3>`,t+=qn([{label:"\u{1F4BB} Desktop",value:I.isDesktop()},{label:"\u{1F4F1} Mobile Device",value:I.isMobileDevice()},{label:"\u{1F34E} iOS",value:I.isiOS()},{label:"\u{1F4F1} iPad",value:I.isiPad()},{label:"\u{1F916} Android",value:I.isAndroidDevice()},{label:"\u{1F98A} Mozilla XR",value:I.isMozillaXR()},{label:"\u{1F335} Needle App Clip",value:I.isNeedleAppClip()},{label:"\u{1F34F} macOS",value:I.isMacOS()},{label:"\u{1F453} VisionOS",value:I.isVisionOS()},{label:"\u{1F9ED} Safari",value:I.isSafari()},{label:"\u{1F576}\uFE0F Meta Quest",value:I.isQuest()},{label:"\u{1F517} QuickLook AR Support",value:I.supportsQuickLookAR()}],!0);const n=[],s=I.getiOSVersion();s&&n.push({label:"\u{1F34E} iOS Version",value:s});const r=I.getChromeVersion();r&&n.push({label:"\u{1F310} Chrome Version",value:r});const a=I.getSafariVersion();a&&n.push({label:"\u{1F9ED} Safari Version",value:a}),n.length>0&&(t+=qn(n,!1)),t+="</div>",t+=`<div style='${bg} margin-top: 20px;'>`,t+=`<h3 style='${F_}'>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?"\u2705":"\u274C"},{label:"WebGPU",value:"gpu"in navigator?"\u2705":"\u274C"},{label:"WebGL 2",value:z_()}];t+=qn(l,!1),t+="</div>",e(t)}),o}function ak(){if(!globalThis.VConsole)return;const o=new VConsole.VConsolePlugin("graphics-info","\u{1F3A8} Graphics Info");return o.on("renderTab",async function(e){let t=`<div style='${bg}'>`;const i=lk();i.length>0&