@needle-tools/engine 4.12.0-next.99c3b94 → 4.12.0-next.ae9cea2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -141,7 +141,7 @@ void main(){
141
141
  #__vconsole .vc-mask {
142
142
  overflow: hidden;
143
143
  }
144
- `,Oo?.prepend(i),s===!0&&Fb()<=0&&nv(),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.":"")),cl=!1,Qt=null},e.src="https://cdn.jsdelivr.net/npm/vconsole@3.15.1/dist/vconsole.min.js",document.body.appendChild(e)}function LS(){if(!globalThis.VConsole)return;const s=new VConsole.VConsolePlugin("needle-console","🌵 Inspect glTF"),e=()=>document.querySelector("#__vc_plug_"+s._id+" iframe");return s.on("renderTab",function(t){const i=globalThis["needle:codegen_files"];if(!i||i.length===0)return;let n=globalThis["needle:codegen_files"][0];const o=n.indexOf("?");o>-1&&(n=n.substring(0,o));const a=location.protocol+"//"+location.host+location.pathname+"/"+n,l=encodeURIComponent(a);s.fullUrl="https://viewer.needle.tools?inspect&file="+l;var h='<iframe src="" style="width: 100%; height: 99%; border: none;"></iframe>';t(h)}),s.on("show",function(){const t=e();t&&t.src!==s.fullUrl&&(t.src=s.fullUrl)}),s.on("hide",function(){const t=e();t&&(t.src="")}),s.on("addTopBar",function(t){var i=new Array;i.push({name:"Open in new window ↗",onClick:function(n){window.open(s.fullUrl,"_blank"),Qt?.hide()}}),i.push({name:"Reload",onClick:function(n){const o=e();o&&(o.src=s.fullUrl)}}),i.push({name:"Fullscreen",onClick:function(n){const o=e();o.requestFullscreen?o.requestFullscreen():o.webkitRequestFullscreen instanceof Function&&o.webkitRequestFullscreen()}}),t(i)}),s}const Pp="padding: 10px; font-family: monospace;",zy="margin-bottom: 10px;",Mo="margin-bottom: 10px; margin-top: 15px;",IS="width: 100%; border-collapse: collapse; border: 1px solid rgba(0,0,0,0.1); table-layout: fixed;",sv="border: 1px solid rgba(0,0,0,0.1); padding: 5px;",jS=sv,BS=sv+" word-break: break-all;";function Cn(s,e=!1){e&&s.sort((i,n)=>(n.value?1:0)-(i.value?1:0));let t=`<table style='${IS}'>`;t+="<tbody>";for(const i of s){const n=typeof i.value=="boolean"?i.value?"✅":"❌":i.value;t+=`<tr><td style='${jS}'>${i.label}</td><td style='${BS}'>${n}</td></tr>`}return t+="</tbody></table>",t}function ov(){try{if(document.createElement("canvas").getContext("webgl2"))return"✅"}catch{}return"❌"}function US(){if(!globalThis.VConsole)return;const s=new VConsole.VConsolePlugin("device-utilities","📱 Device Info");return s.on("renderTab",function(e){let t=`<div style='${Pp}'>`;const i=XS();t+=`<h3 style='${zy}'>Device: ${i}</h3>`,t+=Cn([{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+=Cn(n,!1)),t+="</div>",t+=`<div style='${Pp} margin-top: 20px;'>`,t+=`<h3 style='${zy}'>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:ov()}];t+=Cn(l,!1),t+="</div>",e(t)}),s}function FS(){if(!globalThis.VConsole)return;const s=new VConsole.VConsolePlugin("graphics-info","🎨 Graphics Info");return s.on("renderTab",async function(e){let t=`<div style='${Pp}'>`;const i=zS();i.length>0&&(t+=`<h3 style='${Mo}'>General GPU Info</h3>`,t+=Cn(i,!1));const n=VS();n.length>0&&(t+=`<h3 style='${Mo}'>WebGL</h3>`,t+=Cn(n,!1));const o=$S();o.length>0&&(t+=`<h3 style='${Mo}'>WebGL 2 Features</h3>`,t+=Cn(o,!1));const r=WS();r.length>0&&(t+=`<h3 style='${Mo}'>WebGL Limits</h3>`,t+=Cn(r,!1));const a=GS();a.length>0&&(t+=`<h3 style='${Mo}'>Texture Formats</h3>`,t+=Cn(a,!1));const l=await HS();if(l.length>0&&(t+=`<h3 style='${Mo}'>WebGPU</h3>`,t+=Cn(l,!1)),exports.DeviceUtilities.isSafari()){const h=qS();h.length>0&&(t+=`<h3 style='${Mo}'>Safari GPU Info</h3>`,t+=Cn(h,!1))}t+="</div>",e(t)}),s}function zS(){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=rv();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=NS(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 NS(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 VS(){const s=[],e=rv();return e&&(s.push({label:"📊 WebGL Version",value:e.version}),s.push({label:"🎮 WebGL 2 Available",value:ov()})),s}function $S(){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 WS(){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.push({label:"🎨 Max Renderbuffer Size",value:t.getParameter(t.MAX_RENDERBUFFER_SIZE).toString()}),s.push({label:"🔗 Max Vertex Attribs",value:t.getParameter(t.MAX_VERTEX_ATTRIBS).toString()}),s.push({label:"🎯 Max Texture Units",value:t.getParameter(t.MAX_TEXTURE_IMAGE_UNITS).toString()}),i&&(s.push({label:"⚡ Max Samples",value:t.getParameter(t.MAX_SAMPLES).toString()}),s.push({label:"🔄 Max Uniform Buffer Bindings",value:t.getParameter(t.MAX_UNIFORM_BUFFER_BINDINGS).toString()}),s.push({label:"📐 Max 3D Texture Size",value:t.getParameter(t.MAX_3D_TEXTURE_SIZE).toString()}))}catch{}return s}function GS(){const s=[];try{document.createElement("canvas").getContext("webgl")&&(s.push({label:"WebGL 1 RGBA",value:"✅"}),s.push({label:"WebGL 1 RGB",value:"✅"}));const n=document.createElement("canvas").getContext("webgl2");n&&(s.push({label:"WebGL 2 RGBA32F",value:n.getExtension("EXT_color_buffer_float")?"✅":"❌"}),s.push({label:"WebGL 2 RGB32F",value:n.getExtension("EXT_color_buffer_float")?"✅":"❌"}),s.push({label:"WebGL 2 R11F_G11F_B10F",value:"✅"}),s.push({label:"WebGL 2 RGB565",value:"✅"}),s.push({label:"WebGL 2 RGB5_A1",value:"✅"}),s.push({label:"WebGL 2 RGBA4444",value:"✅"}))}catch{}return s}async function HS(){const s=[];if(!("gpu"in navigator))return s.push({label:"🚀 WebGPU Support",value:"❌ Not supported"}),s;s.push({label:"🚀 WebGPU Support",value:"✅ Supported"});try{const e=await navigator.gpu.requestAdapter();if(!e)return s.push({label:"🎯 Adapter",value:"No adapter available"}),s;s.push({label:"🎯 Adapter",value:e.name||"Unknown Adapter"});const t=await e.requestDevice();s.push({label:"🔧 Device",value:t.label||"WebGPU Device"}),s.push({label:"📏 Max Texture 2D",value:t.limits.maxTextureDimension2D.toString()}),s.push({label:"📐 Max Texture 3D",value:t.limits.maxTextureDimension3D.toString()}),s.push({label:"📊 Max Texture Array Layers",value:t.limits.maxTextureArrayLayers.toString()}),s.push({label:"💾 Max Buffer Size",value:`${(t.limits.maxBufferSize/1024/1024).toFixed(1)}MB`}),s.push({label:"🔗 Max Bind Groups",value:t.limits.maxBindGroups.toString()})}catch(e){s.push({label:"❌ Error",value:e.message})}return s}function rv(){try{const s=document.createElement("canvas"),e=s.getContext("webgl2")||s.getContext("webgl");if(!e)return null;const t=e.getExtension("WEBGL_debug_renderer_info"),i=t?e.getParameter(t.UNMASKED_RENDERER_WEBGL):e.getParameter(e.RENDERER),n=t?e.getParameter(t.UNMASKED_VENDOR_WEBGL):e.getParameter(e.VENDOR),o=e.getParameter(e.VERSION);let r;if(i&&i.includes("ANGLE")){const a=i.match(/ANGLE \(([^)]+)\)/);a&&(r=a[1])}return{renderer:i,vendor:n,version:o,angle:r}}catch{return null}}function qS(){const s=[];try{const t=document.createElement("canvas").getContext("webgl");if(t){const i=t.getExtension("WEBGL_debug_renderer_info");if(i){const n=t.getParameter(i.UNMASKED_RENDERER_WEBGL);n&&n.includes("Apple")&&s.push({label:"🍎 Apple GPU",value:n})}}}catch{}try{const t=document.createElement("canvas").getContext("webgl");t&&(t.getSupportedExtensions()||[]).includes("WEBGL_compressed_texture_pvrtc")&&s.push({label:"🗜️ PVRTC Support",value:"✅"})}catch{}return s}function XS(){return exports.DeviceUtilities.isQuest()?"Meta Quest":exports.DeviceUtilities.isVisionOS()?"Vision Pro":exports.DeviceUtilities.isiOS()?exports.DeviceUtilities.isiPad()?"iPad":"iPhone/iPod":exports.DeviceUtilities.isAndroidDevice()?"Android Device":exports.DeviceUtilities.isMozillaXR()?"Mozilla XR Browser":exports.DeviceUtilities.isNeedleAppClip()?"Needle App Clip":exports.DeviceUtilities.isMacOS()?"Mac":exports.DeviceUtilities.isDesktop()?"Desktop PC":"Unknown Device"}function QS(){const s=document.querySelector("#__vconsole .vc-switch");return s||null}function YS(){const s=document.querySelector("#__vconsole");return s||null}const av=x("debugdefines");lo('if(!globalThis["NEEDLE_ENGINE_VERSION"]) globalThis["NEEDLE_ENGINE_VERSION"] = "0.0.0";');lo('if(!globalThis["NEEDLE_ENGINE_GENERATOR"]) globalThis["NEEDLE_ENGINE_GENERATOR"] = "unknown";');lo('if(!globalThis["NEEDLE_PROJECT_BUILD_TIME"]) globalThis["NEEDLE_PROJECT_BUILD_TIME"] = "unknown";');lo('if(!globalThis["NEEDLE_PUBLIC_KEY"]) globalThis["NEEDLE_PUBLIC_KEY"] = "unknown";');lo('globalThis["__NEEDLE_ENGINE_VERSION__"] = "4.12.0-beta.2";');lo('globalThis["__NEEDLE_ENGINE_GENERATOR__"] = "undefined";');lo('globalThis["__NEEDLE_PROJECT_BUILD_TIME__"] = "Thu Jan 22 2026 18:06:36 GMT+0000 (Coordinated Universal Time)";');lo('globalThis["__NEEDLE_PUBLIC_KEY__"] = "'+NEEDLE_PUBLIC_KEY+'";');const Di="4.12.0-beta.2",Rc="undefined",iu="Thu Jan 22 2026 18:06:36 GMT+0000 (Coordinated Universal Time)";av&&console.log(`Engine version: ${Di} (generator: ${Rc})
144
+ `,Oo?.prepend(i),s===!0&&Fb()<=0&&nv(),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.":"")),cl=!1,Qt=null},e.src="https://cdn.jsdelivr.net/npm/vconsole@3.15.1/dist/vconsole.min.js",document.body.appendChild(e)}function LS(){if(!globalThis.VConsole)return;const s=new VConsole.VConsolePlugin("needle-console","🌵 Inspect glTF"),e=()=>document.querySelector("#__vc_plug_"+s._id+" iframe");return s.on("renderTab",function(t){const i=globalThis["needle:codegen_files"];if(!i||i.length===0)return;let n=globalThis["needle:codegen_files"][0];const o=n.indexOf("?");o>-1&&(n=n.substring(0,o));const a=location.protocol+"//"+location.host+location.pathname+"/"+n,l=encodeURIComponent(a);s.fullUrl="https://viewer.needle.tools?inspect&file="+l;var h='<iframe src="" style="width: 100%; height: 99%; border: none;"></iframe>';t(h)}),s.on("show",function(){const t=e();t&&t.src!==s.fullUrl&&(t.src=s.fullUrl)}),s.on("hide",function(){const t=e();t&&(t.src="")}),s.on("addTopBar",function(t){var i=new Array;i.push({name:"Open in new window ↗",onClick:function(n){window.open(s.fullUrl,"_blank"),Qt?.hide()}}),i.push({name:"Reload",onClick:function(n){const o=e();o&&(o.src=s.fullUrl)}}),i.push({name:"Fullscreen",onClick:function(n){const o=e();o.requestFullscreen?o.requestFullscreen():o.webkitRequestFullscreen instanceof Function&&o.webkitRequestFullscreen()}}),t(i)}),s}const Pp="padding: 10px; font-family: monospace;",zy="margin-bottom: 10px;",Mo="margin-bottom: 10px; margin-top: 15px;",IS="width: 100%; border-collapse: collapse; border: 1px solid rgba(0,0,0,0.1); table-layout: fixed;",sv="border: 1px solid rgba(0,0,0,0.1); padding: 5px;",jS=sv,BS=sv+" word-break: break-all;";function Cn(s,e=!1){e&&s.sort((i,n)=>(n.value?1:0)-(i.value?1:0));let t=`<table style='${IS}'>`;t+="<tbody>";for(const i of s){const n=typeof i.value=="boolean"?i.value?"✅":"❌":i.value;t+=`<tr><td style='${jS}'>${i.label}</td><td style='${BS}'>${n}</td></tr>`}return t+="</tbody></table>",t}function ov(){try{if(document.createElement("canvas").getContext("webgl2"))return"✅"}catch{}return"❌"}function US(){if(!globalThis.VConsole)return;const s=new VConsole.VConsolePlugin("device-utilities","📱 Device Info");return s.on("renderTab",function(e){let t=`<div style='${Pp}'>`;const i=XS();t+=`<h3 style='${zy}'>Device: ${i}</h3>`,t+=Cn([{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+=Cn(n,!1)),t+="</div>",t+=`<div style='${Pp} margin-top: 20px;'>`,t+=`<h3 style='${zy}'>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:ov()}];t+=Cn(l,!1),t+="</div>",e(t)}),s}function FS(){if(!globalThis.VConsole)return;const s=new VConsole.VConsolePlugin("graphics-info","🎨 Graphics Info");return s.on("renderTab",async function(e){let t=`<div style='${Pp}'>`;const i=zS();i.length>0&&(t+=`<h3 style='${Mo}'>General GPU Info</h3>`,t+=Cn(i,!1));const n=VS();n.length>0&&(t+=`<h3 style='${Mo}'>WebGL</h3>`,t+=Cn(n,!1));const o=$S();o.length>0&&(t+=`<h3 style='${Mo}'>WebGL 2 Features</h3>`,t+=Cn(o,!1));const r=WS();r.length>0&&(t+=`<h3 style='${Mo}'>WebGL Limits</h3>`,t+=Cn(r,!1));const a=GS();a.length>0&&(t+=`<h3 style='${Mo}'>Texture Formats</h3>`,t+=Cn(a,!1));const l=await HS();if(l.length>0&&(t+=`<h3 style='${Mo}'>WebGPU</h3>`,t+=Cn(l,!1)),exports.DeviceUtilities.isSafari()){const h=qS();h.length>0&&(t+=`<h3 style='${Mo}'>Safari GPU Info</h3>`,t+=Cn(h,!1))}t+="</div>",e(t)}),s}function zS(){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=rv();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=NS(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 NS(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 VS(){const s=[],e=rv();return e&&(s.push({label:"📊 WebGL Version",value:e.version}),s.push({label:"🎮 WebGL 2 Available",value:ov()})),s}function $S(){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 WS(){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.push({label:"🎨 Max Renderbuffer Size",value:t.getParameter(t.MAX_RENDERBUFFER_SIZE).toString()}),s.push({label:"🔗 Max Vertex Attribs",value:t.getParameter(t.MAX_VERTEX_ATTRIBS).toString()}),s.push({label:"🎯 Max Texture Units",value:t.getParameter(t.MAX_TEXTURE_IMAGE_UNITS).toString()}),i&&(s.push({label:"⚡ Max Samples",value:t.getParameter(t.MAX_SAMPLES).toString()}),s.push({label:"🔄 Max Uniform Buffer Bindings",value:t.getParameter(t.MAX_UNIFORM_BUFFER_BINDINGS).toString()}),s.push({label:"📐 Max 3D Texture Size",value:t.getParameter(t.MAX_3D_TEXTURE_SIZE).toString()}))}catch{}return s}function GS(){const s=[];try{document.createElement("canvas").getContext("webgl")&&(s.push({label:"WebGL 1 RGBA",value:"✅"}),s.push({label:"WebGL 1 RGB",value:"✅"}));const n=document.createElement("canvas").getContext("webgl2");n&&(s.push({label:"WebGL 2 RGBA32F",value:n.getExtension("EXT_color_buffer_float")?"✅":"❌"}),s.push({label:"WebGL 2 RGB32F",value:n.getExtension("EXT_color_buffer_float")?"✅":"❌"}),s.push({label:"WebGL 2 R11F_G11F_B10F",value:"✅"}),s.push({label:"WebGL 2 RGB565",value:"✅"}),s.push({label:"WebGL 2 RGB5_A1",value:"✅"}),s.push({label:"WebGL 2 RGBA4444",value:"✅"}))}catch{}return s}async function HS(){const s=[];if(!("gpu"in navigator))return s.push({label:"🚀 WebGPU Support",value:"❌ Not supported"}),s;s.push({label:"🚀 WebGPU Support",value:"✅ Supported"});try{const e=await navigator.gpu.requestAdapter();if(!e)return s.push({label:"🎯 Adapter",value:"No adapter available"}),s;s.push({label:"🎯 Adapter",value:e.name||"Unknown Adapter"});const t=await e.requestDevice();s.push({label:"🔧 Device",value:t.label||"WebGPU Device"}),s.push({label:"📏 Max Texture 2D",value:t.limits.maxTextureDimension2D.toString()}),s.push({label:"📐 Max Texture 3D",value:t.limits.maxTextureDimension3D.toString()}),s.push({label:"📊 Max Texture Array Layers",value:t.limits.maxTextureArrayLayers.toString()}),s.push({label:"💾 Max Buffer Size",value:`${(t.limits.maxBufferSize/1024/1024).toFixed(1)}MB`}),s.push({label:"🔗 Max Bind Groups",value:t.limits.maxBindGroups.toString()})}catch(e){s.push({label:"❌ Error",value:e.message})}return s}function rv(){try{const s=document.createElement("canvas"),e=s.getContext("webgl2")||s.getContext("webgl");if(!e)return null;const t=e.getExtension("WEBGL_debug_renderer_info"),i=t?e.getParameter(t.UNMASKED_RENDERER_WEBGL):e.getParameter(e.RENDERER),n=t?e.getParameter(t.UNMASKED_VENDOR_WEBGL):e.getParameter(e.VENDOR),o=e.getParameter(e.VERSION);let r;if(i&&i.includes("ANGLE")){const a=i.match(/ANGLE \(([^)]+)\)/);a&&(r=a[1])}return{renderer:i,vendor:n,version:o,angle:r}}catch{return null}}function qS(){const s=[];try{const t=document.createElement("canvas").getContext("webgl");if(t){const i=t.getExtension("WEBGL_debug_renderer_info");if(i){const n=t.getParameter(i.UNMASKED_RENDERER_WEBGL);n&&n.includes("Apple")&&s.push({label:"🍎 Apple GPU",value:n})}}}catch{}try{const t=document.createElement("canvas").getContext("webgl");t&&(t.getSupportedExtensions()||[]).includes("WEBGL_compressed_texture_pvrtc")&&s.push({label:"🗜️ PVRTC Support",value:"✅"})}catch{}return s}function XS(){return exports.DeviceUtilities.isQuest()?"Meta Quest":exports.DeviceUtilities.isVisionOS()?"Vision Pro":exports.DeviceUtilities.isiOS()?exports.DeviceUtilities.isiPad()?"iPad":"iPhone/iPod":exports.DeviceUtilities.isAndroidDevice()?"Android Device":exports.DeviceUtilities.isMozillaXR()?"Mozilla XR Browser":exports.DeviceUtilities.isNeedleAppClip()?"Needle App Clip":exports.DeviceUtilities.isMacOS()?"Mac":exports.DeviceUtilities.isDesktop()?"Desktop PC":"Unknown Device"}function QS(){const s=document.querySelector("#__vconsole .vc-switch");return s||null}function YS(){const s=document.querySelector("#__vconsole");return s||null}const av=x("debugdefines");lo('if(!globalThis["NEEDLE_ENGINE_VERSION"]) globalThis["NEEDLE_ENGINE_VERSION"] = "0.0.0";');lo('if(!globalThis["NEEDLE_ENGINE_GENERATOR"]) globalThis["NEEDLE_ENGINE_GENERATOR"] = "unknown";');lo('if(!globalThis["NEEDLE_PROJECT_BUILD_TIME"]) globalThis["NEEDLE_PROJECT_BUILD_TIME"] = "unknown";');lo('if(!globalThis["NEEDLE_PUBLIC_KEY"]) globalThis["NEEDLE_PUBLIC_KEY"] = "unknown";');lo('globalThis["__NEEDLE_ENGINE_VERSION__"] = "4.12.0-beta.2";');lo('globalThis["__NEEDLE_ENGINE_GENERATOR__"] = "undefined";');lo('globalThis["__NEEDLE_PROJECT_BUILD_TIME__"] = "Thu Jan 22 2026 18:04:46 GMT+0000 (Coordinated Universal Time)";');lo('globalThis["__NEEDLE_PUBLIC_KEY__"] = "'+NEEDLE_PUBLIC_KEY+'";');const Di="4.12.0-beta.2",Rc="undefined",iu="Thu Jan 22 2026 18:04:46 GMT+0000 (Coordinated Universal Time)";av&&console.log(`Engine version: ${Di} (generator: ${Rc})
145
145
  Project built at ${iu}`);const Vo=NEEDLE_PUBLIC_KEY,ls="needle_isActiveInHierarchy",Bo="builtin_components",$l="needle_editor_guid";function lo(s){try{(0,eval)(s)}catch(e){av&&console.error(e)}}let lv,Ny=null;function an(){return lv}function km(s){if(s==null){console.warn("Oh no: someone tried registering a non-existend gltf-loader. When you see this log it might mean that needle-engine is being imported multiple times. Please check your project setup.");return}Ny!==s&&(Ny=s,lv=new s)}function KS(s,e){if(typeof window!==void 0&&window.SPECTOR){console.log(window.SPECTOR);const t=new URLSearchParams(window.location.search);if(t.has("spector")){let i=function(){if(n>s.time.frame)return window.requestAnimationFrame(()=>i());const r=o.captureCanvas(e);r&&r instanceof Promise?r.then(()=>o.displayUI()):o.displayUI()};const n=Number.parseInt(t.get("spector")||"0")||0;console.log("Scheduled Spector capture at frame #"+n);const o=new window.SPECTOR.Spector;o.spyCanvases=!0,i();return}else R()&&console.debug("Spector available: Add '?spector=<frame>' to the URL to enable it and capture a frame.")}}const ci=Symbol("shadowDomOwner"),ZS=x("debugpatch");function nu(s,e,t,i){const n=ZS===e;if(!t&&!i)return;const o=e+"___needle";eC(s,e,t,i);const r=Object.getOwnPropertyDescriptor(s,e),a=s[e];n&&console.log("Patch",s.constructor.name,e,r,a),r?(n&&console.log("Apply patch with existing descriptor",s.constructor.name,e,r),typeof r.value=="function"&&(s[e]=$y(r.value,s,e))):(n&&console.log("Create patch with new property",s.constructor.name,e,r),Object.defineProperty(s,e,{set:function(l){if(typeof l=="function")this[o]=$y(l,s,e);else{const h=this[o];cv(s,e,this,h,l),this[o]=l,hv(s,e,this,h,l)}},get:function(){const l=this[o];return typeof l=="function"&&l[o]?l[o]:l}}))}function JS(s,e,t){const i=Em(s,e);if(i)for(let n=i.length-1;n>=0;n--){const o=i[n];o.prefix===t&&(o.prefix=null),o.postfix===t&&(o.postfix=null),!o.prefix&&!o.postfix&&i.splice(n,1)}}const Vy=Symbol("Needle:Patches:WrappedFunction");function $y(s,e,t){if(s[Vy])return s;const i=function(...n){cv(e,t,this,...n);const o=s.apply(this,n);return hv(e,t,this,o,...n),o};return i[Vy]=!0,i}const od="Needle:Patches";function Op(){return globalThis[od]||(globalThis[od]=new WeakMap),globalThis[od]}function Em(s,e){const t=Op().get(s);return t?t.get(e):null}function eC(s,e,t,i){let n=Op().get(s);n||(n=new Map,Op().set(s,n));let o=n.get(e);o||(o=[],n.set(e,o)),o.push({prefix:t,postfix:i})}function cv(s,e,t,...i){if(!t)return;const n=Em(s,e);if(n)for(const o of n)o.prefix?.call(t,...i)}function hv(s,e,t,i,...n){if(!t)return;const o=Em(s,e);if(o)for(const r of o)r.postfix?.call(t,i,...n)}const xa=[];function su(s){xa.indexOf(s)===-1&&xa.push(s)}function tC(s){const e=xa.indexOf(s);e!==-1&&xa.splice(e,1)}const Sa=[];function Rm(s){Sa.indexOf(s)===-1&&Sa.push(s)}function iC(s){const e=Sa.indexOf(s);e!==-1&&Sa.splice(e,1)}function dv(s){globalThis.dispatchEvent(new CustomEvent("needle-xrsession-start",{detail:s}));for(let e=0;e<xa.length;e++)xa[e](s)}function uv(s){globalThis.dispatchEvent(new CustomEvent("needle-xrsession-end",{detail:s}));for(let e=0;e<Sa.length;e++)Sa[e](s)}const Xe=x("debuginput");var ou=(s=>(s.Mouse="mouse",s.Touch="touch",s.Controller="controller",s.Hand="hand",s))(ou||{}),Se=(s=>(s.PointerDown="pointerdown",s.PointerUp="pointerup",s.PointerMove="pointermove",s.KeyDown="keydown",s.KeyUp="keyup",s.KeyPressed="keypress",s))(Se||{});class Zn extends PointerEvent{clientZ;deviceIndex;origin;source;mode;get isSpatial(){return this.mode!="screen"}get ray(){return this._ray||(this._ray=new c.Ray(this.space.worldPosition.clone(),this.space.worldForward.clone())),this._ray}set ray(e){this._ray=e}get hasRay(){return this._ray!==void 0}_ray;space;isClick=!1;isDoubleClick=!1;get used(){return this._used}_used=!1;use(){this._used=!0}get pointerId(){return this._pointerid}_pointerid;get pointerType(){return this._pointerType}_pointerType;buttonName=void 0;get type(){return this._type}_type;metadata={};intersections=new Array;constructor(e,t,i){super(e,i),this.clientZ=i.clientZ,this._pointerid=i.pointerId,this._pointerType=i.pointerType,this._type=e,this.deviceIndex=i.deviceIndex,this.origin=i.origin,this.source=t,this.mode=i.mode,this._ray=i.ray,this.space=i.device,this.buttonName=i.buttonName}_immediatePropagationStopped=!1;get immediatePropagationStopped(){return this._immediatePropagationStopped}_propagationStopped=!1;get propagationStopped(){return this._immediatePropagationStopped||this._propagationStopped}stopImmediatePropagation(){this._immediatePropagationStopped=!0,super.stopImmediatePropagation(),this.source?.stopImmediatePropagation()}stopPropagation(){this._propagationStopped=!0,super.stopPropagation(),this.source?.stopPropagation(),Xe&&console.warn("Stop propagation...",this.pointerId,this.pointerType)}}class Ol extends KeyboardEvent{source;constructor(e,t,i){super(e,i),this.source=t}stopImmediatePropagation(){super.stopImmediatePropagation(),this.source?.stopImmediatePropagation()}}class nC{key;keyType;source;constructor(e){this.key=e.key,this.keyType=e.type,this.source=e}}var Zt=(s=>(s[s.Early=-100]="Early",s[s.Default=0]="Default",s[s.Late=100]="Late",s))(Zt||{});class fv{_eventListeners={};addEventListener(e,t,i){if(this._eventListeners[e]||(this._eventListeners[e]=[]),!t||typeof t!="function"){console.error("Invalid call to addEventListener: callback is required and must be a function!");return}i?i={...i}:i={};let n=0;i?.queue!=null&&(n=i.queue);const o=this._eventListeners[e],r=o.find(a=>a.priority===n);r?r.listeners.push({callback:t,options:i}):(o.push({priority:n,listeners:[{callback:t,options:i}]}),o.sort((a,l)=>a.priority-l.priority))}removeEventListener(e,t,i){if(!this._eventListeners[e]||!t)return;const n=this._eventListeners[e];if(i?.queue!=null){const o=n.find(a=>a.priority===i.queue);if(!o)return;const r=o.listeners.findIndex(a=>a.callback===t);r>=0&&o.listeners.splice(r,1)}else for(const o of n){const r=o.listeners.findIndex(a=>a.callback===t);r>=0&&o.listeners.splice(r,1)}}dispatchEvent(e){let t=!1;if(e instanceof Ol){const i=this._eventListeners[e.type];if(i)for(const n of i)for(let o=0;o<n.listeners.length;o++){const r=n.listeners[o];if(r.options?.signal?.aborted){n.listeners.splice(o,1),o--;continue}r.options.once&&(n.listeners.splice(o,1),o--),r.callback(e)}}if(e instanceof Zn){const i=this._eventListeners[e.type];if(i)for(const n of i){if(t)break;for(let o=0;o<n.listeners.length;o++){const r=n.listeners[o];if(r.options?.signal?.aborted){n.listeners.splice(o,1),o--;continue}if(e.immediatePropagationStopped){t=!0,Xe&&console.log("immediatePropagationStopped",e.type);break}else e.propagationStopped&&(t=!0,Xe&&console.log("propagationStopped",e.type));r.options.once&&(n.listeners.splice(o,1),o--),r.callback(e)}}}}_doubleClickTimeThreshold=.2;_longPressTimeThreshold=1;get mousePosition(){return this._pointerPositions[0]}get mousePositionRC(){return this._pointerPositionsRC[0]}get mouseDown(){return this._pointerDown[0]}get mouseUp(){return this._pointerUp[0]}get mouseClick(){return this._pointerClick[0]}get mouseDoubleClick(){return this._pointerDoubleClick[0]}get mousePressed(){return this._pointerPressed[0]}get mouseWheelChanged(){return this.getMouseWheelChanged(0)}get click(){return this._pointerClick[0]}get doubleClick(){return this._pointerDoubleClick[0]}getGamepad(e=0){return typeof navigator<"u"&&"getGamepads"in navigator&&navigator.getGamepads()[e]||null}_setCursorTypes=[];setCursorPointer(){this.setCursor("pointer")}setCursorNormal(){this.unsetCursor("pointer")}setCursor(e){this._setCursorTypes.push(e),this._setCursorTypes.length>10&&this._setCursorTypes.shift(),this.updateCursor()}unsetCursor(e){for(let t=this._setCursorTypes.length-1;t>=0;t--)if(this._setCursorTypes[t]===e){this._setCursorTypes.splice(t,1),this.updateCursor();break}}updateCursor(){this._setCursorTypes?.length==0?this.context.domElement.style.cursor="default":this.context.domElement.style.cursor=this._setCursorTypes[this._setCursorTypes.length-1]}getIsPointerIdInUse(e){for(const t of this._pointerEventsPressed)if(t.pointerId===e&&t.used)return!0;return!1}getPointerPressedCount(){let e=0;for(let t=0;t<this._pointerPressed.length;t++)this._pointerPressed[t]&&e++;return e}getPointerPosition(e){return e>=this._pointerPositions.length?null:this._pointerPositions[e]}getPointerPositionLastFrame(e){return e>=this._pointerPositionsLastFrame.length?null:this._pointerPositionsLastFrame[e]}getPointerPositionDelta(e){return e>=this._pointerPositionsDelta.length?null:this._pointerPositionsDelta[e]}getPointerPositionRC(e){return e>=this._pointerPositionsRC.length?null:this._pointerPositionsRC[e]}getPointerDown(e){return e>=this._pointerDown.length?!1:this._pointerDown[e]}getPointerUp(e){return e>=this._pointerUp.length?!1:this._pointerUp[e]}getPointerPressed(e){return e>=this._pointerPressed.length?!1:this._pointerPressed[e]}getPointerClicked(e){return e>=this._pointerClick.length?!1:this._pointerClick[e]}getPointerDoubleClicked(e){return e>=this._pointerDoubleClick.length?!1:this._pointerDoubleClick[e]}getPointerDownTime(e){return e>=this._pointerDownTime.length?-1:this._pointerDownTime[e]}getPointerUpTime(e){return e>=this._pointerUpTime.length?-1:this._pointerUpTime[e]}getPointerLongPress(e){return e>=this._pointerDownTime.length?!1:this.getPointerPressed(e)&&this.context.time.time-this._pointerDownTime[e]>this._longPressTimeThreshold}getIsMouse(e){return e<0||e>=this._pointerTypes.length?!1:this._pointerTypes[e]==="mouse"}getIsTouch(e){return e<0||e>=this._pointerTypes.length?!1:this._pointerTypes[e]==="touch"}getTouchesPressedCount(){let e=0;for(let t=0;t<this._pointerPressed.length;t++)this._pointerPressed[t]&&this.getIsTouch(t)&&e++;return e}getMouseWheelChanged(e=0){return e>=this._mouseWheelChanged.length?!1:this._mouseWheelChanged[e]}getMouseWheelDeltaY(e=0){return e>=this._mouseWheelDeltaY.length?0:this._mouseWheelDeltaY[e]}getPointerEvent(e){if(!(e>=this._pointerEvent.length))return this._pointerEvent[e]??void 0}*foreachPointerId(e){for(let t=0;t<this._pointerTypes.length;t++)if(this._pointerIsActive(t)){if(e!==void 0){const i=this._pointerTypes[t];if(Array.isArray(e)){let n=!1;for(const o of e)if(i===o){n=!0;break}if(!n)continue}else if(e!==i)continue}yield t}}*foreachTouchId(){for(let e=0;e<this._pointerTypes.length;e++)this._pointerTypes[e]==="touch"&&this._pointerIsActive[e]&&(yield e)}_pointerIsActive(e){return e<0?!1:this._pointerPressed[e]||this._pointerDown[e]||this._pointerUp[e]}context;_pointerDown=[!1];_pointerUp=[!1];_pointerClick=[!1];_pointerDoubleClick=[!1];_pointerPressed=[!1];_pointerPositions=[new c.Vector2];_pointerPositionsLastFrame=[new c.Vector2];_pointerPositionsDelta=[new c.Vector2];_pointerPositionsRC=[new c.Vector2];_pointerPositionDown=[new c.Vector3];_pointerDownTime=[];_pointerUpTime=[];_pointerUpTimestamp=[];_pointerIds=[];_pointerTypes=[""];_mouseWheelChanged=[!1];_mouseWheelDeltaY=[0];_pointerEvent=[];_pointerEventsPressed=[];_pointerSpace=[];_pressedStack=new Map;onDownButton(e,t){let i=this._pressedStack.get(e);i||(i=[],this._pressedStack.set(e,i)),i.push(t)}onReleaseButton(e,t){const i=this._pressedStack.get(e);if(!i)return;const n=i.indexOf(t);n>=0&&i.splice(n,1)}getFirstPressedButtonForPointer(e){const t=this._pressedStack.get(e);if(t)return t[0]}getLatestPressedButtonForPointer(e){const t=this._pressedStack.get(e);if(t)return t[t.length-1]}getKeyDown(e){if(e!==void 0)return this.isKeyDown(e);for(const t in this.keysPressed){const i=this.keysPressed[t];if(i.startFrame===this.context.time.frameCount)return i.key}return null}getKeyPressed(e){if(e!==void 0)return this.isKeyPressed(e);for(const t in this.keysPressed){const i=this.keysPressed[t];if(i.pressed)return i.key}return null}getKeyUp(e){if(e!==void 0)return this.isKeyUp(e);for(const t in this.keysPressed){const i=this.keysPressed[t];return i.pressed===!1&&i.frame===this.context.time.frameCount}return null}isKeyDown(e){if(!this.context.application.isVisible||!this.context.application.hasFocus)return!1;const t=this.getCodeForCommonKeyName(e);if(t!==null){for(const n of t)if(this.isKeyDown(n))return!0;return!1}const i=this.keysPressed[e];return i?i.startFrame===this.context.time.frameCount&&i.pressed:!1}isKeyUp(e){if(!this.context.application.isVisible||!this.context.application.hasFocus)return!1;const t=this.getCodeForCommonKeyName(e);if(t!==null){for(const n of t)if(this.isKeyUp(n))return!0;return!1}const i=this.keysPressed[e];return i?i.frame===this.context.time.frameCount&&i.pressed===!1:!1}isKeyPressed(e){if(!this.context.application.isVisible||!this.context.application.hasFocus)return!1;const t=this.getCodeForCommonKeyName(e);if(t!==null){for(const n of t)if(this.isKeyPressed(n))return!0;return!1}const i=this.keysPressed[e];return i&&i.pressed||!1}getCodeForCommonKeyName(e){if(e.length===1){if(e>="0"&&e<="9")return["Digit"+e];if(e>="a"&&e<="z")return["Key"+e.toUpperCase()];if(e==" ")return["Space"]}switch(e){case"shift":case"Shift":return["ShiftLeft","ShiftRight"];case"control":case"Control":return["ControlLeft","ControlRight"];case"alt":case"Alt":return["AltLeft","AltRight"]}return null}createInputEvent(e){switch(e.type){case"pointerdown":Xe&&Pe("Create Pointer down"),this.onDownButton(e.deviceIndex,e.button),this.onDown(e);break;case"pointermove":Xe&&Pe("Create Pointer move"),this.onMove(e);break;case"pointerup":Xe&&Pe("Create Pointer up"),this.onUp(e),this.onReleaseButton(e.deviceIndex,e.button);break}}convertScreenspaceToRaycastSpace(e){return e.x=(e.x-this.context.domX)/this.context.domWidth*2-1,e.y=-((e.y-this.context.domY)/this.context.domHeight)*2+1,e}constructor(e){this.context=e,this.context.post_render_callbacks.push(this.onEndOfFrame)}_htmlEventSource;bindEvents(){this.unbindEvents(),this._htmlEventSource=this.context.renderer.domElement,window.addEventListener("contextmenu",this.onContextMenu),this._htmlEventSource.addEventListener("pointerdown",this.onPointerDown,{passive:!0}),window.addEventListener("pointermove",this.onPointerMove,{passive:!0,capture:!0}),window.addEventListener("pointerup",this.onPointerUp,{passive:!0}),window.addEventListener("pointercancel",this.onPointerCancel,{passive:!0}),window.addEventListener("touchstart",this.onTouchStart,{passive:!0}),window.addEventListener("touchmove",this.onTouchMove,{passive:!0}),window.addEventListener("touchend",this.onTouchEnd,{passive:!0}),this._htmlEventSource.addEventListener("wheel",this.onMouseWheel,{passive:!0}),window.addEventListener("wheel",this.onWheelWindow,{passive:!0}),window.addEventListener("keydown",this.onKeyDown,!1),window.addEventListener("keypress",this.onKeyPressed,!1),window.addEventListener("keyup",this.onKeyUp,!1),window.addEventListener("blur",this.onLostFocus)}unbindEvents(){for(const e in this._eventListeners)this._eventListeners[e].length=0;window.removeEventListener("contextmenu",this.onContextMenu),this._htmlEventSource?.removeEventListener("pointerdown",this.onPointerDown),window.removeEventListener("pointermove",this.onPointerMove),window.removeEventListener("pointerup",this.onPointerUp),window.removeEventListener("pointercancel",this.onPointerCancel),window.removeEventListener("touchstart",this.onTouchStart),window.removeEventListener("touchmove",this.onTouchMove),window.removeEventListener("touchend",this.onTouchEnd),this._htmlEventSource?.removeEventListener("wheel",this.onMouseWheel,!1),window.removeEventListener("wheel",this.onWheelWindow,!1),window.removeEventListener("keydown",this.onKeyDown,!1),window.removeEventListener("keypress",this.onKeyPressed,!1),window.removeEventListener("keyup",this.onKeyUp,!1),window.removeEventListener("blur",this.onLostFocus)}dispose(){const e=this.context.post_render_callbacks.indexOf(this.onEndOfFrame);e>=0&&this.context.post_render_callbacks.splice(e,1),this.unbindEvents()}onLostFocus=()=>{for(const e in this.keysPressed)this.keysPressed[e].pressed=!1};_receivedPointerMoveEventsThisFrame=new Array;onEndOfFrame=()=>{this._receivedPointerMoveEventsThisFrame.length=0;for(let e=0;e<this._pointerUp.length;e++)this._pointerUp[e]=!1;for(let e=0;e<this._pointerDown.length;e++)this._pointerDown[e]=!1;for(let e=0;e<this._pointerClick.length;e++)this._pointerClick[e]=!1;for(let e=0;e<this._pointerDoubleClick.length;e++)this._pointerDoubleClick[e]=!1;for(const e of this._pointerPositionsDelta)e.set(0,0);for(let e=0;e<this._mouseWheelChanged.length;e++)this._mouseWheelChanged[e]=!1;for(let e=0;e<this._mouseWheelDeltaY.length;e++)this._mouseWheelDeltaY[e]=0};canReceiveInput(e){return e.target===this.context.renderer?.domElement||e.target===this.context.domElement||this.context.isInAR||this.context.isInAR&&e.target===document.body&&exports.DeviceUtilities.isMozillaXR()?!0:(Xe&&console.warn("CanReceiveInput:False for",e.target),!1)}onContextMenu=e=>{this.canReceiveInput(e)!==!1&&e instanceof PointerEvent&&e.pointerType};keysPressed={};onKeyDown=e=>{if(Xe&&console.log(`key down ${e.code}, ${this.context.application.hasFocus}`,e),!this.context.application.hasFocus)return;const t=this.keysPressed[e.code];if(t&&t.pressed)return;this.keysPressed[e.code]={pressed:!0,frame:this.context.time.frameCount+1,startFrame:this.context.time.frameCount+1,key:e.key,code:e.code};const i=new Ol("keydown",e,e);this.onDispatchEvent(i)};onKeyPressed=e=>{if(!this.context.application.hasFocus)return;const t=this.keysPressed[e.code];if(!t)return;t.pressed=!0,t.frame=this.context.time.frameCount+1;const i=new Ol("keypress",e,e);this.onDispatchEvent(i)};onKeyUp=e=>{if(!this.context.application.hasFocus)return;const t=this.keysPressed[e.code];if(!t)return;t.pressed=!1,t.frame=this.context.time.frameCount+1;const i=new Ol("keyup",e,e);this.onDispatchEvent(i)};onWheelWindow=e=>{document.pointerLockElement&&this.onMouseWheel(e)};onMouseWheel=e=>{if(this.canReceiveInput(e)===!1)return;this._mouseWheelDeltaY.length<=0&&this._mouseWheelDeltaY.push(0),this._mouseWheelChanged.length<=0&&this._mouseWheelChanged.push(!1),this._mouseWheelChanged[0]=!0;const t=this._mouseWheelDeltaY[0];this._mouseWheelDeltaY[0]=t+e.deltaY};onPointerDown=e=>{if(this.context.isInAR||this.canReceiveInput(e)===!1)return;e.target instanceof HTMLElement&&e.target.setPointerCapture(e.pointerId);const t=this.getPointerId(e);Xe&&Pe(`pointer down #${t}, identifier:${e.pointerId}`);const i=this.getAndUpdateSpatialObjectForScreenPosition(t,e.clientX,e.clientY),n=new Zn("pointerdown",e,{origin:this,mode:"screen",deviceIndex:0,pointerId:t,button:e.button,clientX:e.clientX,clientY:e.clientY,pointerType:e.pointerType,buttonName:this.getButtonName(e),device:i,pressure:e.pressure});this.onDown(n)};onPointerMove=e=>{if(this.context.isInAR||this._receivedPointerMoveEventsThisFrame.includes(e.pointerId))return;this._receivedPointerMoveEventsThisFrame.push(e.pointerId);let t=e.button;e.pointerType==="mouse"&&(t=this.getFirstPressedButtonForPointer(0)??0);const i=this.getPointerId(e,t);t===-1&&(t=i);const n=this.getAndUpdateSpatialObjectForScreenPosition(i,e.clientX,e.clientY),o=new Zn("pointermove",e,{origin:this,mode:"screen",deviceIndex:0,pointerId:i,button:t,clientX:e.clientX,clientY:e.clientY,pointerType:e.pointerType,buttonName:this.getButtonName(e),device:n,pressure:e.pressure});this.onMove(o)};onPointerCancel=e=>{this.context.isInAR||(Xe&&console.log("Pointer cancel",e),this.onPointerUp(e))};onPointerUp=e=>{if(this.context.isInAR)return;e.target instanceof HTMLElement&&e.target.releasePointerCapture(e.pointerId);const t=this.getPointerId(e),i=new Zn("pointerup",e,{origin:this,mode:"screen",deviceIndex:0,pointerId:t,button:e.button,clientX:e.clientX,clientY:e.clientY,pointerType:e.pointerType,buttonName:this.getButtonName(e),device:this.getAndUpdateSpatialObjectForScreenPosition(t,e.clientX,e.clientY),pressure:e.pressure});this.onUp(i),this._pointerIds[t]=-1,Xe&&console.log("ID="+t,"PointerId="+e.pointerId,"ALL:",[...this._pointerIds])};getPointerId(e,t){return e.pointerType==="mouse"?0+(t??e.button):this.getPointerIndex(e.pointerId)}getButtonName(e){const t=e.button;if(e.pointerType==="mouse")switch(t){case 0:return"left";case 1:return"middle";case 2:return"right"}return"unknown"}onTouchStart=e=>{if(this.context.isInAR)for(let t=0;t<e.changedTouches.length;t++){const i=e.changedTouches[t],n=this.getPointerIndex(i.identifier),o=this.getAndUpdateSpatialObjectForScreenPosition(n,i.clientX,i.clientY),r=new Zn("pointerdown",e,{origin:this,mode:"screen",deviceIndex:0,pointerId:n,button:0,clientX:i.clientX,clientY:i.clientY,pointerType:"touch",buttonName:"unknown",device:o,pressure:i.force});this.onDown(r)}};onTouchMove=e=>{if(this.context.isInAR)for(let t=0;t<e.changedTouches.length;t++){const i=e.changedTouches[t],n=this.getPointerIndex(i.identifier),o=this.getAndUpdateSpatialObjectForScreenPosition(n,i.clientX,i.clientY),r=new Zn("pointermove",e,{origin:this,mode:"screen",deviceIndex:0,pointerId:n,button:0,clientX:i.clientX,clientY:i.clientY,pointerType:"touch",buttonName:"unknown",device:o,pressure:i.force});this.onMove(r)}};onTouchEnd=e=>{if(this.context.isInAR)for(let t=0;t<e.changedTouches.length;t++){const i=e.changedTouches[t],n=this.getPointerIndex(i.identifier),o=new Zn("pointerup",e,{origin:this,mode:"screen",deviceIndex:0,pointerId:n,button:0,clientX:i.clientX,clientY:i.clientY,pointerType:"touch",buttonName:"unknown",device:this.getAndUpdateSpatialObjectForScreenPosition(n,i.clientX,i.clientY),pressure:i.force});this.onUp(o),this._pointerIds[n]=-1}};tempNearPlaneVector=new c.Vector3;tempFarPlaneVector=new c.Vector3;tempLookMatrix=new c.Matrix4;getAndUpdateSpatialObjectForScreenPosition(e,t,i){let n=this._pointerSpace[e];n||(n=new c.Object3D,this._pointerSpace[e]=n),this._pointerSpace[e]=n;const o=this.context.mainCamera;if(o){const r=this.tempNearPlaneVector.set(t,i,-1);this.convertScreenspaceToRaycastSpace(r);const a=this.tempFarPlaneVector.set(r.x,r.y,1);r.unproject(o),a.unproject(o);const l=o.worldUp||j(0,1,0).applyQuaternion(fe(o));this.tempLookMatrix.lookAt(a,r,l),n.position.set(r.x,r.y,r.z),n.quaternion.setFromRotationMatrix(this.tempLookMatrix)}return n}isInRect(e){if(this.context.isInXR)return!0;const t=this.context.domElement.getBoundingClientRect(),i=e.clientX,n=e.clientY,o=i>=t.x&&i<=t.right&&n>=t.y&&n<=t.bottom;return Xe&&!o&&console.log("Not in rect",t,i,n),o}onDown(e){const t=e.pointerId;if(this.getPointerPressed(t)&&console.warn(`Received pointerDown for pointerId that is already pressed: ${t}`,Xe?e:""),Xe&&console.log(e.pointerType,"DOWN",t),!!this.isInRect(e)){for(this.setPointerState(t,this._pointerPressed,!0),this.setPointerState(t,this._pointerDown,!0),this.setPointerStateT(t,this._pointerEvent,e.source);t>=this._pointerTypes.length;)this._pointerTypes.push(e.pointerType);for(this._pointerTypes[t]=e.pointerType;t>=this._pointerPositionDown.length;)this._pointerPositionDown.push(new c.Vector3);for(this._pointerPositionDown[t].set(e.clientX,e.clientY,e.clientZ??0);t>=this._pointerPositions.length;)this._pointerPositions.push(new c.Vector2);this._pointerPositions[t].set(e.clientX,e.clientY),t>=this._pointerDownTime.length&&this._pointerDownTime.push(0),this._pointerDownTime[t]=this.context.time.realtimeSinceStartup,this.updatePointerPosition(e),this._pointerEventsPressed.push(e),this.onDispatchEvent(e)}}onMove(e){const t=e.pointerId,i=this.getPointerPressed(t);i===!1&&!this.isInRect(e)||e.pointerType==="touch"&&!i||(this.updatePointerPosition(e),this.setPointerStateT(t,this._pointerEvent,e.source),this.onDispatchEvent(e))}onUp(e){const t=e.pointerId;if(!this.getPointerPressed(t)){Xe&&console.log(e.pointerType,"UP",t,"was not down");return}Xe&&console.log(e.pointerType,"UP",t),this.setPointerState(t,this._pointerPressed,!1),this.setPointerStateT(t,this._pointerEvent,e.source),this.setPointerState(t,this._pointerUp,!0),this.updatePointerPosition(e);for(let l=this._pointerEventsPressed.length-1;l>=0;l--)if(this._pointerEventsPressed[l].pointerId===t){this._pointerEventsPressed.splice(l,1);break}if(!this._pointerPositionDown[t]){Xe&&ue("Received pointer up event without matching down event for button: "+t),console.warn("Received pointer up event without matching down event for button: "+t);return}const n=this._pointerUpTime[t],o=this._pointerDownTime[t],r=this.context.time.realtimeSinceStartup,a=r-o;if(t>=this._pointerUpTime.length&&this._pointerUpTime.push(-99),this._pointerUpTime[t]=r,a<1){let l=e.clientX-this._pointerPositionDown[t].x,h=e.clientY-this._pointerPositionDown[t].y,d=0;if(e.isSpatial&&e.clientZ!=null&&(d=e.clientZ-this._pointerPositionDown[t].z,l*=200,h*=200,d*=200),Math.abs(l)<5&&Math.abs(h)<5&&Math.abs(d)<5){this.setPointerState(t,this._pointerClick,!0),e.isClick=!0;const u=r-n;Xe&&console.log("CLICK",t,l,h,d,u),u<this._doubleClickTimeThreshold&&u>0&&(this.setPointerState(t,this._pointerDoubleClick,!0),e.isDoubleClick=!0)}}this.onDispatchEvent(e)}updatePointerPosition(e){const t=e.pointerId;for(;t>=this._pointerPositions.length;)this._pointerPositions.push(new c.Vector2);for(;t>=this._pointerPositionsLastFrame.length;)this._pointerPositionsLastFrame.push(new c.Vector2);for(;t>=this._pointerPositionsDelta.length;)this._pointerPositionsDelta.push(new c.Vector2);const i=this._pointerPositionsLastFrame[t];i.copy(this._pointerPositions[t]);const n=this._pointerPositionsDelta[t];let o=e.clientX-i.x,r=e.clientY-i.y;if(e.source instanceof MouseEvent||e.source instanceof TouchEvent){const d=e.source;o===0&&d.movementX!==0&&(o=d.movementX||0),r===0&&d.movementY!==0&&(r=d.movementY||0)}n.x+=o,n.y+=r,this._pointerPositions[t].x=e.clientX,this._pointerPositions[t].y=e.clientY;const a=e.clientX,l=e.clientY;for(;t>=this._pointerPositionsRC.length;)this._pointerPositionsRC.push(new c.Vector2);const h=this._pointerPositionsRC[t];h.set(a,l),this.convertScreenspaceToRaycastSpace(h)}getPointerIndex(e){let t=-1;for(let i=0;i<this._pointerIds.length;i++){if(this._pointerIds[i]===e)return i;t===-1&&this._pointerIds[i]===-1&&(t=i)}return t!==-1?(this._pointerIds[t]=e,t):(Xe&&console.log("PUSH pointerId:",e),this._pointerIds.push(e),this._pointerIds.length-1)}setPointerState(e,t,i){t[e]=i}setPointerStateT(e,t,i){return t[e]=i,i}onDispatchEvent(e){const t=U.Current;try{U.Current=this.context,this.dispatchEvent(e)}finally{U.Current=t}}}const ua=new c.Matrix4().makeRotationY(Math.PI),ki=new c.Quaternion().setFromAxisAngle(new c.Vector3(0,1,0),Math.PI),sC=x("debugwebxr");class oC{priority=-1e5;gameObject;isXRRig(){return!0}get isActive(){return this.gameObject.visible}constructor(){if(this.gameObject=new c.Object3D,this.gameObject.name="Implicit XR Rig",sC){const e=Bm(16733661);e.position.y+=.5,this.gameObject.add(e)}}}const Gn=x("debugwebxr"),Oh=x("debugcustomgesture"),rC="https://cdn.jsdelivr.net/npm/@webxr-input-profiles/assets@1.0/dist/profiles",aC="generic-trigger",lC=new c.Quaternion().setFromEuler(new c.Euler(c.MathUtils.degToRad(0),c.MathUtils.degToRad(-90),c.MathUtils.degToRad(-90))),cC=new c.Vector3(.04,-.04,0);class Tm{xr;get context(){return this.xr.context}inputSource;index=0;emitEvents=!0;get connected(){return this._connected}_connected=!0;get isTracking(){return this._isTracking}_isTracking=!1;get gamepad(){return this.__gamepad??=this.inputSource.gamepad}__gamepad;get isHand(){return this.hand!=null}get hand(){return this.__hand??=this.inputSource.hand}__hand;get handObject(){return this.context.renderer.xr.getHand(this.index)}get profiles(){return this.inputSource.profiles}get layout(){return this._layout}get targetRayMode(){return this.inputSource.targetRayMode}get targetRaySpace(){return this.inputSource.targetRaySpace}get gripSpace(){return this.inputSource.gripSpace}get side(){return this.__side??=this.inputSource.handedness}__side=void 0;get isRight(){return this.side==="right"}get isLeft(){return this.side==="left"}get isStylus(){return this._isMxInk}getHitTestSource(){return this._hitTestSource||this._requestHitTestSource(),this._hitTestSource}get hasHitTestSource(){return this._hitTestSource}cancelHitTestSource(){this._hitTestSource&&(this._hitTestSource.cancel(),this._hitTestSource=void 0)}_hitTestSource=void 0;_hasSelectEvent=!1;get hasSelectEvent(){return this._hasSelectEvent}_isMxInk=!1;_isMetaQuestTouchController=!1;getHitTest(){return this.xr.getHitTest(this)}_handJointPoses=new Map;getHandJointPose(e,t){if(t=t||this.xr.frame,!this.hand||!t?.getJointPose||!this.xr.referenceSpace)return null;let i=this._handJointPoses?.get(e);return i||(i=t.getJointPose(e,this.xr.referenceSpace),i&&this._handJointPoses.set(e,i),i)}_gripMatrix=new c.Matrix4;_gripPosition=new c.Vector3;_gripQuaternion=new c.Quaternion;_linearVelocity=new c.Vector3;_rayPositionRaw=new c.Vector3;_rayRotationRaw=new c.Quaternion;_rayMatrix=new c.Matrix4;_rayPosition=new c.Vector3;_rayQuaternion=new c.Quaternion;get gripPosition(){return j(this._gripPosition)}get gripQuaternion(){return Kt(this._gripQuaternion)}get gripMatrix(){return this._gripMatrix}get gripLinearVelocity(){return j(this._linearVelocity).applyQuaternion(ki)}get rayPosition(){return j(this._rayPosition)}get rayQuaternion(){return Kt(this._rayQuaternion)}get gripWorldPosition(){return j(this._gripWorldPosition)}_gripWorldPosition=new c.Vector3;get gripWorldQuaternion(){return Kt(this._gripWorldQuaternion)}_gripWorldQuaternion=new c.Quaternion;get rayWorldPosition(){return j(this._rayWorldPosition)}_rayWorldPosition=new c.Vector3;updateRayWorldPosition(){const e=this.xr.context.mainCamera?.parent;this._rayWorldPosition.copy(this._rayPositionRaw),e&&this._rayWorldPosition.applyMatrix4(e.matrixWorld)}get rayWorldQuaternion(){return Kt(this._rayWorldQuaternion)}_rayWorldQuaternion=new c.Quaternion;get pinchPosition(){return j(this._pinchPosition)}_pinchPosition=new c.Vector3;updateRayWorldQuaternion(){const e=this.xr.context.mainCamera?.parent,t=e?fe(e):void 0;this._rayWorldQuaternion.copy(this._rayRotationRaw).multiply(ki),t&&this._rayWorldQuaternion.premultiply(t)}get ray(){return this._ray.origin.copy(this.rayWorldPosition),this._ray.direction.copy(j(0,0,1).applyQuaternion(this.rayWorldQuaternion)),this._ray}_ray;_hand_wristDotUp=void 0;get handWristDotUp(){if(this._hand_wristDotUp!==void 0)return this._hand_wristDotUp;const e=this.handObject?.joints.wrist;if(e){const t=j(0,1,0).applyQuaternion(e.quaternion),i=j(0,1,0).dot(t);return this._hand_wristDotUp=i}}get isHandUpsideDown(){return this.handWristDotUp!==void 0?this.handWristDotUp<-.7:!1}get isTeleportGesture(){return this.isHandUpsideDown&&this.getGesture("pinch")?.isDown}get object(){return this._object}_object;_gripSpaceObject;_raySpaceObject;model=null;_debugAxesHelper=new c.AxesHelper(.15);_debugGripAxesHelper=new c.AxesHelper(.07);_debugRayAxesHelper=new c.AxesHelper(.07);async getModelUrl(){return this.getMotionController?.then(e=>e?.assetUrl||null)}constructor(e,t,i){this.xr=e,this.inputSource=t,this.index=i,this._object=new c.Object3D,this._object.name=`NeedleXRController_${i}`,Gn&&(this._object.add(this._debugAxesHelper),this._gripSpaceObject=new c.Object3D,this._raySpaceObject=new c.Object3D,this._gripSpaceObject.name=`NeedleXRController_${i}_gripSpace`,this._raySpaceObject.name=`NeedleXRController_${i}_raySpace`,this._gripSpaceObject.add(this._debugGripAxesHelper),this._raySpaceObject.add(this._debugRayAxesHelper),this.xr.context.scene.add(this._gripSpaceObject),this.xr.context.scene.add(this._raySpaceObject)),this.xr.context.scene.add(this._object),this._ray=new c.Ray,this.pointerInit={origin:this,pointerType:this.hand?"hand":"controller",deviceIndex:this.index,pointerId:-1,mode:this.inputSource.targetRayMode,ray:this._ray,device:this._object,buttonName:"none"},this.initialize(),this.subscribeEvents()}_hitTestSourcePromise=null;_requestHitTestSource(){return this._hitTestSourcePromise?this._hitTestSourcePromise:this.xr.mode==="immersive-ar"&&this.inputSource.targetRayMode==="tracked-pointer"&&this.xr.session.requestHitTestSourceForTransientInput?this._hitTestSourcePromise=this.xr.session.requestHitTestSourceForTransientInput({profile:this.inputSource.profiles[0],offsetRay:new XRRay})?.then(e=>(this._hitTestSourcePromise=null,this.connected?this._hitTestSource=e:(e.cancel(),null)))??null:null}onPointerHits=e=>{};onUpdate(e){this.onUpdateFrame(e),this.updateInputEvents(),this.onUpdateMove()}onRenderDebug(){B.DrawSphere(this.rayWorldPosition,.003),B.DrawDirection(this.rayWorldPosition,j(0,0,10).applyQuaternion(this.rayWorldQuaternion));const t=(this.inputSource.gripSpace?this.gripWorldPosition:this.object.worldPosition).sub(this.object.worldForward.multiplyScalar(.1)),i=this.inputSource.profiles.join(`
146
146
  `);let n=`Controller[${this.index}] (${this.inputSource.targetRayMode}, ${this.side})
147
147
  C:${this.connected?"x":"-"} T:${this.isTracking?"x":"-"} Hand:${this.inputSource.hand?"x":"-"} Pen: ${this._isMxInk?"x":"-"}`;if(this.inputSource.hand&&(n+=`
@@ -165,7 +165,7 @@ See https://engine.needle.tools/docs/scripting.html#special-lifecycle-hooks for
165
165
  `+xi):console.debug("Connected to networking backend",xi),n(!0),this.onSendQueued(en.OnConnection)}).onClose(h=>{this._connectingToWebsocketPromise=null,this.connected=!1,this._isInRoom=!1,n(!1);let d="Websocket connection closed...";xi?.includes("/socket")||(d+=' Do you perhaps mean to connect to "/socket"?'),console.error(d)}).onError(h=>{console.error("Websocket connection failed..."),n(!1)}).onRetry(()=>{console.log("Retry connecting to networking websocket")}).build();l.addEventListener(o.WebsocketEvent.message,(h,d)=>{this.onMessage(h,d)})})}onMessage(e,t){const i=t.data;try{if(typeof i!="string"){i.size&&this.handleIncomingBinaryMessage(i);return}const n=JSON.parse(i);if(Array.isArray(n))for(const o of n)this.handleIncomingStringMessage(o);else this.handleIncomingStringMessage(n);return}catch(n){Ht&&i==="pong"?console.log("<<",i):R()&&console.error("Failed to parse message",n)}}async handleIncomingBinaryMessage(e){kh&&console.log("<< bin",this.context.time.frame);const t=await e.arrayBuffer();var i=new Uint8Array(t);const n=new re.ByteBuffer(i),o=n.getBufferIdentifier(),r=this._listenersBinary[o],a=mv(n),l=gv(a);if(l&&typeof l=="string"&&(this._state[l]=a),!r)return;const h=a??n;for(const d of r)d(h)}handleIncomingStringMessage(e){if(Ht&&console.log("<<",e.key??e),e.key)switch(e.key){case"connection-start-info":if(e.data){const r=e.data;r&&(console.assert(r.id!==void 0&&r.id!==null&&r.id.length>0,"server did not send connection id",r.id),console.debug("Your id is: "+r.id,this.context.alias??""),this._connectionId=r.id)}else console.warn("Expected connection id in "+e.key);break;case"joined-room":if(Ht&&console.log(e),e){this._isInRoom=!0;const r=e;this._currentRoomName=r.room,this._currentRoomViewId=r.viewId,this._currentRoomAllowEditing=r.allowEditing??!0,this._currentInRoom.length=0,this._currentInRoom.push(...r.inRoom),(kh||R())&&console.debug("Joined Needle Engine Room: "+r.room);const a=new URL(window.location.href);a.searchParams.has("room")&&a.searchParams.delete("room"),a.searchParams.set("view",this._currentRoomViewId),console.debug(`Room view id: ${this._currentRoomViewId}
166
166
  ${a.href}`)}this.onSendQueued(en.OnRoomJoin);break;case"left-room":const n=e;n.room===this.currentRoomName&&(this._isInRoom=!1,this._currentRoomName=null,this._currentRoomAllowEditing=!0,this._currentInRoom.length=0,(kh||R())&&console.debug("Left Needle Engine Room: "+n.room));break;case"user-joined-room":if(e.data){const r=e.data;this._currentInRoom.push(r.userId),Ht&&console.log(r.userId+" joined","now in room:",this._currentInRoom)}break;case"user-left-room":if(e.data){const r=e.data,a=this._currentInRoom.indexOf(r.userId);a>=0&&(Ht&&console.log(r.userId+" left","now in room:",this._currentInRoom),this._currentInRoom.splice(a,1)),r.userId===this.connectionId&&console.log("you left the room")}break;case"all-room-state-deleted":Ht&&console.log("RECEIVED all-room-state-deleted"),this._state={};break;case"ping":case"pong":const o=e.data?.time;o&&(this._currentDelay=this.context.time.time-o),Ht&&console.log(`Current latency: ${(this._currentDelay*1e3).toFixed()} ms`,"Clients in room: "+this._currentInRoom?.length);break}const t=e.data;t&&(this._state[t.guid]=t);let i=this._listeners[e.key];if(i){i=[...i];for(const n of i)try{n(e.data)}catch(o){console.error('Error invoking callback for "'+e.key+'"',o)}}}toMessage(e,t){return{key:e,data:t}}sendWithWebsocket(e,t,i=en.OnRoomJoin){if(!this._ws){const o=this._waitingForSocket[i]||[];o.push(()=>this.sendWithWebsocket(e,t,i)),this._waitingForSocket[i]=o;return}const n=JSON.stringify(this.toMessage(e,t));Ht&&console.log(">>",e),this._ws.send(n)}onSendQueued(e){const t=this._waitingForSocket[e];if(t){for(const i of t)i();t.length=0}}}const Wl=x("debugwebxr");class mf{controllerStates=[];userId;context;userStateEvtName;constructor(e,t){this.userId=e,this.context=t,this.userStateEvtName="xr-sync-user-state-"+e,this.context.connection.beginListen(this.userStateEvtName,this.onReceivedControllerState)}dispose(){this.context.connection.stopListen(this.userStateEvtName,this.onReceivedControllerState)}onReceivedControllerState=e=>{Wl&&console.log(`XRSync: Received change for ${this.userId}: ${e.type} ${e.handedness}; tracked=${e.isTracking}`);let t=!1;for(let i=0;i<this.controllerStates.length;i++)if(this.controllerStates[i].index===e.index){this.controllerStates[i]=e,t=!0;break}t||this.controllerStates.push(e)};update(e){if(this.context.connection.isConnected!=!1){for(let t=this.controllerStates.length-1;t>=0;t--){const i=this.controllerStates[t];let n=!1;for(let o=0;o<e.controllers.length;o++)e.controllers[o].index===i.index&&(n=!0);n||(Wl&&console.log(`XRSync: ${i.type} ${i.handedness} removed`,i.index),this.controllerStates.splice(t,1),this.sendControllerRemoved(i))}for(const t of e.controllers)this.updateControllerStates(t)}}onExitXR(e){for(const t of this.controllerStates)this.sendControllerRemoved(t);this.controllerStates.length=0}sendControllerRemoved(e){e.isTracking=!1,e.guid="",this.context.connection.send(this.userStateEvtName,e),this.context.connection.sendDeleteRemoteState(e.guid)}updateControllerStates(e){const t=this.controllerStates.find(i=>i.index===e.index);if(t){let i=!1;i||=t.isTracking!=e.isTracking,i&&(t.isTracking=e.isTracking,this.context.connection.send(this.userStateEvtName,t))}else{const i={guid:this.userId+"-"+e.index,isTracking:e.isTracking,handedness:e.side,index:e.index,type:e.hand?"hand":"controller"};this.controllerStates.push(i),this.context.connection.send(this.userStateEvtName,i),Wl&&console.log(`XRSync: ${i.type} ${i.handedness} added`,i.index)}}}class xv{hasState(e){return e?this._states.has(e):!1}isTracking(e,t){if(!e)return;const i=this._states.get(e);return i?i.controllerStates.find(o=>o.handedness===t)?.isTracking||!1:void 0}getDeviceType(e,t){if(!e)return;const i=this._states.get(e);return i?i.controllerStates.find(o=>o.handedness===t)?.type||"unknown":void 0}context;constructor(e){this.context=e,this.context.connection.beginListen(Y.JoinedRoom,this.onJoinedRoom),this.context.connection.beginListen(Y.LeftRoom,this.onLeftRoom),this.context.connection.beginListen(Y.UserJoinedRoom,this.onOtherUserJoinedRoom),this.context.connection.beginListen(Y.UserLeftRoom,this.onOtherUserLeftRoom)}destroy(){this.context.connection.stopListen(Y.JoinedRoom,this.onJoinedRoom),this.context.connection.stopListen(Y.LeftRoom,this.onLeftRoom),this.context.connection.stopListen(Y.UserJoinedRoom,this.onOtherUserJoinedRoom),this.context.connection.stopListen(Y.UserLeftRoom,this.onOtherUserLeftRoom)}onJoinedRoom=()=>{if(this.context.connection.connectionId){this._states.has(this.context.connection.connectionId)||(Wl&&console.log("XRSync: Local user joined room",this.context.connection.connectionId),this._states.set(this.context.connection.connectionId,new mf(this.context.connection.connectionId,this.context)));for(const e of this.context.connection.usersInRoom())this._states.has(e)||this._states.set(e,new mf(e,this.context))}};onLeftRoom=()=>{this.context.connection.connectionId&&(this._states.has(this.context.connection.connectionId)||(this._states.get(this.context.connection.connectionId)?.dispose(),this._states.delete(this.context.connection.connectionId)))};onOtherUserJoinedRoom=e=>{const t=e.userId;this._states.has(t)||(Wl&&console.log("XRSync: Remote user joined room",t),this._states.set(t,new mf(t,this.context)))};onOtherUserLeftRoom=e=>{const t=e.userId;this._states.has(t)||(this._states.get(t)?.dispose(),this._states.delete(t))};_states=new Map;onUpdate(e){this.context.connection.isConnected&&this.context.connection.connectionId&&this._states.get(this.context.connection.connectionId)?.update(e)}onExitXR(e){this.context.connection.isConnected&&this.context.connection.connectionId&&this._states.get(this.context.connection.connectionId)?.onExitXR(e)}}class Ky{_fadeToColorQuad;_fadeToColorMaterial;constructor(){this._fadeToColorMaterial=new c.MeshBasicMaterial({color:0,transparent:!0,depthTest:!1,fog:!1,side:c.DoubleSide}),this._fadeToColorQuad=new c.Mesh(new c.PlaneGeometry(10,10),this._fadeToColorMaterial)}dispose(){this._fadeToColorQuad.geometry.dispose(),this._fadeToColorMaterial.dispose()}update(e,t){const i=this._fadeToColorQuad,n=this._fadeToColorMaterial;i.parent!==e&&n.opacity>0?e.add(i):n.opacity===0&&i.removeFromParent(),i.layers.set(2),i.material=this._fadeToColorMaterial,i.position.z=-1,i.renderOrder=1/0;const o=this._requestedFadeValue;n.opacity=L.lerp(n.opacity,o,t/.03),Math.abs(n.opacity-o)<=.01&&this._transitionResolve&&(this._transitionResolve(),this._transitionResolve=null,this._transitionPromise=null,this._requestedFadeValue=0)}remove(){this._fadeToColorQuad.removeFromParent()}fadeTransition(){if(this._transitionPromise)return this._transitionPromise;this._requestedFadeValue=1;const e=new Promise(t=>{this._transitionResolve=t});return this._transitionPromise=e,e}_requestedFadeValue=0;_transitionPromise=null;_transitionResolve=null}var sr=(s=>(s[s.Quad=0]="Quad",s[s.Cube=1]="Cube",s[s.Sphere=2]="Sphere",s[s.Cylinder=3]="Cylinder",s[s.RoundedCube=10]="RoundedCube",s))(sr||{});class mr{static createText(e,t){let i=null;const n=t?.font||_C(t?.familyFamily||null);n instanceof q.Font?i=this.#t(e,n,t):i==null&&(i=new c.BufferGeometry);const o=t?.color||16777215,r=new c.Mesh(i,t?.material??new c.MeshStandardMaterial({color:o}));return this.applyDefaultObjectOptions(r,t),n instanceof Promise?n.then(a=>{r.geometry=this.#t(e,a,t),t?.onGeometry&&t.onGeometry(r)}):t?.onGeometry&&t.onGeometry(r),r}static#t(e,t,i){const n=i?.depth||.1;return new q.TextGeometry(e,{font:t,size:1,depth:n,height:n,bevelEnabled:i?.bevel||!1,bevelThickness:.01,bevelOffset:.01,bevelSize:.01})}static createOccluder(e){const t=new c.MeshBasicMaterial({colorWrite:!1,depthWrite:!0,side:c.DoubleSide});return this.createPrimitive(e,{material:t})}static createPrimitive(e,t){let i;const n=t?.color||16777215;switch(e){case"Quad":case 0:{const o=new c.PlaneGeometry(1,1,1,1),r=t?.material??new c.MeshStandardMaterial({color:n});t?.texture&&"map"in r&&(r.map=t.texture),i=new c.Mesh(o,r),i.name="Quad"}break;case"Cube":case 1:{const o=new c.BoxGeometry(1,1,1),r=t?.material??new c.MeshStandardMaterial({color:n});t?.texture&&"map"in r&&(r.map=t.texture),i=new c.Mesh(o,r),i.name="Cube"}break;case 10:case"RoundedCube":{const o=yC(1,1,1,.1,2),r=t?.material??new c.MeshStandardMaterial({color:n});t?.texture&&"map"in r&&(r.map=t.texture),i=new c.Mesh(o,r),i.name="RoundedCube"}break;case"Sphere":case 2:{const o=new c.SphereGeometry(.5,16,16),r=t?.material??new c.MeshStandardMaterial({color:n});t?.texture&&"map"in r&&(r.map=t.texture),i=new c.Mesh(o,r),i.name="Sphere"}break;case"Cylinder":case 3:{const o=new c.CylinderGeometry(.5,.5,1,32),r=t?.material??new c.MeshStandardMaterial({color:n});t?.texture&&"map"in r&&(r.map=t.texture),i=new c.Mesh(o,r),i.name="Cylinder"}break;case"ShaderBall":i=new c.Group,i.name="ShaderBall",bC(i,t);break}return this.applyDefaultObjectOptions(i,t),i}static createSprite(e){const i=new c.SpriteMaterial({color:16777215});e?.texture&&"map"in i&&(i.map=e.texture);const n=new c.Sprite(i);return this.applyDefaultObjectOptions(n,e),n}static applyDefaultObjectOptions(e,t){e.receiveShadow=!0,e.castShadow=!0,t?.name&&(e.name=t.name),t?.position&&(Array.isArray(t.position)?e.position.set(t.position[0],t.position[1],t.position[2]):e.position.set(t.position.x||0,t.position.y||0,t.position.z||0)),t?.rotation&&(Array.isArray(t.rotation)?e.rotation.set(t.rotation[0],t.rotation[1],t.rotation[2]):e.rotation.set(t.rotation.x||0,t.rotation.y||0,t.rotation.z||0)),t?.scale&&(typeof t.scale=="number"?e.scale.set(t.scale,t.scale,t.scale):Array.isArray(t.scale)?e.scale.set(t.scale[0],t.scale[1],t.scale[2]):e.scale.set(t.scale.x||1,t.scale.y||1,t.scale.z||1)),t?.receiveShadow!=null&&(e.receiveShadow=t.receiveShadow),t?.castShadow!=null&&(e.castShadow=t.castShadow),t?.parent&&t.parent.add(e)}}function yC(s,e,t,i,n){const o=new c.Shape,r=1e-5,a=i-r;o.absarc(r,r,r,-Math.PI/2,-Math.PI,!0),o.absarc(r,e-a*2,r,Math.PI,Math.PI/2,!0),o.absarc(s-a*2,e-a*2,r,Math.PI/2,0,!0),o.absarc(s-a*2,r,r,0,-Math.PI/2,!0);const l=new c.ExtrudeGeometry(o,{bevelEnabled:!0,bevelSegments:n*2,steps:1,bevelSize:a,bevelThickness:i,curveSegments:n,UVGenerator:{generateTopUV:(h,d)=>{const u=[];for(let p=0;p<d.length;p+=3)u.push(new c.Vector2(d[p]/s,d[p+1]/e));return u},generateSideWallUV:(h,d,u,p,m,y)=>{const _=[];return _.push(new c.Vector2(d[u]/s,d[u+1]/e)),_.push(new c.Vector2(d[p]/s,d[p+1]/e)),_.push(new c.Vector2(d[m]/s,d[m+1]/e)),_.push(new c.Vector2(d[y]/s,d[y+1]/e)),_}}});return l.scale(1,1,1-i),l.center(),l.index||l.setIndex(Array.from({length:l.attributes.position.count},(h,d)=>d)),l.computeVertexNormals(),l}const Eh=new Map;function _C(s){let e="";switch(s){default:case"OpenSans":e="https://cdn.needle.tools/static/fonts/facetype/Open Sans_Regular_ascii.json";break;case"Helvetiker":e="https://raw.githubusercontent.com/mrdoob/three.js/master/examples/fonts/helvetiker_regular.typeface.json";break}if(Eh.has(e)){const n=Eh.get(e);if(n)return n}const t=new q.FontLoader,i=new Promise((n,o)=>{t.load(e,r=>{Eh.set(e,r),n(r)},void 0,o)});return Eh.set(e,i),i}let gf=!1,yf=null;function bC(s,e){if(yf===null){const t="https://cdn.needle.tools/static/models/shaderball.glb",i=new q.GLTFLoader,n=se.createLoaders(null);i.setDRACOLoader(n.dracoLoader),i.setKTX2Loader(n.ktx2Loader),gf=!0,yf=i.loadAsync(t).then(o=>{const r=o.scene;return r.position.y-=.5,r}).catch(o=>(console.warn("Failed to load shaderball mesh: "+o.message),Jy())).finally(()=>{gf=!1})}if(gf){const t=Jy();t.name="ShaderBall-Placeholder";const i=t.children[0];i?.type==="Mesh"&&Zy(i,e),s.add(t)}yf.then(t=>{s.children.forEach(o=>{o.name==="ShaderBall-Placeholder"&&s.remove(o)});const i=t.clone(),n=i.children[0];n?.type==="Mesh"&&(n.geometry.attributes.tangent||n.geometry.computeTangents(),Zy(n,e)),s.add(i)})}function Zy(s,e){if(e?.color||e?.material||e?.texture){const i=e?.material??s.material?.clone()??new c.MeshStandardMaterial;e.color&&"color"in i&&i.color instanceof c.Color&&i.color.set(e.color),e?.texture&&"map"in i&&(i.map=e.texture),s.material=i}}function Jy(){return new c.Group().add(mr.createPrimitive("Sphere",{material:new c.MeshBasicMaterial({transparent:!0,opacity:.1})}))}class Ca{static _active=null;static get active(){return this._active}static _requestInFlight=!1;static async start(e,t){if(this._active)return console.error("Cannot start a new XR session while one is already active"),null;if(this._requestInFlight)return console.error("Cannot start a new XR session while a request is already in flight"),null;if("xr"in navigator&&navigator.xr){if(!t)return console.error("XRSessionInit must be provided"),null;this._requestInFlight=!0;const i=await navigator.xr.requestSession(e,t).catch(n=>{console.error("Failed to start temporary XR session:",n)});return i?(i.addEventListener("end",()=>{this._active=null}),this._requestInFlight?(this._requestInFlight=!1,this._active=new Ca(e,t,i),this._active):(i.end(),null)):(this._requestInFlight=!1,null)}return null}static async handoff(){return this._active?this._active.handoff():null}static async stop(){this._requestInFlight=!1,this._active&&(await this._active.end(),await ds(100)),this._active=null}_session;_mode;_init;get isAR(){return this._mode==="immersive-ar"}_renderer;_camera;_scene;constructor(e,t,i){this._mode=e,this._init=t,this._session=i,this._session.addEventListener("end",this.onEnd),this._renderer=new c.WebGLRenderer({alpha:!0,antialias:!0}),this._renderer.outputColorSpace="srgb",this._renderer.setAnimationLoop(this.onFrame),this._renderer.xr.setSession(i),this._renderer.xr.enabled=!0,this._renderer.setPixelRatio(Math.min(2,window.devicePixelRatio)),this._renderer.setSize(window.innerWidth,window.innerHeight),this._camera=new c.PerspectiveCamera,this._scene=new c.Scene,this._scene.fog=new c.Fog(4473924,10,250),this._scene.add(this._camera),this.setupScene()}end(){return this._session?this._session.end():Promise.resolve()}async handoff(){if(!this._session)throw new Error("Cannot handoff a session that has already ended");const e={session:this._session,mode:this._mode,init:this._init};return await this.onBeforeHandoff(),this.onEnd(),this._session=null,e}onEnd=()=>{this._session?.removeEventListener("end",this.onEnd),this._renderer.setAnimationLoop(null),this._renderer.dispose(),this._scene.clear()};_lastTime=0;onFrame=(e,t)=>{const i=e-this._lastTime;this.update(e,i),this._camera.parent!==this._scene&&this._scene.add(this._camera),this._renderer.render(this._scene,this._camera)};async onBeforeHandoff(){await ds(1e3),this._scene.clear()}_objects=[];setupScene(){this._scene.background=new c.Color(0),this._scene.add(new c.GridHelper(5,10,1118481,1118481));const e=new c.DirectionalLight(16777215,1);e.position.set(0,20,0),e.castShadow=!1,this._scene.add(e);const t=new c.DirectionalLight(16777215,1);t.position.set(0,-1,0),t.castShadow=!1,this._scene.add(t);const i=new c.PointLight(16777215,1,100,1);i.position.set(0,2,0),i.castShadow=!1,i.distance=200,this._scene.add(i);const n=50;for(let o=0;o<100;o++){const r=new c.MeshStandardMaterial({color:2236962,metalness:1,roughness:.8});this.isAR&&(r.emissive=new c.Color(Math.random(),Math.random(),Math.random()),r.emissiveIntensity=Math.random());const a=L.random(0,1)>.5?sr.Sphere:sr.Cube,l=mr.createPrimitive(a,{material:r});l.position.x=L.random(-n,n),l.position.y=L.random(-2,n),l.position.z=L.random(-n,n),l.rotation.x=L.random(0,Math.PI*2),l.rotation.y=L.random(0,Math.PI*2),l.rotation.z=L.random(0,Math.PI*2),l.scale.multiplyScalar(.5+Math.random()*10);const h=l.position.distanceTo(this._camera.position)-l.scale.x;h<1&&l.position.multiplyScalar(1+1/h),this._objects.push(l),this._scene.add(l)}}update(e,t){const i=e*4e-4;for(let n=0;n<this._objects.length;n++){const o=this._objects[n];o.position.y+=Math.sin(i+n*.5)*.005,o.rotateY(.002)}}}var ac;(s=>{const e=[];function t(){e?.length||R()&&console.warn("No USDZ exporters found – cannot export USDZ for QuickLook.");for(const o of e)o.exportAndOpen();return!0}s.exportAndOpen=t;function i(o){e.push(o)}s.registerExporter=i;function n(o){if(!e)return;const r=e.indexOf(o);r>=0&&e.splice(r,1)}s.unregisterExporter=n})(ac||(ac={}));const Ie=x("debugwebxr"),e_=x("stats");let _f=0;function vC(s){let e=null;const t=s;return t.getAROverlayContainer?e=t.getAROverlayContainer():e=s,e}wC();async function wC(){let s="immersive-vr";try{if(exports.DeviceUtilities.isNeedleAppClip()?s="immersive-ar":await navigator.xr?.isSessionSupported("immersive-vr")||(s="immersive-ar"),!await navigator.xr?.isSessionSupported("immersive-ar")&&s==="immersive-ar")return}catch(e){console.debug("[NeedleXRSession:granted] Error while checking XR support:",e);return}if(x("debugasap")){let e=globalThis["needle:XRSession"];if(e instanceof Promise){delete globalThis["needle:XRSession"],le.addContextCreatedCallback(async t=>{if(!e)return;da(!0);const i=await e;if(i){const n=H.getDefaultSessionInit(s);H.setSession(s,i,n,t.context)}else console.error("[NeedleXRSession:granted] ASAP session was rejected");e=void 0});return}}if("xr"in navigator){if(/WebXRViewer\//i.test(navigator.userAgent)){console.warn("WebXRViewer does not support addEventListener");return}navigator.xr?.addEventListener("sessiongranted",async()=>{const e=sessionStorage.getItem("needle_xr_session_mode"),t=sessionStorage.getItem("needle_xr_session_init")??null,i=t?JSON.parse(t):null;let n=null;if(Sv()&&(await Ca.start(e||s,i||H.getDefaultSessionInit(s)).catch(o=>console.warn("[NeedleXRSession:granted] TemporaryXRContext start failed:",o)),await CC(),n=await Ca.handoff()),n)H.setSession(n.mode,n.session,n.init,U.Current);else if(e&&t){console.log("[NeedleXRSession:granted] Restore last session");const o=JSON.parse(t);H.start(e,o).catch(r=>console.warn(r))}else H.start(s).catch(o=>console.warn("[NeedleXRSession:granted] failed:",o))},{once:!0})}}function xC(s,e){sessionStorage.setItem("needle_xr_session_mode",s),sessionStorage.setItem("needle_xr_session_init",JSON.stringify(e))}function SC(){sessionStorage.removeItem("needle_xr_session_mode"),sessionStorage.removeItem("needle_xr_session_init")}const jm=new Set;le.registerCallback(ae.ContextCreationStart,async s=>{jm.add(s.context)});le.registerCallback(ae.ContextCreated,async s=>{jm.delete(s.context);const e=s.context?.domElement.getAttribute("autostart")||null;PC(e)});function Sv(){return jm.size>0}function CC(){return new Promise(s=>{const e=Date.now(),t=setInterval(()=>{(!Sv()||Date.now()-e>6e4)&&(clearInterval(t),s())},100)})}exports.DeviceUtilities.isDesktop()&&R()&&window.addEventListener("keydown",s=>{(s.key==="x"||s.key==="Escape")&&H.active&&H.stop()});function PC(s){s&&s?.toLowerCase()==="ar"&&ln.registerWaitForInteraction(()=>{H.start("ar")})}const Rh=Symbol("initial-fov");class H{static _sync=null;static getXRSync(e){return this._sync||(this._sync=new xv(e)),this._sync}static get currentSessionRequest(){return this._currentSessionRequestMode}static _currentSessionRequestMode=null;static get active(){return this._activeSession}static get activeMode(){return this._activeSession?.mode??null}static get xrSystem(){return"xr"in navigator?navigator.xr:void 0}static isXRSupported(){return Promise.all([this.isVRSupported(),this.isARSupported()]).then(e=>e.some(t=>t)).catch(()=>!1)}static isVRSupported(){return this.isSessionSupported("immersive-vr")}static isARSupported(){return this.isSessionSupported("immersive-ar")}static isSessionSupported(e){return this.xrSystem?.isSessionSupported(e).catch(t=>(Ie&&console.error(t),!1))??Promise.resolve(!1)}static _currentSessionRequest;static _activeSession;static onSessionRequestStart(e){this._sessionRequestStartListeners.push(e)}static offSessionRequestStart(e){const t=this._sessionRequestStartListeners.indexOf(e);t>=0&&this._sessionRequestStartListeners.splice(t,1)}static _sessionRequestStartListeners=[];static onSessionRequestEnd(e){this._sessionRequestEndListeners.push(e)}static offSessionRequestEnd(e){const t=this._sessionRequestEndListeners.indexOf(e);t>=0&&this._sessionRequestEndListeners.splice(t,1)}static _sessionRequestEndListeners=[];static onXRSessionStart(e){this._xrStartListeners.push(e)}static offXRSessionStart(e){const t=this._xrStartListeners.indexOf(e);t>=0&&this._xrStartListeners.splice(t,1)}static _xrStartListeners=[];static onXRSessionEnd(e){this._xrEndListeners.push(e)}static offXRSessionEnd(e){const t=this._xrEndListeners.indexOf(e);t>=0&&this._xrEndListeners.splice(t,1)}static _xrEndListeners=[];static onControllerAdded(e){this._controllerAddedListeners.push(e)}static offControllerAdded(e){const t=this._controllerAddedListeners.indexOf(e);t>=0&&this._controllerAddedListeners.splice(t,1)}static _controllerAddedListeners=[];static onControllerRemoved(e){this._controllerRemovedListeners.push(e)}static offControllerRemoved(e){const t=this._controllerRemovedListeners.indexOf(e);t>=0&&this._controllerRemovedListeners.splice(t,1)}static _controllerRemovedListeners=[];static offerSession(e,t,i){return"xr"in navigator&&navigator.xr&&"offerSession"in navigator.xr?(typeof navigator.xr.offerSession=="function"&&(console.log("WebXR offerSession is available - requesting mode: "+e),t=="default"&&(t=this.getDefaultSessionInit(e)),navigator.xr.offerSession(e,{...t}).then(n=>H.setSession(e,n,t,i)).catch(n=>{console.log("XRSession offer rejected (perhaps because another call to offerSession was made or a call to requestSession was made)")})),!0):!1}static getDefaultSessionInit(e){switch(e){case"immersive-ar":const t=["anchors","local-floor","layers","dom-overlay","hit-test","unbounded"];return exports.DeviceUtilities.isVisionOS()||t.push("hand-tracking"),{optionalFeatures:t};case"immersive-vr":const i=["local-floor","bounded-floor","high-fixed-foveation-level","layers"];return exports.DeviceUtilities.isVisionOS()||i.push("hand-tracking"),{optionalFeatures:i};default:return console.warn("No default session init for mode",e),{}}}static async start(e,t,i){if(exports.DeviceUtilities.isiOS()){const a=await this.isARSupported().catch(()=>!1);if(exports.DeviceUtilities.isVisionOS()&&!a&&(e==="ar"||e==="immersive-ar")&&(e="quicklook"),e==="quicklook")return Qs.sendEvent(U.Current,"xr",{action:"quicklook_export",source:"NeedleXRSession.start"}),ac.exportAndOpen(),null;if(!a&&(e==="immersive-ar"||e==="ar")){const l=new URL("https://appclip.apple.com/id?p=tools.needle.launch-app.Clip");l.searchParams.set("url",location.href);const h=l.toString();Qs.sendEvent(U.Current,"xr",{action:"app_clip_launch",source:"NeedleXRSession.start",url:h});const d=window.top||window;try{console.debug("iOS device detected - opening Needle App Clip for AR experience",{mode:e,init:t,url:l}),d.location.href=h}catch(u){console.warn("Error navigating to AppClip "+h+`
167
167
  `,u),window!==window.top?window.open(h,"_blank"):window.location.href=h}return null}}if(e==="quicklook")return console.warn("QuickLook mode is only supported on iOS devices"),null;if(e=="ar"&&(e="immersive-ar"),R()&&x("debugxrpreroom"))return console.warn("Debug: Starting temporary XR session"),await Ca.start(e,t||H.getDefaultSessionInit(e)),null;if(this._currentSessionRequest)return console.warn("A XRSession is already being requested"),(Ie||R())&&ue("A XRSession is already being requested"),this._currentSessionRequest.then(()=>this._activeSession);if(this._activeSession)return console.error("A XRSession is already running"),this._activeSession;if(i||(i=U.Current),i||(i=le.All[0]),!i)throw new Error("No Needle Engine Context found");switch(t||(t={}),e){case"immersive-ar":{if(await this.xrSystem?.isSessionSupported("immersive-ar")!==!0)return console.error(e+" is not supported by this browser."),null;const l=this.getDefaultSessionInit(e),h=vC(i.domElement);h&&!exports.DeviceUtilities.isQuest()&&(l.domOverlay={root:h},l.optionalFeatures.push("dom-overlay")),t={...l,...t}}break;case"immersive-vr":{if(await this.xrSystem?.isSessionSupported("immersive-vr")!==!0)return console.error(e+" is not supported by this browser."),null;t={...this.getDefaultSessionInit(e),...t}}break;default:console.warn("No default session init for mode",e);break}t.optionalFeatures??=[],t.requiredFeatures??=[],await Ca.stop();const n=e=="immersive-ar"?i.scripts_immersive_ar:i.scripts_immersive_vr;Ie?console.log(`%cRequesting ${e} session`,"font-weight:bold;",t,n):console.log(`%cRequesting ${e} session`,"font-weight:bold;");for(const a of n)a.onBeforeXR&&a.activeAndEnabled&&!a.destroyed&&a.onBeforeXR(e,t);for(const a of this._sessionRequestStartListeners)a({mode:e,init:t});Ie&&Pe("Requesting "+e+" session ("+Date.now()+")"),Qs.sendEvent(U.Current,"xr",{action:"session_request",mode:e,features:(t.requiredFeatures??[]).concat(t.optionalFeatures??[]).join(","),source:"NeedleXRSession.start"}),this._currentSessionRequest=navigator?.xr?.requestSession(e,t),this._currentSessionRequestMode=e;const o=await this._currentSessionRequest?.catch(a=>{console.error(a,"Code: "+a?.code),a?.code===9&&ue("Couldn't start XR session. Make sure you allow the required permissions."),console.log("If the specified XR configuration is not supported (e.g. entering AR doesnt work) - make sure you access the website on a secure connection (HTTPS) and your device has the required permissions (e.g. camera access)"),location.protocol==="http:"&&ue("XR requires a secure connection (HTTPS)")});this._currentSessionRequest=void 0,this._currentSessionRequestMode=null;for(const a of this._sessionRequestEndListeners)a({mode:e,init:t,newSession:o||null});return o?this.setSession(e,o,t,i):(console.warn("XR Session request was rejected"),null)}static setSession(e,t,i,n){if(this._activeSession)return console.error("A XRSession is already running"),this._activeSession;const o=e=="immersive-ar"?n.scripts_immersive_ar:n.scripts_immersive_vr;return this._activeSession=new H(e,t,n,{scripts:o,controller_added:this._controllerAddedListeners,controller_removed:this._controllerRemovedListeners,init:i}),t.addEventListener("end",this.onEnd),Ie?console.log(`%cStarted ${e} session`,"font-weight:bold;",o):console.log(`%cStarted ${e} session`,"font-weight:bold;"),this._activeSession}static $_stop_request=Symbol();static stop(){const e=this._activeSession;e&&(e[this.$_stop_request]===void 0?(Ie&&console.log("[NeedleXRSession] Stopping XR Session... (new)"),e[this.$_stop_request]=setTimeout(()=>{e.end()})):Ie&&console.warn("[NeedleXRSession] XR Session stop already requested"))}static onEnd=()=>{Ie&&console.log("XR Session ended"),this._activeSession=null};context;get sync(){return H._sync}get running(){return!this._ended&&this.session!=null}session;mode;get interactionMode(){return this.session.interactionMode}get visibilityState(){return this.session.visibilityState}get isVisibleBlurred(){return this.session.visibilityState==="visible-blurred"}get isSystemKeyboardSupported(){return this.session.isSystemKeyboardSupported}get environmentBlendMode(){return this.session.environmentBlendMode}get frame(){return this.context.xrFrame}controllers=[];get leftController(){return this.controllers.find(e=>e.side==="left")}get rightController(){return this.controllers.find(e=>e.side==="right")}getController(e){return typeof e=="number"?this.controllers[e]||null:this.controllers.find(t=>t.side===e)||null}get isPassThrough(){return!!(this.environmentBlendMode!=="opaque"&&this.interactionMode==="world-space"||this.mode==="immersive-ar"&&this.environmentBlendMode!=="opaque"&&this.controllers.some(e=>e.inputSource.targetRayMode==="tracked-pointer")||R()&&exports.DeviceUtilities.isDesktop()&&this.mode==="immersive-ar")}get isAR(){return this.mode==="immersive-ar"}get isVR(){return this.mode==="immersive-vr"}get isScreenBasedAR(){return this.isAR&&!this.isPassThrough}get posePosition(){return this._transformPosition}get poseOrientation(){return this._transformOrientation}get referenceSpace(){return this.context.renderer.xr.getReferenceSpace()}get viewerPose(){return this._viewerPose}get isTrackingImages(){if(this.frame&&"getImageTrackingResults"in this.frame&&typeof this.frame.getImageTrackingResults=="function")try{const e=this.frame.getImageTrackingResults();for(const t of e)if(t.trackingState==="tracked")return!0}catch{return!1}return!1}get rig(){const e=this._rigs[0]??null;return e?.gameObject&&or(e.gameObject)||e?.isActive===!1?(this.updateActiveXRRig(),this._rigs[0]??null):e}_rigScale=1;_lastRigScaleUpdate=-1;get rigScale(){return this._rigs[0]?(this._lastRigScaleUpdate!==this.context.time.frame&&(this._lastRigScaleUpdate=this.context.time.frame,this._rigScale=this._rigs[0].gameObject.worldScale.x),this._rigScale):1}addRig(e){this._rigs.indexOf(e)>=0||(e.priority===void 0&&(e.priority=0),this._rigs.push(e),this.updateActiveXRRig())}removeRig(e){const t=this._rigs.indexOf(e);t!==-1&&(this._rigs.splice(t,1),this.updateActiveXRRig())}setRigActive(e){const t=this._rigs.indexOf(e),i=this._rigs[0];this._rigs.splice(t,1),this._rigs.unshift(e),e.priority=i?.priority??0,this.updateActiveXRRig()}getUserOffsetInRig(){const e=this.context.mainCamera?.position;if(!e||!this.rig)return j(0,0,0);const t=j(e);return t.x*=-1,t.z*=-1,t.applyQuaternion(Kt(this.rig.gameObject.quaternion)),t}updateActiveXRRig(){const e=this._rigs[0]??null;this._defaultRig.gameObject.parent!==this.context.scene&&this.context.scene.add(this._defaultRig.gameObject),this._defaultRig.gameObject.visible=!0,this._rigs.includes(this._defaultRig)||this._rigs.push(this._defaultRig);let t=this._rigs[0];t&&t.priority===void 0&&(t.priority=0);for(let i=1;i<this._rigs.length;i++){const n=this._rigs[i];if(n.isActive){if(or(n.gameObject)){this._rigs.splice(i,1),i--;continue}(!t||t.isActive===!1||n.priority!==void 0&&n.priority>t.priority)&&(t=n)}}if(e!==t){const i=this._rigs.indexOf(t);i>=0&&this._rigs.splice(i,1),this._rigs.unshift(t)}Ie&&(e===t?console.log("Updated Active XR Rig:",t,"prev:",e):console.log("Updated Active XRRig:",t," (the same as before)"))}_rigs=[];_viewerHitTestSource=null;getHitTest(e){if(e)return this.getControllerHitTest(e);if(!this._viewerHitTestSource)return null;const t=this._viewerHitTestSource,i=this.frame.getHitTestResults(t);if(i.length>0){const n=i[0];return this.convertHitTestResult(n)}return null}getControllerHitTest(e){const t=e.getHitTestSource();if(!t)return null;const i=this.frame.getHitTestResultsForTransientInput(t);for(const n of i)if(n.inputSource===e.inputSource)for(const o of n.results)return this.convertHitTestResult(o);return null}convertHitTestResult(e){const t=this.context.renderer.xr.getReferenceSpace(),i=t&&e.getPose(t);if(i){const n=j(i.transform.position),o=Kt(i.transform.orientation),r=this.context.mainCamera;if(r?.parent!==this._cameraRenderParent&&n.applyMatrix4(ua),r?.parent){n.applyMatrix4(r.parent.matrixWorld),o.multiply(ki);const a=fe(r.parent);a.premultiply(ki),o.premultiply(a)}return{hit:e,position:n,quaternion:o}}return null}convertSpace(e){const t=j(e.position);t.applyMatrix4(ua);const i=Kt(e.orientation);return i.premultiply(ki),{position:t,quaternion:i}}_defaultRig;_xr_scripts;_xr_update_scripts=[];_inactive_scripts=[];_controllerAdded;_controllerRemoved;_originalCameraWorldPosition;_originalCameraWorldRotation;_originalCameraWorldScale;_originalCameraParent;_mainCamera=null;constructor(e,t,i,n){xC(e,n.init),this.session=t,this.mode=e,this.context=i,(Ie||x("console"))&&da(!0),this._xr_scripts=[...n.scripts],this._xr_update_scripts=this._xr_scripts.filter(o=>typeof o.onUpdateXR=="function"),this._controllerAdded=n.controller_added,this._controllerRemoved=n.controller_removed,ps(this.onBefore,me.LateUpdate),this.context.pre_render_callbacks.push(this.onBeforeRender),this.context.post_render_callbacks.push(this.onAfterRender),(n.init.optionalFeatures?.includes("hit-test")||n.init.requiredFeatures?.includes("hit-test"))&&t.requestReferenceSpace("viewer").then(o=>t.requestHitTestSource?.call(t,{space:o})?.then(r=>this._viewerHitTestSource=r).catch(r=>console.error(r))).catch(o=>console.error(o)),this.context.mainCamera&&(this._originalCameraWorldPosition=Q(this.context.mainCamera,new c.Vector3),this._originalCameraWorldRotation=fe(this.context.mainCamera,new c.Quaternion),this._originalCameraWorldScale=Be(this.context.mainCamera,new c.Vector3),this._originalCameraParent=this.context.mainCamera.parent,this.context.mainCamera instanceof c.PerspectiveCamera&&(this.context.mainCamera[Rh]=this.context.mainCamera.fov)),this._defaultRig=new oC,this.context.scene.add(this._defaultRig.gameObject),this.addRig(this._defaultRig);for(let o=0;o<t.inputSources.length;o++){const r=t.inputSources[o];if(!r.handedness){console.warn("Input source in xr session has no handedness - ignoring",o);continue}this.onInputSourceAdded(r)}this.session.addEventListener("end",this.onEnd),this.session.addEventListener("inputsourceschange",o=>{for(const r of o.removed)this.disconnectInputSource(r);for(const r of o.added)this.onInputSourceAdded(r)}),this.context.xr=this,this.context.renderer.xr.setSession(this.session).then(this.onRendererSessionSet),"controllerAutoUpdate"in this.context.renderer.xr?(console.debug("Disabling three.js controllerAutoUpdate"),this.context.renderer.xr.controllerAutoUpdate=!1):Ie&&console.warn("controllerAutoUpdate is not available in three.js - cannot disable it")}onRendererSessionSet=()=>{this.running&&(this.context.renderer.xr.enabled=!0,this.context.renderer.xr.updateCamera(this.context.mainCamera),this.context.mainCameraComponent?.applyClearFlags())};onInputSourceAdded=e=>{if(e.targetRayMode==="screen")return;let t=0;for(let n=0;n<this.session.inputSources.length;n++)if(this.session.inputSources[n]===e){t=n;break}if(this.controllers.find(n=>n.inputSource===e)){console.debug("Controller already exists for input source",t);return}else if(this._newControllers.find(n=>n.inputSource===e)){console.debug("Controller already registered for input source",t);return}const i=new Tm(this,e,t);this._newControllers.push(i)};disconnectInputSource(e){const t=(o,r)=>{if(o.inputSource===e){Ie&&console.log("Disconnecting controller",o.index);const a=r.indexOf(o);a>=0&&r.splice(a,1),this.invokeControllerEvent(o,this._controllerRemoved,"removed");const l={xr:this,controller:o,change:"removed"};for(const h of this._xr_scripts)h.onXRControllerRemoved&&h.onXRControllerRemoved(l);o.onDisconnected()}},i=[...this.controllers];for(let o=i.length-1;o>=0;o--){const r=i[o];t(r,this.controllers)}const n=[...this._newControllers];for(let o=n.length-1;o>=0;o--){const r=n[o];t(r,this._newControllers)}}end(){this._ended||this.session.end().catch(e=>console.warn(e))}_ended=!1;_newControllers=[];onEnd=e=>{if(this._ended)return;this._ended=!0,console.debug("XR Session ended"),Qs.sendEvent(U.Current,"xr",{action:"session_end",mode:this.mode,source:"NeedleXRSession.onEnd"}),SC(),this.onAfterRender(),this.revertCustomForward(),this._didStart=!1,this._previousCameraParent=null,this.requestedCameraNearPlane=null,co(this.onBefore,me.LateUpdate);const t=this.context.pre_render_callbacks.indexOf(this.onBeforeRender);t>=0&&this.context.pre_render_callbacks.splice(t,1);const i=this.context.post_render_callbacks.indexOf(this.onAfterRender);i>=0&&this.context.post_render_callbacks.splice(i,1),this.context.xr=null,this.context.renderer.xr.enabled=!1,this.context.pre_update_oneshot_callbacks.push(()=>{this.context.mainCameraComponent?.applyClearFlags(),this.context.mainCameraComponent?.applyClippingPlane()}),uv({session:this});for(const o of H._xrEndListeners)o({xr:this});const n=[...this.controllers];for(let o=0;o<n.length;o++)this.disconnectInputSource(n[o].inputSource);this.controllers.length=0,this._newControllers.length=0;for(const o of this._xr_scripts)o?.onLeaveXR?.({xr:this});this.sync?.onExitXR(this),this.context.mainCamera&&(this._originalCameraParent?.add(this.context.mainCamera),this._originalCameraWorldPosition&&rt(this.context.mainCamera,this._originalCameraWorldPosition),this._originalCameraWorldRotation&&rn(this.context.mainCamera,this._originalCameraWorldRotation),this._originalCameraWorldScale&&wa(this.context.mainCamera,this._originalCameraWorldScale),this.context.mainCamera instanceof c.PerspectiveCamera&&this.context.mainCamera[Rh]&&(this.context.mainCamera.fov=this.context.mainCamera[Rh],this.context.mainCamera[Rh]=0)),this.context.requestSizeUpdate(),this._defaultRig.gameObject.removeFromParent(),da(!1)};_didStart=!1;onBefore=e=>{const t=e.xrFrame;if(!t)return;this.context.xr=this,this.context.mainCameraComponent&&this.context.mainCameraComponent!==this._mainCamera&&(this._mainCamera=this.context.mainCameraComponent),this.rig?.isActive==!1&&(Ie&&console.warn("Latest rig is not active - trying to activate a different rig",this.rig),this.updateActiveXRRig()),this.rig&&this._mainCamera?.gameObject&&this._mainCamera?.gameObject?.parent!==this.rig.gameObject&&this.rig.gameObject.add(this._mainCamera?.gameObject),this.internalUpdateState(),this.applyCustomForward();const i={xr:this};if(this._didStart){if(this.context.new_scripts_xr.length>0){const n=[...this.context.new_scripts_xr];for(let o=0;o<n.length;o++){const r=this.context.new_scripts_xr[o];if(!r||r.destroyed||r.supportsXR?.(this.mode)==!1){this.context.new_scripts_xr.splice(o,1);continue}if(!r.activeAndEnabled){this.context.new_scripts_xr.splice(o,1),this.markInactive(r);continue}if(this.addScript(r)){this.invokeCallback_EnterXR(r);for(const a of this.controllers)this.invokeCallback_ControllerAdded(r,a)}}}}else{if(this._didStart=!0,this.mode==="immersive-vr"){const o=Vt(this.context.scene.children);if(o){const r=o.getSize(j());if(r.length()>0){const a=this._defaultRig.gameObject;a.position.set(o.min.x+r.x*.5,o.min.y,o.max.z+r.z*.5+1.5);const l=o.getCenter(j());l.y=a.position.y,a.lookAt(l)}}}dv({session:this}),pr();for(const o of H._xrStartListeners)o(i);const n=[...this._xr_scripts];Ie&&console.log("NeedleXRSession start, handle scripts:",n);for(const o of n){if(o.destroyed){this._script_to_remove.push(o);continue}if(!o.activeAndEnabled){this.markInactive(o);continue}this.invokeCallback_EnterXR(o);for(const r of this.controllers)this.invokeCallback_ControllerAdded(o,r)}}this.syncCameraCullingMask();for(const n of this.controllers)n.onUpdate(t);if(this._newControllers.length>0){const n=[...this._newControllers];this._newControllers.length=0;for(const o of n){if(!o.connected){console.warn("New controller is not connected",o);continue}this.controllers.push(o);for(const r of this._xr_scripts){if(r.destroyed){this._script_to_remove.push(r);continue}r.activeAndEnabled!==!1&&this.invokeCallback_ControllerAdded(r,o)}}this.controllers.sort((o,r)=>o.index-r.index)}Ie&&this.context.time.frame%30===0&&this.controllers.length<=0&&this.session.inputSources.length>0&&(da(!0),console.error("XRControllers are not added but inputSources are present"));for(const n of this._xr_update_scripts){if(n.destroyed===!0){this._script_to_remove.push(n);continue}if(n.activeAndEnabled===!1){this.markInactive(n);continue}n.onUpdateXR&&n.onUpdateXR(i)}if(this.handleInactiveScripts(),this._script_to_remove.length>0){const n=[...new Set(this._script_to_remove)];this._script_to_remove.length=0;for(const o of n)!o.destroyed&&this.running&&o.onLeaveXR?.(i),this.removeScript(o)}this.sync?.onUpdate(this),this.onRenderDebug()};onRenderDebug(){if(Ie)for(const e of this.controllers)e.onRenderDebug();if((Ie||e_)&&this.rig&&(_f++,_f>=20)){const e=this.rig.gameObject.worldPosition,t=this.rig.gameObject.worldForward;e.add(t.multiplyScalar(1.5));const i=this.rig.gameObject.worldUp;e.add(i.multiplyScalar(2.5));let n="";if(n+=`${this.context.time.smoothedFps.toFixed(0)} FPS`,n+=`, calls: ${this.context.renderer.info.render.calls}, tris: ${this.context.renderer.info.render.triangles.toLocaleString()}`,Ie||e_)for(const o of this.controllers)n+=`
168
- ${o.hand?"hand":"ctrl"} ${o.inputSource.handedness}[${o.index}] con:${o.connected} tr:${o.isTracking} hts:${o.hasHitTestSource?"yes":"no"}`;_f=0,B.DrawLabel(e,n,void 0,1/60*20)}}onBeforeRender=()=>{this.context.mainCamera&&(this.updateFade(this.context.mainCamera),this.requestedCameraNearPlane!==null&&this.context.mainCamera instanceof c.PerspectiveCamera&&(this.context.mainCamera.near=this.requestedCameraNearPlane,this.requestedCameraNearPlane=null))};onAfterRender=()=>{if(this.onUpdateFade_PostRender(),exports.DeviceUtilities.isDesktop()||!this._renderOnceOnDevice){const e=this.context.renderer;if(e.xr.isPresenting&&this.context.mainCamera){this._renderOnceOnDevice=!0;const t=e.xr.enabled,i=e.getRenderTarget(),n=this.context.scene.background;e.xr.enabled=!1,e.setRenderTarget(null),this.isPassThrough&&(this.context.scene.background=null),this.context.composer?this.context.composer.render(this.context.time.deltaTime):e.render(this.context.scene,this.context.mainCamera),e.xr.enabled=t,e.setRenderTarget(i),this.context.scene.background=n}}};addScript(e){return this._xr_scripts.includes(e)?!1:(Ie&&console.log("Register new XRScript",e),this._xr_scripts.push(e),typeof e.onUpdateXR=="function"&&this._xr_update_scripts.push(e),!0)}markInactive(e){if(!(this._inactive_scripts.indexOf(e)>=0)){this.removeScript(e,!1),this._inactive_scripts.push(e);for(const t of this.controllers)this.invokeCallback_ControllerRemoved(e,t);this.invokeCallback_LeaveXR(e)}}handleInactiveScripts(){if(this._inactive_scripts.length>0)for(let e=this._inactive_scripts.length-1;e>=0;e--){const t=this._inactive_scripts[e];if(t.activeAndEnabled){this._inactive_scripts.splice(e,1),this.addScript(t),this.invokeCallback_EnterXR(t);for(const i of this.controllers)this.invokeCallback_ControllerAdded(t,i)}}}_script_to_remove=[];removeScript(e,t=!0){Ie&&console.log("Remove XRScript",e);const i=this._xr_scripts.indexOf(e);i>=0&&this._xr_scripts.splice(i,1);const n=this._xr_update_scripts.indexOf(e);if(n>=0&&this._xr_update_scripts.splice(n,1),t){const o=this._inactive_scripts.indexOf(e);o>=0&&this._inactive_scripts.splice(o,1)}}invokeCallback_EnterXR(e){e.onEnterXR&&e.onEnterXR({xr:this})}invokeCallback_ControllerAdded(e,t){e.onXRControllerAdded&&e.onXRControllerAdded({xr:this,controller:t,change:"added"})}invokeCallback_ControllerRemoved(e,t){e.onXRControllerRemoved&&e.onXRControllerRemoved({xr:this,controller:t,change:"removed"})}invokeCallback_LeaveXR(e){e.onLeaveXR&&!e.destroyed&&e.onLeaveXR({xr:this})}syncCameraCullingMask(){const e=this.context.xrCamera,t=this.context.mainCameraComponent?.cullingMask;if(e&&t!==void 0){for(const i of e.cameras)i.layers.mask=t;e.layers.mask=t}else if(e){for(const i of e.cameras)i.layers.enableAll();e.layers.enableAll()}}invokeControllerEvent(e,t,i){for(let n=t.length-1;n>=0;n--){const o=t[n];if(o)try{o({xr:this,controller:e,change:i})}catch(r){console.error(r)}}}_camera;_cameraRenderParent=new c.Object3D().rotateY(Math.PI);_previousCameraParent;_customforward=!0;originalCameraNearPlane;requestedCameraNearPlane=null;applyCustomForward(){if(this.context.mainCamera&&this._customforward){this._camera=this.context.mainCamera,this._camera.parent!==this._cameraRenderParent&&(this._previousCameraParent=this._camera.parent,this._previousCameraParent?.add(this._cameraRenderParent)),this._cameraRenderParent.name="XR Camera Render Parent",this._cameraRenderParent.add(this._camera);{let e=.02;const t=.001;if(this.rig){const i=Be(this.rig.gameObject);e*=i.x}this._camera instanceof c.PerspectiveCamera&&Math.abs(this._camera.near-e)>t&&(this.isAR?this.originalCameraNearPlane=this._camera.near:this._camera.near=e,Ie&&console.debug(`Setting camera near plane to ${e} (was ${this.originalCameraNearPlane}) to account for XR rendering scale`))}}}revertCustomForward(){this._camera&&this._previousCameraParent&&this._previousCameraParent.add(this._camera),this._previousCameraParent=null,this._camera instanceof c.PerspectiveCamera&&this.originalCameraNearPlane!=null&&(this._camera.near=this.originalCameraNearPlane,this.originalCameraNearPlane=void 0)}_viewerPose;_transformOrientation=new c.Quaternion;_transformPosition=new c.Vector3;internalUpdateState(){const e=this.context.renderer.xr.getReferenceSpace();if(!e){this._viewerPose=void 0;return}if(this._viewerPose=this.frame.getViewerPose(e),this._viewerPose){const t=this._viewerPose.transform;this._transformPosition.set(t.position.x,t.position.y,t.position.z),this._transformOrientation.set(t.orientation.x,t.orientation.y,t.orientation.z,t.orientation.w)}}_transition;get transition(){return this._transition||(this._transition=new Ky),this._transition}fadeTransition(){return this._transition||(this._transition=new Ky),this._transition.fadeTransition()}updateFade(e){this._transition&&e instanceof c.PerspectiveCamera&&this._transition.update(e,this.context.time.deltaTime)}onUpdateFade_PostRender(){this._transition?.remove()}}const bf=x("debugwebxr");class Cv{static tryFindAvatarObjects(e,t,i){if(i.head&&i.leftHand&&i.rightHand)return;const n=e.name.toLocaleLowerCase();!i.head&&n.includes("head")&&(bf&&console.log("FOUND AVATAR HEAD",e.name),i.head=new K("",t,e)),n.includes("hand")&&(!i.leftHand&&n.includes("left")&&(bf&&console.log("FOUND AVATAR LEFT HAND",e.name),i.leftHand=new K("",t,e)),!i.rightHand&&n.includes("right")&&(bf&&console.log("FOUND AVATAR RIGHT HAND",e.name),i.rightHand=new K("",t,e)));for(let o=0;o<e.children.length;o++){if(i.head&&i.leftHand&&i.rightHand)return;const r=e.children[o];this.tryFindAvatarObjects(r,t,i)}}}class ee extends c.Color{alpha=1;get isRGBAColor(){return!0}set a(e){this.alpha=e}get a(){return this.alpha}constructor(e,t,i,n){super(),typeof e=="number"&&typeof t=="number"&&typeof i=="number"?(this.set(e,t,i),this.alpha=typeof n=="number"?n:1):e!==void 0&&(this.set(e),this.alpha=1)}clone(){const e=super.clone();return e.alpha=this.alpha,e}copy(e){return this.r=e.r,this.g=e.g,this.b=e.b,"alpha"in e&&typeof e.alpha=="number"?this.alpha=e.alpha:typeof e.a=="number"&&(this.alpha=e.a),this}lerp(e,t){const i=e;return i.alpha!=null&&(this.alpha=L.lerp(this.alpha,i.alpha,t)),super.lerp(e,t)}lerpColors(e,t,i){const n=e,o=t;return n.alpha!=null&&o.alpha!=null&&(this.alpha=L.lerp(n.alpha,o.alpha,i)),super.lerpColors(e,t,i)}multiply(e){const t=e;return t.alpha!=null&&(this.alpha=this.alpha*t.alpha),super.multiply(e)}fromArray(e,t=0){return this.alpha=e[t+3],super.fromArray(e,t)}static fromColorRepresentation(e){if(typeof e=="string"){if(e.trim()==="transparent")return new ee(0,0,0,0);if(e.startsWith("#")&&e.length===9){const t=parseInt(e.slice(1,9),16),i=t>>24&255,n=t>>16&255,o=t>>8&255,r=t>>0&255;return new ee(i/255,n/255,o/255,r/255)}else if(e.startsWith("#")){const t=parseInt(e.slice(1),16),i=t>>16&255,n=t>>8&255,o=t>>0&255;return new ee(i/255,n/255,o/255,1)}else if(e.startsWith("rgba")){const t=e.slice(5,-1).split(",").map(Number);return new ee(t[0]/255,t[1]/255,t[2]/255,t[3])}else if(e.startsWith("rgb")){const t=e.slice(4,-1).split(",").map(Number);return new ee(t[0]/255,t[1]/255,t[2]/255,1)}}else if(Array.isArray(e)){if(e.length===4)return new ee(e[0],e[1],e[2],e[3]);if(e.length===3)return new ee(e[0],e[1],e[2],1);console.error("Invalid color array length. Expected 3 or 4, got "+e.length)}return new ee(e)}}const xt=new c.Vector3,t_=new c.Vector3,i_=new c.Quaternion,OC=x("debuggizmos"),Qi=8947848,vf=32;class B{constructor(){}static enabled=!0;static isGizmo(e){return e[Ep]!==void 0}static setVisible(e){for(const t of Si.timedObjectsBuffer)t.visible=e}static DrawLabel(e,t,i=.05,n=0,o,r,a){if(!B.enabled)return null;o||(o=Qi);const l=H.active?.rigScale??1,h=Si.getTextLabel(n,t,i*l,o,r);return a instanceof c.Object3D&&a.add(h),h.position.x=e.x,h.position.y=e.y,h.position.z=e.z,h}static DrawRay(e,t,i=Qi,n=0,o=!0){if(!B.enabled)return;const r=Si.getLine(n),a=r.geometry.getAttribute("position");a.setXYZ(0,e.x,e.y,e.z),xt.set(t.x,t.y,t.z).multiplyScalar(999999999),a.setXYZ(1,e.x+xt.x,e.y+xt.y,e.z+xt.z),a.needsUpdate=!0,r.material.depthTest=o,r.material.depthWrite=!1,r.material.fog=!1,Ji(r.material,i)}static DrawDirection(e,t,i=Qi,n=0,o=!0,r=1){if(!B.enabled)return;const a=Si.getLine(n),l=a.geometry.getAttribute("position");l.setXYZ(0,e.x,e.y,e.z),t.w!==void 0?(xt.set(0,0,-r),i_.set(t.x,t.y,t.z,t.w),xt.applyQuaternion(i_)):(xt.set(t.x,t.y,t.z),xt.multiplyScalar(r)),l.setXYZ(1,e.x+xt.x,e.y+xt.y,e.z+xt.z),l.needsUpdate=!0,a.material.depthTest=o,a.material.depthWrite=!1,Ji(a.material,i)}static DrawLine(e,t,i=Qi,n=0,o=!0){if(!B.enabled)return;const r=Si.getLine(n),a=r.geometry.getAttribute("position");a.setXYZ(0,e.x,e.y,e.z),a.setXYZ(1,t.x,t.y,t.z),a.needsUpdate=!0,r.material.depthTest=o,r.material.depthWrite=!1,r.material.fog=!1,Ji(r.material,i)}static DrawCircle(e,t,i,n=Qi,o=0,r=!0){if(!B.enabled)return;const a=Si.getCircle(o);a.position.set(e.x,e.y,e.z),a.scale.set(i,i,i),a.quaternion.setFromUnitVectors(this._up,xt.set(t.x,t.y,t.z).normalize()),a.material.depthTest=r,a.material.depthWrite=!1,a.material.fog=!1,Ji(a.material,n)}static DrawWireSphere(e,t,i=Qi,n=0,o=!0){if(!B.enabled)return;const r=Si.getSphere(t,n,!0);nr(r,e.x,e.y,e.z),r.material.depthTest=o,r.material.depthWrite=!1,r.material.fog=!1,Ji(r.material,i)}static DrawSphere(e,t,i=Qi,n=0,o=!0){if(!B.enabled)return;const r=Si.getSphere(t,n,!1);nr(r,e.x,e.y,e.z),r.material.depthTest=o,r.material.depthWrite=!1,Ji(r.material,i)}static DrawWireBox(e,t,i=Qi,n=0,o=!0,r=void 0){if(!B.enabled)return;const a=Si.getBox(n);a.position.set(e.x,e.y,e.z),a.scale.set(t.x,t.y,t.z),r?a.quaternion.copy(r):a.quaternion.identity(),a.material.depthTest=o,a.material.wireframe=!0,a.material.depthWrite=!1,a.material.fog=!1,Ji(a.material,i)}static DrawWireBox3(e,t=Qi,i=0,n=!0){if(!B.enabled)return;const o=Si.getBox(i);o.position.copy(e.getCenter(xt)),o.scale.copy(e.getSize(xt)),o.material.depthTest=n,o.material.wireframe=!0,o.material.depthWrite=!1,o.material.fog=!1,Ji(o.material,t)}static _up=new c.Vector3(0,1,0);static DrawArrow(e,t,i=Qi,n=0,o=!0,r=!1){if(!B.enabled)return;const a=Si.getArrowHead(n);a.position.set(t.x,t.y,t.z),a.quaternion.setFromUnitVectors(this._up.set(0,1,0),xt.set(t.x,t.y,t.z).sub(t_.set(e.x,e.y,e.z)).normalize());const h=xt.set(t.x,t.y,t.z).sub(t_.set(e.x,e.y,e.z)).length()*.1;a.scale.set(h,h,h),a.material.depthTest=o,a.material.wireframe=r,Ji(a.material,i),this.DrawLine(e,t,i,n,o)}static DrawWireMesh(e){const t=Si.getMesh(e.duration??0);"mesh"in e?(t.geometry=e.mesh.geometry,t.matrixWorld.copy(e.mesh.matrixWorld)):(t.geometry=e.geometry,t.matrixWorld.copy(e.matrix)),t.matrixAutoUpdate=!1,t.matrixWorldAutoUpdate=!1,t.material.depthTest=e.depthTest??!0,t.material.wireframe=!0,Ji(t.material,e.color??Qi)}}const MC=new c.BoxGeometry(1,1,1);function Bm(s=null){const e=new c.Color(s??14540253),t=new c.EdgesGeometry(MC);return new c.LineSegments(t,new c.LineBasicMaterial({color:e}))}function Ji(s,e){if(Array.isArray(s)){for(const i of s)Ji(i,e);return}const t=e instanceof ee?e.a:1;s.color.set(e),s.opacity=t,s.transparent=t<1}const Ep=Symbol("GizmoCache");class Si{static familyName="needle-gizmos";static ensureFont(){let e=te.__webpack_exports__default.FontLibrary.getFontFamily(this.familyName);e||(e=te.__webpack_exports__default.FontLibrary.addFontFamily(this.familyName),e.addVariant("normal","normal","https://uploads.needle.tools/include/font-msdf.json","https://uploads.needle.tools/include/font.png")?.addEventListener("ready",()=>{te.__webpack_exports__default.update()}))}static getTextLabel(e,t,i,n,o){this.ensureFont();let r=this.textLabelCache.pop(),a=1;o&&typeof o=="string"&&o?.length>=8&&o.startsWith("#")?(a=parseInt(o.substring(7),16)/255,o=o.substring(0,7),OC&&console.log(o,a)):typeof o=="object"&&o.a!==void 0&&(a=o.a);const l={boxSizing:"border-box",fontFamily:this.familyName,width:"auto",fontSize:i,color:n,lineHeight:1,backgroundColor:o??void 0,backgroundOpacity:a,textContent:t,borderRadius:.5*i,padding:.8*i,whiteSpace:"pre",offset:.05*i};if(r)r.set(l);else{r=new te.__webpack_exports__Text(l);const h=this,d=r;d.setText=function(u){this.set({textContent:u}),h.tmuiNeedsUpdate=!0}}return this.tmuiNeedsUpdate=!0,this.registerTimedObject(U.Current,r,e,this.textLabelCache),r}static getBox(e){let t=this.boxesCache.pop();if(!t){const i=new c.BoxGeometry(1,1,1);t=new c.Mesh(i)}return this.registerTimedObject(U.Current,t,e,this.boxesCache),t}static getLine(e){let t=this.linesCache.pop();if(!t){t=new c.Line;let i=t.geometry.getAttribute("position");i||(i=new c.BufferAttribute(new Float32Array(6),3),t.geometry.setAttribute("position",i))}return t.frustumCulled=!1,this.registerTimedObject(U.Current,t,e,this.linesCache),t}static getCircle(e){let t=this.circlesCache.pop();if(!t){t=new c.Line;let i=t.geometry.getAttribute("position");if(!i){i=new c.BufferAttribute(new Float32Array(vf*3),3),t.geometry.setAttribute("position",i);const n=j(0,1,0),o=j(0,0,1),r=j(o);r.cross(n).normalize();const a=j(r),l=Math.PI*2/(vf-1);for(let h=0;h<vf+1;h++){const d=l*h;n.copy(a).multiplyScalar(Math.cos(d)*1),r.copy(o).multiplyScalar(Math.sin(d)*1);const u=n.add(r);i.setXYZ(h,u.x,u.y,u.z)}}}return t.frustumCulled=!1,this.registerTimedObject(U.Current,t,e,this.circlesCache),t}static getSphere(e,t,i){let n=this.spheresCache.pop();return n||(n=new c.Mesh(new c.SphereGeometry(1,8,8))),n.scale.set(e,e,e),n.material.wireframe=i,this.registerTimedObject(U.Current,n,t,this.spheresCache),n}static getArrowHead(e){let t=this.arrowHeadsCache.pop();return t||(t=new c.Mesh(new c.CylinderGeometry(0,.5,1,8))),this.registerTimedObject(U.Current,t,e,this.arrowHeadsCache),t}static getMesh(e){let t=this.mesh.pop();return t||(t=new c.Mesh,t.material=new c.MeshBasicMaterial),this.registerTimedObject(U.Current,t,e,this.mesh),t}static linesCache=[];static circlesCache=[];static spheresCache=[];static boxesCache=[];static arrowHeadsCache=[];static mesh=[];static textLabelCache=[];static registerTimedObject(e,t,i,n){if(!e){console.error("No Needle Engine context available. Did you call a Gizmos function in global scope?");return}const o=this.contextBeforeRenderCallbacks.get(e),r=this.contextPostRenderCallbacks.get(e);if(o){if(e.pre_render_callbacks[e.pre_render_callbacks.length-1]!==o){const a=e.pre_render_callbacks.indexOf(o);a>=0&&e.pre_render_callbacks.splice(a,1),e.pre_render_callbacks.push(o)}}else{const a=()=>{this.onBeforeRender(e,this.timedObjectsBuffer)};this.contextBeforeRenderCallbacks.set(e,a),e.pre_render_callbacks.push(a)}if(r){if(e.post_render_callbacks[e.post_render_callbacks.length-1]!==r){const a=e.post_render_callbacks.indexOf(r);a>=0&&e.post_render_callbacks.splice(a,1),e.post_render_callbacks.push(r)}}else{const a=()=>{this.onPostRender(e,this.timedObjectsBuffer,this.timesBuffer)};this.contextPostRenderCallbacks.set(e,a),e.post_render_callbacks.push(a)}t.traverse(a=>{a.layers.disableAll(),a.layers.enable(2)}),t.renderOrder=999999,t[Ep]=n,t.castShadow=!1,t.receiveShadow=!1,t.isGizmo=!0,this.timedObjectsBuffer.push(t),this.timesBuffer.push(U.Current.time.realtimeSinceStartup+i),e.scene.add(t)}static timedObjectsBuffer=new Array;static timesBuffer=new Array;static contextPostRenderCallbacks=new Map;static contextBeforeRenderCallbacks=new Map;static tmuiNeedsUpdate=!1;static onBeforeRender(e,t){this.tmuiNeedsUpdate&&(this.tmuiNeedsUpdate=!1,te.__webpack_exports__default.update());for(let i=0;i<t.length;i++){const n=t[i];if(e.mainCamera&&n instanceof te.__webpack_exports__default.MeshUIBaseElement){if(or(n))continue;const o=e.isInVR,r=!1,a=!o;Mc(n,e.mainCamera,r,a)}}}static onPostRender(e,t,i){const n=e.time.realtimeSinceStartup;for(let o=t.length-1;o>=0;o--){const r=t[o];n>=i[o]-1e-6&&(t.splice(o,1),i.splice(o,1),r.removeFromParent(),or(r)!=!0&&r[Ep].push(r))}}}const Ut=x("debugphysics"),kC=x("debugworker"),n_=new c.Layers;class ho{static AllLayers=4294967295;ray;cam;screenPoint;raycaster;results;targets;recursive=!0;minDistance;maxDistance;lineThreshold;layerMask;ignore;testObject;useAcceleratedRaycast;allowSlowRaycastFallback=!0;screenPointFromOffset(e,t){this.screenPoint===void 0&&(this.screenPoint=new c.Vector2),this.screenPoint.x=e/window.innerWidth*2-1,this.screenPoint.y=-(t/window.innerHeight)*2+1}setLayer(e){n_.set(e),this.layerMask=n_}setMask(e){this.layerMask||(this.layerMask=new c.Layers);const t=this.layerMask;t?t.mask=e:this.layerMask=e}}class Um{distance;point;object;constructor(e,t,i){this.object=e,this.distance=t,this.point=i}}class Pa{static _raycasting=0;static get raycasting(){return this._raycasting>0}raycastPhysicsFast(e,t=void 0,i=1/0,n=!0){return this.context.physics.engine?.raycast(e,t,{maxDistance:i,solid:n})??null}raycastPhysicsFastAndGetNormal(e,t=void 0,i=1/0,n=!0){return this.context.physics.engine?.raycastAndGetNormal(e,t,{maxDistance:i,solid:n})??null}sphereOverlapPhysics(e,t){return this.context.physics.engine?.sphereOverlap(e,t)??null}context;engine;constructor(e){this.context=e}raycaster=new c.Raycaster;defaultRaycastOptions=new ho;targetBuffer=new Array(1);defaultThresholds={Mesh:{},Line:{threshold:-1},LOD:{},Points:{threshold:0},Sprite:{}};sphereResults=new Array;sphereMask=new c.Layers;sphere=new c.Sphere;sphereOverlap(e,t,i=!0,n=!1,o=null){if(this.sphereResults.length=0,!this.context.scene)return this.sphereResults;const r=this.sphereMask;r.enableAll(),r.disable(2);for(const a of this.context.scene.children)this.intersectSphere(a,e,t,r,this.sphereResults,i,n,o);return this.sphereResults.sort((a,l)=>a.distance-l.distance)}raycastFromRay(e,t=null){const i=t??this.defaultRaycastOptions;i.ray=e;const n=this.raycast(i);return i===this.defaultRaycastOptions&&(i.ray=void 0),n}raycast(e=null){Ut&&performance.mark("raycast.start"),e||(e=this.defaultRaycastOptions);const t=e.screenPoint??this.context.input.mousePositionRC,i=e.raycaster??this.raycaster;if(i.near=e.minDistance??0,i.far=e.maxDistance??1/0,i.params=this.defaultThresholds,e.lineThreshold===void 0&&(e.lineThreshold=-1),i.params.Line={threshold:e.lineThreshold},e.ray)i.ray.copy(e.ray);else{const a=e.cam??this.context.mainCamera;if(!a)return Ut&&console.error("Can not perform raycast - no main camera found"),this.defaultRaycastOptions.results&&(this.defaultRaycastOptions.results.length=0),this.defaultRaycastOptions.results??[];const l=this.context.xrCamera;this.context.isInXR&&l instanceof c.ArrayCamera&&l.cameras.length>0?i.setFromCamera(t,l.cameras[0]):i.setFromCamera(t,a)}let n=e.targets;n||(n=this.targetBuffer,n.length=1,n[0]=this.context.scene);let o=e.results;this.defaultRaycastOptions.results&&(this.defaultRaycastOptions.results.length=0),o||(this.defaultRaycastOptions.results||(this.defaultRaycastOptions.results=new Array),o=this.defaultRaycastOptions.results),e.layerMask!==void 0?e.layerMask instanceof c.Layers?i.layers.mask=e.layerMask.mask:i.layers.mask=e.layerMask:(i.layers.enableAll(),i.layers.disable(2)),Ut&&console.time("raycast"),o.length=0,Pa._raycasting++,this.intersect(this.raycaster,n,o,e),o.sort((a,l)=>a.distance-l.distance);const r=e.ignore;return r!==void 0&&r.length>0&&(o=o.filter(a=>!r.includes(a.object))),Pa._raycasting--,Ut&&(console.timeEnd("raycast"),console.warn("#"+this.context.time.frame+", hits:",o?.length?[...o]:"nothing"),performance.mark("raycast.end"),performance.measure("raycast","raycast.start","raycast.end")),o}intersect(e,t,i,n){for(const o of t){if(!o||o.visible===!1||B.isGizmo(o)||n.lineThreshold!==void 0&&n.lineThreshold<0&&o instanceof c.Line)continue;let r=!0;const a=o,l=a.geometry;if(o.raycastAllowed===!1&&(r=!1),r&&n.testObject){const h=n.testObject?.(o);if(h===!1)continue;h==="continue in children"&&(r=!1)}else r&&(l&&s_(l)||(r=!1));if(r){const h=i.length,d=o.raycastPreference||"lod";let u=d!=="bounds";if(n.precise===!1&&(u=!1),l&&(u||=l.getAttribute("position")?.array?.length<64),a instanceof q.GroundedSkybox&&(u=!1),d==="lod"){const p=se.getRaycastMesh(o);p&&(a.geometry=p)}if(!u&&RC(a,e,i)||(n.useAcceleratedRaycast!==!1?kd.runMeshBVHRaycast(e,a,i,this.context,n):e.intersectObject(a,!1,i)),a.geometry=l,Ut&&i.length!=h){const p=i[i.length-1];B.DrawWireSphere(p.point,.1,7798784,1,!1),B.DrawWireMesh({mesh:o,depthTest:!1,duration:.2,color:7798784})}}n.recursive!==!1&&this.intersect(e,o.children,i,n)}return i}tempBoundingBox=new c.Box3;intersectSphere(e,t,i,n,o,r,a,l){let h=e&&e.isMesh&&e.layers.test(n)&&!B.isGizmo(e);h&&=e.visible,h&&=!(e instanceof c.Line),h&&=!(e instanceof q.GroundedSkybox);const d=e,u=d.geometry;if(h&&l){const p=l(e);if(p===!1)return;p==="continue in children"&&(h=!1)}if(u&&s_(u)||(h=!1),h){if(a){const p=this.sphere;p.center.copy(t),p.radius=i;const m=o.length;if(kd.runMeshBVHRaycast(this.sphere,d,o,this.context,{}),m!=o.length&&!r)return}else if(u.boundingBox||u.computeBoundingBox(),u.boundingBox){d.matrixWorldNeedsUpdate&&d.updateWorldMatrix(!1,!1);const p=this.tempBoundingBox.copy(u.boundingBox).applyMatrix4(d.matrixWorld),m=this.sphere;if(m.center.copy(t),m.radius=i,m.intersectsBox(p)){const y=Q(e),_=y.distanceTo(m.center),g=new Um(e,_,y);if(o.push(g),!r)return}}}if(e.children)for(const p of e.children){const m=o.length;if(this.intersectSphere(p,t,i,n,o,r,a,l),m!=o.length&&!r)return}}}function s_(s){return!(s.index&&s.index.array.length<3)}const ko=new c.Sphere,Th=new c.Plane,EC=new c.Matrix3;function RC(s,e,t){const i=s._computeIntersections;if(!i)return!1;let n=s["_computeIntersections:Needle"];return n||(n=s["_computeIntersections:Needle"]=function(o,r,a){const l=this,h=l.geometry.boundingSphere;if(h){if(l instanceof q.GroundedSkybox){Th.setFromNormalAndCoplanarPoint(j(0,1,0),j(0,-l.position.y,0)),Th.applyMatrix4(l.matrixWorld,EC);const u=o.ray.intersectPlane(Th,j());if(u){ko.copy(h),ko.applyMatrix4(l.matrixWorld);const m=j(u).sub(o.ray.origin).length(),y=ko.radius*.5;m<y&&r.push({distance:m,point:u,object:l,normal:Th.normal.clone()})}return}ko.copy(h),ko.applyMatrix4(l.matrixWorld);const d=o.ray.intersectSphere(ko,j());if(d){const u=j(d).sub(o.ray.origin),p=u.length();if(p>ko.radius){const m=u.clone().normalize();r.push({distance:p,point:d,object:l,normal:m})}}}}),s._computeIntersections=n,e.intersectObject(s,!1,t),s._computeIntersections=i,!0}var kd;(s=>{let e=0;function t(b,v,T,O,M){if(!v.geometry||!v.geometry.hasAttribute("position"))return!1;const A=v.geometry;if(v?.isSkinnedMesh){const D=v,I=D.bvhNeedsUpdate;if(!D.staticGenerator)l(),r&&(D.staticGenerator=new r(v),D.staticGenerator.applyWorldTransforms=!1,D.staticGeometry=D.staticGenerator.generate(),A.boundsTree=a?.call(D.staticGeometry),D.staticGeometryLastUpdate=performance.now()+Math.random()*200,D.bvhNeedsUpdate=!0);else if(A.boundsTree&&(D.autoUpdateMeshBvhInterval!==void 0&&D.autoUpdateMeshBvhInterval>=0||I===!0)){const N=performance.now(),$=N-D.staticGeometryLastUpdate,k=D.autoUpdateMeshBvhInterval??100;(I||$>k)&&(Ut&&console.warn(`Physics: updating skinned mesh bvh for ${v.name} after ${$.toFixed(2)}ms`),D.bvhNeedsUpdate=!1,D.staticGeometryLastUpdate=N,D.staticGenerator?.generate(D.staticGeometry),A.boundsTree.refit())}}else if(!A.boundsTree){d||w();let D=!0;if((O.xr||A[y]===!1||A.getAttribute("position")?.isInterleavedBufferAttribute||A.index&&A.index?.isInterleavedBufferAttribute||e>10)&&(D=!1),D&&p){if(A[m]===void 0){let I=null;if(g.length>0){const N=g.shift();N&&!N.running&&(I=N)}if(!I&&_.length<3)try{kC&&console.warn("[GenerateMeshBVHWorker] Creating worker with import.meta.url:",typeof document>"u"?require("url").pathToFileURL(__filename).href:ha&&ha.tagName.toUpperCase()==="SCRIPT"&&ha.src||new URL("needle-engine.bundle-DQC2R6JE.umd.cjs",document.baseURI).href),I=new p,_.push(I)}catch(N){N instanceof DOMException&&N.name==="SecurityError"?(console.warn("Failed to create MeshBVH worker, falling back to main thread generation. This can happen when running from file://, if the browser does not support workers or if the browser is blocking workers for other reasons."),console.debug(N),e+=10):(console.error("Failed to create MeshBVH worker. Please see below for more details:"),console.log(N)),e++}if(I!=null&&!I.running){const N=v.name;Ut&&console.log("<<<< worker start",N,I),A[m]="queued",performance.mark("bvh.create.start");const $=A.clone();try{I.generate($).then(k=>{A[m]="done",A.boundsTree=k}).catch(k=>{A[m]="failed - "+k?.message,A[y]=!1,Ut&&console.error("Failed to generate mesh bvh on worker",k)}).finally(()=>{Ut&&console.log(">>>>> worker done",N,{hasBoundsTre:A.boundsTree!=null}),g.push(I),$.dispose(),performance.mark("bvh.create.end"),performance.measure("bvh.create (worker)","bvh.create.start","bvh.create.end")})}catch(k){console.error("Failed to generate mesh bvh on worker",k)}}else Ut&&console.warn("No worker available")}}else(!u||!D)&&(l(),o&&(performance.mark("bvh.create.start"),A.boundsTree=new o(A),performance.mark("bvh.create.end"),performance.measure("bvh.create","bvh.create.start","bvh.create.end")))}if(b instanceof c.Raycaster){const D=b,I=v.raycast;if(A.boundsTree)l(),n&&(v.acceleratedRaycast||(v.acceleratedRaycast=n.bind(v),Ut&&console.debug(`Physics: bind acceleratedRaycast fn to "${v.name}"`)),v.raycast=v.acceleratedRaycast);else if(Ut&&console.warn("No bounds tree found for mesh",v.name,{workerTask:A[m],hasAcceleratedRaycast:n!=null}),M.allowSlowRaycastFallback===!1&&(A.getAttribute("position")?.array?.length??0)>2e3)return Ut&&console.warn("Skipping raycast because no bounds tree is available and allowSlowRaycastFallback is false"),!1;const N=D.firstHitOnly;return D.firstHitOnly=!1,D.intersectObject(v,!1,T),D.firstHitOnly=N,v.raycast=I,!0}else if(b instanceof c.Sphere){const D=A.boundsTree;if(D){const I=b;if(h.copy(v.matrixWorld).invert(),I.applyMatrix4(h),D.intersectsSphere(I)){const $=Q(v),k=$.distanceTo(I.center),z=new Um(v,k,$);T.push(z)}}return!0}return!1}s.runMeshBVHRaycast=t;let i=!1,n=null,o=null,r=null,a=null;function l(){i||(i=!0,Promise.resolve().then(()=>require("./vendor-tyBvnMF-.umd.cjs")).then(b=>b.index$1).then(b=>{n=b.acceleratedRaycast,o=b.MeshBVH,r=b.StaticGeometryGenerator,a=b.computeBoundsTree}).catch(b=>{(Ut||R())&&console.error("Failed to load BVH library...",b.message)}))}const h=new c.Matrix4;let d=!1,u=!1,p=null;const m=Symbol("Needle:MeshBVH-Worker"),y=Symbol("Needle:MeshBVH-CanUseWorker"),_=[],g=[];function w(){d=!0,u=!0,Promise.resolve().then(()=>LT).then(b=>{p=b.GenerateMeshBVHWorker}).catch(b=>{Ut||R()?console.warn("Failed to setup mesh bvh worker"):console.debug("Failed to setup mesh bvh worker",b)}).finally(()=>{u=!1})}})(kd||(kd={}));const o_=Symbol("gltf-loader-internal-usage-tracker"),TC=x("debugusers");class pa{get name(){return"NEEDLE_internal_usage_tracker"}static isLoading(e){return pa._loadingProcesses>0}static _loadingProcesses=0;parser;_getDependency;_loadingId;_loadedObjects=new Set;constructor(e){this.parser=e,this._getDependency=this.parser.getDependency,this._loadingId=Date.now().toString()}beforeRoot(){pa._loadingProcesses++;const e=this,t=this._getDependency;return this.parser.getDependency=function(i,n){const o=t.call(this,i,n);return o.then(r=>(r&&(e._loadedObjects.add(r),r[o_]=e._loadingId),r)),o},null}afterRoot(e){pa._loadingProcesses--,this.parser.getDependency=this._getDependency;for(const t of this._loadedObjects)delete t[o_],t instanceof c.Object3D&&(t.parent||t instanceof c.Mesh&&setTimeout(()=>{TC&&console.warn("> GLTF LOADER: Mesh not used in scene!",t),t.material=null,t.geometry=null},1e3));return null}}class Pv{constructor(){window.addEventListener("unhandledrejection",e=>{if(e.defaultPrevented)return;const t=e?.reason?.path;if(t){const i=t[0];i&&i.tagName==="IMG"&&(console.warn(`Could not load image:
168
+ ${o.hand?"hand":"ctrl"} ${o.inputSource.handedness}[${o.index}] con:${o.connected} tr:${o.isTracking} hts:${o.hasHitTestSource?"yes":"no"}`;_f=0,B.DrawLabel(e,n,void 0,1/60*20)}}onBeforeRender=()=>{this.context.mainCamera&&(this.updateFade(this.context.mainCamera),this.requestedCameraNearPlane!==null&&this.context.mainCamera instanceof c.PerspectiveCamera&&(this.context.mainCamera.near=this.requestedCameraNearPlane,this.requestedCameraNearPlane=null))};onAfterRender=()=>{if(this.onUpdateFade_PostRender(),exports.DeviceUtilities.isDesktop()||!this._renderOnceOnDevice){const e=this.context.renderer;if(e.xr.isPresenting&&this.context.mainCamera){this._renderOnceOnDevice=!0;const t=e.xr.enabled,i=e.getRenderTarget(),n=this.context.scene.background;e.xr.enabled=!1,e.setRenderTarget(null),this.isPassThrough&&(this.context.scene.background=null),this.context.composer?this.context.composer.render(this.context.time.deltaTime):e.render(this.context.scene,this.context.mainCamera),e.xr.enabled=t,e.setRenderTarget(i),this.context.scene.background=n}}};addScript(e){return this._xr_scripts.includes(e)?!1:(Ie&&console.log("Register new XRScript",e),this._xr_scripts.push(e),typeof e.onUpdateXR=="function"&&this._xr_update_scripts.push(e),!0)}markInactive(e){if(!(this._inactive_scripts.indexOf(e)>=0)){this.removeScript(e,!1),this._inactive_scripts.push(e);for(const t of this.controllers)this.invokeCallback_ControllerRemoved(e,t);this.invokeCallback_LeaveXR(e)}}handleInactiveScripts(){if(this._inactive_scripts.length>0)for(let e=this._inactive_scripts.length-1;e>=0;e--){const t=this._inactive_scripts[e];if(t.activeAndEnabled){this._inactive_scripts.splice(e,1),this.addScript(t),this.invokeCallback_EnterXR(t);for(const i of this.controllers)this.invokeCallback_ControllerAdded(t,i)}}}_script_to_remove=[];removeScript(e,t=!0){Ie&&console.log("Remove XRScript",e);const i=this._xr_scripts.indexOf(e);i>=0&&this._xr_scripts.splice(i,1);const n=this._xr_update_scripts.indexOf(e);if(n>=0&&this._xr_update_scripts.splice(n,1),t){const o=this._inactive_scripts.indexOf(e);o>=0&&this._inactive_scripts.splice(o,1)}}invokeCallback_EnterXR(e){e.onEnterXR&&e.onEnterXR({xr:this})}invokeCallback_ControllerAdded(e,t){e.onXRControllerAdded&&e.onXRControllerAdded({xr:this,controller:t,change:"added"})}invokeCallback_ControllerRemoved(e,t){e.onXRControllerRemoved&&e.onXRControllerRemoved({xr:this,controller:t,change:"removed"})}invokeCallback_LeaveXR(e){e.onLeaveXR&&!e.destroyed&&e.onLeaveXR({xr:this})}syncCameraCullingMask(){const e=this.context.xrCamera,t=this.context.mainCameraComponent?.cullingMask;if(e&&t!==void 0){for(const i of e.cameras)i.layers.mask=t;e.layers.mask=t}else if(e){for(const i of e.cameras)i.layers.enableAll();e.layers.enableAll()}}invokeControllerEvent(e,t,i){for(let n=t.length-1;n>=0;n--){const o=t[n];if(o)try{o({xr:this,controller:e,change:i})}catch(r){console.error(r)}}}_camera;_cameraRenderParent=new c.Object3D().rotateY(Math.PI);_previousCameraParent;_customforward=!0;originalCameraNearPlane;requestedCameraNearPlane=null;applyCustomForward(){if(this.context.mainCamera&&this._customforward){this._camera=this.context.mainCamera,this._camera.parent!==this._cameraRenderParent&&(this._previousCameraParent=this._camera.parent,this._previousCameraParent?.add(this._cameraRenderParent)),this._cameraRenderParent.name="XR Camera Render Parent",this._cameraRenderParent.add(this._camera);{let e=.02;const t=.001;if(this.rig){const i=Be(this.rig.gameObject);e*=i.x}this._camera instanceof c.PerspectiveCamera&&Math.abs(this._camera.near-e)>t&&(this.isAR?this.originalCameraNearPlane=this._camera.near:this._camera.near=e,Ie&&console.debug(`Setting camera near plane to ${e} (was ${this.originalCameraNearPlane}) to account for XR rendering scale`))}}}revertCustomForward(){this._camera&&this._previousCameraParent&&this._previousCameraParent.add(this._camera),this._previousCameraParent=null,this._camera instanceof c.PerspectiveCamera&&this.originalCameraNearPlane!=null&&(this._camera.near=this.originalCameraNearPlane,this.originalCameraNearPlane=void 0)}_viewerPose;_transformOrientation=new c.Quaternion;_transformPosition=new c.Vector3;internalUpdateState(){const e=this.context.renderer.xr.getReferenceSpace();if(!e){this._viewerPose=void 0;return}if(this._viewerPose=this.frame.getViewerPose(e),this._viewerPose){const t=this._viewerPose.transform;this._transformPosition.set(t.position.x,t.position.y,t.position.z),this._transformOrientation.set(t.orientation.x,t.orientation.y,t.orientation.z,t.orientation.w)}}_transition;get transition(){return this._transition||(this._transition=new Ky),this._transition}fadeTransition(){return this._transition||(this._transition=new Ky),this._transition.fadeTransition()}updateFade(e){this._transition&&e instanceof c.PerspectiveCamera&&this._transition.update(e,this.context.time.deltaTime)}onUpdateFade_PostRender(){this._transition?.remove()}}const bf=x("debugwebxr");class Cv{static tryFindAvatarObjects(e,t,i){if(i.head&&i.leftHand&&i.rightHand)return;const n=e.name.toLocaleLowerCase();!i.head&&n.includes("head")&&(bf&&console.log("FOUND AVATAR HEAD",e.name),i.head=new K("",t,e)),n.includes("hand")&&(!i.leftHand&&n.includes("left")&&(bf&&console.log("FOUND AVATAR LEFT HAND",e.name),i.leftHand=new K("",t,e)),!i.rightHand&&n.includes("right")&&(bf&&console.log("FOUND AVATAR RIGHT HAND",e.name),i.rightHand=new K("",t,e)));for(let o=0;o<e.children.length;o++){if(i.head&&i.leftHand&&i.rightHand)return;const r=e.children[o];this.tryFindAvatarObjects(r,t,i)}}}class ee extends c.Color{alpha=1;get isRGBAColor(){return!0}set a(e){this.alpha=e}get a(){return this.alpha}constructor(e,t,i,n){super(),typeof e=="number"&&typeof t=="number"&&typeof i=="number"?(this.set(e,t,i),this.alpha=typeof n=="number"?n:1):e!==void 0&&(this.set(e),this.alpha=1)}clone(){const e=super.clone();return e.alpha=this.alpha,e}copy(e){return this.r=e.r,this.g=e.g,this.b=e.b,"alpha"in e&&typeof e.alpha=="number"?this.alpha=e.alpha:typeof e.a=="number"&&(this.alpha=e.a),this}lerp(e,t){const i=e;return i.alpha!=null&&(this.alpha=L.lerp(this.alpha,i.alpha,t)),super.lerp(e,t)}lerpColors(e,t,i){const n=e,o=t;return n.alpha!=null&&o.alpha!=null&&(this.alpha=L.lerp(n.alpha,o.alpha,i)),super.lerpColors(e,t,i)}multiply(e){const t=e;return t.alpha!=null&&(this.alpha=this.alpha*t.alpha),super.multiply(e)}fromArray(e,t=0){return this.alpha=e[t+3],super.fromArray(e,t)}static fromColorRepresentation(e){if(typeof e=="string"){if(e.trim()==="transparent")return new ee(0,0,0,0);if(e.startsWith("#")&&e.length===9){const t=parseInt(e.slice(1,9),16),i=t>>24&255,n=t>>16&255,o=t>>8&255,r=t>>0&255;return new ee(i/255,n/255,o/255,r/255)}else if(e.startsWith("#")){const t=parseInt(e.slice(1),16),i=t>>16&255,n=t>>8&255,o=t>>0&255;return new ee(i/255,n/255,o/255,1)}else if(e.startsWith("rgba")){const t=e.slice(5,-1).split(",").map(Number);return new ee(t[0]/255,t[1]/255,t[2]/255,t[3])}else if(e.startsWith("rgb")){const t=e.slice(4,-1).split(",").map(Number);return new ee(t[0]/255,t[1]/255,t[2]/255,1)}}else if(Array.isArray(e)){if(e.length===4)return new ee(e[0],e[1],e[2],e[3]);if(e.length===3)return new ee(e[0],e[1],e[2],1);console.error("Invalid color array length. Expected 3 or 4, got "+e.length)}return new ee(e)}}const xt=new c.Vector3,t_=new c.Vector3,i_=new c.Quaternion,OC=x("debuggizmos"),Qi=8947848,vf=32;class B{constructor(){}static enabled=!0;static isGizmo(e){return e[Ep]!==void 0}static setVisible(e){for(const t of Si.timedObjectsBuffer)t.visible=e}static DrawLabel(e,t,i=.05,n=0,o,r,a){if(!B.enabled)return null;o||(o=Qi);const l=H.active?.rigScale??1,h=Si.getTextLabel(n,t,i*l,o,r);return a instanceof c.Object3D&&a.add(h),h.position.x=e.x,h.position.y=e.y,h.position.z=e.z,h}static DrawRay(e,t,i=Qi,n=0,o=!0){if(!B.enabled)return;const r=Si.getLine(n),a=r.geometry.getAttribute("position");a.setXYZ(0,e.x,e.y,e.z),xt.set(t.x,t.y,t.z).multiplyScalar(999999999),a.setXYZ(1,e.x+xt.x,e.y+xt.y,e.z+xt.z),a.needsUpdate=!0,r.material.depthTest=o,r.material.depthWrite=!1,r.material.fog=!1,Ji(r.material,i)}static DrawDirection(e,t,i=Qi,n=0,o=!0,r=1){if(!B.enabled)return;const a=Si.getLine(n),l=a.geometry.getAttribute("position");l.setXYZ(0,e.x,e.y,e.z),t.w!==void 0?(xt.set(0,0,-r),i_.set(t.x,t.y,t.z,t.w),xt.applyQuaternion(i_)):(xt.set(t.x,t.y,t.z),xt.multiplyScalar(r)),l.setXYZ(1,e.x+xt.x,e.y+xt.y,e.z+xt.z),l.needsUpdate=!0,a.material.depthTest=o,a.material.depthWrite=!1,Ji(a.material,i)}static DrawLine(e,t,i=Qi,n=0,o=!0){if(!B.enabled)return;const r=Si.getLine(n),a=r.geometry.getAttribute("position");a.setXYZ(0,e.x,e.y,e.z),a.setXYZ(1,t.x,t.y,t.z),a.needsUpdate=!0,r.material.depthTest=o,r.material.depthWrite=!1,r.material.fog=!1,Ji(r.material,i)}static DrawCircle(e,t,i,n=Qi,o=0,r=!0){if(!B.enabled)return;const a=Si.getCircle(o);a.position.set(e.x,e.y,e.z),a.scale.set(i,i,i),a.quaternion.setFromUnitVectors(this._up,xt.set(t.x,t.y,t.z).normalize()),a.material.depthTest=r,a.material.depthWrite=!1,a.material.fog=!1,Ji(a.material,n)}static DrawWireSphere(e,t,i=Qi,n=0,o=!0){if(!B.enabled)return;const r=Si.getSphere(t,n,!0);nr(r,e.x,e.y,e.z),r.material.depthTest=o,r.material.depthWrite=!1,r.material.fog=!1,Ji(r.material,i)}static DrawSphere(e,t,i=Qi,n=0,o=!0){if(!B.enabled)return;const r=Si.getSphere(t,n,!1);nr(r,e.x,e.y,e.z),r.material.depthTest=o,r.material.depthWrite=!1,Ji(r.material,i)}static DrawWireBox(e,t,i=Qi,n=0,o=!0,r=void 0){if(!B.enabled)return;const a=Si.getBox(n);a.position.set(e.x,e.y,e.z),a.scale.set(t.x,t.y,t.z),r?a.quaternion.copy(r):a.quaternion.identity(),a.material.depthTest=o,a.material.wireframe=!0,a.material.depthWrite=!1,a.material.fog=!1,Ji(a.material,i)}static DrawWireBox3(e,t=Qi,i=0,n=!0){if(!B.enabled)return;const o=Si.getBox(i);o.position.copy(e.getCenter(xt)),o.scale.copy(e.getSize(xt)),o.material.depthTest=n,o.material.wireframe=!0,o.material.depthWrite=!1,o.material.fog=!1,Ji(o.material,t)}static _up=new c.Vector3(0,1,0);static DrawArrow(e,t,i=Qi,n=0,o=!0,r=!1){if(!B.enabled)return;const a=Si.getArrowHead(n);a.position.set(t.x,t.y,t.z),a.quaternion.setFromUnitVectors(this._up.set(0,1,0),xt.set(t.x,t.y,t.z).sub(t_.set(e.x,e.y,e.z)).normalize());const h=xt.set(t.x,t.y,t.z).sub(t_.set(e.x,e.y,e.z)).length()*.1;a.scale.set(h,h,h),a.material.depthTest=o,a.material.wireframe=r,Ji(a.material,i),this.DrawLine(e,t,i,n,o)}static DrawWireMesh(e){const t=Si.getMesh(e.duration??0);"mesh"in e?(t.geometry=e.mesh.geometry,t.matrixWorld.copy(e.mesh.matrixWorld)):(t.geometry=e.geometry,t.matrixWorld.copy(e.matrix)),t.matrixAutoUpdate=!1,t.matrixWorldAutoUpdate=!1,t.material.depthTest=e.depthTest??!0,t.material.wireframe=!0,Ji(t.material,e.color??Qi)}}const MC=new c.BoxGeometry(1,1,1);function Bm(s=null){const e=new c.Color(s??14540253),t=new c.EdgesGeometry(MC);return new c.LineSegments(t,new c.LineBasicMaterial({color:e}))}function Ji(s,e){if(Array.isArray(s)){for(const i of s)Ji(i,e);return}const t=e instanceof ee?e.a:1;s.color.set(e),s.opacity=t,s.transparent=t<1}const Ep=Symbol("GizmoCache");class Si{static familyName="needle-gizmos";static ensureFont(){let e=te.__webpack_exports__default.FontLibrary.getFontFamily(this.familyName);e||(e=te.__webpack_exports__default.FontLibrary.addFontFamily(this.familyName),e.addVariant("normal","normal","https://uploads.needle.tools/include/font-msdf.json","https://uploads.needle.tools/include/font.png")?.addEventListener("ready",()=>{te.__webpack_exports__default.update()}))}static getTextLabel(e,t,i,n,o){this.ensureFont();let r=this.textLabelCache.pop(),a=1;o&&typeof o=="string"&&o?.length>=8&&o.startsWith("#")?(a=parseInt(o.substring(7),16)/255,o=o.substring(0,7),OC&&console.log(o,a)):typeof o=="object"&&o.a!==void 0&&(a=o.a);const l={boxSizing:"border-box",fontFamily:this.familyName,width:"auto",fontSize:i,color:n,lineHeight:1,backgroundColor:o??void 0,backgroundOpacity:a,textContent:t,borderRadius:.5*i,padding:.8*i,whiteSpace:"pre",offset:.05*i};if(r)r.set(l);else{r=new te.__webpack_exports__Text(l);const h=this,d=r;d.setText=function(u){this.set({textContent:u}),h.tmuiNeedsUpdate=!0}}return this.tmuiNeedsUpdate=!0,this.registerTimedObject(U.Current,r,e,this.textLabelCache),r}static getBox(e){let t=this.boxesCache.pop();if(!t){const i=new c.BoxGeometry(1,1,1);t=new c.Mesh(i)}return this.registerTimedObject(U.Current,t,e,this.boxesCache),t}static getLine(e){let t=this.linesCache.pop();if(!t){t=new c.Line;let i=t.geometry.getAttribute("position");i||(i=new c.BufferAttribute(new Float32Array(6),3),t.geometry.setAttribute("position",i))}return t.frustumCulled=!1,this.registerTimedObject(U.Current,t,e,this.linesCache),t}static getCircle(e){let t=this.circlesCache.pop();if(!t){t=new c.Line;let i=t.geometry.getAttribute("position");if(!i){i=new c.BufferAttribute(new Float32Array(vf*3),3),t.geometry.setAttribute("position",i);const n=j(0,1,0),o=j(0,0,1),r=j(o);r.cross(n).normalize();const a=j(r),l=Math.PI*2/(vf-1);for(let h=0;h<vf+1;h++){const d=l*h;n.copy(a).multiplyScalar(Math.cos(d)*1),r.copy(o).multiplyScalar(Math.sin(d)*1);const u=n.add(r);i.setXYZ(h,u.x,u.y,u.z)}}}return t.frustumCulled=!1,this.registerTimedObject(U.Current,t,e,this.circlesCache),t}static getSphere(e,t,i){let n=this.spheresCache.pop();return n||(n=new c.Mesh(new c.SphereGeometry(1,8,8))),n.scale.set(e,e,e),n.material.wireframe=i,this.registerTimedObject(U.Current,n,t,this.spheresCache),n}static getArrowHead(e){let t=this.arrowHeadsCache.pop();return t||(t=new c.Mesh(new c.CylinderGeometry(0,.5,1,8))),this.registerTimedObject(U.Current,t,e,this.arrowHeadsCache),t}static getMesh(e){let t=this.mesh.pop();return t||(t=new c.Mesh,t.material=new c.MeshBasicMaterial),this.registerTimedObject(U.Current,t,e,this.mesh),t}static linesCache=[];static circlesCache=[];static spheresCache=[];static boxesCache=[];static arrowHeadsCache=[];static mesh=[];static textLabelCache=[];static registerTimedObject(e,t,i,n){if(!e){console.error("No Needle Engine context available. Did you call a Gizmos function in global scope?");return}const o=this.contextBeforeRenderCallbacks.get(e),r=this.contextPostRenderCallbacks.get(e);if(o){if(e.pre_render_callbacks[e.pre_render_callbacks.length-1]!==o){const a=e.pre_render_callbacks.indexOf(o);a>=0&&e.pre_render_callbacks.splice(a,1),e.pre_render_callbacks.push(o)}}else{const a=()=>{this.onBeforeRender(e,this.timedObjectsBuffer)};this.contextBeforeRenderCallbacks.set(e,a),e.pre_render_callbacks.push(a)}if(r){if(e.post_render_callbacks[e.post_render_callbacks.length-1]!==r){const a=e.post_render_callbacks.indexOf(r);a>=0&&e.post_render_callbacks.splice(a,1),e.post_render_callbacks.push(r)}}else{const a=()=>{this.onPostRender(e,this.timedObjectsBuffer,this.timesBuffer)};this.contextPostRenderCallbacks.set(e,a),e.post_render_callbacks.push(a)}t.traverse(a=>{a.layers.disableAll(),a.layers.enable(2)}),t.renderOrder=999999,t[Ep]=n,t.castShadow=!1,t.receiveShadow=!1,t.isGizmo=!0,this.timedObjectsBuffer.push(t),this.timesBuffer.push(U.Current.time.realtimeSinceStartup+i),e.scene.add(t)}static timedObjectsBuffer=new Array;static timesBuffer=new Array;static contextPostRenderCallbacks=new Map;static contextBeforeRenderCallbacks=new Map;static tmuiNeedsUpdate=!1;static onBeforeRender(e,t){this.tmuiNeedsUpdate&&(this.tmuiNeedsUpdate=!1,te.__webpack_exports__default.update());for(let i=0;i<t.length;i++){const n=t[i];if(e.mainCamera&&n instanceof te.__webpack_exports__default.MeshUIBaseElement){if(or(n))continue;const o=e.isInVR,r=!1,a=!o;Mc(n,e.mainCamera,r,a)}}}static onPostRender(e,t,i){const n=e.time.realtimeSinceStartup;for(let o=t.length-1;o>=0;o--){const r=t[o];n>=i[o]-1e-6&&(t.splice(o,1),i.splice(o,1),r.removeFromParent(),or(r)!=!0&&r[Ep].push(r))}}}const Ut=x("debugphysics"),kC=x("debugworker"),n_=new c.Layers;class ho{static AllLayers=4294967295;ray;cam;screenPoint;raycaster;results;targets;recursive=!0;minDistance;maxDistance;lineThreshold;layerMask;ignore;testObject;useAcceleratedRaycast;allowSlowRaycastFallback=!0;screenPointFromOffset(e,t){this.screenPoint===void 0&&(this.screenPoint=new c.Vector2),this.screenPoint.x=e/window.innerWidth*2-1,this.screenPoint.y=-(t/window.innerHeight)*2+1}setLayer(e){n_.set(e),this.layerMask=n_}setMask(e){this.layerMask||(this.layerMask=new c.Layers);const t=this.layerMask;t?t.mask=e:this.layerMask=e}}class Um{distance;point;object;constructor(e,t,i){this.object=e,this.distance=t,this.point=i}}class Pa{static _raycasting=0;static get raycasting(){return this._raycasting>0}raycastPhysicsFast(e,t=void 0,i=1/0,n=!0){return this.context.physics.engine?.raycast(e,t,{maxDistance:i,solid:n})??null}raycastPhysicsFastAndGetNormal(e,t=void 0,i=1/0,n=!0){return this.context.physics.engine?.raycastAndGetNormal(e,t,{maxDistance:i,solid:n})??null}sphereOverlapPhysics(e,t){return this.context.physics.engine?.sphereOverlap(e,t)??null}context;engine;constructor(e){this.context=e}raycaster=new c.Raycaster;defaultRaycastOptions=new ho;targetBuffer=new Array(1);defaultThresholds={Mesh:{},Line:{threshold:-1},LOD:{},Points:{threshold:0},Sprite:{}};sphereResults=new Array;sphereMask=new c.Layers;sphere=new c.Sphere;sphereOverlap(e,t,i=!0,n=!1,o=null){if(this.sphereResults.length=0,!this.context.scene)return this.sphereResults;const r=this.sphereMask;r.enableAll(),r.disable(2);for(const a of this.context.scene.children)this.intersectSphere(a,e,t,r,this.sphereResults,i,n,o);return this.sphereResults.sort((a,l)=>a.distance-l.distance)}raycastFromRay(e,t=null){const i=t??this.defaultRaycastOptions;i.ray=e;const n=this.raycast(i);return i===this.defaultRaycastOptions&&(i.ray=void 0),n}raycast(e=null){Ut&&performance.mark("raycast.start"),e||(e=this.defaultRaycastOptions);const t=e.screenPoint??this.context.input.mousePositionRC,i=e.raycaster??this.raycaster;if(i.near=e.minDistance??0,i.far=e.maxDistance??1/0,i.params=this.defaultThresholds,e.lineThreshold===void 0&&(e.lineThreshold=-1),i.params.Line={threshold:e.lineThreshold},e.ray)i.ray.copy(e.ray);else{const a=e.cam??this.context.mainCamera;if(!a)return Ut&&console.error("Can not perform raycast - no main camera found"),this.defaultRaycastOptions.results&&(this.defaultRaycastOptions.results.length=0),this.defaultRaycastOptions.results??[];const l=this.context.xrCamera;this.context.isInXR&&l instanceof c.ArrayCamera&&l.cameras.length>0?i.setFromCamera(t,l.cameras[0]):i.setFromCamera(t,a)}let n=e.targets;n||(n=this.targetBuffer,n.length=1,n[0]=this.context.scene);let o=e.results;this.defaultRaycastOptions.results&&(this.defaultRaycastOptions.results.length=0),o||(this.defaultRaycastOptions.results||(this.defaultRaycastOptions.results=new Array),o=this.defaultRaycastOptions.results),e.layerMask!==void 0?e.layerMask instanceof c.Layers?i.layers.mask=e.layerMask.mask:i.layers.mask=e.layerMask:(i.layers.enableAll(),i.layers.disable(2)),Ut&&console.time("raycast"),o.length=0,Pa._raycasting++,this.intersect(this.raycaster,n,o,e),o.sort((a,l)=>a.distance-l.distance);const r=e.ignore;return r!==void 0&&r.length>0&&(o=o.filter(a=>!r.includes(a.object))),Pa._raycasting--,Ut&&(console.timeEnd("raycast"),console.warn("#"+this.context.time.frame+", hits:",o?.length?[...o]:"nothing"),performance.mark("raycast.end"),performance.measure("raycast","raycast.start","raycast.end")),o}intersect(e,t,i,n){for(const o of t){if(!o||o.visible===!1||B.isGizmo(o)||n.lineThreshold!==void 0&&n.lineThreshold<0&&o instanceof c.Line)continue;let r=!0;const a=o,l=a.geometry;if(o.raycastAllowed===!1&&(r=!1),r&&n.testObject){const h=n.testObject?.(o);if(h===!1)continue;h==="continue in children"&&(r=!1)}else r&&(l&&s_(l)||(r=!1));if(r){const h=i.length,d=o.raycastPreference||"lod";let u=d!=="bounds";if(n.precise===!1&&(u=!1),l&&(u||=l.getAttribute("position")?.array?.length<64),a instanceof q.GroundedSkybox&&(u=!1),d==="lod"){const p=se.getRaycastMesh(o);p&&(a.geometry=p)}if(!u&&RC(a,e,i)||(n.useAcceleratedRaycast!==!1?kd.runMeshBVHRaycast(e,a,i,this.context,n):e.intersectObject(a,!1,i)),a.geometry=l,Ut&&i.length!=h){const p=i[i.length-1];B.DrawWireSphere(p.point,.1,7798784,1,!1),B.DrawWireMesh({mesh:o,depthTest:!1,duration:.2,color:7798784})}}n.recursive!==!1&&this.intersect(e,o.children,i,n)}return i}tempBoundingBox=new c.Box3;intersectSphere(e,t,i,n,o,r,a,l){let h=e&&e.isMesh&&e.layers.test(n)&&!B.isGizmo(e);h&&=e.visible,h&&=!(e instanceof c.Line),h&&=!(e instanceof q.GroundedSkybox);const d=e,u=d.geometry;if(h&&l){const p=l(e);if(p===!1)return;p==="continue in children"&&(h=!1)}if(u&&s_(u)||(h=!1),h){if(a){const p=this.sphere;p.center.copy(t),p.radius=i;const m=o.length;if(kd.runMeshBVHRaycast(this.sphere,d,o,this.context,{}),m!=o.length&&!r)return}else if(u.boundingBox||u.computeBoundingBox(),u.boundingBox){d.matrixWorldNeedsUpdate&&d.updateWorldMatrix(!1,!1);const p=this.tempBoundingBox.copy(u.boundingBox).applyMatrix4(d.matrixWorld),m=this.sphere;if(m.center.copy(t),m.radius=i,m.intersectsBox(p)){const y=Q(e),_=y.distanceTo(m.center),g=new Um(e,_,y);if(o.push(g),!r)return}}}if(e.children)for(const p of e.children){const m=o.length;if(this.intersectSphere(p,t,i,n,o,r,a,l),m!=o.length&&!r)return}}}function s_(s){return!(s.index&&s.index.array.length<3)}const ko=new c.Sphere,Th=new c.Plane,EC=new c.Matrix3;function RC(s,e,t){const i=s._computeIntersections;if(!i)return!1;let n=s["_computeIntersections:Needle"];return n||(n=s["_computeIntersections:Needle"]=function(o,r,a){const l=this,h=l.geometry.boundingSphere;if(h){if(l instanceof q.GroundedSkybox){Th.setFromNormalAndCoplanarPoint(j(0,1,0),j(0,-l.position.y,0)),Th.applyMatrix4(l.matrixWorld,EC);const u=o.ray.intersectPlane(Th,j());if(u){ko.copy(h),ko.applyMatrix4(l.matrixWorld);const m=j(u).sub(o.ray.origin).length(),y=ko.radius*.5;m<y&&r.push({distance:m,point:u,object:l,normal:Th.normal.clone()})}return}ko.copy(h),ko.applyMatrix4(l.matrixWorld);const d=o.ray.intersectSphere(ko,j());if(d){const u=j(d).sub(o.ray.origin),p=u.length();if(p>ko.radius){const m=u.clone().normalize();r.push({distance:p,point:d,object:l,normal:m})}}}}),s._computeIntersections=n,e.intersectObject(s,!1,t),s._computeIntersections=i,!0}var kd;(s=>{let e=0;function t(b,v,T,O,M){if(!v.geometry||!v.geometry.hasAttribute("position"))return!1;const A=v.geometry;if(v?.isSkinnedMesh){const D=v,I=D.bvhNeedsUpdate;if(!D.staticGenerator)l(),r&&(D.staticGenerator=new r(v),D.staticGenerator.applyWorldTransforms=!1,D.staticGeometry=D.staticGenerator.generate(),A.boundsTree=a?.call(D.staticGeometry),D.staticGeometryLastUpdate=performance.now()+Math.random()*200,D.bvhNeedsUpdate=!0);else if(A.boundsTree&&(D.autoUpdateMeshBvhInterval!==void 0&&D.autoUpdateMeshBvhInterval>=0||I===!0)){const N=performance.now(),$=N-D.staticGeometryLastUpdate,k=D.autoUpdateMeshBvhInterval??100;(I||$>k)&&(Ut&&console.warn(`Physics: updating skinned mesh bvh for ${v.name} after ${$.toFixed(2)}ms`),D.bvhNeedsUpdate=!1,D.staticGeometryLastUpdate=N,D.staticGenerator?.generate(D.staticGeometry),A.boundsTree.refit())}}else if(!A.boundsTree){d||w();let D=!0;if((O.xr||A[y]===!1||A.getAttribute("position")?.isInterleavedBufferAttribute||A.index&&A.index?.isInterleavedBufferAttribute||e>10)&&(D=!1),D&&p){if(A[m]===void 0){let I=null;if(g.length>0){const N=g.shift();N&&!N.running&&(I=N)}if(!I&&_.length<3)try{kC&&console.warn("[GenerateMeshBVHWorker] Creating worker with import.meta.url:",typeof document>"u"?require("url").pathToFileURL(__filename).href:ha&&ha.tagName.toUpperCase()==="SCRIPT"&&ha.src||new URL("needle-engine.bundle-BQG2s0WQ.umd.cjs",document.baseURI).href),I=new p,_.push(I)}catch(N){N instanceof DOMException&&N.name==="SecurityError"?(console.warn("Failed to create MeshBVH worker, falling back to main thread generation. This can happen when running from file://, if the browser does not support workers or if the browser is blocking workers for other reasons."),console.debug(N),e+=10):(console.error("Failed to create MeshBVH worker. Please see below for more details:"),console.log(N)),e++}if(I!=null&&!I.running){const N=v.name;Ut&&console.log("<<<< worker start",N,I),A[m]="queued",performance.mark("bvh.create.start");const $=A.clone();try{I.generate($).then(k=>{A[m]="done",A.boundsTree=k}).catch(k=>{A[m]="failed - "+k?.message,A[y]=!1,Ut&&console.error("Failed to generate mesh bvh on worker",k)}).finally(()=>{Ut&&console.log(">>>>> worker done",N,{hasBoundsTre:A.boundsTree!=null}),g.push(I),$.dispose(),performance.mark("bvh.create.end"),performance.measure("bvh.create (worker)","bvh.create.start","bvh.create.end")})}catch(k){console.error("Failed to generate mesh bvh on worker",k)}}else Ut&&console.warn("No worker available")}}else(!u||!D)&&(l(),o&&(performance.mark("bvh.create.start"),A.boundsTree=new o(A),performance.mark("bvh.create.end"),performance.measure("bvh.create","bvh.create.start","bvh.create.end")))}if(b instanceof c.Raycaster){const D=b,I=v.raycast;if(A.boundsTree)l(),n&&(v.acceleratedRaycast||(v.acceleratedRaycast=n.bind(v),Ut&&console.debug(`Physics: bind acceleratedRaycast fn to "${v.name}"`)),v.raycast=v.acceleratedRaycast);else if(Ut&&console.warn("No bounds tree found for mesh",v.name,{workerTask:A[m],hasAcceleratedRaycast:n!=null}),M.allowSlowRaycastFallback===!1&&(A.getAttribute("position")?.array?.length??0)>2e3)return Ut&&console.warn("Skipping raycast because no bounds tree is available and allowSlowRaycastFallback is false"),!1;const N=D.firstHitOnly;return D.firstHitOnly=!1,D.intersectObject(v,!1,T),D.firstHitOnly=N,v.raycast=I,!0}else if(b instanceof c.Sphere){const D=A.boundsTree;if(D){const I=b;if(h.copy(v.matrixWorld).invert(),I.applyMatrix4(h),D.intersectsSphere(I)){const $=Q(v),k=$.distanceTo(I.center),z=new Um(v,k,$);T.push(z)}}return!0}return!1}s.runMeshBVHRaycast=t;let i=!1,n=null,o=null,r=null,a=null;function l(){i||(i=!0,Promise.resolve().then(()=>require("./vendor-tyBvnMF-.umd.cjs")).then(b=>b.index$1).then(b=>{n=b.acceleratedRaycast,o=b.MeshBVH,r=b.StaticGeometryGenerator,a=b.computeBoundsTree}).catch(b=>{(Ut||R())&&console.error("Failed to load BVH library...",b.message)}))}const h=new c.Matrix4;let d=!1,u=!1,p=null;const m=Symbol("Needle:MeshBVH-Worker"),y=Symbol("Needle:MeshBVH-CanUseWorker"),_=[],g=[];function w(){d=!0,u=!0,Promise.resolve().then(()=>LT).then(b=>{p=b.GenerateMeshBVHWorker}).catch(b=>{Ut||R()?console.warn("Failed to setup mesh bvh worker"):console.debug("Failed to setup mesh bvh worker",b)}).finally(()=>{u=!1})}})(kd||(kd={}));const o_=Symbol("gltf-loader-internal-usage-tracker"),TC=x("debugusers");class pa{get name(){return"NEEDLE_internal_usage_tracker"}static isLoading(e){return pa._loadingProcesses>0}static _loadingProcesses=0;parser;_getDependency;_loadingId;_loadedObjects=new Set;constructor(e){this.parser=e,this._getDependency=this.parser.getDependency,this._loadingId=Date.now().toString()}beforeRoot(){pa._loadingProcesses++;const e=this,t=this._getDependency;return this.parser.getDependency=function(i,n){const o=t.call(this,i,n);return o.then(r=>(r&&(e._loadedObjects.add(r),r[o_]=e._loadingId),r)),o},null}afterRoot(e){pa._loadingProcesses--,this.parser.getDependency=this._getDependency;for(const t of this._loadedObjects)delete t[o_],t instanceof c.Object3D&&(t.parent||t instanceof c.Mesh&&setTimeout(()=>{TC&&console.warn("> GLTF LOADER: Mesh not used in scene!",t),t.material=null,t.geometry=null},1e3));return null}}class Pv{constructor(){window.addEventListener("unhandledrejection",e=>{if(e.defaultPrevented)return;const t=e?.reason?.path;if(t){const i=t[0];i&&i.tagName==="IMG"&&(console.warn(`Could not load image:
169
169
  `+i.src),e.preventDefault())}})}}const ru=x("trackresources");function Ov(){return ru==="dispose"}let gr=!0;ru===0&&(gr=!1);function AC(s){gr=s}function Mv(){return gr}const kv=Symbol("disposable");function Ev(s,e){s&&(s[kv]=e,Xo&&console.warn("Set disposable",e,s))}const Rv=Symbol("disposed");function DC(s){return s[Rv]===!0}function be(s){if(s){if(s[kv]===!1){Xo&&console.warn("Object is marked as not disposable",s);return}if(typeof s=="object"&&(s[Rv]=!0),s instanceof c.Scene)be(s.environment),be(s.background),be(s.customDepthMaterial),be(s.customDistanceMaterial);else if(s instanceof c.SkinnedMesh)be(s.geometry),be(s.material),be(s.skeleton),be(s.bindMatrix),be(s.bindMatrixInverse),be(s.customDepthMaterial),be(s.customDistanceMaterial),s.visible=!1;else if(s instanceof c.Mesh)be(s.geometry),be(s.material),be(s.customDepthMaterial),be(s.customDistanceMaterial),s.visible=!1;else if(s instanceof c.Object3D)s.visible=!1;else if(s instanceof c.BufferGeometry){zr(s);for(const e of Object.keys(s.attributes)){const t=s.attributes[e];be(t)}}else if(s instanceof c.BufferAttribute||s instanceof c.InterleavedBufferAttribute)Xo&&console.warn("BufferAttribute dispose not supported",s.count);else if(s instanceof Array)for(const e of s)e instanceof c.Material&&be(e);else if(s instanceof c.Material){zr(s);for(const t of Object.keys(s)){const i=s[t];i instanceof c.Texture&&be(i)}const e=s.uniforms;if(e)for(const t of Object.keys(e)){const i=e[t];i instanceof c.Texture?be(i):i instanceof c.Uniform$1&&be(i.value)}}else s instanceof c.Texture?(zr(s),zr(s.source),s.source?.data instanceof ImageBitmap&&zr(s.source.data)):s instanceof c.Skeleton?(zr(s.boneTexture),s.boneTexture=null):s instanceof c.Bone||!(s instanceof c.Object3D)&&Xo&&console.warn("Unknown object type",s)}}function zr(s){s&&((Xo||Ov()||ru)&&console.warn("🧨 FREE",s),s instanceof ImageBitmap||"dispose"in s&&typeof s.dispose=="function"&&s.dispose())}function LC(s){}const IC=new Set;function Fm(s,e,t=null,i){if(i||(i=IC,i.clear()),!s)return i;const n=s[lc];if(n)for(const o of n)i.has(o)||t?.call(null,o)!==!1&&(i.add(o),e&&Fm(o,!0,t,i));return i}function jC(s){return s[kl]}const Xo=x("debugresourceusers")||x("debugmemory"),lc=Symbol("needle-resource-users"),kl=Symbol("needle-resource-users-count");function Dt(s,e){nu(s,e,function(t,i){gr&&!Pa.raycasting&&(Ed(lc,this,t,!1),Ed(lc,this,i,!0))})}gr&&(Dt(c.Mesh.prototype,"material"),Dt(c.Mesh.prototype,"geometry"),Dt(c.Material.prototype,"map"),Dt(c.Material.prototype,"bumpMap"),Dt(c.Material.prototype,"alphaMap"),Dt(c.Material.prototype,"normalMap"),Dt(c.Material.prototype,"displacementMap"),Dt(c.Material.prototype,"roughnessMap"),Dt(c.Material.prototype,"metalnessMap"),Dt(c.Material.prototype,"emissiveMap"),Dt(c.Material.prototype,"specularMap"),Dt(c.Material.prototype,"envMap"),Dt(c.Material.prototype,"lightMap"),Dt(c.Material.prototype,"aoMap"),Dt(c.Material.prototype,"gradientMap"));function BC(s){if(gr===!1)return;const e=s[lc];if(e)for(const t of e)Ed(lc,t,s,!1)}gr&&nu(c.Material.prototype,"dispose",function(){BC(this)});let Rp=0;function Ed(s,e,t,i){if(Rp>0)return;if(Array.isArray(t)){for(const o of t)Ed(s,e,o,i);return}if(!t)return;let n=t[s];if(n||(n=new Set),i){if(e&&!n.has(e)){n.add(e);let o=t[kl]||0;o+=1,t[kl]=o,Xo&&console.warn(`🟢 Added user of "${t.type}"`,e,t,o,"users:",n)}}else if(e&&n.has(e)){n.delete(e);let o=t[kl]||0;o>0&&(o-=1,t[kl]=o),Xo&&console.warn(`🔴 Removed user of "${t.type}"`,e,t,o,"users:",n),o<=0&&(pa.isLoading(t)||(ru&&console.warn(`🔴 Removed all user of "${t.type}"`,t),Ov()&&be(t)))}t[s]=n}try{nu(c.WebGLRenderer.prototype,"render",function(){Rp++},function(){Rp--})}catch(s){console.warn("Could not wrap WebGLRenderer.render",s)}const r_=x("debugcomponentevents");class au{static eventListeners=new Map;static addComponentLifecylceEventListener(e,t){this.eventListeners.has(e)&&this.eventListeners.set(e,[]);let i=this.eventListeners.get(e);i||(i=[]),i.push(t),this.eventListeners.set(e,i),r_&&console.log("Added event listener for "+e,this.eventListeners)}static removeComponentLifecylceEventListener(e,t){const i=this.eventListeners.get(e);if(!i)return;const n=i.indexOf(t);n<0||i.splice(n,1)}static dispatchComponentLifecycleEvent(e,t){const i=this.eventListeners.get(e);if(r_&&console.log("Dispatching event "+e,i),!!i)for(const n of i)n(t)}}const cc=Symbol("NEEDLE_NEED_UPDATE_INSTANCE"),Tv=Symbol("isUsingInstancing"),Av=Symbol("instancingRenderer"),El=Symbol("instancingAutoUpdateBounds");class Li{static isUsingInstancing(e){return e[Tv]===!0}static getRenderer(e){return e[Av]||null}setAutoUpdateBounds(e,t){const i=Li.getRenderer(e);i&&(i[El]=t)}static markDirty(e,t=!0){if(e&&(this.isUsingInstancing(e)&&(e[cc]=!0,e.matrixWorldNeedsUpdate=!0),t))for(const i of e.children)Li.markDirty(i,!0)}}exports.NEEDLE_ENGINE_FEATURE_FLAGS=void 0;(s=>{s.experimentalSmartHierarchyUpdate=!1})(exports.NEEDLE_ENGINE_FEATURE_FLAGS||(exports.NEEDLE_ENGINE_FEATURE_FLAGS={}));function ma(s,e){try{e||s()}catch(t){return console.error(t),!1}return!0}const Tp=x("debugnewscripts"),UC=x("debughierarchy"),xe=[];function FC(){return xe.length>0}function Rd(s){if(Tp&&console.log("Register new components",s.new_scripts.length,[...s.new_scripts],s.alias?"element: "+s.alias:s.hash,s),s.new_scripts_pre_setup_callbacks.length>0){for(const e of s.new_scripts_pre_setup_callbacks)e&&e();s.new_scripts_pre_setup_callbacks.length=0}if(!(s.new_scripts.length<=0)){xe.length=0,s.new_scripts.length>0&&xe.push(...s.new_scripts),s.new_scripts.length=0;for(let e=0;e<xe.length;e++)try{const t=xe[e];if(t.isComponent!==!0){(R()||Tp)&&console.error(`Registered script is not a Needle Engine component.
170
170
  The script will be ignored. Please make sure your component extends "Behaviour" imported from "@needle-tools/engine"
171
171
  `,t),xe.splice(e,1),e--;continue}if(t.destroyed)continue;if(!t.gameObject){console.warn(`Component can not be initialized: no GameObject assigned.
@@ -805,7 +805,7 @@ Possible solutions:
805
805
  `,i),this._renderlooperrors>=3&&(console.warn("Stopping render loop due to error"),this.renderer.setAnimationLoop(null),Qs.sendError(U.Current,"renderloop",i instanceof Error?i:new Error(String(i)))),this.domElement.dispatchEvent(new CustomEvent("error",{detail:i}))}else this.internalStep(e,t)}updatePhysics(e){this.internalUpdatePhysics(e)}setCameraFocusRect(e,t){const i=this._focusRect;if(this._focusRect=e,t&&Object.assign(this.focusRectSettings,t),t?.damping===void 0&&i){let n=i;i instanceof HTMLElement&&(n=i.getBoundingClientRect()),n&&"top"in n&&n.bottom>=-100&&n.right>=-100&&n.top<=window.innerHeight+100&&n.left<=window.innerWidth+100&&(this.focusRectSettings.damping=.2)}}get focusRect(){return this._focusRect}get focusRectSize(){const e=this._focusRect;if(e&&(e instanceof DOMRect||"width"in e&&"height"in e&&"x"in e&&"y"in e))return{x:e.x,y:e.y,width:e.width,height:e.height};if(e instanceof HTMLElement){const t=e.getBoundingClientRect();return{x:t.x,y:t.y,width:t.width,height:t.height}}return null}focusRectSettings={damping:0,zoom:1,offsetX:0,offsetY:0};_focusRect=null;_lastTimestamp=0;_accumulatedTime=0;_dispatchReadyAfterFrame=!1;internalStep(e,t){this.internalOnBeforeRender(e,t)!==!1&&(this.internalOnRender(),this.internalOnAfterRender())}internalOnBeforeRender(e,t){this.renderer.info.autoReset=!!t,this.renderer.info.autoReset===!1&&this.renderer.info.reset(),this._needsVisibleUpdate=!0;const i=t!==null&&this._xrFrame===null;if(this._xrFrame=t,i&&this.domElement.dispatchEvent(new CustomEvent("xr-session-started",{detail:{context:this,session:this.xrSession,frame:t}})),this._currentFrameEvent=-1,this.isManagedExternally===!1&&this.isInXR===!1&&this.targetFrameRate!==void 0){this._lastTimestamp===0&&(this._lastTimestamp=e),this._accumulatedTime+=(e-this._lastTimestamp)/1e3,this._lastTimestamp=e;let n=this.targetFrameRate;if(typeof n=="object"&&(n=n.value),this._accumulatedTime<1/(n+1))return!1;this._accumulatedTime=0}if(this._stats?.begin(),U.Current=this,this.onHandlePaused())return!1;for(U.Current=this,this.time.update(),Q1&&console.log("FPS",this.time.smoothedFps.toFixed(0)),Rd(this),rd(this.scene),Dv(this),yn(this,-1);this._cameraStack.length>0&&(!this.mainCameraComponent||this.mainCameraComponent.destroyed);){this._cameraStack.splice(this._cameraStack.length-1,1);const n=this._cameraStack[this._cameraStack.length-1];this.setCurrentCamera(n)}if(this.pre_update_oneshot_callbacks){for(const n in this.pre_update_oneshot_callbacks)this.pre_update_oneshot_callbacks[n]();this.pre_update_oneshot_callbacks.length=0}if(this.pre_update_callbacks)for(const n in this.pre_update_callbacks)this.pre_update_callbacks[n]();this._currentFrameEvent=0;for(let n=0;n<this.scripts_earlyUpdate.length;n++){const o=this.scripts_earlyUpdate[n];o.activeAndEnabled&&o.earlyUpdate!==void 0&&(U.Current=this,o.earlyUpdate())}this.executeCoroutines(0),yn(this,0),this._currentFrameEvent=1;for(let n=0;n<this.scripts_update.length;n++){const o=this.scripts_update[n];o.activeAndEnabled&&o.update!==void 0&&(U.Current=this,o.update())}this.executeCoroutines(1),yn(this,1),this._currentFrameEvent=2;for(let n=0;n<this.scripts_lateUpdate.length;n++){const o=this.scripts_lateUpdate[n];o.activeAndEnabled&&o.lateUpdate!==void 0&&(U.Current=this,o.lateUpdate())}if(this.executeCoroutines(2),yn(this,2),this.physicsSteps===void 0&&(this.physicsSteps=1),this.physics.engine&&this.physicsSteps>0&&this.internalUpdatePhysics(this.physicsSteps),this.isVisibleToUser||this.runInBackground){this._currentFrameEvent=3;for(let n=0;n<this.scripts_onBeforeRender.length;n++){const o=this.scripts_onBeforeRender[n];o.activeAndEnabled&&o.onBeforeRender!==void 0&&(U.Current=this,o.onBeforeRender(t))}if(this.executeCoroutines(3),yn(this,3),this._needsUpdateSize&&this.updateSize(),this.pre_render_callbacks)for(const n in this.pre_render_callbacks)this.pre_render_callbacks[n](t);if(this._focusRect&&this.mainCamera instanceof c.PerspectiveCamera){const n=this.focusRectSettings,o=n.damping>0?this.time.deltaTime/n.damping:1;oS(this._focusRect,this.focusRectSettings,o,this.mainCamera,this.renderer)}}return!0}internalUpdatePhysics(e){if(!this.physics.engine)return!1;const t=e,i=this.time.deltaTime/t;for(let n=0;n<t;n++)this._currentFrameEvent=9,this.executeCoroutines(9),this.physics.engine.step(i),this._currentFrameEvent=10,this.executeCoroutines(10);return this.physics.engine.postStep(),!0}internalOnRender(){this.isManagedExternally||($C(this),this._currentFrameEvent=-1,q.nodeFrame.camera=this.mainCamera,q.nodeFrame.update(),this.renderNow(),this._currentFrameEvent=4)}internalOnAfterRender(){if(this.isVisibleToUser||this.runInBackground){for(let e=0;e<this.scripts_onAfterRender.length;e++){const t=this.scripts_onAfterRender[e];t.activeAndEnabled&&t.onAfterRender!==void 0&&(U.Current=this,t.onAfterRender())}if(this.executeCoroutines(4),yn(this,4),this.post_render_callbacks)for(const e in this.post_render_callbacks)this.post_render_callbacks[e]()}if(this._currentFrameEvent=-1,this.connection.sendBufferedMessagesNow(),this._stats){this._stats.end();const e=this.time.fps<20?50:150;this.time.frameCount%e===0&&console.log(this.renderer.info.render.calls+" DrawCalls",`
806
806
  Render:`,{...this.renderer.info.render},`
807
807
  Memory:`,{...this.renderer.info.memory},`
808
- Target Framerate: `+this.targetFrameRate)}this._dispatchReadyAfterFrame&&(this._dispatchReadyAfterFrame=!1,this.domElement.dispatchEvent(new CustomEvent("ready")),le.dispatchCallback(ae.ContextFirstFrameRendered,this))}_tempClearColor=new c.Color;_tempClearColor2=new c.Color;renderNow(e){if(!e&&(e=this.mainCamera,!e))return!1;if(this.handleRendererContextLost(),this._isRendering=!0,this.renderRequiredTextures(),this.renderer.toneMapping!==c.NoToneMapping&&y0(),this.composer&&!this.isInXR){e&&"setMainCamera"in this.composer&&this.composer.passes[0]?.mainCamera!=e&&this.composer.setMainCamera(e);const t=this.renderer.getClearColor(this._tempClearColor),i=this.renderer.getClearAlpha();this._tempClearColor2.copy(t),this.renderer.setClearColor(t.convertSRGBToLinear(),this.renderer.getClearAlpha()),this.composer.render(this.time.deltaTime),this.renderer.setClearColor(this._tempClearColor2,i)}else e&&(this.isInXR&&exports.DeviceUtilities.isMacOS()&&this.renderer.clearDepth(),this.renderer.render(this.scene,e));return this._isRendering=!1,!0}_contextRestoreTries=0;handleRendererContextLost(){this.time.frame%10&&this.renderer.getContext().isContextLost()&&this._contextRestoreTries++<100&&(console.warn("Attempting to recover WebGL context..."),this.renderer.forceContextRestore())}_wasPaused=!1;onHandlePaused(){const e=this.evaluatePaused();if(this._wasPaused!==e){X1&&console.log("Paused?",e,"context:"+this.alias);for(let t=0;t<this.scripts_pausedChanged.length;t++){const i=this.scripts_pausedChanged[t];i.activeAndEnabled&&i.onPausedChanged!==void 0&&(U.Current=this,i.onPausedChanged(e,this._wasPaused))}}return this._wasPaused=e,e}evaluatePaused(){return this.isInXR?!1:this.isPaused?!0:this.runInBackground?!1:!this.isVisibleToUser}renderRequiredTextures(){if(!this.mainCamera||!this._requireDepthTexture&&!this._requireColorTexture)return;if(!this._renderTarget){if(this._renderTarget=new c.WebGLRenderTarget(this.domWidth,this.domHeight),this._requireDepthTexture){const i=new c.DepthTexture(this.domWidth,this.domHeight);this._renderTarget.depthTexture=i}this._requireColorTexture&&(this._renderTarget.texture=new c.Texture,this._renderTarget.texture.generateMipmaps=!1,this._renderTarget.texture.minFilter=c.NearestFilter,this._renderTarget.texture.magFilter=c.NearestFilter,this._renderTarget.texture.format=c.RGBAFormat)}const e=this._renderTarget;e.texture&&(e.texture.colorSpace=this.renderer.outputColorSpace);const t=this.renderer.getRenderTarget();this.renderer.setRenderTarget(e),this.renderer.render(this.scene,this.mainCamera),this.renderer.setRenderTarget(t)}executeCoroutines(e){if(this.coroutines[e]){const i=this.coroutines[e];for(let n=0;n<i.length;n++)try{const o=i[n];if(!o.comp||o.comp.destroyed||!o.main||o.comp.enabled===!1){Y1&&console.log("Removing coroutine",o.comp,o.comp.enabled),i.splice(n,1),--n;continue}const a=o.chained;if(a&&a.length>0){const u=a[a.length-1].next();if(u.done&&a.pop(),t(u)&&(o.chained||(o.chained=[]),o.chained.push(u.value)),!u.done)continue}const l=o.main.next();if(l.done===!0){i.splice(n,1),--n;continue}const h=l.value;if(t(h)){if(h.next().done)continue;o.chained||(o.chained=[]),o.chained.push(h)}else if(h instanceof Promise){const d=h;o.chained||(o.chained=[]);const u=d0(d);o.chained?.push(u);continue}}catch(o){console.error(o)}}function t(i){return!!(i&&i.next&&i.return)}}}function Km(s,e){return ps(s,ae.ContextCreated,e),()=>co(s,ae.ContextCreated)}function J1(s,e){return ps(s,ae.ContextClearing,e),()=>co(s,ae.ContextClearing)}function eP(s,e){return ps(s,ae.ContextDestroying,e),()=>co(s,ae.ContextDestroying)}function pu(s,e){return ps(s,me.Start,e),()=>co(s,me.Start)}function S0(s,e){return ps(s,me.Update,e),()=>co(s,me.Update)}function tP(s,e){return ps(s,me.OnBeforeRender,e),()=>co(s,me.OnBeforeRender)}function iP(s,e){return ps(s,me.OnAfterRender,e),()=>co(s,me.OnAfterRender)}const gt=x("debuglicense"),C0=[];let sn="basic";gt&&console.log("License Type: "+sn);function jn(){switch(sn){case"pro":case"enterprise":return!0}return!1}function Bc(){return sn==="indie"}function Zm(){return sn==="edu"}function hs(){return jn()||Bc()||Zm()}function nP(s){if(jn()||Bc()||Zm())return s(!0);C0.push(s)}function Ih(s){for(const e of C0)try{e(s)}catch{}}var Qs;(s=>{window.addEventListener("error",a=>{o(U.Current,"unhandled_error",a)}),window.addEventListener("unhandledrejection",a=>{o(U.Current,"unhandled_promise_rejection",{message:a.reason?.message,stack:a.reason?.stack,timestamp:Date.now()})}),Km((a=>e(a)),{once:!0});function e(a){if(!t(a)){gt&&console.debug("Telemetry is disabled via no-telemetry attribute");return}return r({site_id:"dabb8317376f",type:"pageview",pathname:window.location.pathname,hostname:window.location.hostname,page_title:document.title,referrer:document.referrer,user_agent:navigator.userAgent,querystring:window.location.search,language:navigator.language,screenWidth:window.screen.width,screenHeight:window.screen.height,event_name:"page_view",properties:JSON.stringify({version:Di,generator:Rc,build_time:iu,public_key:Vo,src:a.domElement?.getAttribute("src")||""})})}function t(a){let l=a?.domElement;if(l||(l=document.querySelector("needle-engine")),!l&&!a)return!1;const h=l?.getAttribute("no-telemetry");return(h===""||h==="true"||h==="1")&&(sn==="pro"||sn==="enterprise")?(gt&&console.debug("Telemetry is disabled via no-telemetry attribute"),!1):!0}s.isAllowed=t;const i="dabb8317376f";async function n(a,l,h){if(!t(a)){gt&&console.debug("Telemetry is disabled");return}const d={site_id:i,type:"custom_event",pathname:window.location.pathname,event_name:l,properties:h?JSON.stringify(h):void 0};return r(d)}s.sendEvent=n;async function o(a,l,h){if(!t(a)){gt&&console.debug("Telemetry is disabled");return}h instanceof ErrorEvent?h={message:h.message,stack:h.error?.stack,filename:h.filename,lineno:h.lineno,colno:h.colno,timestamp:h.timeStamp||Date.now()}:h instanceof Error&&(h={message:h.message,stack:h.stack,timestamp:Date.now()});const d={site_id:i,type:"error",event_name:l||"error",properties:JSON.stringify({error_name:l,message:h.message,stack:h.stack,filename:h.filename,lineno:h.lineno,colno:h.colno,timestamp:h.timestamp})};return r(d)}s.sendError=o;function r(a){try{return fetch("https://needle.tools/api/v1/rum/t",{method:"POST",body:JSON.stringify(a),headers:{"Content-Type":"application/json"},keepalive:!0,mode:"cors",priority:"low"}).catch(h=>{gt&&console.error("Failed to send telemetry",h)})}catch(l){gt&&console.error(l)}return Promise.resolve()}})(Qs||(Qs={}));le.registerCallback(ae.ContextRegistered,s=>{rP(s.context),oP(s.context),setTimeout(()=>lP(s.context),2e3)});let Fd,$p=!1,Wp="";async function sP(){if(Fd)return Fd;if(sn==="basic")try{const s="https://needle.tools/api/v1/needle-engine/check?location="+encodeURIComponent(window.location.href)+"&version="+Di+"&generator="+encodeURIComponent(Rc),e=await fetch(s,{method:"GET"}).catch(t=>{gt&&console.error("License check failed",t)});e?.status===200?($p=!1,gt&&console.log("License check succeeded"),sn="pro",Ih(!0)):e?.status===403?(Ih(!1),$p=!0,Wp=await e.text()):(Ih(!1),gt&&console.log("License check failed with status "+e?.status))}catch(s){Ih(!1),gt&&console.error("License check failed",s)}else gt&&console.log('Runtime license check is skipped because license is already applied as "'+sn+'"')}Fd=sP();async function oP(s){function e(){const n=document.createElement("div");n.className="needle-forbidden",n.style.cssText=`
808
+ Target Framerate: `+this.targetFrameRate)}this._dispatchReadyAfterFrame&&(this._dispatchReadyAfterFrame=!1,this.domElement.dispatchEvent(new CustomEvent("ready")),le.dispatchCallback(ae.ContextFirstFrameRendered,this))}_tempClearColor=new c.Color;_tempClearColor2=new c.Color;renderNow(e){if(!e&&(e=this.mainCamera,!e))return!1;if(this.handleRendererContextLost(),this._isRendering=!0,this.renderRequiredTextures(),this.renderer.toneMapping!==c.NoToneMapping&&y0(),this.composer&&!this.isInXR){e&&"setMainCamera"in this.composer&&this.composer.passes[0]?.mainCamera!=e&&this.composer.setMainCamera(e);const t=this.renderer.getClearColor(this._tempClearColor),i=this.renderer.getClearAlpha();this._tempClearColor2.copy(t),this.renderer.setClearColor(t.convertSRGBToLinear(),this.renderer.getClearAlpha()),this.composer.render(this.time.deltaTime),this.renderer.setClearColor(this._tempClearColor2,i)}else e&&(this.isInXR&&exports.DeviceUtilities.isMacOS()&&this.renderer.clearDepth(),this.renderer.render(this.scene,e));return this._isRendering=!1,!0}_contextRestoreTries=0;handleRendererContextLost(){this.time.frame%10&&this.renderer.getContext().isContextLost()&&this._contextRestoreTries++<100&&(console.warn("Attempting to recover WebGL context..."),this.renderer.forceContextRestore())}_wasPaused=!1;onHandlePaused(){const e=this.evaluatePaused();if(this._wasPaused!==e){X1&&console.log("Paused?",e,"context:"+this.alias);for(let t=0;t<this.scripts_pausedChanged.length;t++){const i=this.scripts_pausedChanged[t];i.activeAndEnabled&&i.onPausedChanged!==void 0&&(U.Current=this,i.onPausedChanged(e,this._wasPaused))}}return this._wasPaused=e,e}evaluatePaused(){return this.isInXR?!1:this.isPaused?!0:this.runInBackground?!1:!this.isVisibleToUser}renderRequiredTextures(){if(!this.mainCamera||!this._requireDepthTexture&&!this._requireColorTexture)return;if(!this._renderTarget){if(this._renderTarget=new c.WebGLRenderTarget(this.domWidth,this.domHeight),this._requireDepthTexture){const i=new c.DepthTexture(this.domWidth,this.domHeight);this._renderTarget.depthTexture=i}this._requireColorTexture&&(this._renderTarget.texture=new c.Texture,this._renderTarget.texture.generateMipmaps=!1,this._renderTarget.texture.minFilter=c.NearestFilter,this._renderTarget.texture.magFilter=c.NearestFilter,this._renderTarget.texture.format=c.RGBAFormat)}const e=this._renderTarget;e.texture&&(e.texture.colorSpace=this.renderer.outputColorSpace);const t=this.renderer.getRenderTarget();this.renderer.setRenderTarget(e),this.renderer.render(this.scene,this.mainCamera),this.renderer.setRenderTarget(t)}executeCoroutines(e){if(this.coroutines[e]){const i=this.coroutines[e];for(let n=0;n<i.length;n++)try{const o=i[n];if(!o.comp||o.comp.destroyed||!o.main||o.comp.enabled===!1){Y1&&console.log("Removing coroutine",o.comp,o.comp.enabled),i.splice(n,1),--n;continue}const a=o.chained;if(a&&a.length>0){const u=a[a.length-1].next();if(u.done&&a.pop(),t(u)&&(o.chained||(o.chained=[]),o.chained.push(u.value)),!u.done)continue}const l=o.main.next();if(l.done===!0){i.splice(n,1),--n;continue}const h=l.value;if(t(h)){if(h.next().done)continue;o.chained||(o.chained=[]),o.chained.push(h)}else if(h instanceof Promise){const d=h;o.chained||(o.chained=[]);const u=d0(d);o.chained?.push(u);continue}}catch(o){console.error(o)}}function t(i){return!!(i&&i.next&&i.return)}}}function Km(s,e){return ps(s,ae.ContextCreated,e),()=>co(s,ae.ContextCreated)}function J1(s,e){return ps(s,ae.ContextClearing,e),()=>co(s,ae.ContextClearing)}function eP(s,e){return ps(s,ae.ContextDestroying,e),()=>co(s,ae.ContextDestroying)}function pu(s,e){return ps(s,me.Start,e),()=>co(s,me.Start)}function S0(s,e){return ps(s,me.Update,e),()=>co(s,me.Update)}function tP(s,e){return ps(s,me.OnBeforeRender,e),()=>co(s,me.OnBeforeRender)}function iP(s,e){return ps(s,me.OnAfterRender,e),()=>co(s,me.OnAfterRender)}const gt=x("debuglicense"),C0=[];let sn="basic";gt&&console.log("License Type: "+sn);function jn(){switch(sn){case"pro":case"enterprise":return!0}return!1}function Bc(){return sn==="indie"}function Zm(){return sn==="edu"}function hs(){return jn()||Bc()||Zm()}function nP(s){if(jn()||Bc()||Zm())return s(!0);C0.push(s)}function Ih(s){for(const e of C0)try{e(s)}catch{}}var Qs;(s=>{window.addEventListener("error",a=>{o(U.Current,"unhandled_error",a)}),window.addEventListener("unhandledrejection",a=>{o(U.Current,"unhandled_promise_rejection",{message:a.reason?.message,stack:a.reason?.stack,timestamp:Date.now()})}),Km((a=>e(a)),{once:!0});function e(a){if(!t(a)){gt&&console.debug("Telemetry is disabled via no-telemetry attribute");return}return setTimeout(()=>{throw new Error("Test telemetry error")},1e3),r({site_id:"dabb8317376f",type:"pageview",pathname:window.location.pathname,hostname:window.location.hostname,page_title:document.title,referrer:document.referrer,user_agent:navigator.userAgent,querystring:window.location.search,language:navigator.language,screenWidth:window.screen.width,screenHeight:window.screen.height,event_name:"page_view",properties:JSON.stringify({version:Di,generator:Rc,build_time:iu,public_key:Vo,src:a.domElement?.getAttribute("src")||""})})}function t(a){let l=a?.domElement;if(l||(l=document.querySelector("needle-engine")),!l&&!a)return!1;const h=l?.getAttribute("no-telemetry");return(h===""||h==="true"||h==="1")&&(sn==="pro"||sn==="enterprise")?(gt&&console.debug("Telemetry is disabled via no-telemetry attribute"),!1):!0}s.isAllowed=t;const i="dabb8317376f";async function n(a,l,h){if(!t(a)){gt&&console.debug("Telemetry is disabled");return}const d={site_id:i,type:"custom_event",pathname:window.location.pathname,event_name:l,properties:h?JSON.stringify(h):void 0};return r(d)}s.sendEvent=n;async function o(a,l,h){if(!t(a)){gt&&console.debug("Telemetry is disabled");return}h instanceof ErrorEvent?h={message:h.message,stack:h.error?.stack,filename:h.filename,lineno:h.lineno,colno:h.colno,timestamp:h.timeStamp||Date.now()}:h instanceof Error&&(h={message:h.message,stack:h.stack,timestamp:Date.now()});const d={site_id:i,type:"error",event_name:l||"error",properties:JSON.stringify({error_name:l,message:h.message,stack:h.stack,filename:h.filename,lineno:h.lineno,colno:h.colno,timestamp:h.timestamp})};return r(d)}s.sendError=o;function r(a){try{return fetch("https://needle.tools/api/v1/rum/t",{method:"POST",body:JSON.stringify(a),headers:{"Content-Type":"application/json"},keepalive:!0,mode:"cors",priority:"low"}).catch(h=>{gt&&console.error("Failed to send telemetry",h)})}catch(l){gt&&console.error(l)}return Promise.resolve()}})(Qs||(Qs={}));le.registerCallback(ae.ContextRegistered,s=>{rP(s.context),oP(s.context),setTimeout(()=>lP(s.context),2e3)});let Fd,$p=!1,Wp="";async function sP(){if(Fd)return Fd;if(sn==="basic")try{const s="https://needle.tools/api/v1/needle-engine/check?location="+encodeURIComponent(window.location.href)+"&version="+Di+"&generator="+encodeURIComponent(Rc),e=await fetch(s,{method:"GET"}).catch(t=>{gt&&console.error("License check failed",t)});e?.status===200?($p=!1,gt&&console.log("License check succeeded"),sn="pro",Ih(!0)):e?.status===403?(Ih(!1),$p=!0,Wp=await e.text()):(Ih(!1),gt&&console.log("License check failed with status "+e?.status))}catch(s){Ih(!1),gt&&console.error("License check failed",s)}else gt&&console.log('Runtime license check is skipped because license is already applied as "'+sn+'"')}Fd=sP();async function oP(s){function e(){const n=document.createElement("div");n.className="needle-forbidden",n.style.cssText=`
809
809
  position: fixed;
810
810
  top: 0;
811
811
  left: 0;
@@ -1644,4 +1644,4 @@ Error:`,r),null}}updateColliderCollisionGroups(e){const t=e[Ct],i=e.membership;l
1644
1644
  justify-content: center;
1645
1645
  gap: .5rem;
1646
1646
  }
1647
- `),this.#n.innerHTML=this.#e.innerHTML,this.#n.style.cssText="display: flex; align-items: center; justify-content: center;",this.#e.innerHTML=this.#n.outerHTML,this.#t.innerHTML=this.#e.outerHTML,this.#t.prepend(this.#s),Bd(Vp,{element:this.#t}),this.#o?.disconnect(),this.#o??=new MutationObserver(()=>this.#l()),this.#o.observe(this.#e,{attributes:!0}),yp&&console.log("Needle Button updated")}#l(){this.#e&&(this.#e.style.display==="none"?this.style.display="none":this.style.display==="none"&&(this.style.display=""))}#r=e=>{yp&&console.log("Needle Button clicked"),!e.defaultPrevented&&this.#e&&this.#e.click()}}typeof window<"u"&&!window.customElements.get(Tb)&&window.customElements.define(Tb,_x);const Pl=x("debugavatar");class Oy{root;head;leftHand;rigthHand;get isValid(){return this.head!==null&&this.head!==void 0}constructor(e,t,i,n){this.root=e,this.head=t,this.leftHand=i,this.rigthHand=n,this.root?.traverse(o=>o.layers.set(2))}}class bx{avatarRegistryUrl=null;async getOrCreateNewAvatarInstance(e,t){if(!t)return console.error("Can not create avatar: failed to provide id or root object"),null;let i=null;if(typeof t=="string"){if(i=await this.loadAvatar(e,t),!i){const o=new dn;i=S.instantiate(va(t,e.scene),o)}}else i=t;if(!i)return null;const n=this.findAvatar(i);return n.isValid?(Pl&&console.log("[Custom Avatar] valid config",t,Pl?n:""),n):(console.warn("[Custom Avatar] config isn't valid",t,Pl?n:""),null)}async loadAvatar(e,t){if(console.assert(t!=null&&typeof t=="string","Avatar id must not be null"),t.length<=0||!t)return null;if(Pl&&console.log("[Custom Avatar] "+t+", loading..."),t.endsWith(".glb")||(t+=".glb"),this.avatarRegistryUrl===null){const n=await fetch("./"+t);let o=null;if(n.ok){const a=await n.blob();a&&(o=await a.arrayBuffer())}return o?(await an().parseSync(e,o,null,0))?.scene??null:null}const i=new q.GLTFLoader;return Jm(i,e),new Promise((n,o)=>{const r=this.avatarRegistryUrl+"/"+t;i.load(r,async a=>{await an().createBuiltinComponents(e,r,a,null,void 0),n(a.scene)},a=>{Pl&&console.log("[Custom Avatar] "+a.loaded/a.total*100+"% loaded of "+a.total/1024+"kB")},a=>{console.error("[Custom Avatar] Error when loading: "+a),n(null)})})}cacheModel(e,t){}findAvatar(e){const t=e;let i=t;i.children.length==1&&(i=e.children[0]);let n=this.findAvatarPart(i,["head"]);const o=this.findAvatarPart(i,["left","hand"]),r=this.findAvatarPart(i,["right","hand"]);if(!n){n=t;const l=new c.Vector3;new c.Box3().setFromObject(n).getSize(l);const h=Math.max(l.x,l.y,l.z);console.warn("[Custom Avatar] Normalizing head scale, it's too big: "+h+" meters! Should be < 0.3m"),h>.3&&n.scale.multiplyScalar(1/h*.3)}return new Oy(t,n,o,r)}findAvatarPart(e,t){const i=e.name.toLowerCase();let n=!0;for(const o of t){if(!n)break;i.indexOf(o)===-1&&(n=!1)}if(n)return e;if(e.children)for(const o of e.children){const r=this.findAvatarPart(o,t);if(r)return r}return null}handleCustomAvatarErrors(e){if(!e.ok)throw Error(e.statusText);return e}}class vx{get extensionName(){return"DocumentExtension"}onAfterBuildDocument(e){}}class wx{}const AT=Object.freeze(Object.defineProperty({__proto__:null,ActionBuilder:he,ActionCollection:Pw,ActionModel:Yt,AlignmentConstraint:Uc,Animation:Mt,AnimationCurve:sh,AnimationExtension:Mu,AnimationTrackHandler:vc,Animator:at,AnimatorController:Ii,Antialiasing:rh,Attractor:Xa,AudioExtension:Cr,AudioListener:ss,AudioSource:mi,AudioTrackHandler:rs,Avatar:so,AvatarBlink_Simple:vr,AvatarEyeLook_Rotation:lg,AvatarLoader:bx,AvatarMarker:Ce,AvatarModel:Oy,Avatar_Brain_LookAt:pc,Avatar_MouthShapes:Vc,Avatar_MustacheShake:rg,Avatar_POI:tr,AxesHelper:Ia,BaseUIComponent:Ui,BasicIKConstraint:hg,BehaviorExtension:zg,BehaviorModel:bt,BloomEffect:zu,BoxCollider:xu,BoxGizmo:kr,BoxHelperComponent:st,Button:Ps,CallInfo:ns,Camera:Jt,CameraTargetReachedEvent:fc,Canvas:Ea,CanvasGroup:oo,CapsuleCollider:us,ChangeMaterialOnClick:Tg,ChangeTransformOnClick:Pr,CharacterController:wr,CharacterControllerInput:gs,ChromaticAberration:ah,ClickThrough:sf,ColorAdjustments:vo,ColorBySpeedModule:qa,ColorOverLifetimeModule:Bu,ContactShadows:$c,ControlTrackHandler:Yu,CursorFollow:Ur,CustomBranding:Mr,Deletable:pg,DeleteBox:Zs,DepthOfField:pn,DeviceFlag:Su,DocumentExtension:vx,DragControls:Wo,DropListener:_s,Duplicatable:xg,EffectWrapper:bc,EmissionModule:xs,EmphasizeOnClick:Fa,EnvironmentScene:tf,EventList:oe,EventListEvent:yu,EventSystem:Nt,EventTrigger:Pu,FieldWithDefault:rw,FixedJoint:ey,Fog:Wa,GltfExport:Mg,GltfExportBox:Pg,Gradient:Rr,Graphic:Zc,GraphicRaycaster:_u,GridHelper:Ga,GridLayoutGroup:Hg,GroundProjectedEnv:Fn,GroupActionModel:Go,HideOnStart:Ei,HingeJoint:eh,HorizontalLayoutGroup:Gg,get HoverAnimation(){return exports.HoverAnimation},Image:el,InheritVelocityModule:sy,InputField:_y,InstanceHandle:ir,InstancingHandler:hr,Interactable:fg,Keyframe:ei,LODGroup:ih,LODModel:Ha,Light:oi,LimitVelocityOverLifetimeModule:et,LogStats:ug,LookAt:by,LookAtConstraint:br,MainModule:Rt,MarkerTrackHandler:Qu,MaskableGraphic:Jc,MeshCollider:fo,MeshRenderer:Gc,MinMaxCurve:G,MinMaxGradient:Tr,NeedleMenu:Nn,NestedGltf:nh,Networking:iy,NoiseModule:pe,ObjectRaycaster:pi,OffsetConstraint:Er,OpenURL:tl,OrbitControls:de,Outline:$a,Padding:Or,ParticleBurst:Qd,ParticleSubEmitter:oy,ParticleSystem:_c,ParticleSystemRenderer:Wi,PhysicsExtension:Ng,PixelationEffect:lh,PlayAnimationOnClick:gc,PlayAudioOnClick:no,PlayableDirector:fr,PlayerColor:Ra,PointerEventData:zc,PostProcessingHandler:hy,PreliminaryAction:za,PreliminaryTrigger:Xc,RawImage:Ju,Rect:Rw,RectTransform:hn,ReflectionProbe:mc,RegisteredAnimationInfo:Ys,RemoteSkybox:Vu,Renderer:$t,RendererLightmap:bg,Rigidbody:$e,RotationBySpeedModule:$i,RotationOverLifetimeModule:fn,SceneSwitcher:Fe,ScreenCapture:wo,ScreenSpaceAmbientOcclusion:Ss,ScreenSpaceAmbientOcclusionN8:mn,ScrollFollow:Os,SeeThrough:Cs,SetActiveOnClick:Ag,ShadowCatcher:uh,ShapeModule:ny,SharpeningEffect:hh,SignalAsset:Xu,SignalReceiver:yh,SignalReceiverEvent:gh,SignalTrackHandler:wc,Size:Ew,SizeBySpeedModule:ri,SizeOverLifetimeModule:Ar,SkinnedMeshRenderer:vg,SmoothFollow:Wu,SpatialGrabRaycaster:lr,SpatialHtml:bh,SpatialTrigger:Gu,SpatialTriggerReceiver:Bn,SpectatorCamera:Hu,SphereCollider:ja,SplineContainer:jr,SplineData:Un,SplineWalker:Hi,Sprite:bs,SpriteData:_a,SpriteRenderer:ni,SpriteSheet:ka,SubEmitterSystem:Yd,SyncedCamera:uy,SyncedRoom:gn,SyncedTransform:cn,TapGestureTrigger:Lg,TeleportTarget:Au,TestRunner:fy,TestSimulateUserData:py,Text:Et,TextBuilder:$g,TextExtension:Lu,TextureSheetAnimationModule:Tt,TiltShiftEffect:Wn,ToneMappingEffect:ro,TrailModule:Te,TransformData:Ee,TransformGizmo:Br,TriggerBuilder:Ot,TriggerModel:Js,UIRaycastUtils:ig,UIRootComponent:Yc,USDZExporter:on,USDZText:la,USDZUIExtension:Xg,UsageMarker:Wc,VariantAction:Rg,VelocityOverLifetimeModule:Le,VerticalLayoutGroup:Wg,VideoPlayer:Ze,get ViewBox(){return exports.ViewBox},Vignette:Ir,VisibilityAction:Qc,Voip:uo,Volume:Ya,VolumeParameter:F,VolumeProfile:Uu,WebARCameraBackground:wh,WebARSessionRoot:ui,WebXR:Du,WebXRImageTracking:xh,WebXRImageTrackingModel:ks,WebXRPlaneTracking:Es,WebXRTrackedImage:Ta,XRControllerFollow:Ms,XRControllerModel:fs,XRControllerMovement:yi,XRFlag:Ri,XRRig:af,XRState:zt,__Ignore:wx},Symbol.toStringTag,{value:"Module"})),Sc=x("debugmissingcamera");le.registerCallback(ae.MissingCamera,s=>{Sc&&console.warn("Creating missing camera");const e=s.context.scene,t=new c.PerspectiveCamera;t.name="Default Fallback Camera",e.add(t);const i=new Jt;if(i.sourceId=s.files?.[0]?.src??"unknown",i.fieldOfView=35,s.context.domElement.getAttribute("transparent")!=null)i.clearFlags=er.Uninitialized;else if(s.context.domElement.getAttribute("background-image")?.length||s.context.lightmaps.tryGetSkybox(i.sourceId))i.clearFlags=er.Skybox;else{if(i.clearFlags=er.SolidColor,!s.context.domElement.getAttribute("background-color")){let a="#efefef";typeof window!==void 0&&window.matchMedia("(prefers-color-scheme: dark)").matches&&(a="#1f1f1f"),e.background=new c.Color(a)}if(!e.environment){const a=new c.PMREMGenerator$1(s.context.renderer),l=new tf("neutral");e.environment=a.fromScene(l,.025).texture}}const o=Qo(t,i,!0);return t.position.x=0,t.position.y=1,t.position.z=2,s.context.domElement?.cameraControls!=!1&&xx(s.context,o),o});le.registerCallback(ae.ContextCreated,s=>{if(!s.context.mainCamera){Sc&&console.log("Will not auto-fit because a default camera exists");return}if(s.context.domElement?.cameraControls==!0){if(Wb(s.context.mainCamera)?.isCameraController==!0){Sc&&console.log("Will not auto-fit because a camera controller exists");return}xx(s.context)}});function xx(s,e){e=e??s.mainCameraComponent;const t=e?.gameObject;if(Sc&&console.log("Creating default camera controls",e?.name),t){const i=Dc(t,de);i.sourceId=e?.sourceId??"unknown";const n=s.domElement.getAttribute("auto-rotate");i.autoRotate=n!="0"&&n?.toLowerCase()!="false";const o=Number.parseFloat(n||".5");i.autoRotateSpeed=isNaN(o)?.5:o,Sc&&console.log("Auto-rotate",i.autoRotate,"speed:",i.autoRotateSpeed);const r=s.domElement.getAttribute("auto-fit");i.autoFit=r!=="0"&&r?.toLowerCase()!="false",i.autoTarget=!0}else console.warn("Missing camera object, can not add orbit controls")}le.registerCallback(ae.ContextCreated,s=>{const e=s.context.domElement.getAttribute("autoplay");if(e!==void 0&&(e===""||e==="true"||e==="1")&&s.files)for(const t of s.files)S.foreachComponent(t.file.scene,n=>{if(n.enabled!==!1){if(n instanceof Mt&&n.playAutomatically||n instanceof at||n instanceof fr&&n.playOnAwake===!0)return!0;if(n instanceof Mt)return n.playAutomatically=!0,!0;if(n instanceof fr)return n.playOnAwake=!0,!0}},!0)!==!0&&io.autoplayAnimations(t.file)});exports.SplineUtils=void 0;(s=>{function e(t,i=!1,n=.75){const o=new jr,r=1-L.clamp(n,0,1);return t.forEach((a,l)=>{const h=new c.Vector3;l<t.length-1?h.subVectors(t[l+1],a).normalize().multiplyScalar(r):i&&t.length>1&&h.subVectors(t[0],a).normalize().multiplyScalar(r);const d=new Un;d.position.copy(a),d.tangentIn.copy(h),d.tangentOut.copy(h),o.addKnot(d)}),o.closed=i,o}s.createFromPoints=e})(exports.SplineUtils||(exports.SplineUtils={}));class DT extends re.WorkerBase{constructor(){super(new Worker(new URL("/generateMeshBVH.worker-iyfPIK6R.js",typeof document>"u"?require("url").pathToFileURL(__filename).href:ha&&ha.tagName.toUpperCase()==="SCRIPT"&&ha.src||new URL("needle-engine.bundle-DQC2R6JE.umd.cjs",document.baseURI).href),{type:"module"})),this.name="GenerateMeshBVHWorker"}runTask(e,t,i={}){return new Promise((n,o)=>{if(t.getAttribute("position").isInterleavedBufferAttribute||t.index&&t.index.isInterleavedBufferAttribute)throw new Error("GenerateMeshBVHWorker: InterleavedBufferAttribute are not supported for the geometry attributes.");e.onerror=h=>{o(new Error(`[GenerateMeshBVHWorker] ${h.message||"Unknown error. Please check the server console. If you're using vite try adding 'three-mesh-bvh' to 'optimizeDeps.exclude' in your vite.config.js"}`))},e.onmessage=h=>{const{data:d}=h;if(d.error)o(new Error(d.error)),e.onmessage=null;else if(d.serialized){const{serialized:u,position:p}=d,m=re.MeshBVH.deserialize(u,t,{setIndex:!1}),y=Object.assign({setBoundingBox:!0},i);if(t.attributes.position.array=p,u.index)if(t.index)t.index.array=u.index;else{const _=new c.BufferAttribute(u.index,1,!1);t.setIndex(_)}y.setBoundingBox&&(t.boundingBox=m.getBoundingBox(new c.Box3)),i.onProgress&&i.onProgress(d.progress),n(m),e.onmessage=null}else i.onProgress&&i.onProgress(d.progress)};const r=t.index?t.index.array:null,a=t.attributes.position.array,l=[a];r&&l.push(r),e.postMessage({index:r,position:a,options:{...i,onProgress:null,includedProgressCallback:!!i.onProgress,groups:[...t.groups]}},l.map(h=>h.buffer).filter(h=>typeof SharedArrayBuffer>"u"||!(h instanceof SharedArrayBuffer)))})}}const LT=Object.freeze(Object.defineProperty({__proto__:null,GenerateMeshBVHWorker:DT},Symbol.toStringTag,{value:"Module"}));exports.$physicsKey=aO;exports.ActionBuilder=he;exports.ActionCollection=Pw;exports.ActionModel=Yt;exports.Addressables=l0;exports.AlignmentConstraint=Uc;exports.AmbientMode=ga;exports.Animation=Mt;exports.AnimationCurve=sh;exports.AnimationExtension=Mu;exports.AnimationTrackHandler=vc;exports.AnimationUtils=io;exports.Animator=at;exports.AnimatorConditionMode=Ws;exports.AnimatorController=Ii;exports.AnimatorControllerParameterType=eg;exports.AnimatorStateInfo=Rl;exports.Antialiasing=rh;exports.Application=ln;exports.AssetDatabase=Pv;exports.AssetReference=K;exports.Attractor=Xa;exports.AudioExtension=Cr;exports.AudioListener=ss;exports.AudioSource=mi;exports.AudioTrackHandler=rs;exports.Avatar=so;exports.AvatarBlink_Simple=vr;exports.AvatarEyeLook_Rotation=lg;exports.AvatarLoader=bx;exports.AvatarMarker=Ce;exports.AvatarModel=Oy;exports.Avatar_Brain_LookAt=pc;exports.Avatar_MouthShapes=Vc;exports.Avatar_MustacheShake=rg;exports.Avatar_POI=tr;exports.Axes=ra;exports.AxesHelper=Ia;exports.BUILD_TIME=iu;exports.BaseUIComponent=Ui;exports.BasicIKConstraint=hg;exports.BehaviorExtension=zg;exports.BehaviorModel=bt;exports.BloomEffect=zu;exports.BoxCollider=xu;exports.BoxGizmo=kr;exports.BoxHelperComponent=st;exports.Button=Ps;exports.ButtonsFactory=tn;exports.CallDirection=W0;exports.CallInfo=ns;exports.Camera=Jt;exports.CameraTargetReachedEvent=fc;exports.Canvas=Ea;exports.CanvasGroup=oo;exports.CapsuleCollider=us;exports.ChangeMaterialOnClick=Tg;exports.ChangeTransformOnClick=Pr;exports.CharacterController=wr;exports.CharacterControllerInput=gs;exports.ChromaticAberration=ah;exports.CircularBuffer=fi;exports.ClearFlags=er;exports.ClickThrough=sf;exports.ClipExtrapolation=Sn;exports.Collider=Vi;exports.Collision=N0;exports.CollisionDetectionMode=gu;exports.ColorAdjustments=vo;exports.ColorBySpeedModule=qa;exports.ColorOverLifetimeModule=Bu;exports.Component=pP;exports.Component$1=E;exports.ComponentLifecycleEvents=au;exports.Components=AT;exports.ConnectionEvents=bv;exports.ContactPoint=z0;exports.ContactShadows=$c;exports.Context=U;exports.ContextArgs=Z1;exports.ContextEvent=ae;exports.ContextRegistry=le;exports.ControlTrackHandler=Yu;exports.CursorFollow=Ur;exports.CustomBranding=Mr;exports.CustomShader=_e;exports.DefaultReflectionMode=Id;exports.Deletable=pg;exports.DeleteBox=Zs;exports.DepthOfField=pn;exports.DeviceFlag=Su;exports.DocumentExtension=vx;exports.DragControls=Wo;exports.DragMode=mg;exports.DropListener=_s;exports.Duplicatable=xg;exports.EffectWrapper=bc;exports.EmissionModule=xs;exports.EmphasizeOnClick=Fa;exports.EngineLoadingView=xc;exports.EnvironmentScene=tf;exports.EventList=oe;exports.EventListEvent=yu;exports.EventSystem=Nt;exports.EventTrigger=Pu;exports.FieldWithDefault=rw;exports.FileReference=Zo;exports.FileReferenceSerializer=h0;exports.FileSpawnModel=RO;exports.File_Event=K0;exports.FixedJoint=ey;exports.Fog=Wa;exports.FrameEvent=me;exports.GENERATOR=Rc;exports.GameObject=S;exports.Gizmos=B;exports.GltfExport=Mg;exports.GltfExportBox=Pg;exports.Gradient=Rr;exports.Graphic=Zc;exports.GraphicRaycaster=_u;exports.Graphics=to;exports.GridHelper=Ga;exports.GridLayoutGroup=Hg;exports.GroundProjectedEnv=Fn;exports.GroupActionModel=Go;exports.HideFlags=bu;exports.HideOnStart=Ei;exports.HingeJoint=eh;exports.HorizontalLayoutGroup=Gg;exports.HostData=GC;exports.Image=el;exports.ImageReference=Ko;exports.ImageReferenceSerializer=c0;exports.InheritVelocityModule=sy;exports.Input=fv;exports.InputEventQueue=Zt;exports.InputEvents=Se;exports.InputField=_y;exports.InstanceHandle=ir;exports.InstancingHandler=hr;exports.InstancingUtil=Li;exports.InstantiateEvent=jv;exports.InstantiateIdProvider=_t;exports.InstantiateOptions=dn;exports.Interactable=fg;exports.JoinedRoomResponse=pC;exports.KeyEventArgs=nC;exports.Keyframe=ei;exports.LODGroup=ih;exports.LODModel=Ha;exports.LeftRoomResponse=mC;exports.Light=oi;exports.LightData=m0;exports.LimitVelocityOverLifetimeModule=et;exports.LoadingElementOptions=yT;exports.LogStats=ug;exports.LogType=di;exports.LookAt=by;exports.LookAtConstraint=br;exports.MainModule=Rt;exports.MarkerTrackHandler=Qu;exports.MarkerType=my;exports.MaskableGraphic=Jc;exports.Mathf=L;exports.MeshCollider=fo;exports.MeshRenderer=Gc;exports.MinMaxCurve=G;exports.MinMaxGradient=Tr;exports.NEKeyboardEvent=Ol;exports.NEPointerEvent=Zn;exports.NeedleButtonElement=_x;exports.NeedleEngineWebComponent=Py;exports.NeedleMenu=Nn;exports.NeedlePatchesKey=od;exports.NeedleXRController=Tm;exports.NeedleXRSession=H;exports.NeedleXRSync=xv;exports.NeedleXRUtils=Cv;exports.NestedGltf=nh;exports.NetworkConnection=wv;exports.NetworkedStreamEvents=An;exports.NetworkedStreams=Nc;exports.Networking=iy;exports.NewInstanceModel=Uv;exports.NoiseModule=pe;exports.ObjectRaycaster=pi;exports.ObjectUtils=mr;exports.OffsetConstraint=Er;exports.OneEuroFilter=nd;exports.OneEuroFilterXYZ=vm;exports.OpenURL=tl;exports.OrbitControls=de;exports.Outline=$a;exports.OwnershipEvent=vv;exports.OwnershipModel=Im;exports.PUBLIC_KEY=Vo;exports.Padding=Or;exports.ParticleBurst=Qd;exports.ParticleSubEmitter=oy;exports.ParticleSystem=_c;exports.ParticleSystemBaseBehaviour=bo;exports.ParticleSystemRenderer=Wi;exports.ParticleSystemShapeType=Xd;exports.PeerHandle=os;exports.PeerNetworking=_v;exports.Physics=Pa;exports.PhysicsExtension=Ng;exports.PhysicsMaterialCombine=it;exports.PixelationEffect=lh;exports.PlayAnimationOnClick=gc;exports.PlayAudioOnClick=no;exports.PlayableDirector=fr;exports.PlayerColor=Ra;exports.PlayerState=Ai;exports.PlayerStateEvent=kw;exports.PlayerSync=Ug;exports.PlayerView=u0;exports.PlayerViewManager=f0;exports.PointerEventData=zc;exports.PointerType=ou;exports.PostProcessingEffect=We;exports.PostProcessingEffectOrder=Ke;exports.PostProcessingHandler=hy;exports.PreliminaryAction=za;exports.PreliminaryTrigger=Xc;exports.PrimitiveType=sr;exports.Progress=ne;exports.PromiseAllWithErrors=_m;exports.PromiseErrorResult=vp;exports.RGBAColor=ee;exports.RapierPhysics=ba;exports.RawImage=Ju;exports.RaycastOptions=ho;exports.Rect=Rw;exports.RectTransform=hn;exports.ReflectionProbe=mc;exports.RegisteredAnimationInfo=Ys;exports.RemoteSkybox=Vu;exports.RenderTexture=Tn;exports.RenderTextureSerializer=j0;exports.Renderer=$t;exports.RendererData=p0;exports.RendererLightmap=bg;exports.Rigidbody=$e;exports.RigidbodyConstraints=je;exports.RoomEvents=Y;exports.RotationBySpeedModule=$i;exports.RotationOverLifetimeModule=fn;exports.SceneLightSettings=$d;exports.SceneSwitcher=Fe;exports.ScreenCapture=wo;exports.ScreenSpaceAmbientOcclusion=Ss;exports.ScreenSpaceAmbientOcclusionN8=mn;exports.ScrollFollow=Os;exports.SeeThrough=Cs;exports.SendQueue=en;exports.SerializationContext=Hm;exports.SetActiveOnClick=Ag;exports.ShadowCatcher=uh;exports.ShapeModule=ny;exports.ShapeOverlapResult=V0;exports.SharpeningEffect=hh;exports.SignalAsset=Xu;exports.SignalReceiver=yh;exports.SignalReceiverEvent=gh;exports.SignalTrackHandler=wc;exports.Size=Ew;exports.SizeBySpeedModule=ri;exports.SizeOverLifetimeModule=Ar;exports.SkinnedMeshRenderer=vg;exports.SmoothFollow=Wu;exports.SpatialGrabRaycaster=lr;exports.SpatialHtml=bh;exports.SpatialTrigger=Gu;exports.SpatialTriggerReceiver=Bn;exports.SpectatorCamera=Hu;exports.SphereCollider=ja;exports.SphereIntersection=Um;exports.SplineContainer=jr;exports.SplineData=Un;exports.SplineWalker=Hi;exports.Sprite=bs;exports.SpriteData=_a;exports.SpriteRenderer=ni;exports.SpriteSheet=ka;exports.StateMachineBehaviour=vP;exports.StreamEndedEvent=sg;exports.StreamReceivedEvent=$0;exports.SubEmitterSystem=Yd;exports.SyncedCamera=uy;exports.SyncedRoom=gn;exports.SyncedTransform=cn;exports.TapGestureTrigger=Lg;exports.TeleportTarget=Au;exports.TestRunner=fy;exports.TestSceneUtils=OT;exports.TestSimulateUserData=py;exports.Text=Et;exports.TextBuilder=$g;exports.TextExtension=Lu;exports.TextureSheetAnimationModule=Tt;exports.TiltShiftEffect=Wn;exports.Time=g0;exports.ToneMappingEffect=ro;exports.TrackHandler=Ja;exports.TrackType=li;exports.TrailModule=Te;exports.TransformData=Ee;exports.TransformGizmo=Br;exports.TriggerBuilder=Ot;exports.TriggerModel=Js;exports.TypeStore=P;exports.UIRaycastUtils=ig;exports.UIRootComponent=Yc;exports.USDDocument=kg;exports.USDObject=Ve;exports.USDWriter=gw;exports.USDZExporter=yw;exports.USDZExporter$1=on;exports.USDZText=la;exports.USDZUIExtension=Xg;exports.UriSerializer=B0;exports.UsageMarker=Wc;exports.UserJoinedOrLeftRoomModel=gC;exports.VERSION=Di;exports.VariantAction=Rg;exports.VelocityOverLifetimeModule=Le;exports.VerticalLayoutGroup=Wg;exports.VideoPlayer=Ze;exports.ViewDevice=cs;exports.Vignette=Ir;exports.VisibilityAction=Qc;exports.Voip=uo;exports.Volume=Ya;exports.VolumeParameter=F;exports.VolumeProfile=Uu;exports.WaitForFrames=S1;exports.WaitForPromise=d0;exports.WaitForSeconds=Qm;exports.Watch=as;exports.WebARCameraBackground=wh;exports.WebARSessionRoot=ui;exports.WebXR=Du;exports.WebXRButtonFactory=eo;exports.WebXRImageTracking=xh;exports.WebXRImageTrackingModel=ks;exports.WebXRPlaneTracking=Es;exports.WebXRTrackedImage=Ta;exports.XRControllerFollow=Ms;exports.XRControllerModel=fs;exports.XRControllerMovement=yi;exports.XRFlag=Ri;exports.XRRig=af;exports.XRState=zt;exports.XRStateFlag=En;exports.__Ignore=wx;exports.__internalNotifyObjectDestroyed=LC;exports.activeInHierarchyFieldName=ls;exports.addAttributeChangeCallback=gm;exports.addComponent=nn;exports.addCustomExtensionPlugin=HO;exports.addNewComponent=Qo;exports.addPatch=nu;exports.apply=cu;exports.applyHMRChanges=uP;exports.applyPrototypeExtensions=Yv;exports.beginListenDestroy=Bv;exports.beginListenInstantiate=zv;exports.binaryIdentifierCasts=Am;exports.build_scene_functions=K1;exports.builtinComponentKeyName=Bo;exports.calculateProgress01=Cy;exports.clearMessages=Kx;exports.colorSerializer=BP;exports.compareAssociation=Wv;exports.componentSerializer=pd;exports.copyTexture=Kb;exports.createMotion=T0;exports.debugNet=Ht;exports.debugOwner=Ml;exports.decompressGpuTexture=ww;exports.deepClone=Pc;exports.delay=ds;exports.delayForFrames=Oc;exports.deserializeObject=Dd;exports.destroy=Bi;exports.destroyComponentInstance=Jv;exports.determineMimeTypeFromExtension=Z0;exports.disposeObjectResources=be;exports.disposeStream=Dn;exports.editorGuidKeyName=$l;exports.enableSpatialConsole=da;exports.euler=FP;exports.eventListSerializer=$P;exports.exportAsGLTF=ET;exports.findByGuid=Xm;exports.findObjectOfType=Da;exports.findObjectsOfType=t0;exports.findResourceUsers=Fm;exports.fitCamera=A0;exports.fitObjectIntoVolume=Jb;exports.foreachComponent=rr;exports.foreachComponentEnumerator=du;exports.forward=mS;exports.generateQRCode=b0;exports.generateSeed=Fv;exports.getBoundingBox=Vt;exports.getCameraController=Wb;exports.getComponent=yr;exports.getComponentInChildren=Ic;exports.getComponentInParent=hc;exports.getComponents=Lc;exports.getComponentsInChildren=Aa;exports.getComponentsInParent=lu;exports.getFormattedDate=uw;exports.getIconElement=yt;exports.getIconTexture=Np;exports.getLoader=an;exports.getOrAddComponent=Dc;exports.getParam=x;exports.getParentHierarchyPath=_S;exports.getPath=Ex;exports.getPeerOptions=hC;exports.getPeerjsInstance=yv;exports.getResourceUserCount=jC;exports.getTempColor=qb;exports.getTempQuaternion=Kt;exports.getTempVector=j;exports.getUrlParams=Cc;exports.getVisibleInCustomShadowRendering=Zb;exports.getWorldDirection=Xb;exports.getWorldEuler=Sm;exports.getWorldPosition=Q;exports.getWorldQuaternion=fe;exports.getWorldRotation=tu;exports.getWorldScale=Be;exports.hasCommercialLicense=hs;exports.hasIndieLicense=Bc;exports.hasPointerEventComponent=zd;exports.hasProLicense=jn;exports.hideDebugConsole=nv;exports.imageToCanvas=xw;exports.instantiate=ar;exports.invokeLoadedImportPluginHooks=ow;exports.invokeXRSessionEnd=uv;exports.invokeXRSessionStart=dv;exports.isActiveInHierarchy=i0;exports.isActiveSelf=La;exports.isAndroidDevice=Ix;exports.isAnimationAction=Yb;exports.isComponent=F0;exports.isDebugMode=Px;exports.isDesktop=Tx;exports.isDestroyed=or;exports.isDevEnvironment=R;exports.isDisposed=DC;exports.isExporting=MT;exports.isGLTFModel=U0;exports.isHostedOnGlitch=Ab;exports.isHotReloadEnabled=Hp;exports.isHotReloading=hP;exports.isIPad=Dx;exports.isIconElement=v0;exports.isLocalNetwork=ji;exports.isMacOS=Bx;exports.isMobileDevice=Ax;exports.isMozillaXR=jx;exports.isQuest=zx;exports.isResourceTrackingEnabled=Mv;exports.isSafari=Fx;exports.isUsingInstancing=hu;exports.isiOS=Ux;exports.isiPad=Lx;exports.loadAsset=dT;exports.loadPMREM=Zw;exports.loadSync=Sy;exports.logHierarchy=Od;exports.lookAtInverse=aS;exports.lookAtObject=Mc;exports.lookAtScreenPoint=lS;exports.makeId=Mx;exports.makeIdFromRandomWords=Ib;exports.makeNameSafe=gi;exports.markAsInstancedRendered=n0;exports.microphonePermissionsGranted=Nx;exports.nameof=Cx;exports.nameofFactory=Db;exports.objectSerializer=I0;exports.offXRSessionEnd=iC;exports.offXRSessionStart=tC;exports.onAfterRender=iP;exports.onBeforeRender=tP;exports.onClear=J1;exports.onDestroy=eP;exports.onInitialized=Km;exports.onStart=pu;exports.onUpdate=S0;exports.onXRSessionEnd=Rm;exports.onXRSessionStart=su;exports.parseSync=fx;exports.placeOnSurface=ev;exports.postprocessFBXMaterials=Om;exports.prefix=TP;exports.pushState=Lb;exports.randomNumber=kx;exports.registerBinaryType=Dm;exports.registerComponent=fu;exports.registerComponentExtension=yg;exports.registerCustomEffectType=Gi;exports.registerExportExtensions=_g;exports.registerExtensions=Gd;exports.registerHotReloadType=M0;exports.registerLoader=km;exports.registerPrefabProvider=Vv;exports.registerPrototypeExtensions=Kv;exports.registerType=$m;exports.relativePathPrefix=Bb;exports.removeAttributeChangeCallback=ym;exports.removeComponent=qm;exports.removeCustomImportExtensionType=qO;exports.removePatch=JS;exports.resolveUrl=ao;exports.sanitizeString=jb;exports.saveImage=cx;exports.screenshot=XR;exports.screenshot2=xy;exports.sendDestroyed=Nm;exports.serializable=f;exports.serializeObject=Hv;exports.serializeable=Ue;exports.setActive=Hl;exports.setAllowBalloonMessages=Nb;exports.setAllowOverlayMessages=qx;exports.setAutoFitEnabled=Cd;exports.setCameraController=xp;exports.setDestroyed=o0;exports.setDevEnvironment=OS;exports.setDisposable=Ev;exports.setDontDestroy=Zr;exports.setOrAddParamsToUrl=bp;exports.setParam=Ox;exports.setParamWithoutReload=oc;exports.setPeerOptions=dC;exports.setResourceTrackingEnabled=AC;exports.setState=pm;exports.setVisibleInCustomShadowRendering=Pm;exports.setWorldEuler=Cm;exports.setWorldPosition=rt;exports.setWorldPositionXYZ=nr;exports.setWorldQuaternion=rn;exports.setWorldQuaternionXYZW=xm;exports.setWorldRotation=Qb;exports.setWorldRotationXYZ=kc;exports.setWorldScale=wa;exports.showBalloonError=Ec;exports.showBalloonMessage=Pe;exports.showBalloonWarning=ue;exports.showDebugConsole=Mm;exports.slerp=rS;exports.syncDestroy=Tc;exports.syncField=Bg;exports.syncInstantiate=Vm;exports.textureToCanvas=bS;exports.toSourceId=Ub;exports.tryCastBinary=mv;exports.tryDetermineMimetypeFromBinary=ew;exports.tryDetermineMimetypeFromURL=J0;exports.tryFindObject=va;exports.tryGetGuid=gv;exports.unregisterHotReloadType=k0;exports.unwatchWrite=mm;exports.useForAutoFit=Gb;exports.validate=vt;exports.watchWrite=eu;
1647
+ `),this.#n.innerHTML=this.#e.innerHTML,this.#n.style.cssText="display: flex; align-items: center; justify-content: center;",this.#e.innerHTML=this.#n.outerHTML,this.#t.innerHTML=this.#e.outerHTML,this.#t.prepend(this.#s),Bd(Vp,{element:this.#t}),this.#o?.disconnect(),this.#o??=new MutationObserver(()=>this.#l()),this.#o.observe(this.#e,{attributes:!0}),yp&&console.log("Needle Button updated")}#l(){this.#e&&(this.#e.style.display==="none"?this.style.display="none":this.style.display==="none"&&(this.style.display=""))}#r=e=>{yp&&console.log("Needle Button clicked"),!e.defaultPrevented&&this.#e&&this.#e.click()}}typeof window<"u"&&!window.customElements.get(Tb)&&window.customElements.define(Tb,_x);const Pl=x("debugavatar");class Oy{root;head;leftHand;rigthHand;get isValid(){return this.head!==null&&this.head!==void 0}constructor(e,t,i,n){this.root=e,this.head=t,this.leftHand=i,this.rigthHand=n,this.root?.traverse(o=>o.layers.set(2))}}class bx{avatarRegistryUrl=null;async getOrCreateNewAvatarInstance(e,t){if(!t)return console.error("Can not create avatar: failed to provide id or root object"),null;let i=null;if(typeof t=="string"){if(i=await this.loadAvatar(e,t),!i){const o=new dn;i=S.instantiate(va(t,e.scene),o)}}else i=t;if(!i)return null;const n=this.findAvatar(i);return n.isValid?(Pl&&console.log("[Custom Avatar] valid config",t,Pl?n:""),n):(console.warn("[Custom Avatar] config isn't valid",t,Pl?n:""),null)}async loadAvatar(e,t){if(console.assert(t!=null&&typeof t=="string","Avatar id must not be null"),t.length<=0||!t)return null;if(Pl&&console.log("[Custom Avatar] "+t+", loading..."),t.endsWith(".glb")||(t+=".glb"),this.avatarRegistryUrl===null){const n=await fetch("./"+t);let o=null;if(n.ok){const a=await n.blob();a&&(o=await a.arrayBuffer())}return o?(await an().parseSync(e,o,null,0))?.scene??null:null}const i=new q.GLTFLoader;return Jm(i,e),new Promise((n,o)=>{const r=this.avatarRegistryUrl+"/"+t;i.load(r,async a=>{await an().createBuiltinComponents(e,r,a,null,void 0),n(a.scene)},a=>{Pl&&console.log("[Custom Avatar] "+a.loaded/a.total*100+"% loaded of "+a.total/1024+"kB")},a=>{console.error("[Custom Avatar] Error when loading: "+a),n(null)})})}cacheModel(e,t){}findAvatar(e){const t=e;let i=t;i.children.length==1&&(i=e.children[0]);let n=this.findAvatarPart(i,["head"]);const o=this.findAvatarPart(i,["left","hand"]),r=this.findAvatarPart(i,["right","hand"]);if(!n){n=t;const l=new c.Vector3;new c.Box3().setFromObject(n).getSize(l);const h=Math.max(l.x,l.y,l.z);console.warn("[Custom Avatar] Normalizing head scale, it's too big: "+h+" meters! Should be < 0.3m"),h>.3&&n.scale.multiplyScalar(1/h*.3)}return new Oy(t,n,o,r)}findAvatarPart(e,t){const i=e.name.toLowerCase();let n=!0;for(const o of t){if(!n)break;i.indexOf(o)===-1&&(n=!1)}if(n)return e;if(e.children)for(const o of e.children){const r=this.findAvatarPart(o,t);if(r)return r}return null}handleCustomAvatarErrors(e){if(!e.ok)throw Error(e.statusText);return e}}class vx{get extensionName(){return"DocumentExtension"}onAfterBuildDocument(e){}}class wx{}const AT=Object.freeze(Object.defineProperty({__proto__:null,ActionBuilder:he,ActionCollection:Pw,ActionModel:Yt,AlignmentConstraint:Uc,Animation:Mt,AnimationCurve:sh,AnimationExtension:Mu,AnimationTrackHandler:vc,Animator:at,AnimatorController:Ii,Antialiasing:rh,Attractor:Xa,AudioExtension:Cr,AudioListener:ss,AudioSource:mi,AudioTrackHandler:rs,Avatar:so,AvatarBlink_Simple:vr,AvatarEyeLook_Rotation:lg,AvatarLoader:bx,AvatarMarker:Ce,AvatarModel:Oy,Avatar_Brain_LookAt:pc,Avatar_MouthShapes:Vc,Avatar_MustacheShake:rg,Avatar_POI:tr,AxesHelper:Ia,BaseUIComponent:Ui,BasicIKConstraint:hg,BehaviorExtension:zg,BehaviorModel:bt,BloomEffect:zu,BoxCollider:xu,BoxGizmo:kr,BoxHelperComponent:st,Button:Ps,CallInfo:ns,Camera:Jt,CameraTargetReachedEvent:fc,Canvas:Ea,CanvasGroup:oo,CapsuleCollider:us,ChangeMaterialOnClick:Tg,ChangeTransformOnClick:Pr,CharacterController:wr,CharacterControllerInput:gs,ChromaticAberration:ah,ClickThrough:sf,ColorAdjustments:vo,ColorBySpeedModule:qa,ColorOverLifetimeModule:Bu,ContactShadows:$c,ControlTrackHandler:Yu,CursorFollow:Ur,CustomBranding:Mr,Deletable:pg,DeleteBox:Zs,DepthOfField:pn,DeviceFlag:Su,DocumentExtension:vx,DragControls:Wo,DropListener:_s,Duplicatable:xg,EffectWrapper:bc,EmissionModule:xs,EmphasizeOnClick:Fa,EnvironmentScene:tf,EventList:oe,EventListEvent:yu,EventSystem:Nt,EventTrigger:Pu,FieldWithDefault:rw,FixedJoint:ey,Fog:Wa,GltfExport:Mg,GltfExportBox:Pg,Gradient:Rr,Graphic:Zc,GraphicRaycaster:_u,GridHelper:Ga,GridLayoutGroup:Hg,GroundProjectedEnv:Fn,GroupActionModel:Go,HideOnStart:Ei,HingeJoint:eh,HorizontalLayoutGroup:Gg,get HoverAnimation(){return exports.HoverAnimation},Image:el,InheritVelocityModule:sy,InputField:_y,InstanceHandle:ir,InstancingHandler:hr,Interactable:fg,Keyframe:ei,LODGroup:ih,LODModel:Ha,Light:oi,LimitVelocityOverLifetimeModule:et,LogStats:ug,LookAt:by,LookAtConstraint:br,MainModule:Rt,MarkerTrackHandler:Qu,MaskableGraphic:Jc,MeshCollider:fo,MeshRenderer:Gc,MinMaxCurve:G,MinMaxGradient:Tr,NeedleMenu:Nn,NestedGltf:nh,Networking:iy,NoiseModule:pe,ObjectRaycaster:pi,OffsetConstraint:Er,OpenURL:tl,OrbitControls:de,Outline:$a,Padding:Or,ParticleBurst:Qd,ParticleSubEmitter:oy,ParticleSystem:_c,ParticleSystemRenderer:Wi,PhysicsExtension:Ng,PixelationEffect:lh,PlayAnimationOnClick:gc,PlayAudioOnClick:no,PlayableDirector:fr,PlayerColor:Ra,PointerEventData:zc,PostProcessingHandler:hy,PreliminaryAction:za,PreliminaryTrigger:Xc,RawImage:Ju,Rect:Rw,RectTransform:hn,ReflectionProbe:mc,RegisteredAnimationInfo:Ys,RemoteSkybox:Vu,Renderer:$t,RendererLightmap:bg,Rigidbody:$e,RotationBySpeedModule:$i,RotationOverLifetimeModule:fn,SceneSwitcher:Fe,ScreenCapture:wo,ScreenSpaceAmbientOcclusion:Ss,ScreenSpaceAmbientOcclusionN8:mn,ScrollFollow:Os,SeeThrough:Cs,SetActiveOnClick:Ag,ShadowCatcher:uh,ShapeModule:ny,SharpeningEffect:hh,SignalAsset:Xu,SignalReceiver:yh,SignalReceiverEvent:gh,SignalTrackHandler:wc,Size:Ew,SizeBySpeedModule:ri,SizeOverLifetimeModule:Ar,SkinnedMeshRenderer:vg,SmoothFollow:Wu,SpatialGrabRaycaster:lr,SpatialHtml:bh,SpatialTrigger:Gu,SpatialTriggerReceiver:Bn,SpectatorCamera:Hu,SphereCollider:ja,SplineContainer:jr,SplineData:Un,SplineWalker:Hi,Sprite:bs,SpriteData:_a,SpriteRenderer:ni,SpriteSheet:ka,SubEmitterSystem:Yd,SyncedCamera:uy,SyncedRoom:gn,SyncedTransform:cn,TapGestureTrigger:Lg,TeleportTarget:Au,TestRunner:fy,TestSimulateUserData:py,Text:Et,TextBuilder:$g,TextExtension:Lu,TextureSheetAnimationModule:Tt,TiltShiftEffect:Wn,ToneMappingEffect:ro,TrailModule:Te,TransformData:Ee,TransformGizmo:Br,TriggerBuilder:Ot,TriggerModel:Js,UIRaycastUtils:ig,UIRootComponent:Yc,USDZExporter:on,USDZText:la,USDZUIExtension:Xg,UsageMarker:Wc,VariantAction:Rg,VelocityOverLifetimeModule:Le,VerticalLayoutGroup:Wg,VideoPlayer:Ze,get ViewBox(){return exports.ViewBox},Vignette:Ir,VisibilityAction:Qc,Voip:uo,Volume:Ya,VolumeParameter:F,VolumeProfile:Uu,WebARCameraBackground:wh,WebARSessionRoot:ui,WebXR:Du,WebXRImageTracking:xh,WebXRImageTrackingModel:ks,WebXRPlaneTracking:Es,WebXRTrackedImage:Ta,XRControllerFollow:Ms,XRControllerModel:fs,XRControllerMovement:yi,XRFlag:Ri,XRRig:af,XRState:zt,__Ignore:wx},Symbol.toStringTag,{value:"Module"})),Sc=x("debugmissingcamera");le.registerCallback(ae.MissingCamera,s=>{Sc&&console.warn("Creating missing camera");const e=s.context.scene,t=new c.PerspectiveCamera;t.name="Default Fallback Camera",e.add(t);const i=new Jt;if(i.sourceId=s.files?.[0]?.src??"unknown",i.fieldOfView=35,s.context.domElement.getAttribute("transparent")!=null)i.clearFlags=er.Uninitialized;else if(s.context.domElement.getAttribute("background-image")?.length||s.context.lightmaps.tryGetSkybox(i.sourceId))i.clearFlags=er.Skybox;else{if(i.clearFlags=er.SolidColor,!s.context.domElement.getAttribute("background-color")){let a="#efefef";typeof window!==void 0&&window.matchMedia("(prefers-color-scheme: dark)").matches&&(a="#1f1f1f"),e.background=new c.Color(a)}if(!e.environment){const a=new c.PMREMGenerator$1(s.context.renderer),l=new tf("neutral");e.environment=a.fromScene(l,.025).texture}}const o=Qo(t,i,!0);return t.position.x=0,t.position.y=1,t.position.z=2,s.context.domElement?.cameraControls!=!1&&xx(s.context,o),o});le.registerCallback(ae.ContextCreated,s=>{if(!s.context.mainCamera){Sc&&console.log("Will not auto-fit because a default camera exists");return}if(s.context.domElement?.cameraControls==!0){if(Wb(s.context.mainCamera)?.isCameraController==!0){Sc&&console.log("Will not auto-fit because a camera controller exists");return}xx(s.context)}});function xx(s,e){e=e??s.mainCameraComponent;const t=e?.gameObject;if(Sc&&console.log("Creating default camera controls",e?.name),t){const i=Dc(t,de);i.sourceId=e?.sourceId??"unknown";const n=s.domElement.getAttribute("auto-rotate");i.autoRotate=n!="0"&&n?.toLowerCase()!="false";const o=Number.parseFloat(n||".5");i.autoRotateSpeed=isNaN(o)?.5:o,Sc&&console.log("Auto-rotate",i.autoRotate,"speed:",i.autoRotateSpeed);const r=s.domElement.getAttribute("auto-fit");i.autoFit=r!=="0"&&r?.toLowerCase()!="false",i.autoTarget=!0}else console.warn("Missing camera object, can not add orbit controls")}le.registerCallback(ae.ContextCreated,s=>{const e=s.context.domElement.getAttribute("autoplay");if(e!==void 0&&(e===""||e==="true"||e==="1")&&s.files)for(const t of s.files)S.foreachComponent(t.file.scene,n=>{if(n.enabled!==!1){if(n instanceof Mt&&n.playAutomatically||n instanceof at||n instanceof fr&&n.playOnAwake===!0)return!0;if(n instanceof Mt)return n.playAutomatically=!0,!0;if(n instanceof fr)return n.playOnAwake=!0,!0}},!0)!==!0&&io.autoplayAnimations(t.file)});exports.SplineUtils=void 0;(s=>{function e(t,i=!1,n=.75){const o=new jr,r=1-L.clamp(n,0,1);return t.forEach((a,l)=>{const h=new c.Vector3;l<t.length-1?h.subVectors(t[l+1],a).normalize().multiplyScalar(r):i&&t.length>1&&h.subVectors(t[0],a).normalize().multiplyScalar(r);const d=new Un;d.position.copy(a),d.tangentIn.copy(h),d.tangentOut.copy(h),o.addKnot(d)}),o.closed=i,o}s.createFromPoints=e})(exports.SplineUtils||(exports.SplineUtils={}));class DT extends re.WorkerBase{constructor(){super(new Worker(new URL("/generateMeshBVH.worker-iyfPIK6R.js",typeof document>"u"?require("url").pathToFileURL(__filename).href:ha&&ha.tagName.toUpperCase()==="SCRIPT"&&ha.src||new URL("needle-engine.bundle-BQG2s0WQ.umd.cjs",document.baseURI).href),{type:"module"})),this.name="GenerateMeshBVHWorker"}runTask(e,t,i={}){return new Promise((n,o)=>{if(t.getAttribute("position").isInterleavedBufferAttribute||t.index&&t.index.isInterleavedBufferAttribute)throw new Error("GenerateMeshBVHWorker: InterleavedBufferAttribute are not supported for the geometry attributes.");e.onerror=h=>{o(new Error(`[GenerateMeshBVHWorker] ${h.message||"Unknown error. Please check the server console. If you're using vite try adding 'three-mesh-bvh' to 'optimizeDeps.exclude' in your vite.config.js"}`))},e.onmessage=h=>{const{data:d}=h;if(d.error)o(new Error(d.error)),e.onmessage=null;else if(d.serialized){const{serialized:u,position:p}=d,m=re.MeshBVH.deserialize(u,t,{setIndex:!1}),y=Object.assign({setBoundingBox:!0},i);if(t.attributes.position.array=p,u.index)if(t.index)t.index.array=u.index;else{const _=new c.BufferAttribute(u.index,1,!1);t.setIndex(_)}y.setBoundingBox&&(t.boundingBox=m.getBoundingBox(new c.Box3)),i.onProgress&&i.onProgress(d.progress),n(m),e.onmessage=null}else i.onProgress&&i.onProgress(d.progress)};const r=t.index?t.index.array:null,a=t.attributes.position.array,l=[a];r&&l.push(r),e.postMessage({index:r,position:a,options:{...i,onProgress:null,includedProgressCallback:!!i.onProgress,groups:[...t.groups]}},l.map(h=>h.buffer).filter(h=>typeof SharedArrayBuffer>"u"||!(h instanceof SharedArrayBuffer)))})}}const LT=Object.freeze(Object.defineProperty({__proto__:null,GenerateMeshBVHWorker:DT},Symbol.toStringTag,{value:"Module"}));exports.$physicsKey=aO;exports.ActionBuilder=he;exports.ActionCollection=Pw;exports.ActionModel=Yt;exports.Addressables=l0;exports.AlignmentConstraint=Uc;exports.AmbientMode=ga;exports.Animation=Mt;exports.AnimationCurve=sh;exports.AnimationExtension=Mu;exports.AnimationTrackHandler=vc;exports.AnimationUtils=io;exports.Animator=at;exports.AnimatorConditionMode=Ws;exports.AnimatorController=Ii;exports.AnimatorControllerParameterType=eg;exports.AnimatorStateInfo=Rl;exports.Antialiasing=rh;exports.Application=ln;exports.AssetDatabase=Pv;exports.AssetReference=K;exports.Attractor=Xa;exports.AudioExtension=Cr;exports.AudioListener=ss;exports.AudioSource=mi;exports.AudioTrackHandler=rs;exports.Avatar=so;exports.AvatarBlink_Simple=vr;exports.AvatarEyeLook_Rotation=lg;exports.AvatarLoader=bx;exports.AvatarMarker=Ce;exports.AvatarModel=Oy;exports.Avatar_Brain_LookAt=pc;exports.Avatar_MouthShapes=Vc;exports.Avatar_MustacheShake=rg;exports.Avatar_POI=tr;exports.Axes=ra;exports.AxesHelper=Ia;exports.BUILD_TIME=iu;exports.BaseUIComponent=Ui;exports.BasicIKConstraint=hg;exports.BehaviorExtension=zg;exports.BehaviorModel=bt;exports.BloomEffect=zu;exports.BoxCollider=xu;exports.BoxGizmo=kr;exports.BoxHelperComponent=st;exports.Button=Ps;exports.ButtonsFactory=tn;exports.CallDirection=W0;exports.CallInfo=ns;exports.Camera=Jt;exports.CameraTargetReachedEvent=fc;exports.Canvas=Ea;exports.CanvasGroup=oo;exports.CapsuleCollider=us;exports.ChangeMaterialOnClick=Tg;exports.ChangeTransformOnClick=Pr;exports.CharacterController=wr;exports.CharacterControllerInput=gs;exports.ChromaticAberration=ah;exports.CircularBuffer=fi;exports.ClearFlags=er;exports.ClickThrough=sf;exports.ClipExtrapolation=Sn;exports.Collider=Vi;exports.Collision=N0;exports.CollisionDetectionMode=gu;exports.ColorAdjustments=vo;exports.ColorBySpeedModule=qa;exports.ColorOverLifetimeModule=Bu;exports.Component=pP;exports.Component$1=E;exports.ComponentLifecycleEvents=au;exports.Components=AT;exports.ConnectionEvents=bv;exports.ContactPoint=z0;exports.ContactShadows=$c;exports.Context=U;exports.ContextArgs=Z1;exports.ContextEvent=ae;exports.ContextRegistry=le;exports.ControlTrackHandler=Yu;exports.CursorFollow=Ur;exports.CustomBranding=Mr;exports.CustomShader=_e;exports.DefaultReflectionMode=Id;exports.Deletable=pg;exports.DeleteBox=Zs;exports.DepthOfField=pn;exports.DeviceFlag=Su;exports.DocumentExtension=vx;exports.DragControls=Wo;exports.DragMode=mg;exports.DropListener=_s;exports.Duplicatable=xg;exports.EffectWrapper=bc;exports.EmissionModule=xs;exports.EmphasizeOnClick=Fa;exports.EngineLoadingView=xc;exports.EnvironmentScene=tf;exports.EventList=oe;exports.EventListEvent=yu;exports.EventSystem=Nt;exports.EventTrigger=Pu;exports.FieldWithDefault=rw;exports.FileReference=Zo;exports.FileReferenceSerializer=h0;exports.FileSpawnModel=RO;exports.File_Event=K0;exports.FixedJoint=ey;exports.Fog=Wa;exports.FrameEvent=me;exports.GENERATOR=Rc;exports.GameObject=S;exports.Gizmos=B;exports.GltfExport=Mg;exports.GltfExportBox=Pg;exports.Gradient=Rr;exports.Graphic=Zc;exports.GraphicRaycaster=_u;exports.Graphics=to;exports.GridHelper=Ga;exports.GridLayoutGroup=Hg;exports.GroundProjectedEnv=Fn;exports.GroupActionModel=Go;exports.HideFlags=bu;exports.HideOnStart=Ei;exports.HingeJoint=eh;exports.HorizontalLayoutGroup=Gg;exports.HostData=GC;exports.Image=el;exports.ImageReference=Ko;exports.ImageReferenceSerializer=c0;exports.InheritVelocityModule=sy;exports.Input=fv;exports.InputEventQueue=Zt;exports.InputEvents=Se;exports.InputField=_y;exports.InstanceHandle=ir;exports.InstancingHandler=hr;exports.InstancingUtil=Li;exports.InstantiateEvent=jv;exports.InstantiateIdProvider=_t;exports.InstantiateOptions=dn;exports.Interactable=fg;exports.JoinedRoomResponse=pC;exports.KeyEventArgs=nC;exports.Keyframe=ei;exports.LODGroup=ih;exports.LODModel=Ha;exports.LeftRoomResponse=mC;exports.Light=oi;exports.LightData=m0;exports.LimitVelocityOverLifetimeModule=et;exports.LoadingElementOptions=yT;exports.LogStats=ug;exports.LogType=di;exports.LookAt=by;exports.LookAtConstraint=br;exports.MainModule=Rt;exports.MarkerTrackHandler=Qu;exports.MarkerType=my;exports.MaskableGraphic=Jc;exports.Mathf=L;exports.MeshCollider=fo;exports.MeshRenderer=Gc;exports.MinMaxCurve=G;exports.MinMaxGradient=Tr;exports.NEKeyboardEvent=Ol;exports.NEPointerEvent=Zn;exports.NeedleButtonElement=_x;exports.NeedleEngineWebComponent=Py;exports.NeedleMenu=Nn;exports.NeedlePatchesKey=od;exports.NeedleXRController=Tm;exports.NeedleXRSession=H;exports.NeedleXRSync=xv;exports.NeedleXRUtils=Cv;exports.NestedGltf=nh;exports.NetworkConnection=wv;exports.NetworkedStreamEvents=An;exports.NetworkedStreams=Nc;exports.Networking=iy;exports.NewInstanceModel=Uv;exports.NoiseModule=pe;exports.ObjectRaycaster=pi;exports.ObjectUtils=mr;exports.OffsetConstraint=Er;exports.OneEuroFilter=nd;exports.OneEuroFilterXYZ=vm;exports.OpenURL=tl;exports.OrbitControls=de;exports.Outline=$a;exports.OwnershipEvent=vv;exports.OwnershipModel=Im;exports.PUBLIC_KEY=Vo;exports.Padding=Or;exports.ParticleBurst=Qd;exports.ParticleSubEmitter=oy;exports.ParticleSystem=_c;exports.ParticleSystemBaseBehaviour=bo;exports.ParticleSystemRenderer=Wi;exports.ParticleSystemShapeType=Xd;exports.PeerHandle=os;exports.PeerNetworking=_v;exports.Physics=Pa;exports.PhysicsExtension=Ng;exports.PhysicsMaterialCombine=it;exports.PixelationEffect=lh;exports.PlayAnimationOnClick=gc;exports.PlayAudioOnClick=no;exports.PlayableDirector=fr;exports.PlayerColor=Ra;exports.PlayerState=Ai;exports.PlayerStateEvent=kw;exports.PlayerSync=Ug;exports.PlayerView=u0;exports.PlayerViewManager=f0;exports.PointerEventData=zc;exports.PointerType=ou;exports.PostProcessingEffect=We;exports.PostProcessingEffectOrder=Ke;exports.PostProcessingHandler=hy;exports.PreliminaryAction=za;exports.PreliminaryTrigger=Xc;exports.PrimitiveType=sr;exports.Progress=ne;exports.PromiseAllWithErrors=_m;exports.PromiseErrorResult=vp;exports.RGBAColor=ee;exports.RapierPhysics=ba;exports.RawImage=Ju;exports.RaycastOptions=ho;exports.Rect=Rw;exports.RectTransform=hn;exports.ReflectionProbe=mc;exports.RegisteredAnimationInfo=Ys;exports.RemoteSkybox=Vu;exports.RenderTexture=Tn;exports.RenderTextureSerializer=j0;exports.Renderer=$t;exports.RendererData=p0;exports.RendererLightmap=bg;exports.Rigidbody=$e;exports.RigidbodyConstraints=je;exports.RoomEvents=Y;exports.RotationBySpeedModule=$i;exports.RotationOverLifetimeModule=fn;exports.SceneLightSettings=$d;exports.SceneSwitcher=Fe;exports.ScreenCapture=wo;exports.ScreenSpaceAmbientOcclusion=Ss;exports.ScreenSpaceAmbientOcclusionN8=mn;exports.ScrollFollow=Os;exports.SeeThrough=Cs;exports.SendQueue=en;exports.SerializationContext=Hm;exports.SetActiveOnClick=Ag;exports.ShadowCatcher=uh;exports.ShapeModule=ny;exports.ShapeOverlapResult=V0;exports.SharpeningEffect=hh;exports.SignalAsset=Xu;exports.SignalReceiver=yh;exports.SignalReceiverEvent=gh;exports.SignalTrackHandler=wc;exports.Size=Ew;exports.SizeBySpeedModule=ri;exports.SizeOverLifetimeModule=Ar;exports.SkinnedMeshRenderer=vg;exports.SmoothFollow=Wu;exports.SpatialGrabRaycaster=lr;exports.SpatialHtml=bh;exports.SpatialTrigger=Gu;exports.SpatialTriggerReceiver=Bn;exports.SpectatorCamera=Hu;exports.SphereCollider=ja;exports.SphereIntersection=Um;exports.SplineContainer=jr;exports.SplineData=Un;exports.SplineWalker=Hi;exports.Sprite=bs;exports.SpriteData=_a;exports.SpriteRenderer=ni;exports.SpriteSheet=ka;exports.StateMachineBehaviour=vP;exports.StreamEndedEvent=sg;exports.StreamReceivedEvent=$0;exports.SubEmitterSystem=Yd;exports.SyncedCamera=uy;exports.SyncedRoom=gn;exports.SyncedTransform=cn;exports.TapGestureTrigger=Lg;exports.TeleportTarget=Au;exports.TestRunner=fy;exports.TestSceneUtils=OT;exports.TestSimulateUserData=py;exports.Text=Et;exports.TextBuilder=$g;exports.TextExtension=Lu;exports.TextureSheetAnimationModule=Tt;exports.TiltShiftEffect=Wn;exports.Time=g0;exports.ToneMappingEffect=ro;exports.TrackHandler=Ja;exports.TrackType=li;exports.TrailModule=Te;exports.TransformData=Ee;exports.TransformGizmo=Br;exports.TriggerBuilder=Ot;exports.TriggerModel=Js;exports.TypeStore=P;exports.UIRaycastUtils=ig;exports.UIRootComponent=Yc;exports.USDDocument=kg;exports.USDObject=Ve;exports.USDWriter=gw;exports.USDZExporter=yw;exports.USDZExporter$1=on;exports.USDZText=la;exports.USDZUIExtension=Xg;exports.UriSerializer=B0;exports.UsageMarker=Wc;exports.UserJoinedOrLeftRoomModel=gC;exports.VERSION=Di;exports.VariantAction=Rg;exports.VelocityOverLifetimeModule=Le;exports.VerticalLayoutGroup=Wg;exports.VideoPlayer=Ze;exports.ViewDevice=cs;exports.Vignette=Ir;exports.VisibilityAction=Qc;exports.Voip=uo;exports.Volume=Ya;exports.VolumeParameter=F;exports.VolumeProfile=Uu;exports.WaitForFrames=S1;exports.WaitForPromise=d0;exports.WaitForSeconds=Qm;exports.Watch=as;exports.WebARCameraBackground=wh;exports.WebARSessionRoot=ui;exports.WebXR=Du;exports.WebXRButtonFactory=eo;exports.WebXRImageTracking=xh;exports.WebXRImageTrackingModel=ks;exports.WebXRPlaneTracking=Es;exports.WebXRTrackedImage=Ta;exports.XRControllerFollow=Ms;exports.XRControllerModel=fs;exports.XRControllerMovement=yi;exports.XRFlag=Ri;exports.XRRig=af;exports.XRState=zt;exports.XRStateFlag=En;exports.__Ignore=wx;exports.__internalNotifyObjectDestroyed=LC;exports.activeInHierarchyFieldName=ls;exports.addAttributeChangeCallback=gm;exports.addComponent=nn;exports.addCustomExtensionPlugin=HO;exports.addNewComponent=Qo;exports.addPatch=nu;exports.apply=cu;exports.applyHMRChanges=uP;exports.applyPrototypeExtensions=Yv;exports.beginListenDestroy=Bv;exports.beginListenInstantiate=zv;exports.binaryIdentifierCasts=Am;exports.build_scene_functions=K1;exports.builtinComponentKeyName=Bo;exports.calculateProgress01=Cy;exports.clearMessages=Kx;exports.colorSerializer=BP;exports.compareAssociation=Wv;exports.componentSerializer=pd;exports.copyTexture=Kb;exports.createMotion=T0;exports.debugNet=Ht;exports.debugOwner=Ml;exports.decompressGpuTexture=ww;exports.deepClone=Pc;exports.delay=ds;exports.delayForFrames=Oc;exports.deserializeObject=Dd;exports.destroy=Bi;exports.destroyComponentInstance=Jv;exports.determineMimeTypeFromExtension=Z0;exports.disposeObjectResources=be;exports.disposeStream=Dn;exports.editorGuidKeyName=$l;exports.enableSpatialConsole=da;exports.euler=FP;exports.eventListSerializer=$P;exports.exportAsGLTF=ET;exports.findByGuid=Xm;exports.findObjectOfType=Da;exports.findObjectsOfType=t0;exports.findResourceUsers=Fm;exports.fitCamera=A0;exports.fitObjectIntoVolume=Jb;exports.foreachComponent=rr;exports.foreachComponentEnumerator=du;exports.forward=mS;exports.generateQRCode=b0;exports.generateSeed=Fv;exports.getBoundingBox=Vt;exports.getCameraController=Wb;exports.getComponent=yr;exports.getComponentInChildren=Ic;exports.getComponentInParent=hc;exports.getComponents=Lc;exports.getComponentsInChildren=Aa;exports.getComponentsInParent=lu;exports.getFormattedDate=uw;exports.getIconElement=yt;exports.getIconTexture=Np;exports.getLoader=an;exports.getOrAddComponent=Dc;exports.getParam=x;exports.getParentHierarchyPath=_S;exports.getPath=Ex;exports.getPeerOptions=hC;exports.getPeerjsInstance=yv;exports.getResourceUserCount=jC;exports.getTempColor=qb;exports.getTempQuaternion=Kt;exports.getTempVector=j;exports.getUrlParams=Cc;exports.getVisibleInCustomShadowRendering=Zb;exports.getWorldDirection=Xb;exports.getWorldEuler=Sm;exports.getWorldPosition=Q;exports.getWorldQuaternion=fe;exports.getWorldRotation=tu;exports.getWorldScale=Be;exports.hasCommercialLicense=hs;exports.hasIndieLicense=Bc;exports.hasPointerEventComponent=zd;exports.hasProLicense=jn;exports.hideDebugConsole=nv;exports.imageToCanvas=xw;exports.instantiate=ar;exports.invokeLoadedImportPluginHooks=ow;exports.invokeXRSessionEnd=uv;exports.invokeXRSessionStart=dv;exports.isActiveInHierarchy=i0;exports.isActiveSelf=La;exports.isAndroidDevice=Ix;exports.isAnimationAction=Yb;exports.isComponent=F0;exports.isDebugMode=Px;exports.isDesktop=Tx;exports.isDestroyed=or;exports.isDevEnvironment=R;exports.isDisposed=DC;exports.isExporting=MT;exports.isGLTFModel=U0;exports.isHostedOnGlitch=Ab;exports.isHotReloadEnabled=Hp;exports.isHotReloading=hP;exports.isIPad=Dx;exports.isIconElement=v0;exports.isLocalNetwork=ji;exports.isMacOS=Bx;exports.isMobileDevice=Ax;exports.isMozillaXR=jx;exports.isQuest=zx;exports.isResourceTrackingEnabled=Mv;exports.isSafari=Fx;exports.isUsingInstancing=hu;exports.isiOS=Ux;exports.isiPad=Lx;exports.loadAsset=dT;exports.loadPMREM=Zw;exports.loadSync=Sy;exports.logHierarchy=Od;exports.lookAtInverse=aS;exports.lookAtObject=Mc;exports.lookAtScreenPoint=lS;exports.makeId=Mx;exports.makeIdFromRandomWords=Ib;exports.makeNameSafe=gi;exports.markAsInstancedRendered=n0;exports.microphonePermissionsGranted=Nx;exports.nameof=Cx;exports.nameofFactory=Db;exports.objectSerializer=I0;exports.offXRSessionEnd=iC;exports.offXRSessionStart=tC;exports.onAfterRender=iP;exports.onBeforeRender=tP;exports.onClear=J1;exports.onDestroy=eP;exports.onInitialized=Km;exports.onStart=pu;exports.onUpdate=S0;exports.onXRSessionEnd=Rm;exports.onXRSessionStart=su;exports.parseSync=fx;exports.placeOnSurface=ev;exports.postprocessFBXMaterials=Om;exports.prefix=TP;exports.pushState=Lb;exports.randomNumber=kx;exports.registerBinaryType=Dm;exports.registerComponent=fu;exports.registerComponentExtension=yg;exports.registerCustomEffectType=Gi;exports.registerExportExtensions=_g;exports.registerExtensions=Gd;exports.registerHotReloadType=M0;exports.registerLoader=km;exports.registerPrefabProvider=Vv;exports.registerPrototypeExtensions=Kv;exports.registerType=$m;exports.relativePathPrefix=Bb;exports.removeAttributeChangeCallback=ym;exports.removeComponent=qm;exports.removeCustomImportExtensionType=qO;exports.removePatch=JS;exports.resolveUrl=ao;exports.sanitizeString=jb;exports.saveImage=cx;exports.screenshot=XR;exports.screenshot2=xy;exports.sendDestroyed=Nm;exports.serializable=f;exports.serializeObject=Hv;exports.serializeable=Ue;exports.setActive=Hl;exports.setAllowBalloonMessages=Nb;exports.setAllowOverlayMessages=qx;exports.setAutoFitEnabled=Cd;exports.setCameraController=xp;exports.setDestroyed=o0;exports.setDevEnvironment=OS;exports.setDisposable=Ev;exports.setDontDestroy=Zr;exports.setOrAddParamsToUrl=bp;exports.setParam=Ox;exports.setParamWithoutReload=oc;exports.setPeerOptions=dC;exports.setResourceTrackingEnabled=AC;exports.setState=pm;exports.setVisibleInCustomShadowRendering=Pm;exports.setWorldEuler=Cm;exports.setWorldPosition=rt;exports.setWorldPositionXYZ=nr;exports.setWorldQuaternion=rn;exports.setWorldQuaternionXYZW=xm;exports.setWorldRotation=Qb;exports.setWorldRotationXYZ=kc;exports.setWorldScale=wa;exports.showBalloonError=Ec;exports.showBalloonMessage=Pe;exports.showBalloonWarning=ue;exports.showDebugConsole=Mm;exports.slerp=rS;exports.syncDestroy=Tc;exports.syncField=Bg;exports.syncInstantiate=Vm;exports.textureToCanvas=bS;exports.toSourceId=Ub;exports.tryCastBinary=mv;exports.tryDetermineMimetypeFromBinary=ew;exports.tryDetermineMimetypeFromURL=J0;exports.tryFindObject=va;exports.tryGetGuid=gv;exports.unregisterHotReloadType=k0;exports.unwatchWrite=mm;exports.useForAutoFit=Gb;exports.validate=vt;exports.watchWrite=eu;